@endora-commerce/contracts 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 +34 -0
- package/dist/actor.d.ts +79 -0
- package/dist/actor.d.ts.map +1 -0
- package/dist/actor.js +41 -0
- package/dist/actor.js.map +1 -0
- package/dist/addresses.d.ts +134 -0
- package/dist/addresses.d.ts.map +1 -0
- package/dist/addresses.js +16 -0
- package/dist/addresses.js.map +1 -0
- package/dist/admin-actions.d.ts +367 -0
- package/dist/admin-actions.d.ts.map +1 -0
- package/dist/admin-actions.js +287 -0
- package/dist/admin-actions.js.map +1 -0
- package/dist/admin-contributions.d.ts +518 -0
- package/dist/admin-contributions.d.ts.map +1 -0
- package/dist/admin-contributions.js +495 -0
- package/dist/admin-contributions.js.map +1 -0
- package/dist/admin-i18n.d.ts +135 -0
- package/dist/admin-i18n.d.ts.map +1 -0
- package/dist/admin-i18n.js +72 -0
- package/dist/admin-i18n.js.map +1 -0
- package/dist/admin-notifications.d.ts +55 -0
- package/dist/admin-notifications.d.ts.map +1 -0
- package/dist/admin-notifications.js +16 -0
- package/dist/admin-notifications.js.map +1 -0
- package/dist/admin-roles.d.ts +125 -0
- package/dist/admin-roles.d.ts.map +1 -0
- package/dist/admin-roles.js +2 -0
- package/dist/admin-roles.js.map +1 -0
- package/dist/admin-users.d.ts +178 -0
- package/dist/admin-users.d.ts.map +1 -0
- package/dist/admin-users.js +14 -0
- package/dist/admin-users.js.map +1 -0
- package/dist/admin.d.ts +243 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +246 -0
- package/dist/admin.js.map +1 -0
- package/dist/analytics.d.ts +123 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +68 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api-keys.d.ts +97 -0
- package/dist/api-keys.d.ts.map +1 -0
- package/dist/api-keys.js +64 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/assets-library.d.ts +684 -0
- package/dist/assets-library.d.ts.map +1 -0
- package/dist/assets-library.js +181 -0
- package/dist/assets-library.js.map +1 -0
- package/dist/audit-logs.d.ts +141 -0
- package/dist/audit-logs.d.ts.map +1 -0
- package/dist/audit-logs.js +31 -0
- package/dist/audit-logs.js.map +1 -0
- package/dist/auth.d.ts +174 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +27 -0
- package/dist/auth.js.map +1 -0
- package/dist/blog.d.ts +669 -0
- package/dist/blog.d.ts.map +1 -0
- package/dist/blog.js +360 -0
- package/dist/blog.js.map +1 -0
- package/dist/capabilities.d.ts +40 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +38 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/carts.d.ts +1367 -0
- package/dist/carts.d.ts.map +1 -0
- package/dist/carts.js +405 -0
- package/dist/carts.js.map +1 -0
- package/dist/catalog.d.ts +2855 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +1543 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cms.d.ts +872 -0
- package/dist/cms.d.ts.map +1 -0
- package/dist/cms.js +468 -0
- package/dist/cms.js.map +1 -0
- package/dist/common.d.ts +82 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +72 -0
- package/dist/common.js.map +1 -0
- package/dist/comparisons.d.ts +487 -0
- package/dist/comparisons.d.ts.map +1 -0
- package/dist/comparisons.js +221 -0
- package/dist/comparisons.js.map +1 -0
- package/dist/credentials.d.ts +292 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +142 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credit-limits.d.ts +111 -0
- package/dist/credit-limits.d.ts.map +1 -0
- package/dist/credit-limits.js +35 -0
- package/dist/credit-limits.js.map +1 -0
- package/dist/currencies.d.ts +127 -0
- package/dist/currencies.d.ts.map +1 -0
- package/dist/currencies.js +20 -0
- package/dist/currencies.js.map +1 -0
- package/dist/custom-fields.d.ts +345 -0
- package/dist/custom-fields.d.ts.map +1 -0
- package/dist/custom-fields.js +185 -0
- package/dist/custom-fields.js.map +1 -0
- package/dist/customer-accounts.d.ts +690 -0
- package/dist/customer-accounts.d.ts.map +1 -0
- package/dist/customer-accounts.js +41 -0
- package/dist/customer-accounts.js.map +1 -0
- package/dist/customers.d.ts +305 -0
- package/dist/customers.d.ts.map +1 -0
- package/dist/customers.js +158 -0
- package/dist/customers.js.map +1 -0
- package/dist/dictionary.d.ts +580 -0
- package/dist/dictionary.d.ts.map +1 -0
- package/dist/dictionary.js +297 -0
- package/dist/dictionary.js.map +1 -0
- package/dist/email-address.d.ts +62 -0
- package/dist/email-address.d.ts.map +1 -0
- package/dist/email-address.js +64 -0
- package/dist/email-address.js.map +1 -0
- package/dist/email.d.ts +175 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +45 -0
- package/dist/email.js.map +1 -0
- package/dist/envelopes.d.ts +15 -0
- package/dist/envelopes.d.ts.map +1 -0
- package/dist/envelopes.js +16 -0
- package/dist/envelopes.js.map +1 -0
- package/dist/environment-inputs.d.ts +306 -0
- package/dist/environment-inputs.d.ts.map +1 -0
- package/dist/environment-inputs.js +277 -0
- package/dist/environment-inputs.js.map +1 -0
- package/dist/erp-connector.d.ts +52 -0
- package/dist/erp-connector.d.ts.map +1 -0
- package/dist/erp-connector.js +34 -0
- package/dist/erp-connector.js.map +1 -0
- package/dist/errors.d.ts +455 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +532 -0
- package/dist/errors.js.map +1 -0
- package/dist/google-analytics.d.ts +181 -0
- package/dist/google-analytics.d.ts.map +1 -0
- package/dist/google-analytics.js +176 -0
- package/dist/google-analytics.js.map +1 -0
- package/dist/google-tag-manager.d.ts +111 -0
- package/dist/google-tag-manager.d.ts.map +1 -0
- package/dist/google-tag-manager.js +129 -0
- package/dist/google-tag-manager.js.map +1 -0
- package/dist/i18n.d.ts +69 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +59 -0
- package/dist/i18n.js.map +1 -0
- package/dist/import-export.d.ts +63 -0
- package/dist/import-export.d.ts.map +1 -0
- package/dist/import-export.js +37 -0
- package/dist/import-export.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +673 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +412 -0
- package/dist/inventory.js.map +1 -0
- package/dist/invoice-ledger.d.ts +366 -0
- package/dist/invoice-ledger.d.ts.map +1 -0
- package/dist/invoice-ledger.js +114 -0
- package/dist/invoice-ledger.js.map +1 -0
- package/dist/invoices.d.ts +845 -0
- package/dist/invoices.d.ts.map +1 -0
- package/dist/invoices.js +314 -0
- package/dist/invoices.js.map +1 -0
- package/dist/kernel.d.ts +49 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +19 -0
- package/dist/kernel.js.map +1 -0
- package/dist/languages.d.ts +122 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +24 -0
- package/dist/languages.js.map +1 -0
- package/dist/linkedin-ads.d.ts +167 -0
- package/dist/linkedin-ads.d.ts.map +1 -0
- package/dist/linkedin-ads.js +156 -0
- package/dist/linkedin-ads.js.map +1 -0
- package/dist/megamenu.d.ts +556 -0
- package/dist/megamenu.d.ts.map +1 -0
- package/dist/megamenu.js +186 -0
- package/dist/megamenu.js.map +1 -0
- package/dist/meta-ads.d.ts +126 -0
- package/dist/meta-ads.d.ts.map +1 -0
- package/dist/meta-ads.js +112 -0
- package/dist/meta-ads.js.map +1 -0
- package/dist/mfa.d.ts +274 -0
- package/dist/mfa.d.ts.map +1 -0
- package/dist/mfa.js +187 -0
- package/dist/mfa.js.map +1 -0
- package/dist/modules.d.ts +1706 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +1390 -0
- package/dist/modules.js.map +1 -0
- package/dist/newsletter.d.ts +611 -0
- package/dist/newsletter.d.ts.map +1 -0
- package/dist/newsletter.js +345 -0
- package/dist/newsletter.js.map +1 -0
- package/dist/orders.d.ts +1175 -0
- package/dist/orders.d.ts.map +1 -0
- package/dist/orders.js +630 -0
- package/dist/orders.js.map +1 -0
- package/dist/organizations.d.ts +938 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +418 -0
- package/dist/organizations.js.map +1 -0
- package/dist/pagination.d.ts +21 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +22 -0
- package/dist/pagination.js.map +1 -0
- package/dist/payment-methods.d.ts +472 -0
- package/dist/payment-methods.d.ts.map +1 -0
- package/dist/payment-methods.js +175 -0
- package/dist/payment-methods.js.map +1 -0
- package/dist/payment-return-url.d.ts +53 -0
- package/dist/payment-return-url.d.ts.map +1 -0
- package/dist/payment-return-url.js +35 -0
- package/dist/payment-return-url.js.map +1 -0
- package/dist/payments.d.ts +386 -0
- package/dist/payments.d.ts.map +1 -0
- package/dist/payments.js +84 -0
- package/dist/payments.js.map +1 -0
- package/dist/pim-connector.d.ts +60 -0
- package/dist/pim-connector.d.ts.map +1 -0
- package/dist/pim-connector.js +43 -0
- package/dist/pim-connector.js.map +1 -0
- package/dist/pim-field-path.d.ts +6 -0
- package/dist/pim-field-path.d.ts.map +1 -0
- package/dist/pim-field-path.js +101 -0
- package/dist/pim-field-path.js.map +1 -0
- package/dist/platform-language.d.ts +20 -0
- package/dist/platform-language.d.ts.map +1 -0
- package/dist/platform-language.js +22 -0
- package/dist/platform-language.js.map +1 -0
- package/dist/price-lists.d.ts +685 -0
- package/dist/price-lists.d.ts.map +1 -0
- package/dist/price-lists.js +330 -0
- package/dist/price-lists.js.map +1 -0
- package/dist/product-feeds.d.ts +2837 -0
- package/dist/product-feeds.d.ts.map +1 -0
- package/dist/product-feeds.js +1504 -0
- package/dist/product-feeds.js.map +1 -0
- package/dist/product-scope-overrides.d.ts +134 -0
- package/dist/product-scope-overrides.d.ts.map +1 -0
- package/dist/product-scope-overrides.js +82 -0
- package/dist/product-scope-overrides.js.map +1 -0
- package/dist/product-value-resolver.d.ts +88 -0
- package/dist/product-value-resolver.d.ts.map +1 -0
- package/dist/product-value-resolver.js +128 -0
- package/dist/product-value-resolver.js.map +1 -0
- package/dist/promotions.d.ts +678 -0
- package/dist/promotions.d.ts.map +1 -0
- package/dist/promotions.js +479 -0
- package/dist/promotions.js.map +1 -0
- package/dist/prompt-actions.d.ts +582 -0
- package/dist/prompt-actions.d.ts.map +1 -0
- package/dist/prompt-actions.js +221 -0
- package/dist/prompt-actions.js.map +1 -0
- package/dist/pwa.d.ts +293 -0
- package/dist/pwa.d.ts.map +1 -0
- package/dist/pwa.js +204 -0
- package/dist/pwa.js.map +1 -0
- package/dist/quick-order.d.ts +340 -0
- package/dist/quick-order.d.ts.map +1 -0
- package/dist/quick-order.js +177 -0
- package/dist/quick-order.js.map +1 -0
- package/dist/quote-requests.d.ts +538 -0
- package/dist/quote-requests.d.ts.map +1 -0
- package/dist/quote-requests.js +308 -0
- package/dist/quote-requests.js.map +1 -0
- package/dist/returns.d.ts +774 -0
- package/dist/returns.d.ts.map +1 -0
- package/dist/returns.js +389 -0
- package/dist/returns.js.map +1 -0
- package/dist/sales-channels.d.ts +392 -0
- package/dist/sales-channels.d.ts.map +1 -0
- package/dist/sales-channels.js +285 -0
- package/dist/sales-channels.js.map +1 -0
- package/dist/scope-notice.d.ts +60 -0
- package/dist/scope-notice.d.ts.map +1 -0
- package/dist/scope-notice.js +56 -0
- package/dist/scope-notice.js.map +1 -0
- package/dist/search.d.ts +321 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +160 -0
- package/dist/search.js.map +1 -0
- package/dist/seo.d.ts +113 -0
- package/dist/seo.d.ts.map +1 -0
- package/dist/seo.js +63 -0
- package/dist/seo.js.map +1 -0
- package/dist/settings.d.ts +453 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +337 -0
- package/dist/settings.js.map +1 -0
- package/dist/shipments.d.ts +140 -0
- package/dist/shipments.d.ts.map +1 -0
- package/dist/shipments.js +14 -0
- package/dist/shipments.js.map +1 -0
- package/dist/shipping-methods.d.ts +350 -0
- package/dist/shipping-methods.d.ts.map +1 -0
- package/dist/shipping-methods.js +99 -0
- package/dist/shipping-methods.js.map +1 -0
- package/dist/shopping-lists.d.ts +122 -0
- package/dist/shopping-lists.d.ts.map +1 -0
- package/dist/shopping-lists.js +92 -0
- package/dist/shopping-lists.js.map +1 -0
- package/dist/taxes.d.ts +106 -0
- package/dist/taxes.d.ts.map +1 -0
- package/dist/taxes.js +80 -0
- package/dist/taxes.js.map +1 -0
- package/dist/text-normalization.d.ts +199 -0
- package/dist/text-normalization.d.ts.map +1 -0
- package/dist/text-normalization.js +205 -0
- package/dist/text-normalization.js.map +1 -0
- package/dist/transactional-emails.d.ts +459 -0
- package/dist/transactional-emails.d.ts.map +1 -0
- package/dist/transactional-emails.js +212 -0
- package/dist/transactional-emails.js.map +1 -0
- package/dist/webhooks.d.ts +69 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +53 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { uuidSchema, moneySchema, multilingualStringSchema } from './common.js';
|
|
3
|
+
import { attributeValueTypeSchema } from './catalog.js';
|
|
4
|
+
// @endora-commerce/contracts — Compare module contracts (feature 007).
|
|
5
|
+
//
|
|
6
|
+
// Per Constitution V, this file is the source of truth for every Zod schema
|
|
7
|
+
// crossing the comparisons HTTP boundary; TS types are inferred via z.infer.
|
|
8
|
+
//
|
|
9
|
+
// US1 schemas (this file): owner-facing CRUD payloads and the
|
|
10
|
+
// `ComparisonOwnerView` response. US2 (recipient view), US4 (PDF export),
|
|
11
|
+
// and US5 (admin overview) extend this file in their respective phases.
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Constants used by storefront + admin clients.
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
export const COMPARE_DISPLAY_MODES = ['all', 'common', 'differences'];
|
|
16
|
+
export const COMPARE_MAX_PRODUCTS_LOWER_BOUND = 1;
|
|
17
|
+
export const COMPARE_MAX_PRODUCTS_UPPER_BOUND = 16;
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Display mode and per-attribute row class.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export const comparisonDisplayModeSchema = z.enum(COMPARE_DISPLAY_MODES);
|
|
22
|
+
/**
|
|
23
|
+
* Server-computed classification per attribute row, per research.md R-6:
|
|
24
|
+
* - `'common'` — every product carries the same value (set-equal for
|
|
25
|
+
* multi-value, ===-equal for scalars).
|
|
26
|
+
* - `'different'` — at least one product disagrees, OR at least one
|
|
27
|
+
* product has no value at all.
|
|
28
|
+
*/
|
|
29
|
+
export const comparisonRowClassSchema = z.enum(['common', 'different']);
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Per-product card (always-on row of the comparison page / PDF).
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
export const comparisonProductSummarySchema = z.object({
|
|
34
|
+
id: uuidSchema,
|
|
35
|
+
sku: z.string(),
|
|
36
|
+
name: multilingualStringSchema,
|
|
37
|
+
slug: z.string(),
|
|
38
|
+
type: z.enum(['simple', 'configurable', 'grouped', 'bundle', 'virtual']),
|
|
39
|
+
/**
|
|
40
|
+
* Resolved base image (asset URL); null when the product has no
|
|
41
|
+
* `gallery_item_labels.label='base_image'` row or its asset cannot be
|
|
42
|
+
* resolved. The PDF renderer renders a placeholder when null.
|
|
43
|
+
*/
|
|
44
|
+
primaryAssetUrl: z.string().url().nullable(),
|
|
45
|
+
/**
|
|
46
|
+
* Price in the viewer's sales-channel currency. Null when the product
|
|
47
|
+
* has no resolvable price for the channel (e.g. shared-link recipient
|
|
48
|
+
* on a channel where the product is not listed).
|
|
49
|
+
*/
|
|
50
|
+
price: moneySchema.nullable(),
|
|
51
|
+
/**
|
|
52
|
+
* False when the product is not currently sellable in the viewer's
|
|
53
|
+
* channel — archived, channel-restricted, or otherwise refused. The
|
|
54
|
+
* column still renders, but the *Add to cart* control is disabled.
|
|
55
|
+
*/
|
|
56
|
+
available: z.boolean(),
|
|
57
|
+
addedAt: z.string().datetime(),
|
|
58
|
+
});
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Body row of the comparison table (one per `comparable` attribute).
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
export const comparisonAttributeRowSchema = z.object({
|
|
63
|
+
key: z.string(),
|
|
64
|
+
label: multilingualStringSchema,
|
|
65
|
+
valueType: attributeValueTypeSchema,
|
|
66
|
+
/**
|
|
67
|
+
* One entry per product in the same column-order as `products`. Strings
|
|
68
|
+
* are pre-formatted by the server for display; multi-value attributes
|
|
69
|
+
* are joined with `', '`. `null` represents "no value" — the storefront
|
|
70
|
+
* renders it as `—` (per spec edge case "Missing values"). Per R-6,
|
|
71
|
+
* any `null` causes the row to be classified as `'different'`.
|
|
72
|
+
*/
|
|
73
|
+
values: z.array(z.string().nullable()),
|
|
74
|
+
rowClass: comparisonRowClassSchema,
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* Whose prices the columns carry.
|
|
78
|
+
*
|
|
79
|
+
* The viewer's identity decides the figures, always: `organization` means they
|
|
80
|
+
* were resolved against the reader's own price lists, `channel` that they are
|
|
81
|
+
* the sales channel's public ones. A share token decides *which products* are
|
|
82
|
+
* in a comparison and never *which prices* are shown, so sender and recipient
|
|
83
|
+
* legitimately see different numbers on one link — and a reader who cannot tell
|
|
84
|
+
* which they are looking at cannot act on either.
|
|
85
|
+
*/
|
|
86
|
+
export const comparisonPricedForSchema = z.enum(['organization', 'channel']);
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Full owner-facing read response.
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
export const comparisonOwnerViewSchema = z.object({
|
|
91
|
+
id: uuidSchema,
|
|
92
|
+
shareToken: z.string().min(8).max(32),
|
|
93
|
+
displayMode: comparisonDisplayModeSchema,
|
|
94
|
+
/** Resolved `compare.max_products` for the owner's sales channel. */
|
|
95
|
+
maxProducts: z.number().int().positive(),
|
|
96
|
+
products: z.array(comparisonProductSummarySchema),
|
|
97
|
+
comparableAttributes: z.array(comparisonAttributeRowSchema),
|
|
98
|
+
/** Whose prices the `products[].price` figures are. */
|
|
99
|
+
pricedFor: comparisonPricedForSchema,
|
|
100
|
+
/**
|
|
101
|
+
* How many products the comparison holds that this viewer may not see.
|
|
102
|
+
* Zero for almost every read; non-zero for a recipient the owner's
|
|
103
|
+
* restricted products are not disclosed to, and for an owner whose own
|
|
104
|
+
* product was restricted after they added it. The count is what lets a
|
|
105
|
+
* shorter table say so instead of being silently shorter.
|
|
106
|
+
*/
|
|
107
|
+
hiddenProductCount: z.number().int().nonnegative(),
|
|
108
|
+
createdAt: z.string().datetime(),
|
|
109
|
+
updatedAt: z.string().datetime(),
|
|
110
|
+
});
|
|
111
|
+
export const comparisonOwnerResponseSchema = z.object({
|
|
112
|
+
data: comparisonOwnerViewSchema,
|
|
113
|
+
});
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Mutation inputs.
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
export const comparisonAddProductInputSchema = z.object({
|
|
118
|
+
productId: uuidSchema,
|
|
119
|
+
});
|
|
120
|
+
export const comparisonSetDisplayModeInputSchema = z.object({
|
|
121
|
+
displayMode: comparisonDisplayModeSchema,
|
|
122
|
+
});
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// US2 — recipient (share-token) view.
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Recipient-side projection. Same column shape as the owner view minus
|
|
128
|
+
* `maxProducts` (the recipient cannot mutate the comparison, so the cap
|
|
129
|
+
* is irrelevant) plus `meta.viewerIsOwner` so the storefront knows
|
|
130
|
+
* whether to render owner-only affordances (Add to cart, Remove,
|
|
131
|
+
* Delete, Copy share link).
|
|
132
|
+
*/
|
|
133
|
+
export const comparisonSharedViewSchema = z.object({
|
|
134
|
+
id: uuidSchema,
|
|
135
|
+
shareToken: z.string().min(8).max(32),
|
|
136
|
+
displayMode: comparisonDisplayModeSchema,
|
|
137
|
+
products: z.array(comparisonProductSummarySchema),
|
|
138
|
+
comparableAttributes: z.array(comparisonAttributeRowSchema),
|
|
139
|
+
/**
|
|
140
|
+
* Whose prices these are — the recipient's own, or the channel's. The
|
|
141
|
+
* sender's are never among the answers: the token carries the products, not
|
|
142
|
+
* a pricing identity.
|
|
143
|
+
*/
|
|
144
|
+
pricedFor: comparisonPricedForSchema,
|
|
145
|
+
/**
|
|
146
|
+
* How many of the sender's products this recipient may not see. The token
|
|
147
|
+
* grants access to the comparison, never to what is in it, so a recipient's
|
|
148
|
+
* table is the sender's minus whatever the sender's organisation alone is
|
|
149
|
+
* entitled to — and it says how much is missing rather than being quietly
|
|
150
|
+
* shorter.
|
|
151
|
+
*/
|
|
152
|
+
hiddenProductCount: z.number().int().nonnegative(),
|
|
153
|
+
createdAt: z.string().datetime(),
|
|
154
|
+
updatedAt: z.string().datetime(),
|
|
155
|
+
});
|
|
156
|
+
export const comparisonSharedResponseSchema = z.object({
|
|
157
|
+
data: comparisonSharedViewSchema,
|
|
158
|
+
meta: z.object({
|
|
159
|
+
viewerIsOwner: z.boolean(),
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// US5 — admin overview (read-only).
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
export const comparisonAdminOwnerSchema = z.object({
|
|
166
|
+
kind: z.enum(['customer', 'anonymous']),
|
|
167
|
+
customerAccountId: uuidSchema.nullable(),
|
|
168
|
+
/** Human-readable identifier for the list (email or display name). */
|
|
169
|
+
email: z.string().nullable(),
|
|
170
|
+
/** The opaque cookie token; null for authenticated owners. */
|
|
171
|
+
anonymousToken: z.string().nullable(),
|
|
172
|
+
});
|
|
173
|
+
export const comparisonAdminSalesChannelSchema = z.object({
|
|
174
|
+
id: uuidSchema,
|
|
175
|
+
code: z.string(),
|
|
176
|
+
});
|
|
177
|
+
export const comparisonAdminListItemSchema = z.object({
|
|
178
|
+
id: uuidSchema,
|
|
179
|
+
shareToken: z.string(),
|
|
180
|
+
owner: comparisonAdminOwnerSchema,
|
|
181
|
+
salesChannel: comparisonAdminSalesChannelSchema,
|
|
182
|
+
displayMode: comparisonDisplayModeSchema,
|
|
183
|
+
productCount: z.number().int().nonnegative(),
|
|
184
|
+
createdAt: z.string().datetime(),
|
|
185
|
+
updatedAt: z.string().datetime(),
|
|
186
|
+
});
|
|
187
|
+
export const comparisonAdminListQuerySchema = z.object({
|
|
188
|
+
salesChannelId: uuidSchema.optional(),
|
|
189
|
+
customerAccountId: uuidSchema.optional(),
|
|
190
|
+
ownerType: z.enum(['customer', 'anonymous']).optional(),
|
|
191
|
+
createdAfter: z.string().datetime().optional(),
|
|
192
|
+
createdBefore: z.string().datetime().optional(),
|
|
193
|
+
cursor: z.string().optional(),
|
|
194
|
+
limit: z.number().int().min(1).max(100).optional(),
|
|
195
|
+
});
|
|
196
|
+
export const comparisonAdminListResponseSchema = z.object({
|
|
197
|
+
data: z.array(comparisonAdminListItemSchema),
|
|
198
|
+
meta: z.object({
|
|
199
|
+
limit: z.number().int().positive(),
|
|
200
|
+
nextCursor: z.string().nullable(),
|
|
201
|
+
}),
|
|
202
|
+
});
|
|
203
|
+
/**
|
|
204
|
+
* Admin detail — same shape the storefront owner sees, plus the admin
|
|
205
|
+
* metadata block (owner identity, sales channel, raw shareToken). The
|
|
206
|
+
* detail endpoint renders prices in the comparison's RECORDED channel
|
|
207
|
+
* (the creator's), not the admin's preferred channel — so a support
|
|
208
|
+
* investigation matches what the customer reported.
|
|
209
|
+
*/
|
|
210
|
+
export const comparisonAdminDetailSchema = z.object({
|
|
211
|
+
id: uuidSchema,
|
|
212
|
+
shareToken: z.string(),
|
|
213
|
+
owner: comparisonAdminOwnerSchema,
|
|
214
|
+
salesChannel: comparisonAdminSalesChannelSchema,
|
|
215
|
+
displayMode: comparisonDisplayModeSchema,
|
|
216
|
+
products: z.array(comparisonProductSummarySchema),
|
|
217
|
+
comparableAttributes: z.array(comparisonAttributeRowSchema),
|
|
218
|
+
createdAt: z.string().datetime(),
|
|
219
|
+
updatedAt: z.string().datetime(),
|
|
220
|
+
});
|
|
221
|
+
//# sourceMappingURL=comparisons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparisons.js","sourceRoot":"","sources":["../src/comparisons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Credentials module (feature 058) — boundary schemas.
|
|
4
|
+
*
|
|
5
|
+
* The credentials core is type-agnostic (Principle XIV): a "configuration type"
|
|
6
|
+
* is a code-registered descriptor declaring its provider variants and per-field
|
|
7
|
+
* definitions (some `secret`). The core stores/validates the declared fields but
|
|
8
|
+
* never interprets provider meaning. These schemas are the single source of
|
|
9
|
+
* truth for the admin API and the in-process configuration-type registry.
|
|
10
|
+
*
|
|
11
|
+
* Secret field values are NEVER returned in plaintext by any read: the DTO
|
|
12
|
+
* replaces them with an `isSet` boolean. Only the server-side `resolve` path
|
|
13
|
+
* (not modelled as an HTTP response) exposes decrypted values for consumer use.
|
|
14
|
+
*/
|
|
15
|
+
/** Frozen field-kind set. */
|
|
16
|
+
export declare const CREDENTIAL_FIELD_KINDS: readonly ["string", "number", "boolean", "select"];
|
|
17
|
+
export declare const FieldKindSchema: z.ZodEnum<{
|
|
18
|
+
string: "string";
|
|
19
|
+
number: "number";
|
|
20
|
+
boolean: "boolean";
|
|
21
|
+
select: "select";
|
|
22
|
+
}>;
|
|
23
|
+
export type FieldKind = z.infer<typeof FieldKindSchema>;
|
|
24
|
+
export declare const FieldOptionSchema: z.ZodObject<{
|
|
25
|
+
value: z.ZodString;
|
|
26
|
+
label: z.ZodString;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export type FieldOption = z.infer<typeof FieldOptionSchema>;
|
|
29
|
+
export declare const FieldDefinitionSchema: z.ZodObject<{
|
|
30
|
+
key: z.ZodString;
|
|
31
|
+
label: z.ZodString;
|
|
32
|
+
kind: z.ZodEnum<{
|
|
33
|
+
string: "string";
|
|
34
|
+
number: "number";
|
|
35
|
+
boolean: "boolean";
|
|
36
|
+
select: "select";
|
|
37
|
+
}>;
|
|
38
|
+
required: z.ZodBoolean;
|
|
39
|
+
secret: z.ZodBoolean;
|
|
40
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
41
|
+
value: z.ZodString;
|
|
42
|
+
label: z.ZodString;
|
|
43
|
+
}, z.core.$strip>>>;
|
|
44
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
export type FieldDefinition = z.infer<typeof FieldDefinitionSchema>;
|
|
47
|
+
export declare const ProviderVariantSchema: z.ZodObject<{
|
|
48
|
+
code: z.ZodString;
|
|
49
|
+
label: z.ZodString;
|
|
50
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
51
|
+
key: z.ZodString;
|
|
52
|
+
label: z.ZodString;
|
|
53
|
+
kind: z.ZodEnum<{
|
|
54
|
+
string: "string";
|
|
55
|
+
number: "number";
|
|
56
|
+
boolean: "boolean";
|
|
57
|
+
select: "select";
|
|
58
|
+
}>;
|
|
59
|
+
required: z.ZodBoolean;
|
|
60
|
+
secret: z.ZodBoolean;
|
|
61
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
62
|
+
value: z.ZodString;
|
|
63
|
+
label: z.ZodString;
|
|
64
|
+
}, z.core.$strip>>>;
|
|
65
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
export type ProviderVariant = z.infer<typeof ProviderVariantSchema>;
|
|
69
|
+
export declare const ConfigurationTypeDescriptorSchema: z.ZodObject<{
|
|
70
|
+
code: z.ZodString;
|
|
71
|
+
label: z.ZodString;
|
|
72
|
+
ownerModule: z.ZodString;
|
|
73
|
+
providers: z.ZodArray<z.ZodObject<{
|
|
74
|
+
code: z.ZodString;
|
|
75
|
+
label: z.ZodString;
|
|
76
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
77
|
+
key: z.ZodString;
|
|
78
|
+
label: z.ZodString;
|
|
79
|
+
kind: z.ZodEnum<{
|
|
80
|
+
string: "string";
|
|
81
|
+
number: "number";
|
|
82
|
+
boolean: "boolean";
|
|
83
|
+
select: "select";
|
|
84
|
+
}>;
|
|
85
|
+
required: z.ZodBoolean;
|
|
86
|
+
secret: z.ZodBoolean;
|
|
87
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
88
|
+
value: z.ZodString;
|
|
89
|
+
label: z.ZodString;
|
|
90
|
+
}, z.core.$strip>>>;
|
|
91
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
}, z.core.$strip>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
export type ConfigurationTypeDescriptor = z.infer<typeof ConfigurationTypeDescriptorSchema>;
|
|
96
|
+
/** `GET /api/v1/admin/credentials/types` response. */
|
|
97
|
+
export declare const ConfigurationTypesResponseSchema: z.ZodObject<{
|
|
98
|
+
types: z.ZodArray<z.ZodObject<{
|
|
99
|
+
code: z.ZodString;
|
|
100
|
+
label: z.ZodString;
|
|
101
|
+
ownerModule: z.ZodString;
|
|
102
|
+
providers: z.ZodArray<z.ZodObject<{
|
|
103
|
+
code: z.ZodString;
|
|
104
|
+
label: z.ZodString;
|
|
105
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
106
|
+
key: z.ZodString;
|
|
107
|
+
label: z.ZodString;
|
|
108
|
+
kind: z.ZodEnum<{
|
|
109
|
+
string: "string";
|
|
110
|
+
number: "number";
|
|
111
|
+
boolean: "boolean";
|
|
112
|
+
select: "select";
|
|
113
|
+
}>;
|
|
114
|
+
required: z.ZodBoolean;
|
|
115
|
+
secret: z.ZodBoolean;
|
|
116
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
117
|
+
value: z.ZodString;
|
|
118
|
+
label: z.ZodString;
|
|
119
|
+
}, z.core.$strip>>>;
|
|
120
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
121
|
+
}, z.core.$strip>>;
|
|
122
|
+
}, z.core.$strip>>;
|
|
123
|
+
}, z.core.$strip>>;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
export type ConfigurationTypesResponse = z.infer<typeof ConfigurationTypesResponseSchema>;
|
|
126
|
+
/** `POST /api/v1/admin/credentials` body. */
|
|
127
|
+
export declare const CreateConfigurationSchema: z.ZodObject<{
|
|
128
|
+
code: z.ZodString;
|
|
129
|
+
name: z.ZodString;
|
|
130
|
+
typeCode: z.ZodString;
|
|
131
|
+
providerCode: z.ZodString;
|
|
132
|
+
values: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
export type CreateConfiguration = z.infer<typeof CreateConfigurationSchema>;
|
|
135
|
+
/**
|
|
136
|
+
* `PUT /api/v1/admin/credentials/:code` body.
|
|
137
|
+
*
|
|
138
|
+
* `typeCode`/`providerCode` are intentionally absent — they are immutable after
|
|
139
|
+
* create (a change is rejected with `CREDENTIAL_TYPE_IMMUTABLE`). A secret field
|
|
140
|
+
* omitted or submitted blank/`[redacted]` preserves the stored envelope
|
|
141
|
+
* (write-only semantics, FR-015). `expectedVersion` drives the optimistic lock.
|
|
142
|
+
*/
|
|
143
|
+
export declare const UpdateConfigurationSchema: z.ZodObject<{
|
|
144
|
+
name: z.ZodOptional<z.ZodString>;
|
|
145
|
+
values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
146
|
+
expectedVersion: z.ZodOptional<z.ZodNumber>;
|
|
147
|
+
}, z.core.$strip>;
|
|
148
|
+
export type UpdateConfiguration = z.infer<typeof UpdateConfigurationSchema>;
|
|
149
|
+
/**
|
|
150
|
+
* One field in a masked configuration DTO. Secret fields carry only `isSet`
|
|
151
|
+
* (never a value); non-secret fields carry their plain `value`.
|
|
152
|
+
*/
|
|
153
|
+
export declare const ConfigurationFieldDtoSchema: z.ZodObject<{
|
|
154
|
+
key: z.ZodString;
|
|
155
|
+
secret: z.ZodBoolean;
|
|
156
|
+
isSet: z.ZodOptional<z.ZodBoolean>;
|
|
157
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
export type ConfigurationFieldDto = z.infer<typeof ConfigurationFieldDtoSchema>;
|
|
160
|
+
export declare const ConfigurationDtoSchema: z.ZodObject<{
|
|
161
|
+
id: z.ZodString;
|
|
162
|
+
code: z.ZodString;
|
|
163
|
+
name: z.ZodString;
|
|
164
|
+
typeCode: z.ZodString;
|
|
165
|
+
typeLabel: z.ZodNullable<z.ZodString>;
|
|
166
|
+
providerCode: z.ZodString;
|
|
167
|
+
providerLabel: z.ZodNullable<z.ZodString>;
|
|
168
|
+
inert: z.ZodBoolean;
|
|
169
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
170
|
+
key: z.ZodString;
|
|
171
|
+
secret: z.ZodBoolean;
|
|
172
|
+
isSet: z.ZodOptional<z.ZodBoolean>;
|
|
173
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
174
|
+
}, z.core.$strip>>;
|
|
175
|
+
version: z.ZodNumber;
|
|
176
|
+
updatedAt: z.ZodString;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
export type ConfigurationDto = z.infer<typeof ConfigurationDtoSchema>;
|
|
179
|
+
/** `GET /api/v1/admin/credentials` response. */
|
|
180
|
+
export declare const ConfigurationListResponseSchema: z.ZodObject<{
|
|
181
|
+
configurations: z.ZodArray<z.ZodObject<{
|
|
182
|
+
id: z.ZodString;
|
|
183
|
+
code: z.ZodString;
|
|
184
|
+
name: z.ZodString;
|
|
185
|
+
typeCode: z.ZodString;
|
|
186
|
+
typeLabel: z.ZodNullable<z.ZodString>;
|
|
187
|
+
providerCode: z.ZodString;
|
|
188
|
+
providerLabel: z.ZodNullable<z.ZodString>;
|
|
189
|
+
inert: z.ZodBoolean;
|
|
190
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
191
|
+
key: z.ZodString;
|
|
192
|
+
secret: z.ZodBoolean;
|
|
193
|
+
isSet: z.ZodOptional<z.ZodBoolean>;
|
|
194
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
195
|
+
}, z.core.$strip>>;
|
|
196
|
+
version: z.ZodNumber;
|
|
197
|
+
updatedAt: z.ZodString;
|
|
198
|
+
}, z.core.$strip>>;
|
|
199
|
+
}, z.core.$strip>;
|
|
200
|
+
export type ConfigurationListResponse = z.infer<typeof ConfigurationListResponseSchema>;
|
|
201
|
+
/** Optional `?type=` filter on the list endpoint. */
|
|
202
|
+
export declare const ConfigurationListQuerySchema: z.ZodObject<{
|
|
203
|
+
type: z.ZodOptional<z.ZodString>;
|
|
204
|
+
}, z.core.$strip>;
|
|
205
|
+
export type ConfigurationListQuery = z.infer<typeof ConfigurationListQuerySchema>;
|
|
206
|
+
/** Delete-blocked payload — the settings referencing a configuration (FR-012). */
|
|
207
|
+
export declare const ConfigurationReferenceSchema: z.ZodObject<{
|
|
208
|
+
settingCode: z.ZodString;
|
|
209
|
+
salesChannelCode: z.ZodOptional<z.ZodString>;
|
|
210
|
+
}, z.core.$strip>;
|
|
211
|
+
export type ConfigurationReference = z.infer<typeof ConfigurationReferenceSchema>;
|
|
212
|
+
/** Frozen resolution-status set. */
|
|
213
|
+
export declare const CREDENTIAL_RESOLVE_STATUSES: readonly ["ok", "not_configured", "unavailable"];
|
|
214
|
+
export declare const CREDENTIAL_UNAVAILABLE_REASONS: readonly ["missing", "inert_type"];
|
|
215
|
+
/**
|
|
216
|
+
* Discriminated result of `CredentialsService.resolve(code)`. `ok` carries
|
|
217
|
+
* decrypted secret values for in-memory consumer use only; the other variants
|
|
218
|
+
* fail closed (never a foreign configuration, never a plaintext leak).
|
|
219
|
+
*/
|
|
220
|
+
export declare const ResolveResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
221
|
+
status: z.ZodLiteral<"ok">;
|
|
222
|
+
typeCode: z.ZodString;
|
|
223
|
+
providerCode: z.ZodString;
|
|
224
|
+
values: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
225
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
226
|
+
status: z.ZodLiteral<"not_configured">;
|
|
227
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
228
|
+
status: z.ZodLiteral<"unavailable">;
|
|
229
|
+
reason: z.ZodEnum<{
|
|
230
|
+
missing: "missing";
|
|
231
|
+
inert_type: "inert_type";
|
|
232
|
+
}>;
|
|
233
|
+
}, z.core.$strip>], "status">;
|
|
234
|
+
export type ResolveResult = z.infer<typeof ResolveResultSchema>;
|
|
235
|
+
/**
|
|
236
|
+
* Container name: `credentialsService`. Owner: `credentials`.
|
|
237
|
+
*
|
|
238
|
+
* `resolve` is the one method that matters at run time: it decrypts a stored
|
|
239
|
+
* configuration's secrets for the integration about to use them. When
|
|
240
|
+
* `credentials` is off it fails closed, and it must — an integration that
|
|
241
|
+
* caught the refusal and proceeded would run against whatever it had cached,
|
|
242
|
+
* which for a credential means "the one the operator just revoked".
|
|
243
|
+
*/
|
|
244
|
+
export interface CredentialsPort {
|
|
245
|
+
list(typeFilter?: string): Promise<ConfigurationDto[]>;
|
|
246
|
+
getByCode(code: string): Promise<ConfigurationDto | null>;
|
|
247
|
+
create(data: CreateConfiguration): Promise<ConfigurationDto>;
|
|
248
|
+
update(code: string, data: UpdateConfiguration): Promise<ConfigurationDto>;
|
|
249
|
+
delete(code: string): Promise<void>;
|
|
250
|
+
resolve(configurationCode: string): Promise<ResolveResult>;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Container name: `configurationTypeRegistry`. Owner: `credentials`.
|
|
254
|
+
*
|
|
255
|
+
* A **contribution seam**: a module that needs a credential type describes it
|
|
256
|
+
* here from its boot hook, and the admin screen renders the form from the
|
|
257
|
+
* descriptor. Every edge into it classifies as `contributes`.
|
|
258
|
+
*
|
|
259
|
+
* `isAvailable` / `get` / `resolve` / `list` filter on the contributor's
|
|
260
|
+
* effective state; `entry`, `ownerOf` and `listAll` deliberately do not, so an
|
|
261
|
+
* admin screen can keep showing a stored configuration *and* the reason its
|
|
262
|
+
* type is unavailable — a credential row outlives the module that described
|
|
263
|
+
* its shape, and hiding the row would look like data loss.
|
|
264
|
+
*
|
|
265
|
+
* **Owner off:** nothing throws here. This is a **contribution seam**, a plain
|
|
266
|
+
* `di.register` rather than a `providePort`, so a push still lands and
|
|
267
|
+
* `credentials` filters by contributor when it enumerates. Converting it to
|
|
268
|
+
* `providePort` would move every edge into it from `contributes` to
|
|
269
|
+
* `fails-closed` in the deactivation-consequence ledger, and change the
|
|
270
|
+
* sentence the operator's confirmation dialog renders.
|
|
271
|
+
*/
|
|
272
|
+
export interface ConfigurationTypeRegistryPort {
|
|
273
|
+
register(descriptor: ConfigurationTypeDescriptor): void;
|
|
274
|
+
unregister(code: string): void;
|
|
275
|
+
/** Registered at all, presence-blind. */
|
|
276
|
+
isRegistered(code: string): boolean;
|
|
277
|
+
/** Registered **and** its contributing module effectively present. */
|
|
278
|
+
isAvailable(code: string): boolean;
|
|
279
|
+
/** The descriptor, presence-blind. */
|
|
280
|
+
entry(code: string): ConfigurationTypeDescriptor | undefined;
|
|
281
|
+
/** The descriptor, or `undefined` when unregistered or its owner is absent. */
|
|
282
|
+
get(code: string): ConfigurationTypeDescriptor | undefined;
|
|
283
|
+
/** Like {@link get}, but throws `ConfigurationTypeUnknown` instead. */
|
|
284
|
+
resolve(code: string): ConfigurationTypeDescriptor;
|
|
285
|
+
/** Descriptors whose contributor is present, in registration order. */
|
|
286
|
+
list(): ConfigurationTypeDescriptor[];
|
|
287
|
+
/** Every registered descriptor, presence-blind. */
|
|
288
|
+
listAll(): ConfigurationTypeDescriptor[];
|
|
289
|
+
/** Which module contributed the code, or `null` when nobody did. */
|
|
290
|
+
ownerOf(code: string): string | null;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Credentials module (feature 058) — boundary schemas.
|
|
4
|
+
*
|
|
5
|
+
* The credentials core is type-agnostic (Principle XIV): a "configuration type"
|
|
6
|
+
* is a code-registered descriptor declaring its provider variants and per-field
|
|
7
|
+
* definitions (some `secret`). The core stores/validates the declared fields but
|
|
8
|
+
* never interprets provider meaning. These schemas are the single source of
|
|
9
|
+
* truth for the admin API and the in-process configuration-type registry.
|
|
10
|
+
*
|
|
11
|
+
* Secret field values are NEVER returned in plaintext by any read: the DTO
|
|
12
|
+
* replaces them with an `isSet` boolean. Only the server-side `resolve` path
|
|
13
|
+
* (not modelled as an HTTP response) exposes decrypted values for consumer use.
|
|
14
|
+
*/
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Configuration-type descriptors (registry surface)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/** Frozen field-kind set. */
|
|
19
|
+
export const CREDENTIAL_FIELD_KINDS = ['string', 'number', 'boolean', 'select'];
|
|
20
|
+
export const FieldKindSchema = z.enum(CREDENTIAL_FIELD_KINDS);
|
|
21
|
+
export const FieldOptionSchema = z.object({
|
|
22
|
+
value: z.string(),
|
|
23
|
+
label: z.string(),
|
|
24
|
+
});
|
|
25
|
+
export const FieldDefinitionSchema = z.object({
|
|
26
|
+
key: z.string().min(1),
|
|
27
|
+
label: z.string(),
|
|
28
|
+
kind: FieldKindSchema,
|
|
29
|
+
required: z.boolean(),
|
|
30
|
+
secret: z.boolean(),
|
|
31
|
+
options: z.array(FieldOptionSchema).optional(),
|
|
32
|
+
placeholder: z.string().optional(),
|
|
33
|
+
});
|
|
34
|
+
export const ProviderVariantSchema = z.object({
|
|
35
|
+
code: z.string().min(1),
|
|
36
|
+
label: z.string(),
|
|
37
|
+
fields: z.array(FieldDefinitionSchema),
|
|
38
|
+
});
|
|
39
|
+
export const ConfigurationTypeDescriptorSchema = z.object({
|
|
40
|
+
code: z.string().min(1),
|
|
41
|
+
label: z.string(),
|
|
42
|
+
ownerModule: z.string().min(1),
|
|
43
|
+
providers: z.array(ProviderVariantSchema),
|
|
44
|
+
});
|
|
45
|
+
/** `GET /api/v1/admin/credentials/types` response. */
|
|
46
|
+
export const ConfigurationTypesResponseSchema = z.object({
|
|
47
|
+
types: z.array(ConfigurationTypeDescriptorSchema),
|
|
48
|
+
});
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Write requests
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
/** `POST /api/v1/admin/credentials` body. */
|
|
53
|
+
export const CreateConfigurationSchema = z.object({
|
|
54
|
+
code: z.string().min(1).max(128),
|
|
55
|
+
name: z.string().min(1).max(255),
|
|
56
|
+
typeCode: z.string().min(1).max(64),
|
|
57
|
+
providerCode: z.string().min(1).max(64),
|
|
58
|
+
/** Field-value bag keyed by `FieldDefinition.key`; validated per descriptor. */
|
|
59
|
+
values: z.record(z.string(), z.unknown()),
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* `PUT /api/v1/admin/credentials/:code` body.
|
|
63
|
+
*
|
|
64
|
+
* `typeCode`/`providerCode` are intentionally absent — they are immutable after
|
|
65
|
+
* create (a change is rejected with `CREDENTIAL_TYPE_IMMUTABLE`). A secret field
|
|
66
|
+
* omitted or submitted blank/`[redacted]` preserves the stored envelope
|
|
67
|
+
* (write-only semantics, FR-015). `expectedVersion` drives the optimistic lock.
|
|
68
|
+
*/
|
|
69
|
+
export const UpdateConfigurationSchema = z.object({
|
|
70
|
+
name: z.string().min(1).max(255).optional(),
|
|
71
|
+
values: z.record(z.string(), z.unknown()).optional(),
|
|
72
|
+
expectedVersion: z.number().int().nonnegative().optional(),
|
|
73
|
+
});
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Read DTO (secrets masked)
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* One field in a masked configuration DTO. Secret fields carry only `isSet`
|
|
79
|
+
* (never a value); non-secret fields carry their plain `value`.
|
|
80
|
+
*/
|
|
81
|
+
export const ConfigurationFieldDtoSchema = z.object({
|
|
82
|
+
key: z.string(),
|
|
83
|
+
secret: z.boolean(),
|
|
84
|
+
/** Present for secret fields — whether a secret is stored. */
|
|
85
|
+
isSet: z.boolean().optional(),
|
|
86
|
+
/** Present for non-secret fields — the plain stored value. */
|
|
87
|
+
value: z.unknown().optional(),
|
|
88
|
+
});
|
|
89
|
+
export const ConfigurationDtoSchema = z.object({
|
|
90
|
+
id: z.string(),
|
|
91
|
+
code: z.string(),
|
|
92
|
+
name: z.string(),
|
|
93
|
+
typeCode: z.string(),
|
|
94
|
+
/** Null when the type is no longer registered (inert). */
|
|
95
|
+
typeLabel: z.string().nullable(),
|
|
96
|
+
providerCode: z.string(),
|
|
97
|
+
/** Null when the type/provider is no longer registered (inert). */
|
|
98
|
+
providerLabel: z.string().nullable(),
|
|
99
|
+
/** True when `typeCode` is no longer registered; the row renders read-only. */
|
|
100
|
+
inert: z.boolean(),
|
|
101
|
+
fields: z.array(ConfigurationFieldDtoSchema),
|
|
102
|
+
version: z.number().int(),
|
|
103
|
+
updatedAt: z.string(),
|
|
104
|
+
});
|
|
105
|
+
/** `GET /api/v1/admin/credentials` response. */
|
|
106
|
+
export const ConfigurationListResponseSchema = z.object({
|
|
107
|
+
configurations: z.array(ConfigurationDtoSchema),
|
|
108
|
+
});
|
|
109
|
+
/** Optional `?type=` filter on the list endpoint. */
|
|
110
|
+
export const ConfigurationListQuerySchema = z.object({
|
|
111
|
+
type: z.string().min(1).max(64).optional(),
|
|
112
|
+
});
|
|
113
|
+
/** Delete-blocked payload — the settings referencing a configuration (FR-012). */
|
|
114
|
+
export const ConfigurationReferenceSchema = z.object({
|
|
115
|
+
settingCode: z.string(),
|
|
116
|
+
salesChannelCode: z.string().optional(),
|
|
117
|
+
});
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Server-side resolution (never an HTTP response body)
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
/** Frozen resolution-status set. */
|
|
122
|
+
export const CREDENTIAL_RESOLVE_STATUSES = ['ok', 'not_configured', 'unavailable'];
|
|
123
|
+
export const CREDENTIAL_UNAVAILABLE_REASONS = ['missing', 'inert_type'];
|
|
124
|
+
/**
|
|
125
|
+
* Discriminated result of `CredentialsService.resolve(code)`. `ok` carries
|
|
126
|
+
* decrypted secret values for in-memory consumer use only; the other variants
|
|
127
|
+
* fail closed (never a foreign configuration, never a plaintext leak).
|
|
128
|
+
*/
|
|
129
|
+
export const ResolveResultSchema = z.discriminatedUnion('status', [
|
|
130
|
+
z.object({
|
|
131
|
+
status: z.literal('ok'),
|
|
132
|
+
typeCode: z.string(),
|
|
133
|
+
providerCode: z.string(),
|
|
134
|
+
values: z.record(z.string(), z.unknown()),
|
|
135
|
+
}),
|
|
136
|
+
z.object({ status: z.literal('not_configured') }),
|
|
137
|
+
z.object({
|
|
138
|
+
status: z.literal('unavailable'),
|
|
139
|
+
reason: z.enum(CREDENTIAL_UNAVAILABLE_REASONS),
|
|
140
|
+
}),
|
|
141
|
+
]);
|
|
142
|
+
//# sourceMappingURL=credentials.js.map
|