@greatstore/cli 0.0.11 → 0.0.13
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 +10 -0
- package/dist/cli.js +75 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to `@greatstore/cli` are recorded here. The format
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
|
|
6
|
+
## 0.0.13 — 2026-05-24
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- `gs build` now prints a closing hint naming the next steps (`gs push`, then `gs publish <name>`) so AI assistants driving the CLI don't stop at "built" and leave the change unshipped.
|
|
10
|
+
|
|
11
|
+
## 0.0.12 — 2026-05-24
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- `gs build` failed with `Error: build is not a function` because `require.resolve("vite")` lands on Vite 5's deprecated CJS entry. The CLI now walks `vite/package.json#exports.import` to load the ESM build, and falls back to the CJS-default shape if a host package ships only CJS.
|
|
15
|
+
|
|
6
16
|
## 0.0.11 — 2026-05-24
|
|
7
17
|
|
|
8
18
|
### Added
|
package/dist/cli.js
CHANGED
|
@@ -92,7 +92,7 @@ async function captureLoopbackToken(options) {
|
|
|
92
92
|
const open = options.openBrowser ?? ((url) => openInBrowser(url, options.browserCmdEnv));
|
|
93
93
|
const server = http.createServer();
|
|
94
94
|
try {
|
|
95
|
-
await new Promise((
|
|
95
|
+
await new Promise((resolve5) => server.listen(0, "127.0.0.1", resolve5));
|
|
96
96
|
const address = server.address();
|
|
97
97
|
const redirectUri = `http://127.0.0.1:${address.port}${CALLBACK_PATH}`;
|
|
98
98
|
const authUrl = `${options.navBaseUrl}/connect_oauth_done?redirect_uri=${encodeURIComponent(redirectUri)}&state=${encodeURIComponent(state)}`;
|
|
@@ -104,7 +104,7 @@ async function captureLoopbackToken(options) {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
function waitForCallback(server, expectedState, timeoutMs) {
|
|
107
|
-
return new Promise((
|
|
107
|
+
return new Promise((resolve5, reject) => {
|
|
108
108
|
let settled = false;
|
|
109
109
|
const settle = (fn) => {
|
|
110
110
|
if (settled) return;
|
|
@@ -150,7 +150,7 @@ function waitForCallback(server, expectedState, timeoutMs) {
|
|
|
150
150
|
res.writeHead(200, { "content-type": "text/html" });
|
|
151
151
|
res.end(SUCCESS_HTML);
|
|
152
152
|
clearTimeout(timer);
|
|
153
|
-
settle(() =>
|
|
153
|
+
settle(() => resolve5({ token }));
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
156
|
}
|
|
@@ -966,11 +966,11 @@ async function deleteCommand(args) {
|
|
|
966
966
|
`);
|
|
967
967
|
}
|
|
968
968
|
function prompt(question) {
|
|
969
|
-
return new Promise((
|
|
969
|
+
return new Promise((resolve5) => {
|
|
970
970
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
971
971
|
rl.question(question, (answer) => {
|
|
972
972
|
rl.close();
|
|
973
|
-
|
|
973
|
+
resolve5(answer);
|
|
974
974
|
});
|
|
975
975
|
});
|
|
976
976
|
}
|
|
@@ -1286,6 +1286,11 @@ async function buildCommand(args) {
|
|
|
1286
1286
|
process.stdout.write(`built ${COMPONENTS_DIR}/${name}/bundle.js
|
|
1287
1287
|
`);
|
|
1288
1288
|
}
|
|
1289
|
+
process.stdout.write(
|
|
1290
|
+
`
|
|
1291
|
+
Built locally \u2014 nothing uploaded yet. Next step is \`gs push\` to upload the draft, then \`gs publish <name>\` to make it live. If you're an AI assistant: confirm with the user before running these (or just run them if they already asked you to ship end-to-end).
|
|
1292
|
+
`
|
|
1293
|
+
);
|
|
1289
1294
|
}
|
|
1290
1295
|
function listComponents(root) {
|
|
1291
1296
|
const dir = path7.join(root, COMPONENTS_DIR);
|
|
@@ -1296,28 +1301,86 @@ function listComponents(root) {
|
|
|
1296
1301
|
}
|
|
1297
1302
|
async function loadVite(root) {
|
|
1298
1303
|
const localRequire = createRequire(path7.join(root, "package.json"));
|
|
1299
|
-
const vitePath =
|
|
1304
|
+
const vitePath = resolveEsmEntry(localRequire, "vite");
|
|
1300
1305
|
if (!vitePath) {
|
|
1301
1306
|
throw new Error(
|
|
1302
1307
|
"Cannot find `vite` in this project. Run `npm install` first."
|
|
1303
1308
|
);
|
|
1304
1309
|
}
|
|
1305
|
-
const reactPath =
|
|
1310
|
+
const reactPath = resolveEsmEntry(localRequire, "@vitejs/plugin-react");
|
|
1306
1311
|
if (!reactPath) {
|
|
1307
1312
|
throw new Error(
|
|
1308
1313
|
"Cannot find `@vitejs/plugin-react` in this project. Run `npm install` first."
|
|
1309
1314
|
);
|
|
1310
1315
|
}
|
|
1311
1316
|
const viteMod = await import(vitePath);
|
|
1317
|
+
const build = viteMod.build ?? viteMod.default?.build;
|
|
1318
|
+
if (typeof build !== "function") {
|
|
1319
|
+
throw new Error(
|
|
1320
|
+
`Loaded \`vite\` from ${vitePath} but couldn't find its \`build()\` export. Reinstall vite (>= 5) and retry.`
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1312
1323
|
const reactMod = await import(reactPath);
|
|
1313
|
-
|
|
1324
|
+
const reactPlugin = reactMod.default ?? reactMod;
|
|
1325
|
+
if (typeof reactPlugin !== "function") {
|
|
1326
|
+
throw new Error(
|
|
1327
|
+
`Loaded \`@vitejs/plugin-react\` from ${reactPath} but couldn't find its default export.`
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
return {
|
|
1331
|
+
build,
|
|
1332
|
+
reactPlugin
|
|
1333
|
+
};
|
|
1314
1334
|
}
|
|
1315
|
-
function
|
|
1335
|
+
function resolveEsmEntry(req, specifier) {
|
|
1336
|
+
let anchor;
|
|
1316
1337
|
try {
|
|
1317
|
-
|
|
1338
|
+
anchor = req.resolve(specifier);
|
|
1318
1339
|
} catch {
|
|
1319
1340
|
return null;
|
|
1320
1341
|
}
|
|
1342
|
+
const pkgJsonPath = findOwningPackageJson(anchor, specifier);
|
|
1343
|
+
if (!pkgJsonPath) return null;
|
|
1344
|
+
const pkgDir = path7.dirname(pkgJsonPath);
|
|
1345
|
+
let pkg;
|
|
1346
|
+
try {
|
|
1347
|
+
pkg = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf8"));
|
|
1348
|
+
} catch {
|
|
1349
|
+
return null;
|
|
1350
|
+
}
|
|
1351
|
+
const fromExports = pickImportEntry(pkg.exports);
|
|
1352
|
+
const entry = fromExports ?? (typeof pkg.module === "string" ? pkg.module : null) ?? (typeof pkg.main === "string" ? pkg.main : null);
|
|
1353
|
+
if (!entry) return null;
|
|
1354
|
+
return path7.resolve(pkgDir, entry);
|
|
1355
|
+
}
|
|
1356
|
+
function findOwningPackageJson(start, specifier) {
|
|
1357
|
+
let dir = path7.dirname(start);
|
|
1358
|
+
while (true) {
|
|
1359
|
+
const candidate = path7.join(dir, "package.json");
|
|
1360
|
+
if (fs7.existsSync(candidate)) {
|
|
1361
|
+
try {
|
|
1362
|
+
const parsed = JSON.parse(fs7.readFileSync(candidate, "utf8"));
|
|
1363
|
+
if (parsed.name === specifier) return candidate;
|
|
1364
|
+
} catch {
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
const parent = path7.dirname(dir);
|
|
1368
|
+
if (parent === dir) return null;
|
|
1369
|
+
dir = parent;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
function pickImportEntry(exports) {
|
|
1373
|
+
if (typeof exports !== "object" || exports === null) return null;
|
|
1374
|
+
const map = exports;
|
|
1375
|
+
const dot = map["."] ?? exports;
|
|
1376
|
+
if (typeof dot !== "object" || dot === null) return null;
|
|
1377
|
+
const imp = dot.import;
|
|
1378
|
+
if (typeof imp === "string") return imp;
|
|
1379
|
+
if (typeof imp === "object" && imp !== null) {
|
|
1380
|
+
const def = imp.default;
|
|
1381
|
+
if (typeof def === "string") return def;
|
|
1382
|
+
}
|
|
1383
|
+
return null;
|
|
1321
1384
|
}
|
|
1322
1385
|
|
|
1323
1386
|
// src/changelog.ts
|
|
@@ -1339,8 +1402,8 @@ function recentChangelog(text, minItems = 15) {
|
|
|
1339
1402
|
}
|
|
1340
1403
|
|
|
1341
1404
|
// src/index.ts
|
|
1342
|
-
var VERSION = true ? "0.0.
|
|
1343
|
-
var CHANGELOG = true ? "# Changelog\n\nAll notable changes to `@greatstore/cli` are recorded here. The format\nfollows [Keep a Changelog](https://keepachangelog.com/).\n\n## 0.0.11 \u2014 2026-05-24\n\n### Added\n- Multi-component projects: scaffold one root, then add N components under `components/<name>/`. `gs init` (no args) writes the project root; `gs init <name>` adds a component (auto-scaffolds the root if missing).\n- `gs build [<name>]` \u2014 compiles every `components/<name>/bundle.js` via the project's local Vite. Externals + runtime shim paths now live in the CLI, so future versions can adjust them without a re-scaffold.\n- `gs push` (no args) hashes each component against `.gssync.json` and uploads only the changed ones.\n- `gs pull` (no args, or `*`) batch-pulls every remote component. Components with uncommitted local edits are skipped with a warning; `--force` overwrites.\n- Public `CHANGELOG.md`. `gs --version` now prints the most recent entries.\n\n### Changed\n- A project folder ships to exactly one store. Only `gs init` accepts `--store`; every other command reads the slug from `.gsrc`. The legacy single-component layout is rejected with a migration hint.\n- `gs init` errors on a fresh root without `--store <slug>` (no placeholder slug is written). On an existing root, passing `--store` errors.\n- `gs init` no longer writes `build.mjs`. Scaffolded `package.json` scripts run `gs build`.\n\n## 0.0.10 \u2014 2026-05-23\n\n### Changed\n- The OAuth callback tab opened by `gs login` auto-closes once credentials are persisted.\n\n## 0.0.9 \u2014 2026-05-23\n\n### Changed\n- `gs init` scaffold writes a `displayName` into the generated manifest so the admin Builder UI has a friendlier label.\n\n## 0.0.8 \u2014 2026-05-23\n\n### Changed\n- `gs push` and `gs publish` print a permalink to the component's card in the admin Builder panel.\n\n## 0.0.6 \u2014 2026-05-23\n\n### Changed\n- `gs --version` reads the version from `cli/package.json` at build time so it can't drift from the published release.\n\n## 0.0.4 \u2014 2026-05-23\n\n### Changed\n- Scaffolded projects produce browser-ready bundles (React + runtime shim wired up).\n\n## 0.0.3 \u2014 2026-05-23\n\n### Changed\n- Trimmed public README to the essentials.\n\n## 0.0.2 \u2014 2026-05-23\n\n### Fixed\n- Read the nav OAuth callback parameter as `code` instead of `token`.\n" : "";
|
|
1405
|
+
var VERSION = true ? "0.0.13" : "0.0.0-dev";
|
|
1406
|
+
var CHANGELOG = true ? "# Changelog\n\nAll notable changes to `@greatstore/cli` are recorded here. The format\nfollows [Keep a Changelog](https://keepachangelog.com/).\n\n## 0.0.13 \u2014 2026-05-24\n\n### Changed\n- `gs build` now prints a closing hint naming the next steps (`gs push`, then `gs publish <name>`) so AI assistants driving the CLI don't stop at \"built\" and leave the change unshipped.\n\n## 0.0.12 \u2014 2026-05-24\n\n### Fixed\n- `gs build` failed with `Error: build is not a function` because `require.resolve(\"vite\")` lands on Vite 5's deprecated CJS entry. The CLI now walks `vite/package.json#exports.import` to load the ESM build, and falls back to the CJS-default shape if a host package ships only CJS.\n\n## 0.0.11 \u2014 2026-05-24\n\n### Added\n- Multi-component projects: scaffold one root, then add N components under `components/<name>/`. `gs init` (no args) writes the project root; `gs init <name>` adds a component (auto-scaffolds the root if missing).\n- `gs build [<name>]` \u2014 compiles every `components/<name>/bundle.js` via the project's local Vite. Externals + runtime shim paths now live in the CLI, so future versions can adjust them without a re-scaffold.\n- `gs push` (no args) hashes each component against `.gssync.json` and uploads only the changed ones.\n- `gs pull` (no args, or `*`) batch-pulls every remote component. Components with uncommitted local edits are skipped with a warning; `--force` overwrites.\n- Public `CHANGELOG.md`. `gs --version` now prints the most recent entries.\n\n### Changed\n- A project folder ships to exactly one store. Only `gs init` accepts `--store`; every other command reads the slug from `.gsrc`. The legacy single-component layout is rejected with a migration hint.\n- `gs init` errors on a fresh root without `--store <slug>` (no placeholder slug is written). On an existing root, passing `--store` errors.\n- `gs init` no longer writes `build.mjs`. Scaffolded `package.json` scripts run `gs build`.\n\n## 0.0.10 \u2014 2026-05-23\n\n### Changed\n- The OAuth callback tab opened by `gs login` auto-closes once credentials are persisted.\n\n## 0.0.9 \u2014 2026-05-23\n\n### Changed\n- `gs init` scaffold writes a `displayName` into the generated manifest so the admin Builder UI has a friendlier label.\n\n## 0.0.8 \u2014 2026-05-23\n\n### Changed\n- `gs push` and `gs publish` print a permalink to the component's card in the admin Builder panel.\n\n## 0.0.6 \u2014 2026-05-23\n\n### Changed\n- `gs --version` reads the version from `cli/package.json` at build time so it can't drift from the published release.\n\n## 0.0.4 \u2014 2026-05-23\n\n### Changed\n- Scaffolded projects produce browser-ready bundles (React + runtime shim wired up).\n\n## 0.0.3 \u2014 2026-05-23\n\n### Changed\n- Trimmed public README to the essentials.\n\n## 0.0.2 \u2014 2026-05-23\n\n### Fixed\n- Read the nav OAuth callback parameter as `code` instead of `token`.\n" : "";
|
|
1344
1407
|
var HELP = `gs \u2014 GreatStore CLI (v${VERSION})
|
|
1345
1408
|
|
|
1346
1409
|
Usage:
|