@substrat-run/contracts 0.48.1 → 0.50.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.
@@ -33,6 +33,7 @@ export declare const adminAction: z.ZodEnum<{
33
33
  rejectVersion: "rejectVersion";
34
34
  removeMember: "removeMember";
35
35
  requestPublish: "requestPublish";
36
+ restoreDirectory: "restoreDirectory";
36
37
  restoreScope: "restoreScope";
37
38
  revokeConnection: "revokeConnection";
38
39
  revokeEntitlement: "revokeEntitlement";
@@ -282,6 +283,7 @@ export declare const adminLogEntry: z.ZodObject<{
282
283
  rejectVersion: "rejectVersion";
283
284
  removeMember: "removeMember";
284
285
  requestPublish: "requestPublish";
286
+ restoreDirectory: "restoreDirectory";
285
287
  restoreScope: "restoreScope";
286
288
  revokeConnection: "revokeConnection";
287
289
  revokeEntitlement: "revokeEntitlement";
@@ -334,4 +336,262 @@ export declare const emailRelayRequest: z.ZodObject<{
334
336
  fromName: z.ZodOptional<z.ZodString>;
335
337
  }, z.core.$strip>;
336
338
  export type EmailRelayRequest = z.infer<typeof emailRelayRequest>;
339
+ /**
340
+ * A whole tenant, exported (#36) — GDPR Art. 20 portability, and the escrow handover.
341
+ *
342
+ * Deliberately a DIFFERENT shape from `directoryDump` (#40), because they answer
343
+ * different questions and one format cannot serve both honestly:
344
+ *
345
+ * - A **directory dump** is for RECOVERY. It is raw tables for one deployment's whole
346
+ * directory, complete and byte-faithful so it can be replayed back into a control
347
+ * plane. It is unreadable to a customer and useless as an answer to "give me my data".
348
+ * - A **tenant export** is for PORTABILITY. It is one tenant's slice, in the platform's
349
+ * own documented vocabulary (`tenant`, `scope`, `org`, `role`, …) rather than in
350
+ * SQLite's, so the receiving party can read it without knowing the schema — plus each
351
+ * scope's data as a `scopeDump`, which is the one part that IS raw, because that is
352
+ * what makes it reloadable.
353
+ *
354
+ * It is assembled from the SANCTIONED reads (`listScopes`, `listOrgs`, `listRoles`,
355
+ * `listEntitlements`, `listIdentityLinks`, `exportScope`, …), never from a back door
356
+ * into the directory database — control-plane.md §7 forbids the control plane acquiring
357
+ * one, and an export that quietly opened it would be exactly that.
358
+ *
359
+ * `masked` says which fidelity this file is. Masked is the default (the same posture as
360
+ * `scope pull`), so a full-fidelity export is a deliberate, audited act — and an Art. 20
361
+ * fulfilment is deliberate by definition.
362
+ */
363
+ export declare const tenantExport: z.ZodObject<{
364
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
365
+ capturedAt: z.ZodString;
366
+ masked: z.ZodBoolean;
367
+ tenant: z.ZodObject<{
368
+ id: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
369
+ slug: z.ZodString;
370
+ name: z.ZodString;
371
+ status: z.ZodEnum<{
372
+ active: "active";
373
+ deleting: "deleting";
374
+ reaped: "reaped";
375
+ suspended: "suspended";
376
+ }>;
377
+ createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
378
+ deletingAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
379
+ provisionedByTenant: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "TenantId", "out">>;
380
+ }, z.core.$strip>;
381
+ scopes: z.ZodArray<z.ZodObject<{
382
+ id: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
383
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
384
+ parentScopeId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
385
+ slug: z.ZodString;
386
+ kind: z.ZodString;
387
+ name: z.ZodString;
388
+ status: z.ZodEnum<{
389
+ active: "active";
390
+ archived: "archived";
391
+ archiving: "archiving";
392
+ provisioning: "provisioning";
393
+ reaped: "reaped";
394
+ suspended: "suspended";
395
+ }>;
396
+ storageShape: z.ZodEnum<{
397
+ A: "A";
398
+ B: "B";
399
+ }>;
400
+ jurisdiction: z.ZodEnum<{
401
+ eu: "eu";
402
+ global: "global";
403
+ us: "us";
404
+ }>;
405
+ vertical: z.ZodNullable<z.ZodString>;
406
+ verticalVersionId: z.ZodNullable<z.ZodString>;
407
+ schemaVersion: z.ZodString;
408
+ migrationFailure: z.ZodNullable<z.ZodObject<{
409
+ version: z.ZodString;
410
+ error: z.ZodString;
411
+ attempts: z.ZodNumber;
412
+ lastAttemptAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
413
+ }, z.core.$strip>>;
414
+ forkedFrom: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
415
+ forkedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
416
+ expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
417
+ servingRef: z.ZodOptional<z.ZodNullable<z.ZodString>>;
418
+ archivedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
419
+ createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
420
+ }, z.core.$strip>>;
421
+ orgs: z.ZodArray<z.ZodObject<{
422
+ id: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
423
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
424
+ slug: z.ZodString;
425
+ name: z.ZodString;
426
+ createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
427
+ }, z.core.$strip>>;
428
+ members: z.ZodArray<z.ZodObject<{
429
+ principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
430
+ orgId: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
431
+ revokedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
432
+ }, z.core.$strip>>;
433
+ roles: z.ZodArray<z.ZodObject<{
434
+ key: z.ZodString;
435
+ permissions: z.ZodArray<z.core.$ZodBranded<z.ZodString, "PermissionKey", "out">>;
436
+ source: z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "ModuleId", "out">, z.ZodLiteral<"vertical">]>;
437
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
438
+ }, z.core.$strip>>;
439
+ entitlements: z.ZodArray<z.ZodObject<{
440
+ entitlementKey: z.ZodString;
441
+ expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
442
+ quota: z.ZodNullable<z.ZodNumber>;
443
+ plan: z.ZodNullable<z.ZodString>;
444
+ grantedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
445
+ grantedBy: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">>;
446
+ }, z.core.$strip>>;
447
+ identityLinks: z.ZodArray<z.ZodObject<{
448
+ provider: z.ZodString;
449
+ externalId: z.ZodString;
450
+ principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
451
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
452
+ scopeId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
453
+ }, z.core.$strip>>;
454
+ hostnames: z.ZodArray<z.ZodObject<{
455
+ hostname: z.ZodString;
456
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
457
+ scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
458
+ verticalSlug: z.ZodNullable<z.ZodString>;
459
+ surface: z.ZodString;
460
+ region: z.ZodNullable<z.ZodEnum<{
461
+ eu: "eu";
462
+ }>>;
463
+ status: z.ZodEnum<{
464
+ active: "active";
465
+ failed: "failed";
466
+ pending: "pending";
467
+ verifying: "verifying";
468
+ }>;
469
+ statusNote: z.ZodNullable<z.ZodString>;
470
+ canonical: z.ZodBoolean;
471
+ createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
472
+ customHostnameId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
473
+ validationRecords: z.ZodDefault<z.ZodArray<z.ZodObject<{
474
+ type: z.ZodEnum<{
475
+ hostname: "hostname";
476
+ txt: "txt";
477
+ }>;
478
+ name: z.ZodString;
479
+ value: z.ZodString;
480
+ status: z.ZodDefault<z.ZodNullable<z.ZodString>>;
481
+ }, z.core.$strip>>>;
482
+ }, z.core.$strip>>;
483
+ stores: z.ZodArray<z.ZodObject<{
484
+ kind: z.ZodEnum<{
485
+ blob: "blob";
486
+ relational: "relational";
487
+ }>;
488
+ vertical: z.ZodString;
489
+ binding: z.ZodString;
490
+ ref: z.ZodString;
491
+ createdAt: z.ZodString;
492
+ }, z.core.$strip>>;
493
+ connections: z.ZodArray<z.ZodObject<{
494
+ id: z.core.$ZodBranded<z.ZodString, "ConnectionId", "out">;
495
+ tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
496
+ vertical: z.ZodString;
497
+ provider: z.ZodString;
498
+ label: z.ZodString;
499
+ status: z.ZodEnum<{
500
+ active: "active";
501
+ error: "error";
502
+ expired: "expired";
503
+ revoked: "revoked";
504
+ }>;
505
+ externalAccountRef: z.ZodNullable<z.ZodString>;
506
+ scopes: z.ZodArray<z.ZodString>;
507
+ expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
508
+ lastOkAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
509
+ lastError: z.ZodNullable<z.ZodString>;
510
+ lastErrorAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
511
+ createdBy: z.ZodString;
512
+ createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
513
+ revokedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
514
+ }, z.core.$strip>>;
515
+ adminLog: z.ZodNullable<z.ZodArray<z.ZodObject<{
516
+ id: z.ZodString;
517
+ actor: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
518
+ action: z.ZodEnum<{
519
+ activateScope: "activateScope";
520
+ addMember: "addMember";
521
+ admitVersion: "admitVersion";
522
+ archiveScope: "archiveScope";
523
+ assignRole: "assignRole";
524
+ bindHostname: "bindHostname";
525
+ bindScopeVersion: "bindScopeVersion";
526
+ createConnection: "createConnection";
527
+ createOrg: "createOrg";
528
+ createTenant: "createTenant";
529
+ defineRole: "defineRole";
530
+ deleteSnapshot: "deleteSnapshot";
531
+ deleteVertical: "deleteVertical";
532
+ grant: "grant";
533
+ grantEntitlement: "grantEntitlement";
534
+ grantToConnection: "grantToConnection";
535
+ grantToOrg: "grantToOrg";
536
+ grantToSystem: "grantToSystem";
537
+ importScope: "importScope";
538
+ linkIdentity: "linkIdentity";
539
+ promoteVersion: "promoteVersion";
540
+ provisionBlobStore: "provisionBlobStore";
541
+ provisionScope: "provisionScope";
542
+ provisionTenantStore: "provisionTenantStore";
543
+ pruneAccessLog: "pruneAccessLog";
544
+ publishVersion: "publishVersion";
545
+ reapScope: "reapScope";
546
+ reapTenant: "reapTenant";
547
+ registerIdentityPool: "registerIdentityPool";
548
+ registerVertical: "registerVertical";
549
+ rejectVersion: "rejectVersion";
550
+ removeMember: "removeMember";
551
+ requestPublish: "requestPublish";
552
+ restoreDirectory: "restoreDirectory";
553
+ restoreScope: "restoreScope";
554
+ revokeConnection: "revokeConnection";
555
+ revokeEntitlement: "revokeEntitlement";
556
+ rewindScope: "rewindScope";
557
+ setHostnameIssuance: "setHostnameIssuance";
558
+ setHostnameStatus: "setHostnameStatus";
559
+ setScopeExpiresAt: "setScopeExpiresAt";
560
+ setScopeServingRef: "setScopeServingRef";
561
+ setTenantName: "setTenantName";
562
+ setTenantStatus: "setTenantStatus";
563
+ setVerticalEmailSender: "setVerticalEmailSender";
564
+ setVerticalInstallsBlocked: "setVerticalInstallsBlocked";
565
+ setVerticalListed: "setVerticalListed";
566
+ setVerticalServing: "setVerticalServing";
567
+ setVerticalTenantProvisioner: "setVerticalTenantProvisioner";
568
+ suspendScope: "suspendScope";
569
+ unarchiveScope: "unarchiveScope";
570
+ unassignRole: "unassignRole";
571
+ unbindHostname: "unbindHostname";
572
+ unlinkIdentity: "unlinkIdentity";
573
+ unsuspendScope: "unsuspendScope";
574
+ updateConnectionSecret: "updateConnectionSecret";
575
+ }>;
576
+ tenantId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "TenantId", "out">>;
577
+ scopeId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
578
+ vertical: z.ZodNullable<z.ZodString>;
579
+ before: z.ZodNullable<z.ZodUnknown>;
580
+ after: z.ZodNullable<z.ZodUnknown>;
581
+ causedBy: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "EventId", "out">>;
582
+ at: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
583
+ }, z.core.$strip>>>;
584
+ data: z.ZodArray<z.ZodObject<{
585
+ tenantId: z.ZodString;
586
+ scopeId: z.ZodString;
587
+ capturedAt: z.ZodString;
588
+ tables: z.ZodArray<z.ZodObject<{
589
+ name: z.ZodString;
590
+ ddl: z.ZodString;
591
+ columns: z.ZodArray<z.ZodString>;
592
+ rows: z.ZodArray<z.ZodArray<z.ZodUnknown>>;
593
+ }, z.core.$strip>>;
594
+ }, z.core.$strip>>;
595
+ }, z.core.$strip>;
596
+ export type TenantExport = z.infer<typeof tenantExport>;
337
597
  //# sourceMappingURL=control-plane.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0EtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB;;;;;;;iBAa3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe;;;;;iBAS1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;;;;iBAIhC,CAAC;AAGH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;;iBAMvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;;iBAAwC,CAAC;AAC3E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY;;;EAAsC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;;;iBAQrB,CAAC;AACL,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;iBAUzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;iBAIxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4BxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;iBAS5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  import { eventId, instant, orgId, platformActorId, principalId, scopeId, tenantId, } from './ids.js';
3
+ // #36's tenant export speaks the platform's own vocabulary rather than restating it, so
4
+ // it composes the schemas that already define these shapes. One-way imports only —
5
+ // none of these modules imports this one, so no cycle.
6
+ import { org, scope, tenant } from './tenancy.js';
7
+ import { tenantRole } from './permission.js';
8
+ import { hostnameBinding } from './routing.js';
9
+ import { connection } from './connections.js';
10
+ import { scopeDump } from './introspection.js';
3
11
  // The control plane — the shared layer across N per-vertical deployments (D-30,
4
12
  // control-plane.md). This file carries the audit contract that every effecting
5
13
  // mutation writes; the tenant registry, lifecycle, and entitlement store land in
@@ -80,6 +88,12 @@ export const adminAction = z.enum([
80
88
  // #383 — a module's system principal may hold a permission (for scheduled work),
81
89
  // so granting one is a named, audited mutation like every other grant.
82
90
  'grantToSystem',
91
+ // #40 — the directory's own disaster-recovery write: replace THE DIRECTORY (tenants,
92
+ // scopes, hostnames, verticals, identities) with a stored dump. Carries no tenant,
93
+ // because its blast radius is every tenant. The entry lands in the log it just
94
+ // replaced, which is exactly right: the restored log is the pre-restore history, and
95
+ // this row is the first thing after it — the seam is legible instead of silent.
96
+ 'restoreDirectory',
83
97
  ]);
84
98
  /**
85
99
  * One entitlement grant, widened from a bare SKU flag to express a plan (#33):
@@ -311,4 +325,72 @@ export const emailRelayRequest = z.object({
311
325
  /** Optional display name for the FROM (e.g. "Substrat Auth"); the address stays platform-owned. */
312
326
  fromName: z.string().min(1).optional(),
313
327
  });
328
+ /**
329
+ * A whole tenant, exported (#36) — GDPR Art. 20 portability, and the escrow handover.
330
+ *
331
+ * Deliberately a DIFFERENT shape from `directoryDump` (#40), because they answer
332
+ * different questions and one format cannot serve both honestly:
333
+ *
334
+ * - A **directory dump** is for RECOVERY. It is raw tables for one deployment's whole
335
+ * directory, complete and byte-faithful so it can be replayed back into a control
336
+ * plane. It is unreadable to a customer and useless as an answer to "give me my data".
337
+ * - A **tenant export** is for PORTABILITY. It is one tenant's slice, in the platform's
338
+ * own documented vocabulary (`tenant`, `scope`, `org`, `role`, …) rather than in
339
+ * SQLite's, so the receiving party can read it without knowing the schema — plus each
340
+ * scope's data as a `scopeDump`, which is the one part that IS raw, because that is
341
+ * what makes it reloadable.
342
+ *
343
+ * It is assembled from the SANCTIONED reads (`listScopes`, `listOrgs`, `listRoles`,
344
+ * `listEntitlements`, `listIdentityLinks`, `exportScope`, …), never from a back door
345
+ * into the directory database — control-plane.md §7 forbids the control plane acquiring
346
+ * one, and an export that quietly opened it would be exactly that.
347
+ *
348
+ * `masked` says which fidelity this file is. Masked is the default (the same posture as
349
+ * `scope pull`), so a full-fidelity export is a deliberate, audited act — and an Art. 20
350
+ * fulfilment is deliberate by definition.
351
+ */
352
+ export const tenantExport = z.object({
353
+ tenantId,
354
+ /** ISO 8601 — when the export was assembled. */
355
+ capturedAt: z.string().min(1),
356
+ /** False only for a `?full=true` break-glass export; true means PII was redacted. */
357
+ masked: z.boolean(),
358
+ /** The tenant record itself. */
359
+ tenant,
360
+ /** Every scope, including archived and reaped ones — the tombstones are part of the history. */
361
+ scopes: z.array(scope),
362
+ orgs: z.array(org),
363
+ /** Org membership across every org, revoked rows included (K-21 tombstones are the record). */
364
+ members: z.array(orgMembership),
365
+ roles: z.array(tenantRole),
366
+ entitlements: z.array(entitlementGrant),
367
+ /** External login links (D-16) — which identity provider subject maps to which principal. */
368
+ identityLinks: z.array(identityLink),
369
+ hostnames: z.array(hostnameBinding),
370
+ /**
371
+ * Inventory, NOT contents: the per-tenant relational and blob stores this tenant has.
372
+ * Their bytes are not in this file, and saying so explicitly is the point — an export
373
+ * that silently omitted them would misrepresent itself as complete.
374
+ */
375
+ stores: z.array(z.object({
376
+ kind: z.enum(['relational', 'blob']),
377
+ vertical: z.string(),
378
+ binding: z.string(),
379
+ ref: z.string(),
380
+ createdAt: z.string(),
381
+ })),
382
+ /** Third-party connections as metadata only — a sealed credential is never exported. */
383
+ connections: z.array(connection),
384
+ /**
385
+ * The tenant's admin-log entries — present only in a FULL export.
386
+ *
387
+ * Excluded from the masked default on purpose: this is the platform's record of what
388
+ * STAFF did, not data the customer provided, so it is not Art. 20 material, and it
389
+ * carries staff actor ids and internal action vocabulary. It is exactly what an escrow
390
+ * or a dispute needs, so break-glass keeps it reachable — and audited.
391
+ */
392
+ adminLog: z.array(adminLogEntry).nullable(),
393
+ /** Each scope's database, as the same `scopeDump` a fork or a pull produces. */
394
+ data: z.array(scopeDump),
395
+ });
314
396
  //# sourceMappingURL=control-plane.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,OAAO,EACP,OAAO,EACP,KAAK,EACL,eAAe,EACf,WAAW,EACX,OAAO,EACP,QAAQ,GACT,MAAM,UAAU,CAAC;AAElB,gFAAgF;AAChF,+EAA+E;AAC/E,iFAAiF;AACjF,4CAA4C;AAE5C,2EAA2E;AAC3E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC;IAChC,YAAY;IACZ,YAAY;IACZ,cAAc,EAAE,+DAA+D;IAC/E,OAAO;IACP,YAAY;IACZ,WAAW;IACX,cAAc,EAAE,2DAA2D;IAC3E,WAAW,EAAE,wDAAwD;IACrE,sBAAsB;IACtB,kBAAkB,EAAE,wCAAwC;IAC5D,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,mBAAmB,EAAE,0EAA0E;IAC/F,gBAAgB,EAAE,iFAAiF;IACnG,4BAA4B,EAAE,mEAAmE;IACjG,8BAA8B,EAAE,4EAA4E;IAC5G,wBAAwB,EAAE,mFAAmF;IAC7G,gBAAgB,EAAE,8EAA8E;IAChG,kBAAkB;IAClB,gBAAgB;IAChB,kFAAkF;IAClF,sFAAsF;IACtF,oBAAoB;IACpB,oBAAoB;IACpB,mBAAmB,EAAE,6FAA6F;IAClH,cAAc,EAAE,0BAA0B;IAC1C,mBAAmB,EAAE,oDAAoD;IACzE,qBAAqB,EAAE,uEAAuE;IAC9F,gBAAgB,EAAE,uEAAuE;IACzF,gBAAgB,EAAE,yHAAyH;IAC3I,cAAc,EAAE,OAAO;IACvB,oFAAoF;IACpF,uFAAuF;IACvF,oFAAoF;IACpF,iBAAiB;IACjB,eAAe,EAAE,qEAAqE;IACtF,wFAAwF;IACxF,qFAAqF;IACrF,0FAA0F;IAC1F,yBAAyB;IACzB,YAAY;IACZ,gBAAgB,EAAE,yDAAyD;IAC3E,sBAAsB,EAAE,kEAAkE;IAC1F,oBAAoB,EAAE,2DAA2D;IACjF,aAAa,EAAE,uEAAuE;IACtF,cAAc,EAAE,2FAA2F;IAC3G,aAAa,EAAE,qFAAqF;IACpG,gBAAgB,EAAE,8EAA8E;IAChG,cAAc,EAAE,OAAO;IACvB,gBAAgB,EAAE,OAAO;IACzB,cAAc,EAAE,OAAO;IACvB,gBAAgB;IAChB,wFAAwF;IACxF,sFAAsF;IACtF,8FAA8F;IAC9F,WAAW;IACX,eAAe,EAAE,uDAAuD;IACxE,kBAAkB,EAAE,6CAA6C;IACjE,mBAAmB,EAAE,OAAO;IAC5B,cAAc,EAAE,kDAAkD;IAClE,gBAAgB,EAAE,wDAAwD;IAC1E,+EAA+E;IAC/E,4EAA4E;IAC5E,kBAAkB;IAClB,wBAAwB,EAAE,2DAA2D;IACrF,kBAAkB;IAClB,8EAA8E;IAC9E,8BAA8B;IAC9B,mBAAmB;IACnB,iFAAiF;IACjF,uEAAuE;IACvE,eAAe;CAChB,CAAC,CAAC;AAGH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,+EAA+E;IAC/E,yEAAyE;IACzE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,iFAAiF;IACjF,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC7B,qFAAqF;IACrF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,gFAAgF;IAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC7B,SAAS,EAAE,eAAe,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,+BAA+B;IAC/B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,2FAA2F;IAC3F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,mGAAmG;IACnG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,qGAAqG;IACrG,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAGH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC;AAKH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,sCAAsC;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,sDAAsD;IACrF,SAAS,EAAE,WAAW;IACtB,QAAQ;IACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,8BAA8B;CAC5D,CAAC,CAAC;AAGH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAG3E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;AAGhE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,EAAE;IACxE,OAAO,EAAE,8DAA8D;CACxE,CAAC,CAAC;AAGL;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAGH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC3C,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC7B,EAAE,EAAE,OAAO;CACZ,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,WAAW;IACtB,KAAK;IACL,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,oDAAoD;IAC3E,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,WAAW;IACnB,oFAAoF;IACpF,mFAAmF;IACnF,mDAAmD;IACnD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,6DAA6D;IAC7F,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,sBAAsB;IACrD;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC5B,EAAE,EAAE,OAAO;CACZ,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ;IACR,OAAO;IACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,mGAAmG;IACnG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC"}
1
+ {"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"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"}
package/dist/deploy.d.ts CHANGED
@@ -102,6 +102,65 @@ export type BlobStoreHandle = z.infer<typeof blobStoreHandle>;
102
102
  * `D1Database`. On the pure adapter there is no binding to name.
103
103
  */
104
104
  export declare function blobStoreBindingName(binding: string, tenantId: string): string;
105
+ /**
106
+ * How the runtime routes a request between the vertical's STATIC files and its worker
107
+ * (#340) — the substrate-vocabulary form of Cloudflare's `assets.config`. Every field is
108
+ * optional with a runtime default, so a vertical that only wants "serve my SPA" declares
109
+ * a directory and nothing else.
110
+ *
111
+ * The two that matter for a Substrat vertical, and why:
112
+ * - `notFoundHandling: 'single-page-application'` — a deep client route (`/jobs/123`) is
113
+ * not a file, and must resolve to `index.html` rather than 404. This is the inline
114
+ * `serveAsset` fallback, expressed as configuration.
115
+ * - `runWorkerFirst` — SPA fallback would otherwise swallow the vertical's OWN routes,
116
+ * which are not files either. Listing `/api/*` + `/internal/*` keeps the worker in
117
+ * front of exactly the paths it owns while everything else is served from the edge
118
+ * without invoking it. `true` runs the worker in front of every request (asset serving
119
+ * still happens behind it) — correct only for a vertical that inspects every path.
120
+ */
121
+ export declare const assetRouting: z.ZodObject<{
122
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
123
+ "auto-trailing-slash": "auto-trailing-slash";
124
+ "drop-trailing-slash": "drop-trailing-slash";
125
+ "force-trailing-slash": "force-trailing-slash";
126
+ none: "none";
127
+ }>>;
128
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
129
+ "404-page": "404-page";
130
+ none: "none";
131
+ "single-page-application": "single-page-application";
132
+ }>>;
133
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
134
+ }, z.core.$strip>;
135
+ export type AssetRouting = z.infer<typeof assetRouting>;
136
+ /**
137
+ * The vertical's STATIC files, as a NEED (#340): a directory of built bytes the platform
138
+ * uploads to the runtime's own asset store, served from the edge without invoking the
139
+ * worker. Native assets are not a binding — they are a top-level upload path — so this is
140
+ * a `runtimeNeeds` need and never rides the §4 binding allowlist (see
141
+ * {@link ADMISSIBLE_BINDING_TYPES}); the platform's own hash verification is what makes
142
+ * accepting builder-supplied bytes safe (self-serve-deploy.md §4.1).
143
+ *
144
+ * Replaces the inline-into-the-worker workaround every demo carried while WfP dispatch had
145
+ * no asset path: base64 in the bundle costs ~+33 % against the script-size limit, is
146
+ * re-parsed on every cold start, and invokes the worker for every image.
147
+ */
148
+ export declare const assetsNeed: z.ZodObject<{
149
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
150
+ "auto-trailing-slash": "auto-trailing-slash";
151
+ "drop-trailing-slash": "drop-trailing-slash";
152
+ "force-trailing-slash": "force-trailing-slash";
153
+ none: "none";
154
+ }>>;
155
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
156
+ "404-page": "404-page";
157
+ none: "none";
158
+ "single-page-application": "single-page-application";
159
+ }>>;
160
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
161
+ directory: z.ZodString;
162
+ }, z.core.$strip>;
163
+ export type AssetsNeed = z.infer<typeof assetsNeed>;
105
164
  /**
106
165
  * What a vertical needs from the runtime, in substrate vocabulary (package.json
107
166
  * `substrat.runtimeNeeds`). A vertical authored with this section never writes deploy
@@ -127,6 +186,21 @@ export declare const runtimeNeeds: z.ZodObject<{
127
186
  binding: z.ZodString;
128
187
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
129
188
  }, z.core.$strip>>>;
189
+ assets: z.ZodOptional<z.ZodObject<{
190
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
191
+ "auto-trailing-slash": "auto-trailing-slash";
192
+ "drop-trailing-slash": "drop-trailing-slash";
193
+ "force-trailing-slash": "force-trailing-slash";
194
+ none: "none";
195
+ }>>;
196
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
197
+ "404-page": "404-page";
198
+ none: "none";
199
+ "single-page-application": "single-page-application";
200
+ }>>;
201
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
202
+ directory: z.ZodString;
203
+ }, z.core.$strip>>;
130
204
  }, z.core.$strip>;
131
205
  export type RuntimeNeeds = z.infer<typeof runtimeNeeds>;
132
206
  /**
@@ -145,6 +219,14 @@ export type RuntimeNeeds = z.infer<typeof runtimeNeeds>;
145
219
  * `mtls_certificate`) — the outside world is a connector concern, and outbound policy is an
146
220
  * open question (§6 / #303); least-privilege means these are refused until decided.
147
221
  *
222
+ * NOT on this list because it is not a binding at all: **native static assets** (#340). They
223
+ * are a top-level upload path (`assets: { jwt, config }` in the script metadata), so they can
224
+ * neither be allowed nor refused here. They are admitted by a separate, narrower rule written
225
+ * down in self-serve-deploy.md §4.1: the bytes are inert and public — no code, no authority,
226
+ * no cross-tenant reach — but their content-address is a namespace-wide dedup key, so the
227
+ * platform RE-DERIVES every hash from the uploaded bytes ({@link assetHash}) and refuses a
228
+ * mismatch. What is trusted is the bytes; what is verified is the key.
229
+ *
148
230
  * Caveat on `d1`: admissible as an own relational store (e.g. a Better-Auth `AUTH_DB`), but
149
231
  * the check does not yet PROVE the declared `database_id` is the vertical's own rather than
150
232
  * another tenant's — trusted under model-B human admission; platform provisioning closes that
@@ -253,6 +335,81 @@ export declare function definePermissions(input: PermissionsInput): PermissionsI
253
335
  * of declaration order.
254
336
  */
255
337
  export declare function buildPermissionRegistry(input: PermissionsInput): PermissionRegistry;
338
+ /**
339
+ * One static file in the shipped manifest (#340). The trio Cloudflare's asset store keys
340
+ * on — content-addressed `hash`, `size` — plus the `contentType` the platform attaches at
341
+ * upload and the runtime serves back.
342
+ *
343
+ * `hash` is the platform's DEDUP KEY, and the reason it is re-derived at the trust boundary
344
+ * rather than trusted: the asset store dedups by hash across the whole dispatch namespace,
345
+ * so bytes accepted under a hash they do not have would let one push decide what a DIFFERENT
346
+ * vertical's identical-hash asset serves. The bytes themselves are inert and public; the
347
+ * *key* is not. The control plane recomputes every hash from the uploaded bytes and refuses
348
+ * a mismatch (self-serve-deploy.md §4.1).
349
+ *
350
+ * The recipe is Cloudflare's, and must stay byte-identical on both ends or nothing dedups:
351
+ * `sha256(base64(content) + extension)`, first 32 hex chars ({@link assetHash}).
352
+ */
353
+ export declare const assetEntry: z.ZodObject<{
354
+ path: z.ZodString;
355
+ hash: z.ZodString;
356
+ size: z.ZodNumber;
357
+ contentType: z.ZodString;
358
+ }, z.core.$strip>;
359
+ export type AssetEntry = z.infer<typeof assetEntry>;
360
+ /**
361
+ * The multipart part-name prefix static files ride under in a push (#340) —
362
+ * `asset:/index.html`. Here, with the manifest schema, for the reason this file exists:
363
+ * both ends must speak the same shape. The prefix is what separates the two kinds of part
364
+ * in one body — anything unprefixed is a worker module — so an asset called `worker.js`
365
+ * can never be uploaded as code, and a served path is never constrained to be a legal
366
+ * module name.
367
+ */
368
+ export declare const ASSET_PART_PREFIX = "asset:";
369
+ /**
370
+ * The content-address of one static file — **Cloudflare's recipe, not ours**:
371
+ * `sha256(base64(content) + extension)` (extension without the dot), first 32 hex chars.
372
+ * It is reproduced here rather than imported because both ends must compute it identically:
373
+ * the CLI to build the manifest it ships, the control plane to VERIFY that manifest against
374
+ * the bytes before either reaches the asset store (see {@link assetEntry}). A divergence
375
+ * would not merely fail — it would silently defeat dedup, or store bytes under a key that
376
+ * is not theirs.
377
+ *
378
+ * Web Crypto (`globalThis.crypto.subtle`), so the one implementation runs unchanged in node,
379
+ * workerd, and the browser.
380
+ */
381
+ export declare function assetHash(content: Uint8Array, path: string): Promise<string>;
382
+ /**
383
+ * The static-file half of a push (#340): the routing config, plus the full file manifest.
384
+ *
385
+ * The manifest is retained (it rides `manifest_json` like the rest of the deploy manifest)
386
+ * for a load-bearing reason: a promote re-uploads a version onto the STABLE serving script
387
+ * from its archive (#286), and an asset upload session is driven by the manifest, not by
388
+ * bytes — content already in the namespace's asset store is skipped, so the retained
389
+ * manifest is what lets a promote re-attach the same assets without the builder re-pushing.
390
+ * It is also what the dashboard renders as the per-version asset list.
391
+ */
392
+ export declare const deployAssets: z.ZodObject<{
393
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
394
+ "auto-trailing-slash": "auto-trailing-slash";
395
+ "drop-trailing-slash": "drop-trailing-slash";
396
+ "force-trailing-slash": "force-trailing-slash";
397
+ none: "none";
398
+ }>>;
399
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
400
+ "404-page": "404-page";
401
+ none: "none";
402
+ "single-page-application": "single-page-application";
403
+ }>>;
404
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
405
+ files: z.ZodArray<z.ZodObject<{
406
+ path: z.ZodString;
407
+ hash: z.ZodString;
408
+ size: z.ZodNumber;
409
+ contentType: z.ZodString;
410
+ }, z.core.$strip>>;
411
+ }, z.core.$strip>;
412
+ export type DeployAssets = z.infer<typeof deployAssets>;
256
413
  /** The JSON part a `substrat push` sends alongside the module files. */
257
414
  export declare const deployManifest: z.ZodObject<{
258
415
  version: z.ZodString;
@@ -276,6 +433,26 @@ export declare const deployManifest: z.ZodObject<{
276
433
  binding: z.ZodString;
277
434
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
278
435
  }, z.core.$strip>>>;
436
+ assets: z.ZodOptional<z.ZodObject<{
437
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
438
+ "auto-trailing-slash": "auto-trailing-slash";
439
+ "drop-trailing-slash": "drop-trailing-slash";
440
+ "force-trailing-slash": "force-trailing-slash";
441
+ none: "none";
442
+ }>>;
443
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
444
+ "404-page": "404-page";
445
+ none: "none";
446
+ "single-page-application": "single-page-application";
447
+ }>>;
448
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
449
+ files: z.ZodArray<z.ZodObject<{
450
+ path: z.ZodString;
451
+ hash: z.ZodString;
452
+ size: z.ZodNumber;
453
+ contentType: z.ZodString;
454
+ }, z.core.$strip>>;
455
+ }, z.core.$strip>>;
279
456
  envSpec: z.ZodOptional<z.ZodArray<z.ZodObject<{
280
457
  key: z.ZodString;
281
458
  label: z.ZodOptional<z.ZodString>;
@@ -348,6 +525,26 @@ export declare const storedDeployManifest: z.ZodObject<{
348
525
  binding: z.ZodString;
349
526
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
350
527
  }, z.core.$strip>>>;
528
+ assets: z.ZodOptional<z.ZodObject<{
529
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
530
+ "auto-trailing-slash": "auto-trailing-slash";
531
+ "drop-trailing-slash": "drop-trailing-slash";
532
+ "force-trailing-slash": "force-trailing-slash";
533
+ none: "none";
534
+ }>>;
535
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
536
+ "404-page": "404-page";
537
+ none: "none";
538
+ "single-page-application": "single-page-application";
539
+ }>>;
540
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
541
+ files: z.ZodArray<z.ZodObject<{
542
+ path: z.ZodString;
543
+ hash: z.ZodString;
544
+ size: z.ZodNumber;
545
+ contentType: z.ZodString;
546
+ }, z.core.$strip>>;
547
+ }, z.core.$strip>>;
351
548
  envSpec: z.ZodOptional<z.ZodArray<z.ZodObject<{
352
549
  key: z.ZodString;
353
550
  label: z.ZodOptional<z.ZodString>;