@spacefast/common 0.0.2
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/README.md +42 -0
- package/dist/brand.d.ts +15 -0
- package/dist/brand.js +24 -0
- package/dist/config/domains.d.ts +30 -0
- package/dist/config/domains.js +75 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +3 -0
- package/dist/contracts/abuse.d.ts +93 -0
- package/dist/contracts/abuse.js +50 -0
- package/dist/contracts/access.d.ts +409 -0
- package/dist/contracts/access.js +396 -0
- package/dist/contracts/account.d.ts +28 -0
- package/dist/contracts/account.js +54 -0
- package/dist/contracts/activity.d.ts +118 -0
- package/dist/contracts/activity.js +180 -0
- package/dist/contracts/analytics.d.ts +56 -0
- package/dist/contracts/analytics.js +91 -0
- package/dist/contracts/annotations.d.ts +327 -0
- package/dist/contracts/annotations.js +234 -0
- package/dist/contracts/api-keys.d.ts +517 -0
- package/dist/contracts/api-keys.js +235 -0
- package/dist/contracts/archives.d.ts +332 -0
- package/dist/contracts/archives.js +120 -0
- package/dist/contracts/auth.d.ts +86 -0
- package/dist/contracts/auth.js +82 -0
- package/dist/contracts/beta.d.ts +106 -0
- package/dist/contracts/beta.js +104 -0
- package/dist/contracts/billing.d.ts +328 -0
- package/dist/contracts/billing.js +203 -0
- package/dist/contracts/builds.d.ts +504 -0
- package/dist/contracts/builds.js +248 -0
- package/dist/contracts/channels.d.ts +49 -0
- package/dist/contracts/channels.js +51 -0
- package/dist/contracts/common.d.ts +238 -0
- package/dist/contracts/common.js +175 -0
- package/dist/contracts/deployments.d.ts +574 -0
- package/dist/contracts/deployments.js +97 -0
- package/dist/contracts/device-auth.d.ts +194 -0
- package/dist/contracts/device-auth.js +162 -0
- package/dist/contracts/domains.d.ts +6115 -0
- package/dist/contracts/domains.js +1435 -0
- package/dist/contracts/enums.d.ts +196 -0
- package/dist/contracts/enums.js +211 -0
- package/dist/contracts/error-code-meta.d.ts +1560 -0
- package/dist/contracts/error-code-meta.js +400 -0
- package/dist/contracts/error-codes.d.ts +13 -0
- package/dist/contracts/error-codes.js +416 -0
- package/dist/contracts/events.d.ts +398 -0
- package/dist/contracts/events.js +320 -0
- package/dist/contracts/fast-domain-search.d.ts +19 -0
- package/dist/contracts/fast-domain-search.js +22 -0
- package/dist/contracts/features.d.ts +240 -0
- package/dist/contracts/features.js +406 -0
- package/dist/contracts/git.d.ts +288 -0
- package/dist/contracts/git.js +116 -0
- package/dist/contracts/ids.d.ts +35 -0
- package/dist/contracts/ids.js +45 -0
- package/dist/contracts/intercom.d.ts +6 -0
- package/dist/contracts/intercom.js +5 -0
- package/dist/contracts/internal.d.ts +103 -0
- package/dist/contracts/internal.js +92 -0
- package/dist/contracts/mcp.d.ts +788 -0
- package/dist/contracts/mcp.js +161 -0
- package/dist/contracts/me.d.ts +81 -0
- package/dist/contracts/me.js +104 -0
- package/dist/contracts/oauth-resources.d.ts +30 -0
- package/dist/contracts/oauth-resources.js +61 -0
- package/dist/contracts/operations.d.ts +54 -0
- package/dist/contracts/operations.js +14 -0
- package/dist/contracts/plan-policy.d.ts +85 -0
- package/dist/contracts/plan-policy.js +75 -0
- package/dist/contracts/platform.d.ts +359 -0
- package/dist/contracts/platform.js +216 -0
- package/dist/contracts/push-new.d.ts +156 -0
- package/dist/contracts/push-new.js +52 -0
- package/dist/contracts/quotas.d.ts +16 -0
- package/dist/contracts/quotas.js +36 -0
- package/dist/contracts/repository-connections.d.ts +231 -0
- package/dist/contracts/repository-connections.js +106 -0
- package/dist/contracts/resources.d.ts +529 -0
- package/dist/contracts/resources.js +209 -0
- package/dist/contracts/routes.d.ts +45 -0
- package/dist/contracts/routes.js +31 -0
- package/dist/contracts/runtime-api.d.ts +449 -0
- package/dist/contracts/runtime-api.js +513 -0
- package/dist/contracts/sites.d.ts +393 -0
- package/dist/contracts/sites.js +121 -0
- package/dist/contracts/slugs.d.ts +31 -0
- package/dist/contracts/slugs.js +47 -0
- package/dist/contracts/space-config.d.ts +216 -0
- package/dist/contracts/space-config.js +237 -0
- package/dist/contracts/space-theme.d.ts +25 -0
- package/dist/contracts/space-theme.js +49 -0
- package/dist/contracts/spaces.d.ts +2760 -0
- package/dist/contracts/spaces.js +589 -0
- package/dist/contracts/superadmin-activity.d.ts +205 -0
- package/dist/contracts/superadmin-activity.js +107 -0
- package/dist/contracts/superadmin-emails.d.ts +212 -0
- package/dist/contracts/superadmin-emails.js +112 -0
- package/dist/contracts/superadmin-queues.d.ts +414 -0
- package/dist/contracts/superadmin-queues.js +202 -0
- package/dist/contracts/superadmin-runtime.d.ts +27 -0
- package/dist/contracts/superadmin-runtime.js +38 -0
- package/dist/contracts/superadmin-spaces.d.ts +429 -0
- package/dist/contracts/superadmin-spaces.js +82 -0
- package/dist/contracts/superadmin-tenants.d.ts +180 -0
- package/dist/contracts/superadmin-tenants.js +117 -0
- package/dist/contracts/superadmin.d.ts +654 -0
- package/dist/contracts/superadmin.js +309 -0
- package/dist/contracts/tags.d.ts +1140 -0
- package/dist/contracts/tags.js +1050 -0
- package/dist/contracts/teams.d.ts +233 -0
- package/dist/contracts/teams.js +174 -0
- package/dist/contracts/telemetry.d.ts +2 -0
- package/dist/contracts/telemetry.js +1 -0
- package/dist/contracts/transfers.d.ts +105 -0
- package/dist/contracts/transfers.js +48 -0
- package/dist/contracts/variables.d.ts +189 -0
- package/dist/contracts/variables.js +82 -0
- package/dist/contracts/webhooks.d.ts +159 -0
- package/dist/contracts/webhooks.js +59 -0
- package/dist/contracts/zero.d.ts +1538 -0
- package/dist/contracts/zero.js +755 -0
- package/dist/docs/agent-prose.d.ts +35 -0
- package/dist/docs/agent-prose.js +153 -0
- package/dist/docs/agent-setup.d.ts +6 -0
- package/dist/docs/agent-setup.js +164 -0
- package/dist/docs/agent-solutions.d.ts +110 -0
- package/dist/docs/agent-solutions.js +181 -0
- package/dist/docs/error-docs.d.ts +12 -0
- package/dist/docs/error-docs.js +1601 -0
- package/dist/docs/skill-distribution.d.ts +12 -0
- package/dist/docs/skill-distribution.js +18 -0
- package/dist/domain-exploration.d.ts +108 -0
- package/dist/domain-exploration.js +488 -0
- package/dist/domain-normalize.d.ts +1 -0
- package/dist/domain-normalize.js +14 -0
- package/dist/domain-zones.d.ts +1 -0
- package/dist/domain-zones.js +5272 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/access-policy.d.ts +39 -0
- package/dist/utils/access-policy.js +232 -0
- package/dist/utils/api.d.ts +4 -0
- package/dist/utils/api.js +13 -0
- package/dist/utils/auth-redirect.d.ts +1 -0
- package/dist/utils/auth-redirect.js +48 -0
- package/dist/utils/auth.d.ts +5 -0
- package/dist/utils/auth.js +13 -0
- package/dist/utils/build-settings.d.ts +49 -0
- package/dist/utils/build-settings.js +366 -0
- package/dist/utils/claim-token.d.ts +1 -0
- package/dist/utils/claim-token.js +9 -0
- package/dist/utils/collections.d.ts +1 -0
- package/dist/utils/collections.js +5 -0
- package/dist/utils/concurrency.d.ts +1 -0
- package/dist/utils/concurrency.js +18 -0
- package/dist/utils/content-type.d.ts +10 -0
- package/dist/utils/content-type.js +145 -0
- package/dist/utils/error-display.d.ts +7 -0
- package/dist/utils/error-display.js +42 -0
- package/dist/utils/error.d.ts +1 -0
- package/dist/utils/error.js +3 -0
- package/dist/utils/generate-space-name.d.ts +14 -0
- package/dist/utils/generate-space-name.js +95 -0
- package/dist/utils/git-repository.d.ts +5 -0
- package/dist/utils/git-repository.js +99 -0
- package/dist/utils/guards.d.ts +1 -0
- package/dist/utils/guards.js +3 -0
- package/dist/utils/publish-detection.d.ts +10 -0
- package/dist/utils/publish-detection.js +118 -0
- package/dist/utils/publish-policy.d.ts +69 -0
- package/dist/utils/publish-policy.js +429 -0
- package/dist/utils/query-client.d.ts +7 -0
- package/dist/utils/query-client.js +21 -0
- package/dist/utils/query-keys.d.ts +75 -0
- package/dist/utils/query-keys.js +78 -0
- package/dist/utils/runtime-paths.d.ts +7 -0
- package/dist/utils/runtime-paths.js +28 -0
- package/dist/utils/runtime-upload.d.ts +19 -0
- package/dist/utils/runtime-upload.js +27 -0
- package/dist/utils/slug.d.ts +5 -0
- package/dist/utils/slug.js +13 -0
- package/dist/utils/space-config.d.ts +75 -0
- package/dist/utils/space-config.js +415 -0
- package/dist/utils/space-theme.d.ts +16 -0
- package/dist/utils/space-theme.js +89 -0
- package/dist/utils/static-runtime-policy.d.ts +17 -0
- package/dist/utils/static-runtime-policy.js +103 -0
- package/dist/utils/upload-session.d.ts +34 -0
- package/dist/utils/upload-session.js +69 -0
- package/dist/utils/urls.d.ts +2 -0
- package/dist/utils/urls.js +7 -0
- package/dist/utils/version-path.d.ts +6 -0
- package/dist/utils/version-path.js +51 -0
- package/dist/utils/wpcom-auth-redirects.d.ts +14 -0
- package/dist/utils/wpcom-auth-redirects.js +49 -0
- package/dist/utils/zero-realtime-signature.d.ts +12 -0
- package/dist/utils/zero-realtime-signature.js +45 -0
- package/dist/vocabulary.d.ts +230 -0
- package/dist/vocabulary.js +218 -0
- package/package.json +58 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { parse as parseToml } from "smol-toml";
|
|
2
|
+
export const BUILD_ANALYZER_CANDIDATE_ROOTS = ["apps", "packages", "sites", "docs"];
|
|
3
|
+
const PACKAGE_MANAGER_ONLY_FILES = new Set([
|
|
4
|
+
"package.json",
|
|
5
|
+
"bun.lock",
|
|
6
|
+
"bun.lockb",
|
|
7
|
+
"pnpm-lock.yaml",
|
|
8
|
+
"yarn.lock",
|
|
9
|
+
"package-lock.json",
|
|
10
|
+
]);
|
|
11
|
+
export function hasWorkspaceSignal(fileNames, packageJsonText) {
|
|
12
|
+
const names = new Set(fileNames);
|
|
13
|
+
if (names.has("pnpm-workspace.yaml") ||
|
|
14
|
+
names.has("turbo.json") ||
|
|
15
|
+
names.has("nx.json") ||
|
|
16
|
+
names.has("lerna.json")) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (!packageJsonText) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(packageJsonText);
|
|
24
|
+
return (Array.isArray(parsed.workspaces) ||
|
|
25
|
+
(parsed.workspaces &&
|
|
26
|
+
typeof parsed.workspaces === "object" &&
|
|
27
|
+
Array.isArray(parsed.workspaces.packages)));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function rankBuildAnalyzerCandidate(input) {
|
|
34
|
+
const names = new Set(input.fileNames);
|
|
35
|
+
const reasons = [];
|
|
36
|
+
let confidence = 0;
|
|
37
|
+
if (input.detected.platformPreset) {
|
|
38
|
+
confidence += 40;
|
|
39
|
+
reasons.push(`${input.detected.platformPreset} config`);
|
|
40
|
+
}
|
|
41
|
+
if (input.detected.frameworkPreset) {
|
|
42
|
+
confidence += 30;
|
|
43
|
+
reasons.push(`${input.detected.frameworkPreset} framework`);
|
|
44
|
+
}
|
|
45
|
+
if (input.detected.buildCommand) {
|
|
46
|
+
confidence += 20;
|
|
47
|
+
reasons.push("build script");
|
|
48
|
+
}
|
|
49
|
+
if (names.has("index.html")) {
|
|
50
|
+
confidence += 8;
|
|
51
|
+
reasons.push("static index");
|
|
52
|
+
}
|
|
53
|
+
if (input.rootDirectory === null) {
|
|
54
|
+
confidence += 2;
|
|
55
|
+
reasons.push("repository root");
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
confidence += 5;
|
|
59
|
+
reasons.push("workspace app directory");
|
|
60
|
+
}
|
|
61
|
+
return { confidence, reasons };
|
|
62
|
+
}
|
|
63
|
+
export function hasBuildAnalyzerCandidateSignal(input) {
|
|
64
|
+
const names = new Set(input.fileNames);
|
|
65
|
+
return (input.detected.detectedFiles.some((file) => !PACKAGE_MANAGER_ONLY_FILES.has(file)) ||
|
|
66
|
+
input.detected.frameworkPreset !== null ||
|
|
67
|
+
input.detected.platformPreset !== null ||
|
|
68
|
+
input.detected.buildCommand !== null ||
|
|
69
|
+
names.has("index.html"));
|
|
70
|
+
}
|
|
71
|
+
function parseJsonObject(value) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(value);
|
|
77
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
78
|
+
? parsed
|
|
79
|
+
: null;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function parseJsonObjectWithComments(value) {
|
|
86
|
+
return parseJsonObject(value
|
|
87
|
+
?.replace(/^\uFEFF/, "")
|
|
88
|
+
.replace(/(^|[^:])\/\/.*$/gm, "$1")
|
|
89
|
+
.replace(/\/\*[\s\S]*?\*\//g, ""));
|
|
90
|
+
}
|
|
91
|
+
function parseTomlObject(value) {
|
|
92
|
+
if (!value) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const parsed = parseToml(value);
|
|
97
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
98
|
+
? parsed
|
|
99
|
+
: null;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function stringField(value, key) {
|
|
106
|
+
const field = value?.[key];
|
|
107
|
+
return typeof field === "string" && field.trim() ? field.trim() : null;
|
|
108
|
+
}
|
|
109
|
+
export function numberField(value, key) {
|
|
110
|
+
const field = value?.[key];
|
|
111
|
+
return typeof field === "number" ? field : null;
|
|
112
|
+
}
|
|
113
|
+
function objectField(value, key) {
|
|
114
|
+
const field = value?.[key];
|
|
115
|
+
return field && typeof field === "object" && !Array.isArray(field)
|
|
116
|
+
? field
|
|
117
|
+
: null;
|
|
118
|
+
}
|
|
119
|
+
function arrayField(value, key) {
|
|
120
|
+
const field = value?.[key];
|
|
121
|
+
return Array.isArray(field)
|
|
122
|
+
? field.filter((entry) => entry !== null && typeof entry === "object" && !Array.isArray(entry))
|
|
123
|
+
: [];
|
|
124
|
+
}
|
|
125
|
+
function vercelConfig(value) {
|
|
126
|
+
const config = parseJsonObjectWithComments(value);
|
|
127
|
+
if (!config) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
platform: "vercel",
|
|
132
|
+
rootDirectory: stringField(config, "rootDirectory"),
|
|
133
|
+
installDirectory: null,
|
|
134
|
+
installCommand: stringField(config, "installCommand"),
|
|
135
|
+
buildCommand: stringField(config, "buildCommand"),
|
|
136
|
+
outputDirectory: stringField(config, "outputDirectory"),
|
|
137
|
+
redirects: arrayField(config, "redirects"),
|
|
138
|
+
rewrites: arrayField(config, "rewrites"),
|
|
139
|
+
headers: arrayField(config, "headers"),
|
|
140
|
+
unsupportedFeatures: [
|
|
141
|
+
...("functions" in config ? ["Vercel functions are not converted."] : []),
|
|
142
|
+
...("middleware" in config ? ["Vercel middleware is not converted."] : []),
|
|
143
|
+
...("images" in config ? ["Vercel image optimization config is not converted."] : []),
|
|
144
|
+
...("crons" in config ? ["Vercel cron jobs are not converted."] : []),
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function netlifyConfig(value) {
|
|
149
|
+
const config = parseTomlObject(value);
|
|
150
|
+
if (!config) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const build = objectField(config, "build");
|
|
154
|
+
return {
|
|
155
|
+
platform: "netlify",
|
|
156
|
+
rootDirectory: stringField(build, "base") ?? stringField(config, "base"),
|
|
157
|
+
installDirectory: null,
|
|
158
|
+
installCommand: null,
|
|
159
|
+
buildCommand: stringField(build, "command"),
|
|
160
|
+
outputDirectory: stringField(build, "publish"),
|
|
161
|
+
redirects: arrayField(config, "redirects"),
|
|
162
|
+
rewrites: [],
|
|
163
|
+
headers: arrayField(config, "headers"),
|
|
164
|
+
unsupportedFeatures: [
|
|
165
|
+
...("functions" in config ? ["Netlify functions are not converted."] : []),
|
|
166
|
+
...("edge_functions" in config ? ["Netlify edge functions are not converted."] : []),
|
|
167
|
+
...("plugins" in config ? ["Netlify build plugins are not converted."] : []),
|
|
168
|
+
...("processing" in config ? ["Netlify post-processing config is not converted."] : []),
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function cloudflarePagesConfig(input) {
|
|
173
|
+
const toml = parseTomlObject(input.wranglerToml);
|
|
174
|
+
const json = parseJsonObjectWithComments(input.wranglerJson);
|
|
175
|
+
const config = json ?? toml;
|
|
176
|
+
if (!config) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const build = objectField(config, "build");
|
|
180
|
+
const assets = objectField(config, "assets");
|
|
181
|
+
const unsupportedFeatures = [
|
|
182
|
+
...("main" in config ? ["Cloudflare Worker entrypoints are not converted."] : []),
|
|
183
|
+
...("kv_namespaces" in config ||
|
|
184
|
+
"r2_buckets" in config ||
|
|
185
|
+
"d1_databases" in config ||
|
|
186
|
+
"durable_objects" in config ||
|
|
187
|
+
"services" in config ||
|
|
188
|
+
"queues" in config ||
|
|
189
|
+
"vars" in config
|
|
190
|
+
? ["Wrangler bindings are not converted."]
|
|
191
|
+
: []),
|
|
192
|
+
...(assets && "run_worker_first" in assets
|
|
193
|
+
? ["Cloudflare Worker-first static asset routing is not converted."]
|
|
194
|
+
: []),
|
|
195
|
+
...(assets && "not_found_handling" in assets
|
|
196
|
+
? ["Cloudflare static asset not-found handling is not converted."]
|
|
197
|
+
: []),
|
|
198
|
+
];
|
|
199
|
+
return {
|
|
200
|
+
platform: "cloudflare-pages",
|
|
201
|
+
rootDirectory: null,
|
|
202
|
+
installDirectory: null,
|
|
203
|
+
installCommand: null,
|
|
204
|
+
buildCommand: stringField(config, "command") ?? stringField(build, "command"),
|
|
205
|
+
outputDirectory: stringField(assets, "directory") ?? stringField(config, "pages_build_output_dir"),
|
|
206
|
+
redirects: [],
|
|
207
|
+
rewrites: [],
|
|
208
|
+
headers: [],
|
|
209
|
+
unsupportedFeatures,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export function detectPlatformConfigs(input) {
|
|
213
|
+
return [
|
|
214
|
+
vercelConfig(input.vercelJson),
|
|
215
|
+
netlifyConfig(input.netlifyToml),
|
|
216
|
+
cloudflarePagesConfig(input),
|
|
217
|
+
].filter((config) => Boolean(config));
|
|
218
|
+
}
|
|
219
|
+
function parsePackageJson(value) {
|
|
220
|
+
const parsed = parseJsonObject(value);
|
|
221
|
+
if (!parsed) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const scripts = parsed.scripts;
|
|
225
|
+
const dependencies = parsed.dependencies;
|
|
226
|
+
const devDependencies = parsed.devDependencies;
|
|
227
|
+
return {
|
|
228
|
+
scripts: scripts && typeof scripts === "object" ? scripts : {},
|
|
229
|
+
dependencies: dependencies && typeof dependencies === "object"
|
|
230
|
+
? dependencies
|
|
231
|
+
: {},
|
|
232
|
+
devDependencies: devDependencies && typeof devDependencies === "object"
|
|
233
|
+
? devDependencies
|
|
234
|
+
: {},
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function packageManagerForFiles(files) {
|
|
238
|
+
if (files.has("bun.lock") || files.has("bun.lockb"))
|
|
239
|
+
return "bun";
|
|
240
|
+
if (files.has("pnpm-lock.yaml"))
|
|
241
|
+
return "pnpm";
|
|
242
|
+
if (files.has("yarn.lock"))
|
|
243
|
+
return "yarn";
|
|
244
|
+
return "npm";
|
|
245
|
+
}
|
|
246
|
+
function detectFrameworkPreset(files, dependencies) {
|
|
247
|
+
if ("next" in dependencies)
|
|
248
|
+
return "next";
|
|
249
|
+
if ("@tanstack/react-start" in dependencies)
|
|
250
|
+
return "tanstack-start";
|
|
251
|
+
if ("vite" in dependencies)
|
|
252
|
+
return "vite";
|
|
253
|
+
if ("astro" in dependencies)
|
|
254
|
+
return "astro";
|
|
255
|
+
if ("@sveltejs/kit" in dependencies)
|
|
256
|
+
return "sveltekit";
|
|
257
|
+
if ("gatsby" in dependencies)
|
|
258
|
+
return "gatsby";
|
|
259
|
+
if ("@remix-run/dev" in dependencies)
|
|
260
|
+
return "remix";
|
|
261
|
+
if ("@docusaurus/core" in dependencies)
|
|
262
|
+
return "docusaurus";
|
|
263
|
+
if (files.has("hugo.toml") || files.has("config.toml"))
|
|
264
|
+
return "hugo";
|
|
265
|
+
if (files.has("_config.yml") || files.has("_config.yaml"))
|
|
266
|
+
return "jekyll";
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
function outputDirectoryForFramework(frameworkPreset, files) {
|
|
270
|
+
switch (frameworkPreset) {
|
|
271
|
+
case "next":
|
|
272
|
+
return "out";
|
|
273
|
+
case "tanstack-start":
|
|
274
|
+
return "dist/client";
|
|
275
|
+
case "gatsby":
|
|
276
|
+
return "public";
|
|
277
|
+
case "sveltekit":
|
|
278
|
+
return "build";
|
|
279
|
+
case "remix":
|
|
280
|
+
return "build/client";
|
|
281
|
+
case "docusaurus":
|
|
282
|
+
return "build";
|
|
283
|
+
case "hugo":
|
|
284
|
+
return "public";
|
|
285
|
+
case "jekyll":
|
|
286
|
+
return "_site";
|
|
287
|
+
default:
|
|
288
|
+
return files.has("dist") ? "dist" : null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function installCommandForManager(packageManager, packageJson) {
|
|
292
|
+
switch (packageManager) {
|
|
293
|
+
case "bun":
|
|
294
|
+
return "bun install --frozen-lockfile";
|
|
295
|
+
case "pnpm":
|
|
296
|
+
return "corepack enable && pnpm install --frozen-lockfile";
|
|
297
|
+
case "yarn":
|
|
298
|
+
return "corepack enable && (yarn install --immutable || yarn install --frozen-lockfile)";
|
|
299
|
+
default:
|
|
300
|
+
return packageJson ? "npm ci" : null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function buildCommandForDefaults(packageJson, run, frameworkPreset) {
|
|
304
|
+
if (packageJson?.scripts?.build)
|
|
305
|
+
return `${run} build`;
|
|
306
|
+
if (frameworkPreset === "hugo")
|
|
307
|
+
return "hugo";
|
|
308
|
+
if (frameworkPreset === "jekyll")
|
|
309
|
+
return "bundle exec jekyll build";
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
function packageDefaults(files, packageJsonText) {
|
|
313
|
+
const packageJson = parsePackageJson(packageJsonText);
|
|
314
|
+
const dependencies = {
|
|
315
|
+
...packageJson?.dependencies,
|
|
316
|
+
...packageJson?.devDependencies,
|
|
317
|
+
};
|
|
318
|
+
const packageManager = packageManagerForFiles(files);
|
|
319
|
+
const run = packageManager === "npm" ? "npm run" : packageManager === "bun" ? "bun run" : packageManager;
|
|
320
|
+
const frameworkPreset = detectFrameworkPreset(files, dependencies);
|
|
321
|
+
return {
|
|
322
|
+
frameworkPreset,
|
|
323
|
+
installCommand: installCommandForManager(packageManager, packageJson),
|
|
324
|
+
buildCommand: buildCommandForDefaults(packageJson, run, frameworkPreset),
|
|
325
|
+
outputDirectory: outputDirectoryForFramework(frameworkPreset, files),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
export function detectBuildSettings(input) {
|
|
329
|
+
const files = new Set(input.fileNames);
|
|
330
|
+
const defaults = {
|
|
331
|
+
...packageDefaults(files, input.packageJson),
|
|
332
|
+
rootDirectory: input.rootDirectory ?? null,
|
|
333
|
+
platformPreset: null,
|
|
334
|
+
detectedFiles: [
|
|
335
|
+
input.packageJson ? "package.json" : null,
|
|
336
|
+
files.has("bun.lock") ? "bun.lock" : null,
|
|
337
|
+
files.has("bun.lockb") ? "bun.lockb" : null,
|
|
338
|
+
files.has("pnpm-lock.yaml") ? "pnpm-lock.yaml" : null,
|
|
339
|
+
files.has("yarn.lock") ? "yarn.lock" : null,
|
|
340
|
+
files.has("package-lock.json") ? "package-lock.json" : null,
|
|
341
|
+
].filter((file) => Boolean(file)),
|
|
342
|
+
};
|
|
343
|
+
const vercelFramework = input.vercelJson
|
|
344
|
+
? stringField(parseJsonObjectWithComments(input.vercelJson), "framework")
|
|
345
|
+
: null;
|
|
346
|
+
for (const config of detectPlatformConfigs(input)) {
|
|
347
|
+
defaults.platformPreset = defaults.platformPreset ?? config.platform;
|
|
348
|
+
defaults.rootDirectory = config.rootDirectory ?? defaults.rootDirectory;
|
|
349
|
+
defaults.installCommand = config.installCommand ?? defaults.installCommand;
|
|
350
|
+
defaults.buildCommand = config.buildCommand ?? defaults.buildCommand;
|
|
351
|
+
defaults.outputDirectory = config.outputDirectory ?? defaults.outputDirectory;
|
|
352
|
+
if (config.platform === "vercel") {
|
|
353
|
+
defaults.frameworkPreset = vercelFramework ?? defaults.frameworkPreset;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (input.vercelJson) {
|
|
357
|
+
defaults.detectedFiles.push("vercel.json");
|
|
358
|
+
}
|
|
359
|
+
if (input.netlifyToml) {
|
|
360
|
+
defaults.detectedFiles.push("netlify.toml");
|
|
361
|
+
}
|
|
362
|
+
if (input.wranglerJson || input.wranglerToml) {
|
|
363
|
+
defaults.detectedFiles.push(input.wranglerJson ? "wrangler.json" : "wrangler.toml");
|
|
364
|
+
}
|
|
365
|
+
return defaults;
|
|
366
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function normalizeClaimToken(token: string | null | undefined): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sortCopy<T>(values: readonly T[], compareFn: (left: T, right: T) => number): T[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mapConcurrent<T, R>(items: readonly T[], limit: number, mapper: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export async function mapConcurrent(items, limit, mapper) {
|
|
2
|
+
if (!Number.isInteger(limit) || limit < 1) {
|
|
3
|
+
throw new Error("Concurrency limit must be a positive integer.");
|
|
4
|
+
}
|
|
5
|
+
const results = [];
|
|
6
|
+
let nextIndex = 0;
|
|
7
|
+
async function worker() {
|
|
8
|
+
const index = nextIndex;
|
|
9
|
+
nextIndex += 1;
|
|
10
|
+
if (index >= items.length) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
results[index] = await mapper(items[index], index);
|
|
14
|
+
await worker();
|
|
15
|
+
}
|
|
16
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
17
|
+
return results;
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a file extension to a Content-Type header value. Returns
|
|
3
|
+
* `application/octet-stream` when the extension is not recognized.
|
|
4
|
+
*
|
|
5
|
+
* This is the superset of the extensions handled by the control-plane
|
|
6
|
+
* runtime service and the spacefast-cli uploader, so both sides agree on the
|
|
7
|
+
* same content types when uploading and serving version files.
|
|
8
|
+
*/
|
|
9
|
+
export declare function contentTypeForPath(filePath: string): string;
|
|
10
|
+
export declare function contentTypeForBytes(filePath: string, bytes: Uint8Array): string;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a file extension to a Content-Type header value. Returns
|
|
3
|
+
* `application/octet-stream` when the extension is not recognized.
|
|
4
|
+
*
|
|
5
|
+
* This is the superset of the extensions handled by the control-plane
|
|
6
|
+
* runtime service and the spacefast-cli uploader, so both sides agree on the
|
|
7
|
+
* same content types when uploading and serving version files.
|
|
8
|
+
*/
|
|
9
|
+
export function contentTypeForPath(filePath) {
|
|
10
|
+
const extensionIndex = filePath.lastIndexOf(".");
|
|
11
|
+
const extension = extensionIndex >= 0 ? filePath.slice(extensionIndex).toLowerCase() : "";
|
|
12
|
+
switch (extension) {
|
|
13
|
+
case ".html":
|
|
14
|
+
case ".htm":
|
|
15
|
+
return "text/html; charset=utf-8";
|
|
16
|
+
case ".css":
|
|
17
|
+
return "text/css; charset=utf-8";
|
|
18
|
+
case ".js":
|
|
19
|
+
case ".mjs":
|
|
20
|
+
case ".cjs":
|
|
21
|
+
return "text/javascript; charset=utf-8";
|
|
22
|
+
case ".json":
|
|
23
|
+
case ".map":
|
|
24
|
+
return "application/json; charset=utf-8";
|
|
25
|
+
case ".webmanifest":
|
|
26
|
+
return "application/manifest+json; charset=utf-8";
|
|
27
|
+
case ".gz":
|
|
28
|
+
case ".tgz":
|
|
29
|
+
return "application/gzip";
|
|
30
|
+
case ".txt":
|
|
31
|
+
case ".sh":
|
|
32
|
+
return "text/plain; charset=utf-8";
|
|
33
|
+
case ".md":
|
|
34
|
+
return "text/markdown; charset=utf-8";
|
|
35
|
+
case ".csv":
|
|
36
|
+
return "text/csv; charset=utf-8";
|
|
37
|
+
case ".xml":
|
|
38
|
+
return "application/xml; charset=utf-8";
|
|
39
|
+
case ".svg":
|
|
40
|
+
return "image/svg+xml";
|
|
41
|
+
case ".png":
|
|
42
|
+
return "image/png";
|
|
43
|
+
case ".jpg":
|
|
44
|
+
case ".jpeg":
|
|
45
|
+
return "image/jpeg";
|
|
46
|
+
case ".gif":
|
|
47
|
+
return "image/gif";
|
|
48
|
+
case ".webp":
|
|
49
|
+
return "image/webp";
|
|
50
|
+
case ".avif":
|
|
51
|
+
return "image/avif";
|
|
52
|
+
case ".ico":
|
|
53
|
+
return "image/x-icon";
|
|
54
|
+
case ".pdf":
|
|
55
|
+
return "application/pdf";
|
|
56
|
+
case ".woff":
|
|
57
|
+
return "font/woff";
|
|
58
|
+
case ".woff2":
|
|
59
|
+
return "font/woff2";
|
|
60
|
+
case ".ttf":
|
|
61
|
+
return "font/ttf";
|
|
62
|
+
case ".otf":
|
|
63
|
+
return "font/otf";
|
|
64
|
+
case ".wasm":
|
|
65
|
+
return "application/wasm";
|
|
66
|
+
default:
|
|
67
|
+
return "application/octet-stream";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function hasPrefix(bytes, prefix) {
|
|
71
|
+
return prefix.every((value, index) => bytes[index] === value);
|
|
72
|
+
}
|
|
73
|
+
function hasAsciiPrefix(bytes, prefix) {
|
|
74
|
+
return hasPrefix(bytes, Array.from(prefix, (char) => char.charCodeAt(0)));
|
|
75
|
+
}
|
|
76
|
+
function textTypeForPath(filePath) {
|
|
77
|
+
const contentType = contentTypeForPath(filePath);
|
|
78
|
+
const normalized = contentType.split(";")[0]?.trim().toLowerCase();
|
|
79
|
+
return normalized &&
|
|
80
|
+
(normalized.startsWith("text/") ||
|
|
81
|
+
normalized === "application/json" ||
|
|
82
|
+
normalized === "application/manifest+json" ||
|
|
83
|
+
normalized === "application/xml" ||
|
|
84
|
+
normalized === "image/svg+xml")
|
|
85
|
+
? contentType
|
|
86
|
+
: null;
|
|
87
|
+
}
|
|
88
|
+
function bytesLookTextual(bytes) {
|
|
89
|
+
const sample = bytes.slice(0, Math.min(bytes.length, 512));
|
|
90
|
+
if (sample.length === 0) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
for (const byte of sample) {
|
|
94
|
+
if (byte === 0) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (byte < 0x08 || (byte > 0x0d && byte < 0x20)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
export function contentTypeForBytes(filePath, bytes) {
|
|
104
|
+
if (hasPrefix(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {
|
|
105
|
+
return "image/png";
|
|
106
|
+
}
|
|
107
|
+
if (hasPrefix(bytes, [0xff, 0xd8, 0xff])) {
|
|
108
|
+
return "image/jpeg";
|
|
109
|
+
}
|
|
110
|
+
if (hasAsciiPrefix(bytes, "GIF87a") || hasAsciiPrefix(bytes, "GIF89a")) {
|
|
111
|
+
return "image/gif";
|
|
112
|
+
}
|
|
113
|
+
if (hasAsciiPrefix(bytes, "RIFF") && hasAsciiPrefix(bytes.slice(8), "WEBP")) {
|
|
114
|
+
return "image/webp";
|
|
115
|
+
}
|
|
116
|
+
if (hasAsciiPrefix(bytes.slice(4), "ftypavif") || hasAsciiPrefix(bytes.slice(4), "ftypavis")) {
|
|
117
|
+
return "image/avif";
|
|
118
|
+
}
|
|
119
|
+
if (hasPrefix(bytes, [0x00, 0x00, 0x01, 0x00])) {
|
|
120
|
+
return "image/x-icon";
|
|
121
|
+
}
|
|
122
|
+
if (hasAsciiPrefix(bytes, "%PDF-")) {
|
|
123
|
+
return "application/pdf";
|
|
124
|
+
}
|
|
125
|
+
if (hasPrefix(bytes, [0x1f, 0x8b, 0x08])) {
|
|
126
|
+
return "application/gzip";
|
|
127
|
+
}
|
|
128
|
+
if (hasAsciiPrefix(bytes, "wOFF")) {
|
|
129
|
+
return "font/woff";
|
|
130
|
+
}
|
|
131
|
+
if (hasAsciiPrefix(bytes, "wOF2")) {
|
|
132
|
+
return "font/woff2";
|
|
133
|
+
}
|
|
134
|
+
if (hasPrefix(bytes, [0x00, 0x01, 0x00, 0x00]) || hasAsciiPrefix(bytes, "true")) {
|
|
135
|
+
return "font/ttf";
|
|
136
|
+
}
|
|
137
|
+
if (hasAsciiPrefix(bytes, "OTTO")) {
|
|
138
|
+
return "font/otf";
|
|
139
|
+
}
|
|
140
|
+
const textType = textTypeForPath(filePath);
|
|
141
|
+
if (textType && bytesLookTextual(bytes)) {
|
|
142
|
+
return textType;
|
|
143
|
+
}
|
|
144
|
+
return "application/octet-stream";
|
|
145
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ApiError } from "./api.js";
|
|
2
|
+
function baseMessage(error) {
|
|
3
|
+
if (error instanceof Error) {
|
|
4
|
+
return error.message;
|
|
5
|
+
}
|
|
6
|
+
return String(error);
|
|
7
|
+
}
|
|
8
|
+
function detailLines(error) {
|
|
9
|
+
if (!(error instanceof ApiError) || !error.details) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const lines = [];
|
|
13
|
+
const { details } = error;
|
|
14
|
+
const missingPaths = details.missingPaths;
|
|
15
|
+
if (Array.isArray(missingPaths)) {
|
|
16
|
+
const paths = missingPaths.filter((entry) => typeof entry === "string");
|
|
17
|
+
if (paths.length > 0) {
|
|
18
|
+
lines.push(`Missing files: ${paths.join(", ")}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const path = details.path;
|
|
22
|
+
if (typeof path === "string" && path && lines.length === 0) {
|
|
23
|
+
lines.push(`Path: ${path}`);
|
|
24
|
+
}
|
|
25
|
+
if (error.requestId) {
|
|
26
|
+
lines.push(`Request ID: ${error.requestId}`);
|
|
27
|
+
}
|
|
28
|
+
return lines;
|
|
29
|
+
}
|
|
30
|
+
export function describeError(error) {
|
|
31
|
+
return {
|
|
32
|
+
message: baseMessage(error),
|
|
33
|
+
details: detailLines(error),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function formatErrorMessage(error) {
|
|
37
|
+
const description = describeError(error);
|
|
38
|
+
if (description.details.length === 0) {
|
|
39
|
+
return description.message;
|
|
40
|
+
}
|
|
41
|
+
return `${description.message} ${description.details.join(" ")}`;
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function errorMessage(error: unknown): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a whimsical, WordPress-flavored space title.
|
|
3
|
+
*
|
|
4
|
+
* The pool mixes WordPress jargon (Codex, Permalink, Gutenberg, Pingback)
|
|
5
|
+
* with engineering/web adjectives so the output reads like a tiny inside
|
|
6
|
+
* joke instead of an auto-increment. Users can rename later, so the only
|
|
7
|
+
* requirement is that two back-to-back calls almost never collide.
|
|
8
|
+
*
|
|
9
|
+
* Pool size: 32 × 32 = 1024 combinations. Combined with the collision
|
|
10
|
+
* handling in `uniqueSpaceSlug`, per-team conflicts are very
|
|
11
|
+
* unlikely. The generator is intentionally dependency-free so it can be
|
|
12
|
+
* shared by the control-plane, the CLI, and any future surface.
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateSpaceTitle(): string;
|