@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.
Files changed (202) hide show
  1. package/README.md +42 -0
  2. package/dist/brand.d.ts +15 -0
  3. package/dist/brand.js +24 -0
  4. package/dist/config/domains.d.ts +30 -0
  5. package/dist/config/domains.js +75 -0
  6. package/dist/config/index.d.ts +1 -0
  7. package/dist/config/index.js +3 -0
  8. package/dist/contracts/abuse.d.ts +93 -0
  9. package/dist/contracts/abuse.js +50 -0
  10. package/dist/contracts/access.d.ts +409 -0
  11. package/dist/contracts/access.js +396 -0
  12. package/dist/contracts/account.d.ts +28 -0
  13. package/dist/contracts/account.js +54 -0
  14. package/dist/contracts/activity.d.ts +118 -0
  15. package/dist/contracts/activity.js +180 -0
  16. package/dist/contracts/analytics.d.ts +56 -0
  17. package/dist/contracts/analytics.js +91 -0
  18. package/dist/contracts/annotations.d.ts +327 -0
  19. package/dist/contracts/annotations.js +234 -0
  20. package/dist/contracts/api-keys.d.ts +517 -0
  21. package/dist/contracts/api-keys.js +235 -0
  22. package/dist/contracts/archives.d.ts +332 -0
  23. package/dist/contracts/archives.js +120 -0
  24. package/dist/contracts/auth.d.ts +86 -0
  25. package/dist/contracts/auth.js +82 -0
  26. package/dist/contracts/beta.d.ts +106 -0
  27. package/dist/contracts/beta.js +104 -0
  28. package/dist/contracts/billing.d.ts +328 -0
  29. package/dist/contracts/billing.js +203 -0
  30. package/dist/contracts/builds.d.ts +504 -0
  31. package/dist/contracts/builds.js +248 -0
  32. package/dist/contracts/channels.d.ts +49 -0
  33. package/dist/contracts/channels.js +51 -0
  34. package/dist/contracts/common.d.ts +238 -0
  35. package/dist/contracts/common.js +175 -0
  36. package/dist/contracts/deployments.d.ts +574 -0
  37. package/dist/contracts/deployments.js +97 -0
  38. package/dist/contracts/device-auth.d.ts +194 -0
  39. package/dist/contracts/device-auth.js +162 -0
  40. package/dist/contracts/domains.d.ts +6115 -0
  41. package/dist/contracts/domains.js +1435 -0
  42. package/dist/contracts/enums.d.ts +196 -0
  43. package/dist/contracts/enums.js +211 -0
  44. package/dist/contracts/error-code-meta.d.ts +1560 -0
  45. package/dist/contracts/error-code-meta.js +400 -0
  46. package/dist/contracts/error-codes.d.ts +13 -0
  47. package/dist/contracts/error-codes.js +416 -0
  48. package/dist/contracts/events.d.ts +398 -0
  49. package/dist/contracts/events.js +320 -0
  50. package/dist/contracts/fast-domain-search.d.ts +19 -0
  51. package/dist/contracts/fast-domain-search.js +22 -0
  52. package/dist/contracts/features.d.ts +240 -0
  53. package/dist/contracts/features.js +406 -0
  54. package/dist/contracts/git.d.ts +288 -0
  55. package/dist/contracts/git.js +116 -0
  56. package/dist/contracts/ids.d.ts +35 -0
  57. package/dist/contracts/ids.js +45 -0
  58. package/dist/contracts/intercom.d.ts +6 -0
  59. package/dist/contracts/intercom.js +5 -0
  60. package/dist/contracts/internal.d.ts +103 -0
  61. package/dist/contracts/internal.js +92 -0
  62. package/dist/contracts/mcp.d.ts +788 -0
  63. package/dist/contracts/mcp.js +161 -0
  64. package/dist/contracts/me.d.ts +81 -0
  65. package/dist/contracts/me.js +104 -0
  66. package/dist/contracts/oauth-resources.d.ts +30 -0
  67. package/dist/contracts/oauth-resources.js +61 -0
  68. package/dist/contracts/operations.d.ts +54 -0
  69. package/dist/contracts/operations.js +14 -0
  70. package/dist/contracts/plan-policy.d.ts +85 -0
  71. package/dist/contracts/plan-policy.js +75 -0
  72. package/dist/contracts/platform.d.ts +359 -0
  73. package/dist/contracts/platform.js +216 -0
  74. package/dist/contracts/push-new.d.ts +156 -0
  75. package/dist/contracts/push-new.js +52 -0
  76. package/dist/contracts/quotas.d.ts +16 -0
  77. package/dist/contracts/quotas.js +36 -0
  78. package/dist/contracts/repository-connections.d.ts +231 -0
  79. package/dist/contracts/repository-connections.js +106 -0
  80. package/dist/contracts/resources.d.ts +529 -0
  81. package/dist/contracts/resources.js +209 -0
  82. package/dist/contracts/routes.d.ts +45 -0
  83. package/dist/contracts/routes.js +31 -0
  84. package/dist/contracts/runtime-api.d.ts +449 -0
  85. package/dist/contracts/runtime-api.js +513 -0
  86. package/dist/contracts/sites.d.ts +393 -0
  87. package/dist/contracts/sites.js +121 -0
  88. package/dist/contracts/slugs.d.ts +31 -0
  89. package/dist/contracts/slugs.js +47 -0
  90. package/dist/contracts/space-config.d.ts +216 -0
  91. package/dist/contracts/space-config.js +237 -0
  92. package/dist/contracts/space-theme.d.ts +25 -0
  93. package/dist/contracts/space-theme.js +49 -0
  94. package/dist/contracts/spaces.d.ts +2760 -0
  95. package/dist/contracts/spaces.js +589 -0
  96. package/dist/contracts/superadmin-activity.d.ts +205 -0
  97. package/dist/contracts/superadmin-activity.js +107 -0
  98. package/dist/contracts/superadmin-emails.d.ts +212 -0
  99. package/dist/contracts/superadmin-emails.js +112 -0
  100. package/dist/contracts/superadmin-queues.d.ts +414 -0
  101. package/dist/contracts/superadmin-queues.js +202 -0
  102. package/dist/contracts/superadmin-runtime.d.ts +27 -0
  103. package/dist/contracts/superadmin-runtime.js +38 -0
  104. package/dist/contracts/superadmin-spaces.d.ts +429 -0
  105. package/dist/contracts/superadmin-spaces.js +82 -0
  106. package/dist/contracts/superadmin-tenants.d.ts +180 -0
  107. package/dist/contracts/superadmin-tenants.js +117 -0
  108. package/dist/contracts/superadmin.d.ts +654 -0
  109. package/dist/contracts/superadmin.js +309 -0
  110. package/dist/contracts/tags.d.ts +1140 -0
  111. package/dist/contracts/tags.js +1050 -0
  112. package/dist/contracts/teams.d.ts +233 -0
  113. package/dist/contracts/teams.js +174 -0
  114. package/dist/contracts/telemetry.d.ts +2 -0
  115. package/dist/contracts/telemetry.js +1 -0
  116. package/dist/contracts/transfers.d.ts +105 -0
  117. package/dist/contracts/transfers.js +48 -0
  118. package/dist/contracts/variables.d.ts +189 -0
  119. package/dist/contracts/variables.js +82 -0
  120. package/dist/contracts/webhooks.d.ts +159 -0
  121. package/dist/contracts/webhooks.js +59 -0
  122. package/dist/contracts/zero.d.ts +1538 -0
  123. package/dist/contracts/zero.js +755 -0
  124. package/dist/docs/agent-prose.d.ts +35 -0
  125. package/dist/docs/agent-prose.js +153 -0
  126. package/dist/docs/agent-setup.d.ts +6 -0
  127. package/dist/docs/agent-setup.js +164 -0
  128. package/dist/docs/agent-solutions.d.ts +110 -0
  129. package/dist/docs/agent-solutions.js +181 -0
  130. package/dist/docs/error-docs.d.ts +12 -0
  131. package/dist/docs/error-docs.js +1601 -0
  132. package/dist/docs/skill-distribution.d.ts +12 -0
  133. package/dist/docs/skill-distribution.js +18 -0
  134. package/dist/domain-exploration.d.ts +108 -0
  135. package/dist/domain-exploration.js +488 -0
  136. package/dist/domain-normalize.d.ts +1 -0
  137. package/dist/domain-normalize.js +14 -0
  138. package/dist/domain-zones.d.ts +1 -0
  139. package/dist/domain-zones.js +5272 -0
  140. package/dist/index.d.ts +1 -0
  141. package/dist/index.js +1 -0
  142. package/dist/utils/access-policy.d.ts +39 -0
  143. package/dist/utils/access-policy.js +232 -0
  144. package/dist/utils/api.d.ts +4 -0
  145. package/dist/utils/api.js +13 -0
  146. package/dist/utils/auth-redirect.d.ts +1 -0
  147. package/dist/utils/auth-redirect.js +48 -0
  148. package/dist/utils/auth.d.ts +5 -0
  149. package/dist/utils/auth.js +13 -0
  150. package/dist/utils/build-settings.d.ts +49 -0
  151. package/dist/utils/build-settings.js +366 -0
  152. package/dist/utils/claim-token.d.ts +1 -0
  153. package/dist/utils/claim-token.js +9 -0
  154. package/dist/utils/collections.d.ts +1 -0
  155. package/dist/utils/collections.js +5 -0
  156. package/dist/utils/concurrency.d.ts +1 -0
  157. package/dist/utils/concurrency.js +18 -0
  158. package/dist/utils/content-type.d.ts +10 -0
  159. package/dist/utils/content-type.js +145 -0
  160. package/dist/utils/error-display.d.ts +7 -0
  161. package/dist/utils/error-display.js +42 -0
  162. package/dist/utils/error.d.ts +1 -0
  163. package/dist/utils/error.js +3 -0
  164. package/dist/utils/generate-space-name.d.ts +14 -0
  165. package/dist/utils/generate-space-name.js +95 -0
  166. package/dist/utils/git-repository.d.ts +5 -0
  167. package/dist/utils/git-repository.js +99 -0
  168. package/dist/utils/guards.d.ts +1 -0
  169. package/dist/utils/guards.js +3 -0
  170. package/dist/utils/publish-detection.d.ts +10 -0
  171. package/dist/utils/publish-detection.js +118 -0
  172. package/dist/utils/publish-policy.d.ts +69 -0
  173. package/dist/utils/publish-policy.js +429 -0
  174. package/dist/utils/query-client.d.ts +7 -0
  175. package/dist/utils/query-client.js +21 -0
  176. package/dist/utils/query-keys.d.ts +75 -0
  177. package/dist/utils/query-keys.js +78 -0
  178. package/dist/utils/runtime-paths.d.ts +7 -0
  179. package/dist/utils/runtime-paths.js +28 -0
  180. package/dist/utils/runtime-upload.d.ts +19 -0
  181. package/dist/utils/runtime-upload.js +27 -0
  182. package/dist/utils/slug.d.ts +5 -0
  183. package/dist/utils/slug.js +13 -0
  184. package/dist/utils/space-config.d.ts +75 -0
  185. package/dist/utils/space-config.js +415 -0
  186. package/dist/utils/space-theme.d.ts +16 -0
  187. package/dist/utils/space-theme.js +89 -0
  188. package/dist/utils/static-runtime-policy.d.ts +17 -0
  189. package/dist/utils/static-runtime-policy.js +103 -0
  190. package/dist/utils/upload-session.d.ts +34 -0
  191. package/dist/utils/upload-session.js +69 -0
  192. package/dist/utils/urls.d.ts +2 -0
  193. package/dist/utils/urls.js +7 -0
  194. package/dist/utils/version-path.d.ts +6 -0
  195. package/dist/utils/version-path.js +51 -0
  196. package/dist/utils/wpcom-auth-redirects.d.ts +14 -0
  197. package/dist/utils/wpcom-auth-redirects.js +49 -0
  198. package/dist/utils/zero-realtime-signature.d.ts +12 -0
  199. package/dist/utils/zero-realtime-signature.js +45 -0
  200. package/dist/vocabulary.d.ts +230 -0
  201. package/dist/vocabulary.js +218 -0
  202. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,39 @@
1
+ import { type ApiKeyPreset, type StatticAccessPolicy, type StatticAction } from "../contracts/api-keys.js";
2
+ type RequestCondition = NonNullable<StatticAccessPolicy["statements"][number]["conditions"]>;
3
+ export type PolicyCompileInput = {
4
+ tenantId: string;
5
+ teamId: string;
6
+ };
7
+ export type PolicyAuthorizeInput = {
8
+ policy: StatticAccessPolicy;
9
+ action: StatticAction;
10
+ /**
11
+ * Candidate resource URIs for one request target, evaluated together: spaces
12
+ * are addressed by their canonical site-rooted URI AND a principal-scoped
13
+ * candidate so principal wildcards cover them. A deny matching ANY candidate
14
+ * wins; otherwise an allow matching any candidate permits.
15
+ */
16
+ resource: string | readonly string[];
17
+ conditions?: RequestCondition;
18
+ };
19
+ export declare function compileApiKeyPreset(preset: ApiKeyPreset, input: PolicyCompileInput): StatticAccessPolicy;
20
+ export declare function compileTeamRolePolicy(input: PolicyCompileInput & {
21
+ role: string;
22
+ }): StatticAccessPolicy;
23
+ export declare function allowPolicy(actions: StatticAction[], resources: string[]): StatticAccessPolicy;
24
+ export declare function denyAllPolicy(): StatticAccessPolicy;
25
+ export declare function policyIsSubsetOfGrantor(requested: StatticAccessPolicy, grantor: StatticAccessPolicy): boolean;
26
+ export declare function policyAllows(input: PolicyAuthorizeInput): boolean;
27
+ export declare function grantedTenantsFromPolicy(policy: StatticAccessPolicy): {
28
+ all: boolean;
29
+ tenantIds: string[];
30
+ };
31
+ export declare function grantedPrincipalsFromPolicy(policy: StatticAccessPolicy, input: {
32
+ tenantId: string;
33
+ principalType: "team" | "external";
34
+ }): {
35
+ all: boolean;
36
+ principalIds: string[];
37
+ };
38
+ export declare function policyReaches(policy: StatticAccessPolicy, resourceBase: string): boolean;
39
+ export {};
@@ -0,0 +1,232 @@
1
+ import { SPACEFAST_ACCESS_POLICY_VERSION, parseStatticResource, } from "../contracts/api-keys.js";
2
+ const publishActions = [
3
+ "spaces:read",
4
+ "spaces:create",
5
+ "spaces:write",
6
+ "spaces:publish",
7
+ "versions:read",
8
+ "versions:promote",
9
+ "versions:download",
10
+ "builds:read",
11
+ "builds:create",
12
+ ];
13
+ const spaceAdminActions = [
14
+ ...publishActions,
15
+ "spaces:delete",
16
+ "spaces:transfer",
17
+ "spaces:export",
18
+ "spaces:import",
19
+ "versions:delete",
20
+ // Resolving the owning team (name/slug) is part of administering its spaces:
21
+ // the CLI resolves teams before every publish, so admin-tier presets carry
22
+ // read access to the team resource itself.
23
+ "teams:read",
24
+ ];
25
+ const domainActions = [
26
+ "domains:read",
27
+ "domains:create",
28
+ "domains:verify",
29
+ "domains:assign",
30
+ "domains:bind",
31
+ "domains:delete",
32
+ "domains:dns.write",
33
+ "domains:purchase",
34
+ ];
35
+ function teamResource(input) {
36
+ return `stt://tenant/${input.tenantId}/principal/team/${input.teamId}/*`;
37
+ }
38
+ export function compileApiKeyPreset(preset, input) {
39
+ const resource = teamResource(input);
40
+ switch (preset) {
41
+ case "ci_deploy":
42
+ case "space_publisher":
43
+ return allowPolicy(publishActions, [resource]);
44
+ case "space_admin":
45
+ return allowPolicy(spaceAdminActions, [resource]);
46
+ case "site_admin":
47
+ return allowPolicy([
48
+ "sites:read",
49
+ "sites:create",
50
+ "sites:write",
51
+ "sites:delete",
52
+ "sites:policy.write",
53
+ ...spaceAdminActions,
54
+ ...domainActions,
55
+ "webhooks:read",
56
+ "webhooks:write",
57
+ ], [resource]);
58
+ case "domain_manager":
59
+ return allowPolicy(domainActions, [resource]);
60
+ case "billing_viewer":
61
+ return allowPolicy(["teams:read", "billing:read"], [resource]);
62
+ case "team_admin":
63
+ return allowPolicy(["*"], [resource]);
64
+ }
65
+ }
66
+ export function compileTeamRolePolicy(input) {
67
+ switch (input.role) {
68
+ case "owner":
69
+ case "admin":
70
+ return compileApiKeyPreset("team_admin", input);
71
+ case "member":
72
+ return allowPolicy([
73
+ "sites:read",
74
+ "spaces:read",
75
+ "spaces:create",
76
+ "spaces:write",
77
+ "spaces:publish",
78
+ "versions:read",
79
+ "versions:promote",
80
+ "versions:download",
81
+ "domains:read",
82
+ "builds:read",
83
+ "builds:create",
84
+ "teams:read",
85
+ "billing:read",
86
+ ], [teamResource(input)]);
87
+ default:
88
+ return denyAllPolicy();
89
+ }
90
+ }
91
+ export function allowPolicy(actions, resources) {
92
+ return {
93
+ version: SPACEFAST_ACCESS_POLICY_VERSION,
94
+ statements: [{ effect: "allow", actions: [...new Set(actions)], resources }],
95
+ };
96
+ }
97
+ export function denyAllPolicy() {
98
+ return {
99
+ version: SPACEFAST_ACCESS_POLICY_VERSION,
100
+ statements: [{ effect: "deny", actions: ["*"], resources: ["stt://tenant/*"] }],
101
+ };
102
+ }
103
+ export function policyIsSubsetOfGrantor(requested, grantor) {
104
+ return (requested.statements.every((statement) => {
105
+ if (statement.effect === "deny") {
106
+ return true;
107
+ }
108
+ return statement.actions.every((action) => statement.resources.every((resource) => grantorAllows(grantor, action, resource, statement.conditions)));
109
+ }) && grantorDeniesArePreserved(requested, grantor));
110
+ }
111
+ // Request-time evaluation (internal-docs/platform.md IAM-lite): explicit deny wins,
112
+ // explicit allow permits, otherwise implicit deny. Condition keys are ANDed and an
113
+ // unresolvable condition attribute fails closed (see `conditionsMatch`).
114
+ export function policyAllows(input) {
115
+ const resources = typeof input.resource === "string" ? [input.resource] : input.resource;
116
+ if (resources.some((resource) => matchesEffect(input.policy, "deny", input.action, resource, input.conditions, "request"))) {
117
+ return false;
118
+ }
119
+ return resources.some((resource) => matchesEffect(input.policy, "allow", input.action, resource, input.conditions, "request"));
120
+ }
121
+ // The tenants a credential's policy grants any access to. Drives tenant
122
+ // selection (internal-docs/platform.md Tenant): `X-Spacefast-Tenant-Id` may pick
123
+ // one granted tenant but is never an authority by itself, and a token spanning
124
+ // multiple tenants must fail ambiguous requests with `tenant_selection_required`.
125
+ export function grantedTenantsFromPolicy(policy) {
126
+ const tenantIds = new Set();
127
+ let all = false;
128
+ for (const statement of policy.statements) {
129
+ if (statement.effect !== "allow") {
130
+ continue;
131
+ }
132
+ for (const resource of statement.resources) {
133
+ const tenantId = parseStatticResource(resource)?.tenantId;
134
+ if (tenantId === "*") {
135
+ all = true;
136
+ }
137
+ else if (tenantId !== undefined) {
138
+ tenantIds.add(tenantId);
139
+ }
140
+ }
141
+ }
142
+ return { all, tenantIds: [...tenantIds] };
143
+ }
144
+ // The principal ids of one type a policy grants any access to within a tenant.
145
+ // Used to scope list queries; specific actions still go through `policyAllows`.
146
+ export function grantedPrincipalsFromPolicy(policy, input) {
147
+ const principalIds = new Set();
148
+ let all = false;
149
+ for (const statement of policy.statements) {
150
+ if (statement.effect !== "allow") {
151
+ continue;
152
+ }
153
+ for (const resource of statement.resources) {
154
+ const parsed = parseStatticResource(resource);
155
+ if (!parsed || (parsed.tenantId !== input.tenantId && parsed.tenantId !== "*")) {
156
+ continue;
157
+ }
158
+ // Tenant-rooted grants (both `stt://tenant/*` and a concrete
159
+ // `stt://tenant/{t}` already filtered to this tenant) are scope-wide:
160
+ // they reach every principal in the tenant.
161
+ if (parsed.kind === "tenant") {
162
+ all = true;
163
+ }
164
+ else if (parsed.kind === "principal" && parsed.principalType === input.principalType) {
165
+ if (parsed.principalId === "*") {
166
+ all = true;
167
+ }
168
+ else {
169
+ principalIds.add(parsed.principalId);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ return { all, principalIds: [...principalIds] };
175
+ }
176
+ // Whether the policy's allow statements reach a resource subtree at all —
177
+ // either a statement resource covers the base, or it lives inside the base.
178
+ // This is a visibility/scoping check (404 vs 403), never an action grant.
179
+ export function policyReaches(policy, resourceBase) {
180
+ return policy.statements.some((statement) => statement.effect === "allow" &&
181
+ statement.resources.some((resource) => resourceMatches(resource, resourceBase) ||
182
+ resource === resourceBase ||
183
+ resource.startsWith(`${resourceBase}/`)));
184
+ }
185
+ function grantorAllows(policy, action, resource, conditions) {
186
+ if (matchesEffect(policy, "deny", action, resource, conditions, "subset")) {
187
+ return false;
188
+ }
189
+ return matchesEffect(policy, "allow", action, resource, conditions, "subset");
190
+ }
191
+ function grantorDeniesArePreserved(requested, grantor) {
192
+ return grantor.statements
193
+ .filter((statement) => statement.effect === "deny")
194
+ .every((deny) => deny.actions.every((action) => deny.resources.every((resource) => matchesEffect(requested, "deny", action, resource, deny.conditions, "subset"))));
195
+ }
196
+ function matchesEffect(policy, effect, action, resource, conditions, mode) {
197
+ return policy.statements.some((statement) => statement.effect === effect &&
198
+ statement.actions.some((candidate) => candidate === "*" || candidate === action) &&
199
+ statement.resources.some((candidate) => resourceMatches(candidate, resource)) &&
200
+ conditionsMatch(statement.conditions, conditions, effect, mode));
201
+ }
202
+ function resourceMatches(pattern, resource) {
203
+ if (pattern === resource) {
204
+ return true;
205
+ }
206
+ if (pattern.endsWith("/*")) {
207
+ return resource === pattern.slice(0, -2) || resource.startsWith(pattern.slice(0, -1));
208
+ }
209
+ // A tenant-rooted resource is scope-wide (internal-docs/platform.md L617/L879:
210
+ // `stt://tenant/{t}` is a grantable StatticResource and resource grants cover
211
+ // their subtree): it covers every resource inside that tenant. This is the
212
+ // tenant-scoped (partner/agency) credential shape.
213
+ if (parseStatticResource(pattern)?.kind === "tenant") {
214
+ return resource.startsWith(`${pattern}/`);
215
+ }
216
+ return false;
217
+ }
218
+ function conditionsMatch(statementConditions, contextConditions, effect, mode) {
219
+ if (!statementConditions) {
220
+ return true;
221
+ }
222
+ return Object.entries(statementConditions).every(([key, value]) => {
223
+ const resolved = contextConditions?.[key];
224
+ if (resolved === undefined && mode === "request") {
225
+ // Fail closed on unresolvable condition attributes: the condition never
226
+ // matches for allow statements and always matches for deny statements, so
227
+ // callers cannot dodge a deny by stripping request context.
228
+ return effect === "deny";
229
+ }
230
+ return resolved === value;
231
+ });
232
+ }
@@ -0,0 +1,4 @@
1
+ export type UnwrapEnvelope<B> = B extends {
2
+ data: infer D;
3
+ } ? Exclude<keyof B, "data" | "$schema"> extends never ? D : B : B;
4
+ export declare function unwrapEnvelope<B>(body: B): UnwrapEnvelope<B>;
@@ -0,0 +1,13 @@
1
+ // Response envelope helpers for the CLI's HTTP layer. The canonical client
2
+ // implementation lives in @spacefast/sdk (generated from the external OpenAPI
3
+ // spec); browser surfaces import the SDK directly via app-shell/lib/api.ts.
4
+ export function unwrapEnvelope(body) {
5
+ if (body &&
6
+ typeof body === "object" &&
7
+ !Array.isArray(body) &&
8
+ "data" in body &&
9
+ Object.keys(body).every((key) => key === "data" || key === "$schema")) {
10
+ return body.data;
11
+ }
12
+ return body;
13
+ }
@@ -0,0 +1 @@
1
+ export declare function sanitizeDashboardReturnTo(returnTo: string | null | undefined): string | undefined;
@@ -0,0 +1,48 @@
1
+ const INVALID_RETURN_TO_PREFIXES = ["/login", "/log-in", "/sign-in"];
2
+ const DASHBOARD_RETURN_TO_BASE = "https://dashboard.local";
3
+ function decodedReturnTo(value) {
4
+ try {
5
+ return decodeURIComponent(value);
6
+ }
7
+ catch {
8
+ return null;
9
+ }
10
+ }
11
+ function hasUnsafeReturnToChars(value) {
12
+ for (const char of value) {
13
+ const code = char.charCodeAt(0);
14
+ if (char === "\\" || code < 0x20 || code === 0x7f) {
15
+ return true;
16
+ }
17
+ }
18
+ return false;
19
+ }
20
+ export function sanitizeDashboardReturnTo(returnTo) {
21
+ const normalized = returnTo?.trim();
22
+ const decoded = normalized ? decodedReturnTo(normalized) : null;
23
+ if (!normalized ||
24
+ !decoded ||
25
+ !normalized.startsWith("/") ||
26
+ normalized.startsWith("//") ||
27
+ decoded.startsWith("//") ||
28
+ hasUnsafeReturnToChars(normalized) ||
29
+ hasUnsafeReturnToChars(decoded)) {
30
+ return undefined;
31
+ }
32
+ let url;
33
+ try {
34
+ url = new URL(normalized, DASHBOARD_RETURN_TO_BASE);
35
+ }
36
+ catch {
37
+ return undefined;
38
+ }
39
+ if (url.origin !== DASHBOARD_RETURN_TO_BASE) {
40
+ return undefined;
41
+ }
42
+ const safePath = `${url.pathname}${url.search}${url.hash}`;
43
+ const lowerPath = url.pathname.toLowerCase();
44
+ if (INVALID_RETURN_TO_PREFIXES.some((prefix) => lowerPath === prefix || lowerPath.startsWith(`${prefix}/`))) {
45
+ return undefined;
46
+ }
47
+ return safePath;
48
+ }
@@ -0,0 +1,5 @@
1
+ export declare const SPACEFAST_TENANT_HEADER = "x-spacefast-tenant-id";
2
+ export declare const SPACEFAST_CLIENT_HEADER = "x-spacefast-client";
3
+ export declare const SPACEFAST_CLI_DEVICE_CLIENT_ID = "spacefast-cli";
4
+ export declare function normalizeDeviceUserCode(value: string): string;
5
+ export declare function formatDeviceUserCode(value: string): string;
@@ -0,0 +1,13 @@
1
+ export const SPACEFAST_TENANT_HEADER = "x-spacefast-tenant-id";
2
+ export const SPACEFAST_CLIENT_HEADER = "x-spacefast-client";
3
+ export const SPACEFAST_CLI_DEVICE_CLIENT_ID = "spacefast-cli";
4
+ export function normalizeDeviceUserCode(value) {
5
+ return value.replace(/[^a-z0-9]/gi, "").toUpperCase();
6
+ }
7
+ export function formatDeviceUserCode(value) {
8
+ const normalized = normalizeDeviceUserCode(value).slice(0, 8);
9
+ if (normalized.length <= 4) {
10
+ return normalized;
11
+ }
12
+ return `${normalized.slice(0, 4)}-${normalized.slice(4)}`;
13
+ }
@@ -0,0 +1,49 @@
1
+ export type BuildSettingsInput = {
2
+ fileNames: Iterable<string>;
3
+ packageJson?: string | null | undefined;
4
+ vercelJson?: string | null | undefined;
5
+ netlifyToml?: string | null | undefined;
6
+ wranglerToml?: string | null | undefined;
7
+ wranglerJson?: string | null | undefined;
8
+ rootDirectory?: string | null | undefined;
9
+ };
10
+ export type DetectedBuildSettings = {
11
+ frameworkPreset: string | null;
12
+ installCommand: string | null;
13
+ buildCommand: string | null;
14
+ outputDirectory: string | null;
15
+ rootDirectory: string | null;
16
+ platformPreset: string | null;
17
+ detectedFiles: string[];
18
+ };
19
+ export declare const BUILD_ANALYZER_CANDIDATE_ROOTS: readonly ["apps", "packages", "sites", "docs"];
20
+ export type BuildAnalyzerCandidateRankInput = {
21
+ detected: Pick<DetectedBuildSettings, "platformPreset" | "frameworkPreset" | "buildCommand">;
22
+ rootDirectory: string | null;
23
+ fileNames: Iterable<string>;
24
+ };
25
+ export declare function hasWorkspaceSignal(fileNames: Iterable<string>, packageJsonText?: string | null): unknown;
26
+ export declare function rankBuildAnalyzerCandidate(input: BuildAnalyzerCandidateRankInput): {
27
+ confidence: number;
28
+ reasons: string[];
29
+ };
30
+ export declare function hasBuildAnalyzerCandidateSignal(input: {
31
+ detected: Pick<DetectedBuildSettings, "detectedFiles" | "platformPreset" | "frameworkPreset" | "buildCommand">;
32
+ fileNames: Iterable<string>;
33
+ }): boolean;
34
+ export type PlatformConfig = {
35
+ platform: "vercel" | "netlify" | "cloudflare-pages";
36
+ rootDirectory: string | null;
37
+ installDirectory: string | null;
38
+ installCommand: string | null;
39
+ buildCommand: string | null;
40
+ outputDirectory: string | null;
41
+ redirects: Array<Record<string, unknown>>;
42
+ rewrites: Array<Record<string, unknown>>;
43
+ headers: Array<Record<string, unknown>>;
44
+ unsupportedFeatures: string[];
45
+ };
46
+ export declare function stringField(value: Record<string, unknown> | null, key: string): string | null;
47
+ export declare function numberField(value: Record<string, unknown> | null, key: string): number | null;
48
+ export declare function detectPlatformConfigs(input: Omit<BuildSettingsInput, "fileNames" | "packageJson">): PlatformConfig[];
49
+ export declare function detectBuildSettings(input: BuildSettingsInput): DetectedBuildSettings;