@vsceasy/cli 0.1.5 → 0.1.7
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/CHANGELOG.md +6 -0
- package/README.md +11 -5
- package/dist/bin/cli.js +252 -159
- package/dist/index.js +27 -12
- package/dist/lib/templatesData.d.ts +1 -1
- package/package.json +1 -1
- package/templates/_generators/crud/formApp.tsx.tpl +25 -10
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,7 @@ All notable changes follow [Keep a Changelog](https://keepachangelog.com/en/1.1.
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
7
|
### Added
|
|
8
|
+
- **`vsceasy create` post-scaffold setup** — after generating the project, `create` now offers to **initialize a git repository** (`git init`) and **install dependencies** (`bun`, falling back to `npm`). Both prompts default to yes in an interactive terminal. New `--git` / `--install` flags (and `--git=false` / `--install=false`) skip the prompts for scripting/CI. Non-interactive runs without the flags skip both, as before.
|
|
8
9
|
- **`vsceasy job add`** — scaffold recurring / event-triggered jobs into `src/jobs/`. Schedules: `--every "60s"`, `--dailyAt "09:00"`, `--on startup|saveDocument|openDocument|changeActiveEditor|changeConfig`, `--onFile "**/*.md"`. Optional `--minIntervalMs` throttles re-runs via globalState. Runtime (`bootstrap`) auto-registers timers/listeners + cleanup on deactivate, catches errors so they don't crash the host.
|
|
9
10
|
- **`command add --when <expr>`** — declare VS Code `when` clauses on commands. Auto-written to `contributes.commands[].enablement` and `contributes.menus.commandPalette` by `bun run gen`. Enables context-aware visibility (e.g. `editorTextFocus`, `resourceLangId == typescript`).
|
|
10
11
|
- **`vsceasy helper add <kind>`** — generate typed runtime wrappers in `src/helpers/`:
|
|
@@ -40,6 +41,11 @@ All notable changes follow [Keep a Changelog](https://keepachangelog.com/en/1.1.
|
|
|
40
41
|
- Bumped to **0.1.0** — first signed/tagged release.
|
|
41
42
|
- Dropped Svelte/Vue/Vanilla mentions from docs and CLI options. Only React UI is supported in this release.
|
|
42
43
|
|
|
44
|
+
### Fixed
|
|
45
|
+
- **`crud add --menu` flag parsing** — passing a raw policy string (`--menu none`, `--menu new:<id>`, `--menu existing:<id>`) non-interactively was mis-mapped to `existing:<literal>`, so `--menu none` failed with `Menu not found: src/menus/none.ts`. The flag forms now work the same as the interactive choices (which was already the documented behavior).
|
|
46
|
+
- **Generated CRUD form wiped on reveal** — the scaffolded form panel re-ran its loader on every focus/visibility change. With no row pending it reset to an empty "New" form, discarding whatever the user was typing (e.g. ticking a boolean then losing focus). The loader now only resets on the initial mount; later reveals adopt a newly-requested edit row but otherwise leave the in-progress form untouched. Re-run `crud add` (or pull the change into existing `*/App.tsx` form panels) to pick up the fix.
|
|
47
|
+
- **Generated CRUD date fields didn't prefill when editing** — `<input type="date">` only accepts a `yyyy-MM-dd` value, but stored dates are ISO strings (or `Date` objects), so editing a row showed the date field blank. The generated form now normalizes through a `toDateInput()` helper. Re-run `crud add` (or add the helper to existing form panels) to pick up the fix.
|
|
48
|
+
|
|
43
49
|
## [0.0.1] — 2026-05-21
|
|
44
50
|
|
|
45
51
|
- Initial MVP. React template, typed RPC bridge, file-based registry, CLI generators (`panel`, `command`, `menu`, `rpc`, `statusBar`, `subpanel`), `doctor`, `upgrade`.
|
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo-mark.svg" alt="vsceasy octopus mascot" width="96" height="96" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">vsceasy</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">Build VS Code extensions fast. React UI + typed RPC bridge between extension and webview + zero-config build.</p>
|
|
4
8
|
|
|
5
9
|
> Status: v0.1 — React UI. Typed RPC bridge + file-based registry + scaffolding for panels, commands, menus, tree views, subpanels, status bars.
|
|
6
10
|
|
|
@@ -20,13 +24,13 @@ vsceasy --version
|
|
|
20
24
|
|
|
21
25
|
```bash
|
|
22
26
|
bunx @vsceasy/cli create my-extension
|
|
27
|
+
# prompts to init git + install deps, then:
|
|
23
28
|
cd my-extension
|
|
24
|
-
bun install
|
|
25
29
|
bun run dev
|
|
26
30
|
# press F5 in VS Code to launch the Extension Development Host
|
|
27
31
|
```
|
|
28
32
|
|
|
29
|
-
Or with flags:
|
|
33
|
+
Or with flags — `--git` / `--install` skip the post-scaffold prompts:
|
|
30
34
|
|
|
31
35
|
```bash
|
|
32
36
|
bunx @vsceasy/cli create \
|
|
@@ -34,7 +38,9 @@ bunx @vsceasy/cli create \
|
|
|
34
38
|
--displayName "My Extension" \
|
|
35
39
|
--description "Does cool things" \
|
|
36
40
|
--publisher my-publisher \
|
|
37
|
-
--ui react
|
|
41
|
+
--ui react \
|
|
42
|
+
--git \
|
|
43
|
+
--install
|
|
38
44
|
```
|
|
39
45
|
|
|
40
46
|
## What you get
|
package/dist/bin/cli.js
CHANGED
|
@@ -3826,7 +3826,7 @@ var init_scaffold = __esm(() => {
|
|
|
3826
3826
|
});
|
|
3827
3827
|
|
|
3828
3828
|
// src/lib/templatesData.ts
|
|
3829
|
-
var TEMPLATES_VERSION = "0.1.
|
|
3829
|
+
var TEMPLATES_VERSION = "0.1.7", TEMPLATE_FILES;
|
|
3830
3830
|
var init_templatesData = __esm(() => {
|
|
3831
3831
|
TEMPLATE_FILES = {
|
|
3832
3832
|
"_generators/command/command.ts.tpl": `import { defineCommand } from '../shared/vsceasy';
|
|
@@ -4025,21 +4025,35 @@ type FormState = Partial<{{Name}}>;
|
|
|
4025
4025
|
|
|
4026
4026
|
const emptyForm: FormState = {{emptyFormLiteral}};
|
|
4027
4027
|
|
|
4028
|
+
// \`<input type="date">\` only accepts a \`yyyy-MM-dd\` value. Stored dates may be
|
|
4029
|
+
// ISO strings or Date objects, so normalize before binding to the input.
|
|
4030
|
+
function toDateInput(v: unknown): string {
|
|
4031
|
+
if (v == null || v === '') return '';
|
|
4032
|
+
const d = v instanceof Date ? v : new Date(v as string);
|
|
4033
|
+
return Number.isNaN(d.getTime()) ? '' : d.toISOString().slice(0, 10);
|
|
4034
|
+
}
|
|
4035
|
+
|
|
4028
4036
|
export function App() {
|
|
4029
4037
|
const [form, setForm] = useState<FormState>(emptyForm);
|
|
4030
4038
|
const [editingId, setEditingId] = useState<{{Name}}['{{primaryKey}}'] | null>(null);
|
|
4031
4039
|
const [error, setError] = useState<string | null>(null);
|
|
4032
4040
|
const [saving, setSaving] = useState(false);
|
|
4033
4041
|
|
|
4034
|
-
const load = useCallback(async () => {
|
|
4035
|
-
// The list stashes
|
|
4036
|
-
// clears it after handing it over)
|
|
4042
|
+
const load = useCallback(async (initial: boolean) => {
|
|
4043
|
+
// The list stashes a row id before revealing this panel. Pull it (the host
|
|
4044
|
+
// clears it after handing it over).
|
|
4037
4045
|
const id = await api.pendingId();
|
|
4038
4046
|
if (id == null || id === '') {
|
|
4039
|
-
|
|
4040
|
-
|
|
4047
|
+
// No row was requested. On the first mount, start with an empty "new" form.
|
|
4048
|
+
// On later reveals (focus/visibility), DON'T reset — that would wipe a form
|
|
4049
|
+
// the user is busy filling in. Just leave the current state as-is.
|
|
4050
|
+
if (initial) {
|
|
4051
|
+
setForm(emptyForm);
|
|
4052
|
+
setEditingId(null);
|
|
4053
|
+
}
|
|
4041
4054
|
return;
|
|
4042
4055
|
}
|
|
4056
|
+
// The list asked to edit a specific row — load it, replacing the current form.
|
|
4043
4057
|
const row = await api.get(id);
|
|
4044
4058
|
if (row) {
|
|
4045
4059
|
setForm(row);
|
|
@@ -4048,11 +4062,12 @@ export function App() {
|
|
|
4048
4062
|
}, []);
|
|
4049
4063
|
|
|
4050
4064
|
useEffect(() => {
|
|
4051
|
-
void load();
|
|
4052
|
-
// Webviews retain state when hidden, so re-
|
|
4053
|
-
//
|
|
4054
|
-
|
|
4055
|
-
const
|
|
4065
|
+
void load(true);
|
|
4066
|
+
// Webviews retain state when hidden, so re-check on reveal: the list may have
|
|
4067
|
+
// asked to edit a different row. When nothing is pending, \`load\` leaves the
|
|
4068
|
+
// in-progress form untouched (see above).
|
|
4069
|
+
const onFocus = () => { void load(false); };
|
|
4070
|
+
const onVisible = () => { if (document.visibilityState === 'visible') void load(false); };
|
|
4056
4071
|
window.addEventListener('focus', onFocus);
|
|
4057
4072
|
document.addEventListener('visibilitychange', onVisible);
|
|
4058
4073
|
return () => {
|
|
@@ -7692,65 +7707,6 @@ var init_findProject = __esm(() => {
|
|
|
7692
7707
|
path3 = __toESM(require("path"));
|
|
7693
7708
|
});
|
|
7694
7709
|
|
|
7695
|
-
// src/commands/create.ts
|
|
7696
|
-
function toTitle(s) {
|
|
7697
|
-
return s.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7698
|
-
}
|
|
7699
|
-
var import_cli_maker, path4, createCommand, create_default;
|
|
7700
|
-
var init_create = __esm(() => {
|
|
7701
|
-
init_scaffold();
|
|
7702
|
-
init_findProject();
|
|
7703
|
-
import_cli_maker = __toESM(require_dist(), 1);
|
|
7704
|
-
path4 = __toESM(require("path"));
|
|
7705
|
-
createCommand = {
|
|
7706
|
-
name: "create",
|
|
7707
|
-
description: "Scaffold a new VS Code extension project",
|
|
7708
|
-
params: [
|
|
7709
|
-
{ name: "name", description: "Extension package name (e.g. my-extension or @scope/my-ext)", required: true, type: import_cli_maker.ParamType.Text },
|
|
7710
|
-
{ name: "displayName", description: "Human-readable extension name", required: false, type: import_cli_maker.ParamType.Text },
|
|
7711
|
-
{ name: "description", description: "Short description", required: false, type: import_cli_maker.ParamType.Text },
|
|
7712
|
-
{ name: "publisher", description: "VS Code publisher id", required: false, type: import_cli_maker.ParamType.Text },
|
|
7713
|
-
{ name: "ui", description: "UI framework", required: false, type: import_cli_maker.ParamType.List, options: ["react"] },
|
|
7714
|
-
{ name: "preset", description: "Project preset (minimal = empty extension, full = panel + RPC sample)", required: false, type: import_cli_maker.ParamType.List, options: ["minimal", "full"] },
|
|
7715
|
-
{ name: "dir", description: "Target directory (defaults to ./<name>)", required: false, type: import_cli_maker.ParamType.Text }
|
|
7716
|
-
],
|
|
7717
|
-
action: async (args) => {
|
|
7718
|
-
const name = args.name;
|
|
7719
|
-
const simpleName = name.replace(/^@[^/]+\//, "");
|
|
7720
|
-
const ui = args.ui ?? "react";
|
|
7721
|
-
const preset = args.preset ?? "full";
|
|
7722
|
-
const targetDir = path4.resolve(process.cwd(), args.dir ?? simpleName);
|
|
7723
|
-
try {
|
|
7724
|
-
await scaffold({
|
|
7725
|
-
name,
|
|
7726
|
-
displayName: args.displayName ?? toTitle(simpleName),
|
|
7727
|
-
description: args.description ?? `${simpleName} VS Code extension`,
|
|
7728
|
-
publisher: args.publisher ?? "your-publisher",
|
|
7729
|
-
ui,
|
|
7730
|
-
preset,
|
|
7731
|
-
targetDir,
|
|
7732
|
-
templatesRoot: findTemplatesRoot()
|
|
7733
|
-
});
|
|
7734
|
-
const rel = path4.relative(process.cwd(), targetDir) || ".";
|
|
7735
|
-
console.log(`
|
|
7736
|
-
✓ Created ${name} at ${rel}
|
|
7737
|
-
`);
|
|
7738
|
-
console.log("Next steps:");
|
|
7739
|
-
console.log(` cd ${rel}`);
|
|
7740
|
-
console.log(" bun install");
|
|
7741
|
-
console.log(" bun run launch # builds + opens Extension Development Host");
|
|
7742
|
-
console.log(" # or `bun run dev` + F5 inside VS Code for watch mode\n");
|
|
7743
|
-
} catch (err) {
|
|
7744
|
-
console.error(`
|
|
7745
|
-
✗ Failed to scaffold: ${err.message}
|
|
7746
|
-
`);
|
|
7747
|
-
process.exitCode = 1;
|
|
7748
|
-
}
|
|
7749
|
-
}
|
|
7750
|
-
};
|
|
7751
|
-
create_default = createCommand;
|
|
7752
|
-
});
|
|
7753
|
-
|
|
7754
7710
|
// src/lib/interactive.ts
|
|
7755
7711
|
function rl() {
|
|
7756
7712
|
return readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -7758,11 +7714,11 @@ function rl() {
|
|
|
7758
7714
|
async function askText(question, defaultValue) {
|
|
7759
7715
|
const r = rl();
|
|
7760
7716
|
const hint = defaultValue ? ` ${DIM}[${defaultValue}]${RST}` : "";
|
|
7761
|
-
return new Promise((
|
|
7717
|
+
return new Promise((resolve2) => {
|
|
7762
7718
|
r.question(`${CYAN}?${RST} ${question}${hint}: `, (ans) => {
|
|
7763
7719
|
r.close();
|
|
7764
7720
|
const v = (ans ?? "").trim();
|
|
7765
|
-
|
|
7721
|
+
resolve2(v.length ? v : defaultValue ?? "");
|
|
7766
7722
|
});
|
|
7767
7723
|
});
|
|
7768
7724
|
}
|
|
@@ -7803,7 +7759,7 @@ async function selectArrow(question, options, opts) {
|
|
|
7803
7759
|
if (index >= v.length)
|
|
7804
7760
|
index = Math.max(0, v.length - 1);
|
|
7805
7761
|
};
|
|
7806
|
-
return new Promise((
|
|
7762
|
+
return new Promise((resolve2, reject) => {
|
|
7807
7763
|
const stdin = process.stdin;
|
|
7808
7764
|
const stdout = process.stdout;
|
|
7809
7765
|
let lastLines = 0;
|
|
@@ -7880,7 +7836,7 @@ async function selectArrow(question, options, opts) {
|
|
|
7880
7836
|
cleanup();
|
|
7881
7837
|
stdout.write(`${CYAN}?${RST} ${BOLD}${question}${RST} ${GREEN}${v[index].label}${RST}
|
|
7882
7838
|
`);
|
|
7883
|
-
|
|
7839
|
+
resolve2(v[index].value);
|
|
7884
7840
|
return;
|
|
7885
7841
|
}
|
|
7886
7842
|
if (data === "" || data === "\b") {
|
|
@@ -7949,6 +7905,132 @@ var init_interactive = __esm(() => {
|
|
|
7949
7905
|
style = { DIM, BOLD, CYAN, GREEN, YELLOW, INV, RST };
|
|
7950
7906
|
});
|
|
7951
7907
|
|
|
7908
|
+
// src/commands/create.ts
|
|
7909
|
+
function toTitle(s) {
|
|
7910
|
+
return s.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7911
|
+
}
|
|
7912
|
+
function toBool(v) {
|
|
7913
|
+
if (v === undefined || v === null || v === "")
|
|
7914
|
+
return;
|
|
7915
|
+
if (typeof v === "boolean")
|
|
7916
|
+
return v;
|
|
7917
|
+
const s = String(v).trim().toLowerCase();
|
|
7918
|
+
if (["true", "1", "yes", "y"].includes(s))
|
|
7919
|
+
return true;
|
|
7920
|
+
if (["false", "0", "no", "n"].includes(s))
|
|
7921
|
+
return false;
|
|
7922
|
+
return;
|
|
7923
|
+
}
|
|
7924
|
+
function which(cmd) {
|
|
7925
|
+
const r = import_child_process.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
7926
|
+
return r.status === 0;
|
|
7927
|
+
}
|
|
7928
|
+
function initGit(cwd) {
|
|
7929
|
+
const r = import_child_process.spawnSync("git", ["init"], { cwd, stdio: "inherit" });
|
|
7930
|
+
if (r.status === 0) {
|
|
7931
|
+
console.log("✓ Initialized git repository");
|
|
7932
|
+
return true;
|
|
7933
|
+
}
|
|
7934
|
+
console.warn("! Could not initialize git repository");
|
|
7935
|
+
return false;
|
|
7936
|
+
}
|
|
7937
|
+
function runInstall(pm, cwd) {
|
|
7938
|
+
console.log(`
|
|
7939
|
+
Installing dependencies with ${pm}...
|
|
7940
|
+
`);
|
|
7941
|
+
const r = import_child_process.spawnSync(pm, ["install"], { cwd, stdio: "inherit" });
|
|
7942
|
+
if (r.status === 0) {
|
|
7943
|
+
console.log(`
|
|
7944
|
+
✓ Dependencies installed`);
|
|
7945
|
+
return true;
|
|
7946
|
+
}
|
|
7947
|
+
console.warn(`
|
|
7948
|
+
! ${pm} install failed — run it manually`);
|
|
7949
|
+
return false;
|
|
7950
|
+
}
|
|
7951
|
+
var import_cli_maker, path4, import_child_process, createCommand, create_default;
|
|
7952
|
+
var init_create = __esm(() => {
|
|
7953
|
+
init_scaffold();
|
|
7954
|
+
init_findProject();
|
|
7955
|
+
init_interactive();
|
|
7956
|
+
import_cli_maker = __toESM(require_dist(), 1);
|
|
7957
|
+
path4 = __toESM(require("path"));
|
|
7958
|
+
import_child_process = require("child_process");
|
|
7959
|
+
createCommand = {
|
|
7960
|
+
name: "create",
|
|
7961
|
+
description: "Scaffold a new VS Code extension project",
|
|
7962
|
+
params: [
|
|
7963
|
+
{ name: "name", description: "Extension package name (e.g. my-extension or @scope/my-ext)", required: true, type: import_cli_maker.ParamType.Text },
|
|
7964
|
+
{ name: "displayName", description: "Human-readable extension name", required: false, type: import_cli_maker.ParamType.Text },
|
|
7965
|
+
{ name: "description", description: "Short description", required: false, type: import_cli_maker.ParamType.Text },
|
|
7966
|
+
{ name: "publisher", description: "VS Code publisher id", required: false, type: import_cli_maker.ParamType.Text },
|
|
7967
|
+
{ name: "ui", description: "UI framework", required: false, type: import_cli_maker.ParamType.List, options: ["react"] },
|
|
7968
|
+
{ name: "preset", description: "Project preset (minimal = empty extension, full = panel + RPC sample)", required: false, type: import_cli_maker.ParamType.List, options: ["minimal", "full"] },
|
|
7969
|
+
{ name: "dir", description: "Target directory (defaults to ./<name>)", required: false, type: import_cli_maker.ParamType.Text },
|
|
7970
|
+
{ name: "git", description: "Initialize a git repository (skips the prompt)", required: false, type: import_cli_maker.ParamType.Boolean },
|
|
7971
|
+
{ name: "install", description: "Install dependencies after scaffolding (skips the prompt)", required: false, type: import_cli_maker.ParamType.Boolean }
|
|
7972
|
+
],
|
|
7973
|
+
action: async (args) => {
|
|
7974
|
+
const name = args.name;
|
|
7975
|
+
const simpleName = name.replace(/^@[^/]+\//, "");
|
|
7976
|
+
const ui = args.ui ?? "react";
|
|
7977
|
+
const preset = args.preset ?? "full";
|
|
7978
|
+
const targetDir = path4.resolve(process.cwd(), args.dir ?? simpleName);
|
|
7979
|
+
try {
|
|
7980
|
+
await scaffold({
|
|
7981
|
+
name,
|
|
7982
|
+
displayName: args.displayName ?? toTitle(simpleName),
|
|
7983
|
+
description: args.description ?? `${simpleName} VS Code extension`,
|
|
7984
|
+
publisher: args.publisher ?? "your-publisher",
|
|
7985
|
+
ui,
|
|
7986
|
+
preset,
|
|
7987
|
+
targetDir,
|
|
7988
|
+
templatesRoot: findTemplatesRoot()
|
|
7989
|
+
});
|
|
7990
|
+
const rel = path4.relative(process.cwd(), targetDir) || ".";
|
|
7991
|
+
console.log(`
|
|
7992
|
+
✓ Created ${name} at ${rel}
|
|
7993
|
+
`);
|
|
7994
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
7995
|
+
const gitFlag = toBool(args.git);
|
|
7996
|
+
const installFlag = toBool(args.install);
|
|
7997
|
+
const wantGit = gitFlag ?? (interactive ? await confirm("Initialize a git repository?", true) : false);
|
|
7998
|
+
if (wantGit) {
|
|
7999
|
+
if (which("git"))
|
|
8000
|
+
initGit(targetDir);
|
|
8001
|
+
else
|
|
8002
|
+
console.warn("! git not found — skipping repository init");
|
|
8003
|
+
}
|
|
8004
|
+
let pm = null;
|
|
8005
|
+
const wantInstall = installFlag ?? (interactive ? await confirm("Install dependencies?", true) : false);
|
|
8006
|
+
let installed = false;
|
|
8007
|
+
if (wantInstall) {
|
|
8008
|
+
pm = which("bun") ? "bun" : which("npm") ? "npm" : null;
|
|
8009
|
+
if (pm)
|
|
8010
|
+
installed = runInstall(pm, targetDir);
|
|
8011
|
+
else
|
|
8012
|
+
console.warn("! No package manager (bun/npm) found — skipping install");
|
|
8013
|
+
}
|
|
8014
|
+
const run = pm ?? "bun";
|
|
8015
|
+
console.log(`
|
|
8016
|
+
Next steps:`);
|
|
8017
|
+
console.log(` cd ${rel}`);
|
|
8018
|
+
if (!installed)
|
|
8019
|
+
console.log(` ${run} install`);
|
|
8020
|
+
console.log(` ${run} run launch # builds + opens Extension Development Host`);
|
|
8021
|
+
console.log(` # or \`${run} run dev\` + F5 inside VS Code for watch mode
|
|
8022
|
+
`);
|
|
8023
|
+
} catch (err) {
|
|
8024
|
+
console.error(`
|
|
8025
|
+
✗ Failed to scaffold: ${err.message}
|
|
8026
|
+
`);
|
|
8027
|
+
process.exitCode = 1;
|
|
8028
|
+
}
|
|
8029
|
+
}
|
|
8030
|
+
};
|
|
8031
|
+
create_default = createCommand;
|
|
8032
|
+
});
|
|
8033
|
+
|
|
7952
8034
|
// src/lib/validate.ts
|
|
7953
8035
|
function assertId(field, value) {
|
|
7954
8036
|
const trimmed = (value ?? "").trim();
|
|
@@ -8116,18 +8198,18 @@ function appendApi(apiPath, apiName, body, created, modified, skipped) {
|
|
|
8116
8198
|
}
|
|
8117
8199
|
function runGen(cwd) {
|
|
8118
8200
|
const tryRun = (cmd, args) => {
|
|
8119
|
-
const r =
|
|
8201
|
+
const r = import_child_process2.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
8120
8202
|
return r.status === 0;
|
|
8121
8203
|
};
|
|
8122
|
-
if (
|
|
8204
|
+
if (which2("bun") && tryRun("bun", ["run", "gen"]))
|
|
8123
8205
|
return true;
|
|
8124
|
-
if (
|
|
8206
|
+
if (which2("npm") && tryRun("npm", ["run", "gen"]))
|
|
8125
8207
|
return true;
|
|
8126
8208
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` (or `npm run gen`) manually to wire up the new panel.\n');
|
|
8127
8209
|
return false;
|
|
8128
8210
|
}
|
|
8129
|
-
function
|
|
8130
|
-
const r =
|
|
8211
|
+
function which2(cmd) {
|
|
8212
|
+
const r = import_child_process2.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
8131
8213
|
return r.status === 0;
|
|
8132
8214
|
}
|
|
8133
8215
|
function normalizeCamel(s) {
|
|
@@ -8136,14 +8218,14 @@ function normalizeCamel(s) {
|
|
|
8136
8218
|
return "";
|
|
8137
8219
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
8138
8220
|
}
|
|
8139
|
-
var fs6, path7,
|
|
8221
|
+
var fs6, path7, import_child_process2, PANEL_TEMPLATES, API_BODY, TEMPLATE_VARS;
|
|
8140
8222
|
var init_add2 = __esm(() => {
|
|
8141
8223
|
init_scaffold();
|
|
8142
8224
|
init_validate();
|
|
8143
8225
|
init_add();
|
|
8144
8226
|
fs6 = __toESM(require("fs"));
|
|
8145
8227
|
path7 = __toESM(require("path"));
|
|
8146
|
-
|
|
8228
|
+
import_child_process2 = require("child_process");
|
|
8147
8229
|
PANEL_TEMPLATES = ["blank", "form", "list", "dashboard"];
|
|
8148
8230
|
API_BODY = {
|
|
8149
8231
|
blank: "",
|
|
@@ -8210,18 +8292,18 @@ function editMenu(opts) {
|
|
|
8210
8292
|
}
|
|
8211
8293
|
function runGen2(cwd) {
|
|
8212
8294
|
const tryRun = (cmd, args) => {
|
|
8213
|
-
const r =
|
|
8295
|
+
const r = import_child_process3.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
8214
8296
|
return r.status === 0;
|
|
8215
8297
|
};
|
|
8216
|
-
if (
|
|
8298
|
+
if (which3("bun") && tryRun("bun", ["run", "gen"]))
|
|
8217
8299
|
return true;
|
|
8218
|
-
if (
|
|
8300
|
+
if (which3("npm") && tryRun("npm", ["run", "gen"]))
|
|
8219
8301
|
return true;
|
|
8220
8302
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
8221
8303
|
return false;
|
|
8222
8304
|
}
|
|
8223
|
-
function
|
|
8224
|
-
const r =
|
|
8305
|
+
function which3(cmd) {
|
|
8306
|
+
const r = import_child_process3.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
8225
8307
|
return r.status === 0;
|
|
8226
8308
|
}
|
|
8227
8309
|
function insertItem(src, item) {
|
|
@@ -8393,11 +8475,11 @@ function findMatching(src, openIdx) {
|
|
|
8393
8475
|
}
|
|
8394
8476
|
return -1;
|
|
8395
8477
|
}
|
|
8396
|
-
var fs7, path8,
|
|
8478
|
+
var fs7, path8, import_child_process3;
|
|
8397
8479
|
var init_edit = __esm(() => {
|
|
8398
8480
|
fs7 = __toESM(require("fs"));
|
|
8399
8481
|
path8 = __toESM(require("path"));
|
|
8400
|
-
|
|
8482
|
+
import_child_process3 = require("child_process");
|
|
8401
8483
|
});
|
|
8402
8484
|
|
|
8403
8485
|
// src/lib/command/add.ts
|
|
@@ -8453,18 +8535,18 @@ function addCommand(opts) {
|
|
|
8453
8535
|
}
|
|
8454
8536
|
function runGen3(cwd) {
|
|
8455
8537
|
const tryRun = (cmd, args) => {
|
|
8456
|
-
const r =
|
|
8538
|
+
const r = import_child_process4.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
8457
8539
|
return r.status === 0;
|
|
8458
8540
|
};
|
|
8459
|
-
if (
|
|
8541
|
+
if (which4("bun") && tryRun("bun", ["run", "gen"]))
|
|
8460
8542
|
return true;
|
|
8461
|
-
if (
|
|
8543
|
+
if (which4("npm") && tryRun("npm", ["run", "gen"]))
|
|
8462
8544
|
return true;
|
|
8463
8545
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
8464
8546
|
return false;
|
|
8465
8547
|
}
|
|
8466
|
-
function
|
|
8467
|
-
const r =
|
|
8548
|
+
function which4(cmd) {
|
|
8549
|
+
const r = import_child_process4.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
8468
8550
|
return r.status === 0;
|
|
8469
8551
|
}
|
|
8470
8552
|
function escapeQuotes(s) {
|
|
@@ -8476,7 +8558,7 @@ function normalizeCamel2(s) {
|
|
|
8476
8558
|
return "";
|
|
8477
8559
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
8478
8560
|
}
|
|
8479
|
-
var fs8, path9,
|
|
8561
|
+
var fs8, path9, import_child_process4;
|
|
8480
8562
|
var init_add3 = __esm(() => {
|
|
8481
8563
|
init_scaffold();
|
|
8482
8564
|
init_edit();
|
|
@@ -8484,7 +8566,7 @@ var init_add3 = __esm(() => {
|
|
|
8484
8566
|
init_config();
|
|
8485
8567
|
fs8 = __toESM(require("fs"));
|
|
8486
8568
|
path9 = __toESM(require("path"));
|
|
8487
|
-
|
|
8569
|
+
import_child_process4 = require("child_process");
|
|
8488
8570
|
});
|
|
8489
8571
|
|
|
8490
8572
|
// src/lib/helper/add.ts
|
|
@@ -10013,24 +10095,24 @@ function filesEqual(a, b) {
|
|
|
10013
10095
|
}
|
|
10014
10096
|
function runGen4(cwd) {
|
|
10015
10097
|
const tryRun = (cmd, args) => {
|
|
10016
|
-
const r =
|
|
10098
|
+
const r = import_child_process5.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
10017
10099
|
return r.status === 0;
|
|
10018
10100
|
};
|
|
10019
|
-
if (
|
|
10101
|
+
if (which5("bun") && tryRun("bun", ["run", "gen"]))
|
|
10020
10102
|
return true;
|
|
10021
|
-
if (
|
|
10103
|
+
if (which5("npm") && tryRun("npm", ["run", "gen"]))
|
|
10022
10104
|
return true;
|
|
10023
10105
|
return false;
|
|
10024
10106
|
}
|
|
10025
|
-
function
|
|
10026
|
-
const r =
|
|
10107
|
+
function which5(cmd) {
|
|
10108
|
+
const r = import_child_process5.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
10027
10109
|
return r.status === 0;
|
|
10028
10110
|
}
|
|
10029
|
-
var fs13, path15,
|
|
10111
|
+
var fs13, path15, import_child_process5, SYNC_PATHS;
|
|
10030
10112
|
var init_upgrade = __esm(() => {
|
|
10031
10113
|
fs13 = __toESM(require("fs"));
|
|
10032
10114
|
path15 = __toESM(require("path"));
|
|
10033
|
-
|
|
10115
|
+
import_child_process5 = require("child_process");
|
|
10034
10116
|
SYNC_PATHS = [
|
|
10035
10117
|
"src/shared/vsceasy/define.ts",
|
|
10036
10118
|
"src/shared/vsceasy/bootstrap.ts",
|
|
@@ -10257,18 +10339,18 @@ function addMenu(opts) {
|
|
|
10257
10339
|
}
|
|
10258
10340
|
function runGen5(cwd) {
|
|
10259
10341
|
const tryRun = (cmd, args) => {
|
|
10260
|
-
const r =
|
|
10342
|
+
const r = import_child_process6.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
10261
10343
|
return r.status === 0;
|
|
10262
10344
|
};
|
|
10263
|
-
if (
|
|
10345
|
+
if (which6("bun") && tryRun("bun", ["run", "gen"]))
|
|
10264
10346
|
return true;
|
|
10265
|
-
if (
|
|
10347
|
+
if (which6("npm") && tryRun("npm", ["run", "gen"]))
|
|
10266
10348
|
return true;
|
|
10267
10349
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
10268
10350
|
return false;
|
|
10269
10351
|
}
|
|
10270
|
-
function
|
|
10271
|
-
const r =
|
|
10352
|
+
function which6(cmd) {
|
|
10353
|
+
const r = import_child_process6.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
10272
10354
|
return r.status === 0;
|
|
10273
10355
|
}
|
|
10274
10356
|
function normalizeCamel4(s) {
|
|
@@ -10277,14 +10359,14 @@ function normalizeCamel4(s) {
|
|
|
10277
10359
|
return "";
|
|
10278
10360
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
10279
10361
|
}
|
|
10280
|
-
var fs14, path17,
|
|
10362
|
+
var fs14, path17, import_child_process6;
|
|
10281
10363
|
var init_add7 = __esm(() => {
|
|
10282
10364
|
init_scaffold();
|
|
10283
10365
|
init_validate();
|
|
10284
10366
|
init_config();
|
|
10285
10367
|
fs14 = __toESM(require("fs"));
|
|
10286
10368
|
path17 = __toESM(require("path"));
|
|
10287
|
-
|
|
10369
|
+
import_child_process6 = require("child_process");
|
|
10288
10370
|
});
|
|
10289
10371
|
|
|
10290
10372
|
// src/commands/menu/add.ts
|
|
@@ -10828,25 +10910,25 @@ function buildSnippet(method, argNames) {
|
|
|
10828
10910
|
}
|
|
10829
10911
|
function runGen6(cwd) {
|
|
10830
10912
|
const tryRun = (cmd, args) => {
|
|
10831
|
-
const r =
|
|
10913
|
+
const r = import_child_process7.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
10832
10914
|
return r.status === 0;
|
|
10833
10915
|
};
|
|
10834
|
-
if (
|
|
10916
|
+
if (which7("bun") && tryRun("bun", ["run", "gen"]))
|
|
10835
10917
|
return true;
|
|
10836
|
-
if (
|
|
10918
|
+
if (which7("npm") && tryRun("npm", ["run", "gen"]))
|
|
10837
10919
|
return true;
|
|
10838
10920
|
return false;
|
|
10839
10921
|
}
|
|
10840
|
-
function
|
|
10841
|
-
const r =
|
|
10922
|
+
function which7(cmd) {
|
|
10923
|
+
const r = import_child_process7.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
10842
10924
|
return r.status === 0;
|
|
10843
10925
|
}
|
|
10844
|
-
var fs17, path21,
|
|
10926
|
+
var fs17, path21, import_child_process7;
|
|
10845
10927
|
var init_add10 = __esm(() => {
|
|
10846
10928
|
init_validate();
|
|
10847
10929
|
fs17 = __toESM(require("fs"));
|
|
10848
10930
|
path21 = __toESM(require("path"));
|
|
10849
|
-
|
|
10931
|
+
import_child_process7 = require("child_process");
|
|
10850
10932
|
});
|
|
10851
10933
|
|
|
10852
10934
|
// src/commands/rpc/add.ts
|
|
@@ -11001,17 +11083,17 @@ function asBacktickString(s) {
|
|
|
11001
11083
|
}
|
|
11002
11084
|
function runGen7(cwd) {
|
|
11003
11085
|
const tryRun = (cmd, args) => {
|
|
11004
|
-
const r =
|
|
11086
|
+
const r = import_child_process8.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
11005
11087
|
return r.status === 0;
|
|
11006
11088
|
};
|
|
11007
|
-
if (
|
|
11089
|
+
if (which8("bun") && tryRun("bun", ["run", "gen"]))
|
|
11008
11090
|
return true;
|
|
11009
|
-
if (
|
|
11091
|
+
if (which8("npm") && tryRun("npm", ["run", "gen"]))
|
|
11010
11092
|
return true;
|
|
11011
11093
|
return false;
|
|
11012
11094
|
}
|
|
11013
|
-
function
|
|
11014
|
-
const r =
|
|
11095
|
+
function which8(cmd) {
|
|
11096
|
+
const r = import_child_process8.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
11015
11097
|
return r.status === 0;
|
|
11016
11098
|
}
|
|
11017
11099
|
function normalizeCamel5(s) {
|
|
@@ -11020,14 +11102,14 @@ function normalizeCamel5(s) {
|
|
|
11020
11102
|
return "";
|
|
11021
11103
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
11022
11104
|
}
|
|
11023
|
-
var fs18, path23,
|
|
11105
|
+
var fs18, path23, import_child_process8;
|
|
11024
11106
|
var init_add12 = __esm(() => {
|
|
11025
11107
|
init_scaffold();
|
|
11026
11108
|
init_add3();
|
|
11027
11109
|
init_validate();
|
|
11028
11110
|
fs18 = __toESM(require("fs"));
|
|
11029
11111
|
path23 = __toESM(require("path"));
|
|
11030
|
-
|
|
11112
|
+
import_child_process8 = require("child_process");
|
|
11031
11113
|
});
|
|
11032
11114
|
|
|
11033
11115
|
// src/commands/statusBar/add.ts
|
|
@@ -11304,18 +11386,18 @@ function appendApi2(apiPath, apiName, created, modified, skipped) {
|
|
|
11304
11386
|
}
|
|
11305
11387
|
function runGen8(cwd) {
|
|
11306
11388
|
const tryRun = (cmd, args) => {
|
|
11307
|
-
const r =
|
|
11389
|
+
const r = import_child_process9.spawnSync(cmd, args, { cwd, stdio: "inherit" });
|
|
11308
11390
|
return r.status === 0;
|
|
11309
11391
|
};
|
|
11310
|
-
if (
|
|
11392
|
+
if (which9("bun") && tryRun("bun", ["run", "gen"]))
|
|
11311
11393
|
return true;
|
|
11312
|
-
if (
|
|
11394
|
+
if (which9("npm") && tryRun("npm", ["run", "gen"]))
|
|
11313
11395
|
return true;
|
|
11314
11396
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
11315
11397
|
return false;
|
|
11316
11398
|
}
|
|
11317
|
-
function
|
|
11318
|
-
const r =
|
|
11399
|
+
function which9(cmd) {
|
|
11400
|
+
const r = import_child_process9.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
11319
11401
|
return r.status === 0;
|
|
11320
11402
|
}
|
|
11321
11403
|
function normalizeCamel6(s) {
|
|
@@ -11324,13 +11406,13 @@ function normalizeCamel6(s) {
|
|
|
11324
11406
|
return "";
|
|
11325
11407
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
11326
11408
|
}
|
|
11327
|
-
var fs19, path25,
|
|
11409
|
+
var fs19, path25, import_child_process9;
|
|
11328
11410
|
var init_add14 = __esm(() => {
|
|
11329
11411
|
init_scaffold();
|
|
11330
11412
|
init_validate();
|
|
11331
11413
|
fs19 = __toESM(require("fs"));
|
|
11332
11414
|
path25 = __toESM(require("path"));
|
|
11333
|
-
|
|
11415
|
+
import_child_process9 = require("child_process");
|
|
11334
11416
|
});
|
|
11335
11417
|
|
|
11336
11418
|
// src/commands/subpanel/add.ts
|
|
@@ -11436,16 +11518,16 @@ function addTreeView(opts) {
|
|
|
11436
11518
|
return { created: [target], genRan };
|
|
11437
11519
|
}
|
|
11438
11520
|
function runGen9(cwd) {
|
|
11439
|
-
const tryRun = (cmd, args) =>
|
|
11440
|
-
if (
|
|
11521
|
+
const tryRun = (cmd, args) => import_child_process10.spawnSync(cmd, args, { cwd, stdio: "inherit" }).status === 0;
|
|
11522
|
+
if (which10("bun") && tryRun("bun", ["run", "gen"]))
|
|
11441
11523
|
return true;
|
|
11442
|
-
if (
|
|
11524
|
+
if (which10("npm") && tryRun("npm", ["run", "gen"]))
|
|
11443
11525
|
return true;
|
|
11444
11526
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
11445
11527
|
return false;
|
|
11446
11528
|
}
|
|
11447
|
-
function
|
|
11448
|
-
return
|
|
11529
|
+
function which10(cmd) {
|
|
11530
|
+
return import_child_process10.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" }).status === 0;
|
|
11449
11531
|
}
|
|
11450
11532
|
function normalizeCamel7(s) {
|
|
11451
11533
|
const cleaned = s.trim().replace(/[^a-zA-Z0-9]+(.)/g, (_m, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "");
|
|
@@ -11456,13 +11538,13 @@ function normalizeCamel7(s) {
|
|
|
11456
11538
|
function pascal3(s) {
|
|
11457
11539
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
11458
11540
|
}
|
|
11459
|
-
var fs20, path27,
|
|
11541
|
+
var fs20, path27, import_child_process10;
|
|
11460
11542
|
var init_add16 = __esm(() => {
|
|
11461
11543
|
init_scaffold();
|
|
11462
11544
|
init_validate();
|
|
11463
11545
|
fs20 = __toESM(require("fs"));
|
|
11464
11546
|
path27 = __toESM(require("path"));
|
|
11465
|
-
|
|
11547
|
+
import_child_process10 = require("child_process");
|
|
11466
11548
|
});
|
|
11467
11549
|
|
|
11468
11550
|
// src/commands/treeView/add.ts
|
|
@@ -11674,19 +11756,19 @@ function publishInit(opts) {
|
|
|
11674
11756
|
`);
|
|
11675
11757
|
let dryPackOk = null;
|
|
11676
11758
|
if (opts.runDryPack !== false) {
|
|
11677
|
-
const r =
|
|
11759
|
+
const r = import_child_process11.spawnSync("npx", ["--yes", "@vscode/vsce", "ls"], { cwd: opts.projectRoot, stdio: "inherit" });
|
|
11678
11760
|
dryPackOk = r.status === 0;
|
|
11679
11761
|
if (!dryPackOk)
|
|
11680
11762
|
warnings.push("`vsce ls` exited non-zero — inspect output above.");
|
|
11681
11763
|
}
|
|
11682
11764
|
return { created, pkgUpdated, warnings, dryPackOk };
|
|
11683
11765
|
}
|
|
11684
|
-
var fs22, path31,
|
|
11766
|
+
var fs22, path31, import_child_process11;
|
|
11685
11767
|
var init_init2 = __esm(() => {
|
|
11686
11768
|
init_scaffold();
|
|
11687
11769
|
fs22 = __toESM(require("fs"));
|
|
11688
11770
|
path31 = __toESM(require("path"));
|
|
11689
|
-
|
|
11771
|
+
import_child_process11 = require("child_process");
|
|
11690
11772
|
});
|
|
11691
11773
|
|
|
11692
11774
|
// src/commands/publish/init.ts
|
|
@@ -11850,16 +11932,16 @@ function escape(s) {
|
|
|
11850
11932
|
return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
11851
11933
|
}
|
|
11852
11934
|
function runGen10(cwd) {
|
|
11853
|
-
const tryRun = (cmd, args) =>
|
|
11854
|
-
if (
|
|
11935
|
+
const tryRun = (cmd, args) => import_child_process12.spawnSync(cmd, args, { cwd, stdio: "inherit" }).status === 0;
|
|
11936
|
+
if (which11("bun") && tryRun("bun", ["run", "gen"]))
|
|
11855
11937
|
return true;
|
|
11856
|
-
if (
|
|
11938
|
+
if (which11("npm") && tryRun("npm", ["run", "gen"]))
|
|
11857
11939
|
return true;
|
|
11858
11940
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
11859
11941
|
return false;
|
|
11860
11942
|
}
|
|
11861
|
-
function
|
|
11862
|
-
return
|
|
11943
|
+
function which11(cmd) {
|
|
11944
|
+
return import_child_process12.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" }).status === 0;
|
|
11863
11945
|
}
|
|
11864
11946
|
function normalizeCamel8(s) {
|
|
11865
11947
|
const cleaned = s.trim().replace(/[^a-zA-Z0-9]+(.)/g, (_m, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "");
|
|
@@ -11867,13 +11949,13 @@ function normalizeCamel8(s) {
|
|
|
11867
11949
|
return "";
|
|
11868
11950
|
return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
|
|
11869
11951
|
}
|
|
11870
|
-
var fs23, path34,
|
|
11952
|
+
var fs23, path34, import_child_process12;
|
|
11871
11953
|
var init_add19 = __esm(() => {
|
|
11872
11954
|
init_scaffold();
|
|
11873
11955
|
init_validate();
|
|
11874
11956
|
fs23 = __toESM(require("fs"));
|
|
11875
11957
|
path34 = __toESM(require("path"));
|
|
11876
|
-
|
|
11958
|
+
import_child_process12 = require("child_process");
|
|
11877
11959
|
});
|
|
11878
11960
|
|
|
11879
11961
|
// src/commands/job/add.ts
|
|
@@ -12475,7 +12557,7 @@ function renderInput(field, override) {
|
|
|
12475
12557
|
case "boolean":
|
|
12476
12558
|
return wrap(` <input type="checkbox" checked={!!form.${name}} onChange={(e) => onChange('${name}', e.target.checked as any)} />`);
|
|
12477
12559
|
case "date":
|
|
12478
|
-
return wrap(` <input type="date"${required} value={(form.${name}
|
|
12560
|
+
return wrap(` <input type="date"${required} value={toDateInput(form.${name})} onChange={(e) => onChange('${name}', e.target.value as any)} />`);
|
|
12479
12561
|
case "select": {
|
|
12480
12562
|
const opts = (spec.options ?? []).map((o) => ` <option value=${JSON.stringify(o)}>${escapeJsx(o)}</option>`).join(`
|
|
12481
12563
|
`);
|
|
@@ -12602,18 +12684,18 @@ function camelLower(s) {
|
|
|
12602
12684
|
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
12603
12685
|
}
|
|
12604
12686
|
function runGen11(cwd) {
|
|
12605
|
-
const tryRun = (cmd, args) =>
|
|
12606
|
-
if (
|
|
12687
|
+
const tryRun = (cmd, args) => import_child_process13.spawnSync(cmd, args, { cwd, stdio: "inherit" }).status === 0;
|
|
12688
|
+
if (which12("bun") && tryRun("bun", ["run", "gen"]))
|
|
12607
12689
|
return true;
|
|
12608
|
-
if (
|
|
12690
|
+
if (which12("npm") && tryRun("npm", ["run", "gen"]))
|
|
12609
12691
|
return true;
|
|
12610
12692
|
console.warn('\n! Could not run "gen" automatically. Run `bun run gen` manually.\n');
|
|
12611
12693
|
return false;
|
|
12612
12694
|
}
|
|
12613
|
-
function
|
|
12614
|
-
return
|
|
12695
|
+
function which12(cmd) {
|
|
12696
|
+
return import_child_process13.spawnSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" }).status === 0;
|
|
12615
12697
|
}
|
|
12616
|
-
var fs27, path41,
|
|
12698
|
+
var fs27, path41, import_child_process13;
|
|
12617
12699
|
var init_add22 = __esm(() => {
|
|
12618
12700
|
init_scaffold();
|
|
12619
12701
|
init_validate();
|
|
@@ -12623,7 +12705,7 @@ var init_add22 = __esm(() => {
|
|
|
12623
12705
|
init_edit();
|
|
12624
12706
|
fs27 = __toESM(require("fs"));
|
|
12625
12707
|
path41 = __toESM(require("path"));
|
|
12626
|
-
|
|
12708
|
+
import_child_process13 = require("child_process");
|
|
12627
12709
|
});
|
|
12628
12710
|
|
|
12629
12711
|
// src/commands/crud/add.ts
|
|
@@ -12680,14 +12762,16 @@ var init_add23 = __esm(() => {
|
|
|
12680
12762
|
const projectRoot = findProjectRoot();
|
|
12681
12763
|
const templatesRoot = findTemplatesRoot();
|
|
12682
12764
|
let menuSpec;
|
|
12683
|
-
const choice = String(args.menu ?? NONE_SENTINEL2);
|
|
12684
|
-
if (choice === NONE_SENTINEL2) {
|
|
12765
|
+
const choice = String(args.menu ?? NONE_SENTINEL2).trim();
|
|
12766
|
+
if (choice === NONE_SENTINEL2 || choice === "none") {
|
|
12685
12767
|
menuSpec = "none";
|
|
12686
12768
|
} else if (choice === NEW_SENTINEL) {
|
|
12687
12769
|
const id = args.newMenuId ? String(args.newMenuId).trim() : await import_cli_maker18.prompt(" new menu id: ");
|
|
12688
12770
|
if (!id)
|
|
12689
12771
|
throw new Error("New menu id required.");
|
|
12690
12772
|
menuSpec = `new:${id}`;
|
|
12773
|
+
} else if (choice.startsWith("new:") || choice.startsWith("existing:")) {
|
|
12774
|
+
menuSpec = choice;
|
|
12691
12775
|
} else {
|
|
12692
12776
|
menuSpec = `existing:${choice}`;
|
|
12693
12777
|
}
|
|
@@ -12835,12 +12919,21 @@ var init_cli = __esm(() => {
|
|
|
12835
12919
|
import_cli_maker20 = __toESM(require_dist(), 1);
|
|
12836
12920
|
cli = new import_cli_maker20.CLI("vsceasy", "Build VS Code extensions fast — React UI + typed RPC bridge + zero-config build.", {
|
|
12837
12921
|
interactive: true,
|
|
12838
|
-
version: "0.1.
|
|
12922
|
+
version: "0.1.7",
|
|
12839
12923
|
introAnimation: {
|
|
12840
12924
|
enabled: true,
|
|
12841
12925
|
preset: "retro-space",
|
|
12842
12926
|
title: "vsceasy",
|
|
12843
|
-
subtitle: "VS Code Extension Framework"
|
|
12927
|
+
subtitle: "VS Code Extension Framework",
|
|
12928
|
+
asciiArt: [
|
|
12929
|
+
' .-""""-.',
|
|
12930
|
+
" / o o \\",
|
|
12931
|
+
" | .. |",
|
|
12932
|
+
" \\ '--' /",
|
|
12933
|
+
" /`-.__.-`\\",
|
|
12934
|
+
" _/ /|/||\\|\\ \\_",
|
|
12935
|
+
" `--`-`-``-`-`--`"
|
|
12936
|
+
]
|
|
12844
12937
|
},
|
|
12845
12938
|
defaultCommands: {
|
|
12846
12939
|
rotatePassphrase: false,
|
package/dist/index.js
CHANGED
|
@@ -2238,7 +2238,7 @@ var init_upgrade = __esm(() => {
|
|
|
2238
2238
|
});
|
|
2239
2239
|
|
|
2240
2240
|
// src/lib/templatesData.ts
|
|
2241
|
-
var TEMPLATES_VERSION = "0.1.
|
|
2241
|
+
var TEMPLATES_VERSION = "0.1.7", TEMPLATE_FILES;
|
|
2242
2242
|
var init_templatesData = __esm(() => {
|
|
2243
2243
|
TEMPLATE_FILES = {
|
|
2244
2244
|
"_generators/command/command.ts.tpl": `import { defineCommand } from '../shared/vsceasy';
|
|
@@ -2437,21 +2437,35 @@ type FormState = Partial<{{Name}}>;
|
|
|
2437
2437
|
|
|
2438
2438
|
const emptyForm: FormState = {{emptyFormLiteral}};
|
|
2439
2439
|
|
|
2440
|
+
// \`<input type="date">\` only accepts a \`yyyy-MM-dd\` value. Stored dates may be
|
|
2441
|
+
// ISO strings or Date objects, so normalize before binding to the input.
|
|
2442
|
+
function toDateInput(v: unknown): string {
|
|
2443
|
+
if (v == null || v === '') return '';
|
|
2444
|
+
const d = v instanceof Date ? v : new Date(v as string);
|
|
2445
|
+
return Number.isNaN(d.getTime()) ? '' : d.toISOString().slice(0, 10);
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2440
2448
|
export function App() {
|
|
2441
2449
|
const [form, setForm] = useState<FormState>(emptyForm);
|
|
2442
2450
|
const [editingId, setEditingId] = useState<{{Name}}['{{primaryKey}}'] | null>(null);
|
|
2443
2451
|
const [error, setError] = useState<string | null>(null);
|
|
2444
2452
|
const [saving, setSaving] = useState(false);
|
|
2445
2453
|
|
|
2446
|
-
const load = useCallback(async () => {
|
|
2447
|
-
// The list stashes
|
|
2448
|
-
// clears it after handing it over)
|
|
2454
|
+
const load = useCallback(async (initial: boolean) => {
|
|
2455
|
+
// The list stashes a row id before revealing this panel. Pull it (the host
|
|
2456
|
+
// clears it after handing it over).
|
|
2449
2457
|
const id = await api.pendingId();
|
|
2450
2458
|
if (id == null || id === '') {
|
|
2451
|
-
|
|
2452
|
-
|
|
2459
|
+
// No row was requested. On the first mount, start with an empty "new" form.
|
|
2460
|
+
// On later reveals (focus/visibility), DON'T reset — that would wipe a form
|
|
2461
|
+
// the user is busy filling in. Just leave the current state as-is.
|
|
2462
|
+
if (initial) {
|
|
2463
|
+
setForm(emptyForm);
|
|
2464
|
+
setEditingId(null);
|
|
2465
|
+
}
|
|
2453
2466
|
return;
|
|
2454
2467
|
}
|
|
2468
|
+
// The list asked to edit a specific row — load it, replacing the current form.
|
|
2455
2469
|
const row = await api.get(id);
|
|
2456
2470
|
if (row) {
|
|
2457
2471
|
setForm(row);
|
|
@@ -2460,11 +2474,12 @@ export function App() {
|
|
|
2460
2474
|
}, []);
|
|
2461
2475
|
|
|
2462
2476
|
useEffect(() => {
|
|
2463
|
-
void load();
|
|
2464
|
-
// Webviews retain state when hidden, so re-
|
|
2465
|
-
//
|
|
2466
|
-
|
|
2467
|
-
const
|
|
2477
|
+
void load(true);
|
|
2478
|
+
// Webviews retain state when hidden, so re-check on reveal: the list may have
|
|
2479
|
+
// asked to edit a different row. When nothing is pending, \`load\` leaves the
|
|
2480
|
+
// in-progress form untouched (see above).
|
|
2481
|
+
const onFocus = () => { void load(false); };
|
|
2482
|
+
const onVisible = () => { if (document.visibilityState === 'visible') void load(false); };
|
|
2468
2483
|
window.addEventListener('focus', onFocus);
|
|
2469
2484
|
document.addEventListener('visibilitychange', onVisible);
|
|
2470
2485
|
return () => {
|
|
@@ -6723,7 +6738,7 @@ function renderInput(field, override) {
|
|
|
6723
6738
|
case "boolean":
|
|
6724
6739
|
return wrap(` <input type="checkbox" checked={!!form.${name}} onChange={(e) => onChange('${name}', e.target.checked as any)} />`);
|
|
6725
6740
|
case "date":
|
|
6726
|
-
return wrap(` <input type="date"${required} value={(form.${name}
|
|
6741
|
+
return wrap(` <input type="date"${required} value={toDateInput(form.${name})} onChange={(e) => onChange('${name}', e.target.value as any)} />`);
|
|
6727
6742
|
case "select": {
|
|
6728
6743
|
const opts = (spec.options ?? []).map((o) => ` <option value=${JSON.stringify(o)}>${escapeJsx(o)}</option>`).join(`
|
|
6729
6744
|
`);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const TEMPLATES_VERSION = "0.1.
|
|
1
|
+
export declare const TEMPLATES_VERSION = "0.1.7";
|
|
2
2
|
export declare const TEMPLATE_FILES: Record<string, string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vsceasy/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Build VS Code extensions fast — React UI + typed RPC bridge between extension and webview + file-based routing for panels, commands, menus, tree views, and subpanels.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,21 +9,35 @@ type FormState = Partial<{{Name}}>;
|
|
|
9
9
|
|
|
10
10
|
const emptyForm: FormState = {{emptyFormLiteral}};
|
|
11
11
|
|
|
12
|
+
// `<input type="date">` only accepts a `yyyy-MM-dd` value. Stored dates may be
|
|
13
|
+
// ISO strings or Date objects, so normalize before binding to the input.
|
|
14
|
+
function toDateInput(v: unknown): string {
|
|
15
|
+
if (v == null || v === '') return '';
|
|
16
|
+
const d = v instanceof Date ? v : new Date(v as string);
|
|
17
|
+
return Number.isNaN(d.getTime()) ? '' : d.toISOString().slice(0, 10);
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
export function App() {
|
|
13
21
|
const [form, setForm] = useState<FormState>(emptyForm);
|
|
14
22
|
const [editingId, setEditingId] = useState<{{Name}}['{{primaryKey}}'] | null>(null);
|
|
15
23
|
const [error, setError] = useState<string | null>(null);
|
|
16
24
|
const [saving, setSaving] = useState(false);
|
|
17
25
|
|
|
18
|
-
const load = useCallback(async () => {
|
|
19
|
-
// The list stashes
|
|
20
|
-
// clears it after handing it over)
|
|
26
|
+
const load = useCallback(async (initial: boolean) => {
|
|
27
|
+
// The list stashes a row id before revealing this panel. Pull it (the host
|
|
28
|
+
// clears it after handing it over).
|
|
21
29
|
const id = await api.pendingId();
|
|
22
30
|
if (id == null || id === '') {
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
// No row was requested. On the first mount, start with an empty "new" form.
|
|
32
|
+
// On later reveals (focus/visibility), DON'T reset — that would wipe a form
|
|
33
|
+
// the user is busy filling in. Just leave the current state as-is.
|
|
34
|
+
if (initial) {
|
|
35
|
+
setForm(emptyForm);
|
|
36
|
+
setEditingId(null);
|
|
37
|
+
}
|
|
25
38
|
return;
|
|
26
39
|
}
|
|
40
|
+
// The list asked to edit a specific row — load it, replacing the current form.
|
|
27
41
|
const row = await api.get(id);
|
|
28
42
|
if (row) {
|
|
29
43
|
setForm(row);
|
|
@@ -32,11 +46,12 @@ export function App() {
|
|
|
32
46
|
}, []);
|
|
33
47
|
|
|
34
48
|
useEffect(() => {
|
|
35
|
-
void load();
|
|
36
|
-
// Webviews retain state when hidden, so re-
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
const
|
|
49
|
+
void load(true);
|
|
50
|
+
// Webviews retain state when hidden, so re-check on reveal: the list may have
|
|
51
|
+
// asked to edit a different row. When nothing is pending, `load` leaves the
|
|
52
|
+
// in-progress form untouched (see above).
|
|
53
|
+
const onFocus = () => { void load(false); };
|
|
54
|
+
const onVisible = () => { if (document.visibilityState === 'visible') void load(false); };
|
|
40
55
|
window.addEventListener('focus', onFocus);
|
|
41
56
|
document.addEventListener('visibilitychange', onVisible);
|
|
42
57
|
return () => {
|