"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { createRepository: () => createRepository, createSqliteDatabase: () => createSqliteDatabase, createSqliteRepository: () => createSqliteRepository, sqliteMigrateToLatest: () => sqliteMigrateToLatest }); module.exports = __toCommonJS(src_exports); var import_kysely2 = require("kysely"); var import_bouncer_core = require("@dotinc/bouncer-core"); var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1); // src/migration.ts var import_kysely = require("kysely"); var SqliteMigrationProvider = class { getMigrations() { return Promise.resolve({ "2022-10-23_base": { up: async (db) => { await db.schema.createTable("publishers").addColumn("id", "varchar(30)", (col) => col.primaryKey()).addColumn("product_name", "varchar(255)", (col) => col.notNull()).addColumn("publisher_name", "varchar(255)", (col) => col.notNull()).addColumn("home_page_url", "varchar(500)").addColumn("contact_page_url", "varchar(500)").addColumn("privacy_notice_page_url", "varchar(500)").addColumn("contact_sales_email", "varchar(255)").addColumn("contact_sales_url", "varchar(500)").addColumn("contact_support_email", "varchar(255)").addColumn("contact_support_url", "varchar(500)").addColumn("mona_base_storage_url", "varchar(500)").addColumn("mona_subscription_state", "varchar(50)").addColumn("mona_subscription_is_being_configured", "boolean").addColumn("is_setup_complete", "boolean").execute(); await db.schema.createTable("seating_config").addColumn( "owner_id", "varchar(30)", (col) => col.unique().notNull().primaryKey() ).addColumn( "defaultLowSeatWarningLevelPercent", "real", (col) => col.notNull() ).addColumn("seating_strategy_name", "varchar(50)").addColumn("low_seat_warning_level_pct", "real").addColumn("limited_overflow_seating_enabled", "boolean").addColumn("seat_reservation_expiry_in_days", "integer").addColumn("default_seat_expiry_in_days", "integer").execute(); await db.schema.createTable("product_config").addColumn( "publisher_id", "varchar(30)", (col) => col.unique().notNull().primaryKey() ).addColumn("on_access_denied_url", "varchar(500)").addColumn("on_access_granted_url", "varchar(500)").addColumn("on_no_seat_available_url", "varchar(500)").addColumn("on_subscription_not_ready_url", "varchar(500)").addColumn("on_subscription_canceled_url", "varchar(500)").addColumn("on_subscription_suspended_url", "varchar(500)").addColumn("on_subscription_not_found_url", "varchar(500)").addColumn("on_no_subscriptions_found_url", "varchar(500)").execute(); await db.schema.createTable("seats").addColumn( "seat_id", "varchar(30)", (col) => col.notNull().primaryKey() ).addColumn("seating_strategy_name", "varchar(50)").addColumn("subscription_id", "varchar(30)").addColumn("created_utc", "datetime").addColumn("seat_type", "varchar(50)").addColumn("expires_utc", "datetime").addColumn("redeemed_utc", "datetime").execute(); await db.schema.createTable("seat_reservations").addColumn( "seat_id", "varchar(30)", (col) => col.primaryKey().notNull() ).addColumn("tenant_id", "varchar(30)").addColumn("user_id", "varchar(30)").addColumn("email", "varchar(255)").addColumn("invite_url", "varchar(500)").execute(); await db.schema.createTable("seat_occupants").addColumn( "seat_id", "varchar(30)", (col) => col.primaryKey().notNull() ).addColumn("user_id", "varchar(30)", (col) => col.notNull()).addColumn("tenant_id", "varchar(30)", (col) => col.notNull()).addColumn("email", "varchar(255)").addColumn("user_name", "varchar(255)").execute(); await db.schema.createTable("subscriptions").addColumn( "subscription_id", "varchar(30)", (col) => col.primaryKey().notNull() ).addColumn("publisher_id", "varchar(30)").addColumn("is_setup_complete", "boolean").addColumn("created_utc", "datetime").addColumn("tenant_id", "varchar(30)").addColumn("subscriber_info", "jsonb").addColumn("source_subscription", "jsonb").addColumn("subscription_name", "varchar(255)").addColumn("tenant_name", "varchar(255)").addColumn("offer_id", "varchar(30)").addColumn("plan_id", "varchar(30)").addColumn("state", "varchar(15)", (col) => col.notNull()).addColumn("admin_role_name", "varchar(50)").addColumn("user_role_name", "varchar(50)").addColumn("management_urls", "jsonb").addColumn("admin_name", "varchar(50)").addColumn("admin_email", "varchar(255)").addColumn("total_seats", "integer").addColumn("is_being_configured", "boolean").addColumn("is_free_trial", "boolean").addColumn("is_test_subscription", "boolean").addColumn("state_last_updated_utc", "datetime").execute(); }, down: async (db) => { await db.schema.dropTable("subscriptions").execute(); await db.schema.dropTable("seat_occupants").execute(); await db.schema.dropTable("seat_reservations").execute(); await db.schema.dropTable("product_config").execute(); await db.schema.dropTable("seating_config").execute(); await db.schema.dropTable("publishers").execute(); } }, "2022-10-29_seat_summary": { up: async (db) => { await db.schema.createTable("seat_summary").addColumn( "subscription_id", "varchar(30)", (col) => col.unique().notNull().primaryKey() ).addColumn("standard_seat_count", "integer", (col) => col.notNull()).addColumn("limited_seat_count", "integer", (col) => col.notNull()).execute(); }, down: async (db) => { await db.schema.dropTable("seat_summary").execute(); } } }); } }; var migrateToLatest = async (dialect, provider) => { const db = new import_kysely.Kysely({ dialect }); const migrator = new import_kysely.Migrator({ db, provider }); const { error, results } = await migrator.migrateToLatest(); results == null ? void 0 : results.forEach((it) => { if (it.status === "Success") { console.log(`migration "${it.migrationName}" was executed successfully`); } else if (it.status === "Error") { console.error(`failed to execute migration "${it.migrationName}"`); } }); if (error) { console.error("failed to migrate"); console.error(error); process.exit(1); } await db.destroy(); }; var sqliteMigrateToLatest = (config) => { const dialect = new import_kysely.SqliteDialect(config); const provider = new SqliteMigrationProvider(); migrateToLatest(dialect, provider); }; // src/index.ts var actuallyItisJsonAlready = (seeminglyString) => seeminglyString; var createRepository = (args) => { const db = new import_kysely2.Kysely(args); const repo = { getPublisher: async (publisherId) => { const row = await db.selectFrom("publishers").innerJoin("seating_config", "seating_config.owner_id", "id").innerJoin("product_config", "product_config.publisher_id", "id").selectAll().where("id", "=", publisherId).executeTakeFirst(); if (!row) return void 0; return { id: row.id, product_name: row.product_name, publisher_name: row.publisher_name, home_page_url: row.home_page_url, contact_page_url: row.contact_page_url, privacy_notice_page_url: row.privacy_notice_page_url, contact_sales_email: row.contact_sales_email, contact_sales_url: row.contact_sales_url, contact_support_email: row.contact_support_email, contact_support_url: row.contact_support_url, mona_base_storage_url: row.mona_base_storage_url, mona_subscription_state: row.mona_subscription_state, mona_subscription_is_being_configured: row.mona_subscription_is_being_configured, is_setup_complete: row.is_setup_complete, default_seating_config: { defaultLowSeatWarningLevelPercent: row.defaultLowSeatWarningLevelPercent, seating_strategy_name: row.seating_strategy_name, low_seat_warning_level_pct: row.low_seat_warning_level_pct, limited_overflow_seating_enabled: row.limited_overflow_seating_enabled, seat_reservation_expiry_in_days: row.seat_reservation_expiry_in_days, default_seat_expiry_in_days: row.default_seat_expiry_in_days }, product_config: { on_access_denied_url: row.on_access_denied_url, on_access_granted_url: row.on_access_granted_url, on_no_seat_available_url: row.on_no_seat_available_url, on_subscription_not_ready_url: row.on_subscription_not_ready_url, on_subscription_canceled_url: row.on_subscription_canceled_url, on_subscription_suspended_url: row.on_subscription_suspended_url, on_subscription_not_found_url: row.on_subscription_not_found_url, on_no_subscriptions_found_url: row.on_no_subscriptions_found_url } }; }, getPublishers: async () => { const rows = await db.selectFrom("publishers").innerJoin("seating_config", "seating_config.owner_id", "id").innerJoin("product_config", "product_config.publisher_id", "id").selectAll().execute(); return rows.map((row) => ({ id: row.id, product_name: row.product_name, publisher_name: row.publisher_name, home_page_url: row.home_page_url, contact_page_url: row.contact_page_url, privacy_notice_page_url: row.privacy_notice_page_url, contact_sales_email: row.contact_sales_email, contact_sales_url: row.contact_sales_url, contact_support_email: row.contact_support_email, contact_support_url: row.contact_support_url, mona_base_storage_url: row.mona_base_storage_url, mona_subscription_state: row.mona_subscription_state, mona_subscription_is_being_configured: row.mona_subscription_is_being_configured, is_setup_complete: row.is_setup_complete, default_seating_config: { defaultLowSeatWarningLevelPercent: row.defaultLowSeatWarningLevelPercent, seating_strategy_name: row.seating_strategy_name, low_seat_warning_level_pct: row.low_seat_warning_level_pct, limited_overflow_seating_enabled: row.limited_overflow_seating_enabled, seat_reservation_expiry_in_days: row.seat_reservation_expiry_in_days, default_seat_expiry_in_days: row.default_seat_expiry_in_days }, product_config: { on_access_denied_url: row.on_access_denied_url, on_access_granted_url: row.on_access_granted_url, on_no_seat_available_url: row.on_no_seat_available_url, on_subscription_not_ready_url: row.on_subscription_not_ready_url, on_subscription_canceled_url: row.on_subscription_canceled_url, on_subscription_suspended_url: row.on_subscription_suspended_url, on_subscription_not_found_url: row.on_subscription_not_found_url, on_no_subscriptions_found_url: row.on_no_subscriptions_found_url } })); }, updatePublisher: async (update) => { await db.transaction().execute(async (tx) => { const up = await tx.updateTable("publishers").set({ product_name: update.product_name, publisher_name: update.publisher_name, home_page_url: update.home_page_url, contact_page_url: update.contact_page_url, privacy_notice_page_url: update.privacy_notice_page_url, contact_sales_email: update.contact_sales_email, contact_sales_url: update.contact_sales_url, contact_support_email: update.contact_support_email, contact_support_url: update.contact_support_url, mona_base_storage_url: update.mona_base_storage_url, mona_subscription_state: update.mona_subscription_state, mona_subscription_is_being_configured: update.mona_subscription_is_being_configured, is_setup_complete: update.is_setup_complete }).where("id", "=", update.id).executeTakeFirst(); if (up.numUpdatedRows !== 1n) throw new Error( `Failed to update publisher configuration: [${update.id}]` ); const prodConfig = await db.updateTable("product_config").set({ on_access_denied_url: update.product_config.on_access_denied_url, on_access_granted_url: update.product_config.on_access_granted_url, on_no_seat_available_url: update.product_config.on_no_seat_available_url, on_no_subscriptions_found_url: update.product_config.on_no_subscriptions_found_url, on_subscription_canceled_url: update.product_config.on_subscription_canceled_url, on_subscription_not_found_url: update.product_config.on_subscription_not_found_url, on_subscription_not_ready_url: update.product_config.on_subscription_not_ready_url, on_subscription_suspended_url: update.product_config.on_subscription_suspended_url }).where("publisher_id", "=", update.id).executeTakeFirst(); if (prodConfig.numUpdatedRows !== 1n) throw new Error( `Failed to update publisher configuration: [${update.id}]` ); const seatingConfig = await db.updateTable("seating_config").set({ default_seat_expiry_in_days: update.default_seating_config.default_seat_expiry_in_days, defaultLowSeatWarningLevelPercent: update.default_seating_config.defaultLowSeatWarningLevelPercent, limited_overflow_seating_enabled: update.default_seating_config.limited_overflow_seating_enabled, low_seat_warning_level_pct: update.default_seating_config.low_seat_warning_level_pct, seat_reservation_expiry_in_days: update.default_seating_config.seat_reservation_expiry_in_days, seating_strategy_name: update.default_seating_config.seating_strategy_name }).where("seating_config.owner_id", "=", update.id).executeTakeFirst(); if (seatingConfig.numUpdatedRows !== 1n) throw new Error( `Failed to update publisher configuration: [${update.id}]` ); }); return update; }, createPublisher: async (config) => { await db.transaction().execute(async (tx) => { console.log("creating publisher", config.id); const up = await tx.insertInto("publishers").values({ id: config.id, product_name: config.product_name, publisher_name: config.publisher_name, home_page_url: config.home_page_url, contact_page_url: config.contact_page_url, privacy_notice_page_url: config.privacy_notice_page_url, contact_sales_email: config.contact_sales_email, contact_sales_url: config.contact_sales_url, contact_support_email: config.contact_support_email, contact_support_url: config.contact_support_url, mona_base_storage_url: config.mona_base_storage_url, mona_subscription_state: config.mona_subscription_state, mona_subscription_is_being_configured: config.mona_subscription_is_being_configured, is_setup_complete: config.is_setup_complete }).executeTakeFirst(); if (!up) throw new Error( `Failed to save publisher configuration: [${config.id}]` ); console.log( `creating product configuration for publisher [${config.id}]` ); const prodConfig = await tx.insertInto("product_config").values({ publisher_id: config.id, on_access_denied_url: config.product_config.on_access_denied_url, on_access_granted_url: config.product_config.on_access_granted_url, on_no_seat_available_url: config.product_config.on_no_seat_available_url, on_no_subscriptions_found_url: config.product_config.on_no_subscriptions_found_url, on_subscription_canceled_url: config.product_config.on_subscription_canceled_url, on_subscription_not_found_url: config.product_config.on_subscription_not_found_url, on_subscription_not_ready_url: config.product_config.on_subscription_not_ready_url, on_subscription_suspended_url: config.product_config.on_subscription_suspended_url }).executeTakeFirst(); if (!prodConfig) throw new Error( `Failed to save publisher configuration: [${config.id}]` ); console.log( `creating default seating configuration for publisher [${config.id}]` ); const seatingConfig = await tx.insertInto("seating_config").values({ owner_id: config.id, default_seat_expiry_in_days: config.default_seating_config.default_seat_expiry_in_days, defaultLowSeatWarningLevelPercent: config.default_seating_config.defaultLowSeatWarningLevelPercent, limited_overflow_seating_enabled: config.default_seating_config.limited_overflow_seating_enabled, low_seat_warning_level_pct: config.default_seating_config.low_seat_warning_level_pct, seat_reservation_expiry_in_days: config.default_seating_config.seat_reservation_expiry_in_days, seating_strategy_name: config.default_seating_config.seating_strategy_name }).executeTakeFirst(); if (!seatingConfig) throw new Error( `Failed to save publisher configuration: [${config.id}]` ); }); return config; }, getSeat: async (seatId, subscriptionId) => { const row = await db.selectFrom("seats").leftJoin("seat_occupants", "seat_occupants.seat_id", "seats.seat_id").leftJoin( "seat_reservations", "seat_reservations.seat_id", "seats.seat_id" ).select([ "seats.subscription_id", "seats.seat_id", "seats.seat_type", "seats.seating_strategy_name", "seats.redeemed_utc", "seats.created_utc", "seats.expires_utc", "seat_occupants.user_id as occupant_user_id", "seat_occupants.user_name as occupant_user_name", "seat_occupants.tenant_id as occupant_tenant_id", "seat_occupants.email as occupant_email", "seat_reservations.email as reservation_email", "seat_reservations.invite_url as reservation_invite_url", "seat_reservations.tenant_id as reservation_tenant_id", "seat_reservations.user_id as reservation_user_id" ]).where("seats.seat_id", "=", seatId).where("subscription_id", "=", subscriptionId).executeTakeFirst(); if (!row) return void 0; return { subscription_id: row.subscription_id, seat_id: row.seat_id, seat_type: row.seat_type, seating_strategy_name: row.seating_strategy_name, redeemed_utc: row.redeemed_utc, created_utc: row.created_utc, expires_utc: row.expires_utc, occupant: row.occupant_user_id && row.occupant_tenant_id ? { tenant_id: row.occupant_tenant_id, user_id: row.occupant_user_id, user_name: row.occupant_user_name ?? void 0, email: row.occupant_email ?? void 0 } : null, reservation: row.reservation_tenant_id || row.reservation_email ? { identifier: row.reservation_tenant_id ? { user_id: row.reservation_user_id, tenant_id: row.reservation_tenant_id } : { email: row.reservation_email }, invite_url: row.reservation_invite_url } : null }; }, getSeats: async (subscriptionId, byUserId, byEmail) => { const q = db.selectFrom("seats").leftJoin("seat_occupants", "seat_occupants.seat_id", "seats.seat_id").leftJoin( "seat_reservations", "seat_reservations.seat_id", "seats.seat_id" ).select([ "seats.subscription_id", "seats.seat_id", "seats.seat_type", "seats.seating_strategy_name", "seats.redeemed_utc", "seats.created_utc", "seats.expires_utc", "seat_occupants.user_id as occupant_user_id", "seat_occupants.user_name as occupant_user_name", "seat_occupants.tenant_id as occupant_tenant_id", "seat_occupants.email as occupant_email", "seat_reservations.email as reservation_email", "seat_reservations.invite_url as reservation_invite_url", "seat_reservations.tenant_id as reservation_tenant_id", "seat_reservations.user_id as reservation_user_id" ]).where("seats.subscription_id", "=", subscriptionId).where( (qb) => qb.where("expires_utc", "is", null).orWhere("expires_utc", ">", (0, import_bouncer_core.getMysqlFormattedDateTime)()) ); if (byUserId) { q.where( (qb) => qb.where("seat_occupants.user_id", "=", byUserId).orWhere("seat_reservations.user_id", "=", byUserId) ); } if (byEmail) { q.where( (qb) => qb.where("seat_occupants.email", "=", byEmail).orWhere("seat_reservations.email", "=", byEmail) ); } const rows = await q.execute(); return rows.map((row) => ({ subscription_id: row.subscription_id, seat_id: row.seat_id, seat_type: row.seat_type, seating_strategy_name: row.seating_strategy_name, redeemed_utc: row.redeemed_utc, created_utc: row.created_utc, expires_utc: row.expires_utc, occupant: row.occupant_user_id && row.occupant_tenant_id ? { tenant_id: row.occupant_tenant_id, user_id: row.occupant_user_id, user_name: row.occupant_user_name ?? void 0, email: row.occupant_email ?? void 0 } : null, reservation: row.reservation_tenant_id || row.reservation_email ? { identifier: row.reservation_tenant_id ? { user_id: row.reservation_user_id, tenant_id: row.reservation_tenant_id } : { email: row.reservation_email }, invite_url: row.reservation_invite_url } : null })); }, replaceSeat: async (update) => { await db.transaction().execute(async (tx) => { const up = await tx.insertInto("seats").values({ seat_id: update.seat_id, created_utc: update.created_utc, subscription_id: update.subscription_id, expires_utc: update.expires_utc, redeemed_utc: update.redeemed_utc, seat_type: update.seat_type, seating_strategy_name: update.seating_strategy_name }).onDuplicateKeyUpdate({ expires_utc: update.expires_utc, redeemed_utc: update.redeemed_utc, seat_type: update.seat_type, seating_strategy_name: update.seating_strategy_name }).executeTakeFirst(); if (!up) throw new Error(`Failed to save seat: [${update.seat_id}]`); if (!update.reservation) { await tx.deleteFrom("seat_reservations").where("seat_id", "=", update.seat_id).execute(); } else { const reservation = update.reservation; const res = await tx.insertInto("seat_reservations").values({ seat_id: update.seat_id, tenant_id: "tenant_id" in reservation.identifier ? reservation.identifier.tenant_id : null, user_id: "tenant_id" in reservation.identifier ? reservation.identifier.user_id : null, invite_url: reservation.invite_url, email: "email" in reservation.identifier ? reservation.identifier.email : null }).onDuplicateKeyUpdate({ tenant_id: "tenant_id" in reservation.identifier ? reservation.identifier.tenant_id : null, user_id: "tenant_id" in reservation.identifier ? reservation.identifier.user_id : null, invite_url: reservation.invite_url, email: "email" in reservation.identifier ? reservation.identifier.email : null }).executeTakeFirst(); if (!res) throw new Error( `Failed to save seat reservation: [${update.seat_id}]` ); } if (!update.occupant) { await tx.deleteFrom("seat_occupants").where("seat_id", "=", update.seat_id).execute(); } else { const occupant = update.occupant; const occ = await tx.insertInto("seat_occupants").values({ seat_id: update.seat_id, user_id: occupant.user_id, tenant_id: occupant.tenant_id, email: occupant.email, user_name: occupant.user_name }).onDuplicateKeyUpdate({ user_id: occupant.user_id, tenant_id: occupant.tenant_id, email: occupant.email, user_name: occupant.user_name }).executeTakeFirst(); if (!occ) throw new Error( `Failed to save seat occupant: [${update.seat_id}]` ); } }); return update; }, createSeat: async (seat, subscription) => { var _a, _b; const actualSeatSummaryRows = await db.selectFrom("seats").select([import_kysely2.sql`COUNT(1)`.as("seat_count"), "seat_type"]).where("subscription_id", "=", subscription.subscription_id).where( (w) => w.where("expires_utc", "is", null).orWhere("expires_utc", ">", (0, import_bouncer_core.getMysqlFormattedDateTime)()) ).groupBy("seat_type").execute(); const unknownToInt = (seatCount) => { if (!seatCount) return 0; if (typeof seatCount === "number") return seatCount; if (typeof seatCount === "string") return parseInt(seatCount); console.error( "got unknown type for seat count from aggregate query", seatCount, typeof seatCount ); return 0; }; const actualSeatSummary = { standardSeatCount: unknownToInt( (_a = actualSeatSummaryRows.find((r) => r.seat_type === "standard")) == null ? void 0 : _a.seat_count ), limitedSeatCount: unknownToInt( (_b = actualSeatSummaryRows.find((r) => r.seat_type === "limited")) == null ? void 0 : _b.seat_count ) }; console.log("seat_summary", JSON.stringify({ actualSeatSummary })); if (seat.seat_type === "standard") { if (subscription.total_seats && subscription.total_seats <= actualSeatSummary.standardSeatCount) { return { isSeatCreated: false, seatingSummary: actualSeatSummary }; } actualSeatSummary.standardSeatCount = actualSeatSummary.standardSeatCount + 1; } else { actualSeatSummary.limitedSeatCount = actualSeatSummary.limitedSeatCount + 1; } console.log("modified seat_summary", JSON.stringify(actualSeatSummary)); await db.transaction().execute(async (tx) => { const ss = await tx.insertInto("seat_summary").values({ subscription_id: subscription.subscription_id, standard_seat_count: actualSeatSummary.standardSeatCount, limited_seat_count: actualSeatSummary.limitedSeatCount }).onDuplicateKeyUpdate({ standard_seat_count: actualSeatSummary.standardSeatCount, limited_seat_count: actualSeatSummary.limitedSeatCount }).executeTakeFirst(); if (!ss) { throw new Error( `Failed to save seat summary for subscription [${subscription.subscription_id}]` ); } const up = await tx.insertInto("seats").values({ seat_id: seat.seat_id, created_utc: seat.created_utc, subscription_id: seat.subscription_id, expires_utc: seat.expires_utc, redeemed_utc: seat.redeemed_utc, seat_type: seat.seat_type, seating_strategy_name: seat.seating_strategy_name }).executeTakeFirst(); if (!up) throw new Error(`Failed to save seat: [${seat.seat_id}]`); if (seat.reservation) { const reservation = seat.reservation; const res = await tx.insertInto("seat_reservations").values({ seat_id: seat.seat_id, tenant_id: "tenant_id" in reservation.identifier ? reservation.identifier.tenant_id : null, user_id: "tenant_id" in reservation.identifier ? reservation.identifier.user_id : null, invite_url: reservation.invite_url, email: "email" in reservation.identifier ? reservation.identifier.email : null }).executeTakeFirst(); if (!res) throw new Error( `Failed to save seat reservation: [${seat.seat_id}]` ); } if (seat.occupant) { const occupant = seat.occupant; const occ = await tx.insertInto("seat_occupants").values({ seat_id: seat.seat_id, user_id: occupant.user_id, tenant_id: occupant.tenant_id, email: occupant.email, user_name: occupant.user_name }).executeTakeFirst(); if (!occ) throw new Error(`Failed to save seat occupant: [${seat.seat_id}]`); } }); const createdSeat = await repo.getSeat( seat.seat_id, seat.subscription_id ); if (!createdSeat) { console.error( "we failed to get a subscription which we just updated... wtf?" ); throw new Error( "we failed to find the just updated subscription, please call us." ); } return { isSeatCreated: true, seatingSummary: actualSeatSummary, createdSeat }; }, deleteSeat: async (seatId, subscriptionId) => { await db.transaction().execute(async (tx) => { await tx.deleteFrom("seat_occupants").where("seat_id", "=", seatId).execute(); await tx.deleteFrom("seat_reservations").where("seat_id", "=", seatId).execute(); await tx.deleteFrom("seats").where("seat_id", "=", seatId).where("subscription_id", "=", subscriptionId).execute(); }); }, getSubscription: async (subscriptionId) => { const row = await db.selectFrom("subscriptions").leftJoin("seating_config", "owner_id", "subscription_id").selectAll().where("subscription_id", "=", subscriptionId).executeTakeFirst(); if (!row) return void 0; return { subscription_id: row.subscription_id, subscriber_info: actuallyItisJsonAlready(row.subscriber_info), source_subscription: actuallyItisJsonAlready(row.source_subscription), is_setup_complete: row.is_setup_complete, subscription_name: row.subscription_name, tenant_id: row.tenant_id, tenant_name: row.tenant_name, offer_id: row.offer_id, plan_id: row.plan_id, state: row.state, admin_role_name: row.admin_role_name, user_role_name: row.user_role_name, management_urls: actuallyItisJsonAlready(row.management_urls), admin_name: row.admin_name, admin_email: row.admin_email, total_seats: row.total_seats, is_being_configured: row.is_being_configured, is_free_trial: row.is_free_trial, is_test_subscription: row.is_test_subscription, created_utc: row.created_utc, state_last_updated_utc: row.state_last_updated_utc, seating_config: row.seating_strategy_name ? { seat_reservation_expiry_in_days: row.seat_reservation_expiry_in_days ?? void 0, default_seat_expiry_in_days: row.default_seat_expiry_in_days ?? void 0, defaultLowSeatWarningLevelPercent: row.defaultLowSeatWarningLevelPercent ?? 0, seating_strategy_name: row.seating_strategy_name, low_seat_warning_level_pct: row.low_seat_warning_level_pct, limited_overflow_seating_enabled: row.limited_overflow_seating_enabled } : void 0 }; }, getSubscriptions: async (publisherId) => { const rows = await db.selectFrom("subscriptions").leftJoin("seating_config", "owner_id", "subscription_id").selectAll().where("publisher_id", "=", publisherId).execute(); return rows.map((row) => { const r = { subscription_id: row.subscription_id, subscriber_info: actuallyItisJsonAlready(row.subscriber_info), source_subscription: actuallyItisJsonAlready(row.source_subscription), is_setup_complete: row.is_setup_complete, subscription_name: row.subscription_name, tenant_id: row.tenant_id, tenant_name: row.tenant_name, offer_id: row.offer_id, plan_id: row.plan_id, state: row.state, admin_role_name: row.admin_role_name, user_role_name: row.user_role_name, management_urls: actuallyItisJsonAlready(row.management_urls), admin_name: row.admin_name, admin_email: row.admin_email, total_seats: row.total_seats, is_being_configured: row.is_being_configured, is_free_trial: row.is_free_trial, is_test_subscription: row.is_test_subscription, created_utc: row.created_utc, state_last_updated_utc: row.state_last_updated_utc, seating_config: row.seating_strategy_name ? { seat_reservation_expiry_in_days: row.seat_reservation_expiry_in_days ?? void 0, default_seat_expiry_in_days: row.default_seat_expiry_in_days ?? void 0, defaultLowSeatWarningLevelPercent: row.defaultLowSeatWarningLevelPercent ?? 0, seating_strategy_name: row.seating_strategy_name, low_seat_warning_level_pct: row.low_seat_warning_level_pct, limited_overflow_seating_enabled: row.limited_overflow_seating_enabled } : void 0 }; return r; }); }, createSubscription: async (publisherId, sub) => { const defaultSeatConfig = await db.selectFrom("seating_config").selectAll().where("owner_id", "=", publisherId).executeTakeFirstOrThrow(); await db.transaction().execute(async (tx) => { const now = new Date(); const up = await tx.insertInto("subscriptions").values({ subscription_id: sub.subscription_id, publisher_id: publisherId, subscriber_info: JSON.stringify(sub.subscriber_info), source_subscription: JSON.stringify(sub.source_subscription), is_setup_complete: sub.is_setup_complete ?? false, subscription_name: sub.subscription_name ?? sub.subscription_id, tenant_id: sub.tenant_id, tenant_name: sub.tenant_name, offer_id: sub.offer_id, plan_id: sub.plan_id, state: sub.state, admin_role_name: sub.admin_role_name, user_role_name: sub.user_role_name, management_urls: JSON.stringify(sub.management_urls), admin_name: sub.admin_name, admin_email: sub.admin_email, total_seats: sub.total_seats, is_being_configured: sub.is_being_configured, is_free_trial: sub.is_free_trial, is_test_subscription: sub.is_test_subscription, created_utc: sub.created_utc ?? (0, import_bouncer_core.getMysqlFormattedDateTime)(now), state_last_updated_utc: sub.state_last_updated_utc ?? (0, import_bouncer_core.getMysqlFormattedDateTime)(now) }).execute(); if (!up) throw new Error( `Failed to save subscription: [${publisherId}, ${sub.subscription_id}]` ); const seatConfig = !sub.seating_config ? defaultSeatConfig : { ...defaultSeatConfig, ...sub.seating_config }; const scUp = await tx.insertInto("seating_config").values({ owner_id: sub.subscription_id, seat_reservation_expiry_in_days: seatConfig.seat_reservation_expiry_in_days, default_seat_expiry_in_days: seatConfig.default_seat_expiry_in_days, defaultLowSeatWarningLevelPercent: seatConfig.defaultLowSeatWarningLevelPercent, seating_strategy_name: seatConfig.seating_strategy_name, low_seat_warning_level_pct: seatConfig.low_seat_warning_level_pct, limited_overflow_seating_enabled: seatConfig.limited_overflow_seating_enabled }).execute(); if (!scUp) throw new Error( `Failed to save seating_config for subscription: [${publisherId}, ${sub.subscription_id}]` ); }); return sub; }, updateSubscription: async (sub) => { const defaultSeatConfig = await db.selectFrom("seating_config").selectAll().where( "owner_id", "=", db.selectFrom("subscriptions").select("publisher_id").where("subscription_id", "=", sub.subscription_id) ).executeTakeFirstOrThrow(); await db.transaction().execute(async (tx) => { const up = await tx.updateTable("subscriptions").set({ plan_id: sub.plan_id, is_being_configured: sub.is_being_configured, source_subscription: JSON.stringify(sub.source_subscription), subscriber_info: JSON.stringify(sub.subscriber_info), subscription_name: sub.subscription_name, total_seats: sub.total_seats, admin_role_name: sub.admin_role_name, user_role_name: sub.user_role_name, is_setup_complete: sub.is_setup_complete, management_urls: JSON.stringify(sub.management_urls), admin_name: sub.admin_name, admin_email: sub.admin_email, tenant_name: sub.tenant_name, state: sub.state, state_last_updated_utc: (0, import_bouncer_core.getMysqlFormattedDateTime)() }).where("subscription_id", "=", sub.subscription_id).execute(); if (!up) throw new Error( `Failed to save subscription: [${sub.subscription_id}]` ); if (sub.seating_config) { const scUp = await tx.updateTable("seating_config").set({ seat_reservation_expiry_in_days: sub.seating_config.seat_reservation_expiry_in_days ?? defaultSeatConfig.seat_reservation_expiry_in_days, default_seat_expiry_in_days: sub.seating_config.default_seat_expiry_in_days ?? defaultSeatConfig.default_seat_expiry_in_days, seating_strategy_name: sub.seating_config.seating_strategy_name ?? defaultSeatConfig.seating_strategy_name, limited_overflow_seating_enabled: sub.seating_config.limited_overflow_seating_enabled ?? defaultSeatConfig.limited_overflow_seating_enabled, defaultLowSeatWarningLevelPercent: sub.seating_config.defaultLowSeatWarningLevelPercent ?? defaultSeatConfig.defaultLowSeatWarningLevelPercent, low_seat_warning_level_pct: sub.seating_config.low_seat_warning_level_pct ?? defaultSeatConfig.low_seat_warning_level_pct }).where("owner_id", "=", sub.subscription_id).execute(); if (!scUp) throw new Error( `Failed to save seating_config for subscription: [${sub.subscription_id}]` ); } }); const updated = await repo.getSubscription(sub.subscription_id); if (!updated) { console.error( "we failed to get a subscription which we just updated... wtf?" ); throw new Error( "we failed to find the just updated subscription, please call us." ); } return updated; } }; return repo; }; var createSqliteDatabase = (filepath) => { return new import_better_sqlite3.default(filepath, { verbose: console.log }); }; var createSqliteRepository = (config) => { return createRepository({ dialect: new import_kysely2.SqliteDialect(config), plugins: [new SqliteBooleanPlugin()], log: ["query", "error"] }); }; var SqliteBooleanPlugin = class { constructor() { this.transformer = new SqliteBooleanTransformer(); } transformQuery(args) { return this.transformer.transformNode(args.node); } transformResult(args) { return Promise.resolve(args.result); } }; var SqliteBooleanTransformer = class extends import_kysely2.OperationNodeTransformer { transformPrimitiveValueList(node) { console.log("trasnforming values"); const vnode = super.transformPrimitiveValueList(node); return { ...vnode, values: vnode.values.map( (v) => typeof v === "boolean" ? v ? 1 : 0 : v ) }; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createRepository, createSqliteDatabase, createSqliteRepository, sqliteMigrateToLatest });