@dk/jolly 0.1.4 → 0.1.5

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/bootstrap.js CHANGED
@@ -56,8 +56,14 @@ config();
56
56
  function requireToken() {
57
57
  const token = process.env.SALEOR_CLOUD_TOKEN;
58
58
  if (!token) {
59
- console.error("Error: SALEOR_CLOUD_TOKEN environment variable is required");
60
- console.error("Get your token at: https://cloud.saleor.io/settings/api-tokens");
59
+ console.error(`
60
+ \uD83D\uDD11 Saleor Cloud Token Required`);
61
+ console.error(` Get your token at: https://cloud.saleor.io/settings/api-tokens
62
+ `);
63
+ console.error("Or create a .env file with: SALEOR_CLOUD_TOKEN=your-token");
64
+ console.error(`
65
+ To set token: export SALEOR_CLOUD_TOKEN=your-token
66
+ `);
61
67
  process.exit(1);
62
68
  }
63
69
  return token;
package/dist/index.js CHANGED
@@ -74,16 +74,69 @@ class SaleorCloudClient {
74
74
 
75
75
  // src/api/auth.ts
76
76
  import { config } from "dotenv";
77
+ import { writeFileSync, existsSync, readFileSync } from "fs";
78
+ import { join } from "path";
77
79
  config();
78
80
  function requireToken() {
79
81
  const token = process.env.SALEOR_CLOUD_TOKEN;
80
82
  if (!token) {
81
- console.error("Error: SALEOR_CLOUD_TOKEN environment variable is required");
82
- console.error("Get your token at: https://cloud.saleor.io/settings/api-tokens");
83
+ console.error(`
84
+ \uD83D\uDD11 Saleor Cloud Token Required`);
85
+ console.error(` Get your token at: https://cloud.saleor.io/settings/api-tokens
86
+ `);
87
+ console.error("Or create a .env file with: SALEOR_CLOUD_TOKEN=your-token");
88
+ console.error(`
89
+ To set token: export SALEOR_CLOUD_TOKEN=your-token
90
+ `);
83
91
  process.exit(1);
84
92
  }
85
93
  return token;
86
94
  }
95
+ async function promptAndSaveToken() {
96
+ console.log(`
97
+ \uD83D\uDD11 Saleor Cloud Token Required`);
98
+ console.log(` Get your token at: https://cloud.saleor.io/settings/api-tokens
99
+ `);
100
+ const readline = await import("readline");
101
+ const rl = readline.createInterface({
102
+ input: process.stdin,
103
+ output: process.stdout
104
+ });
105
+ return new Promise((resolve) => {
106
+ rl.question("Enter your SALEOR_CLOUD_TOKEN: ", (answer) => {
107
+ rl.close();
108
+ const token = answer.trim();
109
+ if (!token) {
110
+ console.error("Error: Token cannot be empty");
111
+ process.exit(1);
112
+ }
113
+ const envPath = join(process.cwd(), ".env");
114
+ const envLine = `SALEOR_CLOUD_TOKEN=${token}
115
+ `;
116
+ try {
117
+ let existingContent = "";
118
+ if (existsSync(envPath)) {
119
+ existingContent = readFileSync(envPath, "utf-8");
120
+ if (existingContent.includes("SALEOR_CLOUD_TOKEN=")) {
121
+ existingContent = existingContent.replace(/SALEOR_CLOUD_TOKEN=.*\n?/g, envLine);
122
+ } else {
123
+ existingContent += envLine;
124
+ }
125
+ } else {
126
+ existingContent = envLine;
127
+ }
128
+ writeFileSync(envPath, existingContent);
129
+ console.log(`
130
+ ✅ Token saved to .env file`);
131
+ } catch {
132
+ console.log(`
133
+ ⚠️ Could not save to .env, token will not persist`);
134
+ }
135
+ process.env.SALEOR_CLOUD_TOKEN = token;
136
+ resolve(token);
137
+ });
138
+ });
139
+ }
87
140
 
88
141
  // src/tui/theme.ts
89
142
  var theme = {
@@ -191,6 +244,11 @@ async function createEnvironment(storeId, name) {
191
244
  }
192
245
 
193
246
  // src/cli/commands/store.ts
247
+ async function ensureToken() {
248
+ if (!process.env.SALEOR_CLOUD_TOKEN) {
249
+ await promptAndSaveToken();
250
+ }
251
+ }
194
252
  var storeCommands = {
195
253
  command: "store <action>",
196
254
  describe: "Manage Saleor Cloud stores",
@@ -209,6 +267,7 @@ var storeCommands = {
209
267
  default: "us-east-1"
210
268
  }),
211
269
  handler: async (argv) => {
270
+ await ensureToken();
212
271
  await createStore(argv.name, argv.region);
213
272
  }
214
273
  }).command({
@@ -216,6 +275,7 @@ var storeCommands = {
216
275
  describe: "List your Saleor Cloud stores",
217
276
  builder: (yargs2) => yargs2,
218
277
  handler: async () => {
278
+ await ensureToken();
219
279
  await listStores();
220
280
  }
221
281
  }).command({
@@ -236,6 +296,7 @@ var storeCommands = {
236
296
  demandOption: true
237
297
  }),
238
298
  handler: async (argv) => {
299
+ await ensureToken();
239
300
  await createEnvironment(argv.store, argv.name);
240
301
  }
241
302
  })
@@ -342,6 +403,11 @@ function warning(msg) {
342
403
  }
343
404
 
344
405
  // src/cli/commands/app.ts
406
+ async function ensureToken2() {
407
+ if (!process.env.SALEOR_CLOUD_TOKEN) {
408
+ await promptAndSaveToken();
409
+ }
410
+ }
345
411
  var appCommands = {
346
412
  command: "app <action>",
347
413
  describe: "Scaffold Saleor apps",
@@ -371,15 +437,18 @@ var appCommands = {
371
437
  description: "Environment ID to register app with"
372
438
  }),
373
439
  handler: async (argv) => {
440
+ if (argv.environment) {
441
+ await ensureToken2();
442
+ }
374
443
  await createApp(argv.name, argv.type, argv.environment, argv.provider);
375
444
  }
376
445
  })
377
446
  };
378
447
 
379
448
  // src/agents/setup.ts
380
- import { writeFileSync, mkdirSync, existsSync } from "fs";
449
+ import { writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync2 } from "fs";
381
450
  import { spawnSync } from "child_process";
382
- import { join } from "path";
451
+ import { join as join2 } from "path";
383
452
  var AGENT_PATHS = {
384
453
  opencode: {
385
454
  skills: ".agents/skills",
@@ -457,12 +526,12 @@ function detectAgents(projectPath) {
457
526
  { name: "nanobot", file: ".nanobot" }
458
527
  ];
459
528
  for (const { name, file } of filesToCheck) {
460
- const fullPath = join(projectPath, file);
461
- if (existsSync(fullPath)) {
529
+ const fullPath = join2(projectPath, file);
530
+ if (existsSync2(fullPath)) {
462
531
  detected.push({
463
532
  name,
464
533
  path: fullPath,
465
- skillsPath: join(fullPath, "skills")
534
+ skillsPath: join2(fullPath, "skills")
466
535
  });
467
536
  }
468
537
  }
@@ -470,11 +539,11 @@ function detectAgents(projectPath) {
470
539
  }
471
540
  function installSkills(projectPath, agentName) {
472
541
  const agentPaths = AGENT_PATHS[agentName];
473
- const skillsDir = join(projectPath, agentPaths.skills);
542
+ const skillsDir = join2(projectPath, agentPaths.skills);
474
543
  mkdirSync(skillsDir, { recursive: true });
475
544
  info(` Installing skills to ${skillsDir}...`);
476
545
  const skillUrl = "https://github.com/saleor/agent-skills";
477
- const baseDir = join(skillsDir, "..");
546
+ const baseDir = join2(skillsDir, "..");
478
547
  try {
479
548
  const result = spawnSync("git", ["clone", "--depth", "1", skillUrl, "skills"], {
480
549
  cwd: baseDir,
@@ -540,8 +609,8 @@ Configure saleor-mcp for AI agent capabilities:
540
609
  }
541
610
  \`\`\`
542
611
  `;
543
- const agentsMdPath = join(projectPath, "AGENTS.md");
544
- writeFileSync(agentsMdPath, agentsMdContent);
612
+ const agentsMdPath = join2(projectPath, "AGENTS.md");
613
+ writeFileSync2(agentsMdPath, agentsMdContent);
545
614
  info(` Created AGENTS.md`);
546
615
  }
547
616
  function createMcpConfig(projectPath) {
@@ -552,8 +621,8 @@ function createMcpConfig(projectPath) {
552
621
  }
553
622
  }
554
623
  };
555
- const mcpPath = join(projectPath, ".mcp.json");
556
- writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
624
+ const mcpPath = join2(projectPath, ".mcp.json");
625
+ writeFileSync2(mcpPath, JSON.stringify(mcpConfig, null, 2));
557
626
  info(` Created .mcp.json`);
558
627
  }
559
628
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dk/jolly",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Saleor project bootstrapper and agent configurator",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api/auth.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { config } from 'dotenv';
2
+ import { writeFileSync, existsSync, readFileSync } from 'fs';
3
+ import { join } from 'path';
2
4
 
3
5
  config();
4
6
 
@@ -13,9 +15,61 @@ export function getToken(): string {
13
15
  export function requireToken(): string {
14
16
  const token = process.env.SALEOR_CLOUD_TOKEN;
15
17
  if (!token) {
16
- console.error('Error: SALEOR_CLOUD_TOKEN environment variable is required');
17
- console.error('Get your token at: https://cloud.saleor.io/settings/api-tokens');
18
+ console.error('\n🔑 Saleor Cloud Token Required');
19
+ console.error(' Get your token at: https://cloud.saleor.io/settings/api-tokens\n');
20
+ console.error('Or create a .env file with: SALEOR_CLOUD_TOKEN=your-token');
21
+ console.error('\nTo set token: export SALEOR_CLOUD_TOKEN=your-token\n');
18
22
  process.exit(1);
19
23
  }
20
24
  return token;
21
25
  }
26
+
27
+ export async function promptAndSaveToken(): Promise<string> {
28
+ console.log('\n🔑 Saleor Cloud Token Required');
29
+ console.log(' Get your token at: https://cloud.saleor.io/settings/api-tokens\n');
30
+
31
+ const readline = await import('readline');
32
+ const rl = readline.createInterface({
33
+ input: process.stdin,
34
+ output: process.stdout
35
+ });
36
+
37
+ return new Promise((resolve) => {
38
+ rl.question('Enter your SALEOR_CLOUD_TOKEN: ', (answer: string) => {
39
+ rl.close();
40
+ const token = answer.trim();
41
+
42
+ if (!token) {
43
+ console.error('Error: Token cannot be empty');
44
+ process.exit(1);
45
+ }
46
+
47
+ const envPath = join(process.cwd(), '.env');
48
+ const envLine = `SALEOR_CLOUD_TOKEN=${token}\n`;
49
+
50
+ try {
51
+ let existingContent = '';
52
+ if (existsSync(envPath)) {
53
+ existingContent = readFileSync(envPath, 'utf-8');
54
+ if (existingContent.includes('SALEOR_CLOUD_TOKEN=')) {
55
+ existingContent = existingContent.replace(
56
+ /SALEOR_CLOUD_TOKEN=.*\n?/g,
57
+ envLine
58
+ );
59
+ } else {
60
+ existingContent += envLine;
61
+ }
62
+ } else {
63
+ existingContent = envLine;
64
+ }
65
+ writeFileSync(envPath, existingContent);
66
+ console.log('\n✅ Token saved to .env file');
67
+ } catch {
68
+ console.log('\n⚠️ Could not save to .env, token will not persist');
69
+ }
70
+
71
+ process.env.SALEOR_CLOUD_TOKEN = token;
72
+ resolve(token);
73
+ });
74
+ });
75
+ }
@@ -1,9 +1,16 @@
1
1
  import type { CommandModule } from 'yargs';
2
2
  import { createApp } from '../../commands/app.js';
3
+ import { promptAndSaveToken } from '../../api/auth.js';
3
4
 
4
5
  type AppType = 'dashboard-extension' | 'payment' | 'webhook';
5
6
  type PaymentProvider = 'dummy' | 'stripe';
6
7
 
8
+ async function ensureToken() {
9
+ if (!process.env.SALEOR_CLOUD_TOKEN) {
10
+ await promptAndSaveToken();
11
+ }
12
+ }
13
+
7
14
  export const appCommands: CommandModule = {
8
15
  command: 'app <action>',
9
16
  describe: 'Scaffold Saleor apps',
@@ -40,6 +47,9 @@ export const appCommands: CommandModule = {
40
47
  description: 'Environment ID to register app with',
41
48
  }),
42
49
  handler: async (argv) => {
50
+ if (argv.environment) {
51
+ await ensureToken();
52
+ }
43
53
  await createApp(
44
54
  argv.name,
45
55
  argv.type as AppType,
@@ -1,5 +1,12 @@
1
1
  import type { CommandModule } from 'yargs';
2
2
  import { createStore, listStores, createEnvironment } from '../../commands/store.js';
3
+ import { promptAndSaveToken, getToken } from '../../api/auth.js';
4
+
5
+ async function ensureToken() {
6
+ if (!process.env.SALEOR_CLOUD_TOKEN) {
7
+ await promptAndSaveToken();
8
+ }
9
+ }
3
10
 
4
11
  export const storeCommands: CommandModule = {
5
12
  command: 'store <action>',
@@ -24,6 +31,7 @@ export const storeCommands: CommandModule = {
24
31
  default: 'us-east-1',
25
32
  }),
26
33
  handler: async (argv) => {
34
+ await ensureToken();
27
35
  await createStore(argv.name, argv.region);
28
36
  },
29
37
  })
@@ -32,6 +40,7 @@ export const storeCommands: CommandModule = {
32
40
  describe: 'List your Saleor Cloud stores',
33
41
  builder: (yargs) => yargs,
34
42
  handler: async () => {
43
+ await ensureToken();
35
44
  await listStores();
36
45
  },
37
46
  })
@@ -58,6 +67,7 @@ export const storeCommands: CommandModule = {
58
67
  demandOption: true,
59
68
  }),
60
69
  handler: async (argv) => {
70
+ await ensureToken();
61
71
  await createEnvironment(argv.store as string, argv.name as string);
62
72
  },
63
73
  }),