@endora-commerce/mod-invoice-ledger 0.100.0
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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/admin/api/ledger-client.d.ts +15 -0
- package/dist/admin/api/ledger-client.d.ts.map +1 -0
- package/dist/admin/api/ledger-client.js +35 -0
- package/dist/admin/api/ledger-client.js.map +1 -0
- package/dist/admin/index.d.ts +11 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +52 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/LedgerDeliveriesPage.d.ts +4 -0
- package/dist/admin/pages/LedgerDeliveriesPage.d.ts.map +1 -0
- package/dist/admin/pages/LedgerDeliveriesPage.js +101 -0
- package/dist/admin/pages/LedgerDeliveriesPage.js.map +1 -0
- package/dist/admin/pages/LedgerRoutingPage.d.ts +4 -0
- package/dist/admin/pages/LedgerRoutingPage.d.ts.map +1 -0
- package/dist/admin/pages/LedgerRoutingPage.js +67 -0
- package/dist/admin/pages/LedgerRoutingPage.js.map +1 -0
- package/dist/admin/pages/merge-delivery-pages.d.ts +3 -0
- package/dist/admin/pages/merge-delivery-pages.d.ts.map +1 -0
- package/dist/admin/pages/merge-delivery-pages.js +5 -0
- package/dist/admin/pages/merge-delivery-pages.js.map +1 -0
- package/dist/admin/zones/InvoiceLedgerRemoteIdPanel.d.ts +11 -0
- package/dist/admin/zones/InvoiceLedgerRemoteIdPanel.d.ts.map +1 -0
- package/dist/admin/zones/InvoiceLedgerRemoteIdPanel.js +36 -0
- package/dist/admin/zones/InvoiceLedgerRemoteIdPanel.js.map +1 -0
- package/dist/admin/zones/LedgerDeliveriesTab.d.ts +10 -0
- package/dist/admin/zones/LedgerDeliveriesTab.d.ts.map +1 -0
- package/dist/admin/zones/LedgerDeliveriesTab.js +15 -0
- package/dist/admin/zones/LedgerDeliveriesTab.js.map +1 -0
- package/dist/admin/zones/LedgerRoutingTab.d.ts +11 -0
- package/dist/admin/zones/LedgerRoutingTab.d.ts.map +1 -0
- package/dist/admin/zones/LedgerRoutingTab.js +16 -0
- package/dist/admin/zones/LedgerRoutingTab.js.map +1 -0
- package/dist/backend/commands/retry-delivery.command.d.ts +8 -0
- package/dist/backend/commands/retry-delivery.command.d.ts.map +1 -0
- package/dist/backend/commands/retry-delivery.command.js +26 -0
- package/dist/backend/commands/retry-delivery.command.js.map +1 -0
- package/dist/backend/commands/routing.commands.d.ts +7 -0
- package/dist/backend/commands/routing.commands.d.ts.map +1 -0
- package/dist/backend/commands/routing.commands.js +13 -0
- package/dist/backend/commands/routing.commands.js.map +1 -0
- package/dist/backend/entities/invoice-ledger-activation-lock.entity.d.ts +15 -0
- package/dist/backend/entities/invoice-ledger-activation-lock.entity.d.ts.map +1 -0
- package/dist/backend/entities/invoice-ledger-activation-lock.entity.js +46 -0
- package/dist/backend/entities/invoice-ledger-activation-lock.entity.js.map +1 -0
- package/dist/backend/entities/invoice-ledger-client-map.entity.d.ts +18 -0
- package/dist/backend/entities/invoice-ledger-client-map.entity.d.ts.map +1 -0
- package/dist/backend/entities/invoice-ledger-client-map.entity.js +72 -0
- package/dist/backend/entities/invoice-ledger-client-map.entity.js.map +1 -0
- package/dist/backend/entities/invoice-ledger-delivery.entity.d.ts +65 -0
- package/dist/backend/entities/invoice-ledger-delivery.entity.d.ts.map +1 -0
- package/dist/backend/entities/invoice-ledger-delivery.entity.js +168 -0
- package/dist/backend/entities/invoice-ledger-delivery.entity.js.map +1 -0
- package/dist/backend/entities/invoice-ledger-document-map.entity.d.ts +25 -0
- package/dist/backend/entities/invoice-ledger-document-map.entity.d.ts.map +1 -0
- package/dist/backend/entities/invoice-ledger-document-map.entity.js +80 -0
- package/dist/backend/entities/invoice-ledger-document-map.entity.js.map +1 -0
- package/dist/backend/entities/invoice-ledger-webhook-receipt.entity.d.ts +18 -0
- package/dist/backend/entities/invoice-ledger-webhook-receipt.entity.d.ts.map +1 -0
- package/dist/backend/entities/invoice-ledger-webhook-receipt.entity.js +71 -0
- package/dist/backend/entities/invoice-ledger-webhook-receipt.entity.js.map +1 -0
- package/dist/backend/index.d.ts +12 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +230 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +11 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +36 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/services/invoice-ledger-delivery-admin.service.d.ts +33 -0
- package/dist/backend/services/invoice-ledger-delivery-admin.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-delivery-admin.service.js +104 -0
- package/dist/backend/services/invoice-ledger-delivery-admin.service.js.map +1 -0
- package/dist/backend/services/invoice-ledger-delivery.service.d.ts +55 -0
- package/dist/backend/services/invoice-ledger-delivery.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-delivery.service.js +322 -0
- package/dist/backend/services/invoice-ledger-delivery.service.js.map +1 -0
- package/dist/backend/services/invoice-ledger-registry.service.d.ts +64 -0
- package/dist/backend/services/invoice-ledger-registry.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-registry.service.js +119 -0
- package/dist/backend/services/invoice-ledger-registry.service.js.map +1 -0
- package/dist/backend/services/invoice-ledger-routing-write.service.d.ts +15 -0
- package/dist/backend/services/invoice-ledger-routing-write.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-routing-write.service.js +85 -0
- package/dist/backend/services/invoice-ledger-routing-write.service.js.map +1 -0
- package/dist/backend/services/invoice-ledger-routing.service.d.ts +11 -0
- package/dist/backend/services/invoice-ledger-routing.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-routing.service.js +20 -0
- package/dist/backend/services/invoice-ledger-routing.service.js.map +1 -0
- package/dist/backend/services/invoice-ledger-vendor-freeze-registry.d.ts +9 -0
- package/dist/backend/services/invoice-ledger-vendor-freeze-registry.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-vendor-freeze-registry.js +13 -0
- package/dist/backend/services/invoice-ledger-vendor-freeze-registry.js.map +1 -0
- package/dist/backend/services/invoice-ledger-webhook.service.d.ts +30 -0
- package/dist/backend/services/invoice-ledger-webhook.service.d.ts.map +1 -0
- package/dist/backend/services/invoice-ledger-webhook.service.js +170 -0
- package/dist/backend/services/invoice-ledger-webhook.service.js.map +1 -0
- package/dist/backend/services/mapped-delivery-error.d.ts +25 -0
- package/dist/backend/services/mapped-delivery-error.d.ts.map +1 -0
- package/dist/backend/services/mapped-delivery-error.js +54 -0
- package/dist/backend/services/mapped-delivery-error.js.map +1 -0
- package/dist/manifest.d.ts +183 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +112 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260908T125013_invoice_ledger_init.d.ts +12 -0
- package/dist/migrations/20260908T125013_invoice_ledger_init.d.ts.map +1 -0
- package/dist/migrations/20260908T125013_invoice_ledger_init.js +167 -0
- package/dist/migrations/20260908T125013_invoice_ledger_init.js.map +1 -0
- package/dist/migrations/20260914T140000_invoice_ledger_row_organization.d.ts +64 -0
- package/dist/migrations/20260914T140000_invoice_ledger_row_organization.d.ts.map +1 -0
- package/dist/migrations/20260914T140000_invoice_ledger_row_organization.js +126 -0
- package/dist/migrations/20260914T140000_invoice_ledger_row_organization.js.map +1 -0
- package/dist/migrations/index.d.ts +13 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +16 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/invoice-ledger.md +22 -0
- package/i18n/en.json +50 -0
- package/i18n/pl.json +50 -0
- package/package.json +89 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type InvoiceLedgerNativeKsefAction, type InvoiceLedgerNumberingMode, type InvoiceLedgerRegistryPort, type InvoiceLedgerRoutingPort } from '@endora-commerce/contracts';
|
|
2
|
+
import type { SettingsReadPort } from '@endora-commerce/platform/kernel';
|
|
3
|
+
export declare class InvoiceLedgerRoutingService implements InvoiceLedgerRoutingPort {
|
|
4
|
+
private readonly settings;
|
|
5
|
+
private readonly registry;
|
|
6
|
+
constructor(settings: SettingsReadPort, registry: Pick<InvoiceLedgerRegistryPort, 'getActiveModuleId'>);
|
|
7
|
+
numberingModeFor(salesChannelId: string | null): Promise<InvoiceLedgerNumberingMode>;
|
|
8
|
+
nativeKsefActionFor(salesChannelId: string | null): Promise<InvoiceLedgerNativeKsefAction>;
|
|
9
|
+
activeVendorModuleId(): Promise<string | null>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=invoice-ledger-routing.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-routing.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-routing.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,qBAAa,2BAA4B,YAAW,wBAAwB;IAExE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,IAAI,CAAC,yBAAyB,EAAE,mBAAmB,CAAC;IAG3E,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAQpF,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAS1F,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAGrD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { INVOICE_LEDGER_SETTING_CODES, invoiceLedgerKsefRoutingSchema, invoiceLedgerNumberingModeSchema, } from '@endora-commerce/contracts';
|
|
2
|
+
export class InvoiceLedgerRoutingService {
|
|
3
|
+
settings;
|
|
4
|
+
registry;
|
|
5
|
+
constructor(settings, registry) {
|
|
6
|
+
this.settings = settings;
|
|
7
|
+
this.registry = registry;
|
|
8
|
+
}
|
|
9
|
+
async numberingModeFor(salesChannelId) {
|
|
10
|
+
return this.settings.get(INVOICE_LEDGER_SETTING_CODES.NUMBERING_MODE, salesChannelId, invoiceLedgerNumberingModeSchema);
|
|
11
|
+
}
|
|
12
|
+
async nativeKsefActionFor(salesChannelId) {
|
|
13
|
+
const routing = await this.settings.get(INVOICE_LEDGER_SETTING_CODES.KSEF_ROUTING, salesChannelId, invoiceLedgerKsefRoutingSchema);
|
|
14
|
+
return routing === 'vendor' ? 'skip' : 'submit';
|
|
15
|
+
}
|
|
16
|
+
async activeVendorModuleId() {
|
|
17
|
+
return this.registry.getActiveModuleId();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=invoice-ledger-routing.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-routing.service.js","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-routing.service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,EAC9B,gCAAgC,GAKjC,MAAM,4BAA4B,CAAC;AAGpC,MAAM,OAAO,2BAA2B;IAEnB;IACA;IAFnB,YACmB,QAA0B,EAC1B,QAA8D;QAD9D,aAAQ,GAAR,QAAQ,CAAkB;QAC1B,aAAQ,GAAR,QAAQ,CAAsD;IAC9E,CAAC;IAEJ,KAAK,CAAC,gBAAgB,CAAC,cAA6B;QAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CACtB,4BAA4B,CAAC,cAAc,EAC3C,cAAc,EACd,gCAAgC,CACjC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,cAA6B;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CACrC,4BAA4B,CAAC,YAAY,EACzC,cAAc,EACd,8BAA8B,CAC/B,CAAC;QACF,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InvoiceLedgerVendorFreeze, InvoiceLedgerVendorFreezeRegistryPort } from '@endora-commerce/contracts';
|
|
2
|
+
type FreezeResolver = (salesChannelId: string | null) => Promise<InvoiceLedgerVendorFreeze>;
|
|
3
|
+
export declare class InvoiceLedgerVendorFreezeRegistry implements InvoiceLedgerVendorFreezeRegistryPort {
|
|
4
|
+
private readonly resolvers;
|
|
5
|
+
register(adapterId: string, resolve: FreezeResolver, _module: string): void;
|
|
6
|
+
resolve(adapterId: string, salesChannelId: string | null): Promise<InvoiceLedgerVendorFreeze | null>;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=invoice-ledger-vendor-freeze-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-vendor-freeze-registry.d.ts","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-vendor-freeze-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,qCAAqC,EACtC,MAAM,4BAA4B,CAAC;AAEpC,KAAK,cAAc,GAAG,CACpB,cAAc,EAAE,MAAM,GAAG,IAAI,KAC1B,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAExC,qBAAa,iCAAkC,YAAW,qCAAqC;IAC7F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAE/D,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrE,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;CAK7C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class InvoiceLedgerVendorFreezeRegistry {
|
|
2
|
+
resolvers = new Map();
|
|
3
|
+
register(adapterId, resolve, _module) {
|
|
4
|
+
this.resolvers.set(adapterId, resolve);
|
|
5
|
+
}
|
|
6
|
+
async resolve(adapterId, salesChannelId) {
|
|
7
|
+
const resolve = this.resolvers.get(adapterId);
|
|
8
|
+
if (!resolve)
|
|
9
|
+
return null;
|
|
10
|
+
return resolve(salesChannelId);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=invoice-ledger-vendor-freeze-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-vendor-freeze-registry.js","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-vendor-freeze-registry.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,iCAAiC;IAC3B,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE/D,QAAQ,CAAC,SAAiB,EAAE,OAAuB,EAAE,OAAe;QAClE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,SAAiB,EACjB,cAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
2
|
+
import { type InvoiceKsefAssignmentPort, type InvoiceLedgerDeliveryPort, type InvoiceLedgerWebhookEventInput, type InvoiceLedgerWebhookPort, type InvoiceNumberingHostPort, type InvoicePaidHostPort } from '@endora-commerce/contracts';
|
|
3
|
+
export interface InvoiceLedgerWebhookServiceDeps {
|
|
4
|
+
emFactory: () => EntityManager;
|
|
5
|
+
deliveries: InvoiceLedgerDeliveryPort;
|
|
6
|
+
numbering: InvoiceNumberingHostPort;
|
|
7
|
+
paid: InvoicePaidHostPort;
|
|
8
|
+
ksefAssignment: InvoiceKsefAssignmentPort;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Receipt claim + apply for authenticated ledger-vendor webhooks.
|
|
12
|
+
* HMAC stays on the adapter route. Apply uses frozen delivery columns.
|
|
13
|
+
*/
|
|
14
|
+
export declare class InvoiceLedgerWebhookService implements InvoiceLedgerWebhookPort {
|
|
15
|
+
private readonly deps;
|
|
16
|
+
constructor(deps: InvoiceLedgerWebhookServiceDeps);
|
|
17
|
+
handleAuthenticatedEvent(input: InvoiceLedgerWebhookEventInput): Promise<{
|
|
18
|
+
outcome: 'applied' | 'duplicate' | 'acknowledged';
|
|
19
|
+
}>;
|
|
20
|
+
private run;
|
|
21
|
+
private claim;
|
|
22
|
+
private settle;
|
|
23
|
+
private apply;
|
|
24
|
+
private applyCreationSuccess;
|
|
25
|
+
private applyCreationError;
|
|
26
|
+
private findCreationDelivery;
|
|
27
|
+
private lookupUniqueMap;
|
|
28
|
+
private stampRemotePaid;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=invoice-ledger-webhook.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-webhook.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-webhook.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EAEzB,MAAM,4BAA4B,CAAC;AAepC,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,aAAa,CAAC;IAC/B,UAAU,EAAE,yBAAyB,CAAC;IACtC,SAAS,EAAE,wBAAwB,CAAC;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,cAAc,EAAE,yBAAyB,CAAC;CAC3C;AAOD;;;GAGG;AACH,qBAAa,2BAA4B,YAAW,wBAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,+BAA+B;IAE5D,wBAAwB,CAC5B,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC;QAAE,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,cAAc,CAAA;KAAE,CAAC;YAInD,GAAG;YAUH,KAAK;YAoBL,MAAM;YAcN,KAAK;YA6CL,oBAAoB;YAoBpB,kBAAkB;YAYlB,oBAAoB;YAuBpB,eAAe;YAgBf,eAAe;CAS9B"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { INVOICE_LEDGER_ASYNC_CREATE_FAILED_MESSAGE, INVOICE_LEDGER_VENDOR_KSEF_SEND_FAILED_MESSAGE, } from '@endora-commerce/contracts';
|
|
3
|
+
import { mappedDeliveryError } from './mapped-delivery-error.js';
|
|
4
|
+
import { enterSystemScope } from '@endora-commerce/platform/kernel';
|
|
5
|
+
import { InvoiceLedgerDocumentMap } from '../entities/invoice-ledger-document-map.entity.js';
|
|
6
|
+
import { InvoiceLedgerDelivery } from '../entities/invoice-ledger-delivery.entity.js';
|
|
7
|
+
import { InvoiceLedgerWebhookReceipt } from '../entities/invoice-ledger-webhook-receipt.entity.js';
|
|
8
|
+
const APPLIED_TYPES = new Set([
|
|
9
|
+
'async_invoice_creation_success',
|
|
10
|
+
'async_invoice_creation_error',
|
|
11
|
+
'invoice_paid',
|
|
12
|
+
'send_to_ksef_success',
|
|
13
|
+
'send_to_ksef_error',
|
|
14
|
+
]);
|
|
15
|
+
/**
|
|
16
|
+
* Receipt claim + apply for authenticated ledger-vendor webhooks.
|
|
17
|
+
* HMAC stays on the adapter route. Apply uses frozen delivery columns.
|
|
18
|
+
*/
|
|
19
|
+
export class InvoiceLedgerWebhookService {
|
|
20
|
+
deps;
|
|
21
|
+
constructor(deps) {
|
|
22
|
+
this.deps = deps;
|
|
23
|
+
}
|
|
24
|
+
async handleAuthenticatedEvent(input) {
|
|
25
|
+
return enterSystemScope('invoice ledger webhook', () => this.run(input));
|
|
26
|
+
}
|
|
27
|
+
async run(input) {
|
|
28
|
+
const claimed = await this.claim(input);
|
|
29
|
+
if (!claimed)
|
|
30
|
+
return { outcome: 'duplicate' };
|
|
31
|
+
const outcome = await this.apply(input);
|
|
32
|
+
await this.settle(input, 'processed');
|
|
33
|
+
return { outcome };
|
|
34
|
+
}
|
|
35
|
+
async claim(input) {
|
|
36
|
+
const em = this.deps.emFactory();
|
|
37
|
+
// command-coverage-ignore: claim INSERT … ON CONFLICT for this module's
|
|
38
|
+
// webhook ledger — see InpostWebhookLedger.claim.
|
|
39
|
+
const rows = await em.execute(`insert into "invoice_ledger_webhook_receipts"
|
|
40
|
+
("id", "adapter_id", "event_id", "event_type", "state", "attempts", "received_at")
|
|
41
|
+
values (?, ?, ?, ?, 'received', 1, now())
|
|
42
|
+
on conflict ("adapter_id", "event_id") do update
|
|
43
|
+
set "attempts" = "invoice_ledger_webhook_receipts"."attempts" + 1,
|
|
44
|
+
"received_at" = now(),
|
|
45
|
+
"state" = 'received',
|
|
46
|
+
"error" = null
|
|
47
|
+
where "invoice_ledger_webhook_receipts"."state" in ('failed', 'received')
|
|
48
|
+
returning "id"`, [randomUUID(), input.adapterId, input.eventId.slice(0, 128), input.eventType.slice(0, 64)]);
|
|
49
|
+
return rows.length > 0;
|
|
50
|
+
}
|
|
51
|
+
async settle(input, state) {
|
|
52
|
+
// command-coverage-ignore: closes this module's own webhook ledger row —
|
|
53
|
+
// see `claim` above.
|
|
54
|
+
const em = this.deps.emFactory();
|
|
55
|
+
await em.nativeUpdate(InvoiceLedgerWebhookReceipt, { adapterId: input.adapterId, eventId: input.eventId.slice(0, 128) }, { state, appliedAt: new Date(), error: null });
|
|
56
|
+
}
|
|
57
|
+
async apply(input) {
|
|
58
|
+
if (!APPLIED_TYPES.has(input.eventType))
|
|
59
|
+
return 'acknowledged';
|
|
60
|
+
if (input.eventType === 'async_invoice_creation_success') {
|
|
61
|
+
return this.applyCreationSuccess(input);
|
|
62
|
+
}
|
|
63
|
+
if (input.eventType === 'async_invoice_creation_error') {
|
|
64
|
+
return this.applyCreationError(input);
|
|
65
|
+
}
|
|
66
|
+
const lookup = await this.lookupUniqueMap(input.adapterId, input.remoteDocumentId);
|
|
67
|
+
if (lookup.kind !== 'unique')
|
|
68
|
+
return 'acknowledged';
|
|
69
|
+
const delivery = await this.deps.deliveries.findByInvoice(input.adapterId, lookup.invoiceId);
|
|
70
|
+
if (input.eventType === 'invoice_paid') {
|
|
71
|
+
await this.deps.paid.recordPaidFromLedger(lookup.invoiceId);
|
|
72
|
+
if (delivery) {
|
|
73
|
+
await this.stampRemotePaid(delivery.id);
|
|
74
|
+
}
|
|
75
|
+
return 'applied';
|
|
76
|
+
}
|
|
77
|
+
if (input.eventType === 'send_to_ksef_success') {
|
|
78
|
+
if (delivery?.ksefRouting !== 'vendor' || !input.ksefReferenceNumber) {
|
|
79
|
+
return 'acknowledged';
|
|
80
|
+
}
|
|
81
|
+
await this.deps.ksefAssignment.recordKsefAssignment(lookup.invoiceId, {
|
|
82
|
+
ksefReferenceNumber: input.ksefReferenceNumber,
|
|
83
|
+
ksefProcessedAt: new Date(),
|
|
84
|
+
});
|
|
85
|
+
return 'applied';
|
|
86
|
+
}
|
|
87
|
+
if (input.eventType === 'send_to_ksef_error') {
|
|
88
|
+
if (delivery) {
|
|
89
|
+
await this.deps.deliveries.markFailed(delivery.id, mappedDeliveryError(input.errorMessage) ?? INVOICE_LEDGER_VENDOR_KSEF_SEND_FAILED_MESSAGE);
|
|
90
|
+
}
|
|
91
|
+
return 'applied';
|
|
92
|
+
}
|
|
93
|
+
return 'acknowledged';
|
|
94
|
+
}
|
|
95
|
+
async applyCreationSuccess(input) {
|
|
96
|
+
const delivery = await this.findCreationDelivery(input);
|
|
97
|
+
if (!delivery)
|
|
98
|
+
return 'acknowledged';
|
|
99
|
+
if (delivery.numberingMode === 'vendor' && input.vendorNumber) {
|
|
100
|
+
await this.deps.numbering.applyVendorAssignedNumber(delivery.invoiceId, input.vendorNumber);
|
|
101
|
+
}
|
|
102
|
+
if (delivery.ksefRouting === 'vendor' && input.ksefReferenceNumber) {
|
|
103
|
+
await this.deps.ksefAssignment.recordKsefAssignment(delivery.invoiceId, {
|
|
104
|
+
ksefReferenceNumber: input.ksefReferenceNumber,
|
|
105
|
+
ksefProcessedAt: new Date(),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (input.remoteDocumentId) {
|
|
109
|
+
await this.deps.deliveries.markSucceeded(delivery.id, input.remoteDocumentId);
|
|
110
|
+
}
|
|
111
|
+
return 'applied';
|
|
112
|
+
}
|
|
113
|
+
async applyCreationError(input) {
|
|
114
|
+
const delivery = await this.findCreationDelivery(input);
|
|
115
|
+
if (!delivery)
|
|
116
|
+
return 'acknowledged';
|
|
117
|
+
await this.deps.deliveries.markFailed(delivery.id, mappedDeliveryError(input.errorMessage) ?? INVOICE_LEDGER_ASYNC_CREATE_FAILED_MESSAGE);
|
|
118
|
+
return 'applied';
|
|
119
|
+
}
|
|
120
|
+
async findCreationDelivery(input) {
|
|
121
|
+
if (input.asyncTaskId) {
|
|
122
|
+
const row = await this.deps.emFactory().findOne(InvoiceLedgerDelivery, {
|
|
123
|
+
adapterId: input.adapterId,
|
|
124
|
+
asyncTaskId: input.asyncTaskId,
|
|
125
|
+
});
|
|
126
|
+
if (row)
|
|
127
|
+
return this.deps.deliveries.getById(row.id);
|
|
128
|
+
}
|
|
129
|
+
if (input.remoteDocumentId) {
|
|
130
|
+
const rows = await this.deps.emFactory().find(InvoiceLedgerDelivery, {
|
|
131
|
+
adapterId: input.adapterId,
|
|
132
|
+
remoteDocumentId: input.remoteDocumentId,
|
|
133
|
+
});
|
|
134
|
+
if (rows.length !== 1)
|
|
135
|
+
return null;
|
|
136
|
+
const id = rows[0]?.id;
|
|
137
|
+
if (!id)
|
|
138
|
+
return null;
|
|
139
|
+
return this.deps.deliveries.getById(id);
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
async lookupUniqueMap(adapterId, remoteDocumentId) {
|
|
144
|
+
if (!remoteDocumentId)
|
|
145
|
+
return { kind: 'none' };
|
|
146
|
+
const maps = await this.deps.emFactory().find(InvoiceLedgerDocumentMap, {
|
|
147
|
+
adapterId,
|
|
148
|
+
remoteDocumentId,
|
|
149
|
+
});
|
|
150
|
+
if (maps.length === 0)
|
|
151
|
+
return { kind: 'none' };
|
|
152
|
+
if (maps.length > 1)
|
|
153
|
+
return { kind: 'ambiguous' };
|
|
154
|
+
const invoiceId = maps[0]?.invoiceId;
|
|
155
|
+
if (!invoiceId)
|
|
156
|
+
return { kind: 'none' };
|
|
157
|
+
return { kind: 'unique', invoiceId };
|
|
158
|
+
}
|
|
159
|
+
async stampRemotePaid(deliveryId) {
|
|
160
|
+
// command-coverage-ignore: webhook queue stamp that the remote invoice is
|
|
161
|
+
// paid — mirrors `InvoiceLedgerDeliveryService.markRemotePaid`.
|
|
162
|
+
const em = this.deps.emFactory();
|
|
163
|
+
const row = await em.findOne(InvoiceLedgerDelivery, { id: deliveryId });
|
|
164
|
+
if (!row)
|
|
165
|
+
return;
|
|
166
|
+
row.remotePaidAt = new Date();
|
|
167
|
+
await em.flush();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=invoice-ledger-webhook.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-ledger-webhook.service.js","sourceRoot":"","sources":["../../../src/backend/services/invoice-ledger-webhook.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A **vendor-independent shape floor** over `last_error` — D-256
|
|
3
|
+
* (`specs/080-f4-real-scope/rulings.md`).
|
|
4
|
+
*
|
|
5
|
+
* The promise is *"no dump reaches the stored field"*, **not** *"only these
|
|
6
|
+
* sentences do"*. The vendor that authors an operator sentence owns both the
|
|
7
|
+
* vocabulary and the mapping that produces it; this module holds no vendor
|
|
8
|
+
* vocabulary and recognises no vendor sentence. What it refuses is a shape no
|
|
9
|
+
* operator sentence has: markup, a control character, a serialised body, or a
|
|
10
|
+
* length no sentence reaches. Anything else is stored as the vendor wrote it —
|
|
11
|
+
* including prose this module has never seen. Each vendor asserts, in its own
|
|
12
|
+
* package and beside its own vocabulary, that every sentence it can hand the
|
|
13
|
+
* ledger clears this floor.
|
|
14
|
+
*
|
|
15
|
+
* Refusal is whole: an input that fails a clause becomes
|
|
16
|
+
* `INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR`, never a prefix of itself. Half a
|
|
17
|
+
* sentence is prose nobody wrote and can cut a leaked token in two.
|
|
18
|
+
*
|
|
19
|
+
* **Scope.** This is the `last_error` column and nothing else. The neighbouring
|
|
20
|
+
* `attempts[].error` JSONB is stored as it arrives and returned as stored by
|
|
21
|
+
* `POST /api/v1/admin/invoice-ledger/deliveries/:id/retry` — outside this
|
|
22
|
+
* floor, recorded in `specs/deferred-defects.md`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function mappedDeliveryError(raw: string | null | undefined): string | null;
|
|
25
|
+
//# sourceMappingURL=mapped-delivery-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapped-delivery-error.d.ts","sourceRoot":"","sources":["../../../src/backend/services/mapped-delivery-error.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAajF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR } from '@endora-commerce/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* The longest sentence a ledger vendor is expected to author is well under
|
|
4
|
+
* this; the bound is a backstop against a body that happens to carry no
|
|
5
|
+
* markup, not a budget anyone should design against. A vendor that composes a
|
|
6
|
+
* sentence bounds its own composition — see `formatWfirmaValidationError`.
|
|
7
|
+
*/
|
|
8
|
+
const MAX_OPERATOR_SENTENCE_LENGTH = 500;
|
|
9
|
+
// C0, DEL and C1. A newline, a carriage return and a tab are the interesting
|
|
10
|
+
// members: they are what a header dump and a stack trace are made of.
|
|
11
|
+
const CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/;
|
|
12
|
+
/**
|
|
13
|
+
* A **vendor-independent shape floor** over `last_error` — D-256
|
|
14
|
+
* (`specs/080-f4-real-scope/rulings.md`).
|
|
15
|
+
*
|
|
16
|
+
* The promise is *"no dump reaches the stored field"*, **not** *"only these
|
|
17
|
+
* sentences do"*. The vendor that authors an operator sentence owns both the
|
|
18
|
+
* vocabulary and the mapping that produces it; this module holds no vendor
|
|
19
|
+
* vocabulary and recognises no vendor sentence. What it refuses is a shape no
|
|
20
|
+
* operator sentence has: markup, a control character, a serialised body, or a
|
|
21
|
+
* length no sentence reaches. Anything else is stored as the vendor wrote it —
|
|
22
|
+
* including prose this module has never seen. Each vendor asserts, in its own
|
|
23
|
+
* package and beside its own vocabulary, that every sentence it can hand the
|
|
24
|
+
* ledger clears this floor.
|
|
25
|
+
*
|
|
26
|
+
* Refusal is whole: an input that fails a clause becomes
|
|
27
|
+
* `INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR`, never a prefix of itself. Half a
|
|
28
|
+
* sentence is prose nobody wrote and can cut a leaked token in two.
|
|
29
|
+
*
|
|
30
|
+
* **Scope.** This is the `last_error` column and nothing else. The neighbouring
|
|
31
|
+
* `attempts[].error` JSONB is stored as it arrives and returned as stored by
|
|
32
|
+
* `POST /api/v1/admin/invoice-ledger/deliveries/:id/retry` — outside this
|
|
33
|
+
* floor, recorded in `specs/deferred-defects.md`.
|
|
34
|
+
*/
|
|
35
|
+
export function mappedDeliveryError(raw) {
|
|
36
|
+
if (raw == null || raw === '')
|
|
37
|
+
return raw ?? null;
|
|
38
|
+
const trimmed = raw.trim();
|
|
39
|
+
// Whitespace-only is not an operator sentence, and storing `''` on a failed
|
|
40
|
+
// row would read as "no error". Today's answer, kept.
|
|
41
|
+
if (trimmed === '')
|
|
42
|
+
return INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR;
|
|
43
|
+
if (trimmed.includes('<') || trimmed.includes('>'))
|
|
44
|
+
return INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR;
|
|
45
|
+
if (CONTROL_CHARACTER.test(trimmed))
|
|
46
|
+
return INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR;
|
|
47
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
48
|
+
return INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR;
|
|
49
|
+
}
|
|
50
|
+
if (trimmed.length > MAX_OPERATOR_SENTENCE_LENGTH)
|
|
51
|
+
return INVOICE_LEDGER_UNREADABLE_VENDOR_ERROR;
|
|
52
|
+
return trimmed;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=mapped-delivery-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapped-delivery-error.js","sourceRoot":"","sources":["../../../src/backend/services/mapped-delivery-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sCAAsC,EAAE,MAAM,4BAA4B,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEzC,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,iBAAiB,GAAG,8BAA8B,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAA8B;IAChE,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,GAAG,IAAI,IAAI,CAAC;IAClD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,sDAAsD;IACtD,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,sCAAsC,CAAC;IAClE,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,sCAAsC,CAAC;IAClG,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,sCAAsC,CAAC;IACnF,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,OAAO,sCAAsC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,4BAA4B;QAAE,OAAO,sCAAsC,CAAC;IACjG,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
export declare const invoiceLedgerSettingsManifest: {
|
|
2
|
+
moduleCode: string;
|
|
3
|
+
groups: {
|
|
4
|
+
code: string;
|
|
5
|
+
name: string;
|
|
6
|
+
salesChannelCodes?: string[] | undefined;
|
|
7
|
+
isSystemProtected?: boolean | undefined;
|
|
8
|
+
}[];
|
|
9
|
+
settings: {
|
|
10
|
+
code: string;
|
|
11
|
+
name: string;
|
|
12
|
+
valueType: "string" | "number" | "boolean" | "json" | "string_list" | "secret" | "credential_ref";
|
|
13
|
+
defaultValue: unknown;
|
|
14
|
+
description?: string | undefined;
|
|
15
|
+
groupCode?: string | undefined;
|
|
16
|
+
previousDefaultValues?: unknown[] | undefined;
|
|
17
|
+
salesChannelCodes?: string[] | undefined;
|
|
18
|
+
enumOptions?: string[] | undefined;
|
|
19
|
+
configurationType?: string | undefined;
|
|
20
|
+
hidden?: boolean | undefined;
|
|
21
|
+
}[];
|
|
22
|
+
};
|
|
23
|
+
export declare const manifest: {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
version: string;
|
|
27
|
+
dependencies: string[];
|
|
28
|
+
description?: string | undefined;
|
|
29
|
+
acknowledgedDependencies?: {
|
|
30
|
+
moduleId: string;
|
|
31
|
+
port: string;
|
|
32
|
+
reason: string;
|
|
33
|
+
}[] | undefined;
|
|
34
|
+
nonBindingDependencies?: {
|
|
35
|
+
moduleId: string;
|
|
36
|
+
name: string;
|
|
37
|
+
kind: "contributes-to" | "degrades-without" | "refuses-without";
|
|
38
|
+
reason: string;
|
|
39
|
+
whenAbsent?: string | undefined;
|
|
40
|
+
}[] | undefined;
|
|
41
|
+
activation?: {
|
|
42
|
+
settingCode: string;
|
|
43
|
+
default: boolean;
|
|
44
|
+
} | {
|
|
45
|
+
nonDeactivatable: true;
|
|
46
|
+
reason: string;
|
|
47
|
+
} | undefined;
|
|
48
|
+
settings?: {
|
|
49
|
+
moduleCode: string;
|
|
50
|
+
groups: {
|
|
51
|
+
code: string;
|
|
52
|
+
name: string;
|
|
53
|
+
salesChannelCodes?: string[] | undefined;
|
|
54
|
+
isSystemProtected?: boolean | undefined;
|
|
55
|
+
}[];
|
|
56
|
+
settings: {
|
|
57
|
+
code: string;
|
|
58
|
+
name: string;
|
|
59
|
+
valueType: "string" | "number" | "boolean" | "json" | "string_list" | "secret" | "credential_ref";
|
|
60
|
+
defaultValue: unknown;
|
|
61
|
+
description?: string | undefined;
|
|
62
|
+
groupCode?: string | undefined;
|
|
63
|
+
previousDefaultValues?: unknown[] | undefined;
|
|
64
|
+
salesChannelCodes?: string[] | undefined;
|
|
65
|
+
enumOptions?: string[] | undefined;
|
|
66
|
+
configurationType?: string | undefined;
|
|
67
|
+
hidden?: boolean | undefined;
|
|
68
|
+
}[];
|
|
69
|
+
} | undefined;
|
|
70
|
+
i18n?: {
|
|
71
|
+
bundlesDir: string;
|
|
72
|
+
} | undefined;
|
|
73
|
+
docs?: false | {
|
|
74
|
+
dir: string;
|
|
75
|
+
} | undefined;
|
|
76
|
+
demo?: false | {
|
|
77
|
+
summary: string;
|
|
78
|
+
seed: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoSeedResult>;
|
|
79
|
+
reset: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoResetResult>;
|
|
80
|
+
after?: readonly string[] | undefined;
|
|
81
|
+
package?: string | undefined;
|
|
82
|
+
} | undefined;
|
|
83
|
+
actions?: {
|
|
84
|
+
id: string;
|
|
85
|
+
labelKey: string;
|
|
86
|
+
icon: "Plus" | "Sparkles" | "Settings" | "Search" | "Boxes" | "Layers" | "Menu" | "PlusCircle" | "PlusSquare" | "FilePlus" | "FolderPlus" | "Upload" | "FileUp" | "CloudUpload" | "Download" | "FileDown" | "FileText" | "BookOpen" | "Rss" | "Package" | "Tag" | "ShoppingCart" | "Receipt" | "CreditCard" | "Users" | "UserPlus" | "Inbox" | "ListChecks" | "ClipboardList" | "Image" | "Video" | "LayoutDashboard" | "PanelLeft" | "KeyRound" | "ShieldCheck" | "Edit" | "Archive" | "Box" | "Truck" | "CircleDollarSign" | "Activity" | "LineChart" | "Smartphone" | "Webhook" | "Scale" | "PlugZap" | "PercentDiamond" | "Newspaper" | "Languages" | "Eraser" | "Warehouse" | "TrendingDown" | "Bell" | "PackageOpen" | "Building2" | "Store" | "ClipboardCheck";
|
|
87
|
+
targetRoute: string;
|
|
88
|
+
keywords: string[];
|
|
89
|
+
weight: number;
|
|
90
|
+
descriptionKey?: string | undefined;
|
|
91
|
+
requiredPermission?: string | undefined;
|
|
92
|
+
}[] | undefined;
|
|
93
|
+
permissions?: {
|
|
94
|
+
code: string;
|
|
95
|
+
label: string;
|
|
96
|
+
module?: string | undefined;
|
|
97
|
+
description?: string | undefined;
|
|
98
|
+
requires?: string[] | undefined;
|
|
99
|
+
}[] | undefined;
|
|
100
|
+
transactionalEmails?: {
|
|
101
|
+
code: string;
|
|
102
|
+
name: string;
|
|
103
|
+
variables: {
|
|
104
|
+
key: string;
|
|
105
|
+
label: string;
|
|
106
|
+
sampleValue?: string | undefined;
|
|
107
|
+
description?: string | undefined;
|
|
108
|
+
}[];
|
|
109
|
+
description?: string | undefined;
|
|
110
|
+
group?: string | undefined;
|
|
111
|
+
}[] | undefined;
|
|
112
|
+
capabilities?: string[] | undefined;
|
|
113
|
+
exclusiveCapabilities?: {
|
|
114
|
+
key: string;
|
|
115
|
+
errorCode: string;
|
|
116
|
+
}[] | undefined;
|
|
117
|
+
errorCodes?: {
|
|
118
|
+
code: string;
|
|
119
|
+
tokens?: string[] | undefined;
|
|
120
|
+
}[] | undefined;
|
|
121
|
+
blocks?: {
|
|
122
|
+
name: string;
|
|
123
|
+
labelKey: string;
|
|
124
|
+
category: string;
|
|
125
|
+
contexts: ("invoice" | "email" | "cms" | "newsletter")[];
|
|
126
|
+
fields: Record<string, {
|
|
127
|
+
type: "number" | "object" | "array" | "text" | "textarea" | "select" | "radio" | "external" | "uuid" | "richtext";
|
|
128
|
+
label?: string | undefined;
|
|
129
|
+
required?: boolean | undefined;
|
|
130
|
+
options?: {
|
|
131
|
+
label: string;
|
|
132
|
+
value: string | number;
|
|
133
|
+
}[] | undefined;
|
|
134
|
+
refKind?: string | undefined;
|
|
135
|
+
}>;
|
|
136
|
+
descriptionKey?: string | undefined;
|
|
137
|
+
defaultProps?: Record<string, unknown> | undefined;
|
|
138
|
+
responsiveFields?: string[] | undefined;
|
|
139
|
+
previewIcon?: string | undefined;
|
|
140
|
+
weight?: number | undefined;
|
|
141
|
+
}[] | undefined;
|
|
142
|
+
blockCategories?: {
|
|
143
|
+
key: string;
|
|
144
|
+
titleKey: string;
|
|
145
|
+
contexts: ("invoice" | "email" | "cms" | "newsletter")[];
|
|
146
|
+
weight?: number | undefined;
|
|
147
|
+
visible?: boolean | undefined;
|
|
148
|
+
}[] | undefined;
|
|
149
|
+
env?: {
|
|
150
|
+
name: string;
|
|
151
|
+
describes: {
|
|
152
|
+
en: string;
|
|
153
|
+
pl: string;
|
|
154
|
+
};
|
|
155
|
+
requirement: {
|
|
156
|
+
kind: "required";
|
|
157
|
+
} | {
|
|
158
|
+
kind: "requiredWhen";
|
|
159
|
+
input: string;
|
|
160
|
+
equals: string;
|
|
161
|
+
} | {
|
|
162
|
+
kind: "optional";
|
|
163
|
+
without: {
|
|
164
|
+
en: string;
|
|
165
|
+
pl: string;
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
secret: boolean;
|
|
169
|
+
generable: boolean;
|
|
170
|
+
owner: {
|
|
171
|
+
kind: "platform";
|
|
172
|
+
} | {
|
|
173
|
+
kind: "application";
|
|
174
|
+
application: "admin" | "backend" | "storefront";
|
|
175
|
+
} | {
|
|
176
|
+
kind: "module";
|
|
177
|
+
moduleId: string;
|
|
178
|
+
};
|
|
179
|
+
consumers: ("admin" | "backend" | "storefront")[];
|
|
180
|
+
addressOf: "admin" | "backend" | "storefront" | null;
|
|
181
|
+
}[] | undefined;
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;CAyBxC,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FnB,CAAC"}
|