@spacefast/common 0.0.24 → 0.0.26
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/LICENSE-Haskoy.txt +93 -0
- package/brand-assets/haskoy-latin-variable.woff2 +0 -0
- package/brand-assets/spacefast-favicon.svg +4 -4
- package/brand-assets/spacefast-sf-full-bleed.svg +3 -3
- package/brand-assets/spacefast-wordmark.svg +2 -4
- package/dist/agents/connect-targets.js +1 -1
- package/dist/agents/private-key-oauth.d.ts +0 -1
- package/dist/agents/private-key-oauth.js +46 -63
- package/dist/brand-assets-build.js +4 -6
- package/dist/brand-assets.d.ts +5 -15
- package/dist/brand-assets.js +15 -14
- package/dist/config/domains.d.ts +47 -7
- package/dist/config/domains.js +65 -10
- package/dist/contracts/access.d.ts +3 -3
- package/dist/contracts/activity.d.ts +1 -1
- package/dist/contracts/activity.js +5 -3
- package/dist/contracts/api-keys.js +2 -2
- package/dist/contracts/billing.d.ts +2 -1
- package/dist/contracts/billing.js +30 -0
- package/dist/contracts/builds.d.ts +34 -22
- package/dist/contracts/builds.js +18 -6
- package/dist/contracts/channels.js +1 -1
- package/dist/contracts/comments.d.ts +1 -1
- package/dist/contracts/common.d.ts +6 -6
- package/dist/contracts/common.js +5 -5
- package/dist/contracts/crons.d.ts +35 -0
- package/dist/contracts/crons.js +42 -0
- package/dist/contracts/device-auth.js +1 -1
- package/dist/contracts/docs.d.ts +5 -5
- package/dist/contracts/docs.js +2 -2
- package/dist/contracts/domains.d.ts +74 -63
- package/dist/contracts/domains.js +29 -2
- package/dist/contracts/enums.d.ts +3 -2
- package/dist/contracts/enums.js +10 -10
- package/dist/contracts/error-code-meta.d.ts +14 -0
- package/dist/contracts/error-code-meta.js +17 -0
- package/dist/contracts/error-codes.d.ts +1 -1
- package/dist/contracts/error-codes.js +4 -1
- package/dist/contracts/execution.d.ts +15 -12
- package/dist/contracts/execution.js +15 -12
- package/dist/contracts/feature-lifecycle.d.ts +4 -14
- package/dist/contracts/feature-lifecycle.js +0 -11
- package/dist/contracts/features.d.ts +33 -47
- package/dist/contracts/features.js +27 -20
- package/dist/contracts/functions.d.ts +169 -2
- package/dist/contracts/functions.js +160 -4
- package/dist/contracts/git.d.ts +27 -33
- package/dist/contracts/git.js +10 -11
- package/dist/contracts/grants.d.ts +2 -2
- package/dist/contracts/ids.js +2 -2
- package/dist/contracts/internal.d.ts +5 -16
- package/dist/contracts/internal.js +2 -12
- package/dist/contracts/mcp.d.ts +11 -0
- package/dist/contracts/mcp.js +5 -0
- package/dist/contracts/me.js +1 -1
- package/dist/contracts/operations.d.ts +4 -4
- package/dist/contracts/operations.js +2 -2
- package/dist/contracts/pages.d.ts +6 -6
- package/dist/contracts/plan-policy.d.ts +1 -1
- package/dist/contracts/plan-policy.js +1 -1
- package/dist/contracts/platform.d.ts +4 -4
- package/dist/contracts/publish-archive.d.ts +170 -160
- package/dist/contracts/publish-archive.js +8 -1
- package/dist/contracts/push-new.d.ts +4 -4
- package/dist/contracts/quotas.js +2 -2
- package/dist/contracts/repository-connections.d.ts +43 -30
- package/dist/contracts/repository-connections.js +11 -3
- package/dist/contracts/resources.d.ts +8 -8
- package/dist/contracts/resources.js +6 -6
- package/dist/contracts/runtime-api.d.ts +103 -56
- package/dist/contracts/runtime-api.js +67 -26
- package/dist/contracts/runtime-app.d.ts +2 -2
- package/dist/contracts/runtime-db.d.ts +6 -6
- package/dist/contracts/runtime-db.js +2 -2
- package/dist/contracts/runtime-purge.d.ts +8 -0
- package/dist/contracts/runtime-purge.js +7 -0
- package/dist/contracts/runtime-storage.d.ts +3 -2
- package/dist/contracts/runtime-storage.js +2 -1
- package/dist/contracts/sf-config-v1.d.ts +48 -10
- package/dist/contracts/space-config.d.ts +60 -3
- package/dist/contracts/space-config.js +213 -18
- package/dist/contracts/spaces.d.ts +55 -74
- package/dist/contracts/spaces.js +11 -14
- package/dist/contracts/superadmin-spaces.d.ts +9 -9
- package/dist/contracts/superadmin-teams.d.ts +2 -2
- package/dist/contracts/superadmin-tenants.d.ts +0 -6
- package/dist/contracts/superadmin-tenants.js +1 -7
- package/dist/contracts/superadmin.d.ts +135 -22
- package/dist/contracts/superadmin.js +43 -12
- package/dist/contracts/tags.d.ts +21 -21
- package/dist/contracts/tags.js +3 -3
- package/dist/contracts/teams.d.ts +14 -17
- package/dist/contracts/teams.js +6 -6
- package/dist/contracts/transfers.js +2 -2
- package/dist/contracts/variables.d.ts +4 -4
- package/dist/contracts/variables.js +3 -3
- package/dist/contracts/webhooks.d.ts +4 -4
- package/dist/contracts/zero.d.ts +15 -17
- package/dist/contracts/zero.js +12 -12
- package/dist/docs/agent-prose.d.ts +1 -1
- package/dist/docs/agent-prose.js +11 -14
- package/dist/docs/agent-setup.js +5 -2
- package/dist/docs/catalog.d.ts +7 -7
- package/dist/docs/catalog.js +7 -7
- package/dist/docs/error-docs.js +145 -133
- package/dist/docs/skills.d.ts +12 -12
- package/dist/docs/skills.js +4 -4
- package/dist/test-helpers/fetch-stub.js +1 -0
- package/dist/utils/build-settings.d.ts +5 -1
- package/dist/utils/build-settings.js +82 -10
- package/dist/utils/canonical-json.js +1 -0
- package/dist/utils/concurrency.js +1 -0
- package/dist/utils/credential-policy.js +4 -3
- package/dist/utils/dns-instructions.js +9 -9
- package/dist/utils/error-code.js +1 -0
- package/dist/utils/grant-decision.fixtures.json +2 -2
- package/dist/utils/grants.js +3 -1
- package/dist/utils/local-space-state.d.ts +8 -11
- package/dist/utils/local-space-state.js +13 -24
- package/dist/utils/one-shot-replay.d.ts +4 -1
- package/dist/utils/page-colors.d.ts +14 -12
- package/dist/utils/page-colors.js +15 -13
- package/dist/utils/page-fonts.d.ts +1 -1
- package/dist/utils/page-fonts.js +11 -18
- package/dist/utils/pages.d.ts +20 -1
- package/dist/utils/pages.js +22 -9
- package/dist/utils/publish-policy.d.ts +7 -0
- package/dist/utils/publish-policy.fixtures.json +11 -5
- package/dist/utils/publish-policy.js +9 -1
- package/dist/utils/query-keys.d.ts +4 -4
- package/dist/utils/query-keys.js +2 -2
- package/dist/utils/runtime-upload.d.ts +5 -0
- package/dist/utils/runtime-upload.js +7 -0
- package/dist/utils/secure-local-file.js +5 -16
- package/dist/utils/space-config.d.ts +1 -1
- package/dist/utils/space-config.js +3 -0
- package/dist/utils/static-runtime-policy.d.ts +9 -3
- package/dist/utils/static-runtime-policy.fixtures.json +38 -41
- package/dist/utils/static-runtime-policy.js +22 -56
- package/dist/utils/upload-session.d.ts +4 -1
- package/dist/utils/upload-session.js +33 -5
- package/dist/utils/version-path.js +1 -1
- package/dist/vocabulary.d.ts +8 -8
- package/dist/vocabulary.js +31 -20
- package/package.json +2 -17
|
@@ -1,44 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"phpLike": [
|
|
3
|
-
{
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{ "path": "assets/index.js", "expected": false },
|
|
32
|
-
{ "path": "assets/client-widget.js", "expected": false },
|
|
33
|
-
{ "path": "app.1a2b3c4d.css", "expected": false },
|
|
34
|
-
{ "path": "vendor.3f9a2b7e.js", "expected": false },
|
|
35
|
-
{ "path": "static/js/main.d41d8cd98f00b204e9800998.js", "expected": false },
|
|
36
|
-
{ "path": "index.html", "expected": false },
|
|
37
|
-
{ "path": "robots.txt", "expected": false },
|
|
38
|
-
{ "path": "config.xml", "expected": false },
|
|
39
|
-
{ "path": "page.php", "expected": false },
|
|
40
|
-
{ "path": "MyComponent.js", "expected": false },
|
|
41
|
-
{ "path": "image01.png", "expected": false }
|
|
3
|
+
{
|
|
4
|
+
"path": "index.php",
|
|
5
|
+
"expected": true
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"path": "nested/app.phtml",
|
|
9
|
+
"expected": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"path": "lib.phar",
|
|
13
|
+
"expected": true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "legacy.php5",
|
|
17
|
+
"expected": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "index.html",
|
|
21
|
+
"expected": false
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "assets/main.js",
|
|
25
|
+
"expected": false
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": ".env",
|
|
29
|
+
"expected": false
|
|
30
|
+
}
|
|
42
31
|
],
|
|
43
32
|
"safeContentType": [
|
|
44
33
|
{
|
|
@@ -46,12 +35,20 @@
|
|
|
46
35
|
"mime": "application/x-httpd-php",
|
|
47
36
|
"expected": "text/plain; charset=utf-8"
|
|
48
37
|
},
|
|
49
|
-
{
|
|
38
|
+
{
|
|
39
|
+
"path": "lib.phar",
|
|
40
|
+
"mime": "application/zip",
|
|
41
|
+
"expected": "application/octet-stream"
|
|
42
|
+
},
|
|
50
43
|
{
|
|
51
44
|
"path": "assets/main.js",
|
|
52
45
|
"mime": "text/javascript; charset=utf-8",
|
|
53
46
|
"expected": "text/javascript; charset=utf-8"
|
|
54
47
|
},
|
|
55
|
-
{
|
|
48
|
+
{
|
|
49
|
+
"path": "logo.svg",
|
|
50
|
+
"mime": "image/svg+xml",
|
|
51
|
+
"expected": "image/svg+xml"
|
|
52
|
+
}
|
|
56
53
|
]
|
|
57
54
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Single source of truth for static-runtime content policy: PHP-like inert
|
|
2
|
-
// classification
|
|
2
|
+
// classification and safe content-type forcing.
|
|
3
3
|
//
|
|
4
4
|
// This module is intentionally pure (no node:path, no I/O) so the exact same
|
|
5
5
|
// rules can be mechanically code-generated into the PHP runtime (runtime
|
|
@@ -30,7 +30,7 @@ export const INTERNAL_REDIRECT_RESPONSE_HEADERS = [
|
|
|
30
30
|
"x-reproxy-url",
|
|
31
31
|
"x-sendfile",
|
|
32
32
|
];
|
|
33
|
-
// Rejected/platform-managed response headers (
|
|
33
|
+
// Rejected/platform-managed response headers (the platform spec "Routing And
|
|
34
34
|
// Headers"): user `_headers` rules can never set or remove these. The
|
|
35
35
|
// internal-redirect/sendfile family above is spread in, so it stays a strict subset —
|
|
36
36
|
// anything the proxy lane refuses to relay is also refused from `_headers`. The rest is
|
|
@@ -87,52 +87,27 @@ export function isPlatformManagedResponseHeader(name) {
|
|
|
87
87
|
return (PLATFORM_MANAGED_RESPONSE_HEADER_SET.has(lower) ||
|
|
88
88
|
PLATFORM_MANAGED_RESPONSE_HEADER_PREFIXES.some((prefix) => lower.startsWith(prefix)));
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// Each prefix is HIGH-CONFIDENCE guaranteed-hashed:
|
|
106
|
-
// - `_next/static/` Next.js immutable build assets (chunks/css/media), all
|
|
107
|
-
// [contenthash]; Next itself serves this dir with `immutable`.
|
|
108
|
-
// - `_app/immutable/` SvelteKit (Vite) — the directory is literally named `immutable`
|
|
109
|
-
// and holds only fingerprinted chunks/assets.
|
|
110
|
-
// - `_nuxt/` Nuxt build dir — Vite-hashed client bundle, served from a
|
|
111
|
-
// reserved app-owned path.
|
|
112
|
-
// - `_astro/` Astro bundled assets — all content-hashed.
|
|
113
|
-
//
|
|
114
|
-
// DELIBERATELY EXCLUDED: generic user-writable dirs (Vite's `assets/`, CRA/Gatsby's
|
|
115
|
-
// `static/`). Users drop NON-hashed files there, so widening to them would create
|
|
116
|
-
// year-long false positives. Deployments of bundler output declare those dirs immutable
|
|
117
|
-
// themselves via a `_headers` rule (e.g. `/assets/*` → `Cache-Control: public,
|
|
118
|
-
// max-age=31536000, immutable`), which the publisher — a build we ran, an agent, a CI
|
|
119
|
-
// deploy — writes because it KNOWS the output is content-hashed.
|
|
120
|
-
export const GUARANTEED_IMMUTABLE_PREFIXES = [
|
|
121
|
-
"_next/static/",
|
|
122
|
-
"_app/immutable/",
|
|
123
|
-
"_nuxt/",
|
|
124
|
-
"_astro/",
|
|
125
|
-
];
|
|
126
|
-
/** True when the path lives under a framework dir where every emitted asset is content-hashed. */
|
|
127
|
-
function isUnderGuaranteedImmutablePrefix(filePath) {
|
|
128
|
-
const normalized = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
129
|
-
for (const prefix of GUARANTEED_IMMUTABLE_PREFIXES) {
|
|
130
|
-
if (normalized.startsWith(prefix)) {
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return false;
|
|
90
|
+
/**
|
|
91
|
+
* The token grammar a `_headers` rule accepts for a header NAME. The routing
|
|
92
|
+
* compiler enforces it; anything that GENERATES `_headers` rules (the Next
|
|
93
|
+
* materializer's framework sections) must gate on the same pattern, so a
|
|
94
|
+
* generated rule can never fail the author's publish.
|
|
95
|
+
*/
|
|
96
|
+
export const HEADER_RULE_NAME_PATTERN = /^[A-Za-z0-9-]+$/;
|
|
97
|
+
/** `content-type` → `Content-Type`: the casing compiled rules and generated `_headers` carry. */
|
|
98
|
+
export function canonicalHeaderName(input) {
|
|
99
|
+
return input
|
|
100
|
+
.trim()
|
|
101
|
+
.toLowerCase()
|
|
102
|
+
.split("-")
|
|
103
|
+
.map((part) => (part ? `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}` : part))
|
|
104
|
+
.join("-");
|
|
135
105
|
}
|
|
106
|
+
const PHP_LIKE_EXTENSION_SET = new Set(PHP_LIKE_EXTENSIONS);
|
|
107
|
+
// Immutable-asset detection is NOT decided here: `compiled_cache_class` in
|
|
108
|
+
// crates/stattic-runtime-core (responses.rs) is the one implementation, at
|
|
109
|
+
// finalize. A TS re-implementation lived here once, drifted from the
|
|
110
|
+
// enforcer, and was deleted rather than re-synced.
|
|
136
111
|
function lastSegment(filePath) {
|
|
137
112
|
const slash = filePath.lastIndexOf("/");
|
|
138
113
|
return slash >= 0 ? filePath.slice(slash + 1) : filePath;
|
|
@@ -152,15 +127,6 @@ export function pathStem(filePath) {
|
|
|
152
127
|
export function isPhpLikeStaticPath(filePath) {
|
|
153
128
|
return PHP_LIKE_EXTENSION_SET.has(pathExtension(filePath));
|
|
154
129
|
}
|
|
155
|
-
export function isImmutableAssetPath(filePath) {
|
|
156
|
-
if (NON_IMMUTABLE_EXTENSION_SET.has(pathExtension(filePath))) {
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
// Path-convention layer: anything under a guaranteed-content-hashed framework build
|
|
160
|
-
// dir is immutable regardless of filename. The extension gate above still applies,
|
|
161
|
-
// so an `index.html` accidentally under `_next/static/` is never pinned.
|
|
162
|
-
return isUnderGuaranteedImmutablePrefix(filePath);
|
|
163
|
-
}
|
|
164
130
|
/** Forced inert serving policy for a committed static file. PHP-like files are never executable. */
|
|
165
131
|
export function runtimeFileSafety(filePath) {
|
|
166
132
|
return {
|
|
@@ -33,8 +33,10 @@ export declare class UploadTargetError extends Error {
|
|
|
33
33
|
readonly target: UploadTarget;
|
|
34
34
|
readonly status: number;
|
|
35
35
|
readonly serverError?: UploadTargetServerError | undefined;
|
|
36
|
-
|
|
36
|
+
readonly retryAfterMs?: number | undefined;
|
|
37
|
+
constructor(target: UploadTarget, status: number, message: string, serverError?: UploadTargetServerError | undefined, retryAfterMs?: number | undefined);
|
|
37
38
|
}
|
|
39
|
+
export declare function uploadRetryAfterMs(value: string | null, now?: number): number | undefined;
|
|
38
40
|
export declare function uploadPageHasRemainder(page: UploadSession): boolean;
|
|
39
41
|
export declare const UPLOAD_STALLED_RESUME_MAX_ATTEMPTS = 3;
|
|
40
42
|
export declare function uploadQueueAdvanced(before: UploadSession, after: UploadSession | null): boolean;
|
|
@@ -42,6 +44,7 @@ export declare function executeUploadSession(input: {
|
|
|
42
44
|
session: UploadSession;
|
|
43
45
|
targets?: readonly UploadTarget[] | undefined;
|
|
44
46
|
concurrency?: number | undefined;
|
|
47
|
+
settleOnFailure?: boolean | undefined;
|
|
45
48
|
fetch?: ((...args: Parameters<typeof fetch>) => ReturnType<typeof fetch>) | undefined;
|
|
46
49
|
prepareTarget?: ((target: UploadTarget) => Promise<UploadTargetBody> | UploadTargetBody) | undefined;
|
|
47
50
|
onEvent?: ((event: UploadSessionEvent) => void) | undefined;
|
|
@@ -2,14 +2,30 @@ export class UploadTargetError extends Error {
|
|
|
2
2
|
target;
|
|
3
3
|
status;
|
|
4
4
|
serverError;
|
|
5
|
-
|
|
5
|
+
retryAfterMs;
|
|
6
|
+
constructor(target, status, message, serverError, retryAfterMs) {
|
|
6
7
|
super(message);
|
|
7
8
|
this.target = target;
|
|
8
9
|
this.status = status;
|
|
9
10
|
this.serverError = serverError;
|
|
11
|
+
this.retryAfterMs = retryAfterMs;
|
|
10
12
|
this.name = "UploadTargetError";
|
|
11
13
|
}
|
|
12
14
|
}
|
|
15
|
+
export function uploadRetryAfterMs(value, now = Date.now()) {
|
|
16
|
+
if (!value) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const seconds = Number(value);
|
|
20
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
21
|
+
return Math.ceil(seconds * 1000);
|
|
22
|
+
}
|
|
23
|
+
const date = Date.parse(value);
|
|
24
|
+
if (!Number.isFinite(date)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return Math.max(0, date - now);
|
|
28
|
+
}
|
|
13
29
|
function parseUploadTargetServerError(raw) {
|
|
14
30
|
let parsed;
|
|
15
31
|
try {
|
|
@@ -73,7 +89,7 @@ export function uploadQueueAdvanced(before, after) {
|
|
|
73
89
|
}
|
|
74
90
|
return after.targets.some((target, index) => target.path !== before.targets[index]?.path);
|
|
75
91
|
}
|
|
76
|
-
async function runConcurrent(items, concurrency, fn) {
|
|
92
|
+
async function runConcurrent(items, concurrency, settleOnFailure, fn) {
|
|
77
93
|
let nextIndex = 0;
|
|
78
94
|
const runWorker = async () => {
|
|
79
95
|
const item = items[nextIndex++];
|
|
@@ -83,7 +99,18 @@ async function runConcurrent(items, concurrency, fn) {
|
|
|
83
99
|
await fn(item);
|
|
84
100
|
return runWorker();
|
|
85
101
|
};
|
|
86
|
-
|
|
102
|
+
const workers = Array.from({
|
|
103
|
+
length: Math.min(Math.max(concurrency, 1), items.length || 1),
|
|
104
|
+
}).map(() => runWorker());
|
|
105
|
+
if (!settleOnFailure) {
|
|
106
|
+
await Promise.all(workers);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const outcomes = await Promise.allSettled(workers);
|
|
110
|
+
const failed = outcomes.find((outcome) => outcome.status === "rejected");
|
|
111
|
+
if (failed) {
|
|
112
|
+
throw failed.reason;
|
|
113
|
+
}
|
|
87
114
|
}
|
|
88
115
|
export async function executeUploadSession(input) {
|
|
89
116
|
const targets = input.targets ?? input.session.targets;
|
|
@@ -91,7 +118,8 @@ export async function executeUploadSession(input) {
|
|
|
91
118
|
return;
|
|
92
119
|
}
|
|
93
120
|
const fetchImpl = input.fetch ?? fetch;
|
|
94
|
-
|
|
121
|
+
const settleOnFailure = input.settleOnFailure ?? false;
|
|
122
|
+
await runConcurrent(targets, input.concurrency ?? 4, settleOnFailure, async (target) => {
|
|
95
123
|
input.onEvent?.({ type: "target-start", target });
|
|
96
124
|
try {
|
|
97
125
|
const prepared = input.prepareTarget
|
|
@@ -114,7 +142,7 @@ export async function executeUploadSession(input) {
|
|
|
114
142
|
const details = await response.text().catch(() => "");
|
|
115
143
|
const serverError = parseUploadTargetServerError(details);
|
|
116
144
|
const suffix = details.trim() ? `: ${details.trim().slice(0, 1_000)}` : "";
|
|
117
|
-
throw new UploadTargetError(target, response.status, `Upload failed for ${target.path} with ${response.status} ${response.statusText}${suffix}.`, serverError);
|
|
145
|
+
throw new UploadTargetError(target, response.status, `Upload failed for ${target.path} with ${response.status} ${response.statusText}${suffix}.`, serverError, uploadRetryAfterMs(response.headers.get("retry-after")));
|
|
118
146
|
}
|
|
119
147
|
input.onEvent?.({ type: "target-done", target });
|
|
120
148
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Canonical object-path form (
|
|
1
|
+
// Canonical object-path form (the platform spec "Upload Contract"):
|
|
2
2
|
// UTF-8, Unicode NFC, percent-decoded exactly once. This canonical form is
|
|
3
3
|
// what manifest paths, finalize's normalized paths, route-map keys, and dedup
|
|
4
4
|
// keys all mean. The PHP runtime applies the same transform (rawurldecode once
|
package/dist/vocabulary.d.ts
CHANGED
|
@@ -104,8 +104,8 @@ export declare const CONCEPTS: {
|
|
|
104
104
|
readonly id: "infra";
|
|
105
105
|
readonly canonicalNoun: "infra";
|
|
106
106
|
readonly aliases: readonly ["infrastructure"];
|
|
107
|
-
readonly externalTerms: readonly ["WP
|
|
108
|
-
readonly deprecated: readonly ["code.storage", "Pierre"];
|
|
107
|
+
readonly externalTerms: readonly ["WP Cloud"];
|
|
108
|
+
readonly deprecated: readonly ["code.storage", "Pierre", "the hosting provider"];
|
|
109
109
|
readonly description: string;
|
|
110
110
|
};
|
|
111
111
|
};
|
|
@@ -143,10 +143,10 @@ export declare const EXTERNAL_TERM_ALLOWLIST: readonly [{
|
|
|
143
143
|
readonly replacement: "space";
|
|
144
144
|
readonly reason: string;
|
|
145
145
|
}, {
|
|
146
|
-
readonly term: "WP
|
|
146
|
+
readonly term: "WP Cloud";
|
|
147
147
|
readonly concept: "infra";
|
|
148
|
-
readonly allowedContexts: readonly ["
|
|
149
|
-
readonly allowedPhrases: readonly ["
|
|
148
|
+
readonly allowedContexts: readonly ["fixed-phrase"];
|
|
149
|
+
readonly allowedPhrases: readonly ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"];
|
|
150
150
|
readonly replacement: "infra";
|
|
151
151
|
readonly reason: string;
|
|
152
152
|
}];
|
|
@@ -208,10 +208,10 @@ export declare const PROVIDER_HYGIENE: {
|
|
|
208
208
|
readonly reason: "The build sandbox vendor is never named; it is 'Spacefast Builds'.";
|
|
209
209
|
};
|
|
210
210
|
readonly wpcloud: {
|
|
211
|
-
readonly internalName: "WP
|
|
211
|
+
readonly internalName: "WP Cloud";
|
|
212
212
|
readonly replacement: "infra";
|
|
213
|
-
readonly allowedContexts: readonly ["
|
|
214
|
-
readonly allowedPhrases: readonly ["
|
|
213
|
+
readonly allowedContexts: readonly ["fixed-phrase"];
|
|
214
|
+
readonly allowedPhrases: readonly ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"];
|
|
215
215
|
readonly reason: string;
|
|
216
216
|
};
|
|
217
217
|
readonly codeStorage: {
|
package/dist/vocabulary.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
//
|
|
11
11
|
// - `space` is the primitive noun everywhere, user surfaces and platform API
|
|
12
12
|
// alike. A space IS a site: there is no second host entity to name. `site`
|
|
13
|
-
// survives only as WP
|
|
13
|
+
// survives only as WP Cloud's own word for the box, in operator surfaces
|
|
14
14
|
// and the warm-pool inventory.
|
|
15
15
|
// - `publish` is the verb. AMENDED 2026-07-02: `deploy` / `deployments` are
|
|
16
16
|
// first-class ALIASES of `publish` / `versions` (see DEPLOY_ALIASES) — they
|
|
@@ -22,10 +22,14 @@
|
|
|
22
22
|
// - `API key` — never "access token".
|
|
23
23
|
// - `Collab` is the feature; `comment` is the unit.
|
|
24
24
|
// - `Superpowers` is the page-enhancement feature.
|
|
25
|
-
// - Provider names
|
|
26
|
-
// Builds" / "Spacefast CI"), never "
|
|
27
|
-
//
|
|
28
|
-
//
|
|
25
|
+
// - Provider names stay off public surfaces by default: never "E2B" (say
|
|
26
|
+
// "Spacefast Builds" / "Spacefast CI"), never "code.storage" / "Pierre".
|
|
27
|
+
// The infra brand is "WP Cloud" — never "WP.Cloud"/"wp-cloud" (AMENDED
|
|
28
|
+
// 2026-08-13). Prefer "infra"; when an external reference is genuinely
|
|
29
|
+
// necessary (provider identity fields, domain conflicts), name WP Cloud
|
|
30
|
+
// outright — NEVER the euphemism "the hosting provider". Marketing may use
|
|
31
|
+
// the family line "the same infra as Automattic, WP Cloud, Pressable, and
|
|
32
|
+
// WordPress.com" (see PROVIDER_HYGIENE).
|
|
29
33
|
export const CONCEPTS = {
|
|
30
34
|
space: {
|
|
31
35
|
id: "space",
|
|
@@ -102,10 +106,11 @@ export const CONCEPTS = {
|
|
|
102
106
|
id: "infra",
|
|
103
107
|
canonicalNoun: "infra",
|
|
104
108
|
aliases: ["infrastructure"],
|
|
105
|
-
externalTerms: ["WP
|
|
106
|
-
deprecated: ["code.storage", "Pierre"],
|
|
107
|
-
description: "The hosting substrate.
|
|
108
|
-
"
|
|
109
|
+
externalTerms: ["WP Cloud"],
|
|
110
|
+
deprecated: ["code.storage", "Pierre", "the hosting provider"],
|
|
111
|
+
description: "The hosting substrate. Prefer 'infra'; when an external reference is " +
|
|
112
|
+
"necessary, name 'WP Cloud' (its real spelling) — never the euphemism " +
|
|
113
|
+
"'the hosting provider'. Never 'code.storage'/'Pierre'.",
|
|
109
114
|
},
|
|
110
115
|
};
|
|
111
116
|
export const EXTERNAL_TERM_ALLOWLIST = [
|
|
@@ -134,17 +139,21 @@ export const EXTERNAL_TERM_ALLOWLIST = [
|
|
|
134
139
|
allowedContexts: ["operator"],
|
|
135
140
|
replacement: "space",
|
|
136
141
|
reason: "A space IS a site, so 'site' is no longer a Spacefast noun — it is only " +
|
|
137
|
-
"WP
|
|
142
|
+
"WP Cloud's word for the box, which operator surfaces and warm-pool " +
|
|
138
143
|
"inventory may use. Every customer-facing surface says 'space'.",
|
|
139
144
|
},
|
|
140
145
|
{
|
|
141
|
-
term: "WP
|
|
146
|
+
term: "WP Cloud",
|
|
142
147
|
concept: "infra",
|
|
143
|
-
allowedContexts: ["
|
|
144
|
-
allowedPhrases: ["
|
|
148
|
+
allowedContexts: ["fixed-phrase"],
|
|
149
|
+
allowedPhrases: ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"],
|
|
145
150
|
replacement: "infra",
|
|
146
|
-
reason: "
|
|
147
|
-
"
|
|
151
|
+
reason: "AMENDED 2026-08-13: prefer 'infra'. Same day: the platform-api " +
|
|
152
|
+
"carve-out is revoked — API values say mysql/phpmyadmin/infra, never " +
|
|
153
|
+
"wpcloud. Name WP Cloud (its real spelling — never 'WP.Cloud') only " +
|
|
154
|
+
"where the external reference is necessary: domain-conflict copy and " +
|
|
155
|
+
"the marketing family line in allowedPhrases. Never the euphemism " +
|
|
156
|
+
"'the hosting provider'.",
|
|
148
157
|
},
|
|
149
158
|
];
|
|
150
159
|
export const DEPLOY_ALIASES = [
|
|
@@ -167,12 +176,14 @@ export const PROVIDER_HYGIENE = {
|
|
|
167
176
|
reason: "The build sandbox vendor is never named; it is 'Spacefast Builds'.",
|
|
168
177
|
},
|
|
169
178
|
wpcloud: {
|
|
170
|
-
internalName: "WP
|
|
179
|
+
internalName: "WP Cloud",
|
|
171
180
|
replacement: "infra",
|
|
172
|
-
allowedContexts: ["
|
|
173
|
-
allowedPhrases: ["
|
|
174
|
-
reason: "Hosting substrate;
|
|
175
|
-
"
|
|
181
|
+
allowedContexts: ["fixed-phrase"],
|
|
182
|
+
allowedPhrases: ["the same infra as Automattic, WP Cloud, Pressable, and WordPress.com"],
|
|
183
|
+
reason: "Hosting substrate; prefer 'infra' (AMENDED 2026-08-13, same day: the " +
|
|
184
|
+
"platform-api carve-out is revoked — API values say mysql/phpmyadmin/" +
|
|
185
|
+
"infra, never wpcloud). Necessary external references name WP Cloud " +
|
|
186
|
+
"outright — never 'the hosting provider'.",
|
|
176
187
|
},
|
|
177
188
|
codeStorage: {
|
|
178
189
|
internalName: "code.storage",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spacefast/common",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Shared TypeScript contracts and utilities for Spacefast packages.",
|
|
6
6
|
"repository": {
|
|
@@ -20,22 +20,6 @@
|
|
|
20
20
|
"brand-assets",
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
|
-
"spacefastTestCache": {
|
|
24
|
-
"mode": "hermetic",
|
|
25
|
-
"inputs": [
|
|
26
|
-
"../../apps/www/dist/.well-known/agent-card.json",
|
|
27
|
-
"../../apps/www/dist/ai.txt",
|
|
28
|
-
"../../apps/www/dist/llms-full.txt",
|
|
29
|
-
"../../apps/www/dist/llms.txt",
|
|
30
|
-
"../cli/skill.template.md",
|
|
31
|
-
"../cli/skill.references.template.md",
|
|
32
|
-
"../cli/scripts/generate-skill.mjs",
|
|
33
|
-
"../../e2e-tests/fixtures/zero-all-features/api-finalize-request.json",
|
|
34
|
-
"../../e2e-tests/fixtures/zero-all-features/runtime-compiler-finalize-input.json",
|
|
35
|
-
"../../runtime/engine/shared/fonts",
|
|
36
|
-
"src/docs/agent-prose.ts"
|
|
37
|
-
]
|
|
38
|
-
},
|
|
39
23
|
"exports": {
|
|
40
24
|
"./brand": {
|
|
41
25
|
"types": "./dist/brand.d.ts",
|
|
@@ -116,6 +100,7 @@
|
|
|
116
100
|
"culori": "^4.0.2",
|
|
117
101
|
"js-yaml": "^4.1.1",
|
|
118
102
|
"mime": "^4.1.0",
|
|
103
|
+
"oauth4webapi": "3.8.7",
|
|
119
104
|
"parse5": "^7.3.0",
|
|
120
105
|
"smol-toml": "^1.7.0",
|
|
121
106
|
"zod": "^4.4.3"
|