run402 1.49.0 → 1.50.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.
- package/core-dist/config.js +10 -0
- package/lib/deploy-v2.mjs +359 -0
- package/lib/deploy.mjs +14 -0
- package/package.json +1 -1
- package/sdk/core-dist/config.js +10 -0
- package/sdk/dist/errors.d.ts +41 -0
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +23 -0
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/index.d.ts +24 -1
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +24 -1
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/apps.d.ts +14 -0
- package/sdk/dist/namespaces/apps.d.ts.map +1 -1
- package/sdk/dist/namespaces/apps.js +175 -20
- package/sdk/dist/namespaces/apps.js.map +1 -1
- package/sdk/dist/namespaces/blobs.d.ts.map +1 -1
- package/sdk/dist/namespaces/blobs.js +20 -6
- package/sdk/dist/namespaces/blobs.js.map +1 -1
- package/sdk/dist/namespaces/blobs.types.d.ts +20 -5
- package/sdk/dist/namespaces/blobs.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +116 -0
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -0
- package/sdk/dist/namespaces/deploy.js +1251 -0
- package/sdk/dist/namespaces/deploy.js.map +1 -0
- package/sdk/dist/namespaces/deploy.types.d.ts +438 -0
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -0
- package/sdk/dist/namespaces/deploy.types.js +11 -0
- package/sdk/dist/namespaces/deploy.types.js.map +1 -0
- package/sdk/dist/node/canonicalize.d.ts +12 -5
- package/sdk/dist/node/canonicalize.d.ts.map +1 -1
- package/sdk/dist/node/canonicalize.js +12 -5
- package/sdk/dist/node/canonicalize.js.map +1 -1
- package/sdk/dist/node/files.d.ts +38 -0
- package/sdk/dist/node/files.d.ts.map +1 -0
- package/sdk/dist/node/files.js +88 -0
- package/sdk/dist/node/files.js.map +1 -0
- package/sdk/dist/node/index.d.ts +5 -3
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +2 -1
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/sites-node.d.ts +34 -107
- package/sdk/dist/node/sites-node.d.ts.map +1 -1
- package/sdk/dist/node/sites-node.js +91 -353
- package/sdk/dist/node/sites-node.js.map +1 -1
package/core-dist/config.js
CHANGED
|
@@ -4,6 +4,16 @@ import { existsSync, renameSync, mkdirSync } from "node:fs";
|
|
|
4
4
|
export function getApiBase() {
|
|
5
5
|
return process.env.RUN402_API_BASE || "https://api.run402.com";
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* API base for the deploy-v2 routes. Defaults to the same value as
|
|
9
|
+
* `getApiBase()`. Set `RUN402_DEPLOY_API_BASE` to point only deploy traffic
|
|
10
|
+
* elsewhere — useful when running deploy-v2 against a staging gateway while
|
|
11
|
+
* the rest of the SDK still talks to production. In normal use callers
|
|
12
|
+
* should not need this override.
|
|
13
|
+
*/
|
|
14
|
+
export function getDeployApiBase() {
|
|
15
|
+
return process.env.RUN402_DEPLOY_API_BASE || getApiBase();
|
|
16
|
+
}
|
|
7
17
|
export function getConfigDir() {
|
|
8
18
|
return process.env.RUN402_CONFIG_DIR || join(homedir(), ".config", "run402");
|
|
9
19
|
}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `run402 deploy apply` and `run402 deploy resume` — CLI wrappers over the
|
|
3
|
+
* unified deploy primitive (`r.deploy.apply` / `r.deploy.resume`).
|
|
4
|
+
*
|
|
5
|
+
* The legacy `run402 deploy --manifest …` command is preserved in
|
|
6
|
+
* `cli/lib/deploy.mjs` and continues to work; this file adds the new
|
|
7
|
+
* subcommand surface.
|
|
8
|
+
*
|
|
9
|
+
* Manifest format mirrors the MCP `deploy` tool's input schema:
|
|
10
|
+
* {
|
|
11
|
+
* "project_id": "...",
|
|
12
|
+
* "base": { "release": "current" } | { "release": "empty" } | { "release_id": "..." },
|
|
13
|
+
* "database": { "migrations": [...], "expose": {...}, "zero_downtime": false },
|
|
14
|
+
* "secrets": { "set": {...}, "delete": [...], "replace_all": {...} },
|
|
15
|
+
* "functions": { "replace": {...}, "patch": { "set": {...}, "delete": [...] } },
|
|
16
|
+
* "site": { "replace": {...} } | { "patch": { "put": {...}, "delete": [...] } },
|
|
17
|
+
* "subdomains": { "set": ["..."], "add": [...], "remove": [...] },
|
|
18
|
+
* "idempotency_key": "..."
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* File entries: `{ "data": "...", "encoding": "utf-8" | "base64", "contentType": "..." }`
|
|
22
|
+
* — same shape used by `bundle_deploy`. UTF-8 is the default; binary files
|
|
23
|
+
* pass `"encoding": "base64"`.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import { resolve, dirname, isAbsolute, join } from "node:path";
|
|
28
|
+
import { getSdk } from "./sdk.mjs";
|
|
29
|
+
import { reportSdkError } from "./sdk-errors.mjs";
|
|
30
|
+
import { allowanceAuthHeaders, resolveProjectId } from "./config.mjs";
|
|
31
|
+
|
|
32
|
+
const APPLY_HELP = `run402 deploy apply — Unified deploy primitive (v1.34+)
|
|
33
|
+
|
|
34
|
+
Usage:
|
|
35
|
+
run402 deploy apply --manifest <path> [--project <id>] [--quiet]
|
|
36
|
+
run402 deploy apply --spec '<json>' [--project <id>] [--quiet]
|
|
37
|
+
cat spec.json | run402 deploy apply [--project <id>]
|
|
38
|
+
|
|
39
|
+
Manifest format mirrors the MCP \`deploy\` tool's ReleaseSpec:
|
|
40
|
+
{
|
|
41
|
+
"project_id": "prj_...",
|
|
42
|
+
"base": { "release": "current" },
|
|
43
|
+
"database": { "migrations": [{ "id": "001_init", "sql": "CREATE TABLE ..." }], "expose": {...} },
|
|
44
|
+
"secrets": { "set": { "OPENAI_API_KEY": { "value": "sk-..." } } },
|
|
45
|
+
"functions": { "replace": { "api": { "source": { "data": "export default ..." } } } },
|
|
46
|
+
"site": { "replace": { "index.html": { "data": "<html>..." } } },
|
|
47
|
+
"subdomains": { "set": ["my-app"] }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Options:
|
|
51
|
+
--manifest <path> Read the spec from this JSON file
|
|
52
|
+
--spec '<json>' Inline JSON spec (single-quote in shell)
|
|
53
|
+
--project <id> Override project_id from the manifest
|
|
54
|
+
--quiet Suppress per-event JSON-line stderr (final result still on stdout)
|
|
55
|
+
|
|
56
|
+
Output:
|
|
57
|
+
stdout: { "status": "ok", "release_id": "rel_...", "operation_id": "op_...", "urls": {...} }
|
|
58
|
+
stderr: one JSON event per line (suppressed with --quiet)
|
|
59
|
+
|
|
60
|
+
Patch examples (only the listed file changes):
|
|
61
|
+
{ "project_id": "prj_...", "site": { "patch": { "put": { "index.html": { "data": "..." } } } } }
|
|
62
|
+
{ "project_id": "prj_...", "site": { "patch": { "delete": ["old.html"] } } }
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
const RESUME_HELP = `run402 deploy resume — Resume a stuck deploy operation
|
|
66
|
+
|
|
67
|
+
Usage:
|
|
68
|
+
run402 deploy resume <operation_id> [--quiet]
|
|
69
|
+
|
|
70
|
+
Used when a previous \`deploy apply\` ended in \`activation_pending\` or
|
|
71
|
+
\`schema_settling\` (e.g. transient gateway failure between SQL commit and
|
|
72
|
+
the pointer-swap activation). The gateway re-runs only the failed phase
|
|
73
|
+
forward — SQL is never replayed.
|
|
74
|
+
|
|
75
|
+
Output:
|
|
76
|
+
stdout: { "status": "ok", "release_id": "...", "operation_id": "...", "urls": {...} }
|
|
77
|
+
stderr: one JSON event per line (suppressed with --quiet)
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
export async function runDeployV2(sub, args) {
|
|
81
|
+
if (sub === "apply") return await applyCmd(args);
|
|
82
|
+
if (sub === "resume") return await resumeCmd(args);
|
|
83
|
+
console.error(JSON.stringify({ status: "error", message: `Unknown deploy subcommand: ${sub}` }));
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function readStdin() {
|
|
88
|
+
const chunks = [];
|
|
89
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
90
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function makeStderrEventWriter(quiet) {
|
|
94
|
+
if (quiet) return undefined;
|
|
95
|
+
return (event) => {
|
|
96
|
+
console.error(JSON.stringify(event));
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function applyCmd(args) {
|
|
101
|
+
const opts = { manifest: null, spec: null, project: null, quiet: false };
|
|
102
|
+
for (let i = 0; i < args.length; i++) {
|
|
103
|
+
if (args[i] === "--help" || args[i] === "-h") { console.log(APPLY_HELP); process.exit(0); }
|
|
104
|
+
if (args[i] === "--manifest" && args[i + 1]) { opts.manifest = args[++i]; continue; }
|
|
105
|
+
if (args[i] === "--spec" && args[i + 1]) { opts.spec = args[++i]; continue; }
|
|
106
|
+
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
107
|
+
if (args[i] === "--quiet") { opts.quiet = true; continue; }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let raw;
|
|
111
|
+
if (opts.spec) {
|
|
112
|
+
raw = opts.spec;
|
|
113
|
+
} else if (opts.manifest) {
|
|
114
|
+
try {
|
|
115
|
+
const manifestPath = isAbsolute(opts.manifest) ? opts.manifest : resolve(process.cwd(), opts.manifest);
|
|
116
|
+
raw = readFileSync(manifestPath, "utf-8");
|
|
117
|
+
} catch (err) {
|
|
118
|
+
console.error(JSON.stringify({ status: "error", message: `Failed to read manifest: ${err.message}` }));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
raw = await readStdin();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let spec;
|
|
126
|
+
try {
|
|
127
|
+
spec = JSON.parse(raw);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error(JSON.stringify({ status: "error", message: `Manifest is not valid JSON: ${err.message}` }));
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (opts.manifest) resolveFileDataPaths(spec, dirname(resolve(opts.manifest)));
|
|
134
|
+
|
|
135
|
+
if (opts.project && spec.project_id && spec.project_id !== opts.project) {
|
|
136
|
+
console.error(JSON.stringify({
|
|
137
|
+
status: "error",
|
|
138
|
+
message: `project_id conflict: spec.project_id=${spec.project_id} but --project=${opts.project}`,
|
|
139
|
+
}));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
if (opts.project) spec.project_id = opts.project;
|
|
143
|
+
if (!spec.project_id) spec.project_id = resolveProjectId(null);
|
|
144
|
+
|
|
145
|
+
// Translate { project_id, ... } envelope → ReleaseSpec ({ project, ... })
|
|
146
|
+
// The SDK ReleaseSpec uses `project` rather than `project_id`; both shapes
|
|
147
|
+
// are accepted at the manifest layer (project_id is friendlier for agents
|
|
148
|
+
// sharing JSON manifests with the MCP tool).
|
|
149
|
+
const releaseSpec = mapManifestToReleaseSpec(spec);
|
|
150
|
+
const idempotencyKey = spec.idempotency_key;
|
|
151
|
+
|
|
152
|
+
// Preserve the aggressive early exit when no allowance is configured.
|
|
153
|
+
allowanceAuthHeaders("/deploy/v2/plans");
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const result = await getSdk().deploy.apply(releaseSpec, {
|
|
157
|
+
onEvent: makeStderrEventWriter(opts.quiet),
|
|
158
|
+
idempotencyKey,
|
|
159
|
+
});
|
|
160
|
+
console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
|
|
161
|
+
} catch (err) {
|
|
162
|
+
reportSdkError(err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function resumeCmd(args) {
|
|
167
|
+
const opts = { operationId: null, quiet: false };
|
|
168
|
+
for (let i = 0; i < args.length; i++) {
|
|
169
|
+
if (args[i] === "--help" || args[i] === "-h") { console.log(RESUME_HELP); process.exit(0); }
|
|
170
|
+
if (args[i] === "--quiet") { opts.quiet = true; continue; }
|
|
171
|
+
if (!args[i].startsWith("-") && !opts.operationId) opts.operationId = args[i];
|
|
172
|
+
}
|
|
173
|
+
if (!opts.operationId) {
|
|
174
|
+
console.error(JSON.stringify({ status: "error", message: "Usage: run402 deploy resume <operation_id>" }));
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
allowanceAuthHeaders("/deploy/v2/operations");
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const result = await getSdk().deploy.resume(opts.operationId, {
|
|
182
|
+
onEvent: makeStderrEventWriter(opts.quiet),
|
|
183
|
+
});
|
|
184
|
+
console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
|
|
185
|
+
} catch (err) {
|
|
186
|
+
reportSdkError(err);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ─── Manifest → ReleaseSpec ──────────────────────────────────────────────────
|
|
191
|
+
|
|
192
|
+
function mapManifestToReleaseSpec(spec) {
|
|
193
|
+
const out = { project: spec.project_id };
|
|
194
|
+
if (spec.base !== undefined) out.base = spec.base;
|
|
195
|
+
if (spec.subdomains !== undefined) out.subdomains = spec.subdomains;
|
|
196
|
+
if (spec.secrets !== undefined) out.secrets = spec.secrets;
|
|
197
|
+
if (spec.routes !== undefined) out.routes = spec.routes;
|
|
198
|
+
if (spec.checks !== undefined) out.checks = spec.checks;
|
|
199
|
+
|
|
200
|
+
if (spec.database) {
|
|
201
|
+
out.database = {};
|
|
202
|
+
if (spec.database.expose !== undefined) out.database.expose = spec.database.expose;
|
|
203
|
+
if (spec.database.zero_downtime !== undefined) out.database.zero_downtime = spec.database.zero_downtime;
|
|
204
|
+
if (spec.database.migrations) {
|
|
205
|
+
out.database.migrations = spec.database.migrations.map((m) => {
|
|
206
|
+
const mm = { id: m.id };
|
|
207
|
+
if (m.sql !== undefined) mm.sql = m.sql;
|
|
208
|
+
if (m.sql_ref !== undefined) mm.sql_ref = m.sql_ref;
|
|
209
|
+
if (m.checksum !== undefined) mm.checksum = m.checksum;
|
|
210
|
+
if (m.transaction !== undefined) mm.transaction = m.transaction;
|
|
211
|
+
return mm;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (spec.functions) {
|
|
217
|
+
out.functions = {};
|
|
218
|
+
if (spec.functions.replace) out.functions.replace = mapFunctionMap(spec.functions.replace);
|
|
219
|
+
if (spec.functions.patch) {
|
|
220
|
+
out.functions.patch = {};
|
|
221
|
+
if (spec.functions.patch.set) out.functions.patch.set = mapFunctionMap(spec.functions.patch.set);
|
|
222
|
+
if (spec.functions.patch.delete) out.functions.patch.delete = spec.functions.patch.delete;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (spec.site) {
|
|
227
|
+
if (spec.site.replace) {
|
|
228
|
+
out.site = { replace: mapFileMap(spec.site.replace) };
|
|
229
|
+
} else if (spec.site.patch) {
|
|
230
|
+
const patch = {};
|
|
231
|
+
if (spec.site.patch.put) patch.put = mapFileMap(spec.site.patch.put);
|
|
232
|
+
if (spec.site.patch.delete) patch.delete = spec.site.patch.delete;
|
|
233
|
+
out.site = { patch };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function mapFunctionMap(map) {
|
|
241
|
+
const out = {};
|
|
242
|
+
for (const [name, fn] of Object.entries(map)) {
|
|
243
|
+
const f = {};
|
|
244
|
+
if (fn.runtime) f.runtime = fn.runtime;
|
|
245
|
+
if (fn.source !== undefined) f.source = fileEntryToContentSource(fn.source);
|
|
246
|
+
if (fn.files) f.files = mapFileMap(fn.files);
|
|
247
|
+
if (fn.entrypoint !== undefined) f.entrypoint = fn.entrypoint;
|
|
248
|
+
if (fn.config !== undefined) f.config = fn.config;
|
|
249
|
+
if (fn.schedule !== undefined) f.schedule = fn.schedule;
|
|
250
|
+
out[name] = f;
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function mapFileMap(map) {
|
|
256
|
+
const out = {};
|
|
257
|
+
for (const [path, entry] of Object.entries(map)) {
|
|
258
|
+
out[path] = fileEntryToContentSource(entry);
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function fileEntryToContentSource(entry) {
|
|
264
|
+
if (entry === null || entry === undefined) return entry;
|
|
265
|
+
if (typeof entry === "string") return entry;
|
|
266
|
+
if (entry instanceof Uint8Array) return entry;
|
|
267
|
+
if (typeof entry === "object") {
|
|
268
|
+
if (entry.encoding === "base64" && typeof entry.data === "string") {
|
|
269
|
+
const bytes = Buffer.from(entry.data, "base64");
|
|
270
|
+
const u8 = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
271
|
+
return entry.contentType ? { data: u8, contentType: entry.contentType } : u8;
|
|
272
|
+
}
|
|
273
|
+
if (typeof entry.data === "string") {
|
|
274
|
+
return entry.contentType ? { data: entry.data, contentType: entry.contentType } : entry.data;
|
|
275
|
+
}
|
|
276
|
+
// Pre-resolved ContentRef shape — pass through.
|
|
277
|
+
if (typeof entry.sha256 === "string" && typeof entry.size === "number") {
|
|
278
|
+
return entry;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return entry;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Resolve any `{ "path": "..." }` entries in the manifest to inline data.
|
|
286
|
+
* Mirrors the legacy deploy.mjs behavior so `run402 deploy apply` accepts
|
|
287
|
+
* the same files-with-paths shape that `run402 deploy` does today.
|
|
288
|
+
*/
|
|
289
|
+
function resolveFileDataPaths(spec, baseDir) {
|
|
290
|
+
// Site files
|
|
291
|
+
if (spec.site?.replace) resolveMap(spec.site.replace, baseDir);
|
|
292
|
+
if (spec.site?.patch?.put) resolveMap(spec.site.patch.put, baseDir);
|
|
293
|
+
// Function files
|
|
294
|
+
const visitFns = (fnMap) => {
|
|
295
|
+
if (!fnMap) return;
|
|
296
|
+
for (const fn of Object.values(fnMap)) {
|
|
297
|
+
if (fn.source && typeof fn.source === "object" && fn.source.path) {
|
|
298
|
+
const resolved = readFileEntry(fn.source, baseDir);
|
|
299
|
+
if (resolved) fn.source = resolved;
|
|
300
|
+
}
|
|
301
|
+
if (fn.files) resolveMap(fn.files, baseDir);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
visitFns(spec.functions?.replace);
|
|
305
|
+
visitFns(spec.functions?.patch?.set);
|
|
306
|
+
// Migration sql_path / sql_file
|
|
307
|
+
if (spec.database?.migrations) {
|
|
308
|
+
for (const m of spec.database.migrations) {
|
|
309
|
+
if (!m.sql && m.sql_path) {
|
|
310
|
+
try {
|
|
311
|
+
const p = isAbsolute(m.sql_path) ? m.sql_path : join(baseDir, m.sql_path);
|
|
312
|
+
m.sql = readFileSync(p, "utf-8");
|
|
313
|
+
delete m.sql_path;
|
|
314
|
+
} catch (err) {
|
|
315
|
+
console.error(JSON.stringify({
|
|
316
|
+
status: "error",
|
|
317
|
+
message: `Failed to read migration sql_path '${m.sql_path}': ${err.message}`,
|
|
318
|
+
}));
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function resolveMap(map, baseDir) {
|
|
327
|
+
for (const [key, entry] of Object.entries(map)) {
|
|
328
|
+
if (entry && typeof entry === "object" && typeof entry.path === "string" && entry.data === undefined) {
|
|
329
|
+
const resolved = readFileEntry(entry, baseDir);
|
|
330
|
+
if (resolved) map[key] = resolved;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function readFileEntry(entry, baseDir) {
|
|
336
|
+
try {
|
|
337
|
+
const p = isAbsolute(entry.path) ? entry.path : join(baseDir, entry.path);
|
|
338
|
+
const buf = readFileSync(p);
|
|
339
|
+
const out = {};
|
|
340
|
+
// Detect text vs binary via simple UTF-8 round-trip; mirrors the bundle
|
|
341
|
+
// deploy behavior. Image/font types get base64; HTML/CSS/JS stay UTF-8.
|
|
342
|
+
const looksTextual = !entry.contentType?.match(/^(image|font|application\/(pdf|wasm|octet-stream|zip))/);
|
|
343
|
+
if (looksTextual) {
|
|
344
|
+
out.data = buf.toString("utf-8");
|
|
345
|
+
out.encoding = "utf-8";
|
|
346
|
+
} else {
|
|
347
|
+
out.data = buf.toString("base64");
|
|
348
|
+
out.encoding = "base64";
|
|
349
|
+
}
|
|
350
|
+
if (entry.contentType) out.contentType = entry.contentType;
|
|
351
|
+
return out;
|
|
352
|
+
} catch (err) {
|
|
353
|
+
console.error(JSON.stringify({
|
|
354
|
+
status: "error",
|
|
355
|
+
message: `Failed to read file '${entry.path}': ${err.message}`,
|
|
356
|
+
}));
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
}
|
package/lib/deploy.mjs
CHANGED
|
@@ -255,6 +255,20 @@ async function loadManifest(opts) {
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
export async function run(args) {
|
|
258
|
+
// Subcommand dispatch (v1.34+):
|
|
259
|
+
// run402 deploy apply ... → unified deploy primitive (deploy.apply)
|
|
260
|
+
// run402 deploy resume <op> → resume an activation_pending operation
|
|
261
|
+
// run402 deploy --manifest … → legacy bundle deploy (still works)
|
|
262
|
+
const sub = args[0];
|
|
263
|
+
switch (sub) {
|
|
264
|
+
case "apply":
|
|
265
|
+
case "resume": {
|
|
266
|
+
const { runDeployV2 } = await import("./deploy-v2.mjs");
|
|
267
|
+
await runDeployV2(sub, args.slice(1));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
258
272
|
const opts = { manifest: null, project: null };
|
|
259
273
|
for (let i = 0; i < args.length; i++) {
|
|
260
274
|
if (args[i] === "--help" || args[i] === "-h") { console.log(HELP); process.exit(0); }
|
package/package.json
CHANGED
package/sdk/core-dist/config.js
CHANGED
|
@@ -4,6 +4,16 @@ import { existsSync, renameSync, mkdirSync } from "node:fs";
|
|
|
4
4
|
export function getApiBase() {
|
|
5
5
|
return process.env.RUN402_API_BASE || "https://api.run402.com";
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* API base for the deploy-v2 routes. Defaults to the same value as
|
|
9
|
+
* `getApiBase()`. Set `RUN402_DEPLOY_API_BASE` to point only deploy traffic
|
|
10
|
+
* elsewhere — useful when running deploy-v2 against a staging gateway while
|
|
11
|
+
* the rest of the SDK still talks to production. In normal use callers
|
|
12
|
+
* should not need this override.
|
|
13
|
+
*/
|
|
14
|
+
export function getDeployApiBase() {
|
|
15
|
+
return process.env.RUN402_DEPLOY_API_BASE || getApiBase();
|
|
16
|
+
}
|
|
7
17
|
export function getConfigDir() {
|
|
8
18
|
return process.env.RUN402_CONFIG_DIR || join(homedir(), ".config", "run402");
|
|
9
19
|
}
|
package/sdk/dist/errors.d.ts
CHANGED
|
@@ -36,4 +36,45 @@ export declare class LocalError extends Run402Error {
|
|
|
36
36
|
readonly cause?: unknown;
|
|
37
37
|
constructor(message: string, context: string, cause?: unknown);
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Deploy-state-machine failure surfaced from the v2 deploy flow. Carries the
|
|
41
|
+
* structured error envelope the gateway returns alongside the operation
|
|
42
|
+
* snapshot — phase, resource, retryability, and an optional remediation hint.
|
|
43
|
+
*
|
|
44
|
+
* The `code` enumerates the gateway's deploy error codes; consumers may
|
|
45
|
+
* switch on it to decide whether to retry, prompt the user for payment, ask
|
|
46
|
+
* for a fix, or escalate. Unknown codes from a newer gateway pass through
|
|
47
|
+
* verbatim — callers should treat unrecognized values as opaque.
|
|
48
|
+
*/
|
|
49
|
+
export type Run402DeployErrorCode = "MIGRATION_FAILED" | "MIGRATION_CHECKSUM_MISMATCH" | "MIGRATION_SQL_NOT_FOUND" | "BASE_RELEASE_CONFLICT" | "PAYMENT_REQUIRED" | "SUBDOMAIN_MULTI_NOT_SUPPORTED" | "SCHEMA_SETTLE_TIMEOUT" | "ACTIVATION_FAILED" | "STORAGE_UNAVAILABLE" | "SITE_STAGE_FAILED" | "FUNCTION_BUILD_FAILED" | "CONTENT_UPLOAD_FAILED" | "INVALID_SPEC" | "OPERATION_NOT_FOUND" | "PLAN_NOT_FOUND" | "NOT_RESUMABLE" | "INVALID_STATE" | "RESUME_FAILED" | "INTERNAL_ERROR" | "NETWORK_ERROR" | "PROJECT_NOT_FOUND" | (string & {});
|
|
50
|
+
export interface Run402DeployErrorFix {
|
|
51
|
+
action: string;
|
|
52
|
+
path?: string;
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
export declare class Run402DeployError extends Run402Error {
|
|
56
|
+
readonly code: Run402DeployErrorCode;
|
|
57
|
+
readonly phase: string | null;
|
|
58
|
+
readonly resource: string | null;
|
|
59
|
+
readonly retryable: boolean;
|
|
60
|
+
readonly operationId: string | null;
|
|
61
|
+
readonly planId: string | null;
|
|
62
|
+
readonly fix: Run402DeployErrorFix | null;
|
|
63
|
+
readonly logs: string[] | null;
|
|
64
|
+
readonly rolledBack: boolean;
|
|
65
|
+
constructor(message: string, init: {
|
|
66
|
+
code: Run402DeployErrorCode;
|
|
67
|
+
phase?: string | null;
|
|
68
|
+
resource?: string | null;
|
|
69
|
+
retryable?: boolean;
|
|
70
|
+
operationId?: string | null;
|
|
71
|
+
planId?: string | null;
|
|
72
|
+
fix?: Run402DeployErrorFix | null;
|
|
73
|
+
logs?: string[] | null;
|
|
74
|
+
rolledBack?: boolean;
|
|
75
|
+
status?: number | null;
|
|
76
|
+
body?: unknown;
|
|
77
|
+
context: string;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
39
80
|
//# sourceMappingURL=errors.d.ts.map
|
package/sdk/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8BAAsB,WAAY,SAAQ,KAAK;IAC7C,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM;CAOnF;AAED,oGAAoG;AACpG,qBAAa,eAAgB,SAAQ,WAAW;CAAG;AAEnD,qGAAqG;AACrG,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBACf,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,IAAW,EAAE,IAAI,GAAE,OAAc;CAInG;AAED,4FAA4F;AAC5F,qBAAa,YAAa,SAAQ,WAAW;CAAG;AAEhD,wDAAwD;AACxD,qBAAa,QAAS,SAAQ,WAAW;CAAG;AAE5C,iGAAiG;AACjG,qBAAa,YAAa,SAAQ,WAAW;IAC3C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM;CAI7D;AAED,iGAAiG;AACjG,qBAAa,UAAW,SAAQ,WAAW;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBACb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI9D"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/sdk/dist/errors.js
CHANGED
|
@@ -52,4 +52,27 @@ export class LocalError extends Run402Error {
|
|
|
52
52
|
this.cause = cause;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
export class Run402DeployError extends Run402Error {
|
|
56
|
+
code;
|
|
57
|
+
phase;
|
|
58
|
+
resource;
|
|
59
|
+
retryable;
|
|
60
|
+
operationId;
|
|
61
|
+
planId;
|
|
62
|
+
fix;
|
|
63
|
+
logs;
|
|
64
|
+
rolledBack;
|
|
65
|
+
constructor(message, init) {
|
|
66
|
+
super(message, init.status ?? null, init.body ?? null, init.context);
|
|
67
|
+
this.code = init.code;
|
|
68
|
+
this.phase = init.phase ?? null;
|
|
69
|
+
this.resource = init.resource ?? null;
|
|
70
|
+
this.retryable = init.retryable ?? false;
|
|
71
|
+
this.operationId = init.operationId ?? null;
|
|
72
|
+
this.planId = init.planId ?? null;
|
|
73
|
+
this.fix = init.fix ?? null;
|
|
74
|
+
this.logs = init.logs ?? null;
|
|
75
|
+
this.rolledBack = init.rolledBack ?? false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
55
78
|
//# sourceMappingURL=errors.js.map
|
package/sdk/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAgB,WAAY,SAAQ,KAAK;IAC7C,iFAAiF;IACxE,MAAM,CAAgB;IAC/B,+DAA+D;IACtD,IAAI,CAAU;IACvB,2FAA2F;IAClF,OAAO,CAAS;IAEzB,YAAY,OAAe,EAAE,MAAqB,EAAE,IAAa,EAAE,OAAe;QAChF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,oGAAoG;AACpG,MAAM,OAAO,eAAgB,SAAQ,WAAW;CAAG;AAEnD,qGAAqG;AACrG,MAAM,OAAO,eAAgB,SAAQ,WAAW;IACrC,SAAS,CAAS;IAC3B,YAAY,SAAiB,EAAE,OAAe,EAAE,SAAwB,IAAI,EAAE,OAAgB,IAAI;QAChG,KAAK,CAAC,WAAW,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,4FAA4F;AAC5F,MAAM,OAAO,YAAa,SAAQ,WAAW;CAAG;AAEhD,wDAAwD;AACxD,MAAM,OAAO,QAAS,SAAQ,WAAW;CAAG;AAE5C,iGAAiG;AACjG,MAAM,OAAO,YAAa,SAAQ,WAAW;IAClC,KAAK,CAAU;IACxB,YAAY,OAAe,EAAE,KAAc,EAAE,OAAe;QAC1D,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,iGAAiG;AACjG,MAAM,OAAO,UAAW,SAAQ,WAAW;IAChC,KAAK,CAAW;IACzB,YAAY,OAAe,EAAE,OAAe,EAAE,KAAe;QAC3D,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAC9C,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/sdk/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ import { Apps } from "./namespaces/apps.js";
|
|
|
24
24
|
import { Email } from "./namespaces/email.js";
|
|
25
25
|
import { Contracts } from "./namespaces/contracts.js";
|
|
26
26
|
import { Admin } from "./namespaces/admin.js";
|
|
27
|
+
import { Deploy } from "./namespaces/deploy.js";
|
|
28
|
+
import type { ContentSource, FileSet } from "./namespaces/deploy.types.js";
|
|
27
29
|
export interface Run402Options {
|
|
28
30
|
/** API base URL, e.g. `https://api.run402.com`. */
|
|
29
31
|
apiBase: string;
|
|
@@ -55,14 +57,35 @@ export declare class Run402 {
|
|
|
55
57
|
readonly email: Email;
|
|
56
58
|
readonly contracts: Contracts;
|
|
57
59
|
readonly admin: Admin;
|
|
60
|
+
readonly deploy: Deploy;
|
|
58
61
|
constructor(opts: Run402Options);
|
|
59
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Build a `FileSet` from a path-keyed record of byte sources. A passthrough
|
|
65
|
+
* convenience: the SDK can consume the same shape whether you call this or
|
|
66
|
+
* pass the literal directly. Useful for IDE autocomplete on the
|
|
67
|
+
* `ContentSource` union and for keeping deploy specs declarative.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* await r.deploy.apply({
|
|
71
|
+
* project,
|
|
72
|
+
* site: { replace: files({
|
|
73
|
+
* "index.html": "<h1>hi</h1>",
|
|
74
|
+
* "logo.png": logoBytes,
|
|
75
|
+
* "data.json": new Blob([JSON.stringify(d)], { type: "application/json" }),
|
|
76
|
+
* })},
|
|
77
|
+
* });
|
|
78
|
+
*/
|
|
79
|
+
export declare function files(record: Record<string, ContentSource>): FileSet;
|
|
60
80
|
/**
|
|
61
81
|
* Factory wrapper equivalent to `new Run402(opts)`. Reads better in code-mode
|
|
62
82
|
* sandbox examples: `const r = run402({ ... })`.
|
|
63
83
|
*/
|
|
64
84
|
export declare function run402(opts: Run402Options): Run402;
|
|
65
|
-
export { Run402Error, PaymentRequired, ProjectNotFound, Unauthorized, ApiError, NetworkError, LocalError, } from "./errors.js";
|
|
85
|
+
export { Run402Error, PaymentRequired, ProjectNotFound, Unauthorized, ApiError, NetworkError, LocalError, Run402DeployError, } from "./errors.js";
|
|
86
|
+
export type { Run402DeployErrorCode, Run402DeployErrorFix, } from "./errors.js";
|
|
66
87
|
export type { CredentialsProvider, ProjectKeys } from "./credentials.js";
|
|
67
88
|
export type { RequestOptions, Client } from "./kernel.js";
|
|
89
|
+
export { Deploy } from "./namespaces/deploy.js";
|
|
90
|
+
export type { ApplyOptions, CommitResponse, CommitStatus, ContentRef, ContentSource, DatabaseSpec, DeployDiff, DeployEvent, DeployOperation, DeployResult, ExposeManifest, FileSet, FsFileSource, FunctionSpec, FunctionsSpec, MigrationSpec, MissingContent, OperationSnapshot, OperationStatus, PaymentRequiredHint, PlanRequest, PlanResponse, ReleaseSpec, RouteSpec, SecretsSpec, SiteSpec, SmokeCheck, StartOptions, SubdomainsSpec, } from "./namespaces/deploy.types.js";
|
|
68
91
|
//# sourceMappingURL=index.d.ts.map
|
package/sdk/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/sdk/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { Apps } from "./namespaces/apps.js";
|
|
|
24
24
|
import { Email } from "./namespaces/email.js";
|
|
25
25
|
import { Contracts } from "./namespaces/contracts.js";
|
|
26
26
|
import { Admin } from "./namespaces/admin.js";
|
|
27
|
+
import { Deploy } from "./namespaces/deploy.js";
|
|
27
28
|
export class Run402 {
|
|
28
29
|
projects;
|
|
29
30
|
blobs;
|
|
@@ -43,6 +44,7 @@ export class Run402 {
|
|
|
43
44
|
email;
|
|
44
45
|
contracts;
|
|
45
46
|
admin;
|
|
47
|
+
deploy;
|
|
46
48
|
constructor(opts) {
|
|
47
49
|
const kernel = {
|
|
48
50
|
apiBase: opts.apiBase,
|
|
@@ -68,8 +70,28 @@ export class Run402 {
|
|
|
68
70
|
this.email = new Email(client);
|
|
69
71
|
this.contracts = new Contracts(client);
|
|
70
72
|
this.admin = new Admin(client);
|
|
73
|
+
this.deploy = new Deploy(client);
|
|
71
74
|
}
|
|
72
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Build a `FileSet` from a path-keyed record of byte sources. A passthrough
|
|
78
|
+
* convenience: the SDK can consume the same shape whether you call this or
|
|
79
|
+
* pass the literal directly. Useful for IDE autocomplete on the
|
|
80
|
+
* `ContentSource` union and for keeping deploy specs declarative.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* await r.deploy.apply({
|
|
84
|
+
* project,
|
|
85
|
+
* site: { replace: files({
|
|
86
|
+
* "index.html": "<h1>hi</h1>",
|
|
87
|
+
* "logo.png": logoBytes,
|
|
88
|
+
* "data.json": new Blob([JSON.stringify(d)], { type: "application/json" }),
|
|
89
|
+
* })},
|
|
90
|
+
* });
|
|
91
|
+
*/
|
|
92
|
+
export function files(record) {
|
|
93
|
+
return record;
|
|
94
|
+
}
|
|
73
95
|
/**
|
|
74
96
|
* Factory wrapper equivalent to `new Run402(opts)`. Reads better in code-mode
|
|
75
97
|
* sandbox examples: `const r = run402({ ... })`.
|
|
@@ -77,5 +99,6 @@ export class Run402 {
|
|
|
77
99
|
export function run402(opts) {
|
|
78
100
|
return new Run402(opts);
|
|
79
101
|
}
|
|
80
|
-
export { Run402Error, PaymentRequired, ProjectNotFound, Unauthorized, ApiError, NetworkError, LocalError, } from "./errors.js";
|
|
102
|
+
export { Run402Error, PaymentRequired, ProjectNotFound, Unauthorized, ApiError, NetworkError, LocalError, Run402DeployError, } from "./errors.js";
|
|
103
|
+
export { Deploy } from "./namespaces/deploy.js";
|
|
81
104
|
//# sourceMappingURL=index.js.map
|
package/sdk/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAkC,MAAM,aAAa,CAAC;AAE1E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|