jsrepo 1.7.0 → 1.8.0

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
@@ -6,7 +6,7 @@ import path12 from "pathe";
6
6
 
7
7
  // src/commands/add.ts
8
8
  import fs6 from "node:fs";
9
- import { cancel, confirm, isCancel, multiselect, outro, spinner as spinner2 } from "@clack/prompts";
9
+ import { cancel, confirm, isCancel, multiselect, outro, spinner as spinner2, text } from "@clack/prompts";
10
10
  import color7 from "chalk";
11
11
  import { Command, program as program2 } from "commander";
12
12
  import { resolveCommand as resolveCommand2 } from "package-manager-detector/commands";
@@ -1415,14 +1415,32 @@ var _add = async (blockNames, options) => {
1415
1415
  };
1416
1416
  verbose(`Attempting to add ${JSON.stringify(blockNames)}`);
1417
1417
  const loading = spinner2();
1418
- const config = getConfig(options.cwd).match(
1419
- (val) => val,
1420
- (err) => program2.error(color7.red(err))
1421
- );
1418
+ const configResult = getConfig(options.cwd);
1419
+ const noConfig = configResult.isErr();
1420
+ let config;
1421
+ if (configResult.isErr()) {
1422
+ const response = await confirm({
1423
+ message: `You don't have ${JSREPO} initialized in your project. Do you want to continue?`,
1424
+ initialValue: false
1425
+ });
1426
+ if (isCancel(response) || !response) {
1427
+ cancel("Canceled!");
1428
+ process.exit(0);
1429
+ }
1430
+ config = {
1431
+ $schema: "",
1432
+ includeTests: false,
1433
+ watermark: true,
1434
+ path: "./src/blocks",
1435
+ repos: []
1436
+ };
1437
+ } else {
1438
+ config = configResult.unwrap();
1439
+ }
1422
1440
  let repoPaths = config.repos;
1423
1441
  if (options.repo) repoPaths = [options.repo];
1424
1442
  for (const blockSpecifier of blockNames) {
1425
- if (!blockSpecifier.startsWith("github")) continue;
1443
+ if (!blockSpecifier.startsWith("github/")) continue;
1426
1444
  const [providerName, owner, repoName, ...rest] = blockSpecifier.split("/");
1427
1445
  let repo;
1428
1446
  if (rest.length > 2) {
@@ -1433,7 +1451,7 @@ var _add = async (blockNames, options) => {
1433
1451
  if (!repoPaths.find((repoPath) => repoPath === repo)) {
1434
1452
  if (!options.allow) {
1435
1453
  const result = await confirm({
1436
- message: `Allow ${color7.cyan("jsrepo")} to download and run code from ${color7.cyan(repo)}?`,
1454
+ message: `Allow ${JSREPO} to download and run code from ${color7.cyan(repo)}?`,
1437
1455
  initialValue: true
1438
1456
  });
1439
1457
  if (isCancel(result) || !result) {
@@ -1446,7 +1464,7 @@ var _add = async (blockNames, options) => {
1446
1464
  }
1447
1465
  if (!options.allow && options.repo) {
1448
1466
  const result = await confirm({
1449
- message: `Allow ${color7.cyan("jsrepo")} to download and run code from ${color7.cyan(options.repo)}?`,
1467
+ message: `Allow ${JSREPO} to download and run code from ${color7.cyan(options.repo)}?`,
1450
1468
  initialValue: true
1451
1469
  });
1452
1470
  if (isCancel(result) || !result) {
@@ -1455,6 +1473,13 @@ var _add = async (blockNames, options) => {
1455
1473
  }
1456
1474
  }
1457
1475
  if (repoPaths.length === 0) {
1476
+ if (noConfig) {
1477
+ program2.error(
1478
+ color7.red(
1479
+ `Fully quality blocks ex: (github/ieedan/std/utils/math) or provide the \`${color7.bold("--repo")}\` flag to specify a registry.`
1480
+ )
1481
+ );
1482
+ }
1458
1483
  program2.error(
1459
1484
  color7.red(
1460
1485
  `There were no repos present in your config and you didn't provide the \`${color7.bold("--repo")}\` flag with a repo.`
@@ -1509,7 +1534,7 @@ var _add = async (blockNames, options) => {
1509
1534
  if (options.verbose) console.log("Blocks map: ", blocksMap);
1510
1535
  const installingBlocks = (await resolveTree(installingBlockNames, blocksMap, repoPaths)).match(
1511
1536
  (val) => val,
1512
- program2.error
1537
+ (err) => program2.error(err)
1513
1538
  );
1514
1539
  const pm = (await detect({ cwd: options.cwd }))?.agent ?? "npm";
1515
1540
  const tasks = [];
@@ -1520,6 +1545,43 @@ var _add = async (blockNames, options) => {
1520
1545
  const watermark = getWatermark(context.package.version, block.sourceRepo.url);
1521
1546
  const providerInfo = block.sourceRepo;
1522
1547
  verbose(`Setting up ${fullSpecifier}`);
1548
+ if (noConfig) {
1549
+ const partialSpecifier = `${color7.cyan(`${block.category}/${block.name}`)}`;
1550
+ const blocksPath = await text({
1551
+ message: `Where would you like to add ${partialSpecifier}?`,
1552
+ initialValue: config.path,
1553
+ defaultValue: config.path,
1554
+ placeholder: config.path,
1555
+ validate(value) {
1556
+ if (value.trim() === "") return "Please provide a value";
1557
+ }
1558
+ });
1559
+ if (isCancel(blocksPath)) {
1560
+ cancel("Canceled!");
1561
+ process.exit(0);
1562
+ }
1563
+ config.path = blocksPath;
1564
+ if (!options.yes) {
1565
+ const includeTests = await confirm({
1566
+ message: `Include tests for ${partialSpecifier}?`,
1567
+ initialValue: config.includeTests
1568
+ });
1569
+ if (isCancel(includeTests)) {
1570
+ cancel("Canceled!");
1571
+ process.exit(0);
1572
+ }
1573
+ config.includeTests = includeTests;
1574
+ const addWatermark = await confirm({
1575
+ message: `Add watermark to ${partialSpecifier}?`,
1576
+ initialValue: config.watermark
1577
+ });
1578
+ if (isCancel(addWatermark)) {
1579
+ cancel("Canceled!");
1580
+ process.exit(0);
1581
+ }
1582
+ config.watermark = addWatermark;
1583
+ }
1584
+ }
1523
1585
  const directory = path6.join(options.cwd, config.path, block.category);
1524
1586
  const blockExists = !block.subdirectory && fs6.existsSync(path6.join(directory, block.files[0])) || block.subdirectory && fs6.existsSync(path6.join(directory, block.name));
1525
1587
  if (blockExists && !options.yes) {
@@ -1700,6 +1762,18 @@ var _auth = async (options) => {
1700
1762
  const storage = get();
1701
1763
  if (options.logout) {
1702
1764
  for (const provider of providers) {
1765
+ const tokenKey = `${provider.name()}-token`;
1766
+ if (storage.get(tokenKey) === void 0) {
1767
+ process.stdout.write(`${VERTICAL_LINE}
1768
+ `);
1769
+ process.stdout.write(
1770
+ color8.gray(
1771
+ `${VERTICAL_LINE} Already logged out of ${provider.name()}.
1772
+ `
1773
+ )
1774
+ );
1775
+ continue;
1776
+ }
1703
1777
  const response = await confirm2({
1704
1778
  message: `Remove ${provider.name()} token?`,
1705
1779
  initialValue: true
@@ -1709,7 +1783,7 @@ var _auth = async (options) => {
1709
1783
  process.exit(0);
1710
1784
  }
1711
1785
  if (!response) continue;
1712
- storage.delete(`${provider.name()}-token`);
1786
+ storage.delete(tokenKey);
1713
1787
  }
1714
1788
  return;
1715
1789
  }
@@ -2193,7 +2267,7 @@ ${prefix?.() ?? ""}
2193
2267
 
2194
2268
  // src/commands/init.ts
2195
2269
  import fs9 from "node:fs";
2196
- import { cancel as cancel4, confirm as confirm4, isCancel as isCancel4, outro as outro5, password as password2, select as select2, spinner as spinner5, text } from "@clack/prompts";
2270
+ import { cancel as cancel4, confirm as confirm4, isCancel as isCancel4, outro as outro5, password as password2, select as select2, spinner as spinner5, text as text2 } from "@clack/prompts";
2197
2271
  import color12 from "chalk";
2198
2272
  import { Command as Command5, program as program5 } from "commander";
2199
2273
  import { detect as detect2, resolveCommand as resolveCommand3 } from "package-manager-detector";
@@ -2250,7 +2324,7 @@ var _initProject = async (options) => {
2250
2324
  const initialConfig = getConfig(options.cwd);
2251
2325
  const loading = spinner5();
2252
2326
  if (!options.path) {
2253
- const result = await text({
2327
+ const result = await text2({
2254
2328
  message: "Where should we add the blocks?",
2255
2329
  validate(value) {
2256
2330
  if (value.trim() === "") return "Please provide a value";
@@ -2276,7 +2350,7 @@ var _initProject = async (options) => {
2276
2350
  process.exit(0);
2277
2351
  }
2278
2352
  if (!confirmResult) break;
2279
- const result = await text({
2353
+ const result = await text2({
2280
2354
  message: "Where should we download the blocks from?",
2281
2355
  placeholder: "github/ieedan/std",
2282
2356
  validate: (val) => {
@@ -2340,8 +2414,12 @@ var _initProject = async (options) => {
2340
2414
  };
2341
2415
  var _initRegistry = async (options) => {
2342
2416
  const loading = spinner5();
2417
+ const packagePath = path9.join(options.cwd, "package.json");
2418
+ if (!fs9.existsSync(packagePath)) {
2419
+ program5.error(color12.red(`Couldn't find your ${color12.bold("package.json")}!`));
2420
+ }
2343
2421
  if (!options.path) {
2344
- const response = await text({
2422
+ const response = await text2({
2345
2423
  message: "Where are your blocks located?",
2346
2424
  defaultValue: "./blocks",
2347
2425
  initialValue: "./blocks",
@@ -2353,10 +2431,6 @@ var _initRegistry = async (options) => {
2353
2431
  }
2354
2432
  options.path = response;
2355
2433
  }
2356
- const packagePath = path9.join(options.cwd, "package.json");
2357
- if (!fs9.existsSync(packagePath)) {
2358
- program5.error(color12.red(`Couldn't find your ${color12.bold("package.json")}!`));
2359
- }
2360
2434
  const pkg = JSON.parse(fs9.readFileSync(packagePath).toString());
2361
2435
  const scriptAlreadyExists = pkg.scripts !== void 0 && pkg.scripts[options.script] !== void 0;
2362
2436
  if (!options.yes && scriptAlreadyExists) {
@@ -2369,7 +2443,7 @@ var _initRegistry = async (options) => {
2369
2443
  process.exit(0);
2370
2444
  }
2371
2445
  if (!response) {
2372
- const response2 = await text({
2446
+ const response2 = await text2({
2373
2447
  message: "What would you like to call the script?",
2374
2448
  defaultValue: "build:registry",
2375
2449
  placeholder: "build:registry",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jsrepo",
3
3
  "description": "A CLI to add shared code from remote repositories.",
4
- "version": "1.7.0",
4
+ "version": "1.8.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ieedan/jsrepo"
@@ -1,5 +1,5 @@
1
1
  import fs from 'node:fs';
2
- import { cancel, confirm, isCancel, multiselect, outro, spinner } from '@clack/prompts';
2
+ import { cancel, confirm, isCancel, multiselect, outro, spinner, text } from '@clack/prompts';
3
3
  import color from 'chalk';
4
4
  import { Command, program } from 'commander';
5
5
  import { resolveCommand } from 'package-manager-detector/commands';
@@ -10,7 +10,7 @@ import { context } from '..';
10
10
  import * as ascii from '../utils/ascii';
11
11
  import { getInstalled, resolveTree } from '../utils/blocks';
12
12
  import { type Block, isTestFile } from '../utils/build';
13
- import { getConfig } from '../utils/config';
13
+ import { type Config, getConfig } from '../utils/config';
14
14
  import { installDependencies } from '../utils/dependencies';
15
15
  import { getWatermark } from '../utils/get-watermark';
16
16
  import * as gitProviders from '../utils/git-providers';
@@ -60,10 +60,35 @@ const _add = async (blockNames: string[], options: Options) => {
60
60
 
61
61
  const loading = spinner();
62
62
 
63
- const config = getConfig(options.cwd).match(
64
- (val) => val,
65
- (err) => program.error(color.red(err))
66
- );
63
+ const configResult = getConfig(options.cwd);
64
+
65
+ /** The user has opted for no config */
66
+ const noConfig = configResult.isErr();
67
+
68
+ let config: Config;
69
+
70
+ if (configResult.isErr()) {
71
+ const response = await confirm({
72
+ message: `You don't have ${ascii.JSREPO} initialized in your project. Do you want to continue?`,
73
+ initialValue: false,
74
+ });
75
+
76
+ if (isCancel(response) || !response) {
77
+ cancel('Canceled!');
78
+ process.exit(0);
79
+ }
80
+
81
+ // add default config used for default values in prompts
82
+ config = {
83
+ $schema: '',
84
+ includeTests: false,
85
+ watermark: true,
86
+ path: './src/blocks',
87
+ repos: [],
88
+ };
89
+ } else {
90
+ config = configResult.unwrap();
91
+ }
67
92
 
68
93
  let repoPaths = config.repos;
69
94
 
@@ -73,7 +98,7 @@ const _add = async (blockNames: string[], options: Options) => {
73
98
  // resolve repos for blocks
74
99
  for (const blockSpecifier of blockNames) {
75
100
  // we are only getting repos for blocks that specified repos
76
- if (!blockSpecifier.startsWith('github')) continue;
101
+ if (!blockSpecifier.startsWith('github/')) continue;
77
102
 
78
103
  const [providerName, owner, repoName, ...rest] = blockSpecifier.split('/');
79
104
 
@@ -88,7 +113,7 @@ const _add = async (blockNames: string[], options: Options) => {
88
113
  if (!repoPaths.find((repoPath) => repoPath === repo)) {
89
114
  if (!options.allow) {
90
115
  const result = await confirm({
91
- message: `Allow ${color.cyan('jsrepo')} to download and run code from ${color.cyan(repo)}?`,
116
+ message: `Allow ${ascii.JSREPO} to download and run code from ${color.cyan(repo)}?`,
92
117
  initialValue: true,
93
118
  });
94
119
 
@@ -104,7 +129,7 @@ const _add = async (blockNames: string[], options: Options) => {
104
129
 
105
130
  if (!options.allow && options.repo) {
106
131
  const result = await confirm({
107
- message: `Allow ${color.cyan('jsrepo')} to download and run code from ${color.cyan(options.repo)}?`,
132
+ message: `Allow ${ascii.JSREPO} to download and run code from ${color.cyan(options.repo)}?`,
108
133
  initialValue: true,
109
134
  });
110
135
 
@@ -115,6 +140,14 @@ const _add = async (blockNames: string[], options: Options) => {
115
140
  }
116
141
 
117
142
  if (repoPaths.length === 0) {
143
+ if (noConfig) {
144
+ program.error(
145
+ color.red(
146
+ `Fully quality blocks ex: (github/ieedan/std/utils/math) or provide the \`${color.bold('--repo')}\` flag to specify a registry.`
147
+ )
148
+ );
149
+ }
150
+
118
151
  program.error(
119
152
  color.red(
120
153
  `There were no repos present in your config and you didn't provide the \`${color.bold('--repo')}\` flag with a repo.`
@@ -191,7 +224,7 @@ const _add = async (blockNames: string[], options: Options) => {
191
224
 
192
225
  const installingBlocks = (await resolveTree(installingBlockNames, blocksMap, repoPaths)).match(
193
226
  (val) => val,
194
- program.error
227
+ (err) => program.error(err)
195
228
  );
196
229
 
197
230
  const pm = (await detect({ cwd: options.cwd }))?.agent ?? 'npm';
@@ -209,6 +242,53 @@ const _add = async (blockNames: string[], options: Options) => {
209
242
 
210
243
  verbose(`Setting up ${fullSpecifier}`);
211
244
 
245
+ if (noConfig) {
246
+ const partialSpecifier = `${color.cyan(`${block.category}/${block.name}`)}`;
247
+
248
+ const blocksPath = await text({
249
+ message: `Where would you like to add ${partialSpecifier}?`,
250
+ initialValue: config.path,
251
+ defaultValue: config.path,
252
+ placeholder: config.path,
253
+ validate(value) {
254
+ if (value.trim() === '') return 'Please provide a value';
255
+ },
256
+ });
257
+
258
+ if (isCancel(blocksPath)) {
259
+ cancel('Canceled!');
260
+ process.exit(0);
261
+ }
262
+
263
+ config.path = blocksPath;
264
+
265
+ if (!options.yes) {
266
+ const includeTests = await confirm({
267
+ message: `Include tests for ${partialSpecifier}?`,
268
+ initialValue: config.includeTests,
269
+ });
270
+
271
+ if (isCancel(includeTests)) {
272
+ cancel('Canceled!');
273
+ process.exit(0);
274
+ }
275
+
276
+ config.includeTests = includeTests;
277
+
278
+ const addWatermark = await confirm({
279
+ message: `Add watermark to ${partialSpecifier}?`,
280
+ initialValue: config.watermark,
281
+ });
282
+
283
+ if (isCancel(addWatermark)) {
284
+ cancel('Canceled!');
285
+ process.exit(0);
286
+ }
287
+
288
+ config.watermark = addWatermark;
289
+ }
290
+ }
291
+
212
292
  const directory = path.join(options.cwd, config.path, block.category);
213
293
 
214
294
  const blockExists =
@@ -3,6 +3,7 @@ import color from 'chalk';
3
3
  import { Command, Option } from 'commander';
4
4
  import * as v from 'valibot';
5
5
  import { context } from '..';
6
+ import * as ascii from '../utils/ascii';
6
7
  import { providers } from '../utils/git-providers';
7
8
  import * as persisted from '../utils/persisted';
8
9
  import { intro } from '../utils/prompts';
@@ -41,6 +42,18 @@ const _auth = async (options: Options) => {
41
42
 
42
43
  if (options.logout) {
43
44
  for (const provider of providers) {
45
+ const tokenKey = `${provider.name()}-token`;
46
+
47
+ if (storage.get(tokenKey) === undefined) {
48
+ process.stdout.write(`${ascii.VERTICAL_LINE}\n`);
49
+ process.stdout.write(
50
+ color.gray(
51
+ `${ascii.VERTICAL_LINE} Already logged out of ${provider.name()}.\n`
52
+ )
53
+ );
54
+ continue;
55
+ }
56
+
44
57
  const response = await confirm({
45
58
  message: `Remove ${provider.name()} token?`,
46
59
  initialValue: true,
@@ -53,7 +66,7 @@ const _auth = async (options: Options) => {
53
66
 
54
67
  if (!response) continue;
55
68
 
56
- storage.delete(`${provider.name()}-token`);
69
+ storage.delete(tokenKey);
57
70
  }
58
71
  return;
59
72
  }
@@ -206,6 +206,12 @@ const _initProject = async (options: Options) => {
206
206
  const _initRegistry = async (options: Options) => {
207
207
  const loading = spinner();
208
208
 
209
+ const packagePath = path.join(options.cwd, 'package.json');
210
+
211
+ if (!fs.existsSync(packagePath)) {
212
+ program.error(color.red(`Couldn't find your ${color.bold('package.json')}!`));
213
+ }
214
+
209
215
  if (!options.path) {
210
216
  const response = await text({
211
217
  message: 'Where are your blocks located?',
@@ -222,12 +228,6 @@ const _initRegistry = async (options: Options) => {
222
228
  options.path = response;
223
229
  }
224
230
 
225
- const packagePath = path.join(options.cwd, 'package.json');
226
-
227
- if (!fs.existsSync(packagePath)) {
228
- program.error(color.red(`Couldn't find your ${color.bold('package.json')}!`));
229
- }
230
-
231
231
  const pkg = JSON.parse(fs.readFileSync(packagePath).toString());
232
232
 
233
233
  const scriptAlreadyExists =