@contractspec/lib.contracts 1.49.0 → 1.51.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.
Files changed (73) hide show
  1. package/dist/app-config/contracts.d.ts +51 -51
  2. package/dist/app-config/events.d.ts +27 -27
  3. package/dist/app-config/lifecycle-contracts.d.ts +55 -55
  4. package/dist/app-config/runtime.d.ts +1 -1
  5. package/dist/app-config/spec.d.ts +1 -1
  6. package/dist/capabilities/capabilities.d.ts +64 -5
  7. package/dist/capabilities/capabilities.js +125 -0
  8. package/dist/capabilities/context.d.ts +88 -0
  9. package/dist/capabilities/context.js +87 -0
  10. package/dist/capabilities/docs/capabilities.docblock.js +191 -2
  11. package/dist/capabilities/guards.d.ts +110 -0
  12. package/dist/capabilities/guards.js +146 -0
  13. package/dist/capabilities/index.d.ts +4 -1
  14. package/dist/capabilities/index.js +4 -1
  15. package/dist/capabilities/validation.d.ts +76 -0
  16. package/dist/capabilities/validation.js +141 -0
  17. package/dist/client/react/feature-render.d.ts +2 -2
  18. package/dist/data-views/runtime.d.ts +1 -1
  19. package/dist/events.d.ts +79 -13
  20. package/dist/events.js +33 -3
  21. package/dist/examples/schema.d.ts +10 -10
  22. package/dist/experiments/spec.d.ts +7 -4
  23. package/dist/features/install.d.ts +4 -4
  24. package/dist/features/types.d.ts +28 -32
  25. package/dist/index.d.ts +21 -12
  26. package/dist/index.js +12 -3
  27. package/dist/install.d.ts +1 -1
  28. package/dist/integrations/openbanking/contracts/accounts.d.ts +67 -67
  29. package/dist/integrations/openbanking/contracts/balances.d.ts +35 -35
  30. package/dist/integrations/openbanking/contracts/transactions.d.ts +49 -49
  31. package/dist/integrations/openbanking/models.d.ts +55 -55
  32. package/dist/integrations/operations.d.ts +103 -103
  33. package/dist/integrations/spec.d.ts +1 -1
  34. package/dist/knowledge/operations.d.ts +67 -67
  35. package/dist/llm/exporters.d.ts +2 -2
  36. package/dist/markdown.d.ts +1 -1
  37. package/dist/onboarding-base.d.ts +29 -29
  38. package/dist/operations/operation.d.ts +6 -0
  39. package/dist/ownership.d.ts +133 -8
  40. package/dist/ownership.js +25 -0
  41. package/dist/policy/context.d.ts +237 -0
  42. package/dist/policy/context.js +227 -0
  43. package/dist/policy/guards.d.ts +145 -0
  44. package/dist/policy/guards.js +254 -0
  45. package/dist/policy/index.d.ts +12 -1
  46. package/dist/policy/index.js +11 -1
  47. package/dist/policy/spec.d.ts +7 -4
  48. package/dist/policy/validation.d.ts +67 -0
  49. package/dist/policy/validation.js +307 -0
  50. package/dist/presentations/presentations.d.ts +6 -0
  51. package/dist/tests/spec.d.ts +17 -12
  52. package/dist/themes.d.ts +7 -4
  53. package/dist/translations/index.d.ts +6 -0
  54. package/dist/translations/index.js +5 -0
  55. package/dist/translations/registry.d.ts +144 -0
  56. package/dist/translations/registry.js +223 -0
  57. package/dist/translations/spec.d.ts +126 -0
  58. package/dist/translations/spec.js +31 -0
  59. package/dist/translations/validation.d.ts +85 -0
  60. package/dist/translations/validation.js +328 -0
  61. package/dist/types.d.ts +140 -14
  62. package/dist/versioning/index.d.ts +2 -1
  63. package/dist/versioning/index.js +2 -1
  64. package/dist/versioning/refs.d.ts +179 -0
  65. package/dist/versioning/refs.js +161 -0
  66. package/dist/workflow/context.d.ts +191 -0
  67. package/dist/workflow/context.js +227 -0
  68. package/dist/workflow/index.d.ts +4 -2
  69. package/dist/workflow/index.js +4 -2
  70. package/dist/workflow/spec.d.ts +1 -1
  71. package/dist/workflow/validation.d.ts +64 -2
  72. package/dist/workflow/validation.js +194 -1
  73. package/package.json +19 -6
@@ -0,0 +1,223 @@
1
+ //#region src/translations/registry.ts
2
+ /**
3
+ * Registry for translation specs with locale-aware lookup.
4
+ */
5
+ var TranslationRegistry = class {
6
+ specs = /* @__PURE__ */ new Map();
7
+ latestByLocale = /* @__PURE__ */ new Map();
8
+ locales = /* @__PURE__ */ new Set();
9
+ domains = /* @__PURE__ */ new Set();
10
+ constructor(items) {
11
+ if (items) for (const spec of items) this.register(spec);
12
+ }
13
+ /**
14
+ * Register a translation spec.
15
+ *
16
+ * @param spec - Translation spec to register
17
+ */
18
+ register(spec) {
19
+ const fullKey = this.makeKey(spec.meta.key, spec.meta.version, spec.locale);
20
+ this.specs.set(fullKey, spec);
21
+ const localeKey = `${spec.meta.key}:${spec.locale}`;
22
+ const existing = this.latestByLocale.get(localeKey);
23
+ if (!existing || this.isNewerVersion(spec.meta.version, existing.meta.version)) this.latestByLocale.set(localeKey, spec);
24
+ this.locales.add(spec.locale);
25
+ this.domains.add(spec.meta.domain);
26
+ }
27
+ /**
28
+ * Get a translation spec by key, version, and locale.
29
+ *
30
+ * @param key - Translation spec key
31
+ * @param version - Version string
32
+ * @param locale - Locale code
33
+ * @returns Translation spec or undefined
34
+ */
35
+ get(key, version, locale) {
36
+ return this.specs.get(this.makeKey(key, version, locale));
37
+ }
38
+ /**
39
+ * Get the latest version of a translation spec for a locale.
40
+ *
41
+ * @param key - Translation spec key
42
+ * @param locale - Locale code
43
+ * @returns Translation spec or undefined
44
+ */
45
+ getLatest(key, locale) {
46
+ return this.latestByLocale.get(`${key}:${locale}`);
47
+ }
48
+ /**
49
+ * Get a specific message from a translation spec.
50
+ *
51
+ * @param specKey - Translation spec key
52
+ * @param messageKey - Message key within the spec
53
+ * @param locale - Locale code
54
+ * @param version - Optional version (uses latest if not specified)
55
+ * @returns Translation message or undefined
56
+ */
57
+ getMessage(specKey, messageKey, locale, version) {
58
+ const spec = version ? this.get(specKey, version, locale) : this.getLatest(specKey, locale);
59
+ if (!spec) return void 0;
60
+ return spec.messages[messageKey];
61
+ }
62
+ /**
63
+ * Get a message value with fallback chain support.
64
+ *
65
+ * @param specKey - Translation spec key
66
+ * @param messageKey - Message key within the spec
67
+ * @param locale - Primary locale
68
+ * @param fallbackLocale - Fallback locale (optional, uses spec's fallback if not provided)
69
+ * @param version - Optional version (uses latest if not specified)
70
+ * @returns Translation lookup result or undefined
71
+ */
72
+ getWithFallback(specKey, messageKey, locale, fallbackLocale, version) {
73
+ const spec = version ? this.get(specKey, version, locale) : this.getLatest(specKey, locale);
74
+ if (spec) {
75
+ const message = spec.messages[messageKey];
76
+ if (message) return {
77
+ spec,
78
+ message,
79
+ locale,
80
+ fromFallback: false
81
+ };
82
+ fallbackLocale = fallbackLocale ?? spec.fallback;
83
+ }
84
+ if (fallbackLocale && fallbackLocale !== locale) {
85
+ const fallbackSpec = version ? this.get(specKey, version, fallbackLocale) : this.getLatest(specKey, fallbackLocale);
86
+ if (fallbackSpec) {
87
+ const message = fallbackSpec.messages[messageKey];
88
+ if (message) return {
89
+ spec: fallbackSpec,
90
+ message,
91
+ locale: fallbackLocale,
92
+ fromFallback: true
93
+ };
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * Get a message value string with fallback.
99
+ *
100
+ * Convenience method that returns just the string value or a fallback.
101
+ *
102
+ * @param specKey - Translation spec key
103
+ * @param messageKey - Message key
104
+ * @param locale - Primary locale
105
+ * @param fallback - String to return if message not found (default: messageKey)
106
+ * @returns Message value or fallback
107
+ */
108
+ getValue(specKey, messageKey, locale, fallback) {
109
+ return this.getWithFallback(specKey, messageKey, locale)?.message.value ?? fallback ?? messageKey;
110
+ }
111
+ /**
112
+ * List all locales available for a spec key.
113
+ *
114
+ * @param specKey - Translation spec key
115
+ * @returns Array of available locales
116
+ */
117
+ listLocales(specKey) {
118
+ const locales = [];
119
+ for (const [key, spec] of this.specs.entries()) if (key.startsWith(`${specKey}:`)) {
120
+ if (!locales.includes(spec.locale)) locales.push(spec.locale);
121
+ }
122
+ return locales;
123
+ }
124
+ /**
125
+ * List all translation specs.
126
+ *
127
+ * @returns Array of all registered translation specs
128
+ */
129
+ list() {
130
+ return [...this.specs.values()];
131
+ }
132
+ /**
133
+ * List translation specs by locale.
134
+ *
135
+ * @param locale - Locale to filter by
136
+ * @returns Array of translation specs for the locale
137
+ */
138
+ listByLocale(locale) {
139
+ return [...this.specs.values()].filter((s) => s.locale === locale);
140
+ }
141
+ /**
142
+ * List translation specs by domain.
143
+ *
144
+ * @param domain - Domain to filter by
145
+ * @returns Array of translation specs for the domain
146
+ */
147
+ listByDomain(domain) {
148
+ return [...this.specs.values()].filter((s) => s.meta.domain === domain);
149
+ }
150
+ /**
151
+ * Check if a translation spec exists.
152
+ *
153
+ * @param key - Translation spec key
154
+ * @param locale - Locale code
155
+ * @param version - Optional version
156
+ * @returns True if spec exists
157
+ */
158
+ has(key, locale, version) {
159
+ if (version) return this.specs.has(this.makeKey(key, version, locale));
160
+ return this.latestByLocale.has(`${key}:${locale}`);
161
+ }
162
+ /**
163
+ * Get all registered locales.
164
+ *
165
+ * @returns Set of all registered locales
166
+ */
167
+ getLocales() {
168
+ return this.locales;
169
+ }
170
+ /**
171
+ * Get all registered domains.
172
+ *
173
+ * @returns Set of all registered domains
174
+ */
175
+ getDomains() {
176
+ return this.domains;
177
+ }
178
+ /**
179
+ * Get registry statistics.
180
+ *
181
+ * @returns Registry statistics
182
+ */
183
+ getStats() {
184
+ let totalMessages = 0;
185
+ for (const spec of this.specs.values()) totalMessages += Object.keys(spec.messages).length;
186
+ return {
187
+ totalSpecs: this.specs.size,
188
+ locales: [...this.locales],
189
+ domains: [...this.domains],
190
+ totalMessages
191
+ };
192
+ }
193
+ /**
194
+ * Clear all registered specs.
195
+ */
196
+ clear() {
197
+ this.specs.clear();
198
+ this.latestByLocale.clear();
199
+ this.locales.clear();
200
+ this.domains.clear();
201
+ }
202
+ makeKey(key, version, locale) {
203
+ return `${key}:${version}:${locale}`;
204
+ }
205
+ isNewerVersion(a, b) {
206
+ const parseVersion = (v) => {
207
+ const parts = v.split(".").map(Number);
208
+ return {
209
+ major: parts[0] ?? 0,
210
+ minor: parts[1] ?? 0,
211
+ patch: parts[2] ?? 0
212
+ };
213
+ };
214
+ const va = parseVersion(a);
215
+ const vb = parseVersion(b);
216
+ if (va.major !== vb.major) return va.major > vb.major;
217
+ if (va.minor !== vb.minor) return va.minor > vb.minor;
218
+ return va.patch > vb.patch;
219
+ }
220
+ };
221
+
222
+ //#endregion
223
+ export { TranslationRegistry };
@@ -0,0 +1,126 @@
1
+ import { Owner, Stability, Tag } from "../ownership.js";
2
+
3
+ //#region src/translations/spec.d.ts
4
+
5
+ /** ISO 639-1 locale code (e.g., 'en', 'fr', 'de'). */
6
+ type Locale = string;
7
+ /** Message key identifier. */
8
+ type MessageKey = string;
9
+ type PlaceholderType = 'string' | 'number' | 'date' | 'time' | 'datetime' | 'currency' | 'percent' | 'plural' | 'select' | 'selectordinal';
10
+ interface PlaceholderDef {
11
+ /** Placeholder name (without braces). */
12
+ name: string;
13
+ /** Type of the placeholder value. */
14
+ type: PlaceholderType;
15
+ /** Format specifier (e.g., 'short', 'long', 'currency'). */
16
+ format?: string;
17
+ /** Description for translators. */
18
+ description?: string;
19
+ /** Example value for context. */
20
+ example?: string;
21
+ }
22
+ /**
23
+ * CLDR plural categories.
24
+ * @see https://cldr.unicode.org/index/cldr-spec/plural-rules
25
+ */
26
+ type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
27
+ interface PluralRule {
28
+ category: PluralCategory;
29
+ value: string;
30
+ }
31
+ interface PluralRuleSet {
32
+ /** Name of the plural variable. */
33
+ variable: string;
34
+ /** Rules for each plural category. */
35
+ rules: PluralRule[];
36
+ }
37
+ type VariantType = 'gender' | 'formality' | 'context';
38
+ interface MessageVariant {
39
+ /** Type of variant (gender, formality, context). */
40
+ type: VariantType;
41
+ /** Variant key (e.g., 'male', 'female', 'formal', 'informal'). */
42
+ key: string;
43
+ /** Variant value (the translated message for this variant). */
44
+ value: string;
45
+ }
46
+ interface TranslationMessage {
47
+ /** The translated value (may use ICU message format). */
48
+ value: string;
49
+ /** Description for translators explaining context and usage. */
50
+ description?: string;
51
+ /** Usage context to help translators understand where this appears. */
52
+ context?: string;
53
+ /** Placeholder definitions for dynamic values. */
54
+ placeholders?: PlaceholderDef[];
55
+ /** Variants for gender, formality, or other contextual differences. */
56
+ variants?: MessageVariant[];
57
+ /** Maximum character length (hint for UI constraints). */
58
+ maxLength?: number;
59
+ /** Tags for categorization and filtering. */
60
+ tags?: string[];
61
+ }
62
+ type TranslationMessages = Record<MessageKey, TranslationMessage>;
63
+ interface TranslationMeta {
64
+ /** Unique key for this translation spec. */
65
+ key: string;
66
+ /** Semantic version (e.g., "1.0.0"). */
67
+ version: string;
68
+ /** Business domain this translation belongs to. */
69
+ domain: string;
70
+ /** Description of the translation bundle. */
71
+ description?: string;
72
+ /** Owners responsible for this translation spec. */
73
+ owners: Owner[];
74
+ /** Stability marker. */
75
+ stability?: Stability;
76
+ /** Tags for categorization. */
77
+ tags?: Tag[];
78
+ }
79
+ interface TranslationSpec {
80
+ /** Metadata about this translation spec. */
81
+ meta: TranslationMeta;
82
+ /** Primary locale for this translation spec. */
83
+ locale: Locale;
84
+ /** Fallback locale when a message is missing. */
85
+ fallback?: Locale;
86
+ /** Translation messages keyed by message key. */
87
+ messages: TranslationMessages;
88
+ /** Plural rules for the locale. */
89
+ pluralRules?: PluralRuleSet[];
90
+ /** Tags for categorization. */
91
+ tags?: string[];
92
+ }
93
+ interface TranslationRef {
94
+ key: string;
95
+ version: string;
96
+ locale?: Locale;
97
+ }
98
+ /**
99
+ * Helper to define a Translation spec.
100
+ *
101
+ * @param spec - Translation specification
102
+ * @returns The same spec with type inference
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const messages = defineTranslation({
107
+ * meta: {
108
+ * key: 'auth.messages',
109
+ * version: '1.0.0',
110
+ * domain: 'auth',
111
+ * owners: [{ team: 'platform' }],
112
+ * },
113
+ * locale: 'en',
114
+ * messages: {
115
+ * 'login.success': {
116
+ * value: 'Welcome back, {name}!',
117
+ * description: 'Shown after successful login',
118
+ * placeholders: [{ name: 'name', type: 'string' }],
119
+ * },
120
+ * },
121
+ * });
122
+ * ```
123
+ */
124
+ declare const defineTranslation: (spec: TranslationSpec) => TranslationSpec;
125
+ //#endregion
126
+ export { Locale, MessageKey, MessageVariant, PlaceholderDef, PlaceholderType, PluralCategory, PluralRule, PluralRuleSet, TranslationMessage, TranslationMessages, TranslationMeta, TranslationRef, TranslationSpec, VariantType, defineTranslation };
@@ -0,0 +1,31 @@
1
+ //#region src/translations/spec.ts
2
+ /**
3
+ * Helper to define a Translation spec.
4
+ *
5
+ * @param spec - Translation specification
6
+ * @returns The same spec with type inference
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const messages = defineTranslation({
11
+ * meta: {
12
+ * key: 'auth.messages',
13
+ * version: '1.0.0',
14
+ * domain: 'auth',
15
+ * owners: [{ team: 'platform' }],
16
+ * },
17
+ * locale: 'en',
18
+ * messages: {
19
+ * 'login.success': {
20
+ * value: 'Welcome back, {name}!',
21
+ * description: 'Shown after successful login',
22
+ * placeholders: [{ name: 'name', type: 'string' }],
23
+ * },
24
+ * },
25
+ * });
26
+ * ```
27
+ */
28
+ const defineTranslation = (spec) => spec;
29
+
30
+ //#endregion
31
+ export { defineTranslation };
@@ -0,0 +1,85 @@
1
+ import { Locale, MessageKey, TranslationMessage, TranslationSpec } from "./spec.js";
2
+ import { TranslationRegistry } from "./registry.js";
3
+
4
+ //#region src/translations/validation.d.ts
5
+
6
+ type TranslationValidationLevel = 'error' | 'warning' | 'info';
7
+ interface TranslationValidationIssue {
8
+ level: TranslationValidationLevel;
9
+ message: string;
10
+ path?: string;
11
+ context?: Record<string, unknown>;
12
+ }
13
+ interface TranslationValidationResult {
14
+ valid: boolean;
15
+ issues: TranslationValidationIssue[];
16
+ }
17
+ interface ICUValidationResult {
18
+ valid: boolean;
19
+ error?: string;
20
+ placeholders: string[];
21
+ plurals: string[];
22
+ selects: string[];
23
+ }
24
+ interface MissingTranslation {
25
+ messageKey: MessageKey;
26
+ sourceLocale: Locale;
27
+ targetLocale: Locale;
28
+ sourceMessage: TranslationMessage;
29
+ }
30
+ /**
31
+ * Validate a translation spec for internal consistency.
32
+ *
33
+ * @param spec - Translation spec to validate
34
+ * @returns Validation result with any issues found
35
+ */
36
+ declare function validateTranslationSpec(spec: TranslationSpec): TranslationValidationResult;
37
+ /**
38
+ * Validate ICU message format syntax.
39
+ *
40
+ * This is a simplified validator that checks for balanced braces
41
+ * and extracts placeholders, plurals, and selects.
42
+ *
43
+ * @param message - Message string to validate
44
+ * @returns Validation result with extracted components
45
+ */
46
+ declare function validateICUFormat(message: string): ICUValidationResult;
47
+ /**
48
+ * Find messages that exist in source but not in target.
49
+ *
50
+ * @param sourceSpec - Source translation spec (usually base locale like 'en')
51
+ * @param targetSpec - Target translation spec to check
52
+ * @returns Array of missing translations
53
+ */
54
+ declare function findMissingTranslations(sourceSpec: TranslationSpec, targetSpec: TranslationSpec): MissingTranslation[];
55
+ /**
56
+ * Find all missing translations across a registry.
57
+ *
58
+ * Compares each locale against a base locale to find missing keys.
59
+ *
60
+ * @param registry - Translation registry
61
+ * @param specKey - Translation spec key to check
62
+ * @param baseLocale - Base locale to compare against
63
+ * @returns Map of locale to missing translations
64
+ */
65
+ declare function findAllMissingTranslations(registry: TranslationRegistry, specKey: string, baseLocale: Locale): Map<Locale, MissingTranslation[]>;
66
+ /**
67
+ * Validate all translation specs in a registry.
68
+ *
69
+ * @param registry - Translation registry to validate
70
+ * @returns Validation result
71
+ */
72
+ declare function validateTranslationRegistry(registry: TranslationRegistry): TranslationValidationResult;
73
+ declare class TranslationValidationError extends Error {
74
+ readonly issues: TranslationValidationIssue[];
75
+ constructor(message: string, issues: TranslationValidationIssue[]);
76
+ }
77
+ /**
78
+ * Assert that a translation spec is valid, throwing if not.
79
+ *
80
+ * @param spec - Translation spec to validate
81
+ * @throws {TranslationValidationError} If validation fails
82
+ */
83
+ declare function assertTranslationSpecValid(spec: TranslationSpec): void;
84
+ //#endregion
85
+ export { ICUValidationResult, MissingTranslation, TranslationValidationError, TranslationValidationIssue, TranslationValidationLevel, TranslationValidationResult, assertTranslationSpecValid, findAllMissingTranslations, findMissingTranslations, validateICUFormat, validateTranslationRegistry, validateTranslationSpec };