@wayai/cli 0.3.148 → 0.3.150
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/dist/index.js +47 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18503,13 +18503,20 @@ var init_terminal_output = __esm({
|
|
|
18503
18503
|
|
|
18504
18504
|
// src/lib/base-id.ts
|
|
18505
18505
|
function isValidBaseId(id) {
|
|
18506
|
-
return BASE_ID_RE.test(id);
|
|
18506
|
+
return id.length > 0 && id.length <= BASE_ID_MAX_LENGTH && BASE_ID_RE.test(id);
|
|
18507
18507
|
}
|
|
18508
|
-
|
|
18508
|
+
function isPathSafeId(id) {
|
|
18509
|
+
return PATH_SAFE_ID_RE.test(id);
|
|
18510
|
+
}
|
|
18511
|
+
var BASE_ID_MAX_LENGTH, BASE_ID_RE, BASE_ID_RULE, PATH_SAFE_ID_RE, PATH_SAFE_ID_RULE;
|
|
18509
18512
|
var init_base_id = __esm({
|
|
18510
18513
|
"src/lib/base-id.ts"() {
|
|
18511
18514
|
"use strict";
|
|
18512
|
-
|
|
18515
|
+
BASE_ID_MAX_LENGTH = 128;
|
|
18516
|
+
BASE_ID_RE = /^[A-Za-z0-9_][A-Za-z0-9_-]*$/;
|
|
18517
|
+
BASE_ID_RULE = `letters, digits, \`-\` and \`_\`, starting with a letter, digit or \`_\`, ${BASE_ID_MAX_LENGTH} characters or fewer`;
|
|
18518
|
+
PATH_SAFE_ID_RE = /^(?!\.\.?$)[A-Za-z0-9._-]{1,256}$/;
|
|
18519
|
+
PATH_SAFE_ID_RULE = "letters, digits, dot, dash and underscore, with no path separators, not `.` or `..` alone, 256 characters or fewer";
|
|
18513
18520
|
}
|
|
18514
18521
|
});
|
|
18515
18522
|
|
|
@@ -18572,9 +18579,9 @@ function folderForSelector(basesDir, selector) {
|
|
|
18572
18579
|
return path17.join(basesDir, selector);
|
|
18573
18580
|
}
|
|
18574
18581
|
function assertValidBaseSelector(selector, source = "base") {
|
|
18575
|
-
if (!
|
|
18582
|
+
if (!isPathSafeId(selector)) {
|
|
18576
18583
|
throw expected(
|
|
18577
|
-
`Invalid ${source} "${selector}".
|
|
18584
|
+
`Invalid ${source} "${selector}". A base selector is one folder name \u2014 ${PATH_SAFE_ID_RULE}.`
|
|
18578
18585
|
);
|
|
18579
18586
|
}
|
|
18580
18587
|
}
|
|
@@ -18942,9 +18949,16 @@ var init_base_binding = __esm({
|
|
|
18942
18949
|
init_worktree_binding();
|
|
18943
18950
|
binding2 = createWorktreeBinding({
|
|
18944
18951
|
filename: "wayai-base-binding",
|
|
18945
|
-
|
|
18952
|
+
// `isPathSafeId`, not the API's base-id rule. The tripwire's duty is that a
|
|
18953
|
+
// garbled or multi-line file read as unbound, which this grammar delivers;
|
|
18954
|
+
// applying the mint rule instead would refuse to bind a base whose stored id
|
|
18955
|
+
// predates it — a base the API still serves — and so lock the CLI out of the
|
|
18956
|
+
// one workflow that could migrate off it.
|
|
18957
|
+
isValidId: isPathSafeId,
|
|
18946
18958
|
noun: "base",
|
|
18947
|
-
|
|
18959
|
+
// States what is actually checked. "must be a slug" described no rule the
|
|
18960
|
+
// reader could act on, and naming the API's rule here would name the wrong one.
|
|
18961
|
+
idLabel: `base id (${PATH_SAFE_ID_RULE})`,
|
|
18948
18962
|
unbindCommand: "wayai bases unbind",
|
|
18949
18963
|
useCommand: "wayai bases use"
|
|
18950
18964
|
});
|
|
@@ -18961,10 +18975,14 @@ var init_base_binding = __esm({
|
|
|
18961
18975
|
// src/data/helpers.ts
|
|
18962
18976
|
import { readFileSync as readFileSync16 } from "fs";
|
|
18963
18977
|
function pathSegment(id, label = "id") {
|
|
18978
|
+
if (!isPathSafeId(id)) {
|
|
18979
|
+
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
|
|
18980
|
+
}
|
|
18981
|
+
return encodeURIComponent(id);
|
|
18982
|
+
}
|
|
18983
|
+
function basePathSegment(id, label = "base id") {
|
|
18964
18984
|
if (!isValidBaseId(id)) {
|
|
18965
|
-
throw expected(
|
|
18966
|
-
`Invalid ${label}: ${JSON.stringify(id)}. Ids are slugs \u2014 letters, digits, dot, dash and underscore only.`
|
|
18967
|
-
);
|
|
18985
|
+
throw expected(`Invalid ${label}: ${JSON.stringify(id)}. Base ids are slugs \u2014 ${BASE_ID_RULE}.`);
|
|
18968
18986
|
}
|
|
18969
18987
|
return encodeURIComponent(id);
|
|
18970
18988
|
}
|
|
@@ -19178,7 +19196,7 @@ function writeBaseFolder(folder, meta, config) {
|
|
|
19178
19196
|
for (const raw of entities) {
|
|
19179
19197
|
const entity = raw;
|
|
19180
19198
|
const id = String(entity.id);
|
|
19181
|
-
if (!
|
|
19199
|
+
if (!isPathSafeId(id)) {
|
|
19182
19200
|
console.warn(` Warning: skipping ${kind} entity with unusable id ${JSON.stringify(id)}.`);
|
|
19183
19201
|
continue;
|
|
19184
19202
|
}
|
|
@@ -19502,7 +19520,7 @@ function requireGitRoot(gitRoot) {
|
|
|
19502
19520
|
return gitRoot;
|
|
19503
19521
|
}
|
|
19504
19522
|
async function writeProductionMirror(client, basesDir, prodId, record) {
|
|
19505
|
-
if (!
|
|
19523
|
+
if (!isPathSafeId(prodId)) {
|
|
19506
19524
|
throw expected(`Refusing to mirror base ${JSON.stringify(prodId)}: not a usable base id.`);
|
|
19507
19525
|
}
|
|
19508
19526
|
const config = await getConfig(client, prodId);
|
|
@@ -28135,18 +28153,19 @@ function buildBasesCommand() {
|
|
|
28135
28153
|
"Default IANA timezone for datetime canonicalization (e.g. America/Sao_Paulo); a record type's own timezone overrides it"
|
|
28136
28154
|
).option(
|
|
28137
28155
|
"--environment <env>",
|
|
28138
|
-
"production (default) | preview. Fixed
|
|
28156
|
+
"production (default) | preview. Fixed for the life of a base and not changeable on one that exists \u2014 but not welded to the id: once a base is permanently deleted and that deletion completes, the id is free and can be created again in either environment, so a preview you prototyped on can become the production base under the same slug. For a base you intend to keep, take the default so the durable id belongs to production, then get a linked preview with create-preview and promote from it. Pass preview for an ephemeral or eval base under a derived id: a preview created here has no production origin, cannot be given one later, and so can never be promoted directly"
|
|
28139
28157
|
).action(async function(id, opts) {
|
|
28140
28158
|
const environment = parseEnum("--environment", opts.environment, [
|
|
28141
28159
|
"production",
|
|
28142
28160
|
"preview"
|
|
28143
28161
|
]);
|
|
28162
|
+
const target = basePathSegment(id);
|
|
28144
28163
|
const client = await createDataClient();
|
|
28145
28164
|
const body = { name: opts.name, description: opts.description };
|
|
28146
28165
|
if (environment) body.environment = environment;
|
|
28147
28166
|
if (opts.tags) body.tags = await resolveBaseTags(opts.tags, client);
|
|
28148
28167
|
if (opts.timezone) body.settings = { timezone: opts.timezone };
|
|
28149
|
-
printOutput(await client.request("PUT", `/v1/bases/${
|
|
28168
|
+
printOutput(await client.request("PUT", `/v1/bases/${target}`, body), outputFormat(this));
|
|
28150
28169
|
});
|
|
28151
28170
|
bases.command("update <id>").description(
|
|
28152
28171
|
"Update a base's mutable config (display name, description, tags, default timezone/settings). The id/slug is immutable."
|
|
@@ -28169,6 +28188,7 @@ function buildBasesCommand() {
|
|
|
28169
28188
|
"Nothing to update. Provide at least one of --name, --description, --tags, --timezone, --settings, --integrations."
|
|
28170
28189
|
);
|
|
28171
28190
|
}
|
|
28191
|
+
const target = basePathSegment(id);
|
|
28172
28192
|
const client = await createDataClient();
|
|
28173
28193
|
const body = {};
|
|
28174
28194
|
if (opts.name !== void 0) body.name = opts.name;
|
|
@@ -28189,20 +28209,21 @@ function buildBasesCommand() {
|
|
|
28189
28209
|
}
|
|
28190
28210
|
settings = parsed;
|
|
28191
28211
|
} else {
|
|
28192
|
-
const existing = await client.request("GET", `/v1/bases/${
|
|
28212
|
+
const existing = await client.request("GET", `/v1/bases/${target}`);
|
|
28193
28213
|
settings = { ...existing?.settings ?? {} };
|
|
28194
28214
|
}
|
|
28195
28215
|
if (opts.timezone !== void 0) settings.timezone = opts.timezone;
|
|
28196
28216
|
body.settings = settings;
|
|
28197
28217
|
}
|
|
28198
|
-
printOutput(await client.request("PUT", `/v1/bases/${
|
|
28218
|
+
printOutput(await client.request("PUT", `/v1/bases/${target}`, body), outputFormat(this));
|
|
28199
28219
|
});
|
|
28200
28220
|
bases.command("rename <id>").description(
|
|
28201
28221
|
"Rename a base's display name (the id/slug is immutable \u2014 it scopes token grants, MCP endpoints, and references)"
|
|
28202
28222
|
).requiredOption("--name <name>", "New display name").action(async function(id, opts) {
|
|
28223
|
+
const target = basePathSegment(id);
|
|
28203
28224
|
const client = await createDataClient();
|
|
28204
28225
|
printOutput(
|
|
28205
|
-
await client.request("PUT", `/v1/bases/${
|
|
28226
|
+
await client.request("PUT", `/v1/bases/${target}`, { name: opts.name }),
|
|
28206
28227
|
outputFormat(this)
|
|
28207
28228
|
);
|
|
28208
28229
|
});
|
|
@@ -28210,10 +28231,11 @@ function buildBasesCommand() {
|
|
|
28210
28231
|
"--tags <tags>",
|
|
28211
28232
|
"Comma-separated organization tag names (e.g. clinica-medica,billing). An empty value clears them"
|
|
28212
28233
|
).action(async function(id, opts) {
|
|
28234
|
+
const target = basePathSegment(id);
|
|
28213
28235
|
const client = await createDataClient();
|
|
28214
28236
|
const tags = await resolveBaseTags(opts.tags, client);
|
|
28215
28237
|
printOutput(
|
|
28216
|
-
await client.request("PUT", `/v1/bases/${
|
|
28238
|
+
await client.request("PUT", `/v1/bases/${target}`, { tags }),
|
|
28217
28239
|
outputFormat(this)
|
|
28218
28240
|
);
|
|
28219
28241
|
});
|
|
@@ -28244,6 +28266,11 @@ function buildBasesCommand() {
|
|
|
28244
28266
|
const integrations = parseEnum("--integrations", opts.integrations, ["enabled", "disabled"]);
|
|
28245
28267
|
const client = await createDataClient();
|
|
28246
28268
|
printOutput(
|
|
28269
|
+
// `pathSegment`, not `basePathSegment`: the id at fault here is the
|
|
28270
|
+
// ORIGIN's, which is immutable and not the caller's to re-spell. The API's
|
|
28271
|
+
// `assertDerivablePreviewId` answers that case with the remedy instead of
|
|
28272
|
+
// the charset, and refusing locally would replace it with a rule the
|
|
28273
|
+
// caller cannot act on.
|
|
28247
28274
|
await client.request("POST", `/v1/${pathSegment(originId, "origin base id")}/preview`, {
|
|
28248
28275
|
name: opts.name,
|
|
28249
28276
|
description: opts.description,
|
|
@@ -28357,9 +28384,9 @@ function buildBasesCommand() {
|
|
|
28357
28384
|
function resolveSelectorToBaseId(selector) {
|
|
28358
28385
|
const gitRoot = findGitRoot();
|
|
28359
28386
|
if (!gitRoot || selector.includes("/") || selector.includes(path35.sep)) return selector;
|
|
28360
|
-
if (!
|
|
28387
|
+
if (!isPathSafeId(selector)) return selector;
|
|
28361
28388
|
const id = readBaseMeta(path35.join(resolveBasesDir(gitRoot), selector))?.base_id;
|
|
28362
|
-
return typeof id === "string" &&
|
|
28389
|
+
return typeof id === "string" && isPathSafeId(id) ? id : selector;
|
|
28363
28390
|
}
|
|
28364
28391
|
var init_bases = __esm({
|
|
28365
28392
|
"src/data/commands/bases.ts"() {
|