turnzero 0.21.6 → 0.22.0-next.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/dist/turnzero-cloud.mjs +90 -2
- package/package.json +1 -1
package/dist/turnzero-cloud.mjs
CHANGED
|
@@ -2358,9 +2358,89 @@ var credentialFileName = (name) => {
|
|
|
2358
2358
|
var looksLikeCredential = (name, data) => credentialFileName(name) || holdsPrivateKey(data);
|
|
2359
2359
|
var credentialAdvice = (subject) => `Where ${subject} holds a secret, move it out of the application's folder before the next deploy, and store a secret value the application needs with ${SECRET_ACTION.store}. The ${HASH_SUBCOMMAND} subcommand with ${HASH_OPTION.list} prints every file the zip holds.`;
|
|
2360
2360
|
var credentialLineOf = (names) => names.length === 0 ? null : names.length === 1 ? `${WARNING_LINE_HEAD}the zip holds a file that looks like a key or a credential, and the upload includes it: ${listedNames(names)}. ${credentialAdvice("it")}` : `${WARNING_LINE_HEAD}the zip holds ${names.length} files that look like keys or credentials, and the upload includes them: ${listedNames(names)}. ${credentialAdvice("one")}`;
|
|
2361
|
+
var LOCAL_WRITE_EXTENSIONS = Object.freeze([".js", ".mjs", ".cjs", ".ts"]);
|
|
2362
|
+
var LOCAL_WRITE_UNREAD_FOLDERS = Object.freeze(["client/", "lib/"]);
|
|
2363
|
+
var LOCAL_WRITE_CALLS = Object.freeze(["writeFile", "writeFileSync", "appendFile", "appendFileSync", "createWriteStream", "mkdir", "mkdirSync"]);
|
|
2364
|
+
var LOCAL_WRITE_BASES = Object.freeze(["__dirname", "import.meta.dirname", "process.cwd()"]);
|
|
2365
|
+
var LOCAL_WRITE_SET_ASIDE = Object.freeze(["tmpdir(", "process.env"]);
|
|
2366
|
+
var LOCAL_WRITE_ARGUMENT_MAX = 400;
|
|
2367
|
+
var readForLocalWrite = (name) => {
|
|
2368
|
+
const last = lastSegmentOf(name);
|
|
2369
|
+
return LOCAL_WRITE_EXTENSIONS.some((extension) => last.endsWith(extension)) && !LOCAL_WRITE_UNREAD_FOLDERS.some((folder) => name.startsWith(folder));
|
|
2370
|
+
};
|
|
2371
|
+
var firstArgumentOf = (text, from) => {
|
|
2372
|
+
const open = [];
|
|
2373
|
+
let quote = null;
|
|
2374
|
+
const end = Math.min(text.length, from + LOCAL_WRITE_ARGUMENT_MAX);
|
|
2375
|
+
for (let at = from; at < end; at += 1) {
|
|
2376
|
+
const character = text[at];
|
|
2377
|
+
if (quote !== null) {
|
|
2378
|
+
if (character === "\\") at += 1;
|
|
2379
|
+
else if (character === quote) quote = null;
|
|
2380
|
+
else if (quote === "`" && character === "$" && text[at + 1] === "{") {
|
|
2381
|
+
open.push("`");
|
|
2382
|
+
quote = null;
|
|
2383
|
+
at += 1;
|
|
2384
|
+
}
|
|
2385
|
+
continue;
|
|
2386
|
+
}
|
|
2387
|
+
if (character === "'" || character === '"' || character === "`") quote = character;
|
|
2388
|
+
else if (character === "(" || character === "[" || character === "{") open.push(character);
|
|
2389
|
+
else if (character === ")" || character === "]" || character === "}") {
|
|
2390
|
+
if (open.length === 0) return character === ")" ? text.slice(from, at) : null;
|
|
2391
|
+
if (open.pop() === "`") quote = "`";
|
|
2392
|
+
} else if (character === "," && open.length === 0) return text.slice(from, at);
|
|
2393
|
+
}
|
|
2394
|
+
return null;
|
|
2395
|
+
};
|
|
2396
|
+
var literalTextOf = (argument) => {
|
|
2397
|
+
const quote = argument[0];
|
|
2398
|
+
if (argument.length < 2 || quote !== "'" && quote !== '"' && quote !== "`" || argument.at(-1) !== quote) return null;
|
|
2399
|
+
const inner = argument.slice(1, -1);
|
|
2400
|
+
if (quote === "`" && inner.includes("${")) return null;
|
|
2401
|
+
for (let at = 0; at < inner.length; at += 1) {
|
|
2402
|
+
if (inner[at] === "\\") at += 1;
|
|
2403
|
+
else if (inner[at] === quote) return null;
|
|
2404
|
+
}
|
|
2405
|
+
return inner;
|
|
2406
|
+
};
|
|
2407
|
+
var relativePathText = (path) => path !== "" && !/^([/\\~]|[A-Za-z][A-Za-z0-9+.-]*:)/.test(path);
|
|
2408
|
+
var holdsBase = (argument, base) => {
|
|
2409
|
+
for (let at = argument.indexOf(base); at >= 0; at = argument.indexOf(base, at + 1)) {
|
|
2410
|
+
const before = argument[at - 1];
|
|
2411
|
+
const after = argument[at + base.length];
|
|
2412
|
+
if ((before === void 0 || !/[\w$.]/.test(before)) && (after === void 0 || !/[\w$]/.test(after))) return true;
|
|
2413
|
+
}
|
|
2414
|
+
return false;
|
|
2415
|
+
};
|
|
2416
|
+
var writesInsideFolder = (argument) => {
|
|
2417
|
+
const trimmed = argument.trim();
|
|
2418
|
+
if (LOCAL_WRITE_SET_ASIDE.some((aside) => trimmed.includes(aside))) return false;
|
|
2419
|
+
const literal = literalTextOf(trimmed);
|
|
2420
|
+
if (literal !== null) return relativePathText(literal);
|
|
2421
|
+
return LOCAL_WRITE_BASES.some((base) => holdsBase(trimmed, base));
|
|
2422
|
+
};
|
|
2423
|
+
var LOCAL_WRITE_CALL = new RegExp(`(?<![\\w$])(${[...LOCAL_WRITE_CALLS].sort((a, b) => b.length - a.length).join("|")})\\s*\\(`, "g");
|
|
2424
|
+
var LOCAL_WRITE_OPENINGS = ["writeFile", "appendFile", "createWriteStream", "mkdir"].map((name) => Buffer.from(name, "ascii"));
|
|
2425
|
+
var localWriteLineIn = (data) => {
|
|
2426
|
+
if (!LOCAL_WRITE_OPENINGS.some((opening) => data.includes(opening))) return null;
|
|
2427
|
+
const text = data.toString("utf8");
|
|
2428
|
+
let line = 1;
|
|
2429
|
+
let counted = 0;
|
|
2430
|
+
for (const match of text.matchAll(LOCAL_WRITE_CALL)) {
|
|
2431
|
+
for (let at = text.indexOf("\n", counted); at >= 0 && at < match.index; at = text.indexOf("\n", at + 1)) line += 1;
|
|
2432
|
+
counted = match.index;
|
|
2433
|
+
const head = text.slice(text.lastIndexOf("\n", match.index - 1) + 1, match.index).trimStart();
|
|
2434
|
+
if (head.startsWith("//") || head.startsWith("/*") || head.startsWith("*")) continue;
|
|
2435
|
+
const argument = firstArgumentOf(text, match.index + match[0].length);
|
|
2436
|
+
if (argument !== null && writesInsideFolder(argument)) return line;
|
|
2437
|
+
}
|
|
2438
|
+
return null;
|
|
2439
|
+
};
|
|
2440
|
+
var localWriteLineOf = (found) => found === null ? null : `${WARNING_LINE_HEAD}${shownNoteName(found.name)}, line ${found.line}, writes to a local file inside the application's folder. A running copy's disk is lost whenever the copy is replaced or stops: keep files in a storage area and records in a database, as read_documentation's pages /cloud/guides/store-files/ and /cloud/guides/add-a-database/ describe.`;
|
|
2361
2441
|
var LIST_LINE_HEAD = "file: ";
|
|
2362
2442
|
var listLineOf = (file) => `${LIST_LINE_HEAD}${file.size} ${shownWhole(file.name)}`;
|
|
2363
|
-
var NO_NOTES = Object.freeze({ leftOut: Object.freeze([]), rootZips: Object.freeze([]), credentialFiles: Object.freeze([]), unservedHealthPath: null });
|
|
2443
|
+
var NO_NOTES = Object.freeze({ leftOut: Object.freeze([]), rootZips: Object.freeze([]), credentialFiles: Object.freeze([]), localWrite: null, unservedHealthPath: null });
|
|
2364
2444
|
var noteLinesOf = (notes, health, zipped = null) => {
|
|
2365
2445
|
const lines = [];
|
|
2366
2446
|
const files = zipped === null ? null : filesLineOf(zipped.map((file) => file.name));
|
|
@@ -2371,6 +2451,8 @@ var noteLinesOf = (notes, health, zipped = null) => {
|
|
|
2371
2451
|
if (rootZip !== null) lines.push(rootZip);
|
|
2372
2452
|
const credential = credentialLineOf(notes.credentialFiles);
|
|
2373
2453
|
if (credential !== null) lines.push(credential);
|
|
2454
|
+
const localWrite = localWriteLineOf(notes.localWrite);
|
|
2455
|
+
if (localWrite !== null) lines.push(localWrite);
|
|
2374
2456
|
if (health && notes.unservedHealthPath !== null) lines.push(healthLineOf(notes.unservedHealthPath));
|
|
2375
2457
|
return lines;
|
|
2376
2458
|
};
|
|
@@ -3376,6 +3458,7 @@ function zipFolder(root, seams = {}) {
|
|
|
3376
3458
|
let held = healthPath !== null && segment !== null && files.some((file) => pathCountsForHealth(file.name, healthPath, segment));
|
|
3377
3459
|
const zipped = [];
|
|
3378
3460
|
const credentialFiles = [];
|
|
3461
|
+
let localWrite = null;
|
|
3379
3462
|
const places = [];
|
|
3380
3463
|
const zip = zipFiles(
|
|
3381
3464
|
files,
|
|
@@ -3383,6 +3466,10 @@ function zipFolder(root, seams = {}) {
|
|
|
3383
3466
|
(file, data) => {
|
|
3384
3467
|
zipped.push({ name: file.name, size: data.length });
|
|
3385
3468
|
if (looksLikeCredential(file.name, data)) credentialFiles.push(file.name);
|
|
3469
|
+
if (localWrite === null && readForLocalWrite(file.name)) {
|
|
3470
|
+
const line = localWriteLineIn(data);
|
|
3471
|
+
if (line !== null) localWrite = { name: file.name, line };
|
|
3472
|
+
}
|
|
3386
3473
|
if (segment !== null && !held && readForHealth(file.name) && holdsSegment(data, segment)) held = true;
|
|
3387
3474
|
},
|
|
3388
3475
|
(place) => places.push(place)
|
|
@@ -3396,6 +3483,7 @@ function zipFolder(root, seams = {}) {
|
|
|
3396
3483
|
leftOut,
|
|
3397
3484
|
rootZips: files.filter((file) => !file.name.includes("/") && zipFileName(file.name)).map((file) => file.name),
|
|
3398
3485
|
credentialFiles,
|
|
3486
|
+
localWrite,
|
|
3399
3487
|
unservedHealthPath: segment !== null && !held ? healthPath : null
|
|
3400
3488
|
}
|
|
3401
3489
|
};
|
|
@@ -9278,7 +9366,7 @@ var SUBCOMMANDS = Object.freeze([
|
|
|
9278
9366
|
WHOAMI_ROW
|
|
9279
9367
|
]);
|
|
9280
9368
|
var SERVED = LINE_RUNNER;
|
|
9281
|
-
var NPX_FORM_SENTENCE = `Where the command is not installed, install it with ${installLineOf(DEFAULT_COMMAND_ORIGIN)}
|
|
9369
|
+
var NPX_FORM_SENTENCE = `Where the command is not installed, install it with ${installLineOf(DEFAULT_COMMAND_ORIGIN)}. A person or a job may instead run the same line through npx: write ${commandRunnerOf("latest")} for ${LINE_RUNNER}. A tool where the command is not installed uses deploy_files within its caps, or the deploy skill's setup steps, never the npx line.`;
|
|
9282
9370
|
var namedWithActs = (subcommand) => subcommand.acts ? `${subcommand.name} ${subcommand.acts.join("|")}` : subcommand.name;
|
|
9283
9371
|
var shown = (option) => option.flag ? option.name : `${option.name} ${option.value}`;
|
|
9284
9372
|
var listed = (names) => names.length < 3 ? names.join(" and ") : `${names.slice(0, -1).join(", ")}, and ${names[names.length - 1]}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "turnzero",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0-next.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Turn Zero Cloud command, which an AI coding tool runs on your machine to deploy an application, store a secret, upload a file, download an export, take a library entry, write a local run's settings, start the application locally, and scaffold a new service from a template.",
|
|
6
6
|
"license": "Apache-2.0",
|