@visualautomate/cli 0.6.0 → 0.6.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/README.md +4 -0
- package/dist/index.js +64 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,10 @@ Types: `string`, `number`, `boolean`, `select`, `multiselect`, `json`, `color`,
|
|
|
77
77
|
`date`, `connection`, `file`, `path`, `paths`. A `select` or `multiselect` needs
|
|
78
78
|
`--options`, and a `connection` needs `--provider <name>`.
|
|
79
79
|
|
|
80
|
+
The same field is added to `visualautomate.test.json` under `config`, with its
|
|
81
|
+
default or a value of the right shape, so the next `vsa test` passes something
|
|
82
|
+
for it instead of nothing. A value you have already put there is kept.
|
|
83
|
+
|
|
80
84
|
At the root of an app's repository, `--module <name>` says which one — the same
|
|
81
85
|
short names `test` and `dev` take. The manifest is edited where it stands: your
|
|
82
86
|
comments, the examples underneath and your own formatting stay as they are.
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
5
5
|
import { existsSync as existsSync4, watch } from "node:fs";
|
|
6
|
-
import { join as join4, relative as relative3, resolve as resolve3, sep as sep2 } from "node:path";
|
|
6
|
+
import { basename as basename3, join as join4, relative as relative3, resolve as resolve3, sep as sep2 } from "node:path";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { build, stop as stopBundler } from "esbuild";
|
|
9
9
|
|
|
@@ -2051,24 +2051,25 @@ function lastContent(bare, from, to) {
|
|
|
2051
2051
|
function indented(value, indent, depth) {
|
|
2052
2052
|
return JSON.stringify(value, null, indent.length === 1 ? " " : indent.length).replace(/\{\s*"label": ("(?:[^"\\]|\\.)*"),\s*"value": ("(?:[^"\\]|\\.)*")\s*\}/g, '{ "label": $1, "value": $2 }').split("\n").map((line2, index) => index === 0 ? line2 : indent.repeat(depth) + line2).join("\n");
|
|
2053
2053
|
}
|
|
2054
|
-
function
|
|
2054
|
+
function withMember(text, container, key, value) {
|
|
2055
2055
|
const bare = stripJsonComments(text);
|
|
2056
2056
|
const { object, members } = topLevelMembers(bare);
|
|
2057
|
-
if (!object || object.end === -1) throw new Error("This
|
|
2057
|
+
if (!object || object.end === -1) throw new Error("This file is not a JSON object.");
|
|
2058
2058
|
const indent = indentOf(text);
|
|
2059
|
-
const entry = `"${
|
|
2060
|
-
const existing = members.get(
|
|
2059
|
+
const entry = `"${key}": ${indented(value, indent, 2)}`;
|
|
2060
|
+
const existing = members.get(container);
|
|
2061
2061
|
let next;
|
|
2062
2062
|
if (existing && bare[existing.start] === "{") {
|
|
2063
2063
|
const last = lastContent(bare, existing.start, existing.end);
|
|
2064
|
+
const oneLine = last !== -1 && !text.slice(existing.start, existing.end).includes("\n");
|
|
2064
2065
|
next = last === -1 ? text.slice(0, existing.start + 1) + `
|
|
2065
2066
|
${indent.repeat(2)}${entry}
|
|
2066
|
-
${indent}` + text.slice(existing.end) : text.slice(0, last + 1) + `,
|
|
2067
|
+
${indent}` + text.slice(existing.end) : oneLine ? text.slice(0, last + 1) + `, "${key}": ${JSON.stringify(value)}` + text.slice(last + 1) : text.slice(0, last + 1) + `,
|
|
2067
2068
|
${indent.repeat(2)}${entry}` + text.slice(last + 1);
|
|
2068
2069
|
} else if (existing) {
|
|
2069
|
-
throw new Error(
|
|
2070
|
+
throw new Error(`"${container}" in this file is not an object, so nothing can be added to it.`);
|
|
2070
2071
|
} else {
|
|
2071
|
-
const block = `"
|
|
2072
|
+
const block = `"${container}": {
|
|
2072
2073
|
${indent.repeat(2)}${entry}
|
|
2073
2074
|
${indent}}`;
|
|
2074
2075
|
const last = lastContent(bare, object.start, object.end);
|
|
@@ -2078,14 +2079,35 @@ ${indent}${block}
|
|
|
2078
2079
|
${indent}${block}` + text.slice(last + 1);
|
|
2079
2080
|
}
|
|
2080
2081
|
const parsed = JSON.parse(stripJsonComments(next));
|
|
2081
|
-
if (!parsed
|
|
2082
|
-
throw new Error(
|
|
2082
|
+
if (!parsed[container] || !(key in parsed[container])) {
|
|
2083
|
+
throw new Error(`${key} could not be placed in this file. Add it by hand, or say where this went wrong.`);
|
|
2083
2084
|
}
|
|
2084
2085
|
return next;
|
|
2085
2086
|
}
|
|
2086
|
-
function
|
|
2087
|
+
function hasMember(text, container, key) {
|
|
2087
2088
|
const parsed = JSON.parse(stripJsonComments(text));
|
|
2088
|
-
|
|
2089
|
+
const inside = parsed[container];
|
|
2090
|
+
return Boolean(inside && typeof inside === "object" && !Array.isArray(inside) && key in inside);
|
|
2091
|
+
}
|
|
2092
|
+
function sampleFor(property) {
|
|
2093
|
+
if ("default" in property) return property.default;
|
|
2094
|
+
switch (property.type) {
|
|
2095
|
+
case "number":
|
|
2096
|
+
return 0;
|
|
2097
|
+
case "boolean":
|
|
2098
|
+
return false;
|
|
2099
|
+
case "multiselect":
|
|
2100
|
+
case "paths":
|
|
2101
|
+
return [];
|
|
2102
|
+
case "json":
|
|
2103
|
+
return {};
|
|
2104
|
+
case "select": {
|
|
2105
|
+
const options = property.options;
|
|
2106
|
+
return options?.[0]?.value ?? "";
|
|
2107
|
+
}
|
|
2108
|
+
default:
|
|
2109
|
+
return "";
|
|
2110
|
+
}
|
|
2089
2111
|
}
|
|
2090
2112
|
|
|
2091
2113
|
// src/project.ts
|
|
@@ -2497,7 +2519,7 @@ function runInDocker(run) {
|
|
|
2497
2519
|
}
|
|
2498
2520
|
|
|
2499
2521
|
// src/index.ts
|
|
2500
|
-
var VERSION = true ? "0.6.
|
|
2522
|
+
var VERSION = true ? "0.6.1" : "0.0.0-dev";
|
|
2501
2523
|
function fail(message) {
|
|
2502
2524
|
console.error(red(message));
|
|
2503
2525
|
throw new SilentExit();
|
|
@@ -2817,30 +2839,44 @@ Types: ${PROPERTY_TYPES.join(", ")}`
|
|
|
2817
2839
|
const file2 = join4(target.dir, "manifest.json");
|
|
2818
2840
|
if (!existsSync4(file2)) fail(`${target.name} has no manifest.json.`);
|
|
2819
2841
|
const text = await readFile3(file2, "utf8");
|
|
2820
|
-
if (
|
|
2842
|
+
if (hasMember(text, "properties", name)) {
|
|
2821
2843
|
fail(`${target.name} already has a property called ${name}. Change it in ${target.name}/manifest.json.`);
|
|
2822
2844
|
}
|
|
2845
|
+
let property;
|
|
2823
2846
|
let next;
|
|
2824
2847
|
try {
|
|
2825
|
-
|
|
2826
|
-
|
|
2848
|
+
property = buildProperty({
|
|
2849
|
+
type,
|
|
2827
2850
|
name,
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
provider: flags.provider
|
|
2837
|
-
})
|
|
2838
|
-
);
|
|
2851
|
+
description,
|
|
2852
|
+
value,
|
|
2853
|
+
label: flags.label,
|
|
2854
|
+
required: flags.required === "true",
|
|
2855
|
+
options: flags.options,
|
|
2856
|
+
provider: flags.provider
|
|
2857
|
+
});
|
|
2858
|
+
next = withMember(text, "properties", name, property);
|
|
2839
2859
|
} catch (error) {
|
|
2840
2860
|
fail(error instanceof Error ? error.message : String(error));
|
|
2841
2861
|
}
|
|
2842
2862
|
await writeFile2(file2, next, "utf8");
|
|
2843
|
-
|
|
2863
|
+
const written = [`${target.name}/manifest.json`];
|
|
2864
|
+
const testPath = TEST_FILES.map((name2) => join4(target.dir, name2)).find((path) => existsSync4(path)) ?? join4(target.dir, TEST_FILES[0]);
|
|
2865
|
+
const sample = sampleFor(property);
|
|
2866
|
+
try {
|
|
2867
|
+
const before = existsSync4(testPath) ? await readFile3(testPath, "utf8") : `{
|
|
2868
|
+
"config": {},
|
|
2869
|
+
"input": {}
|
|
2870
|
+
}
|
|
2871
|
+
`;
|
|
2872
|
+
if (!hasMember(before, "config", name)) {
|
|
2873
|
+
await writeFile2(testPath, withMember(before, "config", name, sample), "utf8");
|
|
2874
|
+
written.push(`${target.name}/${basename3(testPath)}`);
|
|
2875
|
+
}
|
|
2876
|
+
} catch (error) {
|
|
2877
|
+
ok(yellow(` ${basename3(testPath)} was left alone: ${error instanceof Error ? error.message : String(error)}`));
|
|
2878
|
+
}
|
|
2879
|
+
ok(green(`\u2713 Added ${name} to ${written.join(" and ")}`));
|
|
2844
2880
|
ok(dim(` Read it in your code as config.${name}`));
|
|
2845
2881
|
}
|
|
2846
2882
|
async function cmdDev(args, flags) {
|