@spottoai/types-package 1.0.2-beta.381 → 1.0.2-beta.382

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 (44) hide show
  1. package/dist/accounts/azureSpSetup.d.ts +1 -1
  2. package/dist/accounts/azureSpSetup.d.ts.map +1 -1
  3. package/dist/ai/index.d.ts +14 -1
  4. package/dist/ai/index.d.ts.map +1 -1
  5. package/dist/ai/index.js +12 -0
  6. package/dist/ai/index.js.map +1 -1
  7. package/dist/environment/canonicalization.d.ts +12 -0
  8. package/dist/environment/canonicalization.d.ts.map +1 -0
  9. package/dist/environment/canonicalization.js +40 -0
  10. package/dist/environment/canonicalization.js.map +1 -0
  11. package/dist/environment/contracts.d.ts +196 -0
  12. package/dist/environment/contracts.d.ts.map +1 -0
  13. package/dist/environment/contracts.js +21 -0
  14. package/dist/environment/contracts.js.map +1 -0
  15. package/dist/environment/index.d.ts +5 -0
  16. package/dist/environment/index.d.ts.map +1 -0
  17. package/dist/environment/index.js +21 -0
  18. package/dist/environment/index.js.map +1 -0
  19. package/dist/environment/internal.d.ts +21 -0
  20. package/dist/environment/internal.d.ts.map +1 -0
  21. package/dist/environment/internal.js +113 -0
  22. package/dist/environment/internal.js.map +1 -0
  23. package/dist/environment/references.d.ts +18 -0
  24. package/dist/environment/references.d.ts.map +1 -0
  25. package/dist/environment/references.js +206 -0
  26. package/dist/environment/references.js.map +1 -0
  27. package/dist/environment/validation.d.ts +28 -0
  28. package/dist/environment/validation.d.ts.map +1 -0
  29. package/dist/environment/validation.js +320 -0
  30. package/dist/environment/validation.js.map +1 -0
  31. package/dist/esm/ai/index.js +10 -1
  32. package/dist/esm/entries/environment.js +3 -0
  33. package/dist/esm/environment/canonicalization.js +34 -0
  34. package/dist/esm/environment/contracts.js +17 -0
  35. package/dist/esm/environment/index.js +4 -0
  36. package/dist/esm/environment/internal.js +97 -0
  37. package/dist/esm/environment/references.js +194 -0
  38. package/dist/esm/environment/validation.js +303 -0
  39. package/dist/esm/index.js +1 -0
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +1 -0
  43. package/dist/index.js.map +1 -1
  44. package/package.json +11 -2
@@ -0,0 +1,320 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEnvironmentSafeLabelV1 = exports.isEnvironmentArtifactKindV1 = exports.isEnvironmentCompiledGenerationPointerV1 = exports.isEnvironmentDocumentDescriptorSetV1 = exports.isEnvironmentDocumentDescriptorV1 = exports.isEnvironmentSubscriptionCostProjectionV1 = exports.isEnvironmentCoverageStateV1 = exports.isEnvironmentMoneyValueV1 = exports.isEnvironmentRunIdV1 = exports.isEnvironmentSourceBindingV1 = exports.isEnvironmentSourceGenerationV1 = exports.isEnvironmentScopeV1 = exports.isEnvironmentPortalRouteV1 = void 0;
4
+ const contracts_js_1 = require("./contracts.js");
5
+ const internal_js_1 = require("./internal.js");
6
+ const references_js_1 = require("./references.js");
7
+ const DOCUMENT_NAMES = new Set(contracts_js_1.ENVIRONMENT_DOCUMENT_NAMES_V1);
8
+ const ARTIFACT_KINDS = new Set(contracts_js_1.ENVIRONMENT_ARTIFACT_KINDS_V1);
9
+ const MONEY_BASES = new Set(['billed', 'amortized']);
10
+ const MONEY_PROVENANCE = new Set([
11
+ 'subscription-summary',
12
+ 'subscription-resources',
13
+ 'cost-savings-summary',
14
+ 'savings-aggregate',
15
+ 'recommendation',
16
+ ]);
17
+ const SAVINGS_ADDITIVITY = new Set(['additive', 'scenario-non-additive']);
18
+ const CHANGE_DIRECTIONS = new Set(['increase', 'decrease', 'unchanged', 'unknown']);
19
+ const scopesEqual = (left, right) => left.kind === right.kind && left.tenantId === right.tenantId && left.companyId === right.companyId && left.subscriptionId === right.subscriptionId;
20
+ /** Validates a bounded, local Portal route suitable for client-visible evidence. */
21
+ const isEnvironmentPortalRouteV1 = (value) => (0, internal_js_1.isBoundedString)(value, contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.customerStringScalars, { trimmed: true, controls: true }) &&
22
+ value.startsWith('/') &&
23
+ !value.startsWith('//') &&
24
+ !value.includes('\\') &&
25
+ !value.includes('://') &&
26
+ !value.includes('?') &&
27
+ !value.includes('#') &&
28
+ !value.includes('%') &&
29
+ value.split('/').every(segment => segment !== '.' && segment !== '..');
30
+ exports.isEnvironmentPortalRouteV1 = isEnvironmentPortalRouteV1;
31
+ const isGeneralKey = (value) => (0, internal_js_1.isBoundedString)(value, contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.safeLabelScalars, { trimmed: true, controls: true });
32
+ const isReferenceArray = (value) => Array.isArray(value) &&
33
+ value.length <= contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.boundedListItems &&
34
+ value.every(references_js_1.isEnvironmentLogicalEvidenceReferenceV1) &&
35
+ new Set(value).size === value.length;
36
+ /** Validates the closed phase-one Azure subscription scope. */
37
+ const isEnvironmentScopeV1 = (value) => (0, internal_js_1.isRecord)(value) &&
38
+ (0, internal_js_1.hasExactKeys)(value, ['kind', 'tenantId', 'companyId', 'subscriptionId']) &&
39
+ value.kind === 'azure-subscription' &&
40
+ (0, internal_js_1.isScopeIdentifier)(value.tenantId) &&
41
+ (0, internal_js_1.isScopeIdentifier)(value.companyId) &&
42
+ (0, internal_js_1.isScopeIdentifier)(value.subscriptionId);
43
+ exports.isEnvironmentScopeV1 = isEnvironmentScopeV1;
44
+ /** Validates the client-safe identity of one authoritative source generation. */
45
+ const isEnvironmentSourceGenerationV1 = (value) => (0, internal_js_1.isRecord)(value) &&
46
+ (0, internal_js_1.hasExactKeys)(value, [
47
+ 'viewSetSchemaVersion',
48
+ 'publicationId',
49
+ 'portalRunId',
50
+ 'pluginRunId',
51
+ 'economicsGenerationId',
52
+ 'economicsFingerprint',
53
+ 'completedAt',
54
+ ]) &&
55
+ value.viewSetSchemaVersion === 1 &&
56
+ (0, internal_js_1.isSourceIdentity)(value.publicationId) &&
57
+ (0, internal_js_1.isSourceIdentity)(value.portalRunId) &&
58
+ (0, internal_js_1.isSourceIdentity)(value.pluginRunId) &&
59
+ (0, internal_js_1.isSourceIdentity)(value.economicsGenerationId) &&
60
+ (0, internal_js_1.isSourceIdentity)(value.economicsFingerprint) &&
61
+ (0, internal_js_1.isCanonicalUtcTimestamp)(value.completedAt);
62
+ exports.isEnvironmentSourceGenerationV1 = isEnvironmentSourceGenerationV1;
63
+ /** Validates a byte-preserving binding to an authoritative CompletedAzureViewSetV1. */
64
+ const isEnvironmentSourceBindingV1 = (value) => (0, internal_js_1.isRecord)(value) &&
65
+ (0, internal_js_1.hasExactKeys)(value, [
66
+ 'kind',
67
+ 'viewSetSchemaVersion',
68
+ 'scope',
69
+ 'publicationId',
70
+ 'portalRunId',
71
+ 'pluginRunId',
72
+ 'economicsGenerationId',
73
+ 'economicsFingerprint',
74
+ 'completedAt',
75
+ ]) &&
76
+ value.kind === 'azure-subscription-view-set' &&
77
+ value.viewSetSchemaVersion === 1 &&
78
+ (0, exports.isEnvironmentScopeV1)(value.scope) &&
79
+ (0, exports.isEnvironmentSourceGenerationV1)({
80
+ viewSetSchemaVersion: value.viewSetSchemaVersion,
81
+ publicationId: value.publicationId,
82
+ portalRunId: value.portalRunId,
83
+ pluginRunId: value.pluginRunId,
84
+ economicsGenerationId: value.economicsGenerationId,
85
+ economicsFingerprint: value.economicsFingerprint,
86
+ completedAt: value.completedAt,
87
+ });
88
+ exports.isEnvironmentSourceBindingV1 = isEnvironmentSourceBindingV1;
89
+ /** Validates a storage-safe environment run identity independently from source identities. */
90
+ const isEnvironmentRunIdV1 = (value) => typeof value === 'string' &&
91
+ value.length > 0 &&
92
+ value.length <= contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.environmentRunIdAsciiCharacters &&
93
+ value !== '.' &&
94
+ value !== '..' &&
95
+ internal_js_1.ENVIRONMENT_RUN_ID_PATTERN.test(value);
96
+ exports.isEnvironmentRunIdV1 = isEnvironmentRunIdV1;
97
+ /** Validates canonical decimal money with explicit currency, basis, period, and provenance. */
98
+ const isEnvironmentMoneyValueV1 = (value) => (0, internal_js_1.isRecord)(value) &&
99
+ (0, internal_js_1.hasExactKeys)(value, ['amount', 'currencyCode', 'basis', 'period', 'provenance'], ['savingsAdditivity']) &&
100
+ typeof value.amount === 'string' &&
101
+ internal_js_1.DECIMAL_PATTERN.test(value.amount) &&
102
+ typeof value.currencyCode === 'string' &&
103
+ internal_js_1.CURRENCY_PATTERN.test(value.currencyCode) &&
104
+ typeof value.basis === 'string' &&
105
+ MONEY_BASES.has(value.basis) &&
106
+ (0, internal_js_1.isBoundedString)(value.period, contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.safeLabelScalars, { trimmed: true, controls: true }) &&
107
+ typeof value.provenance === 'string' &&
108
+ MONEY_PROVENANCE.has(value.provenance) &&
109
+ (value.savingsAdditivity === undefined || (typeof value.savingsAdditivity === 'string' && SAVINGS_ADDITIVITY.has(value.savingsAdditivity)));
110
+ exports.isEnvironmentMoneyValueV1 = isEnvironmentMoneyValueV1;
111
+ const isObservedMoney = (value) => (0, exports.isEnvironmentMoneyValueV1)(value) && value.savingsAdditivity === undefined;
112
+ const isSavingsMoney = (value) => (0, exports.isEnvironmentMoneyValueV1)(value) && value.savingsAdditivity !== undefined;
113
+ /** Validates the closed coverage-state union and state-specific freshness rules. */
114
+ const isEnvironmentCoverageStateV1 = (value) => {
115
+ if (!(0, internal_js_1.isRecord)(value) || typeof value.status !== 'string')
116
+ return false;
117
+ const hasValidFreshness = (value.observedAt === undefined || (0, internal_js_1.isCanonicalUtcTimestamp)(value.observedAt)) &&
118
+ (value.completeThrough === undefined || (0, internal_js_1.isCanonicalUtcTimestamp)(value.completeThrough)) &&
119
+ (value.observedAt === undefined ||
120
+ value.completeThrough === undefined ||
121
+ Date.parse(value.completeThrough) <= Date.parse(value.observedAt));
122
+ if (value.status === 'complete') {
123
+ return (0, internal_js_1.hasExactKeys)(value, ['status'], ['observedAt', 'completeThrough']) && hasValidFreshness;
124
+ }
125
+ if (value.status === 'partial') {
126
+ return ((0, internal_js_1.hasExactKeys)(value, ['status', 'reason'], ['observedAt', 'completeThrough']) &&
127
+ (0, internal_js_1.isCustomerString)(value.reason) &&
128
+ value.reason.length > 0 &&
129
+ hasValidFreshness);
130
+ }
131
+ if (value.status === 'stale') {
132
+ return ((0, internal_js_1.hasExactKeys)(value, ['status', 'reason', 'observedAt'], ['completeThrough']) &&
133
+ (0, internal_js_1.isCustomerString)(value.reason) &&
134
+ value.reason.length > 0 &&
135
+ hasValidFreshness);
136
+ }
137
+ if (value.status === 'unavailable' || value.status === 'not-collected') {
138
+ return (0, internal_js_1.hasExactKeys)(value, ['status', 'reason']) && (0, internal_js_1.isCustomerString)(value.reason) && value.reason.length > 0;
139
+ }
140
+ return false;
141
+ };
142
+ exports.isEnvironmentCoverageStateV1 = isEnvironmentCoverageStateV1;
143
+ const isBoundedList = (value, itemValidator) => {
144
+ if (!(0, internal_js_1.isRecord)(value) || !(0, internal_js_1.hasExactKeys)(value, ['items', 'totalCount', 'includedCount', 'truncated'], ['continuationReference']))
145
+ return false;
146
+ if (!Array.isArray(value.items) || value.items.length > contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.boundedListItems || !value.items.every(itemValidator))
147
+ return false;
148
+ if (!(0, internal_js_1.isNonNegativeInteger)(value.totalCount) || !(0, internal_js_1.isNonNegativeInteger)(value.includedCount))
149
+ return false;
150
+ if (value.includedCount !== value.items.length || value.totalCount < value.includedCount || typeof value.truncated !== 'boolean')
151
+ return false;
152
+ if (value.truncated !== value.totalCount > value.includedCount)
153
+ return false;
154
+ if (value.continuationReference !== undefined && !(0, references_js_1.isEnvironmentLogicalEvidenceReferenceV1)(value.continuationReference))
155
+ return false;
156
+ return !value.truncated || value.continuationReference !== undefined;
157
+ };
158
+ const isCostRollup = (value) => (0, internal_js_1.isRecord)(value) &&
159
+ (0, internal_js_1.hasExactKeys)(value, ['key', 'safeLabel', 'resourceCount', 'sourceReferences'], ['observedCost', 'potentialSavings']) &&
160
+ isGeneralKey(value.key) &&
161
+ (0, internal_js_1.isSafeLabel)(value.safeLabel) &&
162
+ (0, internal_js_1.isNonNegativeInteger)(value.resourceCount) &&
163
+ (value.observedCost === undefined || isObservedMoney(value.observedCost)) &&
164
+ (value.potentialSavings === undefined || isSavingsMoney(value.potentialSavings)) &&
165
+ isReferenceArray(value.sourceReferences);
166
+ const isCostDriver = (value) => (0, internal_js_1.isRecord)(value) &&
167
+ (0, internal_js_1.hasExactKeys)(value, ['key', 'safeLabel', 'sourceReferences'], ['description', 'observedCost', 'portalRoute', 'resourceReference']) &&
168
+ isGeneralKey(value.key) &&
169
+ (0, internal_js_1.isSafeLabel)(value.safeLabel) &&
170
+ (value.description === undefined || (0, internal_js_1.isCustomerString)(value.description)) &&
171
+ (value.observedCost === undefined || isObservedMoney(value.observedCost)) &&
172
+ (value.portalRoute === undefined || (0, exports.isEnvironmentPortalRouteV1)(value.portalRoute)) &&
173
+ (value.resourceReference === undefined || (0, references_js_1.isEnvironmentLogicalResourceReferenceV1)(value.resourceReference)) &&
174
+ isReferenceArray(value.sourceReferences);
175
+ const isRecommendation = (value) => (0, internal_js_1.isRecord)(value) &&
176
+ (0, internal_js_1.hasExactKeys)(value, ['recommendationId', 'safeLabel', 'portalRoute', 'sourceReferences'], ['description', 'potentialSavings']) &&
177
+ (0, internal_js_1.isScopeIdentifier)(value.recommendationId) &&
178
+ (0, internal_js_1.isSafeLabel)(value.safeLabel) &&
179
+ (0, exports.isEnvironmentPortalRouteV1)(value.portalRoute) &&
180
+ (value.description === undefined || (0, internal_js_1.isCustomerString)(value.description)) &&
181
+ (value.potentialSavings === undefined || isSavingsMoney(value.potentialSavings)) &&
182
+ isReferenceArray(value.sourceReferences);
183
+ const isCostChange = (value) => (0, internal_js_1.isRecord)(value) &&
184
+ (0, internal_js_1.hasExactKeys)(value, ['key', 'safeLabel', 'description', 'direction', 'sourceReferences'], ['amount']) &&
185
+ isGeneralKey(value.key) &&
186
+ (0, internal_js_1.isSafeLabel)(value.safeLabel) &&
187
+ (0, internal_js_1.isCustomerString)(value.description) &&
188
+ typeof value.direction === 'string' &&
189
+ CHANGE_DIRECTIONS.has(value.direction) &&
190
+ (value.amount === undefined || isObservedMoney(value.amount)) &&
191
+ isReferenceArray(value.sourceReferences);
192
+ const isWarning = (value) => (0, internal_js_1.isRecord)(value) &&
193
+ (0, internal_js_1.hasExactKeys)(value, ['code', 'safeLabel', 'sourceReferences'], ['detail']) &&
194
+ isGeneralKey(value.code) &&
195
+ (0, internal_js_1.isSafeLabel)(value.safeLabel) &&
196
+ (value.detail === undefined || (0, internal_js_1.isCustomerString)(value.detail)) &&
197
+ isReferenceArray(value.sourceReferences);
198
+ const isSourceCoverage = (value) => (0, internal_js_1.isRecord)(value) &&
199
+ (0, internal_js_1.hasExactKeys)(value, ['subscriptionSummary', 'resources', 'recommendations', 'costs', 'savings']) &&
200
+ (0, exports.isEnvironmentCoverageStateV1)(value.subscriptionSummary) &&
201
+ (0, exports.isEnvironmentCoverageStateV1)(value.resources) &&
202
+ (0, exports.isEnvironmentCoverageStateV1)(value.recommendations) &&
203
+ (0, exports.isEnvironmentCoverageStateV1)(value.costs) &&
204
+ (0, exports.isEnvironmentCoverageStateV1)(value.savings);
205
+ const isCostSummary = (value) => (0, internal_js_1.isRecord)(value) &&
206
+ (0, internal_js_1.hasExactKeys)(value, [], ['observedCost', 'potentialSavings', 'resourceCount', 'recommendationCount']) &&
207
+ (value.observedCost === undefined || isObservedMoney(value.observedCost)) &&
208
+ (value.potentialSavings === undefined || isSavingsMoney(value.potentialSavings)) &&
209
+ (value.resourceCount === undefined || (0, internal_js_1.isNonNegativeInteger)(value.resourceCount)) &&
210
+ (value.recommendationCount === undefined || (0, internal_js_1.isNonNegativeInteger)(value.recommendationCount));
211
+ /** Validates the strict, bounded phase-one subscription-cost projection. */
212
+ const isEnvironmentSubscriptionCostProjectionV1 = (value) => {
213
+ if (!(0, internal_js_1.hasSafeContainerShape)(value) || !(0, internal_js_1.isRecord)(value))
214
+ return false;
215
+ if (!(0, internal_js_1.hasExactKeys)(value, [
216
+ 'schemaVersion',
217
+ 'scope',
218
+ 'sourceBinding',
219
+ 'generatedAt',
220
+ 'subscription',
221
+ 'sourceCoverage',
222
+ 'costSummary',
223
+ 'serviceFamilyRollups',
224
+ 'estateCostRollups',
225
+ 'costDrivers',
226
+ 'recommendations',
227
+ 'changes',
228
+ 'warnings',
229
+ 'sourceReferences',
230
+ ]) ||
231
+ value.schemaVersion !== 1 ||
232
+ !(0, exports.isEnvironmentScopeV1)(value.scope) ||
233
+ !(0, exports.isEnvironmentSourceBindingV1)(value.sourceBinding) ||
234
+ !scopesEqual(value.scope, value.sourceBinding.scope) ||
235
+ !(0, internal_js_1.isCanonicalUtcTimestamp)(value.generatedAt) ||
236
+ Date.parse(value.generatedAt) < Date.parse(value.sourceBinding.completedAt) ||
237
+ !(0, internal_js_1.isRecord)(value.subscription) ||
238
+ !(0, internal_js_1.hasExactKeys)(value.subscription, ['safeLabel', 'portalRoute']) ||
239
+ !(0, internal_js_1.isSafeLabel)(value.subscription.safeLabel) ||
240
+ !(0, exports.isEnvironmentPortalRouteV1)(value.subscription.portalRoute) ||
241
+ !isSourceCoverage(value.sourceCoverage) ||
242
+ !isCostSummary(value.costSummary) ||
243
+ !isBoundedList(value.serviceFamilyRollups, isCostRollup) ||
244
+ !isBoundedList(value.estateCostRollups, isCostRollup) ||
245
+ !isBoundedList(value.costDrivers, isCostDriver) ||
246
+ !isBoundedList(value.recommendations, isRecommendation) ||
247
+ !isBoundedList(value.changes, isCostChange) ||
248
+ !isBoundedList(value.warnings, isWarning) ||
249
+ !isReferenceArray(value.sourceReferences)) {
250
+ return false;
251
+ }
252
+ return (0, internal_js_1.utf8ByteLength)(JSON.stringify(value)) <= contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.projectionBytes;
253
+ };
254
+ exports.isEnvironmentSubscriptionCostProjectionV1 = isEnvironmentSubscriptionCostProjectionV1;
255
+ const descriptorByteLimit = (name) => {
256
+ if (name === 'projection.json')
257
+ return contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.projectionBytes;
258
+ if (name === 'environment-index.md')
259
+ return contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.environmentIndexBytes;
260
+ return contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.costPillarBytes;
261
+ };
262
+ /** Validates one descriptor from the exact V1 three-document allowlist. */
263
+ const isEnvironmentDocumentDescriptorV1 = (value) => {
264
+ if (!(0, internal_js_1.isRecord)(value) || !(0, internal_js_1.hasExactKeys)(value, ['name', 'mediaType', 'byteCount', 'contentSha256', 'approximateTokenCount']))
265
+ return false;
266
+ if (typeof value.name !== 'string' || !DOCUMENT_NAMES.has(value.name))
267
+ return false;
268
+ const expectedMediaType = value.name === 'projection.json' ? 'application/json' : 'text/markdown; charset=utf-8';
269
+ return (value.mediaType === expectedMediaType &&
270
+ (0, internal_js_1.isNonNegativeInteger)(value.byteCount) &&
271
+ value.byteCount > 0 &&
272
+ value.byteCount <= descriptorByteLimit(value.name) &&
273
+ typeof value.contentSha256 === 'string' &&
274
+ internal_js_1.SHA256_PATTERN.test(value.contentSha256) &&
275
+ (0, internal_js_1.isNonNegativeInteger)(value.approximateTokenCount));
276
+ };
277
+ exports.isEnvironmentDocumentDescriptorV1 = isEnvironmentDocumentDescriptorV1;
278
+ /** Validates that descriptors contain each allowlisted V1 document exactly once. */
279
+ const isEnvironmentDocumentDescriptorSetV1 = (value) => Array.isArray(value) &&
280
+ value.length === contracts_js_1.ENVIRONMENT_DOCUMENT_NAMES_V1.length &&
281
+ value.every(exports.isEnvironmentDocumentDescriptorV1) &&
282
+ new Set(value.map(descriptor => descriptor.name)).size === contracts_js_1.ENVIRONMENT_DOCUMENT_NAMES_V1.length &&
283
+ contracts_js_1.ENVIRONMENT_DOCUMENT_NAMES_V1.every(name => value.some(descriptor => descriptor.name === name));
284
+ exports.isEnvironmentDocumentDescriptorSetV1 = isEnvironmentDocumentDescriptorSetV1;
285
+ /** Validates an atomically visible completed environment-generation pointer. */
286
+ const isEnvironmentCompiledGenerationPointerV1 = (value) => {
287
+ if (!(0, internal_js_1.hasSafeContainerShape)(value) || !(0, internal_js_1.isRecord)(value))
288
+ return false;
289
+ if (!(0, internal_js_1.hasExactKeys)(value, ['schemaVersion', 'status', 'environmentRunId', 'scope', 'sourceBinding', 'treeDigestSha256', 'fileCount', 'generatedAt']) ||
290
+ value.schemaVersion !== 1 ||
291
+ value.status !== 'completed' ||
292
+ !(0, exports.isEnvironmentRunIdV1)(value.environmentRunId) ||
293
+ !(0, exports.isEnvironmentScopeV1)(value.scope) ||
294
+ !(0, exports.isEnvironmentSourceBindingV1)(value.sourceBinding) ||
295
+ !scopesEqual(value.scope, value.sourceBinding.scope) ||
296
+ typeof value.treeDigestSha256 !== 'string' ||
297
+ !internal_js_1.SHA256_PATTERN.test(value.treeDigestSha256) ||
298
+ value.fileCount !== 3 ||
299
+ !(0, internal_js_1.isCanonicalUtcTimestamp)(value.generatedAt) ||
300
+ Date.parse(value.generatedAt) < Date.parse(value.sourceBinding.completedAt)) {
301
+ return false;
302
+ }
303
+ const sourceIdentities = [
304
+ value.sourceBinding.publicationId,
305
+ value.sourceBinding.portalRunId,
306
+ value.sourceBinding.pluginRunId,
307
+ value.sourceBinding.economicsGenerationId,
308
+ value.sourceBinding.economicsFingerprint,
309
+ ];
310
+ return (!sourceIdentities.includes(value.environmentRunId) &&
311
+ (0, internal_js_1.utf8ByteLength)(JSON.stringify(value)) <= contracts_js_1.ENVIRONMENT_CONTRACT_LIMITS_V1.completedPointerBytes);
312
+ };
313
+ exports.isEnvironmentCompiledGenerationPointerV1 = isEnvironmentCompiledGenerationPointerV1;
314
+ /** Validates the artifact kind without widening the closed V1 union. */
315
+ const isEnvironmentArtifactKindV1 = (value) => typeof value === 'string' && ARTIFACT_KINDS.has(value);
316
+ exports.isEnvironmentArtifactKindV1 = isEnvironmentArtifactKindV1;
317
+ /** Validates the V1 safe-label bound used by customer-visible evidence metadata. */
318
+ const isEnvironmentSafeLabelV1 = (value) => (0, internal_js_1.isSafeLabel)(value);
319
+ exports.isEnvironmentSafeLabelV1 = isEnvironmentSafeLabelV1;
320
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/environment/validation.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,11 @@
1
1
  /** Common AI interfaces shared between frontend and backend */
2
- export {};
2
+ import { hasExactKeys, isRecord } from '../environment/internal.js';
3
+ import { isEnvironmentArtifactKindV1, isEnvironmentPortalRouteV1, isEnvironmentSafeLabelV1, isEnvironmentScopeV1, isEnvironmentSourceGenerationV1, } from '../environment/validation.js';
4
+ /** Strictly validates the client-safe environment evidence shape. */
5
+ export const isAIEnvironmentEvidenceMatch = (value) => isRecord(value) &&
6
+ hasExactKeys(value, ['safeLabel', 'portalRoute', 'scope', 'artifactKind', 'sourceGeneration']) &&
7
+ isEnvironmentSafeLabelV1(value.safeLabel) &&
8
+ isEnvironmentPortalRouteV1(value.portalRoute) &&
9
+ isEnvironmentScopeV1(value.scope) &&
10
+ isEnvironmentArtifactKindV1(value.artifactKind) &&
11
+ isEnvironmentSourceGenerationV1(value.sourceGeneration);
@@ -0,0 +1,3 @@
1
+ export * from '../environment/index.js';
2
+ import * as namespace from '../environment/index.js';
3
+ export default namespace;
@@ -0,0 +1,34 @@
1
+ import { isEnvironmentDocumentDescriptorSetV1, isEnvironmentScopeV1 } from './validation.js';
2
+ const compareUnicodeCodePoints = (left, right) => {
3
+ const leftPoints = Array.from(left, character => character.codePointAt(0));
4
+ const rightPoints = Array.from(right, character => character.codePointAt(0));
5
+ const length = Math.min(leftPoints.length, rightPoints.length);
6
+ for (let index = 0; index < length; index += 1) {
7
+ const difference = leftPoints[index] - rightPoints[index];
8
+ if (difference !== 0)
9
+ return difference;
10
+ }
11
+ return leftPoints.length - rightPoints.length;
12
+ };
13
+ /**
14
+ * Builds the canonical scope-qualified artifact subject used inside opaque
15
+ * logical references. The JSON tuple is an identifier, never a storage path.
16
+ */
17
+ export const buildEnvironmentScopeQualifiedSubjectV1 = (scope) => {
18
+ if (!isEnvironmentScopeV1(scope))
19
+ throw new TypeError('Invalid V1 environment scope.');
20
+ return JSON.stringify([scope.kind, scope.tenantId, scope.companyId, scope.subscriptionId]);
21
+ };
22
+ /**
23
+ * Produces the exact compact UTF-8 tree-digest preimage. Hashing remains the
24
+ * caller's responsibility so this helper stays browser-safe.
25
+ */
26
+ export const buildEnvironmentTreeDigestPreimageV1 = (descriptors) => {
27
+ if (!isEnvironmentDocumentDescriptorSetV1(descriptors)) {
28
+ throw new TypeError('V1 environment tree digests require each allowlisted document exactly once.');
29
+ }
30
+ const pairs = descriptors
31
+ .map(descriptor => [descriptor.name, descriptor.contentSha256])
32
+ .sort((left, right) => compareUnicodeCodePoints(left[0], right[0]));
33
+ return JSON.stringify(pairs);
34
+ };
@@ -0,0 +1,17 @@
1
+ /** Phase-one environment-memory contract constants shared by producers and consumers. */
2
+ export const ENVIRONMENT_CONTRACT_LIMITS_V1 = Object.freeze({
3
+ completedPointerBytes: 16 * 1024,
4
+ projectionBytes: 64 * 1024,
5
+ environmentIndexBytes: 4 * 1024,
6
+ costPillarBytes: 8 * 1024,
7
+ boundedListItems: 50,
8
+ customerStringScalars: 4096,
9
+ safeLabelScalars: 512,
10
+ scopeIdentifierScalars: 2048,
11
+ environmentRunIdAsciiCharacters: 128,
12
+ sourceIdentityScalars: 256,
13
+ logicalReferencePayloadBytes: 4 * 1024,
14
+ validatedContainerDepth: 8,
15
+ });
16
+ export const ENVIRONMENT_DOCUMENT_NAMES_V1 = ['projection.json', 'environment-index.md', 'pillars/cost.md'];
17
+ export const ENVIRONMENT_ARTIFACT_KINDS_V1 = ['subscription-summary', 'subscription-resources', 'subscription-recommendations'];
@@ -0,0 +1,4 @@
1
+ export * from './contracts.js';
2
+ export * from './references.js';
3
+ export * from './validation.js';
4
+ export * from './canonicalization.js';
@@ -0,0 +1,97 @@
1
+ import { ENVIRONMENT_CONTRACT_LIMITS_V1 } from './contracts.js';
2
+ export const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
3
+ export const ENVIRONMENT_RUN_ID_PATTERN = /^[A-Za-z0-9._-]+$/u;
4
+ export const DECIMAL_PATTERN = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u;
5
+ export const CURRENCY_PATTERN = /^[A-Z]{3}$/u;
6
+ export const PROTOTYPE_KEYS = new Set(['__proto__', 'prototype', 'constructor']);
7
+ export const hasControlCharacter = (value) => {
8
+ for (const character of value) {
9
+ const codePoint = character.codePointAt(0);
10
+ if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))
11
+ return true;
12
+ }
13
+ return false;
14
+ };
15
+ export const isRecord = (value) => {
16
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
17
+ return false;
18
+ const prototype = Object.getPrototypeOf(value);
19
+ return prototype === Object.prototype || prototype === null;
20
+ };
21
+ export const hasExactKeys = (value, required, optional = []) => {
22
+ const allowed = new Set([...required, ...optional]);
23
+ const keys = Object.keys(value);
24
+ return required.every(key => Object.prototype.hasOwnProperty.call(value, key)) && keys.every(key => allowed.has(key) && !PROTOTYPE_KEYS.has(key));
25
+ };
26
+ const scalarLength = (value) => {
27
+ let count = 0;
28
+ for (let index = 0; index < value.length; index += 1) {
29
+ const codeUnit = value.charCodeAt(index);
30
+ if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
31
+ const trailing = value.charCodeAt(index + 1);
32
+ if (!(trailing >= 0xdc00 && trailing <= 0xdfff))
33
+ return null;
34
+ index += 1;
35
+ }
36
+ else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
37
+ return null;
38
+ }
39
+ count += 1;
40
+ }
41
+ return count;
42
+ };
43
+ export const isBoundedString = (value, maximumScalars, options = {}) => {
44
+ if (typeof value !== 'string')
45
+ return false;
46
+ if (options.trimmed && (value.length === 0 || value.trim() !== value))
47
+ return false;
48
+ if (options.controls && hasControlCharacter(value))
49
+ return false;
50
+ const length = scalarLength(value);
51
+ return length !== null && length <= maximumScalars;
52
+ };
53
+ export const isCustomerString = (value) => isBoundedString(value, ENVIRONMENT_CONTRACT_LIMITS_V1.customerStringScalars, { controls: true });
54
+ export const isSafeLabel = (value) => isBoundedString(value, ENVIRONMENT_CONTRACT_LIMITS_V1.safeLabelScalars, { trimmed: true, controls: true });
55
+ export const isScopeIdentifier = (value) => isBoundedString(value, ENVIRONMENT_CONTRACT_LIMITS_V1.scopeIdentifierScalars, { trimmed: true, controls: true });
56
+ export const isSourceIdentity = (value) => isBoundedString(value, ENVIRONMENT_CONTRACT_LIMITS_V1.sourceIdentityScalars, { trimmed: true, controls: true });
57
+ export const isNonNegativeInteger = (value) => Number.isSafeInteger(value) && value >= 0;
58
+ export const isCanonicalUtcTimestamp = (value) => {
59
+ if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(value))
60
+ return false;
61
+ const milliseconds = Date.parse(value);
62
+ return Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === value;
63
+ };
64
+ export const utf8ByteLength = (value) => {
65
+ let bytes = 0;
66
+ for (const character of value) {
67
+ const codePoint = character.codePointAt(0);
68
+ if (codePoint <= 0x7f)
69
+ bytes += 1;
70
+ else if (codePoint <= 0x7ff)
71
+ bytes += 2;
72
+ else if (codePoint <= 0xffff)
73
+ bytes += 3;
74
+ else
75
+ bytes += 4;
76
+ }
77
+ return bytes;
78
+ };
79
+ export const hasSafeContainerShape = (value, depth = 0, seen = new Set()) => {
80
+ if (depth > ENVIRONMENT_CONTRACT_LIMITS_V1.validatedContainerDepth)
81
+ return false;
82
+ if (typeof value !== 'object' || value === null)
83
+ return true;
84
+ if (seen.has(value))
85
+ return false;
86
+ seen.add(value);
87
+ if (Array.isArray(value)) {
88
+ const valid = value.length <= ENVIRONMENT_CONTRACT_LIMITS_V1.boundedListItems && value.every(item => hasSafeContainerShape(item, depth + 1, seen));
89
+ seen.delete(value);
90
+ return valid;
91
+ }
92
+ if (!isRecord(value))
93
+ return false;
94
+ const valid = Object.keys(value).every(key => !PROTOTYPE_KEYS.has(key) && hasSafeContainerShape(value[key], depth + 1, seen));
95
+ seen.delete(value);
96
+ return valid;
97
+ };