@greatstore/cli 0.0.11-beta.1 → 0.0.11-beta.2
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 +3 -1
- package/dist/cli.js +105 -77
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,8 +5,10 @@ Author and ship GreatStore custom remote components from the command line.
|
|
|
5
5
|
```
|
|
6
6
|
npm install -g @greatstore/cli
|
|
7
7
|
gs login
|
|
8
|
+
gs init --store <slug>
|
|
9
|
+
cd <project> && npm install
|
|
8
10
|
gs init my-widget
|
|
9
|
-
|
|
11
|
+
gs build
|
|
10
12
|
gs push
|
|
11
13
|
gs publish my-widget
|
|
12
14
|
```
|
package/dist/cli.js
CHANGED
|
@@ -1027,14 +1027,14 @@ function initCommand(args) {
|
|
|
1027
1027
|
"Next steps:",
|
|
1028
1028
|
...rootExisted ? [] : [` cd ${projectLabel}`, " npm install"],
|
|
1029
1029
|
` # edit components/${name}/component.tsx and manifest.json`,
|
|
1030
|
-
"
|
|
1030
|
+
" gs build",
|
|
1031
1031
|
" gs push",
|
|
1032
1032
|
""
|
|
1033
1033
|
].join("\n")
|
|
1034
1034
|
);
|
|
1035
1035
|
}
|
|
1036
1036
|
function hasRootScaffold(dir) {
|
|
1037
|
-
return fs6.existsSync(path6.join(dir, "package.json")) && fs6.existsSync(path6.join(dir, "
|
|
1037
|
+
return fs6.existsSync(path6.join(dir, "package.json")) && fs6.existsSync(path6.join(dir, ".gsrc"));
|
|
1038
1038
|
}
|
|
1039
1039
|
function ensureRoot(root, rootExisted, force, opts) {
|
|
1040
1040
|
fs6.mkdirSync(root, { recursive: true });
|
|
@@ -1079,7 +1079,6 @@ function rootFiles(opts) {
|
|
|
1079
1079
|
}
|
|
1080
1080
|
return [
|
|
1081
1081
|
["package.json", rootPackageJson()],
|
|
1082
|
-
["build.mjs", buildScript()],
|
|
1083
1082
|
["vite.config.ts", viteEditorConfig()],
|
|
1084
1083
|
["tsconfig.json", rootTsconfig()],
|
|
1085
1084
|
[".gsrc", gsrc(opts.store)],
|
|
@@ -1131,79 +1130,13 @@ export default function ${pascal(name)}(_props: Props): React.ReactElement {
|
|
|
1131
1130
|
}
|
|
1132
1131
|
`;
|
|
1133
1132
|
}
|
|
1134
|
-
function buildScript() {
|
|
1135
|
-
return `import { build } from "vite";
|
|
1136
|
-
import react from "@vitejs/plugin-react";
|
|
1137
|
-
import * as fs from "node:fs";
|
|
1138
|
-
import * as path from "node:path";
|
|
1139
|
-
|
|
1140
|
-
const COMPONENTS_DIR = path.resolve("components");
|
|
1141
|
-
|
|
1142
|
-
function listComponents() {
|
|
1143
|
-
if (!fs.existsSync(COMPONENTS_DIR)) return [];
|
|
1144
|
-
return fs
|
|
1145
|
-
.readdirSync(COMPONENTS_DIR)
|
|
1146
|
-
.filter((entry) => {
|
|
1147
|
-
const dir = path.join(COMPONENTS_DIR, entry);
|
|
1148
|
-
return (
|
|
1149
|
-
fs.statSync(dir).isDirectory() &&
|
|
1150
|
-
fs.existsSync(path.join(dir, "component.tsx"))
|
|
1151
|
-
);
|
|
1152
|
-
})
|
|
1153
|
-
.sort();
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
const components = listComponents();
|
|
1157
|
-
if (components.length === 0) {
|
|
1158
|
-
console.log("(no components in ./components \u2014 run \`gs init <name>\` to add one)");
|
|
1159
|
-
process.exit(0);
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
const target = process.argv[2];
|
|
1163
|
-
const queue = target ? components.filter((c) => c === target) : components;
|
|
1164
|
-
if (target && queue.length === 0) {
|
|
1165
|
-
console.error(\`No component named "\${target}" in ./components\`);
|
|
1166
|
-
process.exit(1);
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
for (const name of queue) {
|
|
1170
|
-
const dir = path.join(COMPONENTS_DIR, name);
|
|
1171
|
-
await build({
|
|
1172
|
-
plugins: [react()],
|
|
1173
|
-
logLevel: "warn",
|
|
1174
|
-
build: {
|
|
1175
|
-
lib: {
|
|
1176
|
-
entry: path.join(dir, "component.tsx"),
|
|
1177
|
-
formats: ["es"],
|
|
1178
|
-
fileName: () => "bundle.js",
|
|
1179
|
-
},
|
|
1180
|
-
outDir: dir,
|
|
1181
|
-
emptyOutDir: false,
|
|
1182
|
-
rollupOptions: {
|
|
1183
|
-
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
1184
|
-
output: {
|
|
1185
|
-
entryFileNames: "bundle.js",
|
|
1186
|
-
paths: {
|
|
1187
|
-
react: "/assets/remote-components/_runtime.js",
|
|
1188
|
-
"react-dom": "/assets/remote-components/_runtime.js",
|
|
1189
|
-
"react/jsx-runtime": "/assets/remote-components/_runtime.js",
|
|
1190
|
-
},
|
|
1191
|
-
},
|
|
1192
|
-
},
|
|
1193
|
-
minify: true,
|
|
1194
|
-
sourcemap: false,
|
|
1195
|
-
},
|
|
1196
|
-
});
|
|
1197
|
-
console.log(\`built components/\${name}/bundle.js\`);
|
|
1198
|
-
}
|
|
1199
|
-
`;
|
|
1200
|
-
}
|
|
1201
1133
|
function viteEditorConfig() {
|
|
1202
1134
|
return `import { defineConfig } from "vite";
|
|
1203
1135
|
import react from "@vitejs/plugin-react";
|
|
1204
1136
|
|
|
1205
|
-
// Real builds happen in build
|
|
1206
|
-
//
|
|
1137
|
+
// Real builds happen in \`gs build\` (one Vite invocation per
|
|
1138
|
+
// component, externals + runtime shim paths owned by the CLI). This
|
|
1139
|
+
// file exists only so editors / language servers can resolve the
|
|
1207
1140
|
// React plugin when inspecting components/*/component.tsx.
|
|
1208
1141
|
export default defineConfig({
|
|
1209
1142
|
plugins: [react()],
|
|
@@ -1225,7 +1158,7 @@ function rootTsconfig() {
|
|
|
1225
1158
|
isolatedModules: true,
|
|
1226
1159
|
noEmit: true
|
|
1227
1160
|
},
|
|
1228
|
-
include: ["components/**/component.tsx", "vite.config.ts"
|
|
1161
|
+
include: ["components/**/component.tsx", "vite.config.ts"]
|
|
1229
1162
|
},
|
|
1230
1163
|
null,
|
|
1231
1164
|
2
|
|
@@ -1239,8 +1172,8 @@ function rootPackageJson() {
|
|
|
1239
1172
|
private: true,
|
|
1240
1173
|
type: "module",
|
|
1241
1174
|
scripts: {
|
|
1242
|
-
build: "
|
|
1243
|
-
push: "
|
|
1175
|
+
build: "gs build",
|
|
1176
|
+
push: "gs build && gs push"
|
|
1244
1177
|
},
|
|
1245
1178
|
dependencies: {
|
|
1246
1179
|
react: "^19.0.0",
|
|
@@ -1280,7 +1213,7 @@ component lives in its own folder under \`components/\`.
|
|
|
1280
1213
|
\`\`\`
|
|
1281
1214
|
npm install
|
|
1282
1215
|
gs init <component_name> # add a new component
|
|
1283
|
-
|
|
1216
|
+
gs build # builds every components/<name>/bundle.js
|
|
1284
1217
|
gs push # uploads every changed component as a draft
|
|
1285
1218
|
gs publish <component_name> # promote a specific component to live
|
|
1286
1219
|
\`\`\`
|
|
@@ -1296,8 +1229,99 @@ function pascal(name) {
|
|
|
1296
1229
|
return name.split(/[_-]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join("");
|
|
1297
1230
|
}
|
|
1298
1231
|
|
|
1232
|
+
// src/commands/build.ts
|
|
1233
|
+
import * as fs7 from "fs";
|
|
1234
|
+
import * as path7 from "path";
|
|
1235
|
+
import { createRequire } from "module";
|
|
1236
|
+
var COMPONENTS_DIR = "components";
|
|
1237
|
+
async function buildCommand(args) {
|
|
1238
|
+
const root = process.cwd();
|
|
1239
|
+
if (!fs7.existsSync(path7.join(root, "package.json")) || !fs7.existsSync(path7.join(root, COMPONENTS_DIR))) {
|
|
1240
|
+
throw new Error(
|
|
1241
|
+
`\`gs build\` must run from a project root (contains \`package.json\` and \`${COMPONENTS_DIR}/\`). Current dir: ${root}`
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
const components = listComponents(root);
|
|
1245
|
+
if (components.length === 0) {
|
|
1246
|
+
process.stdout.write(
|
|
1247
|
+
`(no components in ./${COMPONENTS_DIR} \u2014 run \`gs init <name>\` to add one)
|
|
1248
|
+
`
|
|
1249
|
+
);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
const target = args.positional[0];
|
|
1253
|
+
const queue = target ? components.filter((c) => c === target) : components;
|
|
1254
|
+
if (target && queue.length === 0) {
|
|
1255
|
+
throw new Error(`No component named "${target}" in ./${COMPONENTS_DIR}`);
|
|
1256
|
+
}
|
|
1257
|
+
const { build, reactPlugin } = await loadVite(root);
|
|
1258
|
+
for (const name of queue) {
|
|
1259
|
+
const dir = path7.join(root, COMPONENTS_DIR, name);
|
|
1260
|
+
await build({
|
|
1261
|
+
plugins: [reactPlugin()],
|
|
1262
|
+
logLevel: "warn",
|
|
1263
|
+
build: {
|
|
1264
|
+
lib: {
|
|
1265
|
+
entry: path7.join(dir, "component.tsx"),
|
|
1266
|
+
formats: ["es"],
|
|
1267
|
+
fileName: () => "bundle.js"
|
|
1268
|
+
},
|
|
1269
|
+
outDir: dir,
|
|
1270
|
+
emptyOutDir: false,
|
|
1271
|
+
rollupOptions: {
|
|
1272
|
+
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
1273
|
+
output: {
|
|
1274
|
+
entryFileNames: "bundle.js",
|
|
1275
|
+
paths: {
|
|
1276
|
+
react: "/assets/remote-components/_runtime.js",
|
|
1277
|
+
"react-dom": "/assets/remote-components/_runtime.js",
|
|
1278
|
+
"react/jsx-runtime": "/assets/remote-components/_runtime.js"
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
},
|
|
1282
|
+
minify: true,
|
|
1283
|
+
sourcemap: false
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
process.stdout.write(`built ${COMPONENTS_DIR}/${name}/bundle.js
|
|
1287
|
+
`);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
function listComponents(root) {
|
|
1291
|
+
const dir = path7.join(root, COMPONENTS_DIR);
|
|
1292
|
+
return fs7.readdirSync(dir).filter((entry) => {
|
|
1293
|
+
const candidate = path7.join(dir, entry);
|
|
1294
|
+
return fs7.statSync(candidate).isDirectory() && fs7.existsSync(path7.join(candidate, "component.tsx"));
|
|
1295
|
+
}).sort();
|
|
1296
|
+
}
|
|
1297
|
+
async function loadVite(root) {
|
|
1298
|
+
const localRequire = createRequire(path7.join(root, "package.json"));
|
|
1299
|
+
const vitePath = tryResolve(localRequire, "vite");
|
|
1300
|
+
if (!vitePath) {
|
|
1301
|
+
throw new Error(
|
|
1302
|
+
"Cannot find `vite` in this project. Run `npm install` first."
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
const reactPath = tryResolve(localRequire, "@vitejs/plugin-react");
|
|
1306
|
+
if (!reactPath) {
|
|
1307
|
+
throw new Error(
|
|
1308
|
+
"Cannot find `@vitejs/plugin-react` in this project. Run `npm install` first."
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
const viteMod = await import(vitePath);
|
|
1312
|
+
const reactMod = await import(reactPath);
|
|
1313
|
+
return { build: viteMod.build, reactPlugin: reactMod.default };
|
|
1314
|
+
}
|
|
1315
|
+
function tryResolve(req, specifier) {
|
|
1316
|
+
try {
|
|
1317
|
+
return req.resolve(specifier);
|
|
1318
|
+
} catch {
|
|
1319
|
+
return null;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1299
1323
|
// src/index.ts
|
|
1300
|
-
var VERSION = true ? "0.0.11-beta.
|
|
1324
|
+
var VERSION = true ? "0.0.11-beta.2" : "0.0.0-dev";
|
|
1301
1325
|
var HELP = `gs \u2014 GreatStore CLI (v${VERSION})
|
|
1302
1326
|
|
|
1303
1327
|
Usage:
|
|
@@ -1308,6 +1332,7 @@ Commands:
|
|
|
1308
1332
|
logout Wipe ~/.greatstore/credentials.json.
|
|
1309
1333
|
whoami Print the identity stored locally.
|
|
1310
1334
|
init [<name>] Scaffold project root; add \`components/<name>/\` if name given.
|
|
1335
|
+
build [<name>] Build component bundle(s) via the project's Vite. No args = all.
|
|
1311
1336
|
list List components in the current store.
|
|
1312
1337
|
pull [<name>|*] Download remote component(s) into \`components/<name>/\`. No args = all.
|
|
1313
1338
|
push [<name>] Upload changed components from \`components/\`. No args = all (skips unchanged).
|
|
@@ -1356,6 +1381,9 @@ async function main() {
|
|
|
1356
1381
|
case "init":
|
|
1357
1382
|
initCommand(parsed);
|
|
1358
1383
|
return 0;
|
|
1384
|
+
case "build":
|
|
1385
|
+
await buildCommand(parsed);
|
|
1386
|
+
return 0;
|
|
1359
1387
|
case "list":
|
|
1360
1388
|
await listCommand(parsed);
|
|
1361
1389
|
return 0;
|