@serve.zone/interfaces 19.8.0 → 20.1.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/changelog.md +28 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/immutableimage.d.ts +2 -0
- package/dist_ts/data/immutableimage.js +1 -1
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/data/isolatedrestore.js +7 -82
- package/dist_ts/data/secret.d.ts +205 -0
- package/dist_ts/data/secret.js +469 -0
- package/dist_ts/data/secretbundle.d.ts +4 -0
- package/dist_ts/data/secretgroup.d.ts +4 -0
- package/dist_ts/data/service.d.ts +18 -6
- package/dist_ts/data/service.js +1 -1
- package/dist_ts/platform/index.d.ts +3 -1
- package/dist_ts/platform/index.js +4 -2
- package/dist_ts/platform/storagemigration.d.ts +346 -0
- package/dist_ts/platform/storagemigration.golden.d.ts +49 -0
- package/dist_ts/platform/storagemigration.golden.js +207 -0
- package/dist_ts/platform/storagemigration.js +1554 -0
- package/dist_ts/private/canonicaljson.d.ts +14 -0
- package/dist_ts/private/canonicaljson.js +154 -0
- package/dist_ts/requests/index.d.ts +2 -1
- package/dist_ts/requests/index.js +3 -2
- package/dist_ts/requests/secret.d.ts +198 -0
- package/dist_ts/requests/secret.js +2 -0
- package/dist_ts/runtime.d.ts +41 -0
- package/dist_ts/runtime.js +33 -0
- package/package.json +9 -2
- package/readme.md +162 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/immutableimage.ts +2 -0
- package/ts/data/index.ts +1 -0
- package/ts/data/isolatedrestore.ts +12 -93
- package/ts/data/secret.ts +835 -0
- package/ts/data/secretbundle.ts +4 -0
- package/ts/data/secretgroup.ts +4 -0
- package/ts/data/service.ts +26 -6
- package/ts/platform/index.ts +3 -0
- package/ts/platform/storagemigration.golden.ts +241 -0
- package/ts/platform/storagemigration.ts +3082 -0
- package/ts/private/canonicaljson.ts +221 -0
- package/ts/requests/index.ts +2 -0
- package/ts/requests/secret.ts +256 -0
- package/ts/runtime.ts +80 -0
package/readme.md
CHANGED
|
@@ -120,6 +120,130 @@ must reject unknown manifest fields and unsupported required feature IDs before
|
|
|
120
120
|
provisioning. Legacy `volumes` and `platformRequirements.s3` remain deprecated
|
|
121
121
|
inputs for strict resolver normalization only.
|
|
122
122
|
|
|
123
|
+
`platform.storagemigration` defines the provider-neutral cutover contract for a
|
|
124
|
+
named object-storage binding. Corestore atomically owns and fences the source
|
|
125
|
+
binding after validating a distinct, unfenced active-object snapshot. Onebox
|
|
126
|
+
only receives a held candidate, stages that exact candidate, stops the matching
|
|
127
|
+
workload generation, and attests the quiesced state. The candidate cannot start
|
|
128
|
+
until `destinationBindingStartAuthorized` is true. Corestore continues returning
|
|
129
|
+
`consumerAction: 'startDestination'` until Onebox submits the mutation-fenced
|
|
130
|
+
consumer activation request and the acknowledgement becomes durable evidence.
|
|
131
|
+
Candidate-issued abort tombstones authorize only `startSource` and never retain
|
|
132
|
+
the staged candidate binding.
|
|
133
|
+
|
|
134
|
+
Every migration DTO and status has an exact, versioned runtime normalizer.
|
|
135
|
+
Unknown fields, provider or pool identifiers, unbounded strings, unsafe
|
|
136
|
+
integers, stale mutation revisions, identity drift, and lifecycle-inconsistent
|
|
137
|
+
fields are rejected. Migration-created digests use strict canonical JSON and a
|
|
138
|
+
bare lowercase 64-hex SHA-256 value; portable golden vectors cover the source
|
|
139
|
+
snapshot, target request, prepare intent, and candidate binding. Pre-cutover
|
|
140
|
+
failures may retry or abort; after the durable commit point, recovery can only
|
|
141
|
+
retry or roll forward. Physical pool IDs, mount details, provider receipts, and
|
|
142
|
+
publication capabilities remain private.
|
|
143
|
+
|
|
144
|
+
Primary exports include:
|
|
145
|
+
|
|
146
|
+
- `IObjectStorageMigrationPrepareRequest` and
|
|
147
|
+
`TObjectStorageMigrationStatus` for the immutable intent and status journal.
|
|
148
|
+
- `IObjectStorageMigrationConsumerQuiesceRequest` with
|
|
149
|
+
`IStorageMigrationConsumerQuiesceEvidence` for exact candidate staging and
|
|
150
|
+
source-workload shutdown.
|
|
151
|
+
- `IObjectStorageMigrationConsumerActivationRequest` with
|
|
152
|
+
`IStorageMigrationConsumerActivationEvidence` for durable destination-start
|
|
153
|
+
acknowledgement.
|
|
154
|
+
- `normalizeObjectStorageMigrationStatus`,
|
|
155
|
+
`bindObjectStorageMigrationConsumerQuiesceRequest`, and
|
|
156
|
+
`bindObjectStorageMigrationConsumerActivationRequest` for strict ingress and
|
|
157
|
+
current-revision mutation fencing.
|
|
158
|
+
- The `create*Sha256` helpers for source snapshots, prepare intent, target
|
|
159
|
+
requests, candidate/active bindings, and persisted staging or activation
|
|
160
|
+
evidence.
|
|
161
|
+
|
|
162
|
+
The phase and consumer-action progression is exact:
|
|
163
|
+
|
|
164
|
+
| Phase | `consumerAction` | Destination start authorized |
|
|
165
|
+
| --- | --- | --- |
|
|
166
|
+
| `preparing`, `transferring` | `wait` | No |
|
|
167
|
+
| `awaitingConsumerQuiesce` | `stageCandidateAndStop` | No |
|
|
168
|
+
| `finalizing`, `committing` | `wait` | No |
|
|
169
|
+
| `readyToStart` | `startDestination` | Yes |
|
|
170
|
+
| `cleanupPending`, `complete` | `none` | Yes; durable activation evidence is required |
|
|
171
|
+
| `aborting` | `wait` | No |
|
|
172
|
+
| `aborted` | `startSource` | No; only the active source binding may restart |
|
|
173
|
+
|
|
174
|
+
Normalize every status before acting, and bind consumer mutations to that exact
|
|
175
|
+
status revision:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const status =
|
|
179
|
+
await platform.storagemigration.normalizeObjectStorageMigrationStatus(
|
|
180
|
+
untrustedStatusPayload,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
if (status.phase === 'awaitingConsumerQuiesce') {
|
|
184
|
+
const request =
|
|
185
|
+
await platform.storagemigration.bindObjectStorageMigrationConsumerQuiesceRequest(
|
|
186
|
+
untrustedQuiescePayload,
|
|
187
|
+
status,
|
|
188
|
+
);
|
|
189
|
+
await submitQuiesceAcknowledgement(request);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (status.phase === 'readyToStart') {
|
|
193
|
+
if (
|
|
194
|
+
!status.destinationBindingStartAuthorized ||
|
|
195
|
+
status.consumerAction !== 'startDestination'
|
|
196
|
+
) {
|
|
197
|
+
throw new Error('destination binding is not authorized to start');
|
|
198
|
+
}
|
|
199
|
+
await startWorkload(status.activeBinding);
|
|
200
|
+
const request =
|
|
201
|
+
await platform.storagemigration.bindObjectStorageMigrationConsumerActivationRequest(
|
|
202
|
+
untrustedActivationPayload,
|
|
203
|
+
status,
|
|
204
|
+
);
|
|
205
|
+
await submitActivationAcknowledgement(request);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (status.phase === 'cleanupPending') {
|
|
209
|
+
// Cleanup is reachable only after this durable acknowledgement was accepted.
|
|
210
|
+
const durableActivation = status.consumerActivationEvidence;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (status.phase === 'aborted') {
|
|
214
|
+
if (
|
|
215
|
+
status.destinationBindingStartAuthorized ||
|
|
216
|
+
status.consumerAction !== 'startSource'
|
|
217
|
+
) {
|
|
218
|
+
throw new Error('invalid aborted migration status');
|
|
219
|
+
}
|
|
220
|
+
await startWorkload(status.activeBinding);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Here `startWorkload`, `submitQuiesceAcknowledgement`, and
|
|
225
|
+
`submitActivationAcknowledgement` are consumer-owned operations, not package
|
|
226
|
+
exports. Canonical digests are produced from normalized payloads:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const snapshotSha256 =
|
|
230
|
+
await platform.storagemigration.createUnfencedObjectStorageBindingControlSnapshotSha256(
|
|
231
|
+
snapshotDigestPayload,
|
|
232
|
+
);
|
|
233
|
+
const migrationSha256 =
|
|
234
|
+
await platform.storagemigration.createObjectStorageMigrationSha256(
|
|
235
|
+
prepareRequest,
|
|
236
|
+
);
|
|
237
|
+
const candidateSha256 =
|
|
238
|
+
await platform.storagemigration.createObjectStorageMigrationBindingSha256(
|
|
239
|
+
candidateBinding,
|
|
240
|
+
);
|
|
241
|
+
const activationRecordSha256 =
|
|
242
|
+
await platform.storagemigration.createObjectStorageMigrationPersistedActivationSha256(
|
|
243
|
+
activationDigestPayload,
|
|
244
|
+
);
|
|
245
|
+
```
|
|
246
|
+
|
|
123
247
|
## Data Contracts
|
|
124
248
|
|
|
125
249
|
Use `data` when you need object shapes that are persisted, exchanged between services, or exposed through the Cloudly API.
|
|
@@ -137,7 +261,6 @@ const service: data.IService = {
|
|
|
137
261
|
environment: {
|
|
138
262
|
NODE_ENV: 'production',
|
|
139
263
|
},
|
|
140
|
-
secretBundleId: 'secretbundle-api',
|
|
141
264
|
serviceCategory: 'workload',
|
|
142
265
|
deploymentStrategy: 'limited-replicas',
|
|
143
266
|
scaleFactor: 2,
|
|
@@ -186,7 +309,17 @@ Common data contracts include:
|
|
|
186
309
|
- Service port contracts including `IServiceTargetPort`, `IServiceDomainRoute`, and `IServicePublicPortMapping` for canonical backend targets, domain target references, and edge/Coretraffic TCP/UDP public exposure.
|
|
187
310
|
- `IDomain`, `IDnsEntry`, and traffic contracts for routing and DNS management.
|
|
188
311
|
- Traffic and gateway route contracts including `ICoretrafficPortRouteConfig`, routing `portRoutes`, and `IGatewayClientRoute` client-owned route views. Gateway route intent supports optional match `domains`, `transport`, and `remoteIngress`, plus explicit route `priority` and `managedRouteKind`. Ownership can combine `hostname` with `routeRef` so a normal route and a path-specific managed route for the same hostname reconcile independently.
|
|
189
|
-
- `
|
|
312
|
+
- Value-free `ISecretMetadata`, `ISecretVersionMetadata`, and `ISecretSetMetadata`
|
|
313
|
+
contracts for operator views, plus exact-version `IResolvedSecretManifest`
|
|
314
|
+
contracts for cluster delivery. Manifest helpers enforce canonical shared
|
|
315
|
+
digests, globally unique environment/file delivery targets, and per-cluster
|
|
316
|
+
desired/applied/previous-accepted rollout state. `ISecretBundle` and
|
|
317
|
+
`ISecretGroup` remain legacy compatibility contracts during the versioned
|
|
318
|
+
migration.
|
|
319
|
+
`listSecrets` exposes the dedicated `targetSecretsRevision` CAS fence;
|
|
320
|
+
`createSecret` consumes and returns that fence, while
|
|
321
|
+
`setServiceSecretSetAttachments` returns the independent
|
|
322
|
+
`secretConfigurationRevision`. Generic service writes own neither revision.
|
|
190
323
|
- Mail gateway contracts for domain authorities, address bindings, WorkApp bindings, managed SMTP/API credentials, spool items, delivery journals, and inbound/outbound message payloads.
|
|
191
324
|
- Service-level mail configuration through `IService.data.mail`, including per-address inbound `smtpForward` settings and outbound credential metadata. Cloudly settings include dcrouter gateway, SMTP submission, and inbound forward-target keys for reconciling those bindings.
|
|
192
325
|
- Web Push contracts for environment-specific service bindings, public credential state, public VAPID key rotation metadata, privacy-minimal notification signals, and redacted delivery state. Subscription endpoints, browser key material, provider ciphertext, VAPID private keys, and credential secrets are intentionally absent from public binding and status DTOs.
|
|
@@ -374,6 +507,7 @@ Request groups are exported by product area:
|
|
|
374
507
|
- `requests.node`
|
|
375
508
|
- `requests.platform`
|
|
376
509
|
- `requests.routing`
|
|
510
|
+
- `requests.secret`
|
|
377
511
|
- `requests.secretbundle`
|
|
378
512
|
- `requests.secretgroup`
|
|
379
513
|
- `requests.server`
|
|
@@ -384,6 +518,30 @@ Request groups are exported by product area:
|
|
|
384
518
|
- `requests.version`
|
|
385
519
|
- `requests.webpush`
|
|
386
520
|
|
|
521
|
+
Secret material response contracts are not exported from the universal
|
|
522
|
+
browser-facing entrypoint. Node runtimes import the isolated subpath:
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
import {
|
|
526
|
+
verifyResolvedSecretMaterial,
|
|
527
|
+
} from '@serve.zone/interfaces/runtime';
|
|
528
|
+
import type {
|
|
529
|
+
IReq_GetResolvedSecretMaterial,
|
|
530
|
+
IResolvedSecretMaterial,
|
|
531
|
+
} from '@serve.zone/interfaces/runtime';
|
|
532
|
+
|
|
533
|
+
async function acceptMaterial(material: IResolvedSecretMaterial) {
|
|
534
|
+
if (!await verifyResolvedSecretMaterial(material)) {
|
|
535
|
+
throw new Error('secret material does not match its immutable manifest');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Runtime material is shaped as `{ manifest, values }`. The helper verifies the
|
|
541
|
+
canonical manifest digest and exact one-to-one version-ID coverage before
|
|
542
|
+
plaintext use. The runtime must separately compare the verified manifest
|
|
543
|
+
reference and cluster to its request and authenticated deployment scope.
|
|
544
|
+
|
|
387
545
|
## Platform Contracts
|
|
388
546
|
|
|
389
547
|
Use `platform` for current platform-service capabilities and application-facing platform RPCs.
|
|
@@ -404,6 +562,8 @@ Available platform modules:
|
|
|
404
562
|
- `platform.pushnotification` is the deprecated legacy device-token push contract. New browser Web Push integrations use `requests.webpush`.
|
|
405
563
|
- `platform.letter` for physical letter workflows.
|
|
406
564
|
- `platform.ai`, `platform.database`, `platform.objectstorage`, `platform.logging`, `platform.backup`, and `platform.sip` for infrastructure and application capabilities.
|
|
565
|
+
- `platform.storage` for provider-neutral storage classes, requests, capabilities, and resolved bindings.
|
|
566
|
+
- `platform.storagemigration` for fenced object-storage migration intent, status, consumer acknowledgements, canonical digests, and strict normalizers.
|
|
407
567
|
- `platform.types` plus root re-exports for shared capability, provider, binding, credential, and endpoint metadata.
|
|
408
568
|
|
|
409
569
|
## Legacy Platformservice Contracts
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -66,6 +66,8 @@ export interface ICoreflowRuntimeCapabilities {
|
|
|
66
66
|
immutableImageDeploymentVersion: 1;
|
|
67
67
|
/** Coreflow can answer the versioned, node-scoped Corestore inventory probe. */
|
|
68
68
|
corestoreInventoryVersion?: 1;
|
|
69
|
+
/** Coreflow can consume exact, cluster-scoped resolved secret manifests. */
|
|
70
|
+
secretManifestVersion?: 1;
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
/**
|
package/ts/data/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './isolatedrestore.js';
|
|
|
19
19
|
export * from './isolatedrestore.golden.js';
|
|
20
20
|
export * from './mail.js';
|
|
21
21
|
export * from './registry.js';
|
|
22
|
+
export * from './secret.js';
|
|
22
23
|
export * from './secretbundle.js';
|
|
23
24
|
export * from './secretgroup.js';
|
|
24
25
|
export * from './baremetal.js';
|
|
@@ -3,6 +3,13 @@ import type {
|
|
|
3
3
|
IBackupArchiveObject,
|
|
4
4
|
TIsolatedRestoreResourceMapping,
|
|
5
5
|
} from './backup.js';
|
|
6
|
+
import {
|
|
7
|
+
canonicalizeStrictJson,
|
|
8
|
+
createCanonicalJsonSha256Hex,
|
|
9
|
+
createSha256Hex,
|
|
10
|
+
deepFreezeValue,
|
|
11
|
+
strictCanonicalJsonRules,
|
|
12
|
+
} from '../private/canonicaljson.js';
|
|
6
13
|
|
|
7
14
|
/** Operations carried by a short-lived, single-operation restore grant. */
|
|
8
15
|
export const isolatedRestoreGrantOperations = Object.freeze([
|
|
@@ -307,15 +314,7 @@ export class IsolatedRestoreContractError extends Error {
|
|
|
307
314
|
}
|
|
308
315
|
|
|
309
316
|
/** Cross-runtime rules for restore authority digests. */
|
|
310
|
-
export const isolatedRestoreCanonicalJsonRules =
|
|
311
|
-
version: 1 as const,
|
|
312
|
-
encoding: 'utf-8' as const,
|
|
313
|
-
objectKeyOrdering: 'utf-16-code-unit-ascending' as const,
|
|
314
|
-
arrayOrdering: 'preserved-dense' as const,
|
|
315
|
-
unicodeNormalization: 'preserved' as const,
|
|
316
|
-
numberEncoding: 'safe-integer-json-no-negative-zero' as const,
|
|
317
|
-
digest: 'sha256-lowercase-hex' as const,
|
|
318
|
-
});
|
|
317
|
+
export const isolatedRestoreCanonicalJsonRules = strictCanonicalJsonRules;
|
|
319
318
|
|
|
320
319
|
const canonicalIdentifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:@-]{0,255}$/;
|
|
321
320
|
const canonicalScopedIdPattern = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,191}$/;
|
|
@@ -360,23 +359,7 @@ export const assertIsolatedRestoreControlIngressByteLength = (
|
|
|
360
359
|
return byteLengthArg;
|
|
361
360
|
};
|
|
362
361
|
|
|
363
|
-
const deepFreeze =
|
|
364
|
-
if (!valueArg || typeof valueArg !== 'object') {
|
|
365
|
-
return valueArg;
|
|
366
|
-
}
|
|
367
|
-
const object = valueArg as object;
|
|
368
|
-
if (ArrayBuffer.isView(object) || seenArg.has(object)) {
|
|
369
|
-
return valueArg;
|
|
370
|
-
}
|
|
371
|
-
seenArg.add(object);
|
|
372
|
-
for (const key of Reflect.ownKeys(object)) {
|
|
373
|
-
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
374
|
-
if (descriptor && Object.hasOwn(descriptor, 'value')) {
|
|
375
|
-
deepFreeze(descriptor.value, seenArg);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
return Object.freeze(valueArg);
|
|
379
|
-
};
|
|
362
|
+
const deepFreeze = deepFreezeValue;
|
|
380
363
|
|
|
381
364
|
const verifiedIsolatedRestoreGrantCompacts = new WeakMap<object, string>();
|
|
382
365
|
const verifiedIsolatedRestoreWriteBindings = new WeakSet<object>();
|
|
@@ -1419,64 +1402,7 @@ export const normalizeIsolatedRestoreControlStatusRequest = (
|
|
|
1419
1402
|
};
|
|
1420
1403
|
|
|
1421
1404
|
const canonicalizeJson = (valueArg: unknown): string => {
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
const visit = (currentValueArg: unknown, fieldNameArg: string): string => {
|
|
1425
|
-
if (currentValueArg === null) {
|
|
1426
|
-
return 'null';
|
|
1427
|
-
}
|
|
1428
|
-
if (typeof currentValueArg === 'boolean') {
|
|
1429
|
-
return currentValueArg ? 'true' : 'false';
|
|
1430
|
-
}
|
|
1431
|
-
if (typeof currentValueArg === 'string') {
|
|
1432
|
-
assertUnicodeScalarString(currentValueArg, fieldNameArg);
|
|
1433
|
-
return JSON.stringify(currentValueArg);
|
|
1434
|
-
}
|
|
1435
|
-
if (typeof currentValueArg === 'number') {
|
|
1436
|
-
if (
|
|
1437
|
-
!Number.isSafeInteger(currentValueArg) ||
|
|
1438
|
-
Object.is(currentValueArg, -0)
|
|
1439
|
-
) {
|
|
1440
|
-
return fail(`${fieldNameArg} must contain safe integers only`);
|
|
1441
|
-
}
|
|
1442
|
-
return String(currentValueArg);
|
|
1443
|
-
}
|
|
1444
|
-
if (typeof currentValueArg !== 'object') {
|
|
1445
|
-
return fail(`${fieldNameArg} contains a non-JSON value`);
|
|
1446
|
-
}
|
|
1447
|
-
if (ancestors.has(currentValueArg)) {
|
|
1448
|
-
return fail(`${fieldNameArg} contains a cycle`);
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
ancestors.add(currentValueArg);
|
|
1452
|
-
try {
|
|
1453
|
-
if (Array.isArray(currentValueArg)) {
|
|
1454
|
-
return `[${currentValueArg
|
|
1455
|
-
.map((entryArg, indexArg) =>
|
|
1456
|
-
visit(entryArg, `${fieldNameArg}[${indexArg}]`),
|
|
1457
|
-
)
|
|
1458
|
-
.join(',')}]`;
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
const record = readRecord(currentValueArg, fieldNameArg);
|
|
1462
|
-
const keys = Object.keys(record).sort((leftArg, rightArg) => {
|
|
1463
|
-
return leftArg < rightArg ? -1 : leftArg > rightArg ? 1 : 0;
|
|
1464
|
-
});
|
|
1465
|
-
return `{${keys
|
|
1466
|
-
.map((keyArg) => {
|
|
1467
|
-
assertUnicodeScalarString(keyArg, `${fieldNameArg} key`);
|
|
1468
|
-
return `${JSON.stringify(keyArg)}:${visit(
|
|
1469
|
-
record[keyArg],
|
|
1470
|
-
`${fieldNameArg}.${keyArg}`,
|
|
1471
|
-
)}`;
|
|
1472
|
-
})
|
|
1473
|
-
.join(',')}}`;
|
|
1474
|
-
} finally {
|
|
1475
|
-
ancestors.delete(currentValueArg);
|
|
1476
|
-
}
|
|
1477
|
-
};
|
|
1478
|
-
|
|
1479
|
-
return visit(valueArg, 'canonical JSON input');
|
|
1405
|
+
return canonicalizeStrictJson(valueArg, fail);
|
|
1480
1406
|
};
|
|
1481
1407
|
|
|
1482
1408
|
export const canonicalizeIsolatedRestoreResourceMappings = (
|
|
@@ -1618,20 +1544,13 @@ export const canonicalizeIsolatedRestoreAuthorityProjection = (
|
|
|
1618
1544
|
};
|
|
1619
1545
|
|
|
1620
1546
|
const createSha256 = async (contentsArg: Uint8Array): Promise<string> => {
|
|
1621
|
-
|
|
1622
|
-
if (!subtle) {
|
|
1623
|
-
return fail('Web Crypto SHA-256 is unavailable in this runtime');
|
|
1624
|
-
}
|
|
1625
|
-
const digest = await subtle.digest('SHA-256', new Uint8Array(contentsArg));
|
|
1626
|
-
return Array.from(new Uint8Array(digest), (byteArg) =>
|
|
1627
|
-
byteArg.toString(16).padStart(2, '0'),
|
|
1628
|
-
).join('');
|
|
1547
|
+
return createSha256Hex(contentsArg, fail);
|
|
1629
1548
|
};
|
|
1630
1549
|
|
|
1631
1550
|
const createCanonicalJsonSha256 = async (
|
|
1632
1551
|
canonicalJsonArg: string,
|
|
1633
1552
|
): Promise<string> => {
|
|
1634
|
-
return
|
|
1553
|
+
return createCanonicalJsonSha256Hex(canonicalJsonArg, fail);
|
|
1635
1554
|
};
|
|
1636
1555
|
|
|
1637
1556
|
export const createIsolatedRestoreBytesSha256 = async (
|