@open-mercato/shared 0.6.2-develop.3439.1.94b9d9733c → 0.6.2-develop.3446.1.bd060c6017

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.
@@ -1,4 +1,4 @@
1
- const APP_VERSION = "0.6.2-develop.3439.1.94b9d9733c";
1
+ const APP_VERSION = "0.6.2-develop.3446.1.bd060c6017";
2
2
  const appVersion = APP_VERSION;
3
3
  export {
4
4
  APP_VERSION,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.2-develop.3439.1.94b9d9733c'\nexport const appVersion = APP_VERSION\n"],
4
+ "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.2-develop.3446.1.bd060c6017'\nexport const appVersion = APP_VERSION\n"],
5
5
  "mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
6
6
  "names": []
7
7
  }
@@ -1,51 +1,64 @@
1
- const integrationRegistry = /* @__PURE__ */ new Map();
2
- const integrationBundleRegistry = /* @__PURE__ */ new Map();
1
+ const GLOBAL_INTEGRATION_REGISTRY_KEY = "__openMercatoIntegrationRegistry__";
2
+ function getIntegrationRegistryState() {
3
+ const globalRegistry = globalThis;
4
+ if (!globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY]) {
5
+ globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY] = {
6
+ integrations: /* @__PURE__ */ new Map(),
7
+ bundles: /* @__PURE__ */ new Map()
8
+ };
9
+ }
10
+ return globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY];
11
+ }
3
12
  function registerIntegration(definition) {
4
- integrationRegistry.set(definition.id, definition);
13
+ getIntegrationRegistryState().integrations.set(definition.id, definition);
5
14
  }
6
15
  function registerIntegrations(definitions) {
16
+ const registry = getIntegrationRegistryState().integrations;
7
17
  for (const definition of definitions) {
8
- integrationRegistry.set(definition.id, definition);
18
+ registry.set(definition.id, definition);
9
19
  }
10
20
  }
11
21
  function registerBundle(bundle) {
12
- integrationBundleRegistry.set(bundle.id, bundle);
22
+ getIntegrationRegistryState().bundles.set(bundle.id, bundle);
13
23
  }
14
24
  function registerBundles(bundles) {
25
+ const registry = getIntegrationRegistryState().bundles;
15
26
  for (const bundle of bundles) {
16
- integrationBundleRegistry.set(bundle.id, bundle);
27
+ registry.set(bundle.id, bundle);
17
28
  }
18
29
  }
19
30
  function clearRegisteredIntegrations() {
20
- integrationRegistry.clear();
21
- integrationBundleRegistry.clear();
31
+ const registry = getIntegrationRegistryState();
32
+ registry.integrations.clear();
33
+ registry.bundles.clear();
22
34
  }
23
35
  function getIntegration(integrationId) {
24
- return integrationRegistry.get(integrationId);
36
+ return getIntegrationRegistryState().integrations.get(integrationId);
25
37
  }
26
38
  function getAllIntegrations() {
27
- return Array.from(integrationRegistry.values());
39
+ return Array.from(getIntegrationRegistryState().integrations.values());
28
40
  }
29
41
  function getBundle(bundleId) {
30
- return integrationBundleRegistry.get(bundleId);
42
+ return getIntegrationRegistryState().bundles.get(bundleId);
31
43
  }
32
44
  function getAllBundles() {
33
- return Array.from(integrationBundleRegistry.values());
45
+ return Array.from(getIntegrationRegistryState().bundles.values());
34
46
  }
35
47
  function getBundleIntegrations(bundleId) {
36
- return Array.from(integrationRegistry.values()).filter((integration) => integration.bundleId === bundleId);
48
+ return Array.from(getIntegrationRegistryState().integrations.values()).filter((integration) => integration.bundleId === bundleId);
37
49
  }
38
50
  function resolveIntegrationCredentialsSchema(integrationId) {
39
- const definition = integrationRegistry.get(integrationId);
51
+ const registry = getIntegrationRegistryState();
52
+ const definition = registry.integrations.get(integrationId);
40
53
  if (!definition) return void 0;
41
54
  if (definition.credentials && definition.credentials.fields.length > 0) {
42
55
  return definition.credentials;
43
56
  }
44
57
  if (!definition.bundleId) return definition.credentials;
45
- return integrationBundleRegistry.get(definition.bundleId)?.credentials;
58
+ return registry.bundles.get(definition.bundleId)?.credentials;
46
59
  }
47
60
  function getIntegrationTitle(integrationId) {
48
- return integrationRegistry.get(integrationId)?.title ?? integrationId;
61
+ return getIntegrationRegistryState().integrations.get(integrationId)?.title ?? integrationId;
49
62
  }
50
63
  const LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID = "integrations.detail:tabs";
51
64
  function buildIntegrationDetailWidgetSpotId(integrationId) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/integrations/types.ts"],
4
- "sourcesContent": ["export type IntegrationScope = {\n organizationId: string\n tenantId: string\n}\n\nexport type IntegrationCategory =\n | 'payment'\n | 'shipping'\n | 'data_sync'\n | 'communication'\n | 'webhook'\n | 'storage'\n | 'other'\n\nexport type IntegrationHubId =\n | 'payment_gateways'\n | 'shipping_carriers'\n | 'data_sync'\n | 'communication_channels'\n | 'webhook_endpoints'\n | 'storage_hubs'\n | string\n\nexport type CredentialFieldType =\n | 'text'\n | 'secret'\n | 'select'\n | 'boolean'\n | 'url'\n | 'oauth'\n | 'ssh_keypair'\n\nexport interface CredentialFieldOption {\n value: string\n label: string\n}\n\nexport interface CredentialFieldVisibleWhen {\n field: string\n equals: string | number | boolean\n}\n\nexport interface IntegrationCredentialWebhookHelp {\n kind: 'webhook_setup'\n title: string\n summary: string\n endpointPath: string\n dashboardPathLabel: string\n steps: string[]\n events?: string[]\n localDevelopment?: {\n tunnelCommand: string\n publicUrlExample: string\n note?: string\n }\n}\n\nexport interface IntegrationCredentialFieldBase {\n key: string\n label: string\n required?: boolean\n placeholder?: string\n helpText?: string\n helpDetails?: IntegrationCredentialWebhookHelp\n visibleWhen?: CredentialFieldVisibleWhen\n}\n\nexport interface IntegrationCredentialFieldText extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'text' | 'secret' | 'url'>\n}\n\nexport interface IntegrationCredentialFieldBoolean extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'boolean'>\n}\n\nexport interface IntegrationCredentialFieldSelect extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'select'>\n options: CredentialFieldOption[]\n}\n\nexport interface IntegrationCredentialFieldOauth extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'oauth'>\n authUrl?: string\n tokenUrl?: string\n scopes?: string[]\n clientIdField?: string\n clientSecretField?: string\n}\n\nexport interface IntegrationCredentialFieldSshKeypair extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'ssh_keypair'>\n algorithm?: 'ed25519' | 'rsa'\n rsaBits?: 2048 | 3072 | 4096\n}\n\nexport type IntegrationCredentialField =\n | IntegrationCredentialFieldText\n | IntegrationCredentialFieldBoolean\n | IntegrationCredentialFieldSelect\n | IntegrationCredentialFieldOauth\n | IntegrationCredentialFieldSshKeypair\n\nexport interface IntegrationCredentialsSchema {\n fields: IntegrationCredentialField[]\n}\n\nexport interface IntegrationHealthCheckConfig {\n service: string\n}\n\nexport interface ApiVersionDefinition {\n id: string\n label: string\n status: 'stable' | 'deprecated' | 'experimental'\n default?: boolean\n changelog?: string\n deprecatedAt?: string\n sunsetAt?: string\n migrationGuide?: string\n}\n\nexport interface IntegrationBundle {\n id: string\n title: string\n description: string\n icon?: string\n package?: string\n version?: string\n author?: string\n credentials: IntegrationCredentialsSchema\n healthCheck?: IntegrationHealthCheckConfig\n}\n\nexport interface IntegrationDetailPageConfig {\n /**\n * UMES widget spot rendered on the integration detail page.\n * Widgets registered here can render inline blocks, grouped panels,\n * or additional tabs via `placement.kind`.\n */\n widgetSpotId?: string\n /**\n * Built-in tabs to hide for this integration detail page.\n * Provider modules can replace these with injected tabs using the same spot.\n */\n hiddenTabs?: IntegrationDetailBuiltInTab[]\n}\n\nexport type IntegrationDetailBuiltInTab =\n | 'credentials'\n | 'version'\n | 'health'\n | 'logs'\n | 'data-sync-schedule'\n\nexport interface IntegrationDefaultStateConfig {\n isEnabled?: boolean\n}\n\nexport interface IntegrationDefinition {\n id: string\n title: string\n icon?: string\n buildExternalUrl?: (externalId: string) => string\n bundleId?: string\n apiVersions?: ApiVersionDefinition[]\n description?: string\n category?: IntegrationCategory | string\n hub?: IntegrationHubId\n providerKey?: string\n docsUrl?: string\n package?: string\n version?: string\n author?: string\n company?: string\n license?: string\n tags?: string[]\n detailPage?: IntegrationDetailPageConfig\n defaultState?: IntegrationDefaultStateConfig\n credentials?: IntegrationCredentialsSchema\n healthCheck?: IntegrationHealthCheckConfig\n}\n\nexport interface ExternalIdEnrichment {\n _integrations: Record<string, ExternalIdMapping>\n}\n\nexport interface ExternalIdMapping {\n externalId: string\n externalUrl?: string\n lastSyncedAt?: string\n syncStatus: 'synced' | 'pending' | 'error' | 'not_synced'\n}\n\nconst integrationRegistry = new Map<string, IntegrationDefinition>()\nconst integrationBundleRegistry = new Map<string, IntegrationBundle>()\n\nexport function registerIntegration(definition: IntegrationDefinition): void {\n integrationRegistry.set(definition.id, definition)\n}\n\nexport function registerIntegrations(definitions: IntegrationDefinition[]): void {\n for (const definition of definitions) {\n integrationRegistry.set(definition.id, definition)\n }\n}\n\nexport function registerBundle(bundle: IntegrationBundle): void {\n integrationBundleRegistry.set(bundle.id, bundle)\n}\n\nexport function registerBundles(bundles: IntegrationBundle[]): void {\n for (const bundle of bundles) {\n integrationBundleRegistry.set(bundle.id, bundle)\n }\n}\n\nexport function clearRegisteredIntegrations(): void {\n integrationRegistry.clear()\n integrationBundleRegistry.clear()\n}\n\nexport function getIntegration(integrationId: string): IntegrationDefinition | undefined {\n return integrationRegistry.get(integrationId)\n}\n\nexport function getAllIntegrations(): IntegrationDefinition[] {\n return Array.from(integrationRegistry.values())\n}\n\nexport function getBundle(bundleId: string): IntegrationBundle | undefined {\n return integrationBundleRegistry.get(bundleId)\n}\n\nexport function getAllBundles(): IntegrationBundle[] {\n return Array.from(integrationBundleRegistry.values())\n}\n\nexport function getBundleIntegrations(bundleId: string): IntegrationDefinition[] {\n return Array.from(integrationRegistry.values()).filter((integration) => integration.bundleId === bundleId)\n}\n\nexport function resolveIntegrationCredentialsSchema(integrationId: string): IntegrationCredentialsSchema | undefined {\n const definition = integrationRegistry.get(integrationId)\n if (!definition) return undefined\n\n if (definition.credentials && definition.credentials.fields.length > 0) {\n return definition.credentials\n }\n\n if (!definition.bundleId) return definition.credentials\n return integrationBundleRegistry.get(definition.bundleId)?.credentials\n}\n\nexport function getIntegrationTitle(integrationId: string): string {\n return integrationRegistry.get(integrationId)?.title ?? integrationId\n}\n\nexport const LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID = 'integrations.detail:tabs'\n\nexport function buildIntegrationDetailWidgetSpotId(integrationId: string): string {\n return `integrations.detail:${integrationId}`\n}\n"],
5
- "mappings": "AAiMA,MAAM,sBAAsB,oBAAI,IAAmC;AACnE,MAAM,4BAA4B,oBAAI,IAA+B;AAE9D,SAAS,oBAAoB,YAAyC;AAC3E,sBAAoB,IAAI,WAAW,IAAI,UAAU;AACnD;AAEO,SAAS,qBAAqB,aAA4C;AAC/E,aAAW,cAAc,aAAa;AACpC,wBAAoB,IAAI,WAAW,IAAI,UAAU;AAAA,EACnD;AACF;AAEO,SAAS,eAAe,QAAiC;AAC9D,4BAA0B,IAAI,OAAO,IAAI,MAAM;AACjD;AAEO,SAAS,gBAAgB,SAAoC;AAClE,aAAW,UAAU,SAAS;AAC5B,8BAA0B,IAAI,OAAO,IAAI,MAAM;AAAA,EACjD;AACF;AAEO,SAAS,8BAAoC;AAClD,sBAAoB,MAAM;AAC1B,4BAA0B,MAAM;AAClC;AAEO,SAAS,eAAe,eAA0D;AACvF,SAAO,oBAAoB,IAAI,aAAa;AAC9C;AAEO,SAAS,qBAA8C;AAC5D,SAAO,MAAM,KAAK,oBAAoB,OAAO,CAAC;AAChD;AAEO,SAAS,UAAU,UAAiD;AACzE,SAAO,0BAA0B,IAAI,QAAQ;AAC/C;AAEO,SAAS,gBAAqC;AACnD,SAAO,MAAM,KAAK,0BAA0B,OAAO,CAAC;AACtD;AAEO,SAAS,sBAAsB,UAA2C;AAC/E,SAAO,MAAM,KAAK,oBAAoB,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,YAAY,aAAa,QAAQ;AAC3G;AAEO,SAAS,oCAAoC,eAAiE;AACnH,QAAM,aAAa,oBAAoB,IAAI,aAAa;AACxD,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI,WAAW,eAAe,WAAW,YAAY,OAAO,SAAS,GAAG;AACtE,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,CAAC,WAAW,SAAU,QAAO,WAAW;AAC5C,SAAO,0BAA0B,IAAI,WAAW,QAAQ,GAAG;AAC7D;AAEO,SAAS,oBAAoB,eAA+B;AACjE,SAAO,oBAAoB,IAAI,aAAa,GAAG,SAAS;AAC1D;AAEO,MAAM,yCAAyC;AAE/C,SAAS,mCAAmC,eAA+B;AAChF,SAAO,uBAAuB,aAAa;AAC7C;",
4
+ "sourcesContent": ["export type IntegrationScope = {\n organizationId: string\n tenantId: string\n}\n\nexport type IntegrationCategory =\n | 'payment'\n | 'shipping'\n | 'data_sync'\n | 'communication'\n | 'webhook'\n | 'storage'\n | 'other'\n\nexport type IntegrationHubId =\n | 'payment_gateways'\n | 'shipping_carriers'\n | 'data_sync'\n | 'communication_channels'\n | 'webhook_endpoints'\n | 'storage_hubs'\n | string\n\nexport type CredentialFieldType =\n | 'text'\n | 'secret'\n | 'select'\n | 'boolean'\n | 'url'\n | 'oauth'\n | 'ssh_keypair'\n\nexport interface CredentialFieldOption {\n value: string\n label: string\n}\n\nexport interface CredentialFieldVisibleWhen {\n field: string\n equals: string | number | boolean\n}\n\nexport interface IntegrationCredentialWebhookHelp {\n kind: 'webhook_setup'\n title: string\n summary: string\n endpointPath: string\n dashboardPathLabel: string\n steps: string[]\n events?: string[]\n localDevelopment?: {\n tunnelCommand: string\n publicUrlExample: string\n note?: string\n }\n}\n\nexport interface IntegrationCredentialFieldBase {\n key: string\n label: string\n required?: boolean\n placeholder?: string\n helpText?: string\n helpDetails?: IntegrationCredentialWebhookHelp\n visibleWhen?: CredentialFieldVisibleWhen\n}\n\nexport interface IntegrationCredentialFieldText extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'text' | 'secret' | 'url'>\n}\n\nexport interface IntegrationCredentialFieldBoolean extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'boolean'>\n}\n\nexport interface IntegrationCredentialFieldSelect extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'select'>\n options: CredentialFieldOption[]\n}\n\nexport interface IntegrationCredentialFieldOauth extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'oauth'>\n authUrl?: string\n tokenUrl?: string\n scopes?: string[]\n clientIdField?: string\n clientSecretField?: string\n}\n\nexport interface IntegrationCredentialFieldSshKeypair extends IntegrationCredentialFieldBase {\n type: Extract<CredentialFieldType, 'ssh_keypair'>\n algorithm?: 'ed25519' | 'rsa'\n rsaBits?: 2048 | 3072 | 4096\n}\n\nexport type IntegrationCredentialField =\n | IntegrationCredentialFieldText\n | IntegrationCredentialFieldBoolean\n | IntegrationCredentialFieldSelect\n | IntegrationCredentialFieldOauth\n | IntegrationCredentialFieldSshKeypair\n\nexport interface IntegrationCredentialsSchema {\n fields: IntegrationCredentialField[]\n}\n\nexport interface IntegrationHealthCheckConfig {\n service: string\n}\n\nexport interface ApiVersionDefinition {\n id: string\n label: string\n status: 'stable' | 'deprecated' | 'experimental'\n default?: boolean\n changelog?: string\n deprecatedAt?: string\n sunsetAt?: string\n migrationGuide?: string\n}\n\nexport interface IntegrationBundle {\n id: string\n title: string\n description: string\n icon?: string\n package?: string\n version?: string\n author?: string\n credentials: IntegrationCredentialsSchema\n healthCheck?: IntegrationHealthCheckConfig\n}\n\nexport interface IntegrationDetailPageConfig {\n /**\n * UMES widget spot rendered on the integration detail page.\n * Widgets registered here can render inline blocks, grouped panels,\n * or additional tabs via `placement.kind`.\n */\n widgetSpotId?: string\n /**\n * Built-in tabs to hide for this integration detail page.\n * Provider modules can replace these with injected tabs using the same spot.\n */\n hiddenTabs?: IntegrationDetailBuiltInTab[]\n}\n\nexport type IntegrationDetailBuiltInTab =\n | 'credentials'\n | 'version'\n | 'health'\n | 'logs'\n | 'data-sync-schedule'\n\nexport interface IntegrationDefaultStateConfig {\n isEnabled?: boolean\n}\n\nexport interface IntegrationDefinition {\n id: string\n title: string\n icon?: string\n buildExternalUrl?: (externalId: string) => string\n bundleId?: string\n apiVersions?: ApiVersionDefinition[]\n description?: string\n category?: IntegrationCategory | string\n hub?: IntegrationHubId\n providerKey?: string\n docsUrl?: string\n package?: string\n version?: string\n author?: string\n company?: string\n license?: string\n tags?: string[]\n detailPage?: IntegrationDetailPageConfig\n defaultState?: IntegrationDefaultStateConfig\n credentials?: IntegrationCredentialsSchema\n healthCheck?: IntegrationHealthCheckConfig\n}\n\nexport interface ExternalIdEnrichment {\n _integrations: Record<string, ExternalIdMapping>\n}\n\nexport interface ExternalIdMapping {\n externalId: string\n externalUrl?: string\n lastSyncedAt?: string\n syncStatus: 'synced' | 'pending' | 'error' | 'not_synced'\n}\n\ntype IntegrationRegistryState = {\n integrations: Map<string, IntegrationDefinition>\n bundles: Map<string, IntegrationBundle>\n}\n\nconst GLOBAL_INTEGRATION_REGISTRY_KEY = '__openMercatoIntegrationRegistry__' as const\n\ntype GlobalIntegrationRegistry = typeof globalThis & {\n [GLOBAL_INTEGRATION_REGISTRY_KEY]?: IntegrationRegistryState\n}\n\nfunction getIntegrationRegistryState(): IntegrationRegistryState {\n const globalRegistry = globalThis as GlobalIntegrationRegistry\n if (!globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY]) {\n globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY] = {\n integrations: new Map<string, IntegrationDefinition>(),\n bundles: new Map<string, IntegrationBundle>(),\n }\n }\n return globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY]\n}\n\nexport function registerIntegration(definition: IntegrationDefinition): void {\n getIntegrationRegistryState().integrations.set(definition.id, definition)\n}\n\nexport function registerIntegrations(definitions: IntegrationDefinition[]): void {\n const registry = getIntegrationRegistryState().integrations\n for (const definition of definitions) {\n registry.set(definition.id, definition)\n }\n}\n\nexport function registerBundle(bundle: IntegrationBundle): void {\n getIntegrationRegistryState().bundles.set(bundle.id, bundle)\n}\n\nexport function registerBundles(bundles: IntegrationBundle[]): void {\n const registry = getIntegrationRegistryState().bundles\n for (const bundle of bundles) {\n registry.set(bundle.id, bundle)\n }\n}\n\nexport function clearRegisteredIntegrations(): void {\n const registry = getIntegrationRegistryState()\n registry.integrations.clear()\n registry.bundles.clear()\n}\n\nexport function getIntegration(integrationId: string): IntegrationDefinition | undefined {\n return getIntegrationRegistryState().integrations.get(integrationId)\n}\n\nexport function getAllIntegrations(): IntegrationDefinition[] {\n return Array.from(getIntegrationRegistryState().integrations.values())\n}\n\nexport function getBundle(bundleId: string): IntegrationBundle | undefined {\n return getIntegrationRegistryState().bundles.get(bundleId)\n}\n\nexport function getAllBundles(): IntegrationBundle[] {\n return Array.from(getIntegrationRegistryState().bundles.values())\n}\n\nexport function getBundleIntegrations(bundleId: string): IntegrationDefinition[] {\n return Array.from(getIntegrationRegistryState().integrations.values()).filter((integration) => integration.bundleId === bundleId)\n}\n\nexport function resolveIntegrationCredentialsSchema(integrationId: string): IntegrationCredentialsSchema | undefined {\n const registry = getIntegrationRegistryState()\n const definition = registry.integrations.get(integrationId)\n if (!definition) return undefined\n\n if (definition.credentials && definition.credentials.fields.length > 0) {\n return definition.credentials\n }\n\n if (!definition.bundleId) return definition.credentials\n return registry.bundles.get(definition.bundleId)?.credentials\n}\n\nexport function getIntegrationTitle(integrationId: string): string {\n return getIntegrationRegistryState().integrations.get(integrationId)?.title ?? integrationId\n}\n\nexport const LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID = 'integrations.detail:tabs'\n\nexport function buildIntegrationDetailWidgetSpotId(integrationId: string): string {\n return `integrations.detail:${integrationId}`\n}\n"],
5
+ "mappings": "AAsMA,MAAM,kCAAkC;AAMxC,SAAS,8BAAwD;AAC/D,QAAM,iBAAiB;AACvB,MAAI,CAAC,eAAe,+BAA+B,GAAG;AACpD,mBAAe,+BAA+B,IAAI;AAAA,MAChD,cAAc,oBAAI,IAAmC;AAAA,MACrD,SAAS,oBAAI,IAA+B;AAAA,IAC9C;AAAA,EACF;AACA,SAAO,eAAe,+BAA+B;AACvD;AAEO,SAAS,oBAAoB,YAAyC;AAC3E,8BAA4B,EAAE,aAAa,IAAI,WAAW,IAAI,UAAU;AAC1E;AAEO,SAAS,qBAAqB,aAA4C;AAC/E,QAAM,WAAW,4BAA4B,EAAE;AAC/C,aAAW,cAAc,aAAa;AACpC,aAAS,IAAI,WAAW,IAAI,UAAU;AAAA,EACxC;AACF;AAEO,SAAS,eAAe,QAAiC;AAC9D,8BAA4B,EAAE,QAAQ,IAAI,OAAO,IAAI,MAAM;AAC7D;AAEO,SAAS,gBAAgB,SAAoC;AAClE,QAAM,WAAW,4BAA4B,EAAE;AAC/C,aAAW,UAAU,SAAS;AAC5B,aAAS,IAAI,OAAO,IAAI,MAAM;AAAA,EAChC;AACF;AAEO,SAAS,8BAAoC;AAClD,QAAM,WAAW,4BAA4B;AAC7C,WAAS,aAAa,MAAM;AAC5B,WAAS,QAAQ,MAAM;AACzB;AAEO,SAAS,eAAe,eAA0D;AACvF,SAAO,4BAA4B,EAAE,aAAa,IAAI,aAAa;AACrE;AAEO,SAAS,qBAA8C;AAC5D,SAAO,MAAM,KAAK,4BAA4B,EAAE,aAAa,OAAO,CAAC;AACvE;AAEO,SAAS,UAAU,UAAiD;AACzE,SAAO,4BAA4B,EAAE,QAAQ,IAAI,QAAQ;AAC3D;AAEO,SAAS,gBAAqC;AACnD,SAAO,MAAM,KAAK,4BAA4B,EAAE,QAAQ,OAAO,CAAC;AAClE;AAEO,SAAS,sBAAsB,UAA2C;AAC/E,SAAO,MAAM,KAAK,4BAA4B,EAAE,aAAa,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,YAAY,aAAa,QAAQ;AAClI;AAEO,SAAS,oCAAoC,eAAiE;AACnH,QAAM,WAAW,4BAA4B;AAC7C,QAAM,aAAa,SAAS,aAAa,IAAI,aAAa;AAC1D,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI,WAAW,eAAe,WAAW,YAAY,OAAO,SAAS,GAAG;AACtE,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,CAAC,WAAW,SAAU,QAAO,WAAW;AAC5C,SAAO,SAAS,QAAQ,IAAI,WAAW,QAAQ,GAAG;AACpD;AAEO,SAAS,oBAAoB,eAA+B;AACjE,SAAO,4BAA4B,EAAE,aAAa,IAAI,aAAa,GAAG,SAAS;AACjF;AAEO,MAAM,yCAAyC;AAE/C,SAAS,mCAAmC,eAA+B;AAChF,SAAO,uBAAuB,aAAa;AAC7C;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/shared",
3
- "version": "0.6.2-develop.3439.1.94b9d9733c",
3
+ "version": "0.6.2-develop.3446.1.bd060c6017",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -92,7 +92,7 @@
92
92
  "@mikro-orm/core": "^7.0.15",
93
93
  "@mikro-orm/decorators": "^7.0.15",
94
94
  "@mikro-orm/postgresql": "^7.0.15",
95
- "@open-mercato/cache": "0.6.2-develop.3439.1.94b9d9733c",
95
+ "@open-mercato/cache": "0.6.2-develop.3446.1.bd060c6017",
96
96
  "dotenv": "^17.4.2",
97
97
  "rate-limiter-flexible": "^11.1.0",
98
98
  "reflect-metadata": "^0.2.2",
@@ -0,0 +1,46 @@
1
+ import type * as IntegrationTypes from '../types'
2
+
3
+ describe('integration registry', () => {
4
+ afterEach(() => {
5
+ jest.requireActual<typeof IntegrationTypes>('../types').clearRegisteredIntegrations()
6
+ })
7
+
8
+ it('shares registrations across isolated module instances', () => {
9
+ let firstRegistry: typeof IntegrationTypes | undefined
10
+ let secondRegistry: typeof IntegrationTypes | undefined
11
+
12
+ jest.isolateModules(() => {
13
+ firstRegistry = jest.requireActual<typeof IntegrationTypes>('../types')
14
+ })
15
+
16
+ firstRegistry?.clearRegisteredIntegrations()
17
+ firstRegistry?.registerIntegration({
18
+ id: 'sync_excel',
19
+ title: 'Excel / CSV Import',
20
+ providerKey: 'excel',
21
+ })
22
+
23
+ jest.isolateModules(() => {
24
+ secondRegistry = jest.requireActual<typeof IntegrationTypes>('../types')
25
+ })
26
+
27
+ expect(secondRegistry?.getIntegration('sync_excel')?.providerKey).toBe('excel')
28
+ })
29
+
30
+ it('clears bundles and integrations from the shared registry state', () => {
31
+ const registry = jest.requireActual<typeof IntegrationTypes>('../types')
32
+
33
+ registry.registerIntegration({ id: 'sync_excel', title: 'Excel / CSV Import' })
34
+ registry.registerBundle({
35
+ id: 'bundle_1',
36
+ title: 'Bundle',
37
+ description: 'Bundle description',
38
+ credentials: { fields: [] },
39
+ })
40
+
41
+ registry.clearRegisteredIntegrations()
42
+
43
+ expect(registry.getAllIntegrations()).toEqual([])
44
+ expect(registry.getAllBundles()).toEqual([])
45
+ })
46
+ })
@@ -191,56 +191,79 @@ export interface ExternalIdMapping {
191
191
  syncStatus: 'synced' | 'pending' | 'error' | 'not_synced'
192
192
  }
193
193
 
194
- const integrationRegistry = new Map<string, IntegrationDefinition>()
195
- const integrationBundleRegistry = new Map<string, IntegrationBundle>()
194
+ type IntegrationRegistryState = {
195
+ integrations: Map<string, IntegrationDefinition>
196
+ bundles: Map<string, IntegrationBundle>
197
+ }
198
+
199
+ const GLOBAL_INTEGRATION_REGISTRY_KEY = '__openMercatoIntegrationRegistry__' as const
200
+
201
+ type GlobalIntegrationRegistry = typeof globalThis & {
202
+ [GLOBAL_INTEGRATION_REGISTRY_KEY]?: IntegrationRegistryState
203
+ }
204
+
205
+ function getIntegrationRegistryState(): IntegrationRegistryState {
206
+ const globalRegistry = globalThis as GlobalIntegrationRegistry
207
+ if (!globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY]) {
208
+ globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY] = {
209
+ integrations: new Map<string, IntegrationDefinition>(),
210
+ bundles: new Map<string, IntegrationBundle>(),
211
+ }
212
+ }
213
+ return globalRegistry[GLOBAL_INTEGRATION_REGISTRY_KEY]
214
+ }
196
215
 
197
216
  export function registerIntegration(definition: IntegrationDefinition): void {
198
- integrationRegistry.set(definition.id, definition)
217
+ getIntegrationRegistryState().integrations.set(definition.id, definition)
199
218
  }
200
219
 
201
220
  export function registerIntegrations(definitions: IntegrationDefinition[]): void {
221
+ const registry = getIntegrationRegistryState().integrations
202
222
  for (const definition of definitions) {
203
- integrationRegistry.set(definition.id, definition)
223
+ registry.set(definition.id, definition)
204
224
  }
205
225
  }
206
226
 
207
227
  export function registerBundle(bundle: IntegrationBundle): void {
208
- integrationBundleRegistry.set(bundle.id, bundle)
228
+ getIntegrationRegistryState().bundles.set(bundle.id, bundle)
209
229
  }
210
230
 
211
231
  export function registerBundles(bundles: IntegrationBundle[]): void {
232
+ const registry = getIntegrationRegistryState().bundles
212
233
  for (const bundle of bundles) {
213
- integrationBundleRegistry.set(bundle.id, bundle)
234
+ registry.set(bundle.id, bundle)
214
235
  }
215
236
  }
216
237
 
217
238
  export function clearRegisteredIntegrations(): void {
218
- integrationRegistry.clear()
219
- integrationBundleRegistry.clear()
239
+ const registry = getIntegrationRegistryState()
240
+ registry.integrations.clear()
241
+ registry.bundles.clear()
220
242
  }
221
243
 
222
244
  export function getIntegration(integrationId: string): IntegrationDefinition | undefined {
223
- return integrationRegistry.get(integrationId)
245
+ return getIntegrationRegistryState().integrations.get(integrationId)
224
246
  }
225
247
 
226
248
  export function getAllIntegrations(): IntegrationDefinition[] {
227
- return Array.from(integrationRegistry.values())
249
+ return Array.from(getIntegrationRegistryState().integrations.values())
228
250
  }
229
251
 
230
252
  export function getBundle(bundleId: string): IntegrationBundle | undefined {
231
- return integrationBundleRegistry.get(bundleId)
253
+ return getIntegrationRegistryState().bundles.get(bundleId)
232
254
  }
233
255
 
234
256
  export function getAllBundles(): IntegrationBundle[] {
235
- return Array.from(integrationBundleRegistry.values())
257
+ return Array.from(getIntegrationRegistryState().bundles.values())
236
258
  }
237
259
 
238
260
  export function getBundleIntegrations(bundleId: string): IntegrationDefinition[] {
239
- return Array.from(integrationRegistry.values()).filter((integration) => integration.bundleId === bundleId)
261
+ return Array.from(getIntegrationRegistryState().integrations.values()).filter((integration) => integration.bundleId === bundleId)
240
262
  }
241
263
 
242
264
  export function resolveIntegrationCredentialsSchema(integrationId: string): IntegrationCredentialsSchema | undefined {
243
- const definition = integrationRegistry.get(integrationId)
265
+ const registry = getIntegrationRegistryState()
266
+ const definition = registry.integrations.get(integrationId)
244
267
  if (!definition) return undefined
245
268
 
246
269
  if (definition.credentials && definition.credentials.fields.length > 0) {
@@ -248,11 +271,11 @@ export function resolveIntegrationCredentialsSchema(integrationId: string): Inte
248
271
  }
249
272
 
250
273
  if (!definition.bundleId) return definition.credentials
251
- return integrationBundleRegistry.get(definition.bundleId)?.credentials
274
+ return registry.bundles.get(definition.bundleId)?.credentials
252
275
  }
253
276
 
254
277
  export function getIntegrationTitle(integrationId: string): string {
255
- return integrationRegistry.get(integrationId)?.title ?? integrationId
278
+ return getIntegrationRegistryState().integrations.get(integrationId)?.title ?? integrationId
256
279
  }
257
280
 
258
281
  export const LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID = 'integrations.detail:tabs'