primitive-admin 1.1.0-alpha.4 → 1.1.0-alpha.40
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 +325 -31
- package/assets/skill/skills/primitive-platform/SKILL.md +281 -0
- package/dist/bin/primitive.d.ts +2 -0
- package/dist/bin/primitive.js +266 -16
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.d.ts +2 -0
- package/dist/src/commands/admins.js +123 -18
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +2 -0
- package/dist/src/commands/analytics.js +464 -55
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.d.ts +2 -0
- package/dist/src/commands/apps.js +55 -13
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +177 -7
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.d.ts +2 -0
- package/dist/src/commands/blob-buckets.js +422 -0
- package/dist/src/commands/blob-buckets.js.map +1 -0
- package/dist/src/commands/catalog.d.ts +2 -0
- package/dist/src/commands/catalog.js +34 -35
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.d.ts +2 -0
- package/dist/src/commands/collection-type-configs.js +178 -0
- package/dist/src/commands/collection-type-configs.js.map +1 -0
- package/dist/src/commands/collections.d.ts +2 -0
- package/dist/src/commands/collections.js +515 -0
- package/dist/src/commands/collections.js.map +1 -0
- package/dist/src/commands/comparisons.d.ts +2 -0
- package/dist/src/commands/comparisons.js +6 -6
- package/dist/src/commands/comparisons.js.map +1 -1
- package/dist/src/commands/cron-triggers.d.ts +2 -0
- package/dist/src/commands/cron-triggers.js +357 -0
- package/dist/src/commands/cron-triggers.js.map +1 -0
- package/dist/src/commands/database-types.d.ts +2 -0
- package/dist/src/commands/database-types.js +471 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.d.ts +2 -0
- package/dist/src/commands/databases.js +1462 -83
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +2 -0
- package/dist/src/commands/documents.js +518 -11
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.d.ts +2 -0
- package/dist/src/commands/email-templates.js +281 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/env.d.ts +12 -0
- package/dist/src/commands/env.js +260 -0
- package/dist/src/commands/env.js.map +1 -0
- package/dist/src/commands/group-type-configs.d.ts +2 -0
- package/dist/src/commands/group-type-configs.js +181 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.d.ts +2 -0
- package/dist/src/commands/groups.js +45 -43
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.d.ts +159 -0
- package/dist/src/commands/guides.js +449 -35
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +17 -0
- package/dist/src/commands/init.js +811 -201
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.d.ts +2 -0
- package/dist/src/commands/integrations.js +533 -46
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/llm.d.ts +2 -0
- package/dist/src/commands/llm.js +4 -2
- package/dist/src/commands/llm.js.map +1 -1
- package/dist/src/commands/prompts.d.ts +2 -0
- package/dist/src/commands/prompts.js +50 -52
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +3 -0
- package/dist/src/commands/rule-sets.js +388 -0
- package/dist/src/commands/rule-sets.js.map +1 -0
- package/dist/src/commands/scripts.d.ts +2 -0
- package/dist/src/commands/scripts.js +667 -0
- package/dist/src/commands/scripts.js.map +1 -0
- package/dist/src/commands/secrets.d.ts +2 -0
- package/dist/src/commands/secrets.js +108 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/skill.d.ts +2 -0
- package/dist/src/commands/skill.js +29 -0
- package/dist/src/commands/skill.js.map +1 -0
- package/dist/src/commands/sync.d.ts +174 -0
- package/dist/src/commands/sync.js +4392 -235
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.d.ts +2 -0
- package/dist/src/commands/tokens.js +122 -19
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.d.ts +2 -0
- package/dist/src/commands/users.js +440 -22
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/waitlist.d.ts +2 -0
- package/dist/src/commands/waitlist.js +10 -10
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +2 -0
- package/dist/src/commands/webhooks.js +391 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.d.ts +49 -0
- package/dist/src/commands/workflows.js +1009 -123
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +1272 -0
- package/dist/src/lib/api-client.js +1115 -83
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/auth-flow.d.ts +8 -0
- package/dist/src/lib/block-layout.d.ts +160 -0
- package/dist/src/lib/block-layout.js +451 -0
- package/dist/src/lib/block-layout.js.map +1 -0
- package/dist/src/lib/cli-manifest.d.ts +60 -0
- package/dist/src/lib/cli-manifest.js +70 -0
- package/dist/src/lib/cli-manifest.js.map +1 -0
- package/dist/src/lib/config.d.ts +53 -0
- package/dist/src/lib/config.js +92 -53
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/confirm-prompt.d.ts +83 -0
- package/dist/src/lib/confirm-prompt.js +110 -0
- package/dist/src/lib/confirm-prompt.js.map +1 -0
- package/dist/src/lib/constants.d.ts +2 -0
- package/dist/src/lib/constants.js +3 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/crash-handlers.d.ts +20 -0
- package/dist/src/lib/crash-handlers.js +49 -0
- package/dist/src/lib/crash-handlers.js.map +1 -0
- package/dist/src/lib/credentials-store.d.ts +79 -0
- package/dist/src/lib/credentials-store.js +307 -0
- package/dist/src/lib/credentials-store.js.map +1 -0
- package/dist/src/lib/csv.d.ts +48 -0
- package/dist/src/lib/csv.js +177 -0
- package/dist/src/lib/csv.js.map +1 -0
- package/dist/src/lib/db-codegen/dbFingerprint.d.ts +10 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js +17 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js.map +1 -0
- package/dist/src/lib/db-codegen/dbGenerator.d.ts +111 -0
- package/dist/src/lib/db-codegen/dbGenerator.js +371 -0
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/db-codegen/dbNaming.d.ts +45 -0
- package/dist/src/lib/db-codegen/dbNaming.js +104 -0
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +97 -0
- package/dist/src/lib/db-codegen/dbTemplates.js +159 -0
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTsTypes.d.ts +78 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js +112 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +62 -0
- package/dist/src/lib/env-resolver.js +121 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/fetch.d.ts +5 -0
- package/dist/src/lib/generated-allowlist.d.ts +28 -0
- package/dist/src/lib/generated-allowlist.js +213 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -0
- package/dist/src/lib/init-config.d.ts +59 -0
- package/dist/src/lib/init-config.js +113 -0
- package/dist/src/lib/init-config.js.map +1 -0
- package/dist/src/lib/migration-nag.d.ts +49 -0
- package/dist/src/lib/migration-nag.js +163 -0
- package/dist/src/lib/migration-nag.js.map +1 -0
- package/dist/src/lib/output.d.ts +86 -0
- package/dist/src/lib/output.js +150 -8
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/paginate.d.ts +33 -0
- package/dist/src/lib/paginate.js +42 -0
- package/dist/src/lib/paginate.js.map +1 -0
- package/dist/src/lib/project-config.d.ts +97 -0
- package/dist/src/lib/project-config.js +209 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/query-operators.d.ts +43 -0
- package/dist/src/lib/query-operators.js +80 -0
- package/dist/src/lib/query-operators.js.map +1 -0
- package/dist/src/lib/refresh-admin-credentials.d.ts +65 -0
- package/dist/src/lib/refresh-admin-credentials.js +103 -0
- package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
- package/dist/src/lib/resolve-platform.d.ts +45 -0
- package/dist/src/lib/resolve-platform.js +43 -0
- package/dist/src/lib/resolve-platform.js.map +1 -0
- package/dist/src/lib/skill-installer.d.ts +23 -0
- package/dist/src/lib/skill-installer.js +135 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +99 -0
- package/dist/src/lib/snapshots.js +357 -0
- package/dist/src/lib/snapshots.js.map +1 -0
- package/dist/src/lib/sync-paths.d.ts +72 -0
- package/dist/src/lib/sync-paths.js +130 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/template.d.ts +97 -0
- package/dist/src/lib/template.js +336 -62
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/token-inject.d.ts +56 -0
- package/dist/src/lib/token-inject.js +204 -0
- package/dist/src/lib/token-inject.js.map +1 -0
- package/dist/src/lib/toml-database-config.d.ts +152 -0
- package/dist/src/lib/toml-database-config.js +600 -0
- package/dist/src/lib/toml-database-config.js.map +1 -0
- package/dist/src/lib/toml-metadata-config.d.ts +108 -0
- package/dist/src/lib/toml-metadata-config.js +371 -0
- package/dist/src/lib/toml-metadata-config.js.map +1 -0
- package/dist/src/lib/toml-params-validator.d.ts +129 -0
- package/dist/src/lib/toml-params-validator.js +298 -0
- package/dist/src/lib/toml-params-validator.js.map +1 -0
- package/dist/src/lib/version-check.d.ts +10 -0
- package/dist/src/lib/version-check.js +172 -0
- package/dist/src/lib/version-check.js.map +1 -0
- package/dist/src/lib/workflow-apply.d.ts +66 -0
- package/dist/src/lib/workflow-apply.js +117 -0
- package/dist/src/lib/workflow-apply.js.map +1 -0
- package/dist/src/lib/workflow-fragments.d.ts +41 -0
- package/dist/src/lib/workflow-fragments.js +121 -0
- package/dist/src/lib/workflow-fragments.js.map +1 -0
- package/dist/src/lib/workflow-toml-validator.d.ts +95 -0
- package/dist/src/lib/workflow-toml-validator.js +323 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- package/dist/src/types/index.d.ts +520 -0
- package/dist/src/validators.d.ts +64 -0
- package/dist/src/validators.js +63 -0
- package/dist/src/validators.js.map +1 -0
- package/package.json +18 -4
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for the `primitive tokens inject` command (issue #420).
|
|
3
|
+
*
|
|
4
|
+
* Kept separate from the commander wrapper in `commands/tokens.ts` so the
|
|
5
|
+
* snippet building, shared-secret generation, and one-shot localhost server
|
|
6
|
+
* can be unit-tested without a live backend or a spawned CLI process.
|
|
7
|
+
*/
|
|
8
|
+
import { createServer } from "node:http";
|
|
9
|
+
import { randomBytes } from "node:crypto";
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
/** Default TTL for injected tokens — short-lived per the #420 design (30 minutes). */
|
|
12
|
+
export const DEFAULT_INJECT_TTL = "30m";
|
|
13
|
+
/** Lowest port the `--serve` one-shot server is allowed to bind. */
|
|
14
|
+
const MIN_SERVE_PORT = 30001;
|
|
15
|
+
/** How many random ports to try before giving up on collisions. */
|
|
16
|
+
const SERVE_PORT_ATTEMPTS = 5;
|
|
17
|
+
/**
|
|
18
|
+
* Escape a token for safe embedding inside a single-quoted JS string literal.
|
|
19
|
+
* Tokens are `prim_<base64url>` so they normally need no escaping, but we are
|
|
20
|
+
* defensive in case the source ever changes.
|
|
21
|
+
*/
|
|
22
|
+
function escapeForJsSingleQuote(value) {
|
|
23
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build the browser console one-liner that applies a token via the
|
|
27
|
+
* `window.__PRIMITIVE_SET_TOKEN__` hook installed by `<DevTools>`.
|
|
28
|
+
*/
|
|
29
|
+
export function buildSnippet(token) {
|
|
30
|
+
return `window.__PRIMITIVE_SET_TOKEN__('${escapeForJsSingleQuote(token)}')`;
|
|
31
|
+
}
|
|
32
|
+
/** Render the output for a given `--print` mode. */
|
|
33
|
+
export function buildPrintOutput(mode, token) {
|
|
34
|
+
switch (mode) {
|
|
35
|
+
case "snippet":
|
|
36
|
+
return buildSnippet(token);
|
|
37
|
+
case "token":
|
|
38
|
+
return token;
|
|
39
|
+
case "env":
|
|
40
|
+
return `VITE_PRIMITIVE_DEV_TOKEN=${token}`;
|
|
41
|
+
default:
|
|
42
|
+
throw new Error(`Invalid --print mode: ${mode}. Expected one of: snippet, env, token.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Generate a random, URL-safe shared secret for the `--serve` endpoint. */
|
|
46
|
+
export function generateSharedSecret() {
|
|
47
|
+
return randomBytes(16).toString("hex");
|
|
48
|
+
}
|
|
49
|
+
/** A random integer in [min, max]. */
|
|
50
|
+
function randomPort() {
|
|
51
|
+
// 30001..65535
|
|
52
|
+
const span = 65535 - MIN_SERVE_PORT;
|
|
53
|
+
return MIN_SERVE_PORT + Math.floor(Math.random() * span);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Copy text to the system clipboard using whatever native tool is available.
|
|
57
|
+
* No new npm dependency — shells out to `pbcopy` (macOS), `xclip`/`xsel`
|
|
58
|
+
* (Linux), or `clip` (Windows). Returns `true` on success, `false` if no
|
|
59
|
+
* clipboard tool is available or the copy failed (caller degrades gracefully).
|
|
60
|
+
*/
|
|
61
|
+
export function copyToClipboard(text) {
|
|
62
|
+
const candidates = process.platform === "darwin"
|
|
63
|
+
? [{ cmd: "pbcopy", args: [] }]
|
|
64
|
+
: process.platform === "win32"
|
|
65
|
+
? [{ cmd: "clip", args: [] }]
|
|
66
|
+
: [
|
|
67
|
+
{ cmd: "xclip", args: ["-selection", "clipboard"] },
|
|
68
|
+
{ cmd: "xsel", args: ["--clipboard", "--input"] },
|
|
69
|
+
{ cmd: "wl-copy", args: [] },
|
|
70
|
+
];
|
|
71
|
+
for (const { cmd, args } of candidates) {
|
|
72
|
+
try {
|
|
73
|
+
const res = spawnSync(cmd, args, { input: text });
|
|
74
|
+
if (res.error)
|
|
75
|
+
continue; // command not found — try next
|
|
76
|
+
if (res.status === 0)
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// try next candidate
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* CORS headers for the one-shot token response. `--serve` is documented to be
|
|
87
|
+
* read via `fetch('http://127.0.0.1:PORT/...')` FROM the app's browser console,
|
|
88
|
+
* which is a cross-origin request. Without `Access-Control-Allow-Origin` the
|
|
89
|
+
* browser blocks `r.text()`, so the advertised browser-injection flow fails.
|
|
90
|
+
* We echo back the request `Origin` (falling back to `*`) and allow `GET`.
|
|
91
|
+
*
|
|
92
|
+
* Note: these headers do NOT weaken the loopback-bind + shared-secret model.
|
|
93
|
+
* CORS only governs whether the browser exposes the RESPONSE to page JS; the
|
|
94
|
+
* 127.0.0.1 bind and the unguessable per-run secret are what gate access.
|
|
95
|
+
*/
|
|
96
|
+
function corsHeaders(reqOrigin) {
|
|
97
|
+
return {
|
|
98
|
+
"Access-Control-Allow-Origin": reqOrigin ?? "*",
|
|
99
|
+
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
|
100
|
+
"Access-Control-Allow-Headers": "*",
|
|
101
|
+
Vary: "Origin",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Boot a one-shot HTTP server bound to `127.0.0.1` that serves `token` exactly
|
|
106
|
+
* once, then shuts down. Security model:
|
|
107
|
+
* - binds loopback only (never 0.0.0.0)
|
|
108
|
+
* - requires a random shared-secret `?key=` query param; requests without the
|
|
109
|
+
* correct secret get 403 and do NOT consume the one-shot read
|
|
110
|
+
* - returns CORS headers so the documented cross-origin browser `fetch` can
|
|
111
|
+
* actually read the response; a CORS preflight (`OPTIONS`) is answered 204
|
|
112
|
+
* WITHOUT consuming the one-shot read or shutting the server down
|
|
113
|
+
* - the one-shot consumption + shutdown happen ONLY on the authorized `GET`
|
|
114
|
+
* that actually delivers the token (correct secret) — never on a preflight,
|
|
115
|
+
* a secret-rejected request, or a wrong path
|
|
116
|
+
* - retries random ports >30000 on collision (>= 5 attempts)
|
|
117
|
+
*/
|
|
118
|
+
export async function serveTokenOnce(token, opts = {}) {
|
|
119
|
+
const secret = generateSharedSecret();
|
|
120
|
+
const path = opts.path ?? "/token";
|
|
121
|
+
let resolveDone;
|
|
122
|
+
const done = new Promise((resolve) => {
|
|
123
|
+
resolveDone = resolve;
|
|
124
|
+
});
|
|
125
|
+
let served = false;
|
|
126
|
+
const server = createServer((req, res) => {
|
|
127
|
+
const reqUrl = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
128
|
+
const cors = corsHeaders(req.headers.origin);
|
|
129
|
+
// CORS preflight: the browser sends an OPTIONS before the cross-origin GET.
|
|
130
|
+
// Answer it with the CORS headers and 204, but do NOT consume the one-shot
|
|
131
|
+
// read or shut the server down — the real GET still needs to deliver the
|
|
132
|
+
// token afterward.
|
|
133
|
+
if (req.method === "OPTIONS") {
|
|
134
|
+
res.writeHead(204, cors);
|
|
135
|
+
res.end();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (reqUrl.pathname !== path) {
|
|
139
|
+
res.writeHead(404, { "Content-Type": "text/plain", ...cors });
|
|
140
|
+
res.end("Not found");
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Reject any request missing the correct shared secret. Does not consume
|
|
144
|
+
// the one-shot read, so a racing process cannot lock the dev out.
|
|
145
|
+
if (reqUrl.searchParams.get("key") !== secret) {
|
|
146
|
+
res.writeHead(403, { "Content-Type": "text/plain", ...cors });
|
|
147
|
+
res.end("Forbidden");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (served) {
|
|
151
|
+
res.writeHead(410, { "Content-Type": "text/plain", ...cors });
|
|
152
|
+
res.end("Token already served");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Authorized GET with the correct secret: this is the only path that
|
|
156
|
+
// consumes the one-shot read and shuts the server down.
|
|
157
|
+
served = true;
|
|
158
|
+
res.writeHead(200, { "Content-Type": "text/plain", ...cors });
|
|
159
|
+
res.end(token);
|
|
160
|
+
// Close after the response flushes so the single read completes cleanly.
|
|
161
|
+
res.on("finish", () => {
|
|
162
|
+
server.close(() => resolveDone());
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
const port = await listenWithRetry(server);
|
|
166
|
+
const url = `http://127.0.0.1:${port}${path}?key=${secret}`;
|
|
167
|
+
const stop = () => {
|
|
168
|
+
try {
|
|
169
|
+
server.close();
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// already closed
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
return { url, secret, port, done, stop };
|
|
176
|
+
}
|
|
177
|
+
/** Try random ports > 30000 until one binds, up to SERVE_PORT_ATTEMPTS times. */
|
|
178
|
+
function listenWithRetry(server) {
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
let attempts = 0;
|
|
181
|
+
const tryListen = () => {
|
|
182
|
+
attempts += 1;
|
|
183
|
+
const port = randomPort();
|
|
184
|
+
const onError = (err) => {
|
|
185
|
+
server.removeListener("listening", onListening);
|
|
186
|
+
if (err.code === "EADDRINUSE" && attempts < SERVE_PORT_ATTEMPTS) {
|
|
187
|
+
tryListen();
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
reject(new Error(`Failed to bind a local port for --serve after ${attempts} attempt(s): ${err.message}`));
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const onListening = () => {
|
|
194
|
+
server.removeListener("error", onError);
|
|
195
|
+
resolve(port);
|
|
196
|
+
};
|
|
197
|
+
server.once("error", onError);
|
|
198
|
+
server.once("listening", onListening);
|
|
199
|
+
server.listen(port, "127.0.0.1");
|
|
200
|
+
};
|
|
201
|
+
tryListen();
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=token-inject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-inject.js","sourceRoot":"","sources":["../../../src/lib/token-inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for emitting `DatabaseTypeOperation` configs as native TOML.
|
|
3
|
+
*
|
|
4
|
+
* Background (issue #752): historically `sync pull` serialized
|
|
5
|
+
* `definition` and `params` as JSON strings stuffed into a single TOML
|
|
6
|
+
* field, which produced unreviewable 800-char one-liners. This module
|
|
7
|
+
* lets us emit them as nested TOML tables when they're representable,
|
|
8
|
+
* while preserving the existing file's shape so we don't generate
|
|
9
|
+
* surprise diffs.
|
|
10
|
+
*
|
|
11
|
+
* Three responsibilities:
|
|
12
|
+
* 1. `detectExistingOperationForms()` — read the raw TOML source and
|
|
13
|
+
* decide, per operation name, whether the file uses JSON-string
|
|
14
|
+
* form ("legacy") or nested-table form ("native") for each of
|
|
15
|
+
* `definition` and `params`. This drives form preservation on
|
|
16
|
+
* `sync pull`.
|
|
17
|
+
* 2. `canEmitNative()` — recursively check whether a JS value is
|
|
18
|
+
* representable as a TOML value. Returns a reason string if not.
|
|
19
|
+
* Mainly catches `null` and mixed-type arrays, which `@iarna/toml`
|
|
20
|
+
* either rejects or silently mangles.
|
|
21
|
+
* 3. `buildDatabaseTypeTomlData()` — builds the JS object that we
|
|
22
|
+
* hand to `TOML.stringify`. Per operation, decides JSON-string vs
|
|
23
|
+
* native based on (existing form, can-emit, override mode).
|
|
24
|
+
*/
|
|
25
|
+
export type FieldForm = "native" | "legacy";
|
|
26
|
+
/**
|
|
27
|
+
* Classify a single-line TOML field value (the text after `key = `) as
|
|
28
|
+
* native or legacy form.
|
|
29
|
+
*
|
|
30
|
+
* An inline table (`{ ... }`) or inline array (`[ ... ]`) is native TOML —
|
|
31
|
+
* the operator/param structure is written directly, so `sync pull` should
|
|
32
|
+
* re-emit it through the native-emission path rather than collapse it back
|
|
33
|
+
* to an opaque JSON string. A quoted string (`'...'` / `"..."`) is the
|
|
34
|
+
* legacy JSON-string form.
|
|
35
|
+
*
|
|
36
|
+
* This is the fix for issue #1255: previously ANY `definition = <value>`
|
|
37
|
+
* one-liner was classified `legacy`, so an author who wrote the compact
|
|
38
|
+
* inline form `definition = { filter = { "$in" = [1, 2] } }` got an opaque
|
|
39
|
+
* JSON string back on the next pull (churn). Distinguishing the two makes
|
|
40
|
+
* the inline form round-trip stably through the existing native-emission
|
|
41
|
+
* path.
|
|
42
|
+
*
|
|
43
|
+
* Exported for reuse by `[[subscriptions]]` form detection (issue #803).
|
|
44
|
+
*/
|
|
45
|
+
export declare function classifyInlineFieldForm(rawValue: string): FieldForm;
|
|
46
|
+
export interface OperationFormHints {
|
|
47
|
+
/** Map of op name → existing form for `definition`. Missing op = "default". */
|
|
48
|
+
definition: Map<string, FieldForm>;
|
|
49
|
+
/** Map of op name → existing form for `params`. Missing op = "default". */
|
|
50
|
+
params: Map<string, FieldForm>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Inspect the raw TOML source for a database-type file and decide which
|
|
54
|
+
* form each operation's `definition`/`params` currently use.
|
|
55
|
+
*
|
|
56
|
+
* Detection is intentionally simple: we walk `[[operations]]` blocks in
|
|
57
|
+
* source order and, for each one, look for either a `definition = '...'`
|
|
58
|
+
* line (legacy) or an `[operations.definition]` / `[operations.definition.X]`
|
|
59
|
+
* sub-header (native).
|
|
60
|
+
*/
|
|
61
|
+
export declare function detectExistingOperationForms(rawToml: string): OperationFormHints;
|
|
62
|
+
/**
|
|
63
|
+
* Recursively check whether a JS value can be safely serialized to TOML
|
|
64
|
+
* using `@iarna/toml`. Returns null if OK, a reason string otherwise.
|
|
65
|
+
*
|
|
66
|
+
* Things TOML can't represent (in `@iarna/toml`):
|
|
67
|
+
* - `null` (TOML has no null).
|
|
68
|
+
* - Arrays containing values of different "TOML types" (e.g. mixed
|
|
69
|
+
* string and number). Spec-wise TOML 1.0 actually allows this, but
|
|
70
|
+
* `@iarna/toml` is strict and throws.
|
|
71
|
+
* - `undefined` (different from null but equally not representable).
|
|
72
|
+
*/
|
|
73
|
+
export declare function canEmitNative(value: any): string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Normalize a `params` value into a sorted array of
|
|
76
|
+
* `{ name, type, required, ... }` rows, suitable for emitting as
|
|
77
|
+
* `[[operations.params]]`. Accepts both shapes the wire/parser supports:
|
|
78
|
+
* - object form: `{ projectId: { type: "string", required: true } }`
|
|
79
|
+
* - array form: `[{ name: "projectId", type: "string", required: true }]`
|
|
80
|
+
*/
|
|
81
|
+
export declare function normalizeParamsToArray(params: any): any[] | null;
|
|
82
|
+
export interface BuildOptions {
|
|
83
|
+
/** Per-op form hints derived from `detectExistingOperationForms`. */
|
|
84
|
+
hints?: OperationFormHints;
|
|
85
|
+
/**
|
|
86
|
+
* Override the default form for ops with no hint. Used by `sync pull`
|
|
87
|
+
* to keep behavior backwards-compatible if we ever flip the default,
|
|
88
|
+
* and by `sync migrate-toml` to force native everywhere.
|
|
89
|
+
*/
|
|
90
|
+
defaultForm?: FieldForm;
|
|
91
|
+
/** Sink for human-readable fallback messages. */
|
|
92
|
+
logger?: (message: string) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Server `DatabaseTypeSubscription` rows to emit as `[[subscriptions]]`
|
|
95
|
+
* blocks (issue #803). Already sanitized by the controller's
|
|
96
|
+
* `sanitizeSubscription` (so `select`/`emit` are arrays and `params` is an
|
|
97
|
+
* object). Omitted on the `migrate-toml` path (no subscriptions to merge).
|
|
98
|
+
*/
|
|
99
|
+
subscriptions?: any[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build the JS object to pass to `TOML.stringify` for a database-type
|
|
103
|
+
* config file. Per operation:
|
|
104
|
+
* - If the chosen form is "native" AND `definition` is TOML-emittable,
|
|
105
|
+
* emit `[operations.definition]` (nested table).
|
|
106
|
+
* - Else emit `definition = '<json string>'` and log a message.
|
|
107
|
+
* - Same logic independently for `params`, but the native form for
|
|
108
|
+
* params is `[[operations.params]]` (array-of-tables).
|
|
109
|
+
*/
|
|
110
|
+
export declare function buildDatabaseTypeTomlData(typeConfig: any, operations: any[], ruleSetIdToName: Map<string, string>, options?: BuildOptions): any;
|
|
111
|
+
/**
|
|
112
|
+
* Thrown when a `[[subscriptions]]` block declares both `accessRule` and
|
|
113
|
+
* `access` with different values. We never silently drop the field
|
|
114
|
+
* (issue #803 maintainer decision): prefer `access` when they agree, error
|
|
115
|
+
* when they conflict so the operator fixes the source of truth.
|
|
116
|
+
*/
|
|
117
|
+
export declare class SubscriptionAccessKeyConflictError extends Error {
|
|
118
|
+
subscriptionKey: string | undefined;
|
|
119
|
+
constructor(subscriptionKey: string | undefined);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve the subscription `access` CEL expression from a TOML row.
|
|
123
|
+
*
|
|
124
|
+
* The server's wire key is `access`; the issue author (and the guides) used
|
|
125
|
+
* `accessRule`. We accept both: prefer `access` when present, fall back to
|
|
126
|
+
* `accessRule`, and never silently drop the field. If both are present with
|
|
127
|
+
* different values, throw so the conflict is surfaced rather than guessed.
|
|
128
|
+
*/
|
|
129
|
+
export declare function resolveSubscriptionAccess(sub: any): string | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Normalize a `[[subscriptions]]` TOML row into the server's wire shape.
|
|
132
|
+
*
|
|
133
|
+
* Mirrors `normalizeOperationFromToml`. Maps the `accessRule`→`access`
|
|
134
|
+
* alias (issue #803), and passes `select` / `emit` / `params` through in
|
|
135
|
+
* native form — the server stores them as JSON strings and re-parses on
|
|
136
|
+
* read (`sanitizeSubscription`), so the parse → push → pull round-trip is
|
|
137
|
+
* symmetric with operations' `definition` / `params`.
|
|
138
|
+
*
|
|
139
|
+
* `filter` stays required server-side; we forward whatever is present (or
|
|
140
|
+
* undefined) and let the controller's clean named 400 surface.
|
|
141
|
+
*/
|
|
142
|
+
export declare function normalizeSubscriptionFromToml(sub: any): any;
|
|
143
|
+
/**
|
|
144
|
+
* After parsing TOML, normalize the `definition` and `params` of each
|
|
145
|
+
* operation row into the JS objects the server expects. Handles both
|
|
146
|
+
* native and legacy forms transparently. The server payload is the
|
|
147
|
+
* source of truth; native TOML is purely a source-control affordance.
|
|
148
|
+
*
|
|
149
|
+
* Mirrors `parseDatabaseTypeToml` in `sync.ts`, but is broken out here
|
|
150
|
+
* so the migrate-toml command can call it without re-implementing.
|
|
151
|
+
*/
|
|
152
|
+
export declare function normalizeOperationFromToml(op: any): any;
|