@spacefast/common 0.0.26 → 0.2.1

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 (302) hide show
  1. package/dist/agents/connect-targets.d.ts +6 -146
  2. package/dist/agents/connect-targets.js +63 -295
  3. package/dist/agents/private-key-oauth.d.ts +31 -1
  4. package/dist/agents/private-key-oauth.js +124 -33
  5. package/dist/agents/registry/core.d.ts +292 -0
  6. package/dist/agents/registry/core.js +1388 -0
  7. package/dist/agents/registry/deeplink-probes.d.ts +23 -0
  8. package/dist/agents/registry/deeplink-probes.js +18 -0
  9. package/dist/agents/registry/node.d.ts +56 -0
  10. package/dist/agents/registry/node.js +339 -0
  11. package/dist/brand-assets-build.js +1 -2
  12. package/dist/brand-assets.js +4 -7
  13. package/dist/brand.d.ts +17 -0
  14. package/dist/brand.js +24 -4
  15. package/dist/config/domains.d.ts +55 -28
  16. package/dist/config/domains.js +85 -41
  17. package/dist/config/index.js +1 -2
  18. package/dist/contracts/abuse.js +9 -24
  19. package/dist/contracts/access-profiles.d.ts +86 -0
  20. package/dist/contracts/access-profiles.js +89 -0
  21. package/dist/contracts/access.d.ts +21 -27
  22. package/dist/contracts/access.js +33 -64
  23. package/dist/contracts/activity.d.ts +18 -1
  24. package/dist/contracts/activity.js +70 -26
  25. package/dist/contracts/analytics.js +8 -10
  26. package/dist/contracts/api-keys.d.ts +77 -52
  27. package/dist/contracts/api-keys.js +44 -24
  28. package/dist/contracts/application-journal.d.ts +216 -0
  29. package/dist/contracts/application-journal.js +167 -0
  30. package/dist/contracts/auth.d.ts +90 -17
  31. package/dist/contracts/auth.js +86 -17
  32. package/dist/contracts/beta.d.ts +9 -4
  33. package/dist/contracts/beta.js +20 -16
  34. package/dist/contracts/billing.js +7 -11
  35. package/dist/contracts/bootstrap.d.ts +791 -0
  36. package/dist/contracts/bootstrap.js +51 -0
  37. package/dist/contracts/builds.d.ts +186 -7
  38. package/dist/contracts/builds.js +75 -21
  39. package/dist/contracts/channels.d.ts +43 -0
  40. package/dist/contracts/channels.js +25 -9
  41. package/dist/contracts/cli.d.ts +7 -0
  42. package/dist/contracts/cli.js +6 -0
  43. package/dist/contracts/collab-public.d.ts +1 -1
  44. package/dist/contracts/collab-public.js +5 -8
  45. package/dist/contracts/comments.d.ts +45 -35
  46. package/dist/contracts/comments.js +107 -77
  47. package/dist/contracts/commerce.d.ts +165 -0
  48. package/dist/contracts/commerce.js +146 -0
  49. package/dist/contracts/common.d.ts +3 -3
  50. package/dist/contracts/common.js +18 -29
  51. package/dist/contracts/content-contract-verification.d.ts +521 -0
  52. package/dist/contracts/content-contract-verification.js +320 -0
  53. package/dist/contracts/content-platform-fixture.d.ts +1278 -0
  54. package/dist/contracts/content-platform-fixture.js +44 -0
  55. package/dist/contracts/content-program.d.ts +994 -0
  56. package/dist/contracts/content-program.js +658 -0
  57. package/dist/contracts/content-sync.d.ts +290 -0
  58. package/dist/contracts/content-sync.js +167 -0
  59. package/dist/contracts/content.d.ts +432 -0
  60. package/dist/contracts/content.js +303 -0
  61. package/dist/contracts/continuation.d.ts +17 -1
  62. package/dist/contracts/continuation.js +23 -23
  63. package/dist/contracts/countries.js +3 -4
  64. package/dist/contracts/crons.d.ts +17 -0
  65. package/dist/contracts/crons.js +33 -15
  66. package/dist/contracts/dashboard-prefs.d.ts +56 -0
  67. package/dist/contracts/dashboard-prefs.js +51 -0
  68. package/dist/contracts/device-auth.d.ts +234 -37
  69. package/dist/contracts/device-auth.js +267 -53
  70. package/dist/contracts/docs.d.ts +6 -10
  71. package/dist/contracts/docs.js +5 -13
  72. package/dist/contracts/domains.d.ts +499 -102
  73. package/dist/contracts/domains.js +169 -58
  74. package/dist/contracts/email-preferences.d.ts +3 -3
  75. package/dist/contracts/email-preferences.js +6 -7
  76. package/dist/contracts/enums.d.ts +26 -26
  77. package/dist/contracts/enums.js +61 -54
  78. package/dist/contracts/error-code-meta.d.ts +269 -7
  79. package/dist/contracts/error-code-meta.js +80 -5
  80. package/dist/contracts/error-codes.d.ts +5 -5
  81. package/dist/contracts/error-codes.js +78 -16
  82. package/dist/contracts/events.d.ts +100 -20
  83. package/dist/contracts/events.js +107 -20
  84. package/dist/contracts/execution.d.ts +47 -66
  85. package/dist/contracts/execution.js +51 -64
  86. package/dist/contracts/feature-lifecycle.d.ts +70 -14
  87. package/dist/contracts/feature-lifecycle.js +86 -15
  88. package/dist/contracts/features.d.ts +100 -37
  89. package/dist/contracts/features.js +21 -27
  90. package/dist/contracts/fixtures/content-platform-v1.json +1108 -0
  91. package/dist/contracts/frame-session.d.ts +192 -0
  92. package/dist/contracts/frame-session.js +164 -0
  93. package/dist/contracts/functions.d.ts +218 -211
  94. package/dist/contracts/functions.js +273 -260
  95. package/dist/contracts/grant-copy.d.ts +43 -0
  96. package/dist/contracts/grant-copy.js +44 -0
  97. package/dist/contracts/grants.d.ts +64 -56
  98. package/dist/contracts/grants.js +124 -23
  99. package/dist/contracts/ids.d.ts +4 -1
  100. package/dist/contracts/ids.js +4 -1
  101. package/dist/contracts/internal.d.ts +5 -4
  102. package/dist/contracts/internal.js +12 -3
  103. package/dist/contracts/mcp.d.ts +17 -0
  104. package/dist/contracts/mcp.js +23 -0
  105. package/dist/contracts/me.d.ts +6 -1
  106. package/dist/contracts/me.js +12 -6
  107. package/dist/contracts/notifications.d.ts +27 -29
  108. package/dist/contracts/notifications.js +9 -4
  109. package/dist/contracts/oauth-resources.d.ts +112 -10
  110. package/dist/contracts/oauth-resources.js +116 -11
  111. package/dist/contracts/oauth-scope-actions.d.ts +90 -0
  112. package/dist/contracts/oauth-scope-actions.js +126 -0
  113. package/dist/contracts/operations.d.ts +27 -4
  114. package/dist/contracts/operations.js +11 -5
  115. package/dist/contracts/pages.d.ts +29 -5
  116. package/dist/contracts/pages.js +22 -5
  117. package/dist/contracts/partner-notifications.d.ts +3 -0
  118. package/dist/contracts/partner-notifications.js +65 -0
  119. package/dist/contracts/{platform.d.ts → partner.d.ts} +29 -42
  120. package/dist/contracts/{platform.js → partner.js} +27 -40
  121. package/dist/contracts/plan-policy.d.ts +1 -1
  122. package/dist/contracts/principal-assertion.d.ts +43 -0
  123. package/dist/contracts/principal-assertion.js +67 -0
  124. package/dist/contracts/principals.d.ts +73 -0
  125. package/dist/contracts/principals.js +59 -0
  126. package/dist/contracts/privacy.d.ts +11 -0
  127. package/dist/contracts/privacy.js +17 -0
  128. package/dist/contracts/problem-document.js +3 -4
  129. package/dist/contracts/publish-archive.d.ts +116 -18
  130. package/dist/contracts/publish-archive.js +6 -3
  131. package/dist/contracts/push-new.d.ts +4 -4
  132. package/dist/contracts/quotas.js +3 -3
  133. package/dist/contracts/realtime.d.ts +52 -0
  134. package/dist/contracts/realtime.js +54 -0
  135. package/dist/contracts/repository-connections.d.ts +1 -1
  136. package/dist/contracts/repository-connections.js +6 -2
  137. package/dist/contracts/resources.d.ts +105 -14
  138. package/dist/contracts/resources.js +145 -21
  139. package/dist/contracts/route-inventory.d.ts +358 -0
  140. package/dist/contracts/route-inventory.js +141 -0
  141. package/dist/contracts/runtime-api.d.ts +112 -35
  142. package/dist/contracts/runtime-api.js +86 -66
  143. package/dist/contracts/runtime-app.d.ts +11 -21
  144. package/dist/contracts/runtime-app.js +39 -24
  145. package/dist/contracts/runtime-components.d.ts +143 -0
  146. package/dist/contracts/runtime-components.js +199 -0
  147. package/dist/contracts/runtime-db.d.ts +45 -19
  148. package/dist/contracts/runtime-db.js +85 -20
  149. package/dist/contracts/runtime-purge.js +3 -5
  150. package/dist/contracts/runtime-services.d.ts +43 -75
  151. package/dist/contracts/runtime-services.js +29 -49
  152. package/dist/contracts/runtime-storage.d.ts +14 -14
  153. package/dist/contracts/runtime-storage.js +28 -13
  154. package/dist/contracts/sf-config-v1.d.ts +14 -18
  155. package/dist/contracts/slugs.js +13 -4
  156. package/dist/contracts/space-config.d.ts +235 -28
  157. package/dist/contracts/space-config.js +246 -91
  158. package/dist/contracts/spaces.d.ts +360 -255
  159. package/dist/contracts/spaces.js +190 -122
  160. package/dist/contracts/superadmin-activity.d.ts +3 -43
  161. package/dist/contracts/superadmin-activity.js +6 -30
  162. package/dist/contracts/superadmin-emails.d.ts +1 -0
  163. package/dist/contracts/superadmin-emails.js +17 -1
  164. package/dist/contracts/superadmin-runtime.d.ts +199 -0
  165. package/dist/contracts/superadmin-runtime.js +141 -0
  166. package/dist/contracts/superadmin-search.d.ts +22 -2
  167. package/dist/contracts/superadmin-search.js +14 -6
  168. package/dist/contracts/superadmin-spaces.d.ts +435 -186
  169. package/dist/contracts/superadmin-spaces.js +131 -25
  170. package/dist/contracts/superadmin-teams.d.ts +3 -0
  171. package/dist/contracts/superadmin-teams.js +1 -2
  172. package/dist/contracts/superadmin-tenants.d.ts +627 -6
  173. package/dist/contracts/superadmin-tenants.js +32 -7
  174. package/dist/contracts/superadmin.d.ts +98 -16
  175. package/dist/contracts/superadmin.js +63 -10
  176. package/dist/contracts/tags.d.ts +85 -58
  177. package/dist/contracts/tags.js +44 -34
  178. package/dist/contracts/teams.d.ts +72 -9
  179. package/dist/contracts/teams.js +84 -25
  180. package/dist/contracts/tenants.d.ts +135 -0
  181. package/dist/contracts/tenants.js +120 -0
  182. package/dist/contracts/test-triggers.d.ts +70 -0
  183. package/dist/contracts/test-triggers.js +116 -0
  184. package/dist/contracts/theme-json.js +3 -8
  185. package/dist/contracts/transfers.d.ts +1 -0
  186. package/dist/contracts/transfers.js +1 -0
  187. package/dist/contracts/usage.d.ts +209 -0
  188. package/dist/contracts/usage.js +124 -12
  189. package/dist/contracts/variables.d.ts +2 -2
  190. package/dist/contracts/variables.js +9 -13
  191. package/dist/contracts/webhooks.d.ts +13 -5
  192. package/dist/contracts/webhooks.js +3 -1
  193. package/dist/contracts/zero.d.ts +57 -64
  194. package/dist/contracts/zero.js +68 -66
  195. package/dist/dashboard-paths/index.d.ts +24 -21
  196. package/dist/dashboard-paths/index.js +35 -47
  197. package/dist/dashboard-paths/route-reservations.generated.d.ts +2 -0
  198. package/dist/dashboard-paths/route-reservations.generated.js +36 -0
  199. package/dist/docs/agent-arrival.d.ts +92 -0
  200. package/dist/docs/agent-arrival.js +227 -0
  201. package/dist/docs/agent-output-policy.d.ts +6 -0
  202. package/dist/docs/agent-output-policy.js +22 -0
  203. package/dist/docs/agent-prose.d.ts +11 -17
  204. package/dist/docs/agent-prose.js +62 -37
  205. package/dist/docs/agent-setup.d.ts +72 -41
  206. package/dist/docs/agent-setup.js +336 -436
  207. package/dist/docs/catalog.d.ts +147 -89
  208. package/dist/docs/catalog.js +157 -42
  209. package/dist/docs/error-docs.d.ts +2098 -1
  210. package/dist/docs/error-docs.js +281 -16
  211. package/dist/docs/index-build.d.ts +0 -1
  212. package/dist/docs/index-build.js +2 -3
  213. package/dist/docs/page-context-prompt.d.ts +77 -0
  214. package/dist/docs/page-context-prompt.js +131 -0
  215. package/dist/docs/reference-urls.d.ts +46 -0
  216. package/dist/docs/reference-urls.js +79 -0
  217. package/dist/docs/search.d.ts +6 -8
  218. package/dist/docs/search.js +10 -13
  219. package/dist/docs/skill-distribution.d.ts +4 -1
  220. package/dist/docs/skill-distribution.js +10 -5
  221. package/dist/docs/skills.d.ts +117 -117
  222. package/dist/docs/skills.js +120 -72
  223. package/dist/docs/start-prompts.d.ts +45 -0
  224. package/dist/docs/start-prompts.js +62 -0
  225. package/dist/domain-exploration.js +9 -13
  226. package/dist/og-template.d.ts +56 -0
  227. package/dist/og-template.js +56 -0
  228. package/dist/slug-policy/index.js +5 -11
  229. package/dist/utils/browser-credential.d.ts +13 -6
  230. package/dist/utils/browser-credential.js +14 -7
  231. package/dist/utils/build-settings.d.ts +16 -0
  232. package/dist/utils/build-settings.js +63 -17
  233. package/dist/utils/canonical-json.d.ts +3 -5
  234. package/dist/utils/canonical-json.js +3 -5
  235. package/dist/utils/cast-transport.d.ts +5 -17
  236. package/dist/utils/cast-transport.js +6 -19
  237. package/dist/utils/claim-token.js +1 -2
  238. package/dist/utils/comment-avatars.js +4 -6
  239. package/dist/utils/concurrency.js +2 -3
  240. package/dist/utils/content-type.d.ts +7 -6
  241. package/dist/utils/content-type.js +73 -51
  242. package/dist/utils/credential-policy.d.ts +50 -6
  243. package/dist/utils/credential-policy.js +123 -57
  244. package/dist/utils/egress-policy.fixtures.json +1 -1
  245. package/dist/utils/generate-space-name.d.ts +3 -8
  246. package/dist/utils/generate-space-name.js +3 -8
  247. package/dist/utils/grants.d.ts +0 -1
  248. package/dist/utils/grants.js +4 -7
  249. package/dist/utils/gravatar.d.ts +2 -4
  250. package/dist/utils/gravatar.js +6 -12
  251. package/dist/utils/id-hints.js +14 -23
  252. package/dist/utils/idempotency.d.ts +3 -3
  253. package/dist/utils/idempotency.js +6 -7
  254. package/dist/utils/local-space-state.d.ts +15 -15
  255. package/dist/utils/local-space-state.js +34 -23
  256. package/dist/utils/oauth-signed-query.d.ts +3 -5
  257. package/dist/utils/oauth-signed-query.js +6 -9
  258. package/dist/utils/one-shot-replay.d.ts +3 -5
  259. package/dist/utils/one-shot-replay.js +3 -5
  260. package/dist/utils/page-colors.d.ts +4 -10
  261. package/dist/utils/page-colors.js +11 -35
  262. package/dist/utils/page-fonts.js +6 -11
  263. package/dist/utils/page-preview.d.ts +0 -1
  264. package/dist/utils/page-preview.js +0 -1
  265. package/dist/utils/pages.d.ts +22 -11
  266. package/dist/utils/pages.js +70 -30
  267. package/dist/utils/privacy-regions.d.ts +19 -0
  268. package/dist/utils/privacy-regions.js +91 -0
  269. package/dist/utils/publish-form-data.d.ts +4 -5
  270. package/dist/utils/publish-form-data.js +2 -3
  271. package/dist/utils/publish-policy.d.ts +10 -23
  272. package/dist/utils/publish-policy.js +63 -116
  273. package/dist/utils/query-client.d.ts +2 -0
  274. package/dist/utils/query-client.js +10 -1
  275. package/dist/utils/runtime-paths.d.ts +4 -4
  276. package/dist/utils/runtime-paths.js +6 -8
  277. package/dist/utils/runtime-upload.d.ts +4 -0
  278. package/dist/utils/runtime-upload.js +5 -0
  279. package/dist/utils/secure-local-file.d.ts +3 -3
  280. package/dist/utils/secure-local-file.js +18 -24
  281. package/dist/utils/space-config.d.ts +11 -14
  282. package/dist/utils/space-config.js +10 -16
  283. package/dist/utils/static-runtime-policy.d.ts +5 -8
  284. package/dist/utils/static-runtime-policy.generated.d.ts +16 -0
  285. package/dist/utils/static-runtime-policy.generated.js +70 -0
  286. package/dist/utils/static-runtime-policy.js +17 -84
  287. package/dist/utils/storage-policy.js +1 -2
  288. package/dist/utils/upload-session.js +8 -14
  289. package/dist/utils/version-path.js +11 -19
  290. package/dist/utils/wpcom-auth-redirects.d.ts +5 -14
  291. package/dist/utils/wpcom-auth-redirects.js +1 -4
  292. package/dist/vocabulary.d.ts +7 -7
  293. package/dist/vocabulary.js +30 -16
  294. package/package.json +14 -2
  295. package/dist/agents/client-registry.d.ts +0 -22
  296. package/dist/agents/client-registry.js +0 -41
  297. package/dist/docs/agent-handoff-document.d.ts +0 -15
  298. package/dist/docs/agent-handoff-document.js +0 -180
  299. package/dist/docs/agent-solutions.d.ts +0 -110
  300. package/dist/docs/agent-solutions.js +0 -183
  301. package/dist/utils/query-keys.d.ts +0 -84
  302. package/dist/utils/query-keys.js +0 -108
@@ -1,22 +1,43 @@
1
1
  import { z } from "zod";
2
- import { dataEnvelope, mutationEnvelope } from "./common.js";
2
+ import { CursorPaginationSchema, dataEnvelope, mutationEnvelope } from "./common.js";
3
3
  import { executionIdentifierSchema, executionSha256Schema } from "./execution.js";
4
4
  import { ZERO_RUNTIME_KIND, zeroMigrationOperationSchema, zeroTableSchema } from "./zero.js";
5
5
  /**
6
6
  * The database surface, for whichever runtime a space is carrying.
7
7
  *
8
- * There is one database per space the site's own MySQL and at most one
9
- * runtime with a claim on it, so these contracts are runtime-neutral by
10
- * default. The two exceptions are stated explicitly: a migration plan is a
11
- * capsule's declaration and no worker has one, and the console hand-off is a
12
- * property of the wp.cloud site rather than of anything a version declared.
8
+ * One database per space, the site's own MySQL, and at most one runtime with a
9
+ * claim on it, so these contracts are runtime-neutral. Two exceptions: a
10
+ * migration plan is a capsule's declaration and no worker has one, and the
11
+ * console hand-off is a property of the wp.cloud site.
13
12
  *
14
- * The reads answer in the capsule's declaration shapes (`zeroTableSchema`,
15
- * `zeroMigrationOperationSchema`) because a capsule's declared schema is the
16
- * richest answer either runtime can give and a worker's is the same answer with
17
- * the declaration-shaped fields empty. Those shapes stay Zero-named and stay in
18
- * `./zero.js`: a declared table is the capsule's own statement about itself.
13
+ * Reads answer in the capsule's declaration shapes (`zeroTableSchema`,
14
+ * `zeroMigrationOperationSchema`); a worker's answer is the same shape with the
15
+ * declaration-shaped fields empty.
19
16
  */
17
+ /**
18
+ * Whether the live version's declared migration plan has actually run against
19
+ * the space database. `applied` compares the recorded application against the
20
+ * plan's target `schemaHash`; it is `null` when no application record exists —
21
+ * a version finalized before this record existed, or a finalize whose ready
22
+ * receipt was a replay — because the control plane then cannot prove the plan
23
+ * ran. Honest unknown, never a guess.
24
+ */
25
+ export const runtimeDbPlanStateSchema = z
26
+ .object({
27
+ applied: z
28
+ .boolean()
29
+ .nullable()
30
+ .describe("Whether this plan has been run against the space database. `null` when the control plane has no application record and cannot truthfully say."),
31
+ appliedSchemaHash: executionSha256Schema
32
+ .nullable()
33
+ .describe("Schema hash recorded when a plan was last applied for this version, if any."),
34
+ pendingOperationCount: z
35
+ .number()
36
+ .int()
37
+ .nonnegative()
38
+ .describe("Queued or running `db migrate` operations for this space. Non-zero means an apply is still waiting."),
39
+ })
40
+ .strict();
20
41
  export const runtimeDbInspectResponseSchema = z
21
42
  .object({
22
43
  versionId: z.string().min(1).nullable(),
@@ -26,19 +47,31 @@ export const runtimeDbInspectResponseSchema = z
26
47
  schemaHash: executionSha256Schema.nullable(),
27
48
  tables: z.array(zeroTableSchema).default([]),
28
49
  migrations: z.array(zeroMigrationOperationSchema).default([]),
50
+ plan: runtimeDbPlanStateSchema
51
+ .nullable()
52
+ .describe("Applied-state of the live version's migration plan. `null` when the live version declares no migration plan."),
29
53
  })
30
54
  .strict();
31
55
  export const runtimeDbInspectPublicResponseSchema = dataEnvelope(runtimeDbInspectResponseSchema);
32
56
  export const runtimeDbDumpQuerySchema = z
33
57
  .object({
34
- table: executionIdentifierSchema.optional(),
35
- limit: z.coerce.number().int().min(1).max(100).default(25),
58
+ table: executionIdentifierSchema
59
+ .optional()
60
+ .describe("Dump only this declared table. Omit it to dump every declared table."),
61
+ limit: z.coerce
62
+ .number()
63
+ .int()
64
+ .min(1)
65
+ .max(100)
66
+ .default(25)
67
+ .describe("Maximum rows to read per table."),
36
68
  })
37
69
  .strict();
70
+ export const runtimeDbCellValueSchema = z.json();
38
71
  export const runtimeDbDumpTableSchema = z
39
72
  .object({
40
73
  name: executionIdentifierSchema,
41
- rows: z.array(z.record(z.string(), z.unknown())).default([]),
74
+ rows: z.array(z.record(z.string(), runtimeDbCellValueSchema)).default([]),
42
75
  })
43
76
  .strict();
44
77
  export const runtimeDbDumpResponseSchema = z
@@ -49,7 +82,22 @@ export const runtimeDbDumpResponseSchema = z
49
82
  tables: z.array(runtimeDbDumpTableSchema).default([]),
50
83
  })
51
84
  .strict();
52
- export const runtimeDbDumpPublicResponseSchema = dataEnvelope(runtimeDbDumpResponseSchema);
85
+ // OpenAPI embeds a local recursive `$ref` below the route and cannot resolve
86
+ // it, so the same wire contract is spelled out non-recursively here.
87
+ const runtimeDbWireCellValueSchema = z.union([
88
+ z.string(),
89
+ z.number(),
90
+ z.boolean(),
91
+ z.null(),
92
+ z.array(z.unknown()),
93
+ z.record(z.string(), z.unknown()),
94
+ ]);
95
+ const runtimeDbDumpPublicTableSchema = runtimeDbDumpTableSchema.extend({
96
+ rows: z.array(z.record(z.string(), runtimeDbWireCellValueSchema)).default([]),
97
+ });
98
+ export const runtimeDbDumpPublicResponseSchema = dataEnvelope(runtimeDbDumpResponseSchema.extend({
99
+ tables: z.array(runtimeDbDumpPublicTableSchema).default([]),
100
+ }));
53
101
  export const runtimeDbExportOrderingSchema = z
54
102
  .object({
55
103
  tables: z.literal("name_asc"),
@@ -69,18 +117,35 @@ export const runtimeDbExportMetadataSchema = z
69
117
  export const runtimeDbExportMetadataPublicResponseSchema = dataEnvelope(runtimeDbExportMetadataSchema);
70
118
  export const runtimeDbExportPageQuerySchema = z
71
119
  .object({
72
- schemaHash: executionSha256Schema,
73
- cursor: z.string().min(1).max(4_096).optional(),
74
- limit: z.coerce.number().int().min(1).max(1_000).default(500),
120
+ schemaHash: executionSha256Schema.describe("Schema fence from `GET /v1/spaces/{spaceId}/db/export`. A page whose table has changed shape since is rejected rather than mixed into the export."),
121
+ cursor: z
122
+ .string()
123
+ .min(1)
124
+ .max(4_096)
125
+ .optional()
126
+ .describe("Opaque cursor from the previous page's `pagination.nextCursor`."),
127
+ limit: z.coerce
128
+ .number()
129
+ .int()
130
+ .min(1)
131
+ .max(1_000)
132
+ .default(500)
133
+ .describe("Maximum rows to return in this page."),
75
134
  })
76
135
  .strict();
136
+ // The runtime's own wire shape for an export page: rows plus a bare keyset
137
+ // `cursor` that is null at the end. The control plane re-envelopes it into the
138
+ // one platform list envelope below.
77
139
  export const runtimeDbExportPageSchema = z
78
140
  .object({
79
- rows: z.array(z.record(z.string(), z.unknown())),
141
+ rows: z.array(z.record(z.string(), runtimeDbCellValueSchema)),
80
142
  cursor: z.string().nullable(),
81
143
  })
82
144
  .strict();
83
- export const runtimeDbExportPagePublicResponseSchema = dataEnvelope(runtimeDbExportPageSchema);
145
+ export const runtimeDbExportPagePublicResponseSchema = z.object({
146
+ data: z.array(z.record(z.string(), runtimeDbWireCellValueSchema)),
147
+ pagination: CursorPaginationSchema,
148
+ });
84
149
  export const runtimeDbMigrateResultSchema = z
85
150
  .object({
86
151
  versionId: z.string().min(1).describe("Live version whose migration plan this is."),
@@ -1,7 +1,5 @@
1
1
  import { z } from "zod";
2
- // One vocabulary for every runtime mutation that can invalidate edge state.
3
- // `queued` is a successful durable handoff: production FPM flushes the
4
- // management response once the purge journal owns the work, before the edge
5
- // provider call runs. `pending` is narrower — the synchronous worker kick did
6
- // not reach the purge entrypoint, so maintenance still owes the attempt.
2
+ // `queued` means the purge journal durably owns the work; the edge provider
3
+ // call may not have run yet. `pending` is narrower: the synchronous worker kick
4
+ // never reached the purge entrypoint, so maintenance still owes the attempt.
7
5
  export const runtimePurgeStatusSchema = z.enum(["queued", "ok", "failed", "pending"]);
@@ -2,30 +2,18 @@
2
2
  * Platform services that tenant code reaches through the runtime rather than
3
3
  * through a credential of its own: Gravatar, spam checking, and mail.
4
4
  *
5
- * Three properties hold for all three, and they are the reason this file
6
- * exists instead of three unrelated ones:
5
+ * Every call is brokered, so no credential is ever in tenant reach. Zero hands
6
+ * these to a handler as `ctx.gravatar` / `ctx.spam` / `ctx.email`; Functions
7
+ * binds them as `env.GRAVATAR` / `env.SPAM` / `env.EMAIL`, with the same method
8
+ * names and fields. Zero's `check` narrows the input because its HTTP host can
9
+ * add request metadata; a detached Functions call supplies it explicitly.
7
10
  *
8
- * - **The credential is never in tenant reach.** An Akismet key or a Gravatar
9
- * token in a bundle is a published secret, and a wp.cloud `SMTP_PASS` in a
10
- * capsule is worse. Every call below is brokered: the runtime attaches
11
- * authority outside the code that asked for the call.
12
- * - **The interface is the contract, not the accessor.** Zero hands these to a
13
- * handler as `ctx.gravatar` / `ctx.spam` / `ctx.email`; Functions binds them
14
- * as `env.GRAVATAR` / `env.SPAM` / `env.EMAIL`. Method names and semantic
15
- * fields stay shared. Zero's `check` narrows the input because its HTTP host
16
- * can add request metadata; a detached Functions call supplies that metadata
17
- * explicitly.
18
- * - **The client is the same source on both tiers.** See
19
- * `RUNTIME_SERVICE_CLIENT_SOURCE`: normalization, validation and the pure
20
- * avatar-URL construction are one implementation injected into both runtimes,
21
- * so the two tiers cannot drift into behaving differently.
22
- *
23
- * What differs between tiers is the transport under `call()`, and only that.
11
+ * `RUNTIME_SERVICE_CLIENT_SOURCE` is one implementation injected into both
12
+ * runtimes, so only the transport under `call()` differs between tiers.
24
13
  */
25
14
  /**
26
- * What Gravatar serves when an address has no image. `404` is here so callers
27
- * can detect absence by status instead of receiving a generated face they then
28
- * have to recognise as a placeholder.
15
+ * What Gravatar serves when an address has no image. `404` lets a caller detect
16
+ * absence by status instead of by recognising a generated placeholder.
29
17
  */
30
18
  export declare const GRAVATAR_DEFAULTS: readonly ["404", "mp", "identicon", "monsterid", "wavatar", "retro", "robohash", "blank"];
31
19
  export type GravatarDefault = (typeof GRAVATAR_DEFAULTS)[number];
@@ -34,7 +22,7 @@ export type GravatarRating = (typeof GRAVATAR_RATINGS)[number];
34
22
  /** Gravatar's own ceiling. Larger values are refused rather than clamped. */
35
23
  export declare const GRAVATAR_AVATAR_MAX_SIZE = 2048;
36
24
  export type GravatarAvatarOptions = {
37
- /** Requested square edge in pixels, 12048. */
25
+ /** Requested square edge in pixels, 1 to 2048. */
38
26
  size?: number;
39
27
  /** Image to serve when the address has no Gravatar. */
40
28
  default?: GravatarDefault;
@@ -49,9 +37,9 @@ export type GravatarVerifiedAccount = {
49
37
  label: string | null;
50
38
  };
51
39
  /**
52
- * The subset of the Gravatar profile that is stable, public, and useful to a
53
- * page. Deliberately not the raw upstream document: passing that through would
54
- * make every upstream field addition a silent contract change here.
40
+ * The stable, public subset of the Gravatar profile. Not the raw upstream
41
+ * document: passing that through would make every upstream field addition a
42
+ * silent contract change.
55
43
  */
56
44
  export type GravatarProfile = {
57
45
  hash: string;
@@ -64,32 +52,24 @@ export type GravatarProfile = {
64
52
  verifiedAccounts: GravatarVerifiedAccount[];
65
53
  };
66
54
  export type Gravatar = {
67
- /**
68
- * Pure and synchronous: an avatar URL is a hash and a query string, so it
69
- * costs no network call and cannot fail. It stays on this interface anyway
70
- * because an author looking for an avatar looks here, not in a utility
71
- * module.
72
- */
55
+ /** Pure and synchronous: an avatar URL is a hash and a query string. */
73
56
  avatarUrl(email: string, options?: GravatarAvatarOptions): string;
74
57
  /** The profile behind an address, or null when the address has none. */
75
58
  profile(email: string): Promise<GravatarProfile | null>;
76
59
  };
77
60
  /**
78
- * Akismet's recognised content types. The vendor is not in the name of
79
- * anything an author touches `ctx.spam` outlives whichever service answers
80
- * it but the vocabulary is Akismet's because the classifier is trained on
81
- * it, and inventing synonyms would only lose signal.
61
+ * Akismet's recognised content types. The vocabulary is Akismet's because the
62
+ * classifier is trained on it; the vendor name stays out of the API surface,
63
+ * because `ctx.spam` outlives whichever service answers it.
82
64
  */
83
65
  export declare const SPAM_CONTENT_TYPES: readonly ["comment", "reply", "forum-post", "contact-form", "signup", "message"];
84
66
  export type SpamContentType = (typeof SPAM_CONTENT_TYPES)[number];
85
67
  /**
86
68
  * One complete submission, as the classifier sees it. Detached runtimes such
87
- * as Functions use this shape; Zero uses {@link RequestSpamSubmission} while
88
- * handling an HTTP invocation and fills the network fields itself.
69
+ * as Functions use this shape; Zero uses {@link RequestSpamSubmission} and
70
+ * fills the network fields itself.
89
71
  *
90
- * `userIp` and `userAgent` are the two heaviest signals Akismet uses, and
91
- * accuracy drops sharply without them — hence `userIp` being required rather
92
- * than another optional field an author would skip.
72
+ * `userIp` is required because accuracy drops sharply without it.
93
73
  */
94
74
  export type SpamSubmission = {
95
75
  /** The text being classified. */
@@ -106,9 +86,7 @@ export type SpamSubmission = {
106
86
  authorUrl?: string;
107
87
  /**
108
88
  * Set to `"administrator"` for a trusted, authenticated operator of the
109
- * space. Akismet passes that role unconditionally, so this is an author's
110
- * own escape hatch for their own team — it grants nothing beyond skipping a
111
- * check the author asked for.
89
+ * space. Akismet passes that role unconditionally, so the check is skipped.
112
90
  */
113
91
  authorRole?: "administrator";
114
92
  /** ISO-8601 UTC. Defaults to the moment of the call. */
@@ -119,19 +97,17 @@ export type SpamSubmission = {
119
97
  /**
120
98
  * A spam check made while handling a visitor request.
121
99
  *
122
- * Network evidence is deliberately absent. The runtime, not capsule code,
123
- * supplies the visitor IP, user agent, referrer, and current URL from the
124
- * trusted invocation envelope. This keeps a browser from claiming its own IP
125
- * through mutation arguments or an endpoint body.
100
+ * The runtime, not capsule code, supplies the visitor IP, user agent, referrer,
101
+ * and current URL from the trusted invocation envelope, so a browser cannot
102
+ * claim its own IP through mutation arguments or an endpoint body.
126
103
  */
127
104
  export type RequestSpamSubmission = Omit<SpamSubmission, "userIp" | "userAgent" | "referrer" | "permalink">;
128
105
  export type SpamVerdict = {
129
106
  /** Whether the submission classifies as spam. */
130
107
  spam: boolean;
131
108
  /**
132
- * Blatant, pervasive spam. Akismet's own guidance is that this may be
133
- * dropped outright rather than held for review, so it is surfaced instead of
134
- * being folded into `spam`.
109
+ * Blatant, pervasive spam. Akismet's guidance is to drop it outright rather
110
+ * than hold it for review.
135
111
  */
136
112
  discard: boolean;
137
113
  };
@@ -157,10 +133,8 @@ export type RuntimeSpamRequestContext = {
157
133
  permalink?: string;
158
134
  };
159
135
  /**
160
- * The structured subset of Cloudflare's `SendEmail` binding, field for field.
161
- *
162
- * Matching it is a portability decision, not an aesthetic one: a worker
163
- * deployed straight to Cloudflare gets the native binding and the same
136
+ * The structured subset of Cloudflare's `SendEmail` binding, field for field: a
137
+ * worker deployed straight to Cloudflare gets the native binding, and the same
164
138
  * message-building code has to typecheck against both.
165
139
  */
166
140
  export type EmailAddress = {
@@ -180,40 +154,34 @@ export type EmailMessage = {
180
154
  };
181
155
  export type SendEmail = {
182
156
  /**
183
- * Accepts one email effect. The identifier names the message; it is not a
184
- * claim that anything was delivered, and no state beyond "queued" is
185
- * observable from here — see the runtime's message views for that.
157
+ * Accepts one email effect. The identifier names the message, not a delivery;
158
+ * nothing beyond "queued" is observable here.
186
159
  */
187
160
  send(message: EmailMessage): Promise<{
188
161
  messageId: string;
189
162
  }>;
190
163
  };
191
164
  /**
192
- * The hosts a broker may reach on a tenant's behalf are deliberately NOT listed
193
- * here. That table lives in `stattic-runtime-core`'s egress policy, where it is
194
- * generated into both the runtime's PHP constants and the Rust broker, so one
195
- * declaration is enforced at both places a connection is actually made. A copy
196
- * in this file would be a third statement of the same fact that nothing checks.
165
+ * The hosts a broker may reach on a tenant's behalf are NOT listed here. That
166
+ * table lives in `stattic-runtime-core`'s egress policy, generated into both
167
+ * the runtime's PHP constants and the Rust broker.
197
168
  *
198
- * The `gravatar.com` in the avatar URL below is not that table: it is a public
199
- * URL handed to a browser, not an egress target.
169
+ * The `gravatar.com` in the avatar URL below is a public URL handed to a
170
+ * browser, not an egress target.
200
171
  */
201
172
  /**
202
173
  * The client both runtimes inject, as source.
203
174
  *
204
- * It is a string rather than a module because neither runtime can import from
205
- * npm at the point it needs this: Zero compiles a capsule to QuickJS bytecode
206
- * with a generated prelude, and the Functions host injects modules into a
207
- * tenant isolate it does not build. Shipping one source to both is what makes
208
- * "the same API" a fact about the code rather than a promise in a doc.
175
+ * A string rather than a module because neither runtime can import from npm
176
+ * here: Zero compiles a capsule to QuickJS bytecode with a generated prelude,
177
+ * and the Functions host injects modules into a tenant isolate it does not
178
+ * build.
209
179
  *
210
180
  * It closes over nothing of ours. The host defines `call(service, operation,
211
- * payload)` and everything else normalization, the pure avatar URL, the
212
- * shapes returned to tenant code — is here, identical on both tiers.
181
+ * payload)`; everything else is here, identical on both tiers.
213
182
  *
214
- * The SHA-256 is hand-rolled for the same reason: QuickJS has no WebCrypto,
215
- * and Cloudflare's `crypto.subtle` is async, which would force `avatarUrl` to
216
- * return a promise on one tier and a string on the other. A synchronous
217
- * implementation is the only way the signature can be identical.
183
+ * The SHA-256 is hand-rolled because QuickJS has no WebCrypto and
184
+ * `crypto.subtle` is async, which would make `avatarUrl` return a promise on
185
+ * one tier and a string on the other.
218
186
  */
219
187
  export declare const RUNTIME_SERVICE_CLIENT_SOURCE: string;
@@ -2,33 +2,21 @@
2
2
  * Platform services that tenant code reaches through the runtime rather than
3
3
  * through a credential of its own: Gravatar, spam checking, and mail.
4
4
  *
5
- * Three properties hold for all three, and they are the reason this file
6
- * exists instead of three unrelated ones:
5
+ * Every call is brokered, so no credential is ever in tenant reach. Zero hands
6
+ * these to a handler as `ctx.gravatar` / `ctx.spam` / `ctx.email`; Functions
7
+ * binds them as `env.GRAVATAR` / `env.SPAM` / `env.EMAIL`, with the same method
8
+ * names and fields. Zero's `check` narrows the input because its HTTP host can
9
+ * add request metadata; a detached Functions call supplies it explicitly.
7
10
  *
8
- * - **The credential is never in tenant reach.** An Akismet key or a Gravatar
9
- * token in a bundle is a published secret, and a wp.cloud `SMTP_PASS` in a
10
- * capsule is worse. Every call below is brokered: the runtime attaches
11
- * authority outside the code that asked for the call.
12
- * - **The interface is the contract, not the accessor.** Zero hands these to a
13
- * handler as `ctx.gravatar` / `ctx.spam` / `ctx.email`; Functions binds them
14
- * as `env.GRAVATAR` / `env.SPAM` / `env.EMAIL`. Method names and semantic
15
- * fields stay shared. Zero's `check` narrows the input because its HTTP host
16
- * can add request metadata; a detached Functions call supplies that metadata
17
- * explicitly.
18
- * - **The client is the same source on both tiers.** See
19
- * `RUNTIME_SERVICE_CLIENT_SOURCE`: normalization, validation and the pure
20
- * avatar-URL construction are one implementation injected into both runtimes,
21
- * so the two tiers cannot drift into behaving differently.
22
- *
23
- * What differs between tiers is the transport under `call()`, and only that.
11
+ * `RUNTIME_SERVICE_CLIENT_SOURCE` is one implementation injected into both
12
+ * runtimes, so only the transport under `call()` differs between tiers.
24
13
  */
25
14
  /* -------------------------------------------------------------------------- */
26
15
  /* Gravatar */
27
16
  /* -------------------------------------------------------------------------- */
28
17
  /**
29
- * What Gravatar serves when an address has no image. `404` is here so callers
30
- * can detect absence by status instead of receiving a generated face they then
31
- * have to recognise as a placeholder.
18
+ * What Gravatar serves when an address has no image. `404` lets a caller detect
19
+ * absence by status instead of by recognising a generated placeholder.
32
20
  */
33
21
  export const GRAVATAR_DEFAULTS = [
34
22
  "404",
@@ -47,10 +35,9 @@ export const GRAVATAR_AVATAR_MAX_SIZE = 2048;
47
35
  /* Spam */
48
36
  /* -------------------------------------------------------------------------- */
49
37
  /**
50
- * Akismet's recognised content types. The vendor is not in the name of
51
- * anything an author touches `ctx.spam` outlives whichever service answers
52
- * it but the vocabulary is Akismet's because the classifier is trained on
53
- * it, and inventing synonyms would only lose signal.
38
+ * Akismet's recognised content types. The vocabulary is Akismet's because the
39
+ * classifier is trained on it; the vendor name stays out of the API surface,
40
+ * because `ctx.spam` outlives whichever service answers it.
54
41
  */
55
42
  export const SPAM_CONTENT_TYPES = [
56
43
  "comment",
@@ -64,14 +51,12 @@ export const SPAM_CONTENT_TYPES = [
64
51
  /* Upstreams */
65
52
  /* -------------------------------------------------------------------------- */
66
53
  /**
67
- * The hosts a broker may reach on a tenant's behalf are deliberately NOT listed
68
- * here. That table lives in `stattic-runtime-core`'s egress policy, where it is
69
- * generated into both the runtime's PHP constants and the Rust broker, so one
70
- * declaration is enforced at both places a connection is actually made. A copy
71
- * in this file would be a third statement of the same fact that nothing checks.
54
+ * The hosts a broker may reach on a tenant's behalf are NOT listed here. That
55
+ * table lives in `stattic-runtime-core`'s egress policy, generated into both
56
+ * the runtime's PHP constants and the Rust broker.
72
57
  *
73
- * The `gravatar.com` in the avatar URL below is not that table: it is a public
74
- * URL handed to a browser, not an egress target.
58
+ * The `gravatar.com` in the avatar URL below is a public URL handed to a
59
+ * browser, not an egress target.
75
60
  */
76
61
  /* -------------------------------------------------------------------------- */
77
62
  /* The shared client */
@@ -79,20 +64,17 @@ export const SPAM_CONTENT_TYPES = [
79
64
  /**
80
65
  * The client both runtimes inject, as source.
81
66
  *
82
- * It is a string rather than a module because neither runtime can import from
83
- * npm at the point it needs this: Zero compiles a capsule to QuickJS bytecode
84
- * with a generated prelude, and the Functions host injects modules into a
85
- * tenant isolate it does not build. Shipping one source to both is what makes
86
- * "the same API" a fact about the code rather than a promise in a doc.
67
+ * A string rather than a module because neither runtime can import from npm
68
+ * here: Zero compiles a capsule to QuickJS bytecode with a generated prelude,
69
+ * and the Functions host injects modules into a tenant isolate it does not
70
+ * build.
87
71
  *
88
72
  * It closes over nothing of ours. The host defines `call(service, operation,
89
- * payload)` and everything else normalization, the pure avatar URL, the
90
- * shapes returned to tenant code — is here, identical on both tiers.
73
+ * payload)`; everything else is here, identical on both tiers.
91
74
  *
92
- * The SHA-256 is hand-rolled for the same reason: QuickJS has no WebCrypto,
93
- * and Cloudflare's `crypto.subtle` is async, which would force `avatarUrl` to
94
- * return a promise on one tier and a string on the other. A synchronous
95
- * implementation is the only way the signature can be identical.
75
+ * The SHA-256 is hand-rolled because QuickJS has no WebCrypto and
76
+ * `crypto.subtle` is async, which would make `avatarUrl` return a promise on
77
+ * one tier and a string on the other.
96
78
  */
97
79
  export const RUNTIME_SERVICE_CLIENT_SOURCE = String.raw `
98
80
  const SERVICE_DEFAULTS = ${JSON.stringify(GRAVATAR_DEFAULTS)};
@@ -217,9 +199,8 @@ function sha256Hex(value) {
217
199
  return hex;
218
200
  }
219
201
 
220
- // Gravatar's own identifier rule. Trim and lower-case only: it deliberately
221
- // does not strip dots or plus-tags, because two addresses that differ there are
222
- // two accounts as far as Gravatar is concerned.
202
+ // Gravatar's identifier rule: trim and lower-case only. Dots and plus-tags are
203
+ // not stripped; two addresses that differ there are two Gravatar accounts.
223
204
  function gravatarHash(email) {
224
205
  if (typeof email !== "string" || email.trim() === "") {
225
206
  throw invalid("An email address is required.");
@@ -402,9 +383,8 @@ function emailPayload(message) {
402
383
  for (const name of Object.keys(message.headers)) {
403
384
  const value = message.headers[name];
404
385
  if (typeof value !== "string") throw invalid("Header " + name + " must be a string.");
405
- // Refused here rather than at the broker so the author sees the field
406
- // name they wrote. The broker refuses again this is convenience, not
407
- // the boundary.
386
+ // Refused here so the author sees the field name they wrote. The broker
387
+ // refuses again; this is convenience, not the boundary.
408
388
  if (/[^\x21-\x39\x3b-\x7e]/.test(name)) {
409
389
  throw invalid("Header " + name + " is not a valid header name.");
410
390
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- /** Objects are addressed by a bare 128-bit random id there is no key and no visibility. */
2
+ /** Objects are addressed by a bare 128-bit random id. There is no key and no visibility. */
3
3
  export declare const runtimeStorageObjectIdSchema: z.ZodString;
4
4
  /** The runtime-scoped, revocable read key that makes a `/__stattic/u/<id>` URL readable. */
5
5
  export declare const runtimeStorageReadKeySchema: z.ZodString;
@@ -43,19 +43,19 @@ export declare const runtimeStorageListResponseSchema: z.ZodObject<{
43
43
  }, z.core.$strict>;
44
44
  export type RuntimeStorageListResponse = z.infer<typeof runtimeStorageListResponseSchema>;
45
45
  export declare const runtimeStorageListPublicResponseSchema: z.ZodObject<{
46
- data: z.ZodObject<{
47
- objects: z.ZodArray<z.ZodObject<{
48
- id: z.ZodString;
49
- contentType: z.ZodString;
50
- createdAt: z.ZodString;
51
- size: z.ZodNumber;
52
- uploaderId: z.ZodString;
53
- sha256: z.ZodString;
54
- url: z.ZodString;
55
- }, z.core.$strict>>;
56
- cursor: z.ZodNullable<z.ZodString>;
46
+ data: z.ZodArray<z.ZodObject<{
47
+ id: z.ZodString;
48
+ contentType: z.ZodString;
49
+ createdAt: z.ZodString;
50
+ size: z.ZodNumber;
51
+ uploaderId: z.ZodString;
52
+ sha256: z.ZodString;
53
+ url: z.ZodString;
54
+ }, z.core.$strict>>;
55
+ pagination: z.ZodObject<{
56
+ nextCursor: z.ZodNullable<z.ZodString>;
57
57
  hasMore: z.ZodBoolean;
58
- }, z.core.$strict>;
58
+ }, z.core.$strip>;
59
59
  }, z.core.$strip>;
60
60
  export declare const runtimeStorageDeleteResponseSchema: z.ZodObject<{
61
61
  id: z.ZodString;
@@ -90,8 +90,8 @@ export declare const runtimeStorageDeletePublicResponseSchema: z.ZodObject<{
90
90
  code: z.ZodString;
91
91
  severity: z.ZodEnum<{
92
92
  info: "info";
93
- error: "error";
94
93
  warning: "warning";
94
+ error: "error";
95
95
  }>;
96
96
  message: z.ZodString;
97
97
  path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -1,14 +1,25 @@
1
1
  import { z } from "zod";
2
- import { dataEnvelope, mutationEnvelope } from "./common.js";
2
+ import { CursorPaginationSchema, mutationEnvelope } from "./common.js";
3
3
  import { runtimePurgeStatusSchema } from "./runtime-purge.js";
4
- /** Objects are addressed by a bare 128-bit random id there is no key and no visibility. */
4
+ /** Objects are addressed by a bare 128-bit random id. There is no key and no visibility. */
5
5
  export const runtimeStorageObjectIdSchema = z.string().regex(/^[a-f0-9]{32}$/);
6
6
  /** The runtime-scoped, revocable read key that makes a `/__stattic/u/<id>` URL readable. */
7
7
  export const runtimeStorageReadKeySchema = z.string().regex(/^[a-f0-9]{32}$/);
8
8
  export const runtimeStorageListQuerySchema = z
9
9
  .object({
10
- cursor: z.string().min(1).max(2_048).optional(),
11
- limit: z.coerce.number().int().min(1).max(100).default(50),
10
+ cursor: z
11
+ .string()
12
+ .min(1)
13
+ .max(2_048)
14
+ .optional()
15
+ .describe("Opaque cursor from the previous page's `pagination.nextCursor`."),
16
+ limit: z.coerce
17
+ .number()
18
+ .int()
19
+ .min(1)
20
+ .max(100)
21
+ .default(50)
22
+ .describe("Maximum objects to return."),
12
23
  })
13
24
  .strict();
14
25
  export const runtimeStorageObjectSchema = z
@@ -19,12 +30,15 @@ export const runtimeStorageObjectSchema = z
19
30
  size: z.number().int().nonnegative(),
20
31
  uploaderId: z.string().min(1).max(255),
21
32
  sha256: z.string().regex(/^[a-f0-9]{64}$/),
22
- // Path-relative and composed from the read key that was current at response
23
- // time: `/__stattic/u/<id>?k=<key>`. The caller absolutizes it against
24
- // whichever of the space's hostnames it is presenting.
33
+ // Path-relative, carrying the read key current at response time:
34
+ // `/__stattic/u/<id>?k=<key>`. The caller absolutizes it against whichever
35
+ // of the space's hostnames it is presenting.
25
36
  url: z.string().min(1),
26
37
  })
27
38
  .strict();
39
+ // The runtime's own wire shape for a storage page, which the control plane
40
+ // reads and then re-envelopes. `cursor`/`hasMore` here are the runtime's
41
+ // spelling; the public route below answers the one platform list envelope.
28
42
  export const runtimeStorageListResponseSchema = z
29
43
  .object({
30
44
  objects: z.array(runtimeStorageObjectSchema),
@@ -32,7 +46,10 @@ export const runtimeStorageListResponseSchema = z
32
46
  hasMore: z.boolean(),
33
47
  })
34
48
  .strict();
35
- export const runtimeStorageListPublicResponseSchema = dataEnvelope(runtimeStorageListResponseSchema);
49
+ export const runtimeStorageListPublicResponseSchema = z.object({
50
+ data: z.array(runtimeStorageObjectSchema),
51
+ pagination: CursorPaginationSchema,
52
+ });
36
53
  export const runtimeStorageDeleteResponseSchema = z
37
54
  .object({
38
55
  id: runtimeStorageObjectIdSchema,
@@ -43,15 +60,13 @@ export const runtimeStorageDeletePublicResponseSchema = mutationEnvelope(runtime
43
60
  export const runtimeStorageReadKeyResponseSchema = z
44
61
  .object({ key: runtimeStorageReadKeySchema })
45
62
  .strict();
46
- // Rotation is the emergency lever: every URL minted under the old key answers
47
- // 404 afterwards, so the runtime purges every hostname on the box and reports
48
- // how that purge landed.
63
+ // Every URL minted under the old key answers 404 after rotation, so the runtime
64
+ // purges every hostname on the box and reports how that purge landed.
49
65
  export const runtimeStorageReadKeyRotateResponseSchema = z
50
66
  .object({
51
67
  key: runtimeStorageReadKeySchema,
52
68
  rotatedAt: z.string().datetime({ offset: true }),
53
- // `none` is the receipt for a runtime that serves no hostname yet, so there
54
- // was nothing to purge.
69
+ // `none`: the runtime serves no hostname yet, so there was nothing to purge.
55
70
  purge: z
56
71
  .object({
57
72
  status: runtimePurgeStatusSchema,