@carlonicora/nextjs-jsonapi 1.28.0 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-CAUNVZUF.js → BlockNoteEditor-7BDLLHRA.js} +13 -13
- package/dist/{BlockNoteEditor-CAUNVZUF.js.map → BlockNoteEditor-7BDLLHRA.js.map} +1 -1
- package/dist/{BlockNoteEditor-EOA4OEVX.mjs → BlockNoteEditor-F5KCNLVF.mjs} +3 -3
- package/dist/billing/index.d.mts +47 -17
- package/dist/billing/index.d.ts +47 -17
- package/dist/billing/index.js +1241 -1073
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +1375 -1207
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-IXI4GAKB.js → chunk-7M7NPKOF.js} +490 -433
- package/dist/chunk-7M7NPKOF.js.map +1 -0
- package/dist/{chunk-ORFXBO7F.mjs → chunk-DU64WMZD.mjs} +6 -3
- package/dist/chunk-DU64WMZD.mjs.map +1 -0
- package/dist/{chunk-TSEU4KZ2.js → chunk-J22NEVSK.js} +21 -18
- package/dist/chunk-J22NEVSK.js.map +1 -0
- package/dist/{chunk-PYASRX75.mjs → chunk-YLSLXQ3O.mjs} +83 -26
- package/dist/chunk-YLSLXQ3O.mjs.map +1 -0
- package/dist/client/index.d.mts +14 -5
- package/dist/client/index.d.ts +14 -5
- package/dist/client/index.js +5 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -2
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.mjs +2 -2
- package/dist/{config-B4pZpLT9.d.ts → config-CHwoRDOp.d.ts} +1 -1
- package/dist/{config-DT1K-t6I.d.mts → config-DiWyJzk9.d.mts} +1 -1
- package/dist/{content.interface-B2Ldg0vg.d.mts → content.interface-BSpowEiW.d.mts} +1 -1
- package/dist/{content.interface-D8NHv3DX.d.ts → content.interface-DFQ7mkpL.d.ts} +1 -1
- package/dist/contexts/index.d.mts +2 -2
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +39 -37
- package/dist/core/index.d.ts +39 -37
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notification.interface-H0L9WBge.d.ts → notification.interface-CmKmObIU.d.ts} +1 -0
- package/dist/{notification.interface-DEn-Yp_b.d.mts → notification.interface-D5MbtfZK.d.mts} +1 -0
- package/dist/{s3.service-BNytYanU.d.mts → s3.service-BMT7W6KS.d.mts} +19 -19
- package/dist/{s3.service-C7f_Ygz5.d.ts → s3.service-DsXo9nop.d.ts} +19 -19
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/{useSocket-BcnThTD0.d.mts → useSocket-DUqGoPya.d.mts} +1 -1
- package/dist/{useSocket-QZTOCzRF.d.ts → useSocket-QuHa0ZmO.d.ts} +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +1 -0
- package/src/components/forms/FormSelect.tsx +2 -1
- package/src/components/pages/PageContentContainer.tsx +2 -2
- package/src/features/auth/data/auth.ts +0 -2
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +60 -3
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +12 -152
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +168 -0
- package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +19 -1
- package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -235
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +7 -18
- package/src/features/billing/stripe-subscription/components/forms/index.ts +0 -1
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +10 -1
- package/src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx +28 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx +128 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +54 -0
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +68 -0
- package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -1
- package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +114 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +66 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +32 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx +103 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +133 -0
- package/src/features/billing/stripe-subscription/components/wizards/index.ts +6 -0
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +217 -0
- package/src/features/billing/stripe-subscription/index.ts +3 -2
- package/src/features/company/components/details/TokenStatusIndicator.tsx +19 -9
- package/src/features/company/data/company.interface.ts +2 -0
- package/src/features/company/data/company.ts +7 -0
- package/src/features/company/hooks/index.ts +1 -0
- package/src/features/company/hooks/useSubscriptionStatus.ts +71 -0
- package/src/features/user/components/forms/UserEditor.tsx +1 -1
- package/src/features/user/components/lists/AdminUsersList.tsx +1 -1
- package/src/features/user/contexts/CurrentUserContext.tsx +1 -1
- package/src/features/user/data/user.ts +1 -1
- package/dist/chunk-IXI4GAKB.js.map +0 -1
- package/dist/chunk-ORFXBO7F.mjs.map +0 -1
- package/dist/chunk-PYASRX75.mjs.map +0 -1
- package/dist/chunk-TSEU4KZ2.js.map +0 -1
- package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +0 -331
- package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +0 -110
- /package/dist/{BlockNoteEditor-EOA4OEVX.mjs.map → BlockNoteEditor-F5KCNLVF.mjs.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-TSEU4KZ2.js","../src/core/factories/RehydrationFactory.ts","../src/core/abstracts/AbstractApiData.ts","../src/core/abstracts/AbstractService.ts","../src/client/JsonApiClient.ts","../src/core/abstracts/ClientAbstractService.ts","../src/core/registry/ModuleRegistrar.ts","../src/core/registry/ModuleRegistry.ts","../src/core/endpoint/EndpointCreator.ts","../src/core/fields/FieldSelector.ts","../src/core/utils/rehydrate.ts","../src/utils/cn.ts","../src/utils/compose-refs.ts","../src/utils/use-mobile.tsx","../src/utils/date-formatter.ts","../src/utils/exists.ts","../src/utils/table-options.ts","../src/utils/schemas/user.object.schema.ts","../src/utils/schemas/entity.object.schema.ts","../src/utils/blocknote-diff.util.ts","../src/utils/blocknote-word-diff-renderer.util.ts","../src/utils/icons.tsx","../src/permissions/types.ts","../src/permissions/check.ts","../src/features/auth/config.ts","../src/features/auth/data/auth.ts","../src/features/auth/data/auth.service.ts","../src/features/auth/enums/AuthComponent.ts","../src/features/auth/auth.module.ts","../src/features/billing/data/billing.service.ts","../src/features/billing/data/Billing.ts","../src/features/billing/modules/billing.module.ts","../src/features/billing/stripe-customer/data/payment-method.ts","../src/features/billing/stripe-customer/data/stripe-customer.ts","../src/features/billing/stripe-customer/data/stripe-customer.service.ts","../src/features/billing/stripe-customer/stripe-customer.module.ts","../src/features/billing/stripe-customer/stripe-payment-method.module.ts","../src/features/billing/stripe-invoice/data/stripe-invoice.ts","../src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts","../src/features/billing/stripe-invoice/data/stripe-invoice.service.ts","../src/features/billing/stripe-invoice/stripe-invoice.module.ts","../src/features/billing/stripe-price/data/stripe-price.ts","../src/features/billing/stripe-price/data/stripe-price.service.ts","../src/features/billing/stripe-price/stripe-price.module.ts","../src/features/billing/stripe-product/data/stripe-product.ts","../src/features/billing/stripe-product/data/stripe-product.service.ts","../src/features/billing/stripe-product/stripe-product.module.ts","../src/features/billing/stripe-subscription/data/stripe-subscription.ts","../src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts","../src/features/billing/stripe-subscription/data/stripe-subscription.service.ts","../src/features/billing/stripe-subscription/stripe-subscription.module.ts","../src/features/billing/stripe-usage/data/stripe-usage.ts","../src/features/billing/stripe-usage/data/stripe-usage.service.ts","../src/features/billing/stripe-usage/stripe-usage.module.ts","../src/features/company/data/company.ts","../src/features/company/data/company.fields.ts","../src/features/company/data/company.service.ts","../src/features/company/company.module.ts","../src/features/content/data/content.ts","../src/features/content/data/content.fields.ts","../src/features/content/data/content.service.ts","../src/features/content/content.module.ts","../src/features/feature/data/feature.ts","../src/features/feature/data/feature.service.ts","../src/features/feature/feature.module.ts","../src/features/module/data/module.ts","../src/features/module/module.module.ts","../src/features/notification/data/notification.ts","../src/features/notification/data/notification.fields.ts","../src/features/notification/data/notification.service.ts","../src/features/notification/notification.module.ts","../src/features/push/data/push.ts","../src/features/push/data/push.service.ts","../src/features/push/push.module.ts","../src/features/role/data/role.ts","../src/features/role/data/role.fields.ts","../src/features/role/data/role.service.ts","../src/features/role/role.module.ts","../src/features/s3/data/s3.ts","../src/features/s3/s3.module.ts","../src/features/s3/data/s3.service.ts","../src/features/user/data/user.ts","../src/features/user/data/user.fields.ts","../src/features/user/data/user.service.ts","../src/features/user/author.module.ts","../src/features/user/user.module.ts","../src/features/oauth/data/oauth.ts","../src/features/oauth/oauth.module.ts","../src/features/oauth/data/oauth.service.ts","../src/features/oauth/interfaces/oauth.interface.ts"],"names":["includedData","entity","relationshipMeta","HttpMethod","JsonApiGet","JsonApiPost","JsonApiDelete","ClientHttpMethod","globalErrorHandler","Action","AuthComponent","InvoiceStatus","SubscriptionStatus","CompanyFields","ContentFields","NotificationFields","RoleFields","UserFields"],"mappings":"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CqB,MAAA;AAC5B,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAM+B,EAAA;AACH,IAAA;AACV,MAAA;AACd,MAAA;AACc,MAAA;AACP,MAAA;AACa,QAAA;AACG,QAAA;AACP,QAAA;AAChB,MAAA;AAC0B,MAAA;AAC3B,IAAA;AAEM,IAAA;AACqB,MAAA;AAC5B,IAAA;AACF,EAAA;AACF;AxF20JiC;AACA;AyFv5JkC;AAC3D,EAAA;AACG,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACO,EAAA;AACE,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACoB,EAAA;AACX,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACqB,EAAA;AACZ,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACc,EAAA;AACL,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACe,EAAA;AACN,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACS,EAAA;AACA,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACO,EAAA;AACE,IAAA;AACD,IAAA;AACO,IAAA;AACP,IAAA;AACR,EAAA;AACF;AAKwD;AAKpB;AzFi5JH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-TSEU4KZ2.js","sourcesContent":[null,"import { ApiDataInterface } from \"../interfaces/ApiDataInterface\";\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { JsonApiHydratedDataInterface } from \"../interfaces/JsonApiHydratedDataInterface\";\nimport { DataClassRegistry } from \"../registry/DataClassRegistry\";\n\nexport class RehydrationFactory {\n public static rehydrate<T extends ApiDataInterface>(\n classKey: ApiRequestDataTypeInterface,\n data: JsonApiHydratedDataInterface,\n ): T {\n const factoryClass = DataClassRegistry.get(classKey);\n\n const instance = new factoryClass();\n return instance.rehydrate(data) as T;\n }\n\n public static rehydrateList<T extends ApiDataInterface>(\n classKey: ApiRequestDataTypeInterface,\n data: JsonApiHydratedDataInterface[],\n ): T[] {\n const factoryClass = DataClassRegistry.get(classKey);\n\n const response = data.map((item: JsonApiHydratedDataInterface) => {\n const instance = new factoryClass();\n return instance.rehydrate(item) as T;\n });\n\n return response;\n }\n}\n","import { RehydrationFactory } from \"../factories/RehydrationFactory\";\nimport { ApiDataInterface } from \"../interfaces/ApiDataInterface\";\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { JsonApiHydratedDataInterface } from \"../interfaces/JsonApiHydratedDataInterface\";\n\nexport abstract class AbstractApiData implements ApiDataInterface {\n protected _jsonApi?: any;\n protected _included?: any[];\n\n protected _id?: string;\n protected _type?: string;\n protected _createdAt?: Date;\n protected _updatedAt?: Date;\n\n protected _self?: string;\n\n get type(): string {\n if (!this._type) throw new Error(\"Type is not set.\");\n return this._type;\n }\n\n get id(): string {\n if (!this._id) throw new Error(\"Id is not set.\");\n return this._id;\n }\n\n get self(): string | undefined {\n return this._self;\n }\n\n get createdAt(): Date {\n return this._createdAt ?? new Date();\n }\n\n get updatedAt(): Date {\n return this._updatedAt ?? new Date();\n }\n\n get included(): any[] {\n return this._included ?? [];\n }\n\n get jsonApi(): any {\n return this._jsonApi;\n }\n\n ingestJsonApi(_data: JsonApiHydratedDataInterface): void {}\n\n generateApiUrl(_params?: any): string {\n throw new Error(\"Method not implemented.\");\n }\n\n createJsonApi(_data?: any): any {\n throw new Error(\"Method not implemented.\");\n }\n\n protected _readIncluded<T extends ApiDataInterface>(\n data: JsonApiHydratedDataInterface,\n type: string,\n dataType: ApiRequestDataTypeInterface,\n ): T | T[] | undefined {\n if (\n data.included === undefined ||\n data.included.length === 0 ||\n data.jsonApi.relationships === undefined ||\n data.jsonApi.relationships[type] === undefined ||\n data.jsonApi.relationships[type].data === undefined\n ) {\n return undefined;\n }\n\n if (Array.isArray(data.jsonApi.relationships[type].data)) {\n const response: T[] = data.jsonApi.relationships[type].data.map((jsonApiData: any) => {\n const includedData = data.included.find(\n (includedData: any) => includedData.id === jsonApiData.id && includedData.type === jsonApiData.type,\n );\n\n if (includedData === undefined) return undefined;\n\n return RehydrationFactory.rehydrate(dataType, {\n jsonApi: includedData,\n included: data.included,\n }) as T;\n });\n\n return response.filter((item: T | undefined) => item !== undefined) as T[];\n }\n\n const includedData = data.included.find(\n (includedData: any) =>\n includedData.id === data.jsonApi.relationships[type].data.id &&\n includedData.type === data.jsonApi.relationships[type].data.type,\n );\n\n if (includedData === undefined && data.allData !== undefined) {\n // Try to find in allData as a fallback\n const fallbackData = data.allData.find(\n (includedData: any) =>\n includedData.id === data.jsonApi.relationships[type].data.id &&\n includedData.type === data.jsonApi.relationships[type].data.type,\n );\n if (fallbackData !== undefined) {\n return RehydrationFactory.rehydrate(dataType, {\n jsonApi: fallbackData,\n included: data.included,\n }) as T;\n }\n }\n\n if (includedData === undefined) return undefined;\n\n return RehydrationFactory.rehydrate(dataType, {\n jsonApi: includedData,\n included: data.included,\n }) as T;\n }\n\n /**\n * Read included relationship data and augment with relationship meta properties.\n * Handles both single relationships (one-to-one) and array relationships (one-to-many).\n *\n * For single relationships: meta is read from `relationships[type].meta`\n * For array relationships: per-item meta is read from `relationships[type].data[].meta`\n *\n * @param data - Hydrated JSON:API data\n * @param type - Relationship type key (e.g., \"guide\", \"persons\")\n * @param dataType - Module reference for rehydration\n * @returns Related object(s) augmented with meta properties, or undefined\n */\n protected _readIncludedWithMeta<T extends ApiDataInterface, M extends Record<string, any>>(\n data: JsonApiHydratedDataInterface,\n type: string,\n dataType: ApiRequestDataTypeInterface,\n ): (T & M) | (T & M)[] | undefined {\n // Check if relationship exists\n if (\n data.included === undefined ||\n data.included.length === 0 ||\n data.jsonApi.relationships === undefined ||\n data.jsonApi.relationships[type] === undefined ||\n data.jsonApi.relationships[type].data === undefined\n ) {\n return undefined;\n }\n\n const relationshipData = data.jsonApi.relationships[type].data;\n\n // Handle array relationships with per-item meta\n if (Array.isArray(relationshipData)) {\n const result: (T & M)[] = [];\n\n for (const item of relationshipData) {\n const includedData = data.included.find((inc: any) => inc.id === item.id && inc.type === item.type);\n\n if (!includedData) continue;\n\n const entity = RehydrationFactory.rehydrate(dataType, {\n jsonApi: includedData,\n included: data.included,\n }) as T;\n\n // Merge per-item meta from relationships[type].data[].meta\n if (item.meta) {\n Object.assign(entity, item.meta);\n }\n\n result.push(entity as T & M);\n }\n\n return result;\n }\n\n // Handle single relationship\n const includedData = data.included.find(\n (inc: any) => inc.id === relationshipData.id && inc.type === relationshipData.type,\n );\n\n if (!includedData) {\n // Try to find in allData as a fallback\n if (data.allData !== undefined) {\n const fallbackData = data.allData.find(\n (inc: any) => inc.id === relationshipData.id && inc.type === relationshipData.type,\n );\n if (fallbackData) {\n const entity = RehydrationFactory.rehydrate(dataType, {\n jsonApi: fallbackData,\n included: data.included,\n }) as T;\n\n // Merge relationship-level meta for single relationships\n const relationshipMeta = data.jsonApi.relationships[type].meta;\n if (relationshipMeta) {\n Object.assign(entity, relationshipMeta);\n }\n return entity as T & M;\n }\n }\n return undefined;\n }\n\n const entity = RehydrationFactory.rehydrate(dataType, {\n jsonApi: includedData,\n included: data.included,\n }) as T;\n\n // Merge relationship-level meta for single relationships\n const relationshipMeta = data.jsonApi.relationships[type].meta;\n if (relationshipMeta) {\n Object.assign(entity, relationshipMeta);\n }\n\n return entity as T & M;\n }\n\n dehydrate(): JsonApiHydratedDataInterface {\n return {\n jsonApi: this._jsonApi,\n included: this._included ?? [],\n };\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n this._jsonApi = data.jsonApi;\n this._included = data.included;\n\n this._type = this._jsonApi.type;\n this._id = this._jsonApi.id;\n this._createdAt = this._jsonApi.meta?.createdAt !== undefined ? new Date(this._jsonApi.meta.createdAt) : undefined;\n this._updatedAt = this._jsonApi.meta?.updatedAt !== undefined ? new Date(this._jsonApi.meta.updatedAt) : undefined;\n\n this._self = this._jsonApi.links?.self ?? undefined;\n\n return this;\n }\n}\n","import { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { ApiResponseInterface } from \"../interfaces/ApiResponseInterface\";\n\nexport enum HttpMethod {\n GET = \"GET\",\n POST = \"POST\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n}\n\nexport interface NextRef {\n next?: string;\n}\n\nexport interface PreviousRef {\n previous?: string;\n}\n\nexport interface SelfRef {\n self?: string;\n}\n\nlet globalErrorHandler: ((status: number, message: string) => void) | null = null;\n\n/**\n * Set a global error handler for API errors (client-side only).\n * This handler will be called instead of throwing errors.\n */\nexport function setGlobalErrorHandler(handler: (status: number, message: string) => void) {\n globalErrorHandler = handler;\n}\n\n/**\n * Get the current global error handler.\n */\nexport function getGlobalErrorHandler(): ((status: number, message: string) => void) | null {\n return globalErrorHandler;\n}\n\n/**\n * Abstract base class for services that interact with the JSON:API.\n * Extend this class to create feature-specific services.\n */\nexport abstract class AbstractService {\n /**\n * Extract locale from client-side URL pathname\n * URL structure: /{locale}/route-path (e.g., /it/accounts)\n * Fallback chain: URL locale → navigator.language → \"en\"\n */\n private static getClientLocale(): string {\n if (typeof window === \"undefined\") {\n return \"en\"; // Server-side fallback\n }\n\n // Extract locale from URL pathname (first segment after leading slash)\n const pathSegments = window.location.pathname.split(\"/\").filter(Boolean);\n const urlLocale = pathSegments[0];\n\n // Validate against supported locales (currently only \"en\")\n const supportedLocales = [\"en\"];\n if (urlLocale && supportedLocales.includes(urlLocale)) {\n return urlLocale;\n }\n\n // Fallback to navigator language\n const navigatorLocale = navigator.language.split(\"-\")[0];\n if (navigatorLocale && supportedLocales.includes(navigatorLocale)) {\n return navigatorLocale;\n }\n\n // Final fallback\n return \"en\";\n }\n\n static async next<T>(params: {\n type: ApiRequestDataTypeInterface;\n endpoint: string;\n next?: NextRef;\n previous?: PreviousRef;\n self?: SelfRef;\n }): Promise<T> {\n return await this.callApi<T>({\n method: HttpMethod.GET,\n type: params.type,\n endpoint: params.endpoint,\n next: params.next,\n previous: params.previous,\n self: params.self,\n });\n }\n\n /**\n * Fetch the previous page of results.\n */\n static async previous<T>(params: {\n type: ApiRequestDataTypeInterface;\n endpoint: string;\n next?: NextRef;\n previous?: PreviousRef;\n self?: SelfRef;\n }): Promise<T> {\n return await this.callApi<T>({\n method: HttpMethod.GET,\n type: params.type,\n endpoint: params.endpoint,\n next: params.next,\n previous: params.previous,\n self: params.self,\n });\n }\n\n /**\n * Make an API call with automatic environment detection and error handling.\n */\n protected static async callApi<T>(params: {\n type: ApiRequestDataTypeInterface;\n method: HttpMethod;\n endpoint: string;\n companyId?: string;\n input?: any;\n overridesJsonApiCreation?: boolean;\n next?: NextRef;\n previous?: PreviousRef;\n self?: SelfRef;\n responseType?: ApiRequestDataTypeInterface;\n files?: { [key: string]: File | Blob } | File | Blob;\n }): Promise<T> {\n // Dynamic import to avoid bundling issues\n const { JsonApiGet, JsonApiPost, JsonApiPut, JsonApiPatch, JsonApiDelete } =\n await import(\"../../unified/JsonApiRequest\");\n\n let apiResponse: ApiResponseInterface;\n\n // Get language based on environment\n let language = \"en\";\n if (typeof window === \"undefined\") {\n const { getLocale } = await import(\"next-intl/server\");\n language = (await getLocale()) ?? \"en\";\n } else {\n // Client-side: extract locale from URL pathname\n language = this.getClientLocale();\n }\n\n switch (params.method) {\n case HttpMethod.GET:\n apiResponse = await JsonApiGet({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n });\n break;\n case HttpMethod.POST:\n apiResponse = await JsonApiPost({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.PUT:\n apiResponse = await JsonApiPut({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.PATCH:\n apiResponse = await JsonApiPatch({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.DELETE:\n apiResponse = await JsonApiDelete({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n responseType: params.responseType,\n });\n break;\n default:\n throw new Error(\"Method not found\");\n }\n\n if (!apiResponse.ok) {\n if (globalErrorHandler && typeof window !== \"undefined\") {\n globalErrorHandler(apiResponse.response, apiResponse.error);\n return undefined as any;\n } else {\n const error = new Error(`${apiResponse.error}`) as any;\n error.status = apiResponse.response;\n error.digest = `HTTP_${apiResponse.response}`;\n throw error;\n }\n }\n\n if (apiResponse.next && params.next) params.next.next = apiResponse.next;\n if (apiResponse.prev && params.previous) params.previous.previous = apiResponse.prev;\n if (apiResponse.self && params.self) params.self.self = apiResponse.self;\n\n return apiResponse.data as T;\n }\n\n /**\n * Make an API call and return both data and meta from the response.\n */\n protected static async callApiWithMeta<T>(params: {\n type: ApiRequestDataTypeInterface;\n method: HttpMethod;\n endpoint: string;\n companyId?: string;\n input?: any;\n overridesJsonApiCreation?: boolean;\n responseType?: ApiRequestDataTypeInterface;\n files?: { [key: string]: File | Blob } | File | Blob;\n }): Promise<{ data: T; meta?: Record<string, any> }> {\n // Dynamic import to avoid bundling issues\n const { JsonApiGet, JsonApiPost, JsonApiPut, JsonApiPatch, JsonApiDelete } =\n await import(\"../../unified/JsonApiRequest\");\n\n let apiResponse: ApiResponseInterface;\n\n // Get language based on environment\n let language = \"en\";\n if (typeof window === \"undefined\") {\n const { getLocale } = await import(\"next-intl/server\");\n language = (await getLocale()) ?? \"en\";\n } else {\n // Client-side: extract locale from URL pathname\n language = this.getClientLocale();\n }\n\n switch (params.method) {\n case HttpMethod.GET:\n apiResponse = await JsonApiGet({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n });\n break;\n case HttpMethod.POST:\n apiResponse = await JsonApiPost({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.PUT:\n apiResponse = await JsonApiPut({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.PATCH:\n apiResponse = await JsonApiPatch({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case HttpMethod.DELETE:\n apiResponse = await JsonApiDelete({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n responseType: params.responseType,\n });\n break;\n default:\n throw new Error(\"Method not found\");\n }\n\n if (!apiResponse.ok) {\n if (globalErrorHandler && typeof window !== \"undefined\") {\n globalErrorHandler(apiResponse.response, apiResponse.error);\n return { data: undefined as any, meta: undefined };\n } else {\n const error = new Error(`${apiResponse.error}`) as any;\n error.status = apiResponse.response;\n error.digest = `HTTP_${apiResponse.response}`;\n throw error;\n }\n }\n\n return {\n data: apiResponse.data as T,\n meta: apiResponse.meta,\n };\n }\n\n /**\n * Get raw JSON:API response data without deserialization.\n */\n protected static async getRawData(params: {\n type: ApiRequestDataTypeInterface;\n method: HttpMethod;\n endpoint: string;\n companyId?: string;\n }): Promise<any> {\n const { JsonApiGet } = await import(\"../../unified/JsonApiRequest\");\n\n let language = \"en\";\n\n if (typeof window === \"undefined\") {\n const { getLocale } = await import(\"next-intl/server\");\n language = (await getLocale()) ?? \"en\";\n } else {\n // Client-side: extract locale from URL pathname\n language = this.getClientLocale();\n }\n\n const apiResponse: ApiResponseInterface = await JsonApiGet({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n });\n\n if (!apiResponse.ok) {\n if (globalErrorHandler && typeof window !== \"undefined\") {\n globalErrorHandler(apiResponse.response, apiResponse.error);\n return undefined as any;\n } else {\n const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;\n error.status = apiResponse.response;\n error.digest = `HTTP_${apiResponse.response}`;\n throw error;\n }\n }\n\n return apiResponse.raw;\n }\n}\n","\"use client\";\n\nimport { JsonApiDataFactory } from \"../core/factories/JsonApiDataFactory\";\nimport { ApiRequestDataTypeInterface } from \"../core/interfaces/ApiRequestDataTypeInterface\";\nimport { ApiResponseInterface } from \"../core/interfaces/ApiResponseInterface\";\nimport { setBootstrapper } from \"../core/registry/bootstrapStore\";\nimport { translateResponse } from \"../core/utils/translateResponse\";\nimport { ModuleWithPermissions } from \"../permissions/types\";\nimport { directFetch } from \"./request\";\nimport { getClientToken } from \"./token\";\n\n// Config storage for client contexts\nlet _clientConfig: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n} | null = null;\n\n/**\n * Configure the JSON:API client for browser contexts.\n * Call this in your client-side initialization or use JsonApiProvider.\n */\nexport function configureClientJsonApi(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n}): void {\n _clientConfig = config;\n if (config.bootstrapper) {\n setBootstrapper(config.bootstrapper);\n config.bootstrapper();\n }\n}\n\nexport function getClientApiUrl(): string {\n if (_clientConfig?.apiUrl) {\n return _clientConfig.apiUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_API_URL;\n if (!envUrl) {\n throw new Error(\n \"API URL not configured. Use configureClientJsonApi() or set NEXT_PUBLIC_API_URL environment variable.\",\n );\n }\n return envUrl;\n}\n\nexport function getClientAppUrl(): string {\n if (_clientConfig?.appUrl) {\n return _clientConfig.appUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_ADDRESS;\n if (!envUrl) {\n throw new Error(\n \"App URL not configured. Use configureClientJsonApi({ appUrl }) or set NEXT_PUBLIC_ADDRESS environment variable.\",\n );\n }\n return envUrl.trim().replace(/\\/+$/, \"\");\n}\n\nexport function getClientTrackablePages(): ModuleWithPermissions[] {\n return _clientConfig?.trackablePages ?? [];\n}\n\nfunction runClientBootstrapper(): void {\n if (_clientConfig?.bootstrapper) {\n _clientConfig.bootstrapper();\n }\n}\n\nfunction buildClientUrl(endpoint: string): string {\n const apiUrl = getClientApiUrl();\n return endpoint.startsWith(\"http\") ? endpoint : `${apiUrl}${endpoint}`;\n}\n\nexport async function ClientJsonApiGet(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n}): Promise<ApiResponseInterface> {\n runClientBootstrapper();\n const token = await getClientToken();\n\n const apiResponse = await directFetch({\n method: \"GET\",\n url: buildClientUrl(params.endpoint),\n token,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _clientConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n paginationHandler: async (endpoint: string) =>\n ClientJsonApiGet({\n classKey: params.classKey,\n endpoint,\n companyId: params.companyId,\n language: params.language,\n }),\n });\n}\n\nexport async function ClientJsonApiPost(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n overridesJsonApiCreation?: boolean;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runClientBootstrapper();\n const token = await getClientToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await directFetch({\n method: \"POST\",\n url: buildClientUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _clientConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ClientJsonApiPut(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runClientBootstrapper();\n const token = await getClientToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await directFetch({\n method: \"PUT\",\n url: buildClientUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _clientConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ClientJsonApiPatch(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n overridesJsonApiCreation?: boolean;\n responseType?: ApiRequestDataTypeInterface;\n language: string;\n}): Promise<ApiResponseInterface> {\n runClientBootstrapper();\n const token = await getClientToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await directFetch({\n method: \"PATCH\",\n url: buildClientUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _clientConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ClientJsonApiDelete(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runClientBootstrapper();\n const token = await getClientToken();\n\n const apiResponse = await directFetch({\n method: \"DELETE\",\n url: buildClientUrl(params.endpoint),\n token,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _clientConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n","\"use client\";\n\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { ApiResponseInterface } from \"../interfaces/ApiResponseInterface\";\nimport {\n ClientJsonApiGet,\n ClientJsonApiPost,\n ClientJsonApiPut,\n ClientJsonApiPatch,\n ClientJsonApiDelete,\n} from \"../../client/JsonApiClient\";\n// Duplicated to avoid importing from AbstractService which pulls in server code\n// These are exported so client services can import them from here instead of core\nexport enum ClientHttpMethod {\n GET = \"GET\",\n POST = \"POST\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n}\n\nexport interface ClientNextRef {\n next?: string;\n}\n\nexport interface ClientPreviousRef {\n previous?: string;\n}\n\nexport interface ClientSelfRef {\n self?: string;\n}\n\nlet globalErrorHandler: ((status: number, message: string) => void) | null = null;\n\n/**\n * Set a global error handler for API errors (client-side only).\n * This handler will be called instead of throwing errors.\n */\nexport function setClientGlobalErrorHandler(handler: (status: number, message: string) => void) {\n globalErrorHandler = handler;\n}\n\n/**\n * Get the current global error handler.\n */\nexport function getClientGlobalErrorHandler(): ((status: number, message: string) => void) | null {\n return globalErrorHandler;\n}\n\n/**\n * Client-side abstract base class for services that interact with the JSON:API.\n * Use this for client components.\n */\nexport abstract class ClientAbstractService {\n /**\n * Extract locale from client-side URL pathname\n * URL structure: /{locale}/route-path (e.g., /it/accounts)\n * Fallback chain: URL locale → navigator.language → \"en\"\n */\n private static getClientLocale(): string {\n if (typeof window === \"undefined\") {\n return \"en\"; // Should not happen in client service\n }\n\n // Extract locale from URL pathname (first segment after leading slash)\n const pathSegments = window.location.pathname.split(\"/\").filter(Boolean);\n const urlLocale = pathSegments[0];\n\n // Validate against supported locales (currently only \"en\")\n const supportedLocales = [\"en\"];\n if (urlLocale && supportedLocales.includes(urlLocale)) {\n return urlLocale;\n }\n\n // Fallback to navigator language\n const navigatorLocale = navigator.language.split(\"-\")[0];\n if (navigatorLocale && supportedLocales.includes(navigatorLocale)) {\n return navigatorLocale;\n }\n\n // Final fallback\n return \"en\";\n }\n\n /**\n * Fetch the next page of results.\n */\n static async next<T>(params: {\n type: ApiRequestDataTypeInterface;\n endpoint: string;\n next?: ClientNextRef;\n previous?: ClientPreviousRef;\n self?: ClientSelfRef;\n }): Promise<T> {\n return await this.callApi<T>({\n method: ClientHttpMethod.GET,\n type: params.type,\n endpoint: params.endpoint,\n next: params.next,\n previous: params.previous,\n self: params.self,\n });\n }\n\n /**\n * Fetch the previous page of results.\n */\n static async previous<T>(params: {\n type: ApiRequestDataTypeInterface;\n endpoint: string;\n next?: ClientNextRef;\n previous?: ClientPreviousRef;\n self?: ClientSelfRef;\n }): Promise<T> {\n return await this.callApi<T>({\n method: ClientHttpMethod.GET,\n type: params.type,\n endpoint: params.endpoint,\n next: params.next,\n previous: params.previous,\n self: params.self,\n });\n }\n\n /**\n * Make a client-side API call.\n */\n protected static async callApi<T>(params: {\n type: ApiRequestDataTypeInterface;\n method: ClientHttpMethod;\n endpoint: string;\n companyId?: string;\n input?: any;\n overridesJsonApiCreation?: boolean;\n next?: ClientNextRef;\n previous?: ClientPreviousRef;\n self?: ClientSelfRef;\n responseType?: ApiRequestDataTypeInterface;\n files?: { [key: string]: File | Blob } | File | Blob;\n }): Promise<T> {\n let apiResponse: ApiResponseInterface;\n\n // Client-side: extract locale from URL pathname\n const language = this.getClientLocale();\n\n switch (params.method) {\n case ClientHttpMethod.GET:\n apiResponse = await ClientJsonApiGet({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n });\n break;\n case ClientHttpMethod.POST:\n apiResponse = await ClientJsonApiPost({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case ClientHttpMethod.PUT:\n apiResponse = await ClientJsonApiPut({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case ClientHttpMethod.PATCH:\n apiResponse = await ClientJsonApiPatch({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n body: params.input,\n overridesJsonApiCreation: params.overridesJsonApiCreation,\n language: language,\n responseType: params.responseType,\n files: params.files,\n });\n break;\n case ClientHttpMethod.DELETE:\n apiResponse = await ClientJsonApiDelete({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n responseType: params.responseType,\n });\n break;\n default:\n throw new Error(\"Method not found\");\n }\n\n if (!apiResponse.ok) {\n if (globalErrorHandler) {\n globalErrorHandler(apiResponse.response, apiResponse.error);\n return undefined as any;\n } else {\n const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;\n error.status = apiResponse.response;\n error.digest = `HTTP_${apiResponse.response}`;\n throw error;\n }\n }\n\n if (apiResponse.next && params.next) params.next.next = apiResponse.next;\n if (apiResponse.prev && params.previous) params.previous.previous = apiResponse.prev;\n if (apiResponse.self && params.self) params.self.self = apiResponse.self;\n\n return apiResponse.data as T;\n }\n\n /**\n * Get raw JSON:API response data without deserialization.\n */\n protected static async getRawData(params: {\n type: ApiRequestDataTypeInterface;\n method: ClientHttpMethod;\n endpoint: string;\n companyId?: string;\n }): Promise<any> {\n const language = this.getClientLocale();\n\n const apiResponse: ApiResponseInterface = await ClientJsonApiGet({\n classKey: params.type,\n endpoint: params.endpoint,\n companyId: params.companyId,\n language: language,\n });\n\n if (!apiResponse.ok) {\n if (globalErrorHandler) {\n globalErrorHandler(apiResponse.response, apiResponse.error);\n return undefined as any;\n } else {\n const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;\n error.status = apiResponse.response;\n error.digest = `HTTP_${apiResponse.response}`;\n throw error;\n }\n }\n\n return apiResponse.raw;\n }\n}\n","import { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { DataClassRegistry } from \"./DataClassRegistry\";\n\n/**\n * Helper class to bootstrap the registry from a Modules-style class.\n * This supports the pattern where modules are defined as static getters.\n */\nexport class ModuleRegistrar {\n private static _isBootstrapped = false;\n\n /**\n * Bootstrap the registry from a Modules class.\n * Automatically detects static getters and registers their models.\n *\n * @param modulesClass - The Modules class with static getters\n */\n static bootstrap<T extends object>(modulesClass: T): void {\n if (this._isBootstrapped) return;\n\n const data = Object.getOwnPropertyNames(modulesClass)\n .filter((key) => {\n const descriptor = Object.getOwnPropertyDescriptor(modulesClass, key);\n return descriptor && typeof descriptor.get === \"function\";\n })\n .map((key) => (modulesClass as any)[key] as ApiRequestDataTypeInterface);\n\n data.forEach((item) => {\n if (item && item.model) {\n DataClassRegistry.registerObjectClass(item, item.model);\n }\n });\n\n this._isBootstrapped = true;\n }\n\n /**\n * Reset the bootstrapped state. Useful for testing.\n */\n static reset(): void {\n this._isBootstrapped = false;\n DataClassRegistry.clear();\n }\n}\n","import { ModuleWithPermissions } from \"../../permissions/types\";\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { hasBootstrapper, tryBootstrap } from \"./bootstrapStore\";\n\n// Foundation module types - defined by LIBRARY\nexport interface FoundationModuleDefinitions {\n S3: ModuleWithPermissions;\n Auth: ModuleWithPermissions;\n User: ModuleWithPermissions;\n Author: ModuleWithPermissions;\n Company: ModuleWithPermissions;\n Role: ModuleWithPermissions;\n Notification: ModuleWithPermissions;\n Push: ModuleWithPermissions;\n Feature: ModuleWithPermissions;\n Module: ModuleWithPermissions;\n Content: ModuleWithPermissions;\n UserTopic: ModuleWithPermissions;\n UserExpertise: ModuleWithPermissions;\n // Billing modules - READ: all users, UPDATE: CompanyAdministrator, ADMIN: Administrator\n Billing: ModuleWithPermissions;\n StripeCustomer: ModuleWithPermissions;\n StripePaymentMethod: ModuleWithPermissions;\n StripeSubscription: ModuleWithPermissions;\n StripeInvoice: ModuleWithPermissions;\n StripeProduct: ModuleWithPermissions;\n StripePrice: ModuleWithPermissions;\n StripeUsage: ModuleWithPermissions;\n // OAuth modules\n OAuth: ModuleWithPermissions;\n}\n\n// App-specific modules - apps will augment this interface ONLY\n\nexport interface AppModuleDefinitions {}\n\n// Combined type for full autocompletion\nexport type ModuleDefinitions = FoundationModuleDefinitions & AppModuleDefinitions;\n\n// Symbol key to avoid conflicts with other globals\nconst MODULES_KEY = Symbol.for(\"nextjs-jsonapi:modules\");\n\n// Use globalThis to persist module registry across HMR reloads\nconst globalStore = globalThis as unknown as {\n [MODULES_KEY]?: Map<string, ApiRequestDataTypeInterface>;\n};\n\n// Initialize global modules map if not set\nif (!globalStore[MODULES_KEY]) {\n globalStore[MODULES_KEY] = new Map();\n}\n\nclass ModuleRegistryClass {\n private get _modules(): Map<string, ApiRequestDataTypeInterface> {\n return globalStore[MODULES_KEY]!;\n }\n\n register<K extends string>(name: K, module: ApiRequestDataTypeInterface): void {\n this._modules.set(name, module);\n }\n\n get<K extends keyof ModuleDefinitions>(name: K): ModuleDefinitions[K] {\n let module = this._modules.get(name as string);\n\n // Self-healing: if module not found, try bootstrapping first\n if (!module) {\n const didBootstrap = tryBootstrap();\n if (didBootstrap) {\n // Retry after bootstrap\n module = this._modules.get(name as string);\n }\n }\n\n if (!module) {\n // Provide helpful error message based on state\n const hint = hasBootstrapper()\n ? \"Bootstrap was called but module still not found. Check module registration.\"\n : \"No bootstrapper registered. Ensure configureJsonApi({ bootstrapper }) is called before accessing modules.\";\n throw new Error(`Module \"${String(name)}\" not registered. ${hint}`);\n }\n\n return module as ModuleDefinitions[K];\n }\n\n findByName(moduleName: string): ModuleWithPermissions {\n // Self-healing: try bootstrap if registry is empty\n if (this._modules.size === 0) {\n tryBootstrap();\n }\n\n // Search by module's name property (e.g., \"topics\", \"articles\")\n for (const module of this._modules.values()) {\n if ((module as ModuleWithPermissions).name === moduleName) {\n return module as ModuleWithPermissions;\n }\n }\n throw new Error(`Module not found: ${moduleName}`);\n }\n\n findByModelName(modelName: string): ModuleWithPermissions {\n // Direct lookup by registry key (e.g., \"Article\", \"Document\")\n let module = this._modules.get(modelName);\n\n // Self-healing: if not found, try bootstrapping\n if (!module) {\n const didBootstrap = tryBootstrap();\n if (didBootstrap) {\n module = this._modules.get(modelName);\n }\n }\n\n if (!module) {\n throw new Error(`Module not found for model: ${modelName}`);\n }\n return module as ModuleWithPermissions;\n }\n}\n\nexport const ModuleRegistry = new ModuleRegistryClass();\n\n// Proxy object for Modules.X syntax with autocompletion\nexport const Modules = new Proxy({} as ModuleDefinitions, {\n get(_, prop: string) {\n if (prop === \"findByName\") {\n return (name: string) => ModuleRegistry.findByName(name);\n }\n if (prop === \"findByModelName\") {\n return (name: string) => ModuleRegistry.findByModelName(name);\n }\n return ModuleRegistry.get(prop as keyof ModuleDefinitions);\n },\n}) as ModuleDefinitions & {\n findByName: (name: string) => ModuleWithPermissions;\n findByModelName: (name: string) => ModuleWithPermissions;\n};\n","import { FieldSelector } from \"../fields/FieldSelector\";\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\n\nexport type EndpointQuery = {\n endpoint: ApiRequestDataTypeInterface | string;\n id?: string;\n childEndpoint?: ApiRequestDataTypeInterface | string;\n childId?: string;\n additionalParams?: { key: string; value: string | string[] }[];\n};\n\nexport class EndpointCreator {\n private _endpoint: EndpointQuery;\n\n constructor(params: {\n endpoint: ApiRequestDataTypeInterface | string;\n id?: string;\n childEndpoint?: ApiRequestDataTypeInterface | string;\n childId?: string;\n additionalParams?: { key: string; value: string }[];\n }) {\n this._endpoint = {\n endpoint: params.endpoint,\n id: params.id,\n childEndpoint: params.childEndpoint,\n childId: params.childId,\n additionalParams: params.additionalParams ?? [],\n };\n }\n\n endpoint(value: ApiRequestDataTypeInterface | string): EndpointCreator {\n this._endpoint.endpoint = value;\n return this;\n }\n\n id(value: string): EndpointCreator {\n this._endpoint.id = value;\n return this;\n }\n\n childEndpoint(value: ApiRequestDataTypeInterface | string): EndpointCreator {\n this._endpoint.childEndpoint = value;\n return this;\n }\n\n childId(value: string): EndpointCreator {\n this._endpoint.childId = value;\n return this;\n }\n\n set additionalParams(value: { key: string; value: string }[]) {\n this._endpoint.additionalParams = value;\n }\n\n addAdditionalParam(key: string, value: string | string[]): EndpointCreator {\n if (!this._endpoint.additionalParams) this._endpoint.additionalParams = [];\n this._endpoint.additionalParams.push({ key, value });\n return this;\n }\n\n limitToType(selectors: string[]): this {\n this.addAdditionalParam(`include`, selectors.join(\",\"));\n return this;\n }\n\n limitToFields(selectors: FieldSelector<any>[]): this {\n if (selectors.length === 0) return this;\n\n selectors.forEach((selector) => {\n const fieldString = selector.fields.join(\",\");\n this.addAdditionalParam(`fields[${selector.type}]`, fieldString);\n });\n\n return this;\n }\n\n generate(): string {\n let additionalParams = \"\";\n if (this._endpoint.additionalParams) {\n additionalParams = this._endpoint.additionalParams.map((param) => `${param.key}=${param.value}`).join(\"&\");\n }\n\n let response = ``;\n response += `${\n typeof this._endpoint.endpoint === \"string\" ? this._endpoint.endpoint : this._endpoint.endpoint.name\n }`;\n if (this._endpoint.id) response += `/${this._endpoint.id}`;\n if (this._endpoint.childEndpoint) {\n response += `/${\n typeof this._endpoint.childEndpoint === \"string\"\n ? this._endpoint.childEndpoint\n : this._endpoint.childEndpoint.name\n }`;\n }\n if (this._endpoint.childId) response += `/${this._endpoint.childId}`;\n if (additionalParams) response += `?${additionalParams}`;\n\n return response;\n }\n}\n","export type GetterKeys<T> = {\n [K in keyof T]: T[K] extends () => any ? never : K;\n}[keyof T];\n\nexport type FieldSelector<T> = {\n type: string;\n fields: ReadonlyArray<GetterKeys<T>>;\n};\n\nexport function createJsonApiInclusion<T>(dataType: string, fields: ReadonlyArray<GetterKeys<T>>): FieldSelector<T> {\n return {\n type: dataType,\n fields,\n };\n}\n","import { ApiDataInterface } from \"../interfaces/ApiDataInterface\";\nimport { ApiRequestDataTypeInterface } from \"../interfaces/ApiRequestDataTypeInterface\";\nimport { JsonApiHydratedDataInterface } from \"../interfaces/JsonApiHydratedDataInterface\";\nimport { RehydrationFactory } from \"../factories/RehydrationFactory\";\n\n/**\n * Rehydrate a single dehydrated object back into its typed class instance.\n */\nexport function rehydrate<T extends ApiDataInterface>(\n classKey: ApiRequestDataTypeInterface,\n data: JsonApiHydratedDataInterface,\n): T {\n return RehydrationFactory.rehydrate(classKey, data) as T;\n}\n\n/**\n * Rehydrate a list of dehydrated objects back into typed class instances.\n */\nexport function rehydrateList<T extends ApiDataInterface>(\n classKey: ApiRequestDataTypeInterface,\n data: JsonApiHydratedDataInterface[],\n): T[] {\n return RehydrationFactory.rehydrateList(classKey, data) as T[];\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\ntype PossibleRef<T> = React.Ref<T> | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef<T>(ref: PossibleRef<T>, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs\n * Accepts callback refs and RefObject(s)\n */\nfunction useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n return React.useCallback(composeRefs(...refs), refs);\n}\n\nexport { composeRefs, useComposedRefs };\n","\"use client\";\n\nimport * as React from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener(\"change\", onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return !!isMobile;\n}\n","type FormatOption = \"date\" | \"time\" | \"dateTime\" | \"timeSince\" | \"default\";\n\nexport const formatDate = (eventDate: Date, formatOption: FormatOption, locale: string = \"en-GB\"): string => {\n const formatPart = (date: Date, options: Intl.DateTimeFormatOptions): string =>\n new Intl.DateTimeFormat(locale, options).format(date);\n\n const now = new Date();\n const diff = now.getTime() - eventDate.getTime();\n\n if (formatOption === \"default\") {\n if (diff < 24 * 60 * 60 * 1000) formatOption = \"timeSince\";\n else formatOption = \"dateTime\";\n }\n\n if (formatOption === \"timeSince\") {\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) return `${days} days ago`;\n if (hours > 0) return `${hours} hours ago`;\n if (minutes > 0) return `${minutes} minutes ago`;\n return `${seconds} seconds ago`;\n }\n\n // Define formatting options\n const dateOptions: Intl.DateTimeFormatOptions = {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n };\n const timeOptions: Intl.DateTimeFormatOptions = {\n hour: \"2-digit\",\n minute: \"2-digit\",\n };\n\n // Format based on the option\n switch (formatOption) {\n case \"date\":\n return formatPart(eventDate, dateOptions);\n case \"time\":\n return formatPart(eventDate, timeOptions);\n case \"dateTime\":\n return `${formatPart(eventDate, dateOptions)} ${formatPart(eventDate, timeOptions)}`;\n default:\n throw new Error(\"Invalid format option\");\n }\n};\n\nexport type { FormatOption };\n","export const exists = <T>(itemOrArray: T | T[] | null | undefined): boolean => {\n if (!itemOrArray) return false;\n if (Array.isArray(itemOrArray)) {\n return itemOrArray.length > 0;\n }\n return true;\n};\n","import { Action, ModuleWithPermissions } from \"../permissions\";\nimport { cloneElement, createElement, Fragment, ReactElement } from \"react\";\n\nexport class TableOptions {\n private _components: ReactElement<any>[];\n private _hasPermissionToModule: <M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }) => boolean;\n\n constructor(\n hasPermissionToModule: <M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }) => boolean,\n ) {\n this._hasPermissionToModule = hasPermissionToModule;\n this._components = [];\n }\n\n addOption<M extends ModuleWithPermissions>(component: ReactElement<any> | null, module?: M, action?: Action): void {\n if (!component || (module && action && !this._hasPermissionToModule({ module, action }))) return;\n this._components.push(component);\n }\n\n getComponents(): ReactElement<any>[] {\n return this._components;\n }\n\n getOptions(): ReactElement<any> | null {\n if (this._components.length === 0) return null;\n\n const response: ReactElement<any>[] = this._components.map((option, index) =>\n cloneElement(option, { key: option.key ?? index }),\n );\n\n return createElement(Fragment, {}, response);\n }\n}\n\nexport function getTableOptions(params: {\n hasPermissionToModule: <M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }) => boolean;\n options: { component: ReactElement<any> | null; module?: ModuleWithPermissions; action?: Action }[];\n}): ReactElement<any> | null {\n const tableOptions = new TableOptions(params.hasPermissionToModule);\n params.options.forEach((option) => tableOptions.addOption(option.component, option.module, option.action));\n return tableOptions.getOptions();\n}\n\nexport function getTableComponents(params: {\n hasPermissionToModule: <M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }) => boolean;\n options: { component: ReactElement<any> | null; module?: ModuleWithPermissions; action?: Action }[];\n}): ReactElement<any>[] {\n const tableOptions = new TableOptions(params.hasPermissionToModule);\n params.options.forEach((option) => tableOptions.addOption(option.component, option.module, option.action));\n return tableOptions.getComponents();\n}\n","import { z } from \"zod\";\n\nexport const userObjectSchema = z.object({\n id: z.string(),\n name: z.string(),\n avatar: z.string().optional(),\n});\n\nexport type UserObject = z.infer<typeof userObjectSchema>;\n","import { z } from \"zod\";\n\nexport const entityObjectSchema = z.object({\n id: z.uuidv4(),\n name: z.string(),\n});\n\nexport type EntityObject = z.infer<typeof entityObjectSchema>;\n","import { PartialBlock } from \"@blocknote/core\";\nimport { v4 } from \"uuid\";\n\nexport interface WordDiff {\n type: \"added\" | \"removed\" | \"unchanged\";\n text: string;\n diffId: string;\n accepted?: boolean;\n rejected?: boolean;\n}\n\nexport interface DiffBlock {\n id?: string;\n type?: string;\n props?: any;\n content?: any;\n children?: DiffBlock[];\n diffType?: \"added\" | \"removed\" | \"modified\" | \"unchanged\";\n originalContent?: any;\n diffId?: string;\n wordDiffs?: WordDiff[];\n accepted?: boolean;\n rejected?: boolean;\n}\n\nexport interface DiffResult {\n blocks: DiffBlock[];\n hasChanges: boolean;\n}\n\nexport interface BlockDiffOptions {\n ignoreIds?: boolean;\n compareContent?: boolean;\n similarityThreshold?: number;\n}\n\n/**\n * BlockNote Diff Utility\n * Implements a sophisticated diff algorithm for BlockNote document structures\n */\nexport class BlockNoteDiffUtil {\n private static readonly DEFAULT_OPTIONS: BlockDiffOptions = {\n ignoreIds: false,\n compareContent: true,\n similarityThreshold: 0.8,\n };\n\n /**\n * Compare two BlockNote documents and return diff result\n */\n static diff(\n originalBlocks: PartialBlock[] = [],\n newBlocks: PartialBlock[] = [],\n options: BlockDiffOptions = {},\n ): DiffResult {\n const opts = { ...this.DEFAULT_OPTIONS, ...options };\n\n // Create a map for efficient lookups\n const originalMap = new Map<string, PartialBlock>();\n const newMap = new Map<string, PartialBlock>();\n\n // Build maps based on block IDs\n originalBlocks.forEach((block) => {\n if (block.id) {\n originalMap.set(block.id, block);\n }\n });\n\n newBlocks.forEach((block) => {\n if (block.id) {\n newMap.set(block.id, block);\n }\n });\n\n const diffBlocks: DiffBlock[] = [];\n const processedNewIds = new Set<string>();\n\n // Process original blocks to find removed and modified blocks\n for (const originalBlock of originalBlocks) {\n const blockId = originalBlock.id;\n\n // Generate ID if missing\n const processId = blockId || v4();\n const newBlock = blockId ? newMap.get(blockId) : null;\n\n if (!newBlock) {\n // Block was removed\n const removedBlock: DiffBlock = {\n ...originalBlock,\n id: processId,\n diffType: \"removed\",\n diffId: `removed-${processId}`,\n };\n diffBlocks.push(removedBlock);\n } else {\n // Block exists in both, check for modifications\n if (blockId) {\n processedNewIds.add(blockId);\n }\n\n if (this.areBlocksEqual(originalBlock, newBlock, opts)) {\n // Block is unchanged\n const unchangedBlock: DiffBlock = {\n ...newBlock,\n diffType: \"unchanged\",\n };\n diffBlocks.push(unchangedBlock);\n } else {\n // Block was modified - perform word-level diff\n const wordDiffs = this.generateWordDiffs(originalBlock.content, newBlock.content, processId);\n const modifiedBlock: DiffBlock = {\n ...newBlock,\n diffType: \"modified\",\n originalContent: originalBlock.content as any,\n diffId: `modified-${processId}`,\n wordDiffs: wordDiffs,\n };\n diffBlocks.push(modifiedBlock);\n }\n }\n }\n\n // Process new blocks to find added blocks\n for (const newBlock of newBlocks) {\n const blockId = newBlock.id;\n\n // Skip if block was already processed (has ID and was found in original)\n if (blockId && processedNewIds.has(blockId)) continue;\n\n // This is a new block (either no ID or ID not found in original)\n const generatedId = blockId || crypto.randomUUID();\n const addedBlock: DiffBlock = {\n ...newBlock,\n id: generatedId,\n diffType: \"added\",\n diffId: `added-${generatedId}`,\n };\n diffBlocks.push(addedBlock);\n }\n\n // Sort blocks to maintain original order as much as possible\n const sortedDiffBlocks = this.sortDiffBlocks(diffBlocks, originalBlocks, newBlocks);\n\n return {\n blocks: sortedDiffBlocks,\n hasChanges: sortedDiffBlocks.some((block) => block.diffType !== \"unchanged\"),\n };\n }\n\n /**\n * Compare two blocks for equality\n */\n private static areBlocksEqual(block1: PartialBlock, block2: PartialBlock, options: BlockDiffOptions): boolean {\n // Compare block type\n if (block1.type !== block2.type) {\n return false;\n }\n\n // Compare props (excluding diffType specific props)\n if (!this.deepEqual(block1.props, block2.props)) {\n return false;\n }\n\n // Compare content if enabled\n if (options.compareContent) {\n if (!this.deepEqual(block1.content, block2.content)) {\n return false;\n }\n }\n\n // Compare children recursively\n const children1 = block1.children || [];\n const children2 = block2.children || [];\n\n if (children1.length !== children2.length) {\n return false;\n }\n\n for (let i = 0; i < children1.length; i++) {\n if (!this.areBlocksEqual(children1[i], children2[i], options)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Deep equality comparison for objects\n */\n private static deepEqual(obj1: any, obj2: any): boolean {\n if (obj1 === obj2) return true;\n\n if (obj1 == null || obj2 == null) return obj1 === obj2;\n\n if (typeof obj1 !== typeof obj2) return false;\n\n if (typeof obj1 !== \"object\") return obj1 === obj2;\n\n if (Array.isArray(obj1) !== Array.isArray(obj2)) return false;\n\n if (Array.isArray(obj1)) {\n if (obj1.length !== obj2.length) return false;\n for (let i = 0; i < obj1.length; i++) {\n if (!this.deepEqual(obj1[i], obj2[i])) return false;\n }\n return true;\n }\n\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!this.deepEqual(obj1[key], obj2[key])) return false;\n }\n\n return true;\n }\n\n /**\n * Sort diff blocks to maintain logical order\n */\n private static sortDiffBlocks(\n diffBlocks: DiffBlock[],\n originalBlocks: PartialBlock[],\n newBlocks: PartialBlock[],\n ): DiffBlock[] {\n // Create position maps\n const originalPositions = new Map<string, number>();\n const newPositions = new Map<string, number>();\n\n originalBlocks.forEach((block, index) => {\n if (block.id) {\n originalPositions.set(block.id, index);\n }\n });\n\n newBlocks.forEach((block, index) => {\n if (block.id) {\n newPositions.set(block.id, index);\n }\n });\n\n return diffBlocks.sort((a, b) => {\n const aId = a.id;\n const bId = b.id;\n\n if (!aId || !bId) return 0;\n\n // Prioritize by new positions, fallback to original positions\n const aPos = newPositions.get(aId) ?? originalPositions.get(aId) ?? Infinity;\n const bPos = newPositions.get(bId) ?? originalPositions.get(bId) ?? Infinity;\n\n return aPos - bPos;\n });\n }\n\n /**\n * Calculate similarity between two text contents\n */\n private static calculateSimilarity(content1: any[], content2: any[]): number {\n if (!content1 || !content2) return 0;\n\n const text1 = this.extractTextFromContent(content1);\n const text2 = this.extractTextFromContent(content2);\n\n if (text1 === text2) return 1;\n if (!text1 || !text2) return 0;\n\n // Simple Levenshtein distance-based similarity\n const maxLength = Math.max(text1.length, text2.length);\n const distance = this.levenshteinDistance(text1, text2);\n\n return 1 - distance / maxLength;\n }\n\n /**\n * Extract plain text from BlockNote content array\n */\n private static extractTextFromContent(content: any[]): string {\n if (!Array.isArray(content)) return \"\";\n\n return content\n .map((item) => {\n if (item.type === \"text\") {\n return item.text || \"\";\n }\n return \"\";\n })\n .join(\"\");\n }\n\n /**\n * Calculate Levenshtein distance between two strings\n */\n private static levenshteinDistance(str1: string, str2: string): number {\n const matrix = Array(str2.length + 1)\n .fill(null)\n .map(() => Array(str1.length + 1).fill(null));\n\n for (let i = 0; i <= str1.length; i++) {\n matrix[0][i] = i;\n }\n\n for (let j = 0; j <= str2.length; j++) {\n matrix[j][0] = j;\n }\n\n for (let j = 1; j <= str2.length; j++) {\n for (let i = 1; i <= str1.length; i++) {\n const substitutionCost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n matrix[j][i] = Math.min(\n matrix[j][i - 1] + 1, // deletion\n matrix[j - 1][i] + 1, // insertion\n matrix[j - 1][i - 1] + substitutionCost, // substitution\n );\n }\n }\n\n return matrix[str2.length][str1.length];\n }\n\n /**\n * Generate word-level diffs between two content arrays\n */\n static generateWordDiffs(originalContent: any, newContent: any, blockId: string): WordDiff[] {\n const originalText = this.extractTextFromContent(originalContent || []);\n const newText = this.extractTextFromContent(newContent || []);\n\n if (!originalText && !newText) return [];\n if (!originalText) {\n return newText\n .split(/\\s+/)\n .filter((word) => word.trim())\n .map((word, index) => ({\n type: \"added\" as const,\n text: word,\n diffId: `${blockId}-add-${index}`,\n accepted: false,\n rejected: false,\n }));\n }\n if (!newText) {\n return originalText\n .split(/\\s+/)\n .filter((word) => word.trim())\n .map((word, index) => ({\n type: \"removed\" as const,\n text: word,\n diffId: `${blockId}-remove-${index}`,\n accepted: false,\n rejected: false,\n }));\n }\n\n return this.diffWords(originalText, newText, blockId);\n }\n\n /**\n * Perform word-level diff using word-only approach (no space tokenization)\n */\n private static diffWords(text1: string, text2: string, blockId: string): WordDiff[] {\n const words1 = text1.split(/\\s+/).filter((word) => word.length > 0);\n const words2 = text2.split(/\\s+/).filter((word) => word.length > 0);\n\n const diffs = this.myersDiff(words1, words2);\n\n // Consolidate adjacent changes to reduce fragmentation\n const consolidatedDiffs = this.consolidateAdjacentChanges(diffs);\n\n const result: WordDiff[] = [];\n let diffIndex = 0;\n\n for (let i = 0; i < consolidatedDiffs.length; i++) {\n const diff = consolidatedDiffs[i];\n const isLastDiff = i === consolidatedDiffs.length - 1;\n\n switch (diff.type) {\n case \"equal\":\n result.push({\n type: \"unchanged\",\n text: diff.value,\n diffId: `${blockId}-unchanged-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n\n // Add space after word if not the last diff\n if (!isLastDiff) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n break;\n\n case \"delete\":\n // Check if this is a consolidated change or regular change\n if ((diff as any).consolidated) {\n // This is a consolidated deletion - check if next is consolidated insertion\n const nextDiff = i + 1 < consolidatedDiffs.length ? consolidatedDiffs[i + 1] : null;\n const isConsolidatedReplacement = nextDiff && nextDiff.type === \"insert\" && (nextDiff as any).consolidated;\n\n if (isConsolidatedReplacement) {\n // Use single shared diff ID for the entire consolidated change\n const replacementId = `${blockId}-replace-${diffIndex++}`;\n\n // Add the removed text\n result.push({\n type: \"removed\",\n text: diff.value,\n diffId: replacementId,\n accepted: false,\n rejected: false,\n });\n\n // Add the new text with same diff ID\n result.push({\n type: \"added\",\n text: nextDiff.value,\n diffId: replacementId,\n accepted: false,\n rejected: false,\n });\n\n // Skip the next insert since we handled it\n i++;\n\n // Add space after replacement if not the last\n if (i < consolidatedDiffs.length - 1) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n } else {\n // Consolidated deletion without replacement\n result.push({\n type: \"removed\",\n text: diff.value,\n diffId: `${blockId}-remove-${diffIndex++}`,\n accepted: false,\n rejected: false,\n });\n\n // Add space after deletion if not the last\n if (!isLastDiff) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n }\n } else {\n // Regular single-word processing\n const nextDiff = i + 1 < consolidatedDiffs.length ? consolidatedDiffs[i + 1] : null;\n const isReplacement =\n nextDiff && nextDiff.type === \"insert\" && this.areWordsSimilar(diff.value, nextDiff.value);\n\n if (isReplacement) {\n // Use single shared diff ID for both operations\n const replacementId = `${blockId}-replace-${diffIndex++}`;\n\n // Add the removed word\n result.push({\n type: \"removed\",\n text: diff.value,\n diffId: replacementId,\n accepted: false,\n rejected: false,\n });\n\n // Add the new word with same diff ID (no space between them)\n result.push({\n type: \"added\",\n text: nextDiff.value,\n diffId: replacementId,\n accepted: false,\n rejected: false,\n });\n\n // Skip the next insert since we handled it\n i++;\n\n // Add space after replacement if not the last\n if (i < consolidatedDiffs.length - 1) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n } else {\n // Regular deletion\n result.push({\n type: \"removed\",\n text: diff.value,\n diffId: `${blockId}-remove-${diffIndex++}`,\n accepted: false,\n rejected: false,\n });\n\n // Add space after deletion if not the last\n if (!isLastDiff) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n }\n }\n break;\n\n case \"insert\":\n // Only handle if not already processed as part of replacement or consolidation\n if ((diff as any).consolidated) {\n // This should have been handled in the delete case above\n const prevDiff = i > 0 ? consolidatedDiffs[i - 1] : null;\n const wasProcessedAsConsolidatedReplacement =\n prevDiff && prevDiff.type === \"delete\" && (prevDiff as any).consolidated;\n\n if (!wasProcessedAsConsolidatedReplacement) {\n // Standalone consolidated insertion\n result.push({\n type: \"added\",\n text: diff.value,\n diffId: `${blockId}-add-${diffIndex++}`,\n accepted: false,\n rejected: false,\n });\n\n // Add space after insertion if not the last\n if (!isLastDiff) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n }\n } else {\n // Regular single-word processing\n const prevDiff = i > 0 ? consolidatedDiffs[i - 1] : null;\n const wasProcessedAsReplacement =\n prevDiff && prevDiff.type === \"delete\" && this.areWordsSimilar(prevDiff.value, diff.value);\n\n if (!wasProcessedAsReplacement) {\n result.push({\n type: \"added\",\n text: diff.value,\n diffId: `${blockId}-add-${diffIndex++}`,\n accepted: false,\n rejected: false,\n });\n\n // Add space after insertion if not the last\n if (!isLastDiff) {\n result.push({\n type: \"unchanged\",\n text: \" \",\n diffId: `${blockId}-space-${diffIndex++}`,\n accepted: true,\n rejected: false,\n });\n }\n }\n }\n break;\n }\n }\n\n return result;\n } /**\n * Improved diff algorithm that better handles word insertions\n * Uses a combination of LCS and heuristics to minimize false changes\n */\n private static myersDiff(a: string[], b: string[]): Array<{ type: \"equal\" | \"delete\" | \"insert\"; value: string }> {\n if (a.length === 0) {\n return b.map((value) => ({ type: \"insert\" as const, value }));\n }\n if (b.length === 0) {\n return a.map((value) => ({ type: \"delete\" as const, value }));\n }\n\n // Use dynamic programming for optimal diff\n const dp = this.computeEditScript(a, b);\n return this.reconstructDiff(a, b, dp);\n }\n\n /**\n * Compute edit script using dynamic programming\n */\n private static computeEditScript(a: string[], b: string[]): number[][] {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array(m + 1)\n .fill(null)\n .map(() => Array(n + 1).fill(0));\n\n // Initialize base cases\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n // Fill the DP table\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i][j] = dp[i - 1][j - 1]; // No operation needed\n } else {\n dp[i][j] =\n 1 +\n Math.min(\n dp[i - 1][j], // Delete from a\n dp[i][j - 1], // Insert into a\n dp[i - 1][j - 1], // Replace\n );\n }\n }\n }\n\n return dp;\n }\n\n /**\n * Reconstruct the actual diff from the DP table\n */\n private static reconstructDiff(\n a: string[],\n b: string[],\n dp: number[][],\n ): Array<{ type: \"equal\" | \"delete\" | \"insert\"; value: string; sharedDiffId?: boolean }> {\n const result: Array<{ type: \"equal\" | \"delete\" | \"insert\"; value: string; sharedDiffId?: boolean }> = [];\n let i = a.length;\n let j = b.length;\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n // Equal\n result.unshift({ type: \"equal\", value: a[i - 1] });\n i--;\n j--;\n } else {\n // Determine the best operation with preference for insert/delete over replace\n const deleteCost = i > 0 ? dp[i - 1][j] : Infinity;\n const insertCost = j > 0 ? dp[i][j - 1] : Infinity;\n const replaceCost = i > 0 && j > 0 ? dp[i - 1][j - 1] : Infinity;\n\n const minCost = Math.min(deleteCost, insertCost, replaceCost);\n\n // Prefer insertions and deletions over replacements when costs are equal\n if (minCost === insertCost && j > 0) {\n // Insert\n result.unshift({ type: \"insert\", value: b[j - 1] });\n j--;\n } else if (minCost === deleteCost && i > 0) {\n // Delete\n result.unshift({ type: \"delete\", value: a[i - 1] });\n i--;\n } else if (minCost === replaceCost && i > 0 && j > 0) {\n // Only use replace for similar words, otherwise prefer separate operations\n if (this.areWordsSimilar(a[i - 1], b[j - 1])) {\n // Similar words - treat as replacement with shared diffId\n result.unshift({ type: \"insert\", value: b[j - 1], sharedDiffId: true });\n result.unshift({ type: \"delete\", value: a[i - 1], sharedDiffId: true });\n i--;\n j--;\n } else {\n // Different words - prefer insert over delete when costs are equal\n result.unshift({ type: \"insert\", value: b[j - 1] });\n j--;\n }\n }\n }\n }\n\n return result;\n }\n\n /**\n * Consolidate adjacent changes to reduce fragmentation\n * e.g., if we have: delete \"Key\", insert \"Key!\", delete \"Challenges\"\n * We can consolidate this into: replace [\"Key\", \"Challenges\"] with [\"Key!\"]\n */\n private static consolidateAdjacentChanges(\n diffs: Array<{ type: \"equal\" | \"delete\" | \"insert\"; value: string }>,\n ): Array<{ type: \"equal\" | \"delete\" | \"insert\"; value: string; consolidated?: boolean }> {\n const result = [];\n let i = 0;\n\n while (i < diffs.length) {\n const current = diffs[i];\n\n if (current.type === \"equal\") {\n result.push(current);\n i++;\n continue;\n }\n\n // Look for patterns of adjacent changes that can be consolidated\n const changeSequence = [];\n let j = i;\n\n // Collect adjacent non-equal changes\n while (j < diffs.length && diffs[j].type !== \"equal\") {\n changeSequence.push(diffs[j]);\n j++;\n }\n\n if (changeSequence.length <= 1) {\n // Single change, no consolidation needed\n result.push(current);\n i++;\n continue;\n }\n\n // Check if we should consolidate this sequence\n const shouldConsolidate = this.shouldConsolidateChanges(\n changeSequence as Array<{ type: \"delete\" | \"insert\"; value: string }>,\n );\n\n if (shouldConsolidate) {\n // Create consolidated changes\n const deletedWords = changeSequence.filter((c) => c.type === \"delete\").map((c) => c.value);\n const insertedWords = changeSequence.filter((c) => c.type === \"insert\").map((c) => c.value);\n\n if (deletedWords.length > 0) {\n result.push({\n type: \"delete\" as const,\n value: deletedWords.join(\" \"),\n consolidated: true,\n });\n }\n\n if (insertedWords.length > 0) {\n result.push({\n type: \"insert\" as const,\n value: insertedWords.join(\" \"),\n consolidated: true,\n });\n }\n } else {\n // Don't consolidate, add individual changes\n changeSequence.forEach((change) => result.push(change));\n }\n\n i = j;\n }\n\n return result;\n }\n\n /**\n * Determine if a sequence of changes should be consolidated\n */\n private static shouldConsolidateChanges(changes: Array<{ type: \"delete\" | \"insert\"; value: string }>): boolean {\n // Consolidate if we have both deletions and insertions in the same sequence\n const hasDeletes = changes.some((c) => c.type === \"delete\");\n const hasInserts = changes.some((c) => c.type === \"insert\");\n\n // Only consolidate if we have both types of changes (replacements/modifications)\n // Pure additions or pure deletions are fine as separate changes\n return hasDeletes && hasInserts;\n }\n\n /**\n * Check if two words are similar enough to be considered a replacement\n */\n private static areWordsSimilar(word1: string, word2: string): boolean {\n // If words are exactly the same, they're similar\n if (word1 === word2) return true;\n\n // Consider words similar if they share more than 70% of their characters\n const maxLen = Math.max(word1.length, word2.length);\n const minLen = Math.min(word1.length, word2.length);\n\n // If one word is much longer than the other, they're not similar\n if (maxLen > minLen * 2) {\n return false;\n }\n\n // Special case: if one word is just the other plus punctuation, treat as separate changes\n // e.g., \"Key\" and \"Key!\" should not be considered similar for replacement\n const word1Clean = word1.replace(/[^\\w]/g, \"\");\n const word2Clean = word2.replace(/[^\\w]/g, \"\");\n\n if (word1Clean === word2Clean && word1 !== word2) {\n // One word is just the other with added punctuation - don't treat as replacement\n return false;\n }\n\n // Calculate character overlap using Levenshtein distance\n const distance = this.levenshteinDistance(word1, word2);\n const similarity = 1 - distance / maxLen;\n\n return similarity > 0.7; // Increased threshold to be more conservative\n }\n}\n","import { PartialBlock } from \"@blocknote/core\";\nimport { v4 } from \"uuid\";\nimport { DiffBlock, WordDiff } from \"./blocknote-diff.util\";\n\nexport class BlockNoteWordDiffRendererUtil {\n static renderWordDiffs(\n diffBlocks: DiffBlock[],\n onAcceptChange?: (diffId: string) => void,\n onRejectChange?: (diffId: string) => void,\n acceptedChanges?: Set<string>,\n rejectedChanges?: Set<string>,\n ): PartialBlock[] {\n if (acceptedChanges || rejectedChanges) {\n diffBlocks = this.updateWordDiffStates(diffBlocks, acceptedChanges, rejectedChanges);\n }\n return diffBlocks.map((block) => this.renderDiffBlock(block, onAcceptChange, onRejectChange));\n }\n\n private static updateWordDiffStates(\n diffBlocks: DiffBlock[],\n acceptedChanges?: Set<string>,\n rejectedChanges?: Set<string>,\n ): DiffBlock[] {\n return diffBlocks.map((block) => {\n const updatedBlock = { ...block };\n\n if (updatedBlock.diffId) {\n updatedBlock.accepted = acceptedChanges?.has(updatedBlock.diffId) || false;\n updatedBlock.rejected = rejectedChanges?.has(updatedBlock.diffId) || false;\n }\n\n if (updatedBlock.wordDiffs) {\n updatedBlock.wordDiffs = updatedBlock.wordDiffs.map((wordDiff) => ({\n ...wordDiff,\n accepted: acceptedChanges?.has(wordDiff.diffId) || false,\n rejected: rejectedChanges?.has(wordDiff.diffId) || false,\n }));\n }\n\n if (updatedBlock.children) {\n updatedBlock.children = this.updateWordDiffStates(\n updatedBlock.children as DiffBlock[],\n acceptedChanges,\n rejectedChanges,\n );\n }\n\n return updatedBlock;\n });\n }\n\n private static renderDiffBlock(\n block: DiffBlock,\n onAcceptChange?: (diffId: string) => void,\n onRejectChange?: (diffId: string) => void,\n ): PartialBlock {\n if (block.diffType === \"modified\" && block.wordDiffs) {\n return this.renderWordLevelDiff(block, onAcceptChange, onRejectChange);\n }\n\n if (block.diffType === \"added\" || block.diffType === \"removed\") {\n return this.renderBlockLevelDiff(block, onAcceptChange, onRejectChange);\n }\n\n const baseBlock: PartialBlock = {\n id: block.id || v4(),\n type: (block.type as any) || \"paragraph\",\n props: this.getBlockProps(block),\n content: Array.isArray(block.content) ? block.content : [],\n children: block.children?.map((child) =>\n this.renderDiffBlock(child as DiffBlock, onAcceptChange, onRejectChange),\n ),\n };\n\n return baseBlock;\n }\n\n private static renderBlockLevelDiff(\n block: DiffBlock,\n onAcceptChange?: (diffId: string) => void,\n onRejectChange?: (diffId: string) => void,\n ): PartialBlock {\n if (!block.diffId) {\n return {\n id: block.id || v4(),\n type: (block.type as any) || \"paragraph\",\n props: block.props || {},\n content: Array.isArray(block.content) ? block.content : [],\n children: block.children?.map((child) =>\n this.renderDiffBlock(child as DiffBlock, onAcceptChange, onRejectChange),\n ),\n };\n }\n\n const blockAccepted = block.accepted || false;\n const blockRejected = block.rejected || false;\n\n let content = Array.isArray(block.content) ? [...block.content] : [];\n\n if (block.diffType === \"added\") {\n if (blockRejected) {\n return {\n id: block.id || v4(),\n type: \"paragraph\",\n props: {},\n content: [],\n children: [],\n };\n } else if (!blockAccepted) {\n content = content.map((item: any) => ({\n ...item,\n styles: { ...item.styles, bold: true },\n }));\n\n content.push({\n type: \"diffActions\",\n props: { diffIds: block.diffId },\n });\n }\n } else if (block.diffType === \"removed\") {\n if (blockAccepted) {\n return {\n id: block.id || v4(),\n type: \"paragraph\",\n props: {},\n content: [],\n children: [],\n };\n } else if (!blockRejected) {\n content = content.map((item: any) => ({\n ...item,\n styles: { ...item.styles, strike: true },\n }));\n\n content.push({\n type: \"diffActions\",\n props: { diffIds: block.diffId },\n });\n }\n }\n\n const baseBlock: PartialBlock = {\n id: block.id || v4(),\n type: (block.type as any) || \"paragraph\",\n props: this.getBlockProps(block),\n content: content,\n children: block.children?.map((child) =>\n this.renderDiffBlock(child as DiffBlock, onAcceptChange, onRejectChange),\n ),\n };\n\n return baseBlock;\n }\n\n private static renderWordLevelDiff(\n block: DiffBlock,\n onAcceptChange?: (diffId: string) => void,\n onRejectChange?: (diffId: string) => void,\n ): PartialBlock {\n if (!block.wordDiffs) {\n return {\n id: block.id || v4(),\n type: (block.type as any) || \"paragraph\",\n props: block.props || {},\n content: Array.isArray(block.content) ? block.content : [],\n children: [],\n };\n }\n\n const content = this.groupAndRenderWordDiffs(block.wordDiffs);\n\n return {\n id: block.id || v4(),\n type: (block.type as any) || \"paragraph\",\n props: block.props || {},\n content: Array.isArray(content) ? content : [],\n children:\n block.children?.map((child) => this.renderDiffBlock(child as DiffBlock, onAcceptChange, onRejectChange)) || [],\n };\n }\n\n private static groupAndRenderWordDiffs(wordDiffs: WordDiff[]): any[] {\n const content: any[] = [];\n\n for (let i = 0; i < wordDiffs.length; i++) {\n const wordDiff = wordDiffs[i];\n\n const isLastOfGroup = this.isLastDiffInGroup(wordDiffs, i);\n\n const textContent = this.createTextContent(wordDiff, isLastOfGroup);\n if (textContent) {\n if (Array.isArray(textContent)) {\n content.push(...textContent);\n } else {\n content.push(textContent);\n }\n }\n }\n\n const cleanedContent = this.cleanupSpaces(content);\n\n return cleanedContent;\n }\n\n private static cleanupSpaces(content: any[]): any[] {\n const filtered = content.filter((item) => item !== null && item !== undefined);\n\n const cleaned: any[] = [];\n\n for (let i = 0; i < filtered.length; i++) {\n const current = filtered[i];\n\n if (current.type === \"text\" && current.text === \" \") {\n const lastItem = cleaned[cleaned.length - 1];\n\n if (\n i === 0 ||\n i === filtered.length - 1 ||\n (lastItem && lastItem.type === \"text\" && lastItem.text === \" \") ||\n (lastItem && lastItem.type === \"diffActions\")\n ) {\n continue;\n }\n }\n\n if (current.type === \"diffActions\") {\n const nextItem = i + 1 < filtered.length ? filtered[i + 1] : null;\n\n cleaned.push(current);\n\n if (nextItem && nextItem.type === \"text\" && nextItem.text !== \" \" && nextItem.type !== \"diffActions\") {\n cleaned.push({\n type: \"text\",\n text: \" \",\n styles: {},\n });\n }\n\n continue;\n }\n\n cleaned.push(current);\n }\n\n return cleaned;\n }\n\n private static isLastDiffInGroup(wordDiffs: WordDiff[], currentIndex: number): boolean {\n const currentDiff = wordDiffs[currentIndex];\n\n if (currentDiff.type === \"unchanged\") {\n return false;\n }\n\n for (let i = currentIndex + 1; i < wordDiffs.length; i++) {\n const nextDiff = wordDiffs[i];\n\n if (nextDiff.diffId === currentDiff.diffId && (nextDiff.type === \"added\" || nextDiff.type === \"removed\")) {\n return false;\n }\n\n if (nextDiff.type !== \"unchanged\" && nextDiff.diffId !== currentDiff.diffId) {\n break;\n }\n }\n\n return true;\n }\n\n private static createTextContent(wordDiff: WordDiff, isLastOfGroup?: boolean): any[] | any {\n switch (wordDiff.type) {\n case \"added\":\n if (wordDiff.accepted) {\n return {\n type: \"text\",\n text: wordDiff.text,\n styles: {},\n };\n } else if (wordDiff.rejected) {\n return null;\n } else {\n if (wordDiff.text.trim() === \"\") {\n return {\n type: \"text\",\n text: wordDiff.text,\n styles: { backgroundColor: \"#dcfce7\" },\n };\n } else {\n const baseContent = {\n type: \"text\",\n text: wordDiff.text,\n styles: { bold: true },\n };\n\n if (isLastOfGroup) {\n return [\n baseContent,\n {\n type: \"diffActions\",\n props: { diffIds: wordDiff.diffId },\n },\n ];\n } else {\n return baseContent;\n }\n }\n }\n\n case \"removed\":\n if (wordDiff.accepted) {\n return null;\n } else if (wordDiff.rejected) {\n return {\n type: \"text\",\n text: wordDiff.text,\n styles: {},\n };\n } else {\n if (wordDiff.text.trim() === \"\") {\n return {\n type: \"text\",\n text: wordDiff.text,\n styles: { strike: true },\n };\n } else {\n const baseContent = {\n type: \"text\",\n text: wordDiff.text,\n styles: { strike: true },\n };\n\n if (isLastOfGroup) {\n return [\n baseContent,\n {\n type: \"diffActions\",\n props: { diffIds: wordDiff.diffId },\n },\n ];\n } else {\n return baseContent;\n }\n }\n }\n\n case \"unchanged\":\n default:\n return {\n type: \"text\",\n text: wordDiff.text,\n styles: {},\n };\n }\n }\n\n private static getBlockProps(block: DiffBlock): any {\n const baseProps = block.props || {};\n\n return baseProps;\n }\n\n static generateChangeSummary(diffBlocks: DiffBlock[]): {\n totalWords: number;\n addedWords: number;\n removedWords: number;\n acceptedChanges: number;\n rejectedChanges: number;\n pendingChanges: number;\n } {\n let totalWords = 0;\n let addedWords = 0;\n let removedWords = 0;\n let acceptedChanges = 0;\n let rejectedChanges = 0;\n let pendingChanges = 0;\n\n const processBlock = (block: DiffBlock) => {\n if (block.wordDiffs) {\n block.wordDiffs.forEach((wordDiff) => {\n totalWords++;\n\n if (wordDiff.type === \"added\") {\n addedWords++;\n } else if (wordDiff.type === \"removed\") {\n removedWords++;\n }\n\n if (wordDiff.accepted) {\n acceptedChanges++;\n } else if (wordDiff.rejected) {\n rejectedChanges++;\n } else if (wordDiff.type !== \"unchanged\") {\n pendingChanges++;\n }\n });\n }\n\n if (block.children) {\n block.children.forEach((child) => processBlock(child as DiffBlock));\n }\n };\n\n diffBlocks.forEach(processBlock);\n\n return {\n totalWords,\n addedWords,\n removedWords,\n acceptedChanges,\n rejectedChanges,\n pendingChanges,\n };\n }\n}\n","import { LucideIcon } from \"lucide-react\";\nimport { ReactNode } from \"react\";\nimport { ApiDataInterface, Modules } from \"../core\";\nimport { ContentInterface } from \"../features/content/data/content.interface\";\nimport { ModuleWithPermissions } from \"../permissions\";\nimport { cn } from \"./cn\";\n\nexport const getIconByModule = (params: { module: ModuleWithPermissions; className?: string }): ReactNode => {\n const IconComponent = getLucideIconByModule({ module: params.module });\n if (!IconComponent) return null;\n return <IconComponent className={cn(``, params.className)} />;\n};\n\nexport const getIcon = (params: { element: ApiDataInterface; className?: string }): ReactNode => {\n const IconComponent = getLucideIcon({ element: params.element });\n if (!IconComponent) return null;\n return <IconComponent className={cn(``, params.className)} />;\n};\n\nexport const getIconByModuleName = (params: { name: string; className?: string }): ReactNode => {\n return getIconByModule({ module: Modules.findByModelName(params.name), className: params.className });\n};\n\nexport const getLucideIcon = (params: { element: ApiDataInterface }): LucideIcon | null => {\n if (params.element.type === \"contents\") {\n const contentType = (params.element as ContentInterface).contentType;\n if (!contentType) return null;\n return getLucideIconByModule({ module: Modules.findByModelName(contentType) });\n }\n\n return getLucideIconByModule({ module: Modules.findByName(params.element.type) });\n};\n\nexport const getLucideIconByModule = (params: { module: ModuleWithPermissions }): LucideIcon | null => {\n return params.module.icon ?? null;\n};\n\nexport const getLucideIconByModuleName = (params: { name: string }): LucideIcon | null => {\n return getLucideIconByModule({ module: Modules.findByModelName(params.name) });\n};\n","import { LucideIcon } from \"lucide-react\";\nimport { ApiRequestDataTypeInterface } from \"../core/interfaces/ApiRequestDataTypeInterface\";\nimport { FieldSelector } from \"../core/fields/FieldSelector\";\n\n/**\n * Permission actions\n */\nexport enum Action {\n Read = \"read\",\n Create = \"create\",\n Update = \"update\",\n Delete = \"delete\",\n}\n\n/**\n * Generic permission check type.\n * Can be a boolean or a function that checks permissions dynamically.\n * @template T - The data type being checked\n * @template U - The user type (defaults to PermissionUser)\n */\nexport type PermissionCheck<T, U = PermissionUser> = boolean | ((user?: U | string, data?: T) => boolean);\n\n/**\n * Page URL configuration for modules\n */\nexport type PageUrl = {\n pageUrl?: string;\n};\n\n/**\n * Module permission definition wrapper\n */\nexport type ModulePermissionDefinition<T> = {\n interface: T;\n};\n\n/**\n * Base module definition\n */\nexport type ModuleDefinition = {\n pageUrl?: string;\n name: string;\n model: any;\n feature?: string;\n moduleId?: string;\n};\n\n/**\n * Permission configuration for a module.\n * Can be a boolean (allow/deny all) or a string path for dynamic checks.\n */\nexport interface PermissionConfig {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n}\n\n/**\n * Generic interface for a module that has permissions.\n * Apps should ensure their Module class implements this.\n */\nexport interface PermissionModule {\n id: string;\n permissions: PermissionConfig;\n}\n\n/**\n * Generic interface for a user that has modules with permissions.\n * Apps should ensure their User class implements this.\n */\nexport interface PermissionUser {\n id: string;\n modules: PermissionModule[];\n}\n\n/**\n * Module definition with permissions - extends ApiRequestDataTypeInterface\n */\nexport type ModuleWithPermissions = ApiRequestDataTypeInterface & {\n pageUrl?: string;\n feature?: string;\n moduleId?: string;\n icon?: LucideIcon;\n inclusions?: Record<\n string,\n {\n types?: string[];\n fields?: FieldSelector<any>[];\n }\n >;\n};\n\n/**\n * Factory type for creating module definitions\n */\nexport type ModuleFactory = (params: {\n pageUrl?: string;\n name: string;\n cache?: string | \"days\" | \"default\" | \"hours\" | \"max\" | \"minutes\" | \"seconds\" | \"weeks\";\n model: any;\n feature?: string;\n moduleId?: string;\n icon?: LucideIcon;\n inclusions?: Record<\n string,\n {\n types?: string[];\n fields?: FieldSelector<any>[];\n }\n >;\n}) => ModuleWithPermissions;\n","import { Action, ModuleWithPermissions, PermissionModule, PermissionUser } from \"./types\";\n\n/**\n * Check if a user has permission to perform an action on a module.\n *\n * @param module - The module to check permissions for\n * @param action - The action to check (read, create, update, delete)\n * @param user - The user with their modules and permissions\n * @param data - Optional data object for path-based permission checks\n */\nexport function checkPermissions<T extends PermissionUser>(params: {\n module: ModuleWithPermissions;\n action: Action;\n user: T;\n data?: any;\n}): boolean {\n const selectedModule = params.user.modules.find((module: PermissionModule) => module.id === params.module.moduleId);\n\n if (!selectedModule) return false;\n const permissionConfig = selectedModule.permissions[params.action];\n\n if (!permissionConfig) return false;\n if (typeof permissionConfig === \"boolean\") return permissionConfig as boolean;\n\n if (!params.data) return true;\n\n try {\n const singlePermissionConfig = permissionConfig.split(\"|\").map((p) => p.trim());\n\n for (const path of singlePermissionConfig) {\n if (getValueFromPath(params.data, path, params.user.id)) return true;\n }\n return false;\n } catch {\n if (typeof permissionConfig === \"string\") {\n return getValueFromPath(params.data, permissionConfig, params.user.id);\n }\n }\n\n return false;\n}\n\n/**\n * Check permissions from server context where user object is not fully available.\n *\n * @param module - The module to check permissions for\n * @param action - The action to check\n * @param userId - The user's ID\n * @param selectedModule - The selected module with its permissions\n * @param data - Optional data object for path-based permission checks\n */\nexport function checkPermissionsFromServer(params: {\n module: ModuleWithPermissions;\n action: Action;\n userId: string;\n selectedModule?: PermissionModule;\n data?: any;\n}): boolean {\n if (!params.selectedModule) return false;\n const permissionConfig = params.selectedModule.permissions[params.action];\n\n if (!permissionConfig) return false;\n if (typeof permissionConfig === \"boolean\") return permissionConfig as boolean;\n\n if (!params.data) return true;\n\n try {\n const singlePermissionConfig = permissionConfig.split(\"|\").map((p) => p.trim());\n\n for (const path of singlePermissionConfig) {\n if (getValueFromPath(params.data, path, params.userId)) return true;\n }\n return false;\n } catch {\n if (typeof permissionConfig === \"string\") {\n return getValueFromPath(params.data, permissionConfig, params.userId);\n }\n }\n\n return false;\n}\n\n/**\n * Traverse an object path and check if the value matches the user ID.\n * Handles nested objects, arrays, and various data structures.\n */\nexport function getValueFromPath(obj: any, path: string, userId: string): any {\n const parts = path.split(\".\");\n let current = obj;\n\n for (const part of parts) {\n if (!current) return false;\n\n if (Array.isArray(current)) {\n let found = false;\n for (const item of current) {\n const result = getValueFromPath(item, parts.slice(parts.indexOf(part)).join(\".\"), userId);\n if (result === userId || result === true) {\n found = true;\n break;\n }\n }\n return found;\n } else if (current[part] !== undefined) {\n current = current[part];\n } else {\n return false;\n }\n }\n\n if (Array.isArray(current)) {\n // If final value is an array, check if any element has id matching userId\n return current.some((item: any) => {\n if (typeof item === \"object\" && item.id !== undefined) {\n return item.id.toString() === userId;\n }\n return item.toString() === userId;\n });\n }\n\n // Direct comparison for primitive values or objects with id\n if (typeof current === \"object\" && current.id !== undefined) {\n return current.id.toString() === userId;\n }\n\n return current.toString() === userId;\n}\n","/**\n * Token parameters for authentication cookie management\n */\nexport interface TokenParams {\n token?: string;\n refreshToken?: string;\n userId?: string;\n companyId?: string;\n roles?: string[];\n features?: string[];\n modules?: {\n id: string;\n permissions: {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n };\n }[];\n}\n\n/**\n * Token handler interface for dependency injection\n * Apps must provide implementations of these functions via configureAuth()\n */\nexport interface TokenHandler {\n updateToken: (params: TokenParams) => Promise<void>;\n removeToken: () => Promise<void>;\n}\n\n// Private storage for the injected token handler\nlet _tokenHandler: TokenHandler | null = null;\n\n/**\n * Configure authentication token handling\n * Call this at app startup to provide Server Actions for cookie management\n *\n * @example\n * ```typescript\n * import { configureAuth } from \"@carlonicora/nextjs-jsonapi/features\";\n * import { updateToken, removeToken } from \"@/features/auth/utils/AuthCookies\";\n *\n * configureAuth({ updateToken, removeToken });\n * ```\n */\nexport function configureAuth(handler: TokenHandler): void {\n _tokenHandler = handler;\n}\n\n/**\n * Internal getter for AuthService to access the token handler\n * @internal\n */\nexport function getTokenHandler(): TokenHandler | null {\n return _tokenHandler;\n}\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { UserInterface } from \"../../user/data/user.interface\";\nimport { AuthInput, AuthInterface } from \"./auth.interface\";\n\nexport class Auth extends AbstractApiData implements AuthInterface {\n private _token?: string;\n private _refreshToken?: string;\n private _user?: UserInterface;\n\n get token(): string {\n if (!this._token) throw new Error(\"Token is not defined\");\n return this._token;\n }\n\n get refreshToken(): string {\n if (!this._refreshToken) throw new Error(\"Refresh token is not defined\");\n return this._refreshToken;\n }\n\n get user(): UserInterface {\n if (!this._user) throw new Error(\"User is not defined\");\n return this._user;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._token = data.jsonApi.attributes.token ?? undefined;\n this._refreshToken = data.jsonApi.attributes.refreshToken ?? undefined;\n\n this._user = this._readIncluded(data, \"user\", Modules.User) as UserInterface;\n\n return this;\n }\n\n createJsonApi(data: AuthInput) {\n const response: any = {\n data: {\n type: Modules.Auth.name,\n attributes: {},\n },\n };\n\n if (data.id) response.data.id = data.id;\n if (data.email !== undefined) response.data.attributes.email = data.email;\n if (data.name !== undefined) response.data.attributes.name = data.name;\n if (data.companyName !== undefined) response.data.attributes.companyName = data.companyName;\n if (data.password !== undefined) response.data.attributes.password = data.password;\n if (data.partitaIva !== undefined) response.data.attributes.partitaIva = data.partitaIva;\n if (data.codiceFiscale !== undefined) response.data.attributes.codiceFiscale = data.codiceFiscale;\n\n return response;\n }\n}\n","import { AuthInput, AuthInterface } from \".\";\nimport {\n AbstractService,\n ApiResponseInterface,\n EndpointCreator,\n HttpMethod,\n JsonApiHydratedDataInterface,\n Modules,\n rehydrate,\n} from \"../../../core\";\nimport { JsonApiDelete, JsonApiGet, JsonApiPost } from \"../../../unified\";\nimport { UserInterface } from \"../../user\";\nimport { getTokenHandler } from \"../config\";\n\nexport class AuthService extends AbstractService {\n static async login(params: { email: string; password: string; language?: string }): Promise<UserInterface> {\n const language = params.language || \"en-US\";\n\n const apiResponse: ApiResponseInterface = await JsonApiPost({\n classKey: Modules.Auth,\n endpoint: new EndpointCreator({ endpoint: Modules.Auth, id: \"login\" }).generate(),\n body: { email: params.email, password: params.password } as AuthInput,\n language: language,\n });\n\n if (!apiResponse.ok) throw new Error(apiResponse.error);\n\n const auth = apiResponse.data as AuthInterface;\n\n // Use injected token handler if configured\n const handler = getTokenHandler();\n if (handler) {\n await handler.updateToken({\n token: auth.token,\n refreshToken: auth.refreshToken,\n userId: auth.user.id,\n companyId: auth.user.company?.id,\n roles: auth.user.roles.map((role) => role.id),\n features: auth.user.company?.features?.map((feature) => feature.id) ?? [],\n modules: auth.user.modules.map((module) => ({\n id: module.id,\n permissions: module.permissions,\n })),\n });\n }\n\n return auth.user;\n }\n\n static async logout(params?: { language?: string }): Promise<void> {\n const language = params?.language || \"en-US\";\n\n await JsonApiDelete({\n classKey: Modules.Auth,\n endpoint: new EndpointCreator({ endpoint: Modules.Auth }).generate(),\n language: language,\n });\n\n // Use injected token handler if configured\n const handler = getTokenHandler();\n if (handler) {\n await handler.removeToken();\n }\n }\n\n static async initialiseForgotPassword(params: { email: string; language?: string }): Promise<void> {\n const language = params.language || \"en-US\";\n\n const response: ApiResponseInterface = await JsonApiPost({\n classKey: Modules.Auth,\n endpoint: new EndpointCreator({ endpoint: Modules.Auth, id: \"forgot\" }).generate(),\n body: { email: params.email } as AuthInput,\n language: language,\n });\n\n if (!response.ok) {\n throw new Error(response.error);\n }\n }\n\n static async register(params: AuthInput): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Auth, id: \"register\" });\n\n await this.callApi({\n type: Modules.Auth,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n static async activate(params: { activationCode: string }): Promise<void> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Auth,\n id: \"activate\",\n childEndpoint: params.activationCode,\n });\n\n await this.callApi({ type: Modules.Auth, method: HttpMethod.POST, endpoint: endpoint.generate() });\n }\n\n static async validateCode(params: { code: string; language?: string }): Promise<void> {\n const language = params.language || \"en-US\";\n\n const apiResponse: ApiResponseInterface = await JsonApiGet({\n classKey: Modules.Auth,\n endpoint: new EndpointCreator({ endpoint: Modules.Auth, id: \"validate\", childEndpoint: params.code }).generate(),\n language: language,\n });\n\n if (!apiResponse.ok) throw new Error(apiResponse.error);\n }\n\n static async resetPassword(params: { code: string; password: string }): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Auth, id: \"reset\", childEndpoint: params.code });\n\n const input: AuthInput = { password: params.password };\n\n await this.callApi({ type: Modules.Auth, method: HttpMethod.POST, endpoint: endpoint.generate(), input: input });\n }\n\n static async acceptInvitation(params: { code: string; password: string }): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Auth, id: \"invitation\", childEndpoint: params.code });\n\n const input: AuthInput = { password: params.password };\n\n await this.callApi({ type: Modules.Auth, method: HttpMethod.POST, endpoint: endpoint.generate(), input: input });\n }\n\n static async findToken(params: { tokenCode: string }): Promise<AuthInterface> {\n return await this.callApi<AuthInterface>({\n type: Modules.Auth,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: Modules.Auth }).addAdditionalParam(\"code\", params.tokenCode).generate(),\n });\n }\n\n static async saveToken(params: { dehydratedAuth: JsonApiHydratedDataInterface }): Promise<void> {\n const auth: AuthInterface = rehydrate(Modules.Auth, params.dehydratedAuth) as AuthInterface;\n\n const handler = getTokenHandler();\n if (handler) {\n await handler.updateToken({\n token: auth.token,\n refreshToken: auth.refreshToken,\n userId: auth.user.id,\n companyId: auth.user.company?.id,\n roles: auth.user.roles.map((role) => role.id),\n features: auth.user.company?.features?.map((feature) => feature.id) ?? [],\n modules: auth.user.modules.map((module) => ({\n id: module.id,\n permissions: module.permissions,\n })),\n });\n }\n }\n}\n","export enum AuthComponent {\n Login,\n ForgotPassword,\n ResetPassword,\n ActivateAccount,\n AcceptInvitation,\n Register,\n Landing,\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Auth } from \".\";\n\nexport const AuthModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/auth\",\n name: \"auth\",\n model: Auth,\n });\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../core\";\n\n// Import from new sub-modules for backwards compatibility re-exports\nimport { MeterInterface, MeterSummaryInterface } from \"../stripe-usage/data/stripe-usage.interface\";\n\n/**\n * Legacy billing service - only contains meter methods\n * @deprecated Use StripeUsageService for meter methods, StripeInvoiceService for invoices,\n * StripeCustomerService for payment methods\n */\nexport class BillingService extends AbstractService {\n // ============================================================================\n // Meter Methods (kept here for backwards compatibility)\n // ============================================================================\n\n /**\n * List all available usage meters\n * @deprecated Use StripeUsageService.listMeters() instead\n */\n static async listMeters(params?: { next?: NextRef; prev?: PreviousRef }): Promise<MeterInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n childEndpoint: \"meters\",\n });\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get meter summaries for a specific time period\n * @deprecated Use StripeUsageService.getMeterSummaries() instead\n */\n static async getMeterSummaries(params: {\n meterId: string;\n startTime: Date;\n endTime: Date;\n }): Promise<MeterSummaryInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n childEndpoint: `meters/${params.meterId}/summaries`,\n });\n\n endpoint.addAdditionalParam(\"startTime\", params.startTime.toISOString());\n endpoint.addAdditionalParam(\"endTime\", params.endTime.toISOString());\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { AbstractApiData, JsonApiHydratedDataInterface } from \"../../../core\";\n\n/**\n * Billing is a namespace module used for permissions and non-entity endpoints.\n * It doesn't correspond to a specific backend entity but provides routing for\n * meter-related endpoints and permission checks.\n */\nexport class Billing extends AbstractApiData {\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n return this;\n }\n\n createJsonApi(_data?: any): any {\n throw new Error(\"Billing is a namespace module and cannot be created\");\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { Billing } from \"../data/Billing\";\n\nexport const BillingModule = (factory: ModuleFactory) =>\n factory({\n name: \"billing\",\n model: Billing,\n moduleId: \"3266b307-5a9a-46f9-b78d-631f672f8735\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface } from \"../../../../core\";\nimport { PaymentMethodInterface } from \"./payment-method.interface\";\n\n/**\n * PaymentMethod class for JSON:API rehydration\n *\n * Transforms flat JSON:API attributes into the nested PaymentMethodInterface structure\n * expected by the frontend components.\n */\nexport class PaymentMethod extends AbstractApiData implements PaymentMethodInterface {\n private _paymentType?: string;\n private _card?: {\n brand: string;\n last4: string;\n expMonth: number;\n expYear: number;\n };\n private _billingDetails?: {\n name?: string;\n email?: string;\n phone?: string;\n address?: {\n city?: string;\n country?: string;\n line1?: string;\n line2?: string;\n postalCode?: string;\n state?: string;\n };\n };\n\n get type(): string {\n if (!this._paymentType) throw new Error(\"type is not defined\");\n return this._paymentType;\n }\n\n get card():\n | {\n brand: string;\n last4: string;\n expMonth: number;\n expYear: number;\n }\n | undefined {\n return this._card;\n }\n\n get billingDetails():\n | {\n name?: string;\n email?: string;\n phone?: string;\n address?: {\n city?: string;\n country?: string;\n line1?: string;\n line2?: string;\n postalCode?: string;\n state?: string;\n };\n }\n | undefined {\n return this._billingDetails;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n const attrs = data.jsonApi.attributes;\n\n this._paymentType = attrs.type;\n\n // Build card object from flat attributes\n if (attrs.brand || attrs.last4 || attrs.expMonth || attrs.expYear) {\n this._card = {\n brand: attrs.brand,\n last4: attrs.last4,\n expMonth: attrs.expMonth,\n expYear: attrs.expYear,\n };\n }\n\n // Build billingDetails object from flat attributes\n const hasAddress =\n attrs.billingAddressCity ||\n attrs.billingAddressCountry ||\n attrs.billingAddressLine1 ||\n attrs.billingAddressLine2 ||\n attrs.billingAddressPostalCode ||\n attrs.billingAddressState;\n\n const hasBillingDetails = attrs.billingName || attrs.billingEmail || attrs.billingPhone || hasAddress;\n\n if (hasBillingDetails) {\n this._billingDetails = {\n name: attrs.billingName ?? undefined,\n email: attrs.billingEmail ?? undefined,\n phone: attrs.billingPhone ?? undefined,\n };\n\n if (hasAddress) {\n this._billingDetails.address = {\n city: attrs.billingAddressCity ?? undefined,\n country: attrs.billingAddressCountry ?? undefined,\n line1: attrs.billingAddressLine1 ?? undefined,\n line2: attrs.billingAddressLine2 ?? undefined,\n postalCode: attrs.billingAddressPostalCode ?? undefined,\n state: attrs.billingAddressState ?? undefined,\n };\n }\n }\n\n return this;\n }\n\n createJsonApi(_data?: any): any {\n throw new Error(\"PaymentMethod is managed by Stripe and cannot be created directly\");\n }\n}\n","import { AbstractApiData, JsonApiHydratedDataInterface } from \"../../../../core\";\nimport { StripeCustomerInterface } from \"./stripe-customer.interface\";\n\nexport class StripeCustomer extends AbstractApiData implements StripeCustomerInterface {\n private _stripeCustomerId?: string;\n private _email?: string;\n private _name?: string;\n private _defaultPaymentMethodId?: string;\n private _currency?: string;\n private _balance?: number;\n private _delinquent: boolean = false;\n private _metadata?: Record<string, any>;\n\n get stripeCustomerId(): string {\n if (!this._stripeCustomerId) throw new Error(\"stripeCustomerId is not defined\");\n return this._stripeCustomerId;\n }\n\n get email(): string | undefined {\n return this._email;\n }\n\n get name(): string | undefined {\n return this._name;\n }\n\n get defaultPaymentMethodId(): string | undefined {\n return this._defaultPaymentMethodId;\n }\n\n get currency(): string | undefined {\n return this._currency;\n }\n\n get balance(): number | undefined {\n return this._balance;\n }\n\n get delinquent(): boolean {\n return this._delinquent;\n }\n\n get metadata(): Record<string, any> | undefined {\n return this._metadata;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._stripeCustomerId = data.jsonApi.attributes.stripeCustomerId;\n this._email = data.jsonApi.attributes.email;\n this._name = data.jsonApi.attributes.name;\n this._defaultPaymentMethodId = data.jsonApi.attributes.defaultPaymentMethodId;\n this._currency = data.jsonApi.attributes.currency;\n this._balance = data.jsonApi.attributes.balance;\n this._delinquent = data.jsonApi.attributes.delinquent ?? false;\n\n // Parse metadata if it's a string (backend stores as JSON string)\n this._metadata = data.jsonApi.attributes.metadata\n ? typeof data.jsonApi.attributes.metadata === \"string\"\n ? JSON.parse(data.jsonApi.attributes.metadata)\n : data.jsonApi.attributes.metadata\n : undefined;\n\n return this;\n }\n\n createJsonApi(_data?: any): any {\n throw new Error(\"BillingCustomer is managed by Stripe and cannot be created directly\");\n }\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport { PaymentMethodInterface } from \"./payment-method.interface\";\nimport { StripeCustomerInterface } from \"./stripe-customer.interface\";\n\n/**\n * Customer-facing billing service for managing subscriptions, payments, and usage\n */\nexport class StripeCustomerService extends AbstractService {\n // ============================================================================\n // Customer Methods\n // ============================================================================\n\n /**\n * Get the current user's billing customer record\n */\n static async getCustomer(): Promise<StripeCustomerInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeCustomer,\n });\n\n return this.callApi<StripeCustomerInterface>({\n type: Modules.StripeCustomer,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a billing customer for the current user\n */\n static async createCustomer(): Promise<StripeCustomerInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeCustomer,\n });\n\n return this.callApi<StripeCustomerInterface>({\n type: Modules.StripeCustomer,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a setup intent for adding payment methods\n */\n static async createSetupIntent(): Promise<{ clientSecret: string }> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Billing,\n childEndpoint: \"setup-intent\",\n });\n\n return this.callApi({\n type: Modules.Billing,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a Stripe customer portal session URL\n */\n static async createPortalSession(): Promise<{ url: string }> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Billing,\n childEndpoint: \"customers/portal-session\",\n });\n\n return this.callApi({\n type: Modules.Billing,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n // ============================================================================\n // Payment Method Methods\n // ============================================================================\n\n /**\n * List all payment methods for the current user\n */\n static async listPaymentMethods(params?: { next?: NextRef; prev?: PreviousRef }): Promise<PaymentMethodInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeCustomer,\n childEndpoint: \"payment-methods\",\n });\n\n return this.callApi({\n type: Modules.StripePaymentMethod,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Set the default payment method for the current user\n */\n static async setDefaultPaymentMethod(params: { paymentMethodId: string }): Promise<StripeCustomerInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeCustomer,\n childEndpoint: `payment-methods/${params.paymentMethodId}/default`,\n });\n\n return this.callApi<StripeCustomerInterface>({\n type: Modules.StripeCustomer,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Remove a payment method\n */\n static async removePaymentMethod(params: { paymentMethodId: string }): Promise<void> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeCustomer,\n childEndpoint: `payment-methods/${params.paymentMethodId}`,\n });\n\n await this.callApi({\n type: Modules.StripeCustomer,\n method: HttpMethod.DELETE,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripeCustomer } from \"./data\";\n\nexport const StripeCustomerModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-customers\",\n model: StripeCustomer,\n moduleId: \"25a80cb3-bf18-47fd-963a-639212519920\",\n });\n","import { ModuleFactory } from \"../../../permissions\";\nimport { PaymentMethod } from \"./data/payment-method\";\n\nexport const StripePaymentMethodModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-payment-methods\",\n model: PaymentMethod,\n moduleId: \"e8f7d6c5-b4a3-4928-8170-1f2e3d4c5b6a\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules, StripeSubscriptionInterface } from \"../../../../core\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"./stripe-invoice.interface\";\n\nexport class StripeInvoice extends AbstractApiData implements StripeInvoiceInterface {\n private _stripeInvoiceId?: string;\n private _stripeInvoiceNumber?: string;\n private _customerId?: string;\n private _subscriptionId?: string;\n private _subscription?: StripeSubscriptionInterface;\n private _status?: InvoiceStatus;\n private _amountDue?: number;\n private _amountPaid?: number;\n private _amountRemaining?: number;\n private _subtotal?: number;\n private _total?: number;\n private _tax?: number;\n private _currency?: string;\n private _periodStart?: Date;\n private _periodEnd?: Date;\n private _dueDate?: Date;\n private _paidAt?: Date;\n private _attemptCount: number = 0;\n private _attempted: boolean = false;\n private _stripeHostedInvoiceUrl?: string;\n private _stripePdfUrl?: string;\n private _paid: boolean = false;\n private _metadata?: Record<string, any>;\n\n get stripeInvoiceId(): string {\n if (!this._stripeInvoiceId) throw new Error(\"stripeInvoiceId is not defined\");\n return this._stripeInvoiceId;\n }\n\n get stripeInvoiceNumber(): string | undefined {\n return this._stripeInvoiceNumber;\n }\n\n get customerId(): string | undefined {\n return this._customerId;\n }\n\n get subscriptionId(): string | undefined {\n return this._subscriptionId;\n }\n\n get subscription(): StripeSubscriptionInterface | undefined {\n return this._subscription;\n }\n\n get status(): InvoiceStatus {\n if (!this._status) throw new Error(\"status is not defined\");\n return this._status;\n }\n\n get amountDue(): number {\n if (this._amountDue === undefined) throw new Error(\"amountDue is not defined\");\n return this._amountDue;\n }\n\n get amountPaid(): number {\n if (this._amountPaid === undefined) throw new Error(\"amountPaid is not defined\");\n return this._amountPaid;\n }\n\n get amountRemaining(): number {\n if (this._amountRemaining === undefined) throw new Error(\"amountRemaining is not defined\");\n return this._amountRemaining;\n }\n\n get subtotal(): number {\n if (this._subtotal === undefined) throw new Error(\"subtotal is not defined\");\n return this._subtotal;\n }\n\n get total(): number {\n if (this._total === undefined) throw new Error(\"total is not defined\");\n return this._total;\n }\n\n get tax(): number | undefined {\n return this._tax;\n }\n\n get currency(): string {\n if (!this._currency) throw new Error(\"currency is not defined\");\n return this._currency;\n }\n\n get periodStart(): Date {\n if (!this._periodStart) throw new Error(\"periodStart is not defined\");\n return this._periodStart;\n }\n\n get periodEnd(): Date {\n if (!this._periodEnd) throw new Error(\"periodEnd is not defined\");\n return this._periodEnd;\n }\n\n get dueDate(): Date | undefined {\n return this._dueDate;\n }\n\n get paidAt(): Date | undefined {\n return this._paidAt;\n }\n\n get attemptCount(): number {\n return this._attemptCount;\n }\n\n get attempted(): boolean {\n return this._attempted;\n }\n\n get stripeHostedInvoiceUrl(): string | undefined {\n return this._stripeHostedInvoiceUrl;\n }\n\n get stripePdfUrl(): string | undefined {\n return this._stripePdfUrl;\n }\n\n get paid(): boolean {\n return this._paid;\n }\n\n get metadata(): Record<string, any> | undefined {\n return this._metadata;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._stripeInvoiceId = data.jsonApi.attributes.stripeInvoiceId;\n this._stripeInvoiceNumber = data.jsonApi.attributes.stripeInvoiceNumber;\n this._customerId = data.jsonApi.attributes.customerId;\n this._subscriptionId = data.jsonApi.attributes.subscriptionId;\n this._status = data.jsonApi.attributes.status;\n this._amountDue = data.jsonApi.attributes.amountDue;\n this._amountPaid = data.jsonApi.attributes.amountPaid;\n this._amountRemaining = data.jsonApi.attributes.amountRemaining;\n this._subtotal = data.jsonApi.attributes.subtotal;\n this._total = data.jsonApi.attributes.total;\n this._tax = data.jsonApi.attributes.tax;\n this._currency = data.jsonApi.attributes.currency;\n\n this._periodStart = data.jsonApi.attributes.periodStart ? new Date(data.jsonApi.attributes.periodStart) : undefined;\n this._periodEnd = data.jsonApi.attributes.periodEnd ? new Date(data.jsonApi.attributes.periodEnd) : undefined;\n this._dueDate = data.jsonApi.attributes.dueDate ? new Date(data.jsonApi.attributes.dueDate) : undefined;\n this._paidAt = data.jsonApi.attributes.paidAt ? new Date(data.jsonApi.attributes.paidAt) : undefined;\n\n this._attemptCount = data.jsonApi.attributes.attemptCount ?? 0;\n this._attempted = data.jsonApi.attributes.attempted ?? false;\n this._stripeHostedInvoiceUrl = data.jsonApi.attributes.stripeHostedInvoiceUrl;\n this._stripePdfUrl = data.jsonApi.attributes.stripePdfUrl;\n this._paid = data.jsonApi.attributes.paid ?? false;\n\n this._metadata = data.jsonApi.attributes.metadata\n ? typeof data.jsonApi.attributes.metadata === \"string\"\n ? JSON.parse(data.jsonApi.attributes.metadata)\n : data.jsonApi.attributes.metadata\n : undefined;\n\n // Hydrate subscription relationship\n this._subscription = this._readIncluded(\n data,\n \"subscription\",\n Modules.StripeSubscription,\n ) as StripeSubscriptionInterface;\n\n return this;\n }\n\n createJsonApi(_data?: any): any {\n throw new Error(\"Invoice is managed by Stripe and cannot be created directly\");\n }\n}\n","import { ApiDataInterface, StripeSubscriptionInterface } from \"../../../../core\";\n\n// ============================================================================\n// Invoice Enums\n// ============================================================================\n\nexport enum InvoiceStatus {\n DRAFT = \"draft\",\n OPEN = \"open\",\n PAID = \"paid\",\n UNCOLLECTIBLE = \"uncollectible\",\n VOID = \"void\",\n}\n\n// ============================================================================\n// Invoice Interfaces\n// ============================================================================\n\nexport interface StripeInvoiceInterface extends ApiDataInterface {\n get stripeInvoiceId(): string;\n get stripeInvoiceNumber(): string | undefined;\n get customerId(): string | undefined;\n get subscriptionId(): string | undefined;\n get subscription(): StripeSubscriptionInterface | undefined;\n get status(): InvoiceStatus;\n get amountDue(): number;\n get amountPaid(): number;\n get amountRemaining(): number;\n get subtotal(): number;\n get total(): number;\n get tax(): number | undefined;\n get currency(): string;\n get periodStart(): Date;\n get periodEnd(): Date;\n get dueDate(): Date | undefined;\n get paidAt(): Date | undefined;\n get attemptCount(): number;\n get attempted(): boolean;\n get stripeHostedInvoiceUrl(): string | undefined;\n get stripePdfUrl(): string | undefined;\n get paid(): boolean;\n get metadata(): Record<string, any> | undefined;\n}\n\n// ============================================================================\n// Proration Preview Interfaces\n// ============================================================================\n\nexport interface ProrationPreviewInterface {\n amountDue: number;\n currency: string;\n immediateCharge: number;\n prorationDate: Date;\n lineItems: ProrationLineItem[];\n}\n\nexport interface ProrationLineItem {\n description: string;\n amount: number;\n proration: boolean;\n period: {\n start: Date;\n end: Date;\n };\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport { StripeInvoiceInterface } from \"./stripe-invoice.interface\";\n\n/**\n * Service for managing Stripe invoices\n */\nexport class StripeInvoiceService extends AbstractService {\n /**\n * List all invoices for the current user\n */\n static async listInvoices(params?: {\n status?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<StripeInvoiceInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeInvoice,\n });\n\n if (params?.status) {\n endpoint.addAdditionalParam(\"status\", params.status);\n }\n\n return this.callApi({\n type: Modules.StripeInvoice,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get a specific invoice by ID\n */\n static async getInvoice(params: { invoiceId: string }): Promise<StripeInvoiceInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeInvoice,\n id: params.invoiceId,\n });\n\n return this.callApi<StripeInvoiceInterface>({\n type: Modules.StripeInvoice,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Get the upcoming invoice for the current user\n */\n static async getUpcomingInvoice(): Promise<StripeInvoiceInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeInvoice,\n id: \"upcoming\",\n });\n\n return this.callApi<StripeInvoiceInterface>({\n type: Modules.StripeInvoice,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripeInvoice } from \"./data/stripe-invoice\";\n\nexport const StripeInvoiceModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-invoices\",\n model: StripeInvoice,\n moduleId: \"37c73b8b-d3b1-4e5e-8fcb-a66d8ecfc05b\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../../core\";\nimport { StripeProductInterface } from \"../../stripe-product\";\nimport { PriceRecurring, StripePriceInput, StripePriceInterface } from \"./stripe-price.interface\";\n\nexport class StripePrice extends AbstractApiData implements StripePriceInterface {\n private _stripePriceId?: string;\n private _productId?: string;\n private _product?: StripeProductInterface;\n private _active: boolean = true;\n private _currency?: string;\n private _unitAmount?: number;\n private _recurring?: PriceRecurring;\n private _priceType?: \"one_time\" | \"recurring\";\n private _nickname?: string;\n private _lookupKey?: string;\n private _metadata?: Record<string, any>;\n private _description?: string;\n private _features?: string[];\n private _token?: number;\n\n get stripePriceId(): string {\n if (!this._stripePriceId) throw new Error(\"stripePriceId is not defined\");\n return this._stripePriceId;\n }\n\n get productId(): string {\n if (!this._productId) throw new Error(\"productId is not defined\");\n return this._productId;\n }\n\n get product(): StripeProductInterface | undefined {\n return this._product;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get currency(): string {\n if (!this._currency) throw new Error(\"currency is not defined\");\n return this._currency;\n }\n\n get unitAmount(): number | undefined {\n return this._unitAmount;\n }\n\n get recurring(): PriceRecurring | undefined {\n return this._recurring;\n }\n\n get priceType(): \"one_time\" | \"recurring\" {\n if (!this._priceType) throw new Error(\"priceType is not defined\");\n return this._priceType;\n }\n\n get nickname(): string | undefined {\n return this._nickname;\n }\n\n get lookupKey(): string | undefined {\n return this._lookupKey;\n }\n\n get metadata(): Record<string, any> | undefined {\n return this._metadata;\n }\n\n get description(): string | undefined {\n return this._description;\n }\n\n get features(): string[] | undefined {\n return this._features;\n }\n\n get token(): number | undefined {\n return this._token;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._stripePriceId = data.jsonApi.attributes.stripePriceId;\n this._productId = data.jsonApi.attributes.productId;\n this._active = data.jsonApi.attributes.active ?? true;\n this._currency = data.jsonApi.attributes.currency;\n this._unitAmount = data.jsonApi.attributes.unitAmount;\n this._priceType = data.jsonApi.attributes.priceType;\n\n // Construct recurring object from flat attributes\n if (data.jsonApi.attributes.recurringInterval) {\n this._recurring = {\n interval: data.jsonApi.attributes.recurringInterval,\n intervalCount: data.jsonApi.attributes.recurringIntervalCount ?? 1,\n usageType: data.jsonApi.attributes.recurringUsageType,\n };\n }\n\n this._nickname = data.jsonApi.attributes.nickname;\n this._lookupKey = data.jsonApi.attributes.lookupKey;\n\n this._metadata = data.jsonApi.attributes.metadata\n ? typeof data.jsonApi.attributes.metadata === \"string\"\n ? JSON.parse(data.jsonApi.attributes.metadata)\n : data.jsonApi.attributes.metadata\n : undefined;\n\n this._description = data.jsonApi.attributes.description;\n this._features = data.jsonApi.attributes.features\n ? typeof data.jsonApi.attributes.features === \"string\"\n ? JSON.parse(data.jsonApi.attributes.features)\n : data.jsonApi.attributes.features\n : undefined;\n\n this._token = data.jsonApi.attributes.token;\n\n // Hydrate product relationship\n this._product = this._readIncluded(data, \"product\", Modules.StripeProduct) as StripeProductInterface;\n\n return this;\n }\n\n createJsonApi(data: StripePriceInput): any {\n const response: any = {\n data: {\n type: Modules.StripePrice.name,\n id: data.id,\n attributes: {},\n },\n };\n\n if (\"productId\" in data && data.productId) {\n response.data.attributes.productId = data.productId;\n }\n if (\"currency\" in data && data.currency) {\n response.data.attributes.currency = data.currency;\n }\n if (\"unitAmount\" in data && data.unitAmount !== undefined) {\n response.data.attributes.unitAmount = data.unitAmount;\n }\n if (\"active\" in data && data.active !== undefined) {\n response.data.attributes.active = data.active;\n }\n if (\"nickname\" in data && data.nickname !== undefined) {\n response.data.attributes.nickname = data.nickname;\n }\n if (\"metadata\" in data && data.metadata) {\n response.data.attributes.metadata = data.metadata;\n }\n if (\"recurring\" in data && data.recurring) {\n response.data.attributes.recurring = data.recurring;\n }\n if (\"description\" in data && data.description !== undefined) {\n response.data.attributes.description = data.description;\n }\n if (\"features\" in data && data.features !== undefined) {\n response.data.attributes.features = JSON.stringify(data.features);\n }\n if (\"token\" in data && data.token !== undefined) {\n response.data.attributes.token = data.token;\n }\n\n return response;\n }\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport { StripePriceInput, StripePriceInterface } from \"./stripe-price.interface\";\n\n/**\n * Admin billing service for managing products and prices\n */\nexport class StripePriceService extends AbstractService {\n /**\n * List all prices (admin)\n */\n static async listPrices(params?: {\n productId?: string;\n active?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<StripePriceInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n });\n\n if (params?.productId) {\n endpoint.addAdditionalParam(\"productId\", params.productId);\n }\n if (params?.active !== undefined) {\n endpoint.addAdditionalParam(\"active\", params.active.toString());\n }\n\n return this.callApi({\n type: Modules.StripePrice,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get a specific price by ID (admin)\n */\n static async getPrice(params: { id: string }): Promise<StripePriceInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n id: params.id,\n });\n\n return this.callApi<StripePriceInterface>({\n type: Modules.StripePrice,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a new price (admin)\n */\n static async createPrice(params: StripePriceInput): Promise<StripePriceInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n });\n\n return this.callApi<StripePriceInterface>({\n type: Modules.StripePrice,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Update an existing price (admin)\n */\n static async updatePrice(params: StripePriceInput): Promise<StripePriceInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n id: params.id,\n });\n\n return this.callApi<StripePriceInterface>({\n type: Modules.StripePrice,\n method: HttpMethod.PUT,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Archive a price (admin)\n *\n * Sets the price as inactive. Archived prices cannot be used for new subscriptions.\n */\n static async archivePrice(params: { id: string }): Promise<void> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n id: params.id,\n childEndpoint: \"archive\",\n });\n\n await this.callApi({\n type: Modules.StripePrice,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Reactivate a price (admin)\n *\n * Sets the price as active. Active prices can be used for new subscriptions.\n */\n static async reactivatePrice(params: { id: string }): Promise<void> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripePrice,\n id: params.id,\n childEndpoint: \"archive\",\n });\n\n await this.callApi({\n type: Modules.StripePrice,\n method: HttpMethod.DELETE,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripePrice } from \"./data/stripe-price\";\n\nexport const StripePriceModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-prices\",\n model: StripePrice,\n moduleId: \"a7d3e5f1-8c9b-4a2e-b6d7-3f1c8e9a4b5d\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules, StripePriceInterface } from \"../../../../core\";\nimport { StripeProductInput, StripeProductInterface } from \"./stripe-product.interface\";\n\nexport class StripeProduct extends AbstractApiData implements StripeProductInterface {\n private _stripeProductId?: string;\n private _name?: string;\n private _description?: string;\n private _active: boolean = true;\n private _metadata?: Record<string, any>;\n\n private _stripePrices: StripePriceInterface[] = [];\n\n get stripeProductId(): string {\n if (!this._stripeProductId) throw new Error(\"stripeProductId is not defined\");\n return this._stripeProductId;\n }\n\n get name(): string {\n if (!this._name) throw new Error(\"name is not defined\");\n return this._name;\n }\n\n get description(): string | undefined {\n return this._description;\n }\n\n get active(): boolean {\n return this._active;\n }\n\n get metadata(): Record<string, any> | undefined {\n return this._metadata;\n }\n\n get stripePrices(): StripePriceInterface[] {\n return this._stripePrices ?? [];\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._stripeProductId = data.jsonApi.attributes.stripeProductId;\n this._name = data.jsonApi.attributes.name;\n this._description = data.jsonApi.attributes.description;\n this._active = data.jsonApi.attributes.active ?? true;\n\n this._metadata = data.jsonApi.attributes.metadata\n ? typeof data.jsonApi.attributes.metadata === \"string\"\n ? JSON.parse(data.jsonApi.attributes.metadata)\n : data.jsonApi.attributes.metadata\n : undefined;\n\n this._stripePrices = this._readIncluded(data, \"stripePrices\", Modules.StripePrice) as StripePriceInterface[];\n\n return this;\n }\n\n createJsonApi(data: StripeProductInput): any {\n const response: any = {\n data: {\n type: Modules.StripeProduct.name,\n id: data.id,\n attributes: {},\n },\n };\n\n if (data.name) response.data.attributes.name = data.name;\n if (data.description !== undefined) response.data.attributes.description = data.description;\n if (data.active !== undefined) response.data.attributes.active = data.active;\n if (data.metadata) response.data.attributes.metadata = data.metadata;\n\n return response;\n }\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport { StripeProductInput, StripeProductInterface } from \"./stripe-product.interface\";\n\nexport class StripeProductService extends AbstractService {\n /**\n * List all products (admin)\n */\n static async listProducts(params?: {\n active?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<StripeProductInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n });\n\n if (params?.active !== undefined) {\n endpoint.addAdditionalParam(\"active\", params.active.toString());\n }\n\n return this.callApi({\n type: Modules.StripeProduct,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get a specific product by ID (admin)\n */\n static async getProduct(params: { id: string }): Promise<StripeProductInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n id: params.id,\n });\n\n return this.callApi<StripeProductInterface>({\n type: Modules.StripeProduct,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a new product (admin)\n */\n static async createProduct(params: StripeProductInput): Promise<StripeProductInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n });\n\n return this.callApi<StripeProductInterface>({\n type: Modules.StripeProduct,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Update an existing product (admin)\n */\n static async updateProduct(params: StripeProductInput): Promise<StripeProductInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n id: params.id,\n });\n\n return this.callApi<StripeProductInterface>({\n type: Modules.StripeProduct,\n method: HttpMethod.PUT,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Archive a product (admin)\n */\n static async archiveProduct(params: { id: string }): Promise<StripeProductInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n id: params.id,\n childEndpoint: \"archive\",\n });\n\n return this.callApi<StripeProductInterface>({\n type: Modules.StripeProduct,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Reactivate a product (admin) - sets active to true\n */\n static async reactivateProduct(params: { id: string }): Promise<StripeProductInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeProduct,\n id: params.id,\n childEndpoint: \"archive\",\n });\n\n return this.callApi<StripeProductInterface>({\n type: Modules.StripeProduct,\n method: HttpMethod.DELETE,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripeProduct } from \"./data\";\n\nexport const StripeProductModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-products\",\n model: StripeProduct,\n moduleId: \"f8c4a1e9-3b2d-4f7a-9e5c-1d8a6b3c9f2e\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../../core\";\nimport { StripePriceInterface } from \"../../stripe-price\";\nimport {\n StripeSubscriptionInput,\n StripeSubscriptionInterface,\n SubscriptionStatus,\n} from \"./stripe-subscription.interface\";\n\nexport class StripeSubscription extends AbstractApiData implements StripeSubscriptionInterface {\n private _stripeSubscriptionId?: string;\n private _status?: SubscriptionStatus;\n private _currentPeriodStart?: Date;\n private _currentPeriodEnd?: Date;\n private _cancelAtPeriodEnd: boolean = false;\n private _canceledAt?: Date;\n private _trialStart?: Date;\n private _trialEnd?: Date;\n private _price?: StripePriceInterface;\n\n get stripeSubscriptionId(): string {\n if (!this._stripeSubscriptionId) throw new Error(\"stripeSubscriptionId is not defined\");\n return this._stripeSubscriptionId;\n }\n\n get status(): SubscriptionStatus {\n if (!this._status) throw new Error(\"status is not defined\");\n return this._status;\n }\n\n get currentPeriodStart(): Date {\n if (!this._currentPeriodStart) throw new Error(\"currentPeriodStart is not defined\");\n return this._currentPeriodStart;\n }\n\n get currentPeriodEnd(): Date {\n if (!this._currentPeriodEnd) throw new Error(\"currentPeriodEnd is not defined\");\n return this._currentPeriodEnd;\n }\n\n get cancelAtPeriodEnd(): boolean {\n return this._cancelAtPeriodEnd;\n }\n\n get canceledAt(): Date | undefined {\n return this._canceledAt;\n }\n\n get trialStart(): Date | undefined {\n return this._trialStart;\n }\n\n get trialEnd(): Date | undefined {\n return this._trialEnd;\n }\n\n get price(): StripePriceInterface | undefined {\n return this._price;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._stripeSubscriptionId = data.jsonApi.attributes.stripeSubscriptionId;\n this._status = data.jsonApi.attributes.status;\n\n this._currentPeriodStart = data.jsonApi.attributes.currentPeriodStart\n ? new Date(data.jsonApi.attributes.currentPeriodStart)\n : undefined;\n this._currentPeriodEnd = data.jsonApi.attributes.currentPeriodEnd\n ? new Date(data.jsonApi.attributes.currentPeriodEnd)\n : undefined;\n\n this._cancelAtPeriodEnd = data.jsonApi.attributes.cancelAtPeriodEnd ?? false;\n this._canceledAt = data.jsonApi.attributes.canceledAt ? new Date(data.jsonApi.attributes.canceledAt) : undefined;\n\n this._trialStart = data.jsonApi.attributes.trialStart ? new Date(data.jsonApi.attributes.trialStart) : undefined;\n this._trialEnd = data.jsonApi.attributes.trialEnd ? new Date(data.jsonApi.attributes.trialEnd) : undefined;\n\n // Hydrate price relationship\n this._price = this._readIncluded(data, \"price\", Modules.StripePrice) as StripePriceInterface;\n\n return this;\n }\n\n createJsonApi(data: StripeSubscriptionInput): any {\n const response: any = {\n data: {\n type: Modules.StripeSubscription.name,\n id: data.id,\n attributes: {},\n },\n };\n\n // CREATE: priceId goes to relationships\n if (data.priceId) {\n response.data.relationships = {\n stripePrice: {\n data: {\n type: Modules.StripePrice.name,\n id: data.priceId,\n },\n },\n };\n }\n\n // CHANGE-PLAN: newPriceId goes to attributes.priceId\n if (data.newPriceId) {\n response.data.attributes.priceId = data.newPriceId;\n }\n\n // CANCEL: cancelImmediately goes to attributes\n if (data.cancelImmediately !== undefined) {\n response.data.attributes.cancelImmediately = data.cancelImmediately;\n }\n\n // Shared optional fields\n if (data.quantity !== undefined) {\n response.data.attributes.quantity = data.quantity;\n }\n\n if (data.trialPeriodDays !== undefined) {\n response.data.attributes.trialPeriodDays = data.trialPeriodDays;\n }\n\n if (data.paymentMethodId) {\n response.data.attributes.paymentMethodId = data.paymentMethodId;\n }\n\n if (data.metadata) {\n response.data.attributes.metadata = data.metadata;\n }\n\n return response;\n }\n}\n","// ============================================================================\n// Subscription Enums\n// ============================================================================\n\nimport { ApiDataInterface, StripePriceInterface } from \"../../../../core\";\n\nexport enum SubscriptionStatus {\n ACTIVE = \"active\",\n PAST_DUE = \"past_due\",\n UNPAID = \"unpaid\",\n CANCELED = \"canceled\",\n INCOMPLETE = \"incomplete\",\n INCOMPLETE_EXPIRED = \"incomplete_expired\",\n TRIALING = \"trialing\",\n PAUSED = \"paused\",\n}\n\n// ============================================================================\n// Subscription Interfaces\n// ============================================================================\n\nexport interface StripeSubscriptionInterface extends ApiDataInterface {\n get stripeSubscriptionId(): string;\n get status(): SubscriptionStatus;\n get currentPeriodStart(): Date;\n get currentPeriodEnd(): Date;\n get cancelAtPeriodEnd(): boolean;\n get canceledAt(): Date | undefined;\n get trialStart(): Date | undefined;\n get trialEnd(): Date | undefined;\n get price(): StripePriceInterface | undefined;\n}\n\n// ============================================================================\n// Subscription Input DTOs\n// ============================================================================\n\nexport type StripeSubscriptionInput = {\n id: string;\n // For CREATE - goes to relationships.stripePrice\n priceId?: string;\n // For CHANGE-PLAN - goes to attributes.priceId\n newPriceId?: string;\n // For CANCEL - goes to attributes.cancelImmediately\n cancelImmediately?: boolean;\n // Shared optional fields\n quantity?: number;\n trialPeriodDays?: number;\n paymentMethodId?: string;\n metadata?: Record<string, any>;\n};\n\n// ============================================================================\n// Subscription Response Types (for SCA payment confirmation)\n// ============================================================================\n\nexport interface StripeSubscriptionCreateMeta {\n clientSecret: string | null;\n paymentIntentId: string | null;\n requiresAction: boolean;\n}\n\nexport interface StripeSubscriptionCreateResponse {\n subscription: StripeSubscriptionInterface;\n meta: StripeSubscriptionCreateMeta;\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport { ProrationPreviewInterface } from \"../../stripe-invoice/data/stripe-invoice.interface\";\nimport {\n StripeSubscriptionCreateMeta,\n StripeSubscriptionCreateResponse,\n StripeSubscriptionInput,\n StripeSubscriptionInterface,\n} from \"./stripe-subscription.interface\";\n\n/**\n * Customer-facing billing service for managing subscriptions, payments, and usage\n */\nexport class StripeSubscriptionService extends AbstractService {\n // ============================================================================\n // Subscription Methods\n // ============================================================================\n\n /**\n * List all subscriptions for the current user\n */\n static async listSubscriptions(params?: {\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<StripeSubscriptionInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n });\n\n return this.callApi({\n type: Modules.StripeSubscription,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get a specific subscription by ID\n */\n static async getSubscription(params: { subscriptionId: string }): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.subscriptionId,\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Create a new subscription\n * Returns subscription data along with meta containing SCA payment confirmation details\n */\n static async createSubscription(params: StripeSubscriptionInput): Promise<StripeSubscriptionCreateResponse> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n });\n\n const result = await this.callApiWithMeta<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n\n return {\n subscription: result.data,\n meta: (result.meta as StripeSubscriptionCreateMeta) ?? {\n clientSecret: null,\n paymentIntentId: null,\n requiresAction: false,\n },\n };\n }\n\n /**\n * Change the plan of an existing subscription\n */\n static async changePlan(params: StripeSubscriptionInput): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.id,\n childEndpoint: \"change-plan\",\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.PUT,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Get a proration preview for a plan change\n */\n static async getProrationPreview(params: {\n subscriptionId: string;\n newPriceId: string;\n quantity?: number;\n }): Promise<ProrationPreviewInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.subscriptionId,\n childEndpoint: \"proration-preview\",\n });\n\n endpoint.addAdditionalParam(\"newPriceId\", params.newPriceId);\n if (params.quantity) {\n endpoint.addAdditionalParam(\"quantity\", params.quantity.toString());\n }\n\n return this.callApi({\n type: Modules.StripeSubscription,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Cancel a subscription\n */\n static async cancelSubscription(params: StripeSubscriptionInput): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.id,\n childEndpoint: \"cancel\",\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * Pause a subscription\n */\n static async pauseSubscription(params: { subscriptionId: string }): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.subscriptionId,\n childEndpoint: \"pause\",\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Resume a paused subscription\n */\n static async resumeSubscription(params: { subscriptionId: string }): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.subscriptionId,\n childEndpoint: \"resume\",\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Sync a subscription with the latest data from Stripe\n * This is useful after payment confirmation to get the updated status\n */\n static async syncSubscription(params: { subscriptionId: string }): Promise<StripeSubscriptionInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeSubscription,\n id: params.subscriptionId,\n childEndpoint: \"sync\",\n });\n\n return this.callApi<StripeSubscriptionInterface>({\n type: Modules.StripeSubscription,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripeSubscription } from \"./data\";\n\nexport const StripeSubscriptionModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-subscriptions\",\n model: StripeSubscription,\n moduleId: \"5e8797ef-650b-4dd5-ac79-a2e530a6c7ba\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../../core\";\nimport { ReportUsageInput, StripeUsageInterface } from \"./stripe-usage.interface\";\n\nexport class StripeUsage extends AbstractApiData implements StripeUsageInterface {\n private _subscriptionId?: string;\n private _meterId?: string;\n private _meterEventName?: string;\n private _stripeEventId?: string;\n private _quantity?: number;\n private _timestamp?: Date;\n\n get subscriptionId(): string {\n if (!this._subscriptionId) throw new Error(\"subscriptionId is not defined\");\n return this._subscriptionId;\n }\n\n get meterId(): string {\n if (!this._meterId) throw new Error(\"meterId is not defined\");\n return this._meterId;\n }\n\n get meterEventName(): string {\n if (!this._meterEventName) throw new Error(\"meterEventName is not defined\");\n return this._meterEventName;\n }\n\n get stripeEventId(): string {\n if (!this._stripeEventId) throw new Error(\"stripeEventId is not defined\");\n return this._stripeEventId;\n }\n\n get quantity(): number {\n if (this._quantity === undefined) throw new Error(\"quantity is not defined\");\n return this._quantity;\n }\n\n get timestamp(): Date | undefined {\n return this._timestamp;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._subscriptionId = data.jsonApi.attributes.subscriptionId;\n this._meterId = data.jsonApi.attributes.meterId;\n this._meterEventName = data.jsonApi.attributes.meterEventName;\n this._stripeEventId = data.jsonApi.attributes.stripeEventId;\n this._quantity = data.jsonApi.attributes.quantity;\n this._timestamp = data.jsonApi.attributes.timestamp ? new Date(data.jsonApi.attributes.timestamp) : undefined;\n\n return this;\n }\n\n createJsonApi(data: ReportUsageInput): any {\n const response: any = {\n data: {\n type: Modules.StripeUsage.name,\n attributes: {\n subscriptionItemId: data.subscriptionItemId,\n quantity: data.quantity,\n },\n },\n };\n\n if (data.timestamp !== undefined) response.data.attributes.timestamp = data.timestamp;\n if (data.action !== undefined) response.data.attributes.action = data.action;\n\n return response;\n }\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../../core\";\nimport {\n MeterInterface,\n MeterSummaryInterface,\n ReportUsageInput,\n StripeUsageInterface,\n UsageSummaryInterface,\n} from \"./stripe-usage.interface\";\n\n/**\n * Service for managing Stripe usage tracking\n */\nexport class StripeUsageService extends AbstractService {\n // ============================================================================\n // Meter Methods\n // ============================================================================\n\n /**\n * List all available usage meters\n */\n static async listMeters(params?: { next?: NextRef; prev?: PreviousRef }): Promise<MeterInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n childEndpoint: \"meters\",\n });\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get meter summaries for a specific time period\n */\n static async getMeterSummaries(params: {\n meterId: string;\n startTime: Date;\n endTime: Date;\n }): Promise<MeterSummaryInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n childEndpoint: `meters/${params.meterId}/summaries`,\n });\n\n endpoint.addAdditionalParam(\"startTime\", params.startTime.toISOString());\n endpoint.addAdditionalParam(\"endTime\", params.endTime.toISOString());\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n // ============================================================================\n // Usage Record Methods\n // ============================================================================\n\n /**\n * Report usage for a subscription item\n */\n static async reportUsage(params: ReportUsageInput): Promise<StripeUsageInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n });\n\n return this.callApi<StripeUsageInterface>({\n type: Modules.StripeUsage,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params,\n });\n }\n\n /**\n * List usage records for a subscription item\n */\n static async listUsageRecords(params: {\n subscriptionItemId: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<StripeUsageInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n });\n\n endpoint.addAdditionalParam(\"subscriptionItemId\", params.subscriptionItemId);\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params?.next,\n previous: params?.prev,\n });\n }\n\n /**\n * Get usage summary for a subscription item\n */\n static async getUsageSummary(params: {\n subscriptionItemId: string;\n start?: Date;\n end?: Date;\n }): Promise<UsageSummaryInterface> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.StripeUsage,\n childEndpoint: \"summary\",\n });\n\n endpoint.addAdditionalParam(\"subscriptionItemId\", params.subscriptionItemId);\n if (params.start) {\n endpoint.addAdditionalParam(\"start\", params.start.toISOString());\n }\n if (params.end) {\n endpoint.addAdditionalParam(\"end\", params.end.toISOString());\n }\n\n return this.callApi({\n type: Modules.StripeUsage,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../../permissions\";\nimport { StripeUsage } from \"./data/stripe-usage\";\n\nexport const StripeUsageModule = (factory: ModuleFactory) =>\n factory({\n name: \"stripe-usage-records\",\n model: StripeUsage,\n moduleId: \"c2e9f4a6-1d7b-4e3a-8f5c-9b2d6a1e7f3c\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { FeatureInterface } from \"../../feature\";\nimport { ModuleInterface } from \"../../module\";\nimport { CompanyInput, CompanyInterface } from \"./company.interface\";\n\nexport class Company extends AbstractApiData implements CompanyInterface {\n private _name?: string;\n private _logo?: string;\n private _logoUrl?: string;\n private _configurations?: any;\n\n private _monthlyTokens: number = 0;\n private _availableMonthlyTokens: number = 0;\n private _availableExtraTokens: number = 0;\n\n private _features?: FeatureInterface[];\n private _modules?: ModuleInterface[];\n\n get name(): string {\n if (this._name === undefined) throw new Error(\"Name is not defined\");\n return this._name;\n }\n\n get logo(): string | undefined {\n return this._logo;\n }\n\n get logoUrl(): string | undefined {\n return this._logoUrl;\n }\n\n get monthlyTokens(): number {\n return this._monthlyTokens ?? 0;\n }\n\n get availableMonthlyTokens(): number {\n return this._availableMonthlyTokens ?? 0;\n }\n\n get availableExtraTokens(): number {\n return this._availableExtraTokens ?? 0;\n }\n\n get features(): FeatureInterface[] {\n return this._features ?? [];\n }\n\n get modules(): ModuleInterface[] {\n return this._modules ?? [];\n }\n\n get configurations(): any | undefined {\n return this._configurations;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._name = data.jsonApi.attributes.name;\n this._configurations = data.jsonApi.attributes.configurations\n ? JSON.parse(data.jsonApi.attributes.configurations)\n : undefined;\n this._logo = data.jsonApi.attributes.logo;\n this._logoUrl = data.jsonApi.attributes.logoUrl;\n this._monthlyTokens = data.jsonApi.attributes.monthlyTokens ?? 0;\n this._availableMonthlyTokens = data.jsonApi.attributes.availableMonthlyTokens ?? 0;\n this._availableExtraTokens = data.jsonApi.attributes.availableExtraTokens ?? 0;\n\n this._features = this._readIncluded<FeatureInterface>(data, \"features\", Modules.Feature) as FeatureInterface[];\n this._modules = this._readIncluded<ModuleInterface>(data, \"modules\", Modules.Module) as ModuleInterface[];\n\n return this;\n }\n\n createJsonApi(data: CompanyInput) {\n const response: any = {\n data: {\n type: Modules.Company.name,\n id: data.id,\n attributes: {},\n meta: {},\n relationships: {},\n },\n included: [],\n };\n\n if (data.name) response.data.attributes.name = data.name;\n if (data.configurations) response.data.attributes.configurations = JSON.stringify(data.configurations);\n if (data.logo) response.data.attributes.logo = data.logo;\n if (data.monthlyTokens !== undefined) response.data.attributes.monthlyTokens = data.monthlyTokens;\n if (data.availableMonthlyTokens !== undefined)\n response.data.attributes.availableMonthlyTokens = data.availableMonthlyTokens;\n if (data.availableExtraTokens !== undefined)\n response.data.attributes.availableExtraTokens = data.availableExtraTokens;\n\n if (data.featureIds && data.featureIds.length > 0) {\n response.data.relationships.features = {\n data: data.featureIds.map((featureId) => ({\n type: Modules.Feature.name,\n id: featureId,\n })),\n };\n }\n\n if (data.moduleIds && data.moduleIds.length > 0) {\n response.data.relationships.modules = {\n data: data.moduleIds.map((moduleId) => ({\n type: Modules.Module.name,\n id: moduleId,\n })),\n };\n }\n\n return response;\n }\n}\n","export enum CompanyFields {\n companyId = \"companyId\",\n name = \"name\",\n createdAt = \"createdAt\",\n updatedAt = \"updatedAt\",\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef } from \"../../../core\";\nimport { CompanyInput, CompanyInterface } from \"./company.interface\";\n\nexport class CompanyService extends AbstractService {\n static async findOne(params: { companyId: string }): Promise<CompanyInterface> {\n return this.callApi<CompanyInterface>({\n type: Modules.Company,\n method: HttpMethod.GET,\n endpoint: new EndpointCreator({ endpoint: Modules.Company, id: params.companyId }).generate(),\n });\n }\n\n static async findMany(params: { search?: string; next?: NextRef }): Promise<CompanyInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Company });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi<CompanyInterface[]>({\n type: Modules.Company,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async delete(params: { companyId: string }): Promise<void> {\n await this.callApi({\n type: Modules.Company,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({ endpoint: Modules.Company, id: params.companyId }).generate(),\n });\n }\n\n static async create(params: CompanyInput): Promise<CompanyInterface> {\n return this.callApi({\n type: Modules.Company,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: Modules.Company }).generate(),\n input: params,\n });\n }\n\n static async update(params: CompanyInput): Promise<CompanyInterface> {\n return this.callApi({\n type: Modules.Company,\n method: HttpMethod.PUT,\n endpoint: new EndpointCreator({ endpoint: Modules.Company, id: params.id }).generate(),\n input: params,\n });\n }\n\n static async updateConfigurations(params: CompanyInput): Promise<CompanyInterface> {\n return this.callApi({\n type: Modules.Company,\n method: HttpMethod.PUT,\n endpoint: new EndpointCreator({\n endpoint: Modules.Company,\n id: params.id,\n childEndpoint: \"configurations\",\n }).generate(),\n input: params,\n });\n }\n\n static async activateLicense(params: CompanyInput): Promise<CompanyInterface> {\n return this.callApi({\n type: Modules.Company,\n method: HttpMethod.PUT,\n endpoint: new EndpointCreator({ endpoint: Modules.Company, id: params.id, childEndpoint: \"license\" }).generate(),\n input: params,\n });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Company } from \".\";\n\nexport const CompanyModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/companies\",\n name: \"companies\",\n model: Company,\n moduleId: \"f9e77c8f-bfd1-4fd4-80b0-e1d891ab7113\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { SearchResultInterface } from \"../../search/interfaces/search.result.interface\";\nimport { UserInterface } from \"../../user\";\nimport { ContentInput, ContentInterface } from \"./content.interface\";\n\nexport class Content extends AbstractApiData implements ContentInterface, SearchResultInterface {\n private _contentType?: string;\n\n private _name?: string;\n private _abstract?: string;\n private _tldr?: string;\n private _aiStatus?: string;\n private _relevance?: number;\n\n private _author?: UserInterface;\n private _editors?: UserInterface[];\n\n get searchResult(): string {\n return this._name ?? \"\";\n }\n\n get contentType(): string | undefined {\n return this._contentType;\n }\n\n get name(): string {\n if (this._name === undefined) throw new Error(\"JsonApi error: content name is missing\");\n return this._name;\n }\n\n get abstract(): string | undefined {\n return this._abstract;\n }\n\n get tldr(): string | undefined {\n return this._tldr;\n }\n\n get aiStatus(): string {\n return this._aiStatus ?? \"\";\n }\n\n get relevance(): number | undefined {\n return this._relevance;\n }\n\n get author(): UserInterface {\n if (this._author === undefined) throw new Error(\"JsonApi error: document author is missing\");\n return this._author;\n }\n\n get editors(): UserInterface[] {\n return this._editors ?? [];\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._contentType = data.jsonApi.meta.contentType;\n\n this._name = data.jsonApi.attributes.name;\n this._abstract = data.jsonApi.attributes.abstract;\n this._tldr = data.jsonApi.attributes.tldr;\n this._aiStatus = data.jsonApi.meta.aiStatus;\n this._relevance = data.jsonApi.meta.relevance;\n\n this._author = this._readIncluded(data, \"author\", Modules.User) as UserInterface;\n this._editors = this._readIncluded(data, \"editors\", Modules.User) as UserInterface[];\n\n return this;\n }\n\n protected addContentInput(response: any, data: ContentInput) {\n if (data.name) response.data.attributes.name = data.name;\n\n if (data.authorId) {\n response.data.relationships.author = {\n data: {\n type: Modules.User.name,\n id: data.authorId,\n },\n };\n }\n }\n}\n","export enum ContentFields {\n contentId = \"contentId\",\n\n name = \"name\",\n relevance = \"relevance\",\n\n authors = \"authors\",\n\n createdAt = \"createdAt\",\n updatedAt = \"updatedAt\",\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../core\";\nimport { ContentInterface } from \"./content.interface\";\n\nexport class ContentService extends AbstractService {\n static async findMany(params: {\n contentIds?: string[];\n search?: string;\n fetchAll?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<ContentInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Content });\n\n if (params.contentIds) {\n endpoint.addAdditionalParam(\"contentIds\", params.contentIds.join(\",\"));\n endpoint.addAdditionalParam(\"fetchAll\", \"true\");\n } else {\n if (params.fetchAll) endpoint.addAdditionalParam(\"fetchAll\", \"true\");\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n }\n if (Modules.Content.inclusions?.lists?.fields) endpoint.limitToFields(Modules.Content.inclusions.lists.fields);\n if (Modules.Content.inclusions?.lists?.types) endpoint.limitToType(Modules.Content.inclusions.lists.types);\n\n return this.callApi({\n type: Modules.Content,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findRelevant(params: { id: string; next?: NextRef; prev?: PreviousRef }): Promise<ContentInterface[]> {\n const endpoint: EndpointCreator = new EndpointCreator({\n endpoint: Modules.Content,\n id: params.id,\n childEndpoint: \"relevance\",\n });\n\n if (Modules.Content.inclusions?.lists?.fields) endpoint.limitToFields(Modules.Content.inclusions.lists.fields);\n if (Modules.Content.inclusions?.lists?.types) endpoint.limitToType(Modules.Content.inclusions.lists.types);\n\n return this.callApi<ContentInterface[]>({\n type: Modules.Content,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findManyByAuthor(params: {\n userId: string;\n search?: string;\n fetchAll?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<ContentInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Author,\n id: params.userId,\n childEndpoint: Modules.Content,\n });\n\n if (params.fetchAll) endpoint.addAdditionalParam(\"fetchAll\", \"true\");\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n if (Modules.Content.inclusions?.lists?.fields) endpoint.limitToFields(Modules.Content.inclusions.lists.fields);\n if (Modules.Content.inclusions?.lists?.types) endpoint.limitToType(Modules.Content.inclusions.lists.types);\n\n return this.callApi({\n type: Modules.Content,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n}\n","import { createJsonApiInclusion } from \"../../core\";\nimport { ModuleFactory } from \"../../permissions\";\nimport { Content } from \".\";\n\nexport const ContentModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/contents\",\n name: \"contents\",\n model: Content,\n inclusions: {\n lists: {\n fields: [\n createJsonApiInclusion(\"content\", [`name`, `tldr`, `abstract`, `aiStatus`, `relevance`]),\n createJsonApiInclusion(\"users\", [`name`, `avatar`]),\n createJsonApiInclusion(\"topics\", [`name`]),\n createJsonApiInclusion(\"expertises\", [`name`]),\n ],\n },\n },\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { ModuleInterface } from \"../../module\";\nimport { FeatureInterface } from \"./feature.interface\";\n\nexport class Feature extends AbstractApiData implements FeatureInterface {\n private _name?: string;\n private _isCore?: boolean;\n\n private _modules: ModuleInterface[] = [];\n\n get name(): string {\n return this._name ?? \"\";\n }\n\n get isCore(): boolean {\n return this._isCore == true ? true : false;\n }\n\n get modules(): ModuleInterface[] {\n return this._modules;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._name = data.jsonApi.attributes.name;\n this._isCore = data.jsonApi.attributes.isCore ?? false;\n\n this._modules = this._readIncluded(data, `modules`, Modules.Module) as ModuleInterface[];\n\n return this;\n }\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef } from \"../../../core\";\nimport { FeatureInterface } from \"./feature.interface\";\n\nexport class FeatureService extends AbstractService {\n static async findMany(params: { companyId?: string; search?: string; next?: NextRef }): Promise<FeatureInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Feature });\n\n if (params.companyId) endpoint.endpoint(Modules.Company).id(params.companyId).childEndpoint(Modules.Feature);\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi<FeatureInterface[]>({\n type: Modules.Feature,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Feature } from \"./data/feature\";\n\nexport const FeatureModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/features\",\n name: \"features\",\n model: Feature,\n moduleId: \"025fdd23-2803-4360-9fd9-eaa3612c2e23\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface } from \"../../../core\";\nimport { ModuleInterface } from \"./module.interface\";\n\nexport class Module extends AbstractApiData implements ModuleInterface {\n private _name?: string;\n private _permissions?: {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n };\n\n get name(): string {\n if (!this._name) throw new Error(\"Name is not defined\");\n return this._name ?? \"\";\n }\n\n get permissions(): {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n } {\n if (!this._permissions) throw new Error(\"Permissions is not defined\");\n return this._permissions;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._name = data.jsonApi.attributes.name;\n this._permissions = data.jsonApi.meta.permissions;\n\n return this;\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Module } from \"./data\";\n\nexport const ModuleModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/modules\",\n name: \"modules\",\n model: Module,\n moduleId: \"25ffd868-8341-4ca7-963b-6e1c56b03b1d\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { UserInterface } from \"../../user\";\nimport { NotificationInput, NotificationInterface } from \"./notification.interface\";\n\nexport class Notification extends AbstractApiData implements NotificationInterface {\n private _notificationType?: string;\n private _isRead?: boolean;\n private _message?: string;\n private _actionUrl?: string;\n\n private _actor?: UserInterface;\n\n get notificationType(): string {\n if (this._notificationType === undefined) throw new Error(\"notificationType is not set\");\n return this._notificationType;\n }\n\n get isRead(): boolean {\n return this._isRead === undefined ? false : this._isRead;\n }\n\n get message(): string | undefined {\n return this._message;\n }\n\n get actionUrl(): string | undefined {\n return this._actionUrl;\n }\n\n get actor(): UserInterface | undefined {\n return this._actor;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._notificationType = data.jsonApi.attributes.notificationType;\n this._isRead = data.jsonApi.attributes.isRead;\n this._message = data.jsonApi.attributes.message;\n this._actionUrl = data.jsonApi.attributes.actionUrl;\n\n this._actor = this._readIncluded(data, \"actor\", Modules.User) as UserInterface;\n\n return this;\n }\n\n createJsonApi(data: NotificationInput) {\n const response: any = {\n data: {\n type: Modules.Notification.name,\n id: data.id,\n attributes: {\n isRead: data.isRead,\n },\n meta: {},\n relationships: {},\n },\n included: [],\n };\n\n return response;\n }\n}\n","export enum NotificationFields {\n notificationId = \"notificationId\",\n\n name = \"name\",\n\n createdAt = \"createdAt\",\n updatedAt = \"updatedAt\",\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef } from \"../../../core\";\nimport { NotificationInterface } from \"./notification.interface\";\n\nexport class NotificationService extends AbstractService {\n static async findMany(params: { isArchived?: boolean; next?: NextRef }): Promise<NotificationInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Notification });\n\n if (params.isArchived) endpoint.addAdditionalParam(\"isArchived\", \"true\");\n\n return this.callApi<NotificationInterface[]>({\n type: Modules.Notification,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async markAsRead(params: { data: any }): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Notification });\n await this.callApi({\n type: Modules.Notification,\n method: HttpMethod.PATCH,\n endpoint: endpoint.generate(),\n input: params.data,\n overridesJsonApiCreation: true,\n });\n }\n\n static async archive(params: { id: string }): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Notification, id: params.id, childEndpoint: \"archive\" });\n\n await this.callApi({ type: Modules.Notification, method: HttpMethod.POST, endpoint: endpoint.generate() });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Notification } from \"./data/notification\";\n\nexport const NotificationModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/notifications\",\n name: \"notifications\",\n model: Notification,\n moduleId: \"9259d704-c670-4e77-a3a1-a728ffc5be3d\",\n });\n","import { AbstractApiData, Modules } from \"../../../core\";\nimport { PushInput, PushInterface } from \"./push.interface\";\n\nexport class Push extends AbstractApiData implements PushInterface {\n createJsonApi(data: PushInput) {\n const response: any = {\n data: {\n type: Modules.Push.name,\n attributes: {\n key: data.key,\n },\n },\n included: [],\n };\n\n return response;\n }\n}\n","import { AbstractService, HttpMethod } from \"../../../core\";\nimport { EndpointCreator } from \"../../../core\";\nimport { Modules } from \"../../../core\";\n\nexport class PushService extends AbstractService {\n static async register(params: { data: any }): Promise<void> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Push });\n\n await this.callApi({\n type: Modules.Push,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n input: params.data,\n overridesJsonApiCreation: true,\n });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Push } from \"./data/push\";\n\nexport const PushModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/push\",\n name: \"push\",\n model: Push,\n moduleId: \"\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { FeatureInterface } from \"../../feature\";\nimport { RoleInput, RoleInterface } from \"./role.interface\";\n\nexport class Role extends AbstractApiData implements RoleInterface {\n private _name?: string;\n private _description?: string;\n private _isSelectable?: boolean;\n\n private _requiredFeature?: FeatureInterface;\n\n get name(): string {\n if (!this._name) throw new Error(\"Name is not defined\");\n return this._name;\n }\n\n get description(): string {\n return this._description ?? \"\";\n }\n\n get isSelectable(): boolean {\n return this._isSelectable ?? false;\n }\n\n get requiredFeature(): FeatureInterface | undefined {\n return this._requiredFeature;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._name = data.jsonApi.attributes.name ?? undefined;\n this._description = data.jsonApi.attributes.description ?? undefined;\n this._isSelectable = data.jsonApi.attributes.isSelectable ?? undefined;\n\n this._requiredFeature = this._readIncluded<FeatureInterface>(\n data,\n \"requiredFeature\",\n Modules.Feature,\n ) as FeatureInterface;\n\n return this;\n }\n\n createJsonApi(data: RoleInput) {\n const response: any = {\n data: {\n type: Modules.Role.name,\n id: data.id,\n attributes: {\n name: data.name,\n },\n meta: {},\n },\n included: [],\n };\n\n if (data.description !== undefined) response.data.attributes.description = data.description;\n\n return response;\n }\n}\n","export enum RoleFields {\n roleId = \"roleId\",\n name = \"name\",\n description = \"description\",\n\n createdAt = \"createdAt\",\n updatedAt = \"updatedAt\",\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../core\";\nimport { RoleInput, RoleInterface } from \"./role.interface\";\n\nexport class RoleService extends AbstractService {\n static async findById(params: { roleId: string }): Promise<RoleInterface> {\n return this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.GET,\n endpoint: new EndpointCreator({ endpoint: Modules.Role, id: params.roleId }).generate(),\n });\n }\n\n static async findAllRoles(params: { search?: string; next?: NextRef }): Promise<RoleInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Role });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.Role,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findAllRolesByUser(params: {\n userId: string;\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<RoleInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.User, id: params.userId, childEndpoint: Modules.Role });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.Role,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findAllRolesUserNotIn(params: {\n userId: string;\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<RoleInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.User,\n id: params.userId,\n childEndpoint: Modules.Role,\n }).addAdditionalParam(\"userNotIn\", \"true\");\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.Role,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async addUserToRole(params: { userId: string; roleId: string }): Promise<void> {\n this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({\n endpoint: Modules.Role,\n id: params.roleId,\n childEndpoint: Modules.User,\n childId: params.userId,\n }).generate(),\n });\n }\n\n static async removeUserFromRole(params: { userId: string; roleId: string }): Promise<void> {\n this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({\n endpoint: Modules.Role,\n id: params.roleId,\n childEndpoint: Modules.User,\n childId: params.userId,\n }).generate(),\n });\n }\n\n static async create(params: { roleId: string; name: string; description?: string }): Promise<RoleInterface> {\n return this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: Modules.Role }).generate(),\n input: { id: params.roleId, name: params.name, description: params.description } as RoleInput,\n });\n }\n\n static async update(params: { roleId: string; name: string; description?: string }): Promise<RoleInterface> {\n return this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.PUT,\n endpoint: new EndpointCreator({ endpoint: Modules.Role, id: params.roleId }).generate(),\n input: { id: params.roleId, name: params.name, description: params.description } as RoleInput,\n });\n }\n\n static async delete(params: { roleId: string }): Promise<RoleInterface> {\n return this.callApi<RoleInterface>({\n type: Modules.Role,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({ endpoint: Modules.Role, id: params.roleId }).generate(),\n });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { Role } from \"./data/role\";\n\nexport const RoleModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/roles\",\n name: \"roles\",\n model: Role,\n moduleId: \"9f6416e6-7b9b-4e1a-a99f-833191eca8a9\",\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { S3Input, S3Interface } from \"./s3.interface\";\n\nexport class S3 extends AbstractApiData implements S3Interface {\n private _url?: string;\n private _storageType?: string;\n private _contentType?: string;\n private _blobType?: string;\n private _acl?: string;\n\n get url(): string {\n if (!this._url) throw new Error(\"Image URL is not set.\");\n return this._url;\n }\n\n get headers(): Record<string, string> {\n const headers: Record<string, string> = {};\n\n if (this._contentType) {\n headers[\"Content-Type\"] = this._contentType;\n }\n\n if (this._blobType) {\n headers[\"x-ms-blob-type\"] = this._blobType;\n }\n\n if (this._acl) {\n headers[\"x-amz-acl\"] = this._acl;\n }\n\n return headers;\n }\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._url = data.jsonApi.attributes.url ?? undefined;\n this._storageType = data.jsonApi.attributes.storageType ?? undefined;\n this._contentType = data.jsonApi.attributes.contentType ?? undefined;\n this._blobType = data.jsonApi.attributes.blobType ?? undefined;\n this._acl = data.jsonApi.attributes.acl ?? undefined;\n\n return this;\n }\n\n createJsonApi(data: S3Input) {\n const response: any = {\n data: {\n type: Modules.S3.name,\n attributes: {\n key: data.key,\n },\n },\n included: [],\n };\n\n if (data.contentType) response.data.attributes.contentType = data.contentType;\n\n return response;\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { S3 } from \"./data/s3\";\n\nexport const S3Module = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/s3\",\n name: \"s3\",\n model: S3,\n moduleId: \"db41ba46-e171-4324-8845-99353eba8568\",\n });\n","import { AbstractService, EndpointCreator, HttpMethod, Modules } from \"../../../core\";\nimport { S3Interface } from \"./s3.interface\";\n\nexport class S3Service extends AbstractService {\n static async getPreSignedUrl(params: { key: string; contentType: string; isPublic?: boolean }): Promise<S3Interface> {\n const endpoint = new EndpointCreator({ endpoint: Modules.S3 })\n .addAdditionalParam(\"key\", params.key)\n .addAdditionalParam(\"contentType\", params.contentType);\n\n if (params.isPublic) endpoint.addAdditionalParam(\"isPublic\", \"true\");\n\n return this.callApi<S3Interface>({ type: Modules.S3, method: HttpMethod.GET, endpoint: endpoint.generate() });\n }\n\n static async getSignedUrl(params: { key: string; isPublic?: boolean }): Promise<S3Interface> {\n const endpoint = new EndpointCreator({ endpoint: Modules.S3, id: \"sign\" }).addAdditionalParam(\"key\", params.key);\n\n if (params.isPublic) endpoint.addAdditionalParam(\"isPublic\", \"true\");\n\n return this.callApi<S3Interface>({ type: Modules.S3, method: HttpMethod.GET, endpoint: endpoint.generate() });\n }\n\n static async deleteFile(params: { key: string }): Promise<void> {\n this.callApi<S3Interface>({\n type: Modules.S3,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({ endpoint: Modules.S3 }).addAdditionalParam(\"key\", params.key).generate(),\n });\n }\n}\n","import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from \"../../../core\";\nimport { CompanyInterface } from \"../../company\";\nimport { ModuleInterface } from \"../../module\";\nimport { RoleInterface } from \"../../role\";\nimport { SearchResultInterface } from \"../../search\";\nimport { UserInput, UserInterface } from \"./user.interface\";\n\nexport class User extends AbstractApiData implements UserInterface, SearchResultInterface {\n private _name?: string;\n private _email?: string;\n private _title?: string;\n private _bio?: string;\n private _avatar?: string;\n private _avatarUrl?: string;\n private _phone?: string;\n private _rate?: number;\n\n private _isActivated?: boolean;\n private _isDeleted?: boolean;\n private _lastLogin?: Date;\n\n private _relevance?: number;\n\n private _roles: RoleInterface[] = [];\n private _company?: CompanyInterface;\n private _modules: ModuleInterface[] = [];\n\n get searchResult(): string {\n return this._name ?? \"\";\n }\n\n get name(): string {\n return this._name ?? \"\";\n }\n\n get email(): string {\n return this._email ?? \"\";\n }\n\n get title(): string {\n return this._title ?? \"\";\n }\n\n get bio(): string {\n return this._bio ?? \"\";\n }\n\n get avatar(): string | undefined {\n return this._avatar;\n }\n\n get avatarUrl(): string | undefined {\n return this._avatarUrl;\n }\n\n get phone(): string | undefined {\n return this._phone;\n }\n\n get rate(): number | undefined {\n return this._rate;\n }\n\n get relevance(): number | undefined {\n return this._relevance;\n }\n\n get isActivated(): boolean {\n return this._isActivated ?? false;\n }\n\n get isDeleted(): boolean {\n return this._isDeleted ?? false;\n }\n\n get lastLogin(): Date | undefined {\n return this._lastLogin;\n }\n\n get roles(): RoleInterface[] {\n return this._roles;\n }\n\n get company(): CompanyInterface | undefined {\n return this._company;\n }\n\n get modules(): ModuleInterface[] {\n return this._modules;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n this._name = data.jsonApi.attributes.name;\n this._email = data.jsonApi.attributes.email;\n this._title = data.jsonApi.attributes.title;\n this._bio = data.jsonApi.attributes.bio;\n this._phone = data.jsonApi.attributes.phone;\n this._rate = data.jsonApi.attributes.rate;\n\n this._avatar = data.jsonApi.attributes.avatar;\n this._avatarUrl = data.jsonApi.attributes.avatarUrl;\n\n this._isActivated = data.jsonApi.meta.isActive;\n this._isDeleted = data.jsonApi.meta.isDeleted;\n this._lastLogin = data.jsonApi.meta.lastLogin ? new Date(data.jsonApi.meta.lastLogin) : undefined;\n\n this._relevance = data.jsonApi.meta.relevance;\n\n this._roles = this._readIncluded(data, \"roles\", Modules.Role) as RoleInterface[];\n this._company = this._readIncluded(data, \"company\", Modules.Company) as CompanyInterface;\n this._modules = this._readIncluded(data, \"modules\", Modules.Module) as ModuleInterface[];\n\n return this;\n }\n\n createJsonApi(data: UserInput) {\n const response: any = {\n data: {\n type: Modules.User.name,\n id: data.id,\n attributes: {\n name: data.name,\n },\n meta: {},\n relationships: {},\n },\n included: [],\n };\n\n if (data.email !== undefined) response.data.attributes.email = data.email;\n if (data.title !== undefined) response.data.attributes.title = data.title;\n if (data.bio !== undefined) response.data.attributes.bio = data.bio;\n if (data.phone !== undefined) response.data.attributes.phone = data.phone;\n if (data.password !== undefined) response.data.attributes.password = data.password;\n if (data.sendInvitationEmail) response.data.attributes.sendInvitationEmail = true;\n if (data.adminCreated) response.data.attributes.adminCreated = true;\n if (data.avatar) response.data.attributes.avatar = data.avatar;\n if (data.rate !== undefined) response.data.attributes.rate = data.rate;\n\n if (data.roleIds) {\n response.data.relationships.roles = {\n data: data.roleIds.map((roleId) => ({\n type: Modules.Role.name,\n id: roleId,\n })),\n };\n }\n\n if (data.companyId) {\n response.data.relationships.company = {\n data: {\n type: Modules.Company.name,\n id: data.companyId,\n },\n };\n }\n\n return response;\n }\n}\n","export enum UserFields {\n userId = \"userId\",\n name = \"name\",\n email = \"email\",\n relevance = \"relevance\",\n createdAt = \"createdAt\",\n updatedAt = \"updatedAt\",\n}\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from \"../../../core\";\nimport { UserInput, UserInterface } from \"./user.interface\";\n\nexport class UserService extends AbstractService {\n static async findFullUser(): Promise<UserInterface> {\n const endpoint = new EndpointCreator({ endpoint: Modules.User, id: \"me\", childEndpoint: \"full\" });\n\n return this.callApi<UserInterface>({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n static async findById(params: { userId: string }): Promise<UserInterface> {\n return this.callApi<UserInterface>({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: new EndpointCreator({ endpoint: Modules.User, id: params.userId }).generate(),\n });\n }\n\n static async findByEmail(params: { email: string }): Promise<UserInterface> {\n const endpoint = new EndpointCreator({ endpoint: Modules.User, id: \"email\", childEndpoint: params.email });\n\n return this.callApi<UserInterface>({ type: Modules.User, method: HttpMethod.GET, endpoint: endpoint.generate() });\n }\n\n static async findMany(params: {\n roleId?: string;\n search?: string;\n fetchAll?: boolean;\n includeDeleted?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.User });\n\n if (params.roleId) endpoint.addAdditionalParam(\"roleId\", params.roleId);\n\n if (params.includeDeleted) endpoint.addAdditionalParam(\"includeDeleted\", \"true\");\n if (params.fetchAll) endpoint.addAdditionalParam(\"fetchAll\", \"true\");\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findManyByContentIds(params: {\n contentIds: string[];\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.User });\n\n endpoint.addAdditionalParam(\"contentIds\", params.contentIds.map((id) => id).join(\",\"));\n endpoint.addAdditionalParam(\"includeDeleted\", \"true\");\n endpoint.addAdditionalParam(\"fetchAll\", \"true\");\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findRelevant(params: { id: string; next?: NextRef; prev?: PreviousRef }): Promise<UserInterface[]> {\n const endpoint: EndpointCreator = new EndpointCreator({\n endpoint: Modules.Content,\n id: params.id,\n childEndpoint: \"user-relevance\",\n });\n\n if (Modules.User.inclusions?.lists?.fields) endpoint.limitToFields(Modules.User.inclusions.lists.fields);\n if (Modules.User.inclusions?.lists?.types) endpoint.limitToType(Modules.User.inclusions.lists.types);\n\n return this.callApi<UserInterface[]>({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findManyForAmin(params: {\n companyId?: string;\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n if (!params.companyId) return [];\n\n const endpoint = new EndpointCreator({\n endpoint: Modules.Company,\n id: params.companyId,\n childEndpoint: Modules.User,\n });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n previous: params.prev,\n });\n }\n\n static async findAllUsers(params: {\n companyId: string;\n search?: string;\n limitToRoles?: string[];\n isDeleted?: boolean;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Company,\n id: params.companyId,\n childEndpoint: Modules.User,\n });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n if (params.isDeleted) endpoint.addAdditionalParam(\"isDeleted\", \"true\");\n if (params.limitToRoles && params.limitToRoles.length > 0)\n endpoint.addAdditionalParam(\"limitToRoles\", params.limitToRoles.join(\",\"));\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findAllUsersByRole(params: {\n roleId: string;\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n const endpoint = new EndpointCreator({ endpoint: Modules.Role, id: params.roleId, childEndpoint: Modules.User });\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async findAllUsersNotInRole(params: {\n roleId: string;\n search?: string;\n next?: NextRef;\n prev?: PreviousRef;\n }): Promise<UserInterface[]> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.Role,\n id: params.roleId,\n childEndpoint: Modules.User,\n }).addAdditionalParam(\"notInRole\", \"true\");\n\n if (params.search) endpoint.addAdditionalParam(\"search\", params.search);\n\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n next: params.next,\n });\n }\n\n static async create(params: UserInput): Promise<UserInterface> {\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: Modules.User }).generate(),\n companyId: params.companyId,\n input: params,\n });\n }\n\n static async reactivate(params: { userId: string }): Promise<UserInterface> {\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.PATCH,\n endpoint: new EndpointCreator({ endpoint: Modules.User, id: params.userId }).generate(),\n });\n }\n\n static async sendInvitation(params: { userId: string; companyId?: string }): Promise<void> {\n const endpoint = new EndpointCreator({\n endpoint: Modules.User,\n id: params.userId,\n childEndpoint: \"send-invitation-email\",\n });\n\n if (params.companyId) endpoint.addAdditionalParam(\"companyId\", params.companyId);\n\n this.callApi({\n type: Modules.User,\n method: HttpMethod.POST,\n endpoint: endpoint.generate(),\n });\n }\n\n static async update(params: UserInput): Promise<UserInterface> {\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.PUT,\n endpoint: new EndpointCreator({ endpoint: Modules.User, id: params.id }).generate(),\n companyId: params.companyId,\n input: params,\n });\n }\n\n static async patchRate(params: UserInput): Promise<UserInterface> {\n return this.callApi({\n type: Modules.User,\n method: HttpMethod.PATCH,\n endpoint: new EndpointCreator({ endpoint: Modules.User, id: params.id, childEndpoint: \"rates\" }).generate(),\n companyId: params.companyId,\n input: params,\n });\n }\n\n static async delete(params: { userId: string; companyId: string }): Promise<void> {\n await this.callApi({\n type: Modules.User,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({ endpoint: Modules.User, id: params.userId }).generate(),\n companyId: params.companyId,\n });\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { User } from \"./data\";\n\nexport const AuthorModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/authors\",\n name: \"authors\",\n model: User,\n moduleId: \"04cfc677-0fd2-4f5e-adf4-2483a00c0277\",\n });\n","import { User } from \"./data/user\";\nimport { createJsonApiInclusion } from \"../../core\";\nimport { ModuleFactory } from \"../../permissions\";\n\nexport const UserModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/users\",\n name: \"users\",\n model: User,\n moduleId: \"04cfc677-0fd2-4f5e-adf4-2483a00c0277\",\n inclusions: {\n lists: {\n fields: [\n createJsonApiInclusion(\"users\", [`name`, `email`, `avatar`, `title`]),\n createJsonApiInclusion(\"usertopics\", [`level`]),\n createJsonApiInclusion(\"userexpertises\", [`level`]),\n createJsonApiInclusion(\"topics\", [`name`]),\n ],\n },\n },\n });\n","import { AbstractApiData, JsonApiHydratedDataInterface } from \"../../../core\";\nimport { OAuthClientInput, OAuthClientInterface } from \"../interfaces/oauth.interface\";\n\n/**\n * OAuth client data model\n * Represents a registered OAuth application that can request access tokens\n */\nexport class OAuthClient extends AbstractApiData implements OAuthClientInterface {\n private _clientId?: string;\n private _name?: string;\n private _description?: string;\n private _redirectUris: string[] = [];\n private _allowedScopes: string[] = [];\n private _allowedGrantTypes: string[] = [];\n private _isConfidential: boolean = true;\n private _isActive: boolean = true;\n\n get clientId(): string {\n return this._clientId ?? this.id;\n }\n\n get name(): string {\n if (!this._name) throw new Error(\"Name is not defined\");\n return this._name;\n }\n\n get description(): string | undefined {\n return this._description;\n }\n\n get redirectUris(): string[] {\n return this._redirectUris;\n }\n\n get allowedScopes(): string[] {\n return this._allowedScopes;\n }\n\n get allowedGrantTypes(): string[] {\n return this._allowedGrantTypes;\n }\n\n get isConfidential(): boolean {\n return this._isConfidential;\n }\n\n get isActive(): boolean {\n return this._isActive;\n }\n\n rehydrate(data: JsonApiHydratedDataInterface): this {\n super.rehydrate(data);\n\n const attrs = data.jsonApi.attributes || {};\n\n this._clientId = attrs.clientId ?? this._id;\n this._name = attrs.name;\n this._description = attrs.description;\n this._redirectUris = attrs.redirectUris ?? [];\n this._allowedScopes = attrs.allowedScopes ?? [];\n this._allowedGrantTypes = attrs.allowedGrantTypes ?? [];\n this._isConfidential = attrs.isConfidential ?? true;\n this._isActive = attrs.isActive ?? true;\n\n return this;\n }\n\n createJsonApi(data: OAuthClientInput) {\n const response: any = {\n data: {\n type: \"oauth-clients\",\n attributes: {},\n },\n };\n\n if (data.id) response.data.id = data.id;\n if (data.name !== undefined) response.data.attributes.name = data.name;\n if (data.description !== undefined) response.data.attributes.description = data.description;\n if (data.redirectUris !== undefined) response.data.attributes.redirectUris = data.redirectUris;\n if (data.allowedScopes !== undefined) response.data.attributes.allowedScopes = data.allowedScopes;\n if (data.allowedGrantTypes !== undefined) response.data.attributes.allowedGrantTypes = data.allowedGrantTypes;\n if (data.isConfidential !== undefined) response.data.attributes.isConfidential = data.isConfidential;\n if (data.isActive !== undefined) response.data.attributes.isActive = data.isActive;\n\n return response;\n }\n}\n","import { ModuleFactory } from \"../../permissions\";\nimport { OAuthClient } from \"./data/oauth\";\n\nexport const OAuthModule = (factory: ModuleFactory) =>\n factory({\n pageUrl: \"/oauth\",\n name: \"oauth-clients\",\n model: OAuthClient,\n });\n","import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef } from \"../../../core\";\nimport {\n OAuthClientCreateRequest,\n OAuthClientCreateResponse,\n OAuthClientInput,\n OAuthClientInterface,\n OAuthConsentInfo,\n OAuthConsentRequest,\n} from \"../interfaces/oauth.interface\";\n\n/**\n * Service for OAuth client management and authorization consent flow.\n *\n * Client Management endpoints:\n * - GET /oauth/clients - List all clients for current user\n * - GET /oauth/clients/:clientId - Get single client\n * - POST /oauth/clients - Create new client (returns secret once)\n * - PATCH /oauth/clients/:clientId - Update client\n * - DELETE /oauth/clients/:clientId - Delete client\n * - POST /oauth/clients/:clientId/regenerate-secret - Regenerate client secret\n *\n * Consent Flow endpoints:\n * - GET /oauth/authorize/info - Get client info for consent screen\n * - POST /oauth/authorize/approve - Approve authorization\n * - POST /oauth/authorize/deny - Deny authorization\n */\nexport class OAuthService extends AbstractService {\n // ==========================================\n // CLIENT MANAGEMENT\n // ==========================================\n\n /**\n * List all OAuth clients for the current user\n */\n static async listClients(params?: { next?: NextRef }): Promise<OAuthClientInterface[]> {\n return this.callApi<OAuthClientInterface[]>({\n type: Modules.OAuth,\n method: HttpMethod.GET,\n endpoint: new EndpointCreator({ endpoint: \"oauth/clients\" }).generate(),\n next: params?.next,\n });\n }\n\n /**\n * Get a single OAuth client by ID\n */\n static async getClient(params: { clientId: string }): Promise<OAuthClientInterface> {\n return this.callApi<OAuthClientInterface>({\n type: Modules.OAuth,\n method: HttpMethod.GET,\n endpoint: new EndpointCreator({ endpoint: \"oauth/clients\", id: params.clientId }).generate(),\n });\n }\n\n /**\n * Create a new OAuth client\n * @returns The created client AND the client secret (shown only once!)\n */\n static async createClient(data: OAuthClientCreateRequest): Promise<OAuthClientCreateResponse> {\n const result = await this.callApiWithMeta<OAuthClientInterface>({\n type: Modules.OAuth,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: \"oauth/clients\" }).generate(),\n input: data,\n });\n\n return {\n client: result.data,\n clientSecret: result.meta?.clientSecret as string | undefined,\n };\n }\n\n /**\n * Update an existing OAuth client\n */\n static async updateClient(params: {\n clientId: string;\n data: Partial<OAuthClientInput>;\n }): Promise<OAuthClientInterface> {\n return this.callApi<OAuthClientInterface>({\n type: Modules.OAuth,\n method: HttpMethod.PATCH,\n endpoint: new EndpointCreator({ endpoint: \"oauth/clients\", id: params.clientId }).generate(),\n input: { id: params.clientId, ...params.data },\n });\n }\n\n /**\n * Delete an OAuth client\n */\n static async deleteClient(params: { clientId: string }): Promise<void> {\n await this.callApi({\n type: Modules.OAuth,\n method: HttpMethod.DELETE,\n endpoint: new EndpointCreator({ endpoint: \"oauth/clients\", id: params.clientId }).generate(),\n });\n }\n\n /**\n * Regenerate the client secret\n * @returns The new client secret (shown only once!)\n */\n static async regenerateSecret(params: { clientId: string }): Promise<{ clientSecret: string }> {\n const result = await this.callApiWithMeta<OAuthClientInterface>({\n type: Modules.OAuth,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({\n endpoint: \"oauth/clients\",\n id: params.clientId,\n childEndpoint: \"regenerate-secret\",\n }).generate(),\n });\n\n return {\n clientSecret: result.meta?.clientSecret as string,\n };\n }\n\n // ==========================================\n // CONSENT FLOW\n // ==========================================\n\n /**\n * Get client information for the consent screen\n * Called when user is redirected to /oauth/authorize\n */\n static async getAuthorizationInfo(params: OAuthConsentRequest): Promise<OAuthConsentInfo> {\n const endpoint = new EndpointCreator({ endpoint: \"oauth/authorize/info\" });\n\n // Add query parameters\n endpoint.addAdditionalParam(\"client_id\", params.clientId);\n endpoint.addAdditionalParam(\"redirect_uri\", params.redirectUri);\n endpoint.addAdditionalParam(\"scope\", params.scope);\n if (params.state) endpoint.addAdditionalParam(\"state\", params.state);\n if (params.codeChallenge) endpoint.addAdditionalParam(\"code_challenge\", params.codeChallenge);\n if (params.codeChallengeMethod) endpoint.addAdditionalParam(\"code_challenge_method\", params.codeChallengeMethod);\n\n return this.callApi<OAuthConsentInfo>({\n type: Modules.OAuth,\n method: HttpMethod.GET,\n endpoint: endpoint.generate(),\n });\n }\n\n /**\n * Approve the authorization request\n * @returns Redirect URL with authorization code\n */\n static async approveAuthorization(params: OAuthConsentRequest): Promise<{ redirectUrl: string }> {\n const result = await this.callApiWithMeta<unknown>({\n type: Modules.OAuth,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: \"oauth/authorize/approve\" }).generate(),\n input: {\n client_id: params.clientId,\n redirect_uri: params.redirectUri,\n scope: params.scope,\n state: params.state,\n code_challenge: params.codeChallenge,\n code_challenge_method: params.codeChallengeMethod,\n },\n overridesJsonApiCreation: true,\n });\n\n return {\n redirectUrl: result.meta?.redirectUrl as string,\n };\n }\n\n /**\n * Deny the authorization request\n * @returns Redirect URL with error=access_denied\n */\n static async denyAuthorization(params: OAuthConsentRequest): Promise<{ redirectUrl: string }> {\n const result = await this.callApiWithMeta<unknown>({\n type: Modules.OAuth,\n method: HttpMethod.POST,\n endpoint: new EndpointCreator({ endpoint: \"oauth/authorize/deny\" }).generate(),\n input: {\n client_id: params.clientId,\n redirect_uri: params.redirectUri,\n state: params.state,\n },\n overridesJsonApiCreation: true,\n });\n\n return {\n redirectUrl: result.meta?.redirectUrl as string,\n };\n }\n}\n","import { ApiDataInterface } from \"../../../core\";\n\n/**\n * OAuth client application interface\n * Represents a registered OAuth application that can request access tokens\n */\nexport interface OAuthClientInterface extends ApiDataInterface {\n /** The public client identifier (UUID format) */\n get clientId(): string;\n /** Human-readable application name */\n get name(): string;\n /** Optional description of the application */\n get description(): string | undefined;\n /** Array of allowed redirect URIs (exact match validation) */\n get redirectUris(): string[];\n /** Array of scopes this client can request */\n get allowedScopes(): string[];\n /** Supported grant types (authorization_code, client_credentials, refresh_token) */\n get allowedGrantTypes(): string[];\n /** True for server-side apps (can keep secret secure), false for mobile/desktop apps */\n get isConfidential(): boolean;\n /** Whether the client is currently active */\n get isActive(): boolean;\n /** When the client was created */\n get createdAt(): Date;\n /** When the client was last updated */\n get updatedAt(): Date;\n}\n\n/**\n * Input type for OAuth client CRUD operations\n */\nexport type OAuthClientInput = {\n id?: string;\n name?: string;\n description?: string;\n redirectUris?: string[];\n allowedScopes?: string[];\n allowedGrantTypes?: string[];\n isConfidential?: boolean;\n isActive?: boolean;\n};\n\n/**\n * Request body for creating a new OAuth client\n */\nexport interface OAuthClientCreateRequest {\n /** Required: Human-readable application name */\n name: string;\n /** Optional: Description of the application */\n description?: string;\n /** Required: At least one redirect URI */\n redirectUris: string[];\n /** Required: Array of scopes the client needs */\n allowedScopes: string[];\n /** Optional: Grant types (defaults to authorization_code + refresh_token) */\n allowedGrantTypes?: string[];\n /** Required: Whether this is a confidential client */\n isConfidential: boolean;\n}\n\n/**\n * Response when creating a client (includes one-time secret)\n */\nexport interface OAuthClientCreateResponse {\n client: OAuthClientInterface;\n /** Only returned on creation - must be saved immediately */\n clientSecret?: string;\n}\n\n/**\n * Parameters for the OAuth authorization consent flow\n * Passed via URL query parameters to the consent page\n */\nexport interface OAuthConsentRequest {\n /** The client_id requesting authorization */\n clientId: string;\n /** Where to redirect after authorization */\n redirectUri: string;\n /** Space-separated list of requested scopes */\n scope: string;\n /** CSRF protection token (passed back on redirect) */\n state?: string;\n /** PKCE code challenge (required for public clients) */\n codeChallenge?: string;\n /** PKCE method: 'S256' (recommended) or 'plain' */\n codeChallengeMethod?: string;\n}\n\n/**\n * Scope information for display in consent screen\n */\nexport interface OAuthScopeInfo {\n /** The scope identifier (e.g., 'photographs:read') */\n scope: string;\n /** Human-readable scope name */\n name: string;\n /** Description of what this scope allows */\n description: string;\n /** Optional icon identifier */\n icon?: string;\n}\n\n/**\n * Client info returned for consent screen display\n */\nexport interface OAuthConsentInfo {\n client: OAuthClientInterface;\n scopes: OAuthScopeInfo[];\n}\n\n/**\n * Default scope display configuration\n * Maps scope identifiers to human-readable info\n */\nexport const OAUTH_SCOPE_DISPLAY: Record<string, OAuthScopeInfo> = {\n read: {\n scope: \"read\",\n name: \"Read Access\",\n description: \"Read access to your data\",\n icon: \"eye\",\n },\n write: {\n scope: \"write\",\n name: \"Write Access\",\n description: \"Write access to your data\",\n icon: \"pencil\",\n },\n \"photographs:read\": {\n scope: \"photographs:read\",\n name: \"View Photographs\",\n description: \"Access and download your photo library\",\n icon: \"image\",\n },\n \"photographs:write\": {\n scope: \"photographs:write\",\n name: \"Upload Photographs\",\n description: \"Add new photos to your rolls\",\n icon: \"upload\",\n },\n \"rolls:read\": {\n scope: \"rolls:read\",\n name: \"View Rolls\",\n description: \"See your film rolls and collections\",\n icon: \"film\",\n },\n \"rolls:write\": {\n scope: \"rolls:write\",\n name: \"Manage Rolls\",\n description: \"Create and modify film rolls\",\n icon: \"folder-plus\",\n },\n profile: {\n scope: \"profile\",\n name: \"View Profile\",\n description: \"Access your name and email\",\n icon: \"user\",\n },\n admin: {\n scope: \"admin\",\n name: \"Administrative Access\",\n description: \"Full administrative access to your account\",\n icon: \"shield\",\n },\n};\n\n/**\n * Available scopes list for the scope selector\n */\nexport const AVAILABLE_OAUTH_SCOPES: OAuthScopeInfo[] = Object.values(OAUTH_SCOPE_DISPLAY);\n\n/**\n * Default grant types for new clients\n */\nexport const DEFAULT_GRANT_TYPES = [\"authorization_code\", \"refresh_token\"];\n"]}
|