create-jay 0.22.0 → 0.22.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/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: (value) => {
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
- if (hasWixPlugins2 && !deps["@jay-framework/wix-server-client"]) {
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 hasWixPlugins(selectedPlugins) {
274
- return selectedPlugins.some((p) => p.name.startsWith("@jay-framework/wix-"));
275
- }
276
- async function promptWixApiKey() {
277
- console.log("");
278
- console.log(chalk.bold(" Wix Setup"));
279
- console.log("");
280
- console.log(chalk.dim(" Wix plugins require API credentials. Create an API key at:"));
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
- console.log(chalk.dim(" Connecting to your Wix site..."));
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
- const config = await runPrompts();
385
- const projectDir = path2.resolve(process.cwd(), config.name);
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(`./${config.name}`)}...`);
388
- const wixSelected = hasWixPlugins(config.selectedPlugins);
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,26 @@ async function main() {
408
316
  }
409
317
  console.log(chalk.dim(" Running plugin setup..."));
410
318
  try {
411
- run("npx jay-stack-cli setup", projectDir);
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
- console.log(chalk.yellow(" \u26A0 Setup incomplete (can run later with: npm run setup)"));
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(chalk.yellow(" \u26A0 Setup incomplete (can run later with: npm run setup)"));
329
+ }
330
+ } else {
331
+ console.log(chalk.yellow(" \u26A0 Setup incomplete (can run later with: npm run setup)"));
332
+ }
415
333
  }
416
334
  const runCmd = pm === "yarn" ? "yarn dev" : "npm run dev";
417
335
  console.log("");
418
336
  console.log(chalk.bold(" Ready!"));
419
337
  console.log("");
420
- console.log(` ${chalk.cyan(`cd ${config.name}`)}`);
338
+ console.log(` ${chalk.cyan(`cd ${name}`)}`);
421
339
  console.log(` ${chalk.cyan(runCmd)}`);
422
340
  console.log("");
423
341
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jay",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "type": "module",
5
5
  "description": "Create a new Jay Stack project",
6
6
  "license": "Apache-2.0",
@@ -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 — creates config templates, validates credentials, connects to external services. Run this once when starting a new project or after adding a plugin.
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