@xanots/sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +384 -0
  3. package/dist/agent-file-refresh-7XCACU34.js +95 -0
  4. package/dist/bin.d.ts +1 -0
  5. package/dist/bin.js +184 -0
  6. package/dist/capture-HUV5BNTC.js +32 -0
  7. package/dist/chunk-26CNBZE2.js +963 -0
  8. package/dist/chunk-33ND6LKO.js +78 -0
  9. package/dist/chunk-3DUAGYGP.js +1550 -0
  10. package/dist/chunk-3IGNIP6R.js +89 -0
  11. package/dist/chunk-47WDWMBJ.js +14 -0
  12. package/dist/chunk-4BXJGVZ3.js +318 -0
  13. package/dist/chunk-4HT3BNZ7.js +675 -0
  14. package/dist/chunk-4YMD2OOZ.js +23 -0
  15. package/dist/chunk-5WGEURVI.js +156 -0
  16. package/dist/chunk-5YTBTF25.js +29 -0
  17. package/dist/chunk-6DHBYBTO.js +166 -0
  18. package/dist/chunk-76QBEIGO.js +66 -0
  19. package/dist/chunk-7DKX2SPN.js +100 -0
  20. package/dist/chunk-7REDODS2.js +468 -0
  21. package/dist/chunk-C56BC2FY.js +254 -0
  22. package/dist/chunk-DGSF2Q5H.js +60 -0
  23. package/dist/chunk-EMCAWMHC.js +3982 -0
  24. package/dist/chunk-EZG76F7R.js +159 -0
  25. package/dist/chunk-FJ6ZS5KB.js +3607 -0
  26. package/dist/chunk-GNPVYOPB.js +17 -0
  27. package/dist/chunk-HJPTWBLH.js +38 -0
  28. package/dist/chunk-IZW6MK3U.js +248 -0
  29. package/dist/chunk-LH6Z6KFV.js +247 -0
  30. package/dist/chunk-MZUI3JNX.js +93 -0
  31. package/dist/chunk-NDZFBZHC.js +167 -0
  32. package/dist/chunk-NOO35BQ2.js +37 -0
  33. package/dist/chunk-NUQCEOKA.js +13 -0
  34. package/dist/chunk-QTNO2WD6.js +56 -0
  35. package/dist/chunk-RVB7ITKN.js +49 -0
  36. package/dist/chunk-TRU5OHQ5.js +6904 -0
  37. package/dist/chunk-VKFQJEMW.js +814 -0
  38. package/dist/chunk-VTIL47DT.js +125 -0
  39. package/dist/chunk-WHOJWOSV.js +112 -0
  40. package/dist/chunk-WKP4D5MO.js +1692 -0
  41. package/dist/chunk-X4DVXBFY.js +38 -0
  42. package/dist/chunk-XQ22GLYS.js +118 -0
  43. package/dist/chunk-YDZYMZBE.js +670 -0
  44. package/dist/chunk-YGPIY3WT.js +1146 -0
  45. package/dist/chunk-YYRDLFSJ.js +602 -0
  46. package/dist/chunk-ZUTSMMAG.js +46 -0
  47. package/dist/cli.d.ts +331 -0
  48. package/dist/cli.js +33 -0
  49. package/dist/codegen-command-OOKK6AZK.js +40 -0
  50. package/dist/codegen.d.ts +114 -0
  51. package/dist/codegen.js +71 -0
  52. package/dist/completion-TIPPZN7H.js +298 -0
  53. package/dist/config-NL33PN4D.js +84 -0
  54. package/dist/deploy-command-4EQ7XX5G.js +451 -0
  55. package/dist/env-target-IFJ5QDHC.js +16 -0
  56. package/dist/ephemeral-command-3X3I4ULC.js +242 -0
  57. package/dist/index.d.ts +4477 -0
  58. package/dist/index.js +300 -0
  59. package/dist/init-command-R6H7ZXW5.js +27 -0
  60. package/dist/internal.d.ts +74 -0
  61. package/dist/internal.js +2065 -0
  62. package/dist/io-AMIKRLPC.js +11 -0
  63. package/dist/live-diff-Y3AKETHE.js +196 -0
  64. package/dist/lock-3CVKALKT.js +37 -0
  65. package/dist/lock-commands-XTR2YKLY.js +232 -0
  66. package/dist/login-command-ACJF6KWQ.js +167 -0
  67. package/dist/logout-command-MX3MJS5U.js +68 -0
  68. package/dist/loop-OM3P2Z6O.js +93 -0
  69. package/dist/marketplace-command-RATXTKXN.js +379 -0
  70. package/dist/meta-client-OW5WKWW7.js +170 -0
  71. package/dist/node.d.ts +59 -0
  72. package/dist/node.js +442 -0
  73. package/dist/profile-command-SWJ3SPKR.js +77 -0
  74. package/dist/release-command-VV5UVZKL.js +427 -0
  75. package/dist/response-CVAE2kMj.d.ts +1915 -0
  76. package/dist/routes-manifest-SP3ZXLMR.js +244 -0
  77. package/dist/runtime-V4C3AC3A.js +13 -0
  78. package/dist/sandbox-details-command-HJE5SPVG.js +18 -0
  79. package/dist/sandbox-export-command-QCJY4GMV.js +24 -0
  80. package/dist/static-host-D6KS7X45.js +138 -0
  81. package/dist/store-BQ97nKIF.d.ts +7760 -0
  82. package/dist/test-command-TSPBQHBM.js +383 -0
  83. package/dist/validate-command-4ERHJSCO.js +122 -0
  84. package/dist/verify-rollout-FAVQ6EJY.js +40 -0
  85. package/dist/workspace-K72NP7SX.js +49 -0
  86. package/dist/workspace-command-OF23DPNI.js +156 -0
  87. package/dist/workspace-export-AJMGN3CQ.js +10 -0
  88. package/llms/fields.md +104 -0
  89. package/llms/filters.md +183 -0
  90. package/llms/kinds-agent-mcp.md +11 -0
  91. package/llms/kinds-core.md +68 -0
  92. package/llms/kinds-realtime.md +76 -0
  93. package/llms/lambda.md +111 -0
  94. package/llms/legacy.md +43 -0
  95. package/llms/object-kinds.md +31 -0
  96. package/llms/statements-calls.md +23 -0
  97. package/llms/statements-catalog.md +309 -0
  98. package/llms/statements-data.md +58 -0
  99. package/llms/statements-runtime.md +48 -0
  100. package/llms/tests.md +58 -0
  101. package/llms/triggers.md +22 -0
  102. package/llms/values.md +29 -0
  103. package/llms-full.txt +1672 -0
  104. package/llms.txt +483 -0
  105. package/manifest.json +9592 -0
  106. package/package.json +110 -0
@@ -0,0 +1,244 @@
1
+ import {
2
+ parsePathParams
3
+ } from "./chunk-WHOJWOSV.js";
4
+
5
+ // src/emit/routes-manifest.ts
6
+ var RouteManifestError = class extends Error {
7
+ };
8
+ function literal(value) {
9
+ return JSON.stringify(value);
10
+ }
11
+ function objectLiteral(rows) {
12
+ return rows.length === 0 ? "{}" : `{
13
+ ${rows.join("\n")}
14
+ }`;
15
+ }
16
+ function overloadsFor(fn, rows) {
17
+ return rows.map(
18
+ (r) => r.params.length === 0 ? `export function ${fn}(name: ${literal(r.name)}): string;` : `export function ${fn}(name: ${literal(r.name)}, params: { ${r.params.map((p) => `${literal(p)}: string | number`).join("; ")} }): string;`
19
+ ).join("\n");
20
+ }
21
+ function renderRealtime(realtime) {
22
+ const servers = [...realtime.servers].sort((a, b) => a.name.localeCompare(b.name));
23
+ const known = new Map(servers.map((s) => [s.name, s]));
24
+ const seenServer = /* @__PURE__ */ new Set();
25
+ for (const server of servers) {
26
+ if (seenServer.has(server.name)) {
27
+ throw new RouteManifestError(
28
+ `Two realtime servers are both named "${server.name}". The manifest keys on the server name, so the names must be unique. Rename one.`
29
+ );
30
+ }
31
+ seenServer.add(server.name);
32
+ }
33
+ const seenChannel = /* @__PURE__ */ new Map();
34
+ const channels = [...realtime.channels].sort((a, b) => a.name.localeCompare(b.name)).map((channel) => {
35
+ const clash = seenChannel.get(channel.name);
36
+ if (clash !== void 0) {
37
+ throw new RouteManifestError(
38
+ `The channel path "${channel.name}" is owned by both realtime server "${clash}" and "${channel.server}". The route manifest keys channels on their path, so the paths must be unique across servers. Rename one channel.`
39
+ );
40
+ }
41
+ seenChannel.set(channel.name, channel.server);
42
+ if (!known.has(channel.server)) {
43
+ throw new RouteManifestError(
44
+ `The channel "${channel.name}" names the realtime server "${channel.server}", which is not in this workspace. A channel's socket URL comes from its server's canonical, so the server must be registered too.`
45
+ );
46
+ }
47
+ return { ...channel, params: parsePathParams(`channel "${channel.name}"`, channel.name) };
48
+ });
49
+ const serverRows = servers.map(
50
+ (s) => ` ${literal(s.name)}: { canonical: ${literal(s.canonical)} },`
51
+ );
52
+ const channelRows = channels.map(
53
+ (c) => ` ${literal(c.name)}: { server: ${literal(c.server)} },`
54
+ );
55
+ return `
56
+ /** Every realtime server in this workspace, by name, with its resolved canonical. */
57
+ export const REALTIME_SERVERS = ${objectLiteral(serverRows)} as const;
58
+
59
+ /** Every realtime server name in this workspace. */
60
+ export type RealtimeServerName = keyof typeof REALTIME_SERVERS;
61
+
62
+ /** Every realtime channel in this workspace, by path, with its owning server. */
63
+ export const CHANNELS = ${objectLiteral(channelRows)} as const;
64
+
65
+ /** Every realtime channel path in this workspace. */
66
+ export type ChannelName = keyof typeof CHANNELS;
67
+
68
+ ${overloadsFor("channelPath", channels)}
69
+ ${REALTIME_IMPLEMENTATION}`;
70
+ }
71
+ function renderRouteManifest(routes, realtime) {
72
+ const sorted = [...routes].sort(
73
+ (a, b) => a.canonical.localeCompare(b.canonical) || a.name.localeCompare(b.name)
74
+ );
75
+ const seen = /* @__PURE__ */ new Set();
76
+ const rows = sorted.map((route) => {
77
+ if (seen.has(route.name)) {
78
+ throw new RouteManifestError(
79
+ `Two endpoints are both named "${route.name}". The route manifest keys on the endpoint name, so the names must be unique across api groups. Rename one.`
80
+ );
81
+ }
82
+ seen.add(route.name);
83
+ const params = parsePathParams(`route "${route.name}"`, route.name);
84
+ const path = `/api:${route.canonical}/${route.name.replace(/^\/+/, "")}`;
85
+ return { ...route, params, path };
86
+ });
87
+ const entries = rows.map(
88
+ (r) => ` ${literal(r.name)}: { verb: ${literal(r.verb)}, path: ${literal(r.path)} },`
89
+ );
90
+ const realtimeSection = realtime && (realtime.servers.length > 0 || realtime.channels.length > 0) ? renderRealtime(realtime) : "";
91
+ return `${HEADER}${FILL_PARAMS}
92
+ export const ROUTES = ${objectLiteral(entries)} as const;
93
+
94
+ /** Every endpoint name in this workspace. */
95
+ export type RouteName = keyof typeof ROUTES;
96
+
97
+ ${overloadsFor("routePath", rows)}
98
+ ${IMPLEMENTATION}${realtimeSection}`;
99
+ }
100
+ var HEADER = `/**
101
+ * GENERATED by \`xanots paths --emit\`. Do not edit.
102
+ *
103
+ * Plain data plus one interpolator \u2014 this file imports nothing, so a frontend
104
+ * gets the typed path/verb (and socket) contract without pulling the SDK runtime
105
+ * into its bundle. Regenerate after changing an endpoint's name, verb, or api
106
+ * group, or a realtime server's or channel's name.
107
+ */
108
+ `;
109
+ var FILL_PARAMS = `
110
+ function fillParams(
111
+ label: string,
112
+ noun: string,
113
+ template: string,
114
+ params?: Record<string, string | number>,
115
+ encode = false,
116
+ ): string {
117
+ const declared = [...template.matchAll(/\\{([^/{}]+)\\}/g)].map((m) => m[1]!);
118
+ for (const key of Object.keys(params ?? {})) {
119
+ if (!declared.includes(key)) {
120
+ throw new Error(
121
+ \`\${label}: \\\`\${key}\\\` is not a {param} of this \${noun}.\` +
122
+ (declared.length ? \` Expected: \${declared.join(", ")}.\` : \` This \${noun} is static.\`),
123
+ );
124
+ }
125
+ }
126
+ return template.replace(/\\{([^/{}]+)\\}/g, (_all, key: string) => {
127
+ const value = (params ?? {})[key];
128
+ if (value === undefined || value === null || value === "") {
129
+ throw new Error(\`\${label}: missing a value for the path param \\\`\${key}\\\`.\`);
130
+ }
131
+ if (typeof value === "number" && !Number.isFinite(value)) {
132
+ throw new Error(\`\${label}: the path param \\\`\${key}\\\` is \${value}.\`);
133
+ }
134
+ const text = String(value);
135
+ if (text.includes("/")) {
136
+ throw new Error(
137
+ \`\${label}: the path param \\\`\${key}\\\` cannot contain "/" \u2014 \` +
138
+ \`it would address a different \${noun}.\`,
139
+ );
140
+ }
141
+ if (!encode) return text;
142
+ // A "." or ".." segment is REMOVED before routing (and takes the segment
143
+ // before it), and encoding does not help \u2014 the URL standard reads "%2e" as
144
+ // a dot for that check too. Everything else rides percent-encoded.
145
+ if (/^(\\.|%2e){1,2}$/i.test(text)) {
146
+ throw new Error(
147
+ \`\${label}: the path param \\\`\${key}\\\` cannot be "\${text}" \u2014 \` +
148
+ \`a "." or ".." segment addresses a different \${noun}.\`,
149
+ );
150
+ }
151
+ return encodeURIComponent(text);
152
+ });
153
+ }
154
+ `;
155
+ var IMPLEMENTATION = `
156
+ export function routePath(name: RouteName, params?: Record<string, string | number>): string {
157
+ // Read through a widened view: a workspace with no endpoints at all makes
158
+ // \`RouteName\` \`never\`, which cannot index the literal type.
159
+ const route = (ROUTES as Record<string, { verb: string; path: string } | undefined>)[name];
160
+ if (!route) throw new Error(\`routePath: unknown route "\${String(name)}".\`);
161
+ return fillParams(\`routePath("\${String(name)}")\`, "route", route.path, params, true);
162
+ }
163
+ `;
164
+ var REALTIME_IMPLEMENTATION = `
165
+ export function channelPath(name: ChannelName, params?: Record<string, string | number>): string {
166
+ if (!(CHANNELS as Record<string, unknown>)[name]) {
167
+ throw new Error(\`channelPath: unknown channel "\${String(name)}".\`);
168
+ }
169
+ return fillParams(\`channelPath("\${String(name)}")\`, "channel", String(name), params);
170
+ }
171
+
172
+ /** Reject a tenant name that would break the \\\`<tenant>:<canonical>\\\` split. */
173
+ function assertTenant(tenant: string): string {
174
+ if (!/^[A-Za-z0-9-]+$/.test(tenant)) {
175
+ throw new Error(
176
+ \`socketUrl: invalid \\\`tenant\\\` \${JSON.stringify(tenant)} \u2014 a tenant name is alphanumeric with \` +
177
+ \`dashes (e.g. "xxxx-xxxx-xxxx"). It rides as a "<tenant>:<canonical>" prefix, so ":" and "/" \` +
178
+ "cannot appear in it.",
179
+ );
180
+ }
181
+ return tenant;
182
+ }
183
+
184
+ /** The websocket PATH \u2014 \\\`/ws/<canonical>\\\`, or \\\`/ws/<tenant>:<canonical>\\\`. */
185
+ export function socketPath(server: RealtimeServerName, opts?: { tenant?: string }): string {
186
+ const entry = REALTIME_SERVERS[server];
187
+ if (!entry) throw new Error(\`socketPath: unknown realtime server "\${String(server)}".\`);
188
+ const prefix = opts?.tenant ? \`\${assertTenant(opts.tenant)}:\` : "";
189
+ return \`/ws/\${prefix}\${entry.canonical}\`;
190
+ }
191
+
192
+ /** The absolute websocket URL \u2014 \\\`baseUrl\\\` + {@link socketPath}, scheme normalized to ws/wss. */
193
+ export function socketUrl(
194
+ server: RealtimeServerName,
195
+ baseUrl: string,
196
+ opts?: { tenant?: string },
197
+ ): string {
198
+ if (!REALTIME_SERVERS[server]) {
199
+ throw new Error(\`socketUrl: unknown realtime server "\${String(server)}".\`);
200
+ }
201
+ const base = (baseUrl ?? "").trim().replace(/\\/+$/, "");
202
+ if (!base) throw new Error('socketUrl: needs a base URL (e.g. "https://x.dev.xano.io").');
203
+ const socketBase = /^wss?:\\/\\//i.test(base)
204
+ ? base
205
+ : /^https?:\\/\\//i.test(base)
206
+ ? base.replace(/^http/i, "ws")
207
+ : \`wss://\${base}\`;
208
+ // A base URL ending in \\\`/ws/<something>\\\` is this function's own output fed back
209
+ // in. Appending a second \\\`/ws/<canonical>\\\` is wrong twice: the extra segments
210
+ // join the connection hash, and the tenant is dropped (the first call already
211
+ // consumed the \\\`/tenant/<name>\\\` prefix). Refuse rather than dial a bad URL.
212
+ if (/\\/ws\\/[^/]+$/i.test(socketBase)) {
213
+ throw new Error(
214
+ \`socketUrl: \\\`baseUrl\\\` already carries a socket path (\${base}). Pass the http(s) \` +
215
+ "INSTANCE base URL, not the result of a previous socketUrl()/getUrl() \u2014 resolving twice " +
216
+ 'appends a second "/ws/<canonical>" and drops the tenant.',
217
+ );
218
+ }
219
+ // A tenant base URL names its tenant as its own path segment; the socket glues
220
+ // it to the canonical inside one segment. Translate rather than concatenate \u2014
221
+ // the concatenated form never upgrades at all.
222
+ const lifted = /^(wss?:\\/\\/[^/]+)\\/tenant\\/([^/]+)(\\/.*)?$/i.exec(socketBase);
223
+ let origin = socketBase;
224
+ let tenant = opts?.tenant;
225
+ if (lifted) {
226
+ const fromBase = lifted[2]!;
227
+ if (tenant !== undefined && tenant !== fromBase) {
228
+ throw new Error(
229
+ \`socketUrl: given tenant \${JSON.stringify(tenant)} but the base URL names \` +
230
+ \`\${JSON.stringify(fromBase)} (".../tenant/\${fromBase}"). Refusing to guess which one you \` +
231
+ "meant \u2014 pass the matching tenant, or a base URL without the \\"/tenant/<name>\\" prefix.",
232
+ );
233
+ }
234
+ origin = \`\${lifted[1]!}\${lifted[3] ?? ""}\`;
235
+ tenant = assertTenant(fromBase);
236
+ }
237
+ return \`\${origin}\${socketPath(server, { tenant })}\`;
238
+ }
239
+ `;
240
+ export {
241
+ RouteManifestError,
242
+ renderRouteManifest
243
+ };
244
+ //# sourceMappingURL=routes-manifest-SP3ZXLMR.js.map
@@ -0,0 +1,13 @@
1
+ // src/validate/runtime.ts
2
+ async function smokeRunFunctions(client, workspaceId, names, inputs = {}) {
3
+ const out = [];
4
+ for (const name of names) {
5
+ const res = await client.runFunction(workspaceId, name, inputs[name] ?? {});
6
+ out.push({ name, ran: res.ok, status: res.status, detail: res.body });
7
+ }
8
+ return out;
9
+ }
10
+ export {
11
+ smokeRunFunctions
12
+ };
13
+ //# sourceMappingURL=runtime-V4C3AC3A.js.map
@@ -0,0 +1,18 @@
1
+ import {
2
+ fetchSandboxDetails,
3
+ runSandboxDetailsCommand,
4
+ sandboxBaseUrl
5
+ } from "./chunk-7DKX2SPN.js";
6
+ import "./chunk-NDZFBZHC.js";
7
+ import "./chunk-NUQCEOKA.js";
8
+ import "./chunk-3IGNIP6R.js";
9
+ import "./chunk-C56BC2FY.js";
10
+ import "./chunk-7REDODS2.js";
11
+ import "./chunk-EZG76F7R.js";
12
+ import "./chunk-GNPVYOPB.js";
13
+ export {
14
+ fetchSandboxDetails,
15
+ runSandboxDetailsCommand,
16
+ sandboxBaseUrl
17
+ };
18
+ //# sourceMappingURL=sandbox-details-command-HJE5SPVG.js.map
@@ -0,0 +1,24 @@
1
+ import {
2
+ fetchSandboxBundle,
3
+ fetchSandboxMultidoc,
4
+ resolveOutputTarget,
5
+ runSandboxExportCommand
6
+ } from "./chunk-XQ22GLYS.js";
7
+ import "./chunk-QTNO2WD6.js";
8
+ import "./chunk-ZUTSMMAG.js";
9
+ import "./chunk-X4DVXBFY.js";
10
+ import "./chunk-7DKX2SPN.js";
11
+ import "./chunk-NDZFBZHC.js";
12
+ import "./chunk-NUQCEOKA.js";
13
+ import "./chunk-3IGNIP6R.js";
14
+ import "./chunk-C56BC2FY.js";
15
+ import "./chunk-7REDODS2.js";
16
+ import "./chunk-EZG76F7R.js";
17
+ import "./chunk-GNPVYOPB.js";
18
+ export {
19
+ fetchSandboxBundle,
20
+ fetchSandboxMultidoc,
21
+ resolveOutputTarget,
22
+ runSandboxExportCommand
23
+ };
24
+ //# sourceMappingURL=sandbox-export-command-QCJY4GMV.js.map
@@ -0,0 +1,138 @@
1
+ import {
2
+ tarGz
3
+ } from "./chunk-X4DVXBFY.js";
4
+
5
+ // src/deploy/static-host.ts
6
+ import { existsSync, readdirSync, readFileSync } from "fs";
7
+ import { join, relative, sep } from "path";
8
+ var STATIC_TIMEOUT_MS = 12e4;
9
+ var MAX_ARCHIVE_BYTES = 100 * 1024 * 1024;
10
+ function collectFiles(dir) {
11
+ const out = [];
12
+ const walk = (cur) => {
13
+ for (const ent of readdirSync(cur, { withFileTypes: true })) {
14
+ const full = join(cur, ent.name);
15
+ if (ent.isDirectory()) walk(full);
16
+ else if (ent.isFile()) out.push({ path: relative(dir, full).split(sep).join("/"), data: readFileSync(full) });
17
+ }
18
+ };
19
+ walk(dir);
20
+ return out;
21
+ }
22
+ function findSeedLeaks(dir, values) {
23
+ values = values.filter((v) => v.scannable !== false);
24
+ if (values.length === 0 || !existsSync(dir)) return [];
25
+ const leaks = [];
26
+ for (const file of collectFiles(dir)) {
27
+ const text = file.data.toString("latin1");
28
+ for (const v of values) {
29
+ if (text.includes(v.value)) leaks.push({ file: file.path, table: v.table, column: v.column });
30
+ }
31
+ }
32
+ return leaks;
33
+ }
34
+ function tarGz2(files) {
35
+ return tarGz(files.map((f) => ({ name: f.path, data: f.data })));
36
+ }
37
+ function detectRouting(paths) {
38
+ for (const raw of paths) {
39
+ const path = raw.replace(/^\.?\//, "");
40
+ if (path === "" || path.toLowerCase() === "index.html") continue;
41
+ if (/\.html?$/i.test(path)) return "multipage";
42
+ }
43
+ return "spa";
44
+ }
45
+ function pickUrl(parsed) {
46
+ const dev = parsed.dev;
47
+ const direct = [parsed.custom_url, parsed.default_url, parsed.url, dev?.custom_url, dev?.default_url, dev?.url].find(
48
+ (c) => typeof c === "string" && c !== ""
49
+ );
50
+ if (direct !== void 0) return /^https?:\/\//.test(direct) ? direct : `https://${direct}`;
51
+ const host = [dev?.custom, dev?.host].find((c) => typeof c === "string" && c !== "");
52
+ return host !== void 0 ? `https://${host}` : void 0;
53
+ }
54
+ function pickCanonical(parsed) {
55
+ const dev = parsed.dev;
56
+ const build = parsed.build;
57
+ return [parsed.canonical, dev?.canonical, build?.canonical].find(
58
+ (c) => typeof c === "string" && c !== ""
59
+ );
60
+ }
61
+ function envScript(env) {
62
+ const body = Object.entries(env).map(([k, v]) => `window[${JSON.stringify(k)}]=${JSON.stringify(v)};`).join("").replace(/</g, "\\u003c");
63
+ return `<script>${body}</script>`;
64
+ }
65
+ function injectEnv(html, script) {
66
+ const head = /<head[^>]*>/i.exec(html);
67
+ if (!head) return void 0;
68
+ const at = head.index + head[0].length;
69
+ return html.slice(0, at) + script + html.slice(at);
70
+ }
71
+ async function deployStaticHost(req) {
72
+ if (!existsSync(req.dir)) {
73
+ throw new Error(`--static ${req.dir}: directory not found.`);
74
+ }
75
+ const files = collectFiles(req.dir);
76
+ if (files.length === 0) {
77
+ throw new Error(`--static ${req.dir}: no files to deploy (directory is empty).`);
78
+ }
79
+ const envSkipped = [];
80
+ let envDocuments = 0;
81
+ const env = req.env ?? {};
82
+ if (Object.keys(env).length > 0) {
83
+ const script = envScript(env);
84
+ for (const file of files) {
85
+ if (!/\.html?$/i.test(file.path)) continue;
86
+ const rewritten = injectEnv(file.data.toString("utf8"), script);
87
+ if (rewritten === void 0) {
88
+ envSkipped.push(file.path);
89
+ continue;
90
+ }
91
+ file.data = Buffer.from(rewritten, "utf8");
92
+ envDocuments++;
93
+ }
94
+ }
95
+ const archive = tarGz2(files);
96
+ if (archive.length > MAX_ARCHIVE_BYTES) {
97
+ throw new Error(`--static ${req.dir}: archive is ${archive.length} bytes, over the ${MAX_ARCHIVE_BYTES}-byte cap.`);
98
+ }
99
+ const routing = req.routing ?? detectRouting(files.map((f) => f.path));
100
+ const host = req.host ?? "default";
101
+ const url = `${req.baseUrl.replace(/\/$/, "")}/api:meta/workspace/${req.workspaceId}/static_host/${encodeURIComponent(host)}/build`;
102
+ const form = new FormData();
103
+ form.append("name", "xanots-deploy");
104
+ form.append("routing", routing);
105
+ form.append("file", new Blob([archive], { type: "application/gzip" }), "build.tar.gz");
106
+ const res = await fetch(url, {
107
+ method: "POST",
108
+ headers: { Authorization: `Bearer ${req.accessToken}` },
109
+ body: form,
110
+ signal: AbortSignal.timeout(STATIC_TIMEOUT_MS)
111
+ });
112
+ const text = await res.text();
113
+ if (!res.ok) {
114
+ throw new Error(`Static-host build failed (${res.status} ${res.statusText}):
115
+ ${text}`);
116
+ }
117
+ let parsed = {};
118
+ try {
119
+ parsed = JSON.parse(text);
120
+ } catch {
121
+ }
122
+ return {
123
+ url: pickUrl(parsed),
124
+ canonical: pickCanonical(parsed),
125
+ envInjected: envDocuments > 0,
126
+ envDocuments,
127
+ envSkipped,
128
+ routing,
129
+ raw: text
130
+ };
131
+ }
132
+ export {
133
+ deployStaticHost,
134
+ detectRouting,
135
+ findSeedLeaks,
136
+ tarGz2 as tarGz
137
+ };
138
+ //# sourceMappingURL=static-host-D6KS7X45.js.map