create-jay 0.22.0 → 0.22.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/dist/index.js +64 -144
- package/package.json +1 -1
- package/templates/jay-skill.md +1 -1
package/dist/index.js
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// lib/index.ts
|
|
4
4
|
import path2 from "node:path";
|
|
5
|
-
import fs2 from "node:fs";
|
|
6
5
|
import { execSync } from "node:child_process";
|
|
7
6
|
import chalk from "chalk";
|
|
8
|
-
import { input as input2 } from "@inquirer/prompts";
|
|
9
7
|
|
|
10
8
|
// lib/prompts.ts
|
|
11
9
|
import { input, checkbox } from "@inquirer/prompts";
|
|
@@ -52,14 +50,6 @@ var PLUGINS = [
|
|
|
52
50
|
checked: false,
|
|
53
51
|
isDep: true
|
|
54
52
|
},
|
|
55
|
-
{
|
|
56
|
-
name: "@jay-framework/wix-cart",
|
|
57
|
-
label: "Wix Cart",
|
|
58
|
-
description: "Shopping cart: add/remove items, checkout, order summary",
|
|
59
|
-
group: "Wix",
|
|
60
|
-
checked: false,
|
|
61
|
-
isDep: true
|
|
62
|
-
},
|
|
63
53
|
{
|
|
64
54
|
name: "@jay-framework/wix-members",
|
|
65
55
|
label: "Wix Members",
|
|
@@ -91,14 +81,6 @@ var PLUGINS = [
|
|
|
91
81
|
group: "Wix",
|
|
92
82
|
checked: false,
|
|
93
83
|
isDep: true
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: "@jay-framework/wix-server-client",
|
|
97
|
-
label: "Wix Server Client",
|
|
98
|
-
description: "Server-side Wix API client: authentication, API access",
|
|
99
|
-
group: "Wix",
|
|
100
|
-
checked: false,
|
|
101
|
-
isDep: true
|
|
102
84
|
}
|
|
103
85
|
];
|
|
104
86
|
var CORE_DEPS = {
|
|
@@ -115,17 +97,21 @@ var CORE_DEV_DEPS = {
|
|
|
115
97
|
};
|
|
116
98
|
|
|
117
99
|
// lib/prompts.ts
|
|
100
|
+
function validateProjectName(value) {
|
|
101
|
+
const name = value.trim();
|
|
102
|
+
if (!name)
|
|
103
|
+
return "Project name is required";
|
|
104
|
+
if (name.length < 3)
|
|
105
|
+
return "Project name must be at least 3 characters";
|
|
106
|
+
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name)) {
|
|
107
|
+
return "Use lowercase letters, numbers, and hyphens \u2014 must start and end with a letter or number (e.g., my-store)";
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
118
111
|
async function runPrompts() {
|
|
119
112
|
const name = await input({
|
|
120
113
|
message: "Project name:",
|
|
121
|
-
validate:
|
|
122
|
-
if (!value.trim())
|
|
123
|
-
return "Project name is required";
|
|
124
|
-
if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(value.trim())) {
|
|
125
|
-
return "Use lowercase letters, numbers, and hyphens (e.g., my-store)";
|
|
126
|
-
}
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
114
|
+
validate: validateProjectName
|
|
129
115
|
});
|
|
130
116
|
const groups = /* @__PURE__ */ new Map();
|
|
131
117
|
for (const plugin of PLUGINS) {
|
|
@@ -174,14 +160,16 @@ function writeFile(projectDir, relativePath, content) {
|
|
|
174
160
|
}
|
|
175
161
|
function generatePackageJson(name, selectedPlugins) {
|
|
176
162
|
const deps = { ...CORE_DEPS };
|
|
177
|
-
const hasWixPlugins2 = selectedPlugins.some((p) => p.name.startsWith("@jay-framework/wix-"));
|
|
178
163
|
for (const plugin of selectedPlugins) {
|
|
179
164
|
if (plugin.isDep)
|
|
180
165
|
deps[plugin.name] = "latest";
|
|
181
166
|
}
|
|
182
|
-
|
|
167
|
+
const hasWixPlugins = selectedPlugins.some((p) => p.name.startsWith("@jay-framework/wix-"));
|
|
168
|
+
const hasWixStores = selectedPlugins.some((p) => p.name === "@jay-framework/wix-stores");
|
|
169
|
+
if (hasWixPlugins)
|
|
183
170
|
deps["@jay-framework/wix-server-client"] = "latest";
|
|
184
|
-
|
|
171
|
+
if (hasWixStores)
|
|
172
|
+
deps["@jay-framework/wix-cart"] = "latest";
|
|
185
173
|
const devDeps = { ...CORE_DEV_DEPS };
|
|
186
174
|
for (const plugin of selectedPlugins) {
|
|
187
175
|
if (!plugin.isDep)
|
|
@@ -270,131 +258,51 @@ function detectPackageManager() {
|
|
|
270
258
|
function run(cmd, cwd) {
|
|
271
259
|
execSync(cmd, { cwd, stdio: "inherit" });
|
|
272
260
|
}
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
console.log(chalk.cyan(" https://manage.wix.com/account/api-keys"));
|
|
282
|
-
console.log("");
|
|
283
|
-
return input2({
|
|
284
|
-
message: "Wix API Key:",
|
|
285
|
-
validate: (v) => v.trim() ? true : "API key is required"
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
async function setupWix(projectDir, apiKey) {
|
|
289
|
-
let loggedIn = false;
|
|
290
|
-
try {
|
|
291
|
-
execSync("npx @wix/cli whoami", { cwd: projectDir, stdio: "pipe" });
|
|
292
|
-
loggedIn = true;
|
|
293
|
-
} catch {
|
|
294
|
-
}
|
|
295
|
-
if (!loggedIn) {
|
|
296
|
-
console.log(chalk.dim(" You need to log in to Wix to connect your site."));
|
|
297
|
-
try {
|
|
298
|
-
run("npx @wix/cli login", projectDir);
|
|
299
|
-
} catch {
|
|
300
|
-
console.log(chalk.yellow(" \u26A0 Wix login failed \u2014 run `npx @wix/cli login` manually"));
|
|
301
|
-
return;
|
|
261
|
+
function parseArgs() {
|
|
262
|
+
const args = process.argv.slice(2);
|
|
263
|
+
const result = {};
|
|
264
|
+
for (let i = 0; i < args.length; i++) {
|
|
265
|
+
if (args[i] === "--name" && args[i + 1]) {
|
|
266
|
+
result.name = args[++i];
|
|
267
|
+
} else if (args[i] === "--plugins" && args[i + 1]) {
|
|
268
|
+
result.plugins = args[++i];
|
|
302
269
|
}
|
|
303
270
|
}
|
|
304
|
-
|
|
305
|
-
try {
|
|
306
|
-
run("npm create @wix/new@latest init", projectDir);
|
|
307
|
-
} catch {
|
|
308
|
-
console.log(chalk.yellow(" \u26A0 Wix site init failed \u2014 you can run it manually later"));
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const wixConfigPath = path2.join(projectDir, "wix.config.json");
|
|
312
|
-
if (!fs2.existsSync(wixConfigPath)) {
|
|
313
|
-
console.log(chalk.yellow(" \u26A0 wix.config.json not created \u2014 skipping credential setup"));
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
let siteId = "";
|
|
317
|
-
let appId = "";
|
|
318
|
-
try {
|
|
319
|
-
const wixConfig = JSON.parse(fs2.readFileSync(wixConfigPath, "utf-8"));
|
|
320
|
-
siteId = wixConfig.siteId || "";
|
|
321
|
-
appId = wixConfig.appId || "";
|
|
322
|
-
} catch {
|
|
323
|
-
console.log(chalk.yellow(" \u26A0 Could not parse wix.config.json"));
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
if (!siteId || !appId) {
|
|
327
|
-
console.log(chalk.yellow(" \u26A0 Missing siteId or appId in wix.config.json"));
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
const configDir = path2.join(projectDir, "config");
|
|
331
|
-
fs2.mkdirSync(configDir, { recursive: true });
|
|
332
|
-
fs2.writeFileSync(
|
|
333
|
-
path2.join(configDir, ".wix.yaml"),
|
|
334
|
-
`# Wix API Configuration
|
|
335
|
-
#
|
|
336
|
-
# This file contains credentials for connecting to your Wix site.
|
|
337
|
-
# Get these values from your Wix dashboard:
|
|
338
|
-
# - API Key: https://dev.wix.com/docs/rest/articles/getting-started/api-keys
|
|
339
|
-
# - Site ID: Found in your Wix dashboard URL or site settings
|
|
340
|
-
# - OAuth Client ID: Create an OAuth app in Wix Developers dashboard
|
|
341
|
-
#
|
|
342
|
-
# IMPORTANT: This file contains secrets. Add config/.wix.yaml to .gitignore.
|
|
343
|
-
|
|
344
|
-
# Server-side authentication (required)
|
|
345
|
-
apiKeyStrategy:
|
|
346
|
-
apiKey: "${apiKey.trim()}"
|
|
347
|
-
siteId: "${siteId}"
|
|
348
|
-
|
|
349
|
-
# Client-side authentication (required for interactive features)
|
|
350
|
-
oauthStrategy:
|
|
351
|
-
clientId: "${appId}"
|
|
352
|
-
`,
|
|
353
|
-
"utf-8"
|
|
354
|
-
);
|
|
355
|
-
const gitignorePath = path2.join(projectDir, ".gitignore");
|
|
356
|
-
const gitignoreEntries = ["config/.wix.yaml", "wix.config.json"];
|
|
357
|
-
if (fs2.existsSync(gitignorePath)) {
|
|
358
|
-
let content = fs2.readFileSync(gitignorePath, "utf-8");
|
|
359
|
-
for (const entry of gitignoreEntries) {
|
|
360
|
-
if (!content.includes(entry)) {
|
|
361
|
-
content += `
|
|
362
|
-
${entry}`;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
fs2.writeFileSync(gitignorePath, content.trimEnd() + "\n", "utf-8");
|
|
366
|
-
} else {
|
|
367
|
-
fs2.writeFileSync(
|
|
368
|
-
gitignorePath,
|
|
369
|
-
`node_modules
|
|
370
|
-
dist
|
|
371
|
-
build
|
|
372
|
-
${gitignoreEntries.join("\n")}
|
|
373
|
-
`,
|
|
374
|
-
"utf-8"
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
console.log(chalk.green(" \u2713 Wix credentials configured"));
|
|
271
|
+
return result;
|
|
378
272
|
}
|
|
379
273
|
async function main() {
|
|
380
274
|
const pm = detectPackageManager();
|
|
275
|
+
const cliArgs = parseArgs();
|
|
276
|
+
const isNonInteractive = !!(cliArgs.name && cliArgs.plugins !== void 0);
|
|
381
277
|
console.log("");
|
|
382
278
|
console.log(chalk.bold(" Create Jay Stack Project"));
|
|
383
279
|
console.log("");
|
|
384
|
-
|
|
385
|
-
|
|
280
|
+
let name;
|
|
281
|
+
let selectedPlugins;
|
|
282
|
+
if (isNonInteractive) {
|
|
283
|
+
name = cliArgs.name;
|
|
284
|
+
const nameError = validateProjectName(name);
|
|
285
|
+
if (nameError !== true) {
|
|
286
|
+
console.error(chalk.red(` Error: ${nameError}`));
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
const requested = cliArgs.plugins ? cliArgs.plugins.split(",").map((s) => s.trim()) : [];
|
|
290
|
+
selectedPlugins = PLUGINS.filter(
|
|
291
|
+
(p) => requested.includes(p.name) || requested.includes(p.label.toLowerCase())
|
|
292
|
+
);
|
|
293
|
+
} else {
|
|
294
|
+
const config = await runPrompts();
|
|
295
|
+
name = config.name;
|
|
296
|
+
selectedPlugins = config.selectedPlugins;
|
|
297
|
+
}
|
|
298
|
+
const projectDir = path2.resolve(process.cwd(), name);
|
|
386
299
|
console.log("");
|
|
387
|
-
console.log(`Creating project in ${chalk.cyan(`./${
|
|
388
|
-
|
|
389
|
-
const wixApiKey = wixSelected ? await promptWixApiKey() : "";
|
|
390
|
-
scaffoldProject(projectDir, config.name, config.selectedPlugins);
|
|
300
|
+
console.log(`Creating project in ${chalk.cyan(`./${name}`)}...`);
|
|
301
|
+
scaffoldProject(projectDir, name, selectedPlugins);
|
|
391
302
|
console.log(chalk.green(" \u2713 Created project structure"));
|
|
392
303
|
console.log(chalk.dim(" Installing dependencies..."));
|
|
393
304
|
run(pm === "yarn" ? "yarn install" : "npm install", projectDir);
|
|
394
305
|
console.log(chalk.green(" \u2713 Installed dependencies"));
|
|
395
|
-
if (wixSelected) {
|
|
396
|
-
await setupWix(projectDir, wixApiKey);
|
|
397
|
-
}
|
|
398
306
|
console.log(chalk.dim(" Generating agent-kit..."));
|
|
399
307
|
try {
|
|
400
308
|
run("npx jay-stack-cli agent-kit", projectDir);
|
|
@@ -408,16 +316,28 @@ async function main() {
|
|
|
408
316
|
}
|
|
409
317
|
console.log(chalk.dim(" Running plugin setup..."));
|
|
410
318
|
try {
|
|
411
|
-
|
|
319
|
+
const setupCmd = isNonInteractive ? "npx jay-stack-cli setup" : "npx jay-stack-cli setup --interactive";
|
|
320
|
+
run(setupCmd, projectDir);
|
|
412
321
|
console.log(chalk.green(" \u2713 Plugin setup complete"));
|
|
413
322
|
} catch {
|
|
414
|
-
|
|
323
|
+
if (!isNonInteractive) {
|
|
324
|
+
try {
|
|
325
|
+
run("npx jay-stack-cli setup", projectDir);
|
|
326
|
+
console.log(chalk.green(" \u2713 Plugin setup complete"));
|
|
327
|
+
} catch {
|
|
328
|
+
console.log(
|
|
329
|
+
chalk.yellow(" \u26A0 Setup incomplete (can run later with: npm run setup)")
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
} else {
|
|
333
|
+
console.log(chalk.yellow(" \u26A0 Setup incomplete (can run later with: npm run setup)"));
|
|
334
|
+
}
|
|
415
335
|
}
|
|
416
336
|
const runCmd = pm === "yarn" ? "yarn dev" : "npm run dev";
|
|
417
337
|
console.log("");
|
|
418
338
|
console.log(chalk.bold(" Ready!"));
|
|
419
339
|
console.log("");
|
|
420
|
-
console.log(` ${chalk.cyan(`cd ${
|
|
340
|
+
console.log(` ${chalk.cyan(`cd ${name}`)}`);
|
|
421
341
|
console.log(` ${chalk.cyan(runCmd)}`);
|
|
422
342
|
console.log("");
|
|
423
343
|
}
|
package/package.json
CHANGED
package/templates/jay-skill.md
CHANGED
|
@@ -15,7 +15,7 @@ Jay Stack is a full-stack framework. Plugins provide headless components (data +
|
|
|
15
15
|
yarn jay-stack-cli setup
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
This configures plugins —
|
|
18
|
+
This configures plugins interactively — prompts for API keys and credentials, creates config files, validates services. Run this once when starting a new project or after adding a plugin. Use `--no-interactive` in CI/scripts to create config templates without prompting.
|
|
19
19
|
|
|
20
20
|
### Step 2: Generate the agent kit
|
|
21
21
|
|