@spacefast/common 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/brand-assets/spacefast-favicon.svg +16 -0
- package/brand-assets/spacefast-sf-full-bleed.svg +13 -0
- package/brand-assets/spacefast-wordmark.svg +5 -0
- package/dist/agents/connect-targets.d.ts +138 -0
- package/dist/agents/connect-targets.js +243 -0
- package/dist/brand-assets-build.d.ts +26 -0
- package/dist/brand-assets-build.js +81 -0
- package/dist/brand-assets.d.ts +42 -0
- package/dist/brand-assets.js +30 -0
- package/dist/brand.d.ts +1 -0
- package/dist/brand.js +5 -0
- package/dist/config/domains.d.ts +12 -6
- package/dist/config/domains.js +30 -38
- package/dist/contracts/access.d.ts +967 -124
- package/dist/contracts/access.js +804 -148
- package/dist/contracts/activity.d.ts +1 -1
- package/dist/contracts/activity.js +28 -2
- package/dist/contracts/annotations.d.ts +2 -4
- package/dist/contracts/api-keys.d.ts +126 -4
- package/dist/contracts/api-keys.js +74 -6
- package/dist/contracts/archives.d.ts +8 -2
- package/dist/contracts/archives.js +11 -4
- package/dist/contracts/billing.d.ts +0 -9
- package/dist/contracts/builds.d.ts +65 -21
- package/dist/contracts/builds.js +29 -0
- package/dist/contracts/common.d.ts +2 -0
- package/dist/contracts/common.js +4 -0
- package/dist/contracts/continuation.d.ts +0 -3
- package/dist/contracts/countries.d.ts +2 -0
- package/dist/contracts/countries.js +261 -0
- package/dist/contracts/deployments.d.ts +34 -34
- package/dist/contracts/device-auth.d.ts +4 -11
- package/dist/contracts/device-auth.js +4 -0
- package/dist/contracts/docs.d.ts +119 -0
- package/dist/contracts/docs.js +51 -0
- package/dist/contracts/domains.d.ts +96 -54
- package/dist/contracts/domains.js +26 -4
- package/dist/contracts/enums.d.ts +15 -16
- package/dist/contracts/enums.js +26 -14
- package/dist/contracts/error-code-meta.d.ts +184 -0
- package/dist/contracts/error-code-meta.js +124 -10
- package/dist/contracts/error-codes.d.ts +1 -1
- package/dist/contracts/error-codes.js +42 -0
- package/dist/contracts/events.d.ts +1 -1
- package/dist/contracts/feature-lifecycle-core.d.ts +36 -0
- package/dist/contracts/feature-lifecycle-core.js +220 -0
- package/dist/contracts/feature-lifecycle.d.ts +7 -0
- package/dist/contracts/feature-lifecycle.js +31 -0
- package/dist/contracts/features.d.ts +76 -6
- package/dist/contracts/features.js +178 -13
- package/dist/contracts/generated-feature-launch-entries.d.ts +2 -0
- package/dist/contracts/generated-feature-launch-entries.js +518 -0
- package/dist/contracts/git.d.ts +2 -8
- package/dist/contracts/ids.d.ts +9 -0
- package/dist/contracts/ids.js +13 -0
- package/dist/contracts/mcp.d.ts +8 -10
- package/dist/contracts/me.js +1 -1
- package/dist/contracts/oauth-resources.d.ts +19 -8
- package/dist/contracts/oauth-resources.js +44 -13
- package/dist/contracts/operations.d.ts +161 -1
- package/dist/contracts/operations.js +49 -1
- package/dist/contracts/platform.d.ts +6 -102
- package/dist/contracts/platform.js +6 -50
- package/dist/contracts/publishes.d.ts +130 -0
- package/dist/contracts/publishes.js +145 -0
- package/dist/contracts/push-new.d.ts +4 -4
- package/dist/contracts/quotas.d.ts +2 -0
- package/dist/contracts/quotas.js +8 -0
- package/dist/contracts/repository-connections.d.ts +9 -8
- package/dist/contracts/repository-connections.js +13 -0
- package/dist/contracts/resources.d.ts +99 -13
- package/dist/contracts/resources.js +36 -4
- package/dist/contracts/routes.d.ts +0 -2
- package/dist/contracts/runtime-api.d.ts +363 -39
- package/dist/contracts/runtime-api.js +276 -6
- package/dist/contracts/sf-config-v1.d.ts +75 -0
- package/dist/contracts/sf-config-v1.js +6 -0
- package/dist/contracts/sites.d.ts +19 -2
- package/dist/contracts/sites.js +21 -0
- package/dist/contracts/space-config.d.ts +201 -2
- package/dist/contracts/space-config.js +135 -5
- package/dist/contracts/spaces.d.ts +376 -196
- package/dist/contracts/spaces.js +62 -10
- package/dist/contracts/superadmin-emails.d.ts +4 -2
- package/dist/contracts/superadmin-emails.js +8 -0
- package/dist/contracts/superadmin-queues.d.ts +26 -26
- package/dist/contracts/superadmin-spaces.d.ts +172 -42
- package/dist/contracts/superadmin-tenants.d.ts +6 -6
- package/dist/contracts/superadmin-tenants.js +6 -11
- package/dist/contracts/superadmin.d.ts +6 -93
- package/dist/contracts/superadmin.js +6 -14
- package/dist/contracts/tags.d.ts +10 -9
- package/dist/contracts/tags.js +2 -1
- package/dist/contracts/teams.d.ts +26 -30
- package/dist/contracts/teams.js +11 -17
- package/dist/contracts/theme-json.d.ts +30 -0
- package/dist/contracts/theme-json.js +48 -0
- package/dist/contracts/variables.d.ts +0 -2
- package/dist/contracts/variables.js +0 -5
- package/dist/contracts/webhooks.d.ts +2 -0
- package/dist/contracts/webhooks.js +1 -1
- package/dist/contracts/zero.d.ts +5 -10
- package/dist/docs/agent-prose.d.ts +43 -3
- package/dist/docs/agent-prose.js +146 -7
- package/dist/docs/agent-setup.d.ts +51 -0
- package/dist/docs/agent-setup.js +211 -14
- package/dist/docs/agent-solutions.d.ts +5 -5
- package/dist/docs/agent-solutions.js +2 -2
- package/dist/docs/catalog.d.ts +650 -0
- package/dist/docs/catalog.js +758 -0
- package/dist/docs/error-docs.d.ts +0 -2
- package/dist/docs/error-docs.js +189 -35
- package/dist/docs/index-build.d.ts +17 -0
- package/dist/docs/index-build.js +24 -0
- package/dist/docs/search.d.ts +54 -0
- package/dist/docs/search.js +96 -0
- package/dist/docs/skill-distribution.d.ts +5 -3
- package/dist/docs/skill-distribution.js +8 -8
- package/dist/slug-policy/blocklist.d.ts +4 -0
- package/dist/slug-policy/blocklist.js +122 -0
- package/dist/slug-policy/index.d.ts +17 -0
- package/dist/slug-policy/index.js +86 -0
- package/dist/utils/access-match.d.ts +39 -0
- package/dist/utils/access-match.js +296 -0
- package/dist/utils/auth-redirect.d.ts +3 -1
- package/dist/utils/auth-redirect.js +21 -1
- package/dist/utils/build-settings.d.ts +6 -0
- package/dist/utils/build-settings.js +429 -46
- package/dist/utils/claim-token.d.ts +8 -0
- package/dist/utils/claim-token.js +23 -2
- package/dist/utils/concurrency.d.ts +1 -0
- package/dist/utils/concurrency.js +22 -0
- package/dist/utils/content-type.d.ts +1 -0
- package/dist/utils/content-type.js +1 -1
- package/dist/utils/credential-policy.d.ts +54 -0
- package/dist/utils/{access-policy.js → credential-policy.js} +28 -2
- package/dist/utils/email.d.ts +1 -0
- package/dist/utils/email.js +3 -0
- package/dist/utils/gate-theme.d.ts +61 -0
- package/dist/utils/gate-theme.js +217 -0
- package/dist/utils/git-repository.d.ts +0 -1
- package/dist/utils/git-repository.js +0 -3
- package/dist/utils/id-hints.d.ts +8 -0
- package/dist/utils/id-hints.js +61 -0
- package/dist/utils/local-space-state.d.ts +91 -0
- package/dist/utils/local-space-state.js +251 -0
- package/dist/utils/oauth-signed-query.d.ts +8 -0
- package/dist/utils/oauth-signed-query.js +26 -0
- package/dist/utils/publish-detection.d.ts +0 -8
- package/dist/utils/publish-detection.js +0 -93
- package/dist/utils/publish-policy.d.ts +6 -5
- package/dist/utils/publish-policy.js +71 -7
- package/dist/utils/query-keys.d.ts +16 -4
- package/dist/utils/query-keys.js +31 -4
- package/dist/utils/runtime-paths.d.ts +0 -1
- package/dist/utils/runtime-paths.js +0 -1
- package/dist/utils/runtime-upload-batch.d.ts +18 -0
- package/dist/utils/runtime-upload-batch.js +90 -0
- package/dist/utils/runtime-upload.d.ts +2 -0
- package/dist/utils/runtime-upload.js +5 -0
- package/dist/utils/sf-config-v1.d.ts +2 -0
- package/dist/utils/sf-config-v1.js +542 -0
- package/dist/utils/space-config.d.ts +4 -0
- package/dist/utils/space-config.js +10 -1
- package/dist/utils/space-theme.d.ts +2 -0
- package/dist/utils/space-theme.js +9 -0
- package/dist/utils/static-runtime-policy.d.ts +0 -21
- package/dist/utils/static-runtime-policy.js +19 -103
- package/dist/utils/upload-session.d.ts +1 -1
- package/dist/utils/wpcom-auth-redirects.d.ts +32 -2
- package/dist/utils/wpcom-auth-redirects.js +26 -10
- package/dist/vocabulary.d.ts +130 -30
- package/dist/vocabulary.js +77 -36
- package/package.json +35 -1
- package/dist/contracts/account.d.ts +0 -28
- package/dist/contracts/account.js +0 -54
- package/dist/contracts/intercom.d.ts +0 -6
- package/dist/contracts/intercom.js +0 -5
- package/dist/contracts/telemetry.d.ts +0 -2
- package/dist/contracts/telemetry.js +0 -1
- package/dist/utils/access-policy.d.ts +0 -39
- package/dist/utils/error-display.d.ts +0 -7
- package/dist/utils/error-display.js +0 -42
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { policyDocSchema } from "./access.js";
|
|
2
|
+
import { accessEventSchema, policyDocSchema } from "./access.js";
|
|
3
3
|
import { conventionFilesSchema, manifestFileSchema } from "./internal.js";
|
|
4
4
|
const runtimeConventionFilesSchema = conventionFilesSchema.omit({ routes: true }).strict();
|
|
5
5
|
const hostCanonicalRedirectSchema = z.object({
|
|
@@ -111,15 +111,62 @@ const runtimeRouteConfigSchema = z.object({
|
|
|
111
111
|
// alike. Carries platform + file + cloud rules (platform prepended, always
|
|
112
112
|
// wins). Explicit null clears the stored policy; absence leaves it untouched.
|
|
113
113
|
policy: policyDocSchema.nullable().optional(),
|
|
114
|
-
// Serving-secret map (name -> value) the policy's password
|
|
115
|
-
// `
|
|
116
|
-
// verifier hash the
|
|
117
|
-
//
|
|
114
|
+
// Serving-secret map (name -> value) the policy's password acquires
|
|
115
|
+
// reference by `ref` = "secret:<name>". Carries the space-password bcrypt
|
|
116
|
+
// verifier hash (and the compiled `_headers` basicAuth credential hashes)
|
|
117
|
+
// the runtime resolves and `password_verify`s. Explicit null clears stored
|
|
118
|
+
// secrets; absence leaves them untouched.
|
|
118
119
|
secrets: z.record(z.string().min(1), z.string().min(1)).nullable().optional(),
|
|
120
|
+
// Space session version (access-plan §3.1): the runtime rejects a visitor
|
|
121
|
+
// token whose `sv` claim mismatches this, and derives the space-local `pw:`
|
|
122
|
+
// key from the password secret + this value. Absent = 0.
|
|
123
|
+
session_version: z.number().int().nonnegative().nullable().optional(),
|
|
119
124
|
// Anonymous claim-window countdown (ISO timestamp), compiled into serving
|
|
120
125
|
// state so the runtime can render the expiry-rescue banner for visitors
|
|
121
126
|
// holding the claim-link viewer session. Null/absent once claimed.
|
|
122
127
|
anonymous_expires_at: z.string().nullable().optional(),
|
|
128
|
+
// Serve-time content-type allowlist. Generic serving policy: the engine has
|
|
129
|
+
// no notion of WHY a space is restricted — it refuses (403, blocked_message
|
|
130
|
+
// body) any file whose stored Content-Type matches no pattern. Patterns are
|
|
131
|
+
// exact types or `prefix/*` wildcards ("text/*"). The control plane pushes
|
|
132
|
+
// it for unclaimed anonymous spaces (no opaque binaries pre-claim); explicit
|
|
133
|
+
// null clears the stored policy — route config is rebuilt wholesale, so a
|
|
134
|
+
// claim clears it structurally on the next sync.
|
|
135
|
+
content_types: z
|
|
136
|
+
.object({
|
|
137
|
+
allowed: z.array(z.string().min(1)),
|
|
138
|
+
blocked_message: z.string().optional(),
|
|
139
|
+
})
|
|
140
|
+
.nullable()
|
|
141
|
+
.optional(),
|
|
142
|
+
// Per-space admission-control override (plan §5/§25; contract A1): the
|
|
143
|
+
// in-flight concurrency limit the engine enforces on uncacheable requests
|
|
144
|
+
// for this space, superseding SPACEFAST_UNCACHEABLE_CONC_PER_SPACE. Ops-only
|
|
145
|
+
// in V1 (set via the superadmin admission endpoint); absent means the
|
|
146
|
+
// env-knob default applies.
|
|
147
|
+
admission: z.object({ concurrency: z.number().int().positive() }).optional(),
|
|
148
|
+
// Durable revocation SET (access-plan revocation hardening): every
|
|
149
|
+
// currently-revoked link:/invite:/svc: grant id, computed from the
|
|
150
|
+
// control-plane's Postgres projection (access/resolve.ts
|
|
151
|
+
// `revocationsForSpace`). The runtime REPLACES its revocations store's
|
|
152
|
+
// grant bucket with exactly this set on every sync — the backstop that
|
|
153
|
+
// converges even when the instant best-effort revoke_grant/unrevoke_grant
|
|
154
|
+
// call was dropped. `subs` (JWT-subject revocations) are left untouched.
|
|
155
|
+
// Absence leaves the stored set untouched.
|
|
156
|
+
revocations: z.array(z.string().min(1)).optional(),
|
|
157
|
+
// Serve-time plan entitlements (proxy-routes.md: "the rule stays in your
|
|
158
|
+
// config and activates the moment you upgrade — no redeploy needed"). Stored
|
|
159
|
+
// per space beside `policy`; a `planGated` compiled proxy rule
|
|
160
|
+
// (packages/routing plan.ts) is checked against this doc at REQUEST time by
|
|
161
|
+
// runtime/redirects.php, never baked into the compiled artifact. Explicit
|
|
162
|
+
// null clears the stored doc (falls back to fail-closed); absence leaves it
|
|
163
|
+
// untouched.
|
|
164
|
+
entitlements: z
|
|
165
|
+
.object({
|
|
166
|
+
externalProxy: z.boolean(),
|
|
167
|
+
})
|
|
168
|
+
.nullable()
|
|
169
|
+
.optional(),
|
|
123
170
|
});
|
|
124
171
|
// Compiled SpaceConfig serving primitives (spec "Serving resolution"): the finalize
|
|
125
172
|
// compiler resolves content defaults -> sf.jsonc -> space overlay into this shape;
|
|
@@ -140,6 +187,10 @@ const runtimeServingConfigSchema = z.object({
|
|
|
140
187
|
})
|
|
141
188
|
.nullable()
|
|
142
189
|
.optional(),
|
|
190
|
+
clean_urls: z
|
|
191
|
+
.boolean()
|
|
192
|
+
.optional()
|
|
193
|
+
.describe("Serve flat `<name>.html` files at their extensionless URLs (W7.1). Absent = default: on unless the fallback is the 200-status SPA shape."),
|
|
143
194
|
listing: z
|
|
144
195
|
.boolean()
|
|
145
196
|
.optional()
|
|
@@ -157,6 +208,32 @@ const runtimeServingConfigSchema = z.object({
|
|
|
157
208
|
.nullable()
|
|
158
209
|
.optional()
|
|
159
210
|
.describe("Finalize-resolved listing/viewer/OG metadata (effective SpaceConfig meta); wins over session metadata."),
|
|
211
|
+
// Gate-page presentation (access-plan §5.7, X-16): finalize-compiled theme
|
|
212
|
+
// tokens (tier 1) plus the plan-gated white-label flag (tier 2). The runtime
|
|
213
|
+
// reads this shape defensively from the version's serving_config and defaults
|
|
214
|
+
// per-field; platform-LANE pages (tombstones, plan expiry, claim, invariant
|
|
215
|
+
// errors) never consume it (X-17).
|
|
216
|
+
pages: z
|
|
217
|
+
.object({
|
|
218
|
+
theme: z
|
|
219
|
+
.object({
|
|
220
|
+
accent: z.string().max(64).optional(),
|
|
221
|
+
background: z.string().max(64).optional(),
|
|
222
|
+
logo: z.string().max(2000).optional(),
|
|
223
|
+
name: z.string().max(120).optional(),
|
|
224
|
+
// Free tier ("basic color scheme + fonts"): a validated font-family
|
|
225
|
+
// stack, same grammar as pages.theme.accent/background.
|
|
226
|
+
fontFamily: z.string().max(256).optional(),
|
|
227
|
+
})
|
|
228
|
+
.optional(),
|
|
229
|
+
// Additive theme.json palette/font-family CSS custom properties
|
|
230
|
+
// (access-plan §8 tier 3 middle rung): exposes the full WP-compatible
|
|
231
|
+
// palette to custom 401.html/403.html/layout.html authors beyond the
|
|
232
|
+
// flat accent/background tokens above.
|
|
233
|
+
theme_vars: z.string().max(8192).optional(),
|
|
234
|
+
white_label: z.boolean().optional(),
|
|
235
|
+
})
|
|
236
|
+
.optional(),
|
|
160
237
|
// Hidden experimental build-pipeline flag: absent on every version finalized
|
|
161
238
|
// without it (byte-identical payload to today). Only ever sent as true.
|
|
162
239
|
experimental_gutenberg: z.boolean().optional(),
|
|
@@ -194,6 +271,7 @@ const runtimeZeroEndpointCapabilitiesSchema = z
|
|
|
194
271
|
auth: z.boolean().optional(),
|
|
195
272
|
env: z.boolean().optional(),
|
|
196
273
|
realtime: z.boolean().optional(),
|
|
274
|
+
logging: z.boolean().optional(),
|
|
197
275
|
})
|
|
198
276
|
.default({});
|
|
199
277
|
const runtimeZeroEndpointSchema = z.object({
|
|
@@ -218,8 +296,14 @@ const runtimeZeroRunSchema = z.object({
|
|
|
218
296
|
capabilities: runtimeZeroEndpointCapabilitiesSchema.optional(),
|
|
219
297
|
db: z.record(z.string(), z.unknown()).optional(),
|
|
220
298
|
});
|
|
299
|
+
// Gated-activation mode (plan §9, Placement V2): whether a version/import
|
|
300
|
+
// installs as immediately live ("active") or staged pending an explicit
|
|
301
|
+
// activation call ("activating", the engine's own fail-safe default when
|
|
302
|
+
// absent). Shared by finalize and import — do not re-inline this enum.
|
|
303
|
+
export const runtimeZeroModeSchema = z.enum(["active", "activating"]);
|
|
221
304
|
export const runtimeVersionFinalizeRequestSchema = z.object({
|
|
222
305
|
upload_id: z.string().min(1),
|
|
306
|
+
zero_mode: runtimeZeroModeSchema.optional(),
|
|
223
307
|
// The version's authoritative ready timestamp (epoch seconds), passed by the
|
|
224
308
|
// control plane when the version already reached ready (re-finalize, import
|
|
225
309
|
// re-materialization, provider migration). The engine stamps it ONCE into the
|
|
@@ -266,6 +350,46 @@ export const runtimeVersionFinalizeRequestSchema = z.object({
|
|
|
266
350
|
})
|
|
267
351
|
.optional()
|
|
268
352
|
.describe("Channel-variant template contents, keyed by runtime route name."),
|
|
353
|
+
// Publish-baked custom gate pages (access-plan §5.7 tier 3, X-35): the
|
|
354
|
+
// finalize compiler validates the version's 401.html/403.html slot element
|
|
355
|
+
// (`<div data-sf="challenge">` / `<div data-sf="deny">`), replaces the slot's
|
|
356
|
+
// contents with the opaque v1 marker comment, and ships the baked document
|
|
357
|
+
// here. The engine stores each under the version root as
|
|
358
|
+
// `access-pages/{challenge,deny}.html` (sibling of serving.php — never a
|
|
359
|
+
// publicly served path) and unlinks stale ones on re-finalize; serving is a
|
|
360
|
+
// single str_replace of the marker with the runtime-owned functional
|
|
361
|
+
// fragment. A version finalized without a key here has no override — the
|
|
362
|
+
// default platform page renders.
|
|
363
|
+
access_pages: z
|
|
364
|
+
.object({
|
|
365
|
+
challenge: z
|
|
366
|
+
.string()
|
|
367
|
+
.max(2 * 1024 * 1024)
|
|
368
|
+
.optional()
|
|
369
|
+
.describe("Baked 401.html carrying <!--spacefast:slot:challenge:v1-->."),
|
|
370
|
+
deny: z
|
|
371
|
+
.string()
|
|
372
|
+
.max(2 * 1024 * 1024)
|
|
373
|
+
.optional()
|
|
374
|
+
.describe("Baked 403.html carrying <!--spacefast:slot:deny:v1-->."),
|
|
375
|
+
})
|
|
376
|
+
.optional(),
|
|
377
|
+
// Custom gate-page chrome (access-plan §8 tier 2): the finalize compiler
|
|
378
|
+
// validates `.spacefast/templates/layout.html`'s `<div data-sf="content">`
|
|
379
|
+
// slot, replaces its contents with the opaque v1 marker comment, and ships
|
|
380
|
+
// the baked document here. The engine stores it as
|
|
381
|
+
// `access-pages/layout.html` (sibling of the challenge/deny overrides,
|
|
382
|
+
// never a publicly served path) and unlinks it when a re-finalize omits it.
|
|
383
|
+
// Serving wraps the runtime-owned gate-page content (brand row + heading +
|
|
384
|
+
// functional fragment) in the layout's content slot with one str_replace;
|
|
385
|
+
// a missing/invalid layout falls back to the platform default chrome. Only
|
|
386
|
+
// consulted when no full custom 401.html/403.html override wins for that
|
|
387
|
+
// page (tier 1 > tier 2).
|
|
388
|
+
layout_template: z
|
|
389
|
+
.string()
|
|
390
|
+
.max(2 * 1024 * 1024)
|
|
391
|
+
.optional()
|
|
392
|
+
.describe("Baked .spacefast/templates/layout.html carrying <!--spacefast:slot:layout-content:v1-->."),
|
|
269
393
|
serving: z
|
|
270
394
|
.object({
|
|
271
395
|
headers_exact: z.record(z.string(), z.array(z.record(z.string(), z.unknown()))).default({}),
|
|
@@ -308,6 +432,9 @@ export const runtimeVersionFinalizeResponseSchema = z.object({
|
|
|
308
432
|
space_id: z.string(),
|
|
309
433
|
version_id: z.string(),
|
|
310
434
|
status: z.literal("ready"),
|
|
435
|
+
// Runtime-compiled truth from zero/endpoints-index.json. Optional so older
|
|
436
|
+
// runtimes remain parseable during rolling deploys.
|
|
437
|
+
zero_endpoint_count: z.number().int().nonnegative().optional(),
|
|
311
438
|
// Open sessions: the manifest derived from what was actually uploaded
|
|
312
439
|
// (path, size, streaming sha256). Absent for declared sessions.
|
|
313
440
|
manifest: z.array(manifestFileSchema).optional(),
|
|
@@ -323,11 +450,22 @@ export const runtimeRouteUpdateRequestSchema = z.object({
|
|
|
323
450
|
host_canonical_redirects: runtimeRouteIntentSchema.shape.host_canonical_redirects,
|
|
324
451
|
proxy_host_routes: runtimeRouteIntentSchema.shape.proxy_host_routes,
|
|
325
452
|
});
|
|
453
|
+
export const runtimeHostnameIntentUpdateRequestSchema = z.object({
|
|
454
|
+
production_hostnames: runtimeRouteIntentSchema.shape.production_hostnames,
|
|
455
|
+
noindex_production_hostnames: runtimeRouteIntentSchema.shape.noindex_production_hostnames,
|
|
456
|
+
version_hostnames: runtimeRouteIntentSchema.shape.version_hostnames,
|
|
457
|
+
host_canonical_redirects: runtimeRouteIntentSchema.shape.host_canonical_redirects,
|
|
458
|
+
proxy_host_routes: runtimeRouteIntentSchema.shape.proxy_host_routes,
|
|
459
|
+
});
|
|
326
460
|
export const runtimeRouteUpdateResponseSchema = z.object({
|
|
327
461
|
space_id: z.string(),
|
|
328
462
|
route_name: z.string(),
|
|
329
463
|
version_id: z.string(),
|
|
330
464
|
});
|
|
465
|
+
export const runtimeHostnameIntentUpdateResponseSchema = z.object({
|
|
466
|
+
space_id: z.string(),
|
|
467
|
+
route_count: z.number().int().nonnegative(),
|
|
468
|
+
});
|
|
331
469
|
export const runtimeTombstonesUpdateRequestSchema = z.object({
|
|
332
470
|
hostnames: runtimeRouteIntentSchema.shape.production_hostnames,
|
|
333
471
|
mode: z.enum(["replace", "add", "remove"]).default("replace"),
|
|
@@ -342,6 +480,31 @@ export const runtimeTombstonesUpdateResponseSchema = z.object({
|
|
|
342
480
|
space_id: z.string(),
|
|
343
481
|
tombstone_count: z.number().int().nonnegative(),
|
|
344
482
|
});
|
|
483
|
+
// Retention/pruning policy artifact (Placement V2 tiering, plan §8/§26): the
|
|
484
|
+
// control plane computes prunable version ids; the engine stores the list and
|
|
485
|
+
// its housekeeping tick prunes trees after re-checking live route pointers.
|
|
486
|
+
// An empty list clears the policy.
|
|
487
|
+
export const runtimeRetentionPolicyUpdateRequestSchema = z.object({
|
|
488
|
+
prunable_version_ids: z.array(z.string()),
|
|
489
|
+
});
|
|
490
|
+
export const runtimeRetentionPolicyUpdateResponseSchema = z.object({
|
|
491
|
+
space_id: z.string(),
|
|
492
|
+
prunable_count: z.number().int().nonnegative(),
|
|
493
|
+
});
|
|
494
|
+
// Instant per-grant tombstone (access-plan revocation hardening): the
|
|
495
|
+
// control plane's best-effort synchronous call at revoke/unrevoke time,
|
|
496
|
+
// hitting the SAME `revocations.json` the durable `config.revocations` full
|
|
497
|
+
// replace (above) also converges. `grant` must be a `link:`/`invite:`/`svc:`
|
|
498
|
+
// row id — the runtime rejects anything else.
|
|
499
|
+
export const runtimeGrantRevocationRequestSchema = z.object({
|
|
500
|
+
grant: z.string().min(1),
|
|
501
|
+
});
|
|
502
|
+
export const runtimeGrantRevocationResponseSchema = z.object({
|
|
503
|
+
space_id: z.string(),
|
|
504
|
+
target_type: z.literal("grant"),
|
|
505
|
+
grant: z.string(),
|
|
506
|
+
revoked: z.boolean(),
|
|
507
|
+
});
|
|
345
508
|
export const runtimeSpaceDeleteResponseSchema = z.object({
|
|
346
509
|
space_id: z.string(),
|
|
347
510
|
status: z.literal("deleted"),
|
|
@@ -391,14 +554,21 @@ export const runtimeSpaceExportResponseSchema = z.object({
|
|
|
391
554
|
export const runtimeSpaceImportStartRequestSchema = z
|
|
392
555
|
.object({
|
|
393
556
|
version_id_map: z.record(z.string(), z.string()).optional(),
|
|
557
|
+
// Plan §9 gated activation, extended to import (I-4): shares
|
|
558
|
+
// runtimeZeroModeSchema with runtimeVersionFinalizeRequestSchema.
|
|
559
|
+
// Absent/anything other than 'active' is the engine's own fail-safe
|
|
560
|
+
// 'activating'.
|
|
561
|
+
zero_mode: runtimeZeroModeSchema.optional(),
|
|
394
562
|
})
|
|
395
563
|
.strict();
|
|
396
564
|
// Deferred version-id mapping: control-plane-driven uploads land on the
|
|
397
565
|
// runtime before the control plane has read the archive, so the freshly
|
|
398
|
-
// minted target ids
|
|
566
|
+
// minted target ids (and, for upload-sourced imports, zero_mode) are
|
|
567
|
+
// supplied here before the first step.
|
|
399
568
|
export const runtimeSpaceImportMapRequestSchema = z
|
|
400
569
|
.object({
|
|
401
570
|
version_id_map: z.record(z.string(), z.string()),
|
|
571
|
+
zero_mode: runtimeZeroModeSchema.optional(),
|
|
402
572
|
})
|
|
403
573
|
.strict();
|
|
404
574
|
export const runtimeSpaceImportResponseSchema = z.object({
|
|
@@ -414,6 +584,42 @@ export const runtimeSpaceImportResponseSchema = z.object({
|
|
|
414
584
|
updated_at: z.string(),
|
|
415
585
|
completed_at: z.string().optional(),
|
|
416
586
|
});
|
|
587
|
+
const runtimeTransferBundleFileSchema = z.object({
|
|
588
|
+
path: z.string().min(1),
|
|
589
|
+
content_b64: z.string(),
|
|
590
|
+
});
|
|
591
|
+
export const runtimeTransferBundleSourceRequestSchema = z.object({
|
|
592
|
+
space_id: z.string().min(1),
|
|
593
|
+
version_ids: z.array(z.string().min(1)),
|
|
594
|
+
cursor: z.string().nullable(),
|
|
595
|
+
});
|
|
596
|
+
export const runtimeTransferBundleTargetRequestSchema = z.object({
|
|
597
|
+
space_id: z.string().min(1),
|
|
598
|
+
store: z.literal(true),
|
|
599
|
+
files: z.array(runtimeTransferBundleFileSchema),
|
|
600
|
+
done: z.boolean(),
|
|
601
|
+
});
|
|
602
|
+
export const runtimeTransferBundleResponseSchema = z.object({
|
|
603
|
+
chunk: z.object({ files: z.array(runtimeTransferBundleFileSchema) }),
|
|
604
|
+
next_cursor: z.string().nullable(),
|
|
605
|
+
});
|
|
606
|
+
export const runtimeTransferBundleStoredResponseSchema = z.object({
|
|
607
|
+
stored: z.literal(true),
|
|
608
|
+
});
|
|
609
|
+
export const runtimeTransferCommitRequestSchema = z.object({
|
|
610
|
+
space_id: z.string().min(1),
|
|
611
|
+
version_ids: z.array(z.string().min(1)),
|
|
612
|
+
live_version_id: z.string().nullable(),
|
|
613
|
+
});
|
|
614
|
+
export const runtimeTransferCommitResponseSchema = z.object({
|
|
615
|
+
installed: z.literal(true),
|
|
616
|
+
});
|
|
617
|
+
export const runtimeTransferAbortRequestSchema = z.object({
|
|
618
|
+
space_id: z.string().min(1),
|
|
619
|
+
});
|
|
620
|
+
export const runtimeTransferAbortResponseSchema = z.object({
|
|
621
|
+
aborted: z.boolean().optional(),
|
|
622
|
+
});
|
|
417
623
|
// Per-space generation state reported by the authed state endpoint. The
|
|
418
624
|
// reconciliation sweep compares this against control-plane expectations
|
|
419
625
|
// (space liveVersionId vs the runtime's route pointers) and repairs targeted
|
|
@@ -511,3 +717,67 @@ export const runtimeEventsDrainResponseSchema = z.object({
|
|
|
511
717
|
}))
|
|
512
718
|
.optional(),
|
|
513
719
|
});
|
|
720
|
+
// Engine job runner (plan §22, Placement V2): the box-local job runner behind
|
|
721
|
+
// the two-lane tick. The control plane creates a job, drives it with repeated
|
|
722
|
+
// ticks (kick-on-enqueue; the site-cron watchdog ticks the same route), and
|
|
723
|
+
// reads status from either the tick response or a direct GET. Field names
|
|
724
|
+
// mirror the engine's job record (§22 "Storage layout & job record").
|
|
725
|
+
export const runtimeEngineJobLaneSchema = z.enum(["interactive", "bulk"]);
|
|
726
|
+
export const runtimeEngineJobStatusSchema = z.enum(["pending", "running", "complete", "failed"]);
|
|
727
|
+
export const runtimeEngineJobErrorSchema = z.object({
|
|
728
|
+
code: z.string().min(1),
|
|
729
|
+
message: z.string().min(1),
|
|
730
|
+
});
|
|
731
|
+
export const runtimeEngineJobRecordSchema = z.object({
|
|
732
|
+
id: z.string().min(1),
|
|
733
|
+
type: z.string().min(1),
|
|
734
|
+
lane: runtimeEngineJobLaneSchema,
|
|
735
|
+
space_id: z.string().nullable().optional(),
|
|
736
|
+
operation_id: z.string().nullable().optional(),
|
|
737
|
+
status: runtimeEngineJobStatusSchema,
|
|
738
|
+
attempt: z.number().int().nonnegative().default(0),
|
|
739
|
+
max_attempts: z.number().int().positive().optional(),
|
|
740
|
+
progress: z
|
|
741
|
+
.object({
|
|
742
|
+
done: z.number().nonnegative().default(0),
|
|
743
|
+
total: z.number().nonnegative().default(0),
|
|
744
|
+
})
|
|
745
|
+
.optional(),
|
|
746
|
+
result: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
747
|
+
error: runtimeEngineJobErrorSchema.nullable().optional(),
|
|
748
|
+
created_at: z.string().optional(),
|
|
749
|
+
updated_at: z.string().optional(),
|
|
750
|
+
});
|
|
751
|
+
export const runtimeEngineJobCreateRequestSchema = z.object({
|
|
752
|
+
type: z.string().min(1),
|
|
753
|
+
payload: z.record(z.string(), z.unknown()).default({}),
|
|
754
|
+
// Unique per (type, space, operation) — create is upsert-by-key (§22).
|
|
755
|
+
idempotency_key: z.string().min(1),
|
|
756
|
+
});
|
|
757
|
+
export const runtimeEngineJobResponseSchema = z.object({
|
|
758
|
+
job: runtimeEngineJobRecordSchema,
|
|
759
|
+
});
|
|
760
|
+
// The tick response carries the ticked job's fresh state when one was
|
|
761
|
+
// claimed/advanced this call, so a driver loop can usually avoid a follow-up
|
|
762
|
+
// GET; `job` is absent/null when the lane had nothing eligible to run.
|
|
763
|
+
export const runtimeEngineJobTickResponseSchema = z.object({
|
|
764
|
+
lane: runtimeEngineJobLaneSchema,
|
|
765
|
+
job: runtimeEngineJobRecordSchema.nullable().optional(),
|
|
766
|
+
drained: z.boolean().optional(),
|
|
767
|
+
});
|
|
768
|
+
// The management pull action for the Views panel (access-plan §5.6b, X-37):
|
|
769
|
+
// `GET /access-events?file&offset&limit` — a cursor-resumed read of the
|
|
770
|
+
// runtime's own per-hostname NDJSON access-event journal. `cursor` is the
|
|
771
|
+
// position after the last returned event (feed it back verbatim); `done` is
|
|
772
|
+
// false only when the response was truncated by `limit`; `dropped` totals the
|
|
773
|
+
// writer's `.dropped` sidecars (events skipped past the per-file byte cap).
|
|
774
|
+
export const runtimeAccessEventsCursorSchema = z.object({
|
|
775
|
+
file: z.string().min(1).nullable(),
|
|
776
|
+
offset: z.number().int().nonnegative(),
|
|
777
|
+
});
|
|
778
|
+
export const runtimeAccessEventsResponseSchema = z.object({
|
|
779
|
+
events: z.array(accessEventSchema).default([]),
|
|
780
|
+
cursor: runtimeAccessEventsCursorSchema,
|
|
781
|
+
done: z.boolean(),
|
|
782
|
+
dropped: z.number().int().nonnegative().default(0),
|
|
783
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export declare const SF_CONFIG_V1_CANONICAL_FILE = "sf.jsonc";
|
|
2
|
+
export declare const SF_CONFIG_V1_FILES: readonly ["sf.jsonc", "spacefast.jsonc", "spacefast.json", "sf.json", ".sf/sf.json", ".sf/config.jsonc", ".sf/config.json"];
|
|
3
|
+
/** Published JSON Schema URL for the strict `sf.jsonc` v1 contract. */
|
|
4
|
+
export declare const SF_CONFIG_V1_SCHEMA_URL: `${string}/schemas/sf.v1.json`;
|
|
5
|
+
export type SfConfigV1 = {
|
|
6
|
+
$schema?: typeof SF_CONFIG_V1_SCHEMA_URL;
|
|
7
|
+
version: 1;
|
|
8
|
+
build?: {
|
|
9
|
+
installRoot?: string;
|
|
10
|
+
installCommand?: string;
|
|
11
|
+
command?: string;
|
|
12
|
+
output?: string;
|
|
13
|
+
timeoutSeconds?: number;
|
|
14
|
+
};
|
|
15
|
+
serve?: {
|
|
16
|
+
index?: string | false;
|
|
17
|
+
spaFallback?: string;
|
|
18
|
+
cleanUrls?: boolean;
|
|
19
|
+
directoryListing?: boolean;
|
|
20
|
+
};
|
|
21
|
+
metadata?: {
|
|
22
|
+
title?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
image?: string;
|
|
25
|
+
};
|
|
26
|
+
substitute?: {
|
|
27
|
+
files: string[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export type EffectiveConfigV1 = {
|
|
31
|
+
version: 1;
|
|
32
|
+
build?: NonNullable<SfConfigV1["build"]> & {
|
|
33
|
+
installRoot: string;
|
|
34
|
+
timeoutSeconds: number;
|
|
35
|
+
};
|
|
36
|
+
serve: {
|
|
37
|
+
index: string | false;
|
|
38
|
+
spaFallback?: string;
|
|
39
|
+
cleanUrls: boolean;
|
|
40
|
+
directoryListing: boolean;
|
|
41
|
+
};
|
|
42
|
+
metadata?: SfConfigV1["metadata"];
|
|
43
|
+
substitute?: SfConfigV1["substitute"];
|
|
44
|
+
};
|
|
45
|
+
export type SfConfigV1Issue = {
|
|
46
|
+
code: "config_alias" | "config_conflict" | "config_identity_moved" | "config_invalid" | "config_key_removed" | "config_unknown_key" | "serve_index_required" | "template_syntax_retired";
|
|
47
|
+
severity: "error" | "warning";
|
|
48
|
+
path: string;
|
|
49
|
+
line: number;
|
|
50
|
+
column: number;
|
|
51
|
+
message: string;
|
|
52
|
+
suggestion?: string;
|
|
53
|
+
};
|
|
54
|
+
export type SfConfigV1Location = Pick<SfConfigV1Issue, "line" | "column">;
|
|
55
|
+
type SfConfigV1CompileResultBase = {
|
|
56
|
+
issues: SfConfigV1Issue[];
|
|
57
|
+
locations: ReadonlyMap<string, SfConfigV1Location>;
|
|
58
|
+
};
|
|
59
|
+
export type SfConfigV1CompileResult = SfConfigV1CompileResultBase & ({
|
|
60
|
+
success: true;
|
|
61
|
+
config: SfConfigV1;
|
|
62
|
+
effective: EffectiveConfigV1;
|
|
63
|
+
} | {
|
|
64
|
+
success: false;
|
|
65
|
+
config: null;
|
|
66
|
+
effective: null;
|
|
67
|
+
});
|
|
68
|
+
export type CompileSfConfigV1Options = {
|
|
69
|
+
artifactPaths?: readonly string[];
|
|
70
|
+
templateSources?: readonly {
|
|
71
|
+
path: string;
|
|
72
|
+
source: string;
|
|
73
|
+
}[];
|
|
74
|
+
};
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BRAND } from "../brand.js";
|
|
2
|
+
import { SPACE_CONFIG_ACCEPTED_FILES, SPACE_CONFIG_CANONICAL_FILE, } from "./space-config.js";
|
|
3
|
+
export const SF_CONFIG_V1_CANONICAL_FILE = SPACE_CONFIG_CANONICAL_FILE;
|
|
4
|
+
export const SF_CONFIG_V1_FILES = SPACE_CONFIG_ACCEPTED_FILES;
|
|
5
|
+
/** Published JSON Schema URL for the strict `sf.jsonc` v1 contract. */
|
|
6
|
+
export const SF_CONFIG_V1_SCHEMA_URL = `${BRAND.websiteOrigin}/schemas/sf.v1.json`;
|
|
@@ -5,6 +5,19 @@ export declare const SiteCapacitySchema: z.ZodObject<{
|
|
|
5
5
|
storageBytes: z.ZodOptional<z.ZodNumber>;
|
|
6
6
|
}, z.core.$strip>;
|
|
7
7
|
export type SiteCapacity = z.infer<typeof SiteCapacitySchema>;
|
|
8
|
+
export declare const SitePressureSchema: z.ZodObject<{
|
|
9
|
+
ewmaLimitedPct: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
ewma429: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
ewma429PerMin: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
ewmaWorkersMax: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
ewmaCpuPct: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
lastSampleAt: z.ZodOptional<z.ZodString>;
|
|
15
|
+
consecutivePressured: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
consecutiveClean: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
pressureHoldUntil: z.ZodOptional<z.ZodString>;
|
|
18
|
+
lastBulkLaneActivityAt: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, z.core.$loose>;
|
|
20
|
+
export type SitePressure = z.infer<typeof SitePressureSchema>;
|
|
8
21
|
export declare const SiteSchema: z.ZodObject<{
|
|
9
22
|
id: z.ZodString;
|
|
10
23
|
tenantId: z.ZodString;
|
|
@@ -272,8 +285,10 @@ export declare const SuperadminSiteSchema: z.ZodObject<{
|
|
|
272
285
|
createdAt: z.ZodString;
|
|
273
286
|
updatedAt: z.ZodString;
|
|
274
287
|
class: z.ZodEnum<{
|
|
275
|
-
|
|
288
|
+
shared: "shared";
|
|
289
|
+
dedicated: "dedicated";
|
|
276
290
|
shared_org: "shared_org";
|
|
291
|
+
anonymous_pool: "anonymous_pool";
|
|
277
292
|
dedicated_space: "dedicated_space";
|
|
278
293
|
}>;
|
|
279
294
|
providerClientId: z.ZodNullable<z.ZodString>;
|
|
@@ -359,8 +374,10 @@ export declare const SuperadminSiteListSchema: z.ZodObject<{
|
|
|
359
374
|
createdAt: z.ZodString;
|
|
360
375
|
updatedAt: z.ZodString;
|
|
361
376
|
class: z.ZodEnum<{
|
|
362
|
-
|
|
377
|
+
shared: "shared";
|
|
378
|
+
dedicated: "dedicated";
|
|
363
379
|
shared_org: "shared_org";
|
|
380
|
+
anonymous_pool: "anonymous_pool";
|
|
364
381
|
dedicated_space: "dedicated_space";
|
|
365
382
|
}>;
|
|
366
383
|
providerClientId: z.ZodNullable<z.ZodString>;
|
package/dist/contracts/sites.js
CHANGED
|
@@ -26,6 +26,27 @@ export const SiteCapacitySchema = z
|
|
|
26
26
|
.describe("Storage budget for the site in bytes."),
|
|
27
27
|
})
|
|
28
28
|
.describe("Capacity accounting for shared-pool sites.");
|
|
29
|
+
export const SitePressureSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
ewmaLimitedPct: z.number().nonnegative().optional(),
|
|
32
|
+
ewma429: z.number().nonnegative().optional(),
|
|
33
|
+
ewma429PerMin: z.number().nonnegative().optional(),
|
|
34
|
+
ewmaWorkersMax: z.number().nonnegative().optional(),
|
|
35
|
+
ewmaCpuPct: z.number().nonnegative().optional(),
|
|
36
|
+
lastSampleAt: z.string().datetime().optional(),
|
|
37
|
+
consecutivePressured: z.number().int().nonnegative().optional(),
|
|
38
|
+
consecutiveClean: z.number().int().nonnegative().optional(),
|
|
39
|
+
// Provenance stamp for the sampler's automatic hold: set on trip to the
|
|
40
|
+
// exact hold instant it wrote, so release only clears holds the pressure
|
|
41
|
+
// pipeline itself set — never an operator-set placement hold.
|
|
42
|
+
pressureHoldUntil: z.string().datetime().optional(),
|
|
43
|
+
// Last time a bulk-lane engine job on this site reported activity via the
|
|
44
|
+
// job callbacks (runtime/callback-events.ts); the sampler discounts the
|
|
45
|
+
// CPU signal while this is within the sampling window.
|
|
46
|
+
lastBulkLaneActivityAt: z.string().datetime().optional(),
|
|
47
|
+
})
|
|
48
|
+
.passthrough()
|
|
49
|
+
.describe("Placement pressure signals computed outside the request path.");
|
|
29
50
|
// A Site is THE placement unit (internal-docs/platform.md "Site", `site_`):
|
|
30
51
|
// one WP.Cloud site per row. Spaces are placed onto a site via `space.siteId`.
|
|
31
52
|
// Provider linkage (`providerClientId`, `providerRef`) is operator-only and
|