@spacefast/common 0.0.11 → 0.0.12

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 (122) hide show
  1. package/dist/agents/connect-targets.d.ts +4 -4
  2. package/dist/agents/connect-targets.js +3 -3
  3. package/dist/agents/private-key-oauth.d.ts +37 -0
  4. package/dist/agents/private-key-oauth.js +158 -0
  5. package/dist/config/domains.js +1 -1
  6. package/dist/config/index.d.ts +1 -0
  7. package/dist/config/index.js +1 -0
  8. package/dist/config/postgres-budget.d.ts +126 -0
  9. package/dist/config/postgres-budget.js +135 -0
  10. package/dist/config/postgres-budget.json +50 -0
  11. package/dist/contracts/access.d.ts +42 -24
  12. package/dist/contracts/access.js +73 -34
  13. package/dist/contracts/activity.d.ts +1 -1
  14. package/dist/contracts/activity.js +5 -5
  15. package/dist/contracts/api-keys.d.ts +53 -45
  16. package/dist/contracts/api-keys.js +1 -0
  17. package/dist/contracts/archives.d.ts +8 -8
  18. package/dist/contracts/builds.d.ts +8 -8
  19. package/dist/contracts/builds.js +28 -48
  20. package/dist/contracts/channels.js +1 -2
  21. package/dist/contracts/comments.d.ts +55 -19
  22. package/dist/contracts/comments.js +56 -17
  23. package/dist/contracts/common.d.ts +4 -3
  24. package/dist/contracts/common.js +2 -0
  25. package/dist/contracts/deployments.d.ts +3 -3
  26. package/dist/contracts/device-auth.d.ts +14 -12
  27. package/dist/contracts/docs.d.ts +5 -5
  28. package/dist/contracts/domains.d.ts +261 -1330
  29. package/dist/contracts/domains.js +39 -301
  30. package/dist/contracts/email-preferences.d.ts +50 -0
  31. package/dist/contracts/email-preferences.js +44 -0
  32. package/dist/contracts/enums.d.ts +1 -1
  33. package/dist/contracts/error-code-meta.d.ts +84 -15
  34. package/dist/contracts/error-code-meta.js +28 -4
  35. package/dist/contracts/error-codes.d.ts +1 -1
  36. package/dist/contracts/error-codes.js +24 -6
  37. package/dist/contracts/events.d.ts +13 -13
  38. package/dist/contracts/feature-lifecycle.d.ts +644 -2
  39. package/dist/contracts/feature-lifecycle.js +685 -2
  40. package/dist/contracts/features.d.ts +236 -24
  41. package/dist/contracts/features.js +3 -272
  42. package/dist/contracts/ids.d.ts +1 -2
  43. package/dist/contracts/ids.js +1 -2
  44. package/dist/contracts/internal.d.ts +3 -3
  45. package/dist/contracts/mcp.d.ts +6 -6
  46. package/dist/contracts/me.js +1 -1
  47. package/dist/contracts/mounts.d.ts +142 -0
  48. package/dist/contracts/mounts.js +56 -0
  49. package/dist/contracts/oauth-resources.d.ts +5 -5
  50. package/dist/contracts/oauth-resources.js +1 -0
  51. package/dist/contracts/operations.d.ts +2 -2
  52. package/dist/contracts/pages.d.ts +2 -2
  53. package/dist/contracts/pages.js +8 -3
  54. package/dist/contracts/plan-policy.d.ts +1 -1
  55. package/dist/contracts/platform.d.ts +3 -3
  56. package/dist/contracts/resources.d.ts +12 -20
  57. package/dist/contracts/resources.js +13 -37
  58. package/dist/contracts/runtime-api.d.ts +330 -16
  59. package/dist/contracts/runtime-api.js +58 -14
  60. package/dist/contracts/sf-config-v1.js +1 -1
  61. package/dist/contracts/sites.d.ts +12 -12
  62. package/dist/contracts/sites.js +18 -11
  63. package/dist/contracts/space-config.d.ts +2 -3
  64. package/dist/contracts/space-config.js +3 -1
  65. package/dist/contracts/spaces.d.ts +143 -102
  66. package/dist/contracts/spaces.js +109 -43
  67. package/dist/contracts/superadmin-emails.d.ts +25 -1
  68. package/dist/contracts/superadmin-emails.js +10 -15
  69. package/dist/contracts/superadmin-runtime.d.ts +2 -2
  70. package/dist/contracts/superadmin-spaces.d.ts +6 -14
  71. package/dist/contracts/tags.d.ts +43 -13
  72. package/dist/contracts/tags.js +195 -11
  73. package/dist/contracts/transfers.d.ts +1 -1
  74. package/dist/contracts/variables.d.ts +4 -4
  75. package/dist/contracts/variables.js +4 -3
  76. package/dist/contracts/webhooks.d.ts +2 -2
  77. package/dist/contracts/zero.d.ts +329 -7
  78. package/dist/contracts/zero.js +121 -2
  79. package/dist/dashboard-paths/index.d.ts +1 -1
  80. package/dist/docs/agent-setup.d.ts +4 -2
  81. package/dist/docs/agent-setup.js +15 -7
  82. package/dist/docs/agent-solutions.js +1 -1
  83. package/dist/docs/catalog.d.ts +8 -10
  84. package/dist/docs/catalog.js +8 -10
  85. package/dist/docs/error-docs.js +86 -18
  86. package/dist/utils/access-grant.d.ts +14 -0
  87. package/dist/utils/access-grant.js +88 -0
  88. package/dist/utils/access-match.d.ts +7 -0
  89. package/dist/utils/access-match.fixtures.json +513 -0
  90. package/dist/utils/access-match.js +32 -16
  91. package/dist/utils/access-verdict.fixtures.json +421 -0
  92. package/dist/utils/credential-policy.d.ts +1 -1
  93. package/dist/utils/dns-instructions.d.ts +29 -0
  94. package/dist/utils/dns-instructions.js +78 -0
  95. package/dist/utils/domain-diagnostics.d.ts +29 -0
  96. package/dist/utils/domain-diagnostics.js +63 -0
  97. package/dist/utils/egress-policy.fixtures.json +51 -0
  98. package/dist/utils/id-hints.d.ts +1 -0
  99. package/dist/utils/id-hints.js +55 -13
  100. package/dist/utils/page-colors.d.ts +50 -0
  101. package/dist/utils/page-colors.js +167 -0
  102. package/dist/utils/page-fonts.d.ts +2 -0
  103. package/dist/utils/page-fonts.js +4 -0
  104. package/dist/utils/pages.d.ts +8 -1
  105. package/dist/utils/pages.js +123 -37
  106. package/dist/utils/production-runtime.d.ts +18 -0
  107. package/dist/utils/production-runtime.js +28 -0
  108. package/dist/utils/query-keys.d.ts +6 -7
  109. package/dist/utils/query-keys.js +11 -12
  110. package/dist/utils/sf-config-v1.fixtures.json +9 -0
  111. package/dist/utils/sf-config-v1.js +28 -19
  112. package/dist/utils/source-archive-policy.d.ts +2 -0
  113. package/dist/utils/source-archive-policy.js +2 -0
  114. package/dist/utils/static-runtime-policy.fixtures.json +57 -0
  115. package/dist/utils/static-runtime-policy.js +1 -1
  116. package/package.json +5 -4
  117. package/dist/contracts/annotations.d.ts +0 -327
  118. package/dist/contracts/annotations.js +0 -235
  119. package/dist/contracts/generated-feature-launch-entries.d.ts +0 -2
  120. package/dist/contracts/generated-feature-launch-entries.js +0 -518
  121. package/dist/contracts/publishes.d.ts +0 -135
  122. package/dist/contracts/publishes.js +0 -162
@@ -210,6 +210,7 @@ export declare const ruleMatchSchema: z.ZodObject<{
210
210
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
211
211
  agent: z.ZodOptional<z.ZodString>;
212
212
  country: z.ZodOptional<z.ZodString>;
213
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
213
214
  header: z.ZodOptional<z.ZodObject<{
214
215
  name: z.ZodString;
215
216
  value: z.ZodString;
@@ -235,6 +236,7 @@ export declare const runtimeRuleSchema: z.ZodObject<{
235
236
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
236
237
  agent: z.ZodOptional<z.ZodString>;
237
238
  country: z.ZodOptional<z.ZodString>;
239
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
238
240
  header: z.ZodOptional<z.ZodObject<{
239
241
  name: z.ZodString;
240
242
  value: z.ZodString;
@@ -293,6 +295,9 @@ export declare const accessTokenPayloadSchema: z.ZodObject<{
293
295
  aud: z.ZodOptional<z.ZodString>;
294
296
  sv: z.ZodOptional<z.ZodNumber>;
295
297
  jti: z.ZodOptional<z.ZodString>;
298
+ room: z.ZodOptional<z.ZodString>;
299
+ anonymous_id: z.ZodOptional<z.ZodString>;
300
+ name: z.ZodOptional<z.ZodString>;
296
301
  }, z.core.$strip>;
297
302
  export type AccessTokenPayload = z.infer<typeof accessTokenPayloadSchema>;
298
303
  export declare const authorizeRequestSchema: z.ZodObject<{
@@ -310,6 +315,9 @@ export declare const authorizeResponseSchema: z.ZodObject<{
310
315
  aud: z.ZodOptional<z.ZodString>;
311
316
  sv: z.ZodOptional<z.ZodNumber>;
312
317
  jti: z.ZodOptional<z.ZodString>;
318
+ room: z.ZodOptional<z.ZodString>;
319
+ anonymous_id: z.ZodOptional<z.ZodString>;
320
+ name: z.ZodOptional<z.ZodString>;
313
321
  }, z.core.$strip>;
314
322
  expiresAt: z.ZodNumber;
315
323
  }, z.core.$strip>;
@@ -332,7 +340,6 @@ export declare function spaceLevelGrant(spaceId: string, level: SpaceLevel): str
332
340
  export declare function shareLinkGrant(linkId: string): string;
333
341
  export declare function inviteGrant(inviteId: string): string;
334
342
  export declare function serviceTokenGrant(tokenId: string): string;
335
- export declare const SHARE_LINK_TOKEN_MAX_TTL_SECONDS: number;
336
343
  export declare const shareLinkSchema: z.ZodObject<{
337
344
  id: z.ZodString;
338
345
  spaceId: z.ZodString;
@@ -366,34 +373,42 @@ export declare const shareLinkWithUrlSchema: z.ZodObject<{
366
373
  url: z.ZodString;
367
374
  }, z.core.$strip>;
368
375
  export type ShareLinkWithUrl = z.infer<typeof shareLinkWithUrlSchema>;
369
- export declare const GENERAL_ACCESS_MODES: readonly ["public", "password", "link", "people"];
370
- export declare const generalAccessModeSchema: z.ZodEnum<{
371
- link: "link";
372
- password: "password";
376
+ export declare const SPACE_VISIBILITIES: readonly ["public", "restricted"];
377
+ export declare const spaceVisibilitySchema: z.ZodEnum<{
373
378
  public: "public";
374
- people: "people";
379
+ restricted: "restricted";
375
380
  }>;
376
- export type GeneralAccessMode = z.infer<typeof generalAccessModeSchema>;
381
+ export type SpaceVisibility = z.infer<typeof spaceVisibilitySchema>;
377
382
  export declare const sharingConnectionAudienceSchema: z.ZodObject<{
378
383
  connectionId: z.ZodString;
379
384
  tag: z.ZodOptional<z.ZodString>;
380
385
  emailDomain: z.ZodOptional<z.ZodString>;
381
386
  }, z.core.$strip>;
382
387
  export type SharingConnectionAudience = z.infer<typeof sharingConnectionAudienceSchema>;
383
- export declare const generalAccessWriteSchema: z.ZodObject<{
384
- mode: z.ZodEnum<{
385
- link: "link";
386
- password: "password";
388
+ export declare const visibilityWriteSchema: z.ZodObject<{
389
+ visibility: z.ZodEnum<{
387
390
  public: "public";
388
- people: "people";
391
+ restricted: "restricted";
389
392
  }>;
390
- password: z.ZodOptional<z.ZodString>;
391
- audiences: z.ZodOptional<z.ZodArray<z.ZodObject<{
393
+ }, z.core.$strip>;
394
+ export declare const sharingPasswordWriteSchema: z.ZodObject<{
395
+ password: z.ZodString;
396
+ }, z.core.$strip>;
397
+ export declare const sharingAudiencesWriteSchema: z.ZodObject<{
398
+ audiences: z.ZodArray<z.ZodObject<{
392
399
  connectionId: z.ZodString;
393
400
  tag: z.ZodOptional<z.ZodString>;
394
401
  emailDomain: z.ZodOptional<z.ZodString>;
395
- }, z.core.$strip>>>;
402
+ }, z.core.$strip>>;
403
+ }, z.core.$strip>;
404
+ export declare const spaceProtectionWriteSchema: z.ZodObject<{
405
+ visibility: z.ZodEnum<{
406
+ public: "public";
407
+ restricted: "restricted";
408
+ }>;
409
+ password: z.ZodOptional<z.ZodNullable<z.ZodString>>;
396
410
  }, z.core.$strip>;
411
+ export type SpaceProtectionWrite = z.infer<typeof spaceProtectionWriteSchema>;
397
412
  export declare const sharingAudienceSchema: z.ZodObject<{
398
413
  connectionId: z.ZodString;
399
414
  type: z.ZodEnum<{
@@ -686,15 +701,11 @@ export declare function isTeamPreviewLockRule(rule: Pick<RuntimeRule, "id">): bo
686
701
  export declare function teamPreviewLockActive(rules: ReadonlyArray<Pick<RuntimeRule, "id">>): boolean;
687
702
  export declare function withTeamPreviewLock(rules: RuntimeRule[], teamId: string, enabled: boolean): RuntimeRule[];
688
703
  export declare const spaceSharingSchema: z.ZodObject<{
689
- generalAccess: z.ZodObject<{
690
- mode: z.ZodEnum<{
691
- link: "link";
692
- password: "password";
693
- public: "public";
694
- people: "people";
695
- }>;
696
- hasPassword: z.ZodBoolean;
697
- }, z.core.$strip>;
704
+ visibility: z.ZodEnum<{
705
+ public: "public";
706
+ restricted: "restricted";
707
+ }>;
708
+ hasPassword: z.ZodBoolean;
698
709
  people: z.ZodDefault<z.ZodArray<z.ZodObject<{
699
710
  kind: z.ZodEnum<{
700
711
  team_member: "team_member";
@@ -788,6 +799,7 @@ export declare const policyDocSchema: z.ZodObject<{
788
799
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
789
800
  agent: z.ZodOptional<z.ZodString>;
790
801
  country: z.ZodOptional<z.ZodString>;
802
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
791
803
  header: z.ZodOptional<z.ZodObject<{
792
804
  name: z.ZodString;
793
805
  value: z.ZodString;
@@ -852,6 +864,7 @@ export declare const spacePolicySchema: z.ZodObject<{
852
864
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
853
865
  agent: z.ZodOptional<z.ZodString>;
854
866
  country: z.ZodOptional<z.ZodString>;
867
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
855
868
  header: z.ZodOptional<z.ZodObject<{
856
869
  name: z.ZodString;
857
870
  value: z.ZodString;
@@ -910,6 +923,7 @@ export declare const spaceAccessRulesWriteSchema: z.ZodObject<{
910
923
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
911
924
  agent: z.ZodOptional<z.ZodString>;
912
925
  country: z.ZodOptional<z.ZodString>;
926
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
913
927
  header: z.ZodOptional<z.ZodObject<{
914
928
  name: z.ZodString;
915
929
  value: z.ZodString;
@@ -968,6 +982,7 @@ export declare const spaceAccessRulesReadSchema: z.ZodObject<{
968
982
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
969
983
  agent: z.ZodOptional<z.ZodString>;
970
984
  country: z.ZodOptional<z.ZodString>;
985
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
971
986
  header: z.ZodOptional<z.ZodObject<{
972
987
  name: z.ZodString;
973
988
  value: z.ZodString;
@@ -1057,6 +1072,7 @@ export declare const effectiveRuleSchema: z.ZodObject<{
1057
1072
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
1058
1073
  agent: z.ZodOptional<z.ZodString>;
1059
1074
  country: z.ZodOptional<z.ZodString>;
1075
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
1060
1076
  header: z.ZodOptional<z.ZodObject<{
1061
1077
  name: z.ZodString;
1062
1078
  value: z.ZodString;
@@ -1119,6 +1135,7 @@ export declare const effectivePolicySchema: z.ZodObject<{
1119
1135
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
1120
1136
  agent: z.ZodOptional<z.ZodString>;
1121
1137
  country: z.ZodOptional<z.ZodString>;
1138
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
1122
1139
  header: z.ZodOptional<z.ZodObject<{
1123
1140
  name: z.ZodString;
1124
1141
  value: z.ZodString;
@@ -1197,6 +1214,7 @@ export declare const accessSimulateResultSchema: z.ZodObject<{
1197
1214
  ipCidrs: z.ZodOptional<z.ZodArray<z.ZodString>>;
1198
1215
  agent: z.ZodOptional<z.ZodString>;
1199
1216
  country: z.ZodOptional<z.ZodString>;
1217
+ countryNotIn: z.ZodOptional<z.ZodArray<z.ZodString>>;
1200
1218
  header: z.ZodOptional<z.ZodObject<{
1201
1219
  name: z.ZodString;
1202
1220
  value: z.ZodString;
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { ISO_COUNTRY_CODES } from "./countries.js";
2
3
  // Unified access contracts (internal-docs/access-plan.html — the only access
3
4
  // document).
4
5
  //
@@ -131,7 +132,8 @@ export function externalGrant(connectionId, tag) {
131
132
  // STORED form of a connection login acquire (`loginAcquireSchema.url`): the
132
133
  // compiler stores the symbolic `connection:{acn}` reference and the resolver
133
134
  // rewrites it to the live URL on every policy resolution (the OIDC leg URL or
134
- // the shop's authorizeUrl with the CURRENT space/sv/host baked in). Nothing
135
+ // the shop's authorizeUrl with the CURRENT space/sv baked in). The serving
136
+ // runtime adds the actual request host and same-origin return path. Nothing
135
137
  // stored ever carries a stale sessionVersion; a revoked connection's acquire
136
138
  // resolves to nothing (the login block disappears — fail closed).
137
139
  export function connectionAcquireRef(connectionId) {
@@ -296,9 +298,11 @@ export const passwordAcquireSchema = z.object({
296
298
  });
297
299
  export const loginAcquireSchema = z.object({
298
300
  type: z.literal("login"),
299
- // Interactive login surface the challenge page links to (the cloud authorize
300
- // endpoint, or a BYO connection's authorizeUrl). Hydrated by the compiler;
301
- // the runtime appends `return=` as a plain same-origin path.
301
+ // Interactive handoff target (the cloud authorize endpoint, or a BYO
302
+ // connection's authorizeUrl). The challenge page links only to the runtime's
303
+ // same-origin login endpoint; it never exposes this target directly. The
304
+ // compiler hydrates static identity intent, then the runtime sets `host=`
305
+ // from the actual serving request and `return=` as a plain same-origin path.
302
306
  url: z.string().min(1),
303
307
  // Display label for the challenge-page button (e.g. "Continue with
304
308
  // Spacefast", "Sign in with Acme Shop").
@@ -339,6 +343,10 @@ export const ruleMatchSchema = z.object({
339
343
  agent: z.string().min(1).optional(),
340
344
  // ISO 3166-1 alpha-2 country code matcher.
341
345
  country: z.string().min(2).max(2).optional(),
346
+ // Matches when the resolved country is NOT in this list. Unlike compiling
347
+ // an allowlist as the finite ISO complement, this also matches missing,
348
+ // provider-special, malformed, and future country values.
349
+ countryNotIn: z.array(z.string().min(2).max(2)).min(1).max(250).optional(),
342
350
  // Single request-header matcher: name + expected value.
343
351
  header: z.object({ name: z.string().min(1), value: z.string() }).optional(),
344
352
  });
@@ -425,6 +433,13 @@ export const accessTokenPayloadSchema = z.object({
425
433
  // from browser history is dead after first use. Share tokens carry no `jti`
426
434
  // (the share URL IS the credential; revocation is structural).
427
435
  jti: z.string().min(1).optional(),
436
+ // Cast room capability. Collaboration tokens are valid for exactly one
437
+ // canonical room; other visitor tokens omit it.
438
+ room: z.string().min(1).optional(),
439
+ // Anonymous Comments tokens remain anonymous identities even though they
440
+ // carry a signed room capability.
441
+ anonymous_id: z.string().min(1).optional(),
442
+ name: z.string().min(1).max(120).optional(),
428
443
  });
429
444
  // Authorize request for `POST /v1/spaces/:id/access/authorize` — surviving for
430
445
  // exactly one caller: the dashboard preview-token mint (iframe → runtime
@@ -492,9 +507,11 @@ export function serviceTokenGrant(tokenId) {
492
507
  // 3d. Share links + the sharing projection (access-plan §5.1/§5.2, X-33)
493
508
  // ---------------------------------------------------------------------------
494
509
  // Share tokens are re-signed on demand from the link row (§5.2): the JWT is
495
- // never stored, only the row. `exp` = the link's expiry capped at this ceiling
496
- // (and re-copying re-mints, so a live link's URL never goes stale).
497
- export const SHARE_LINK_TOKEN_MAX_TTL_SECONDS = 30 * 24 * 60 * 60; // 30 days
510
+ // never stored, only the row. Credential lifetime = artifact lifetime: `exp`
511
+ // IS the link's expiry and is omitted for a never-expiring link. The runtime
512
+ // permits that omission only for a signed, audience-bound token whose subject
513
+ // and sole grant are the same `link:` capability. Revocation remains
514
+ // structural — the grant drops from the compiled rules.
498
515
  // A share link row projected onto the wire (§4.4). `path` is "/" for a
499
516
  // space-wide link; any other value scopes the link's grant to that subtree
500
517
  // (compile-time: the grant only ever appears in rules matching the path).
@@ -507,8 +524,8 @@ export const shareLinkSchema = z.object({
507
524
  label: z.string().min(1).nullable().default(null),
508
525
  path: z.string().min(1),
509
526
  createdBy: z.string().min(1).nullable().default(null),
510
- // Unix seconds; null = the link never expires (tokens still cap at 30d and
511
- // re-mint from the row on copy).
527
+ // Unix seconds; null = the link never expires. The minted token mirrors this
528
+ // by omitting exp there is no hidden shorter fuse.
512
529
  expiresAt: z.number().int().nonnegative().nullable().default(null),
513
530
  createdAt: z.string().min(1).describe("ISO 8601 timestamp."),
514
531
  lastUsedAt: z.string().min(1).nullable().default(null),
@@ -528,11 +545,14 @@ export const shareLinkCreateSchema = z.object({
528
545
  export const shareLinkWithUrlSchema = shareLinkSchema.extend({
529
546
  url: z.string().min(1).describe("https://<host><path>?sf_share=<token>"),
530
547
  });
531
- // The Share modal's General-access selector (§5.1). The mode is DERIVED from
532
- // the `sharing:` managed block never stored separately — so "who can see
533
- // this" has exactly one home.
534
- export const GENERAL_ACCESS_MODES = ["public", "password", "link", "people"];
535
- export const generalAccessModeSchema = z.enum(GENERAL_ACCESS_MODES);
548
+ // Who can open the space ONE exclusive bit, always explicit. Everything
549
+ // else (password, share links, invites, connection audiences, service tokens)
550
+ // is an additive KEY into a restricted space: union semantics, any key
551
+ // admits; keys are dormant on a public space, never errors. Visibility is
552
+ // DERIVED from the `sharing:` managed block (a restricted space is one whose
553
+ // block carries the space-wide challenge rule) — never stored separately.
554
+ export const SPACE_VISIBILITIES = ["public", "restricted"];
555
+ export const spaceVisibilitySchema = z.enum(SPACE_VISIBILITIES);
536
556
  // A connection audience member on the People-only selector state (§6.2/§6.3):
537
557
  // "your company SSO" (oidc — optionally narrowed to a verified email domain)
538
558
  // or "Acme Shop subscribers" (external — the owner-defined grant tag).
@@ -556,16 +576,32 @@ export const sharingConnectionAudienceSchema = z.object({
556
576
  .regex(/^[a-z0-9.-]+\.[a-z]{2,}$/i)
557
577
  .optional(),
558
578
  });
559
- export const generalAccessWriteSchema = z.object({
560
- mode: generalAccessModeSchema,
561
- // Required when switching to "password" for the first time; optional when a
562
- // stored password already exists (it is kept).
563
- password: z.string().min(1).max(256).optional(),
564
- // People-mode connection audiences (§6.4): compiled INTO the one sharing
565
- // general rule (mixed audiences = one rule, multiple acquires — the chooser
566
- // is the challenge page, never a new surface). Omitted = keep the current
567
- // audiences; [] = remove them.
568
- audiences: z.array(sharingConnectionAudienceSchema).max(20).optional(),
579
+ // PUT …/sharing/visibility the ONE exclusive choice. Flipping visibility
580
+ // never creates or destroys keys: restricting re-arms whatever keys exist;
581
+ // going public leaves them dormant (including a stored password).
582
+ export const visibilityWriteSchema = z.object({
583
+ visibility: spaceVisibilitySchema,
584
+ });
585
+ // PUT …/sharing/password set/replace the password KEY. Setting a password
586
+ // also restricts a public space (the intent is unambiguous); it never touches
587
+ // other keys. DELETE clears the key and leaves visibility alone (fail-closed:
588
+ // a restricted space stays restricted, team-only if that was the last key).
589
+ export const sharingPasswordWriteSchema = z.object({
590
+ password: z.string().min(1).max(256),
591
+ });
592
+ // PUT …/sharing/audiences — replace the connection-audience keys (§6.2/§6.3).
593
+ // Compiled INTO the one sharing general rule (mixed audiences = one rule,
594
+ // multiple acquires — the chooser is the challenge page, never a new surface).
595
+ export const sharingAudiencesWriteSchema = z.object({
596
+ audiences: z.array(sharingConnectionAudienceSchema).max(20),
597
+ });
598
+ // The core protection op (agent surface): visibility plus the password key in
599
+ // one write. `password: string` sets the key (and restricts), `null` clears
600
+ // it, omitted leaves it alone. Deeper key management (links, invites,
601
+ // audiences) lives on the sharing surface.
602
+ export const spaceProtectionWriteSchema = z.object({
603
+ visibility: spaceVisibilitySchema,
604
+ password: z.string().min(1).max(256).nullable().optional(),
569
605
  });
570
606
  // A connection audience projected back on the sharing read (derived from the
571
607
  // compiled block — never stored separately, X-33).
@@ -782,13 +818,17 @@ export const serviceTokenWithSecretSchema = serviceTokenSchema.extend({
782
818
  export const FIREWALL_EFFECTS = ["deny", "challenge"];
783
819
  export const firewallEffectSchema = z.enum(FIREWALL_EFFECTS);
784
820
  // Country section: `block` denies/challenges the listed countries; `allow`
785
- // admits ONLY the listed countries (the compiler enumerates the complement —
786
- // rule `match.country` is an exact ISO code with no negation, so allow-mode
787
- // is expressed as one rule per non-listed country).
821
+ // admits ONLY the listed countries (one fail-closed `countryNotIn` rule).
788
822
  export const firewallCountriesSchema = z.object({
789
823
  mode: z.enum(["block", "allow"]),
790
824
  // ISO 3166-1 alpha-2, uppercased server-side.
791
- list: z.array(z.string().length(2)).min(1).max(250),
825
+ list: z
826
+ .array(z
827
+ .string()
828
+ .length(2)
829
+ .refine((code) => ISO_COUNTRY_CODES.includes(code.toUpperCase()), "Country must be an ISO 3166-1 alpha-2 code."))
830
+ .min(1)
831
+ .max(250),
792
832
  // deny = blocked outright; challenge = "visitors from these countries must
793
833
  // sign in" (the team-viewer audience per §5.6).
794
834
  effect: firewallEffectSchema.default("deny"),
@@ -874,12 +914,11 @@ export function withTeamPreviewLock(rules, teamId, enabled) {
874
914
  // dashboard renders this and posts intents; it never interprets or compiles
875
915
  // rules.
876
916
  export const spaceSharingSchema = z.object({
877
- generalAccess: z.object({
878
- mode: generalAccessModeSchema,
879
- // Whether a stored space password exists (the verifier hash, never the
880
- // password) lets the modal say "keep existing password".
881
- hasPassword: z.boolean(),
882
- }),
917
+ // The one exclusive bit. Everything below it is keys.
918
+ visibility: spaceVisibilitySchema,
919
+ // Whether the password KEY exists (the verifier hash, never the password).
920
+ // Independent of visibility: a public space can hold a dormant password.
921
+ hasPassword: z.boolean(),
883
922
  people: z.array(sharingPersonSchema).default([]),
884
923
  // Connection audiences on the People-only state (§6.2/§6.3), derived from
885
924
  // the compiled sharing block.
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export declare const ACTIVITY_EVENT_CODES: readonly ["space.created", "space.claimed", "feedback.lead_claim_pending", "space.transferred", "space.move_requested", "space.moved", "space.expired", "space.disabled", "space.enabled", "space.deleted", "space.config_updated", "space.slug_updated", "space.password_updated", "site.provision_requested", "site.placement_hold_set", "site.placement_hold_cleared", "site.burst_toggled", "space.access_logout_all", "space.access_transfer_scrub", "space.access_operator_token", "space.sharing_updated", "space.share_link_created", "space.share_link_revoked", "space.invite_created", "space.invite_revoked", "space.access_request_created", "space.access_request_resolved", "space.firewall_updated", "team.access_defaults_updated", "team.service_token_created", "team.service_token_revoked", "team.access_connection_created", "team.access_connection_updated", "team.access_connection_revoked", "version.created", "version.ready", "version.warning", "version.failed", "version.expired", "version.canceled", "version.deleted", "version.retention_warning", "version.retention_deleted", "channel.promoted", "build.created", "build.succeeded", "build.failed", "build.canceled", "build.skipped", "domain.created", "domain.verified", "domain.verification_failed", "domain.control_lost", "domain.dns_updated", "domain.nameservers_updated", "domain.registration_purchased", "domain.registration_renewed", "domain.registration_expiring", "domain.registration_expired", "domain.transfer_in_started", "domain.transfer_out_started", "domain.deleted", "binding.created", "binding.activated", "binding.blocked", "binding.deleted", "transfer.requested", "transfer.confirmed", "transfer.completed", "transfer.canceled", "transfer.expired", "transfer.failed", "variable.updated", "variable.deleted", "api_key.created", "api_key.updated", "api_key.revoked", "agent_handoff.created", "agent_handoff.redeemed", "agent_handoff.revoked", "webhook.created", "webhook.updated", "webhook.secret_rotated", "webhook.disabled", "webhook.deleted", "team.updated", "team.slug_updated", "team.member_added", "team.member_removed", "team.member_role_updated", "team.builds_deploys_quota_exceeded", "tenant.past_due", "tenant.suspended", "tenant.reactivated", "tenant.deleted", "export.ready", "export.failed", "import.ready", "import.failed", "comment.token_minted", "comment.created", "comment.reply_created", "comment.archived", "comment.unarchived", "abuse_report.created", "abuse_report.updated", "claim.blocked_takedown", "user.created", "user.signed_in", "user.deleted", "user.impersonation_started", "user.impersonation_stopped", "user.two_factor_enabled", "user.two_factor_disabled"];
2
+ export declare const ACTIVITY_EVENT_CODES: readonly ["space.created", "space.claimed", "feedback.lead_claim_pending", "space.transferred", "space.move_requested", "space.moved", "space.expired", "space.disabled", "space.enabled", "space.deleted", "space.config_updated", "space.slug_updated", "space.password_updated", "site.provision_requested", "site.placement_hold_set", "site.placement_hold_cleared", "site.burst_toggled", "space.access_logout_all", "space.access_transfer_scrub", "space.access_operator_token", "space.sharing_updated", "space.share_link_created", "space.share_link_revoked", "space.invite_created", "space.invite_revoked", "space.access_request_created", "space.access_request_resolved", "space.firewall_updated", "team.access_defaults_updated", "team.service_token_created", "team.service_token_revoked", "team.access_connection_created", "team.access_connection_updated", "team.access_connection_revoked", "version.created", "version.ready", "version.warning", "version.failed", "version.expired", "version.canceled", "version.deleted", "version.retention_warning", "version.retention_deleted", "channel.promoted", "build.created", "build.succeeded", "build.failed", "build.canceled", "build.skipped", "domain.created", "domain.verified", "domain.verification_failed", "domain.control_lost", "domain.dns_updated", "domain.nameservers_updated", "domain.registration_purchased", "domain.registration_renewed", "domain.registration_expiring", "domain.registration_expired", "domain.transfer_in_started", "domain.transfer_out_started", "domain.deleted", "domain.attached", "domain.activated", "domain.blocked", "domain.detached", "transfer.requested", "transfer.confirmed", "transfer.completed", "transfer.canceled", "transfer.expired", "transfer.failed", "variable.updated", "variable.deleted", "api_key.created", "api_key.updated", "api_key.revoked", "agent_handoff.created", "agent_handoff.redeemed", "agent_handoff.revoked", "webhook.created", "webhook.updated", "webhook.secret_rotated", "webhook.disabled", "webhook.deleted", "team.updated", "team.slug_updated", "team.member_added", "team.member_removed", "team.member_role_updated", "team.builds_deploys_quota_exceeded", "tenant.past_due", "tenant.suspended", "tenant.reactivated", "tenant.deleted", "export.ready", "export.failed", "import.ready", "import.failed", "comment.token_minted", "comment.created", "comment.reply_created", "comment.archived", "comment.unarchived", "abuse_report.created", "abuse_report.updated", "claim.blocked_takedown", "user.created", "user.signed_in", "user.deleted", "user.impersonation_started", "user.impersonation_stopped", "user.two_factor_enabled", "user.two_factor_disabled"];
3
3
  export type ActivityEventCode = (typeof ACTIVITY_EVENT_CODES)[number];
4
4
  export declare function isActivityEventCode(value: string): value is ActivityEventCode;
5
5
  export declare function isValidActivityEventFilter(filter: string): boolean;
@@ -77,10 +77,10 @@ export const ACTIVITY_EVENT_CODES = [
77
77
  "domain.transfer_out_started",
78
78
  "domain.deleted",
79
79
  // binding
80
- "binding.created",
81
- "binding.activated",
82
- "binding.blocked",
83
- "binding.deleted",
80
+ "domain.attached",
81
+ "domain.activated",
82
+ "domain.blocked",
83
+ "domain.detached",
84
84
  // transfer
85
85
  "transfer.requested",
86
86
  "transfer.confirmed",
@@ -123,7 +123,7 @@ export const ACTIVITY_EVENT_CODES = [
123
123
  "export.failed",
124
124
  "import.ready",
125
125
  "import.failed",
126
- // annotations
126
+ // comments
127
127
  "comment.token_minted",
128
128
  "comment.created",
129
129
  "comment.reply_created",