create-awesome-node-app 0.0.0 → 0.2.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.
Files changed (3) hide show
  1. package/dist/index.cjs +140 -45
  2. package/dist/index.js +140 -45
  3. package/package.json +2 -1
package/dist/index.cjs CHANGED
@@ -3423,7 +3423,9 @@ var require_chalk = __commonJS({
3423
3423
  // src/index.ts
3424
3424
  var import_commander = __toESM(require_commander(), 1);
3425
3425
  var import_chalk = __toESM(require_chalk(), 1);
3426
+ var import_semver = __toESM(require("semver"), 1);
3426
3427
  var import_core = require("@create-node-app/core");
3428
+ var import_helpers = require("@create-node-app/core/helpers");
3427
3429
 
3428
3430
  // src/options.ts
3429
3431
  var import_prompts = __toESM(require("prompts"), 1);
@@ -3441,30 +3443,53 @@ var getTemplateData = async () => {
3441
3443
  templateDataMap.set(TEMPLATE_DATA_FILE_URL, templateData);
3442
3444
  return templateData;
3443
3445
  };
3444
- var getBaseTemplates = async () => {
3446
+ var getTemplateCategories = async () => {
3445
3447
  const templateData = await getTemplateData();
3446
- return templateData.templates;
3448
+ const categories = /* @__PURE__ */ new Set();
3449
+ templateData.templates.forEach((template) => {
3450
+ categories.add(template.category);
3451
+ });
3452
+ return Array.from(categories);
3453
+ };
3454
+ var getTemplatesForCategory = async (category) => {
3455
+ const templateData = await getTemplateData();
3456
+ const templates = templateData.templates.filter(
3457
+ (template) => template.category === category
3458
+ );
3459
+ return templates;
3447
3460
  };
3448
- var getCnaExtensions = async (appType) => {
3461
+ var getExtensionsGroupedByCategory = async (type) => {
3449
3462
  const templateData = await getTemplateData();
3450
- return templateData.extensions.filter(
3451
- (extension) => extension.type === appType
3463
+ const extensions = templateData.extensions.filter(
3464
+ (extension) => extension.type === type
3452
3465
  );
3466
+ const extensionsGroupedByCategory = extensions.reduce((acc, extension) => {
3467
+ const category = extension.category;
3468
+ if (!acc[category]) {
3469
+ acc[category] = [];
3470
+ }
3471
+ acc[category].push(extension);
3472
+ return acc;
3473
+ }, {});
3474
+ return extensionsGroupedByCategory;
3453
3475
  };
3454
3476
 
3455
3477
  // src/options.ts
3456
3478
  import_prompts.default.override(import_yargs.default.argv);
3457
3479
  var getCnaOptions = async (options) => {
3458
3480
  var _a;
3459
- const templates = await getBaseTemplates();
3460
- const appTypeOptions = templates.map((template) => {
3461
- var _a2;
3462
- return {
3463
- title: template.name,
3464
- value: template.type,
3465
- description: template.description + " - " + ((_a2 = template.labels) == null ? void 0 : _a2.join(", "))
3466
- };
3467
- });
3481
+ const categories = await getTemplateCategories();
3482
+ const categoriesOptions = [
3483
+ ...categories.map((category) => ({
3484
+ title: category,
3485
+ value: category
3486
+ })),
3487
+ {
3488
+ title: "None of the above",
3489
+ value: "custom",
3490
+ description: "I have my own template"
3491
+ }
3492
+ ];
3468
3493
  const baseInput = await (0, import_prompts.default)([
3469
3494
  {
3470
3495
  type: "text",
@@ -3482,19 +3507,45 @@ var getCnaOptions = async (options) => {
3482
3507
  },
3483
3508
  {
3484
3509
  type: "select",
3485
- name: "appType",
3510
+ name: "category",
3486
3511
  message: "What type of app do you want to create?",
3487
- choices: appTypeOptions,
3512
+ choices: categoriesOptions,
3488
3513
  initial: 0
3489
- },
3490
- {
3491
- type: "text",
3492
- name: "template",
3493
- message: "Template to use to bootstrap application. e.g: https://github.com/username/repository/tree/main/subdir",
3494
- initial: ""
3495
3514
  }
3496
3515
  ]);
3497
- const extensions = await getCnaExtensions(baseInput.appType);
3516
+ const templates = await getTemplatesForCategory(baseInput.category);
3517
+ const templateOptions = templates.map((template) => {
3518
+ var _a2;
3519
+ return {
3520
+ title: template.name,
3521
+ value: template.type,
3522
+ description: template.description + " Keywords: " + ((_a2 = template.labels) == null ? void 0 : _a2.join(", "))
3523
+ };
3524
+ });
3525
+ const templateInput = await (0, import_prompts.default)(
3526
+ baseInput.category === "custom" ? [
3527
+ {
3528
+ type: "text",
3529
+ name: "template",
3530
+ message: "Enter the URL of your template. e.g: https://github.com/username/repository/tree/main/subdir",
3531
+ initial: "",
3532
+ validate: (value) => {
3533
+ if (!value) {
3534
+ return "Template URL is required";
3535
+ }
3536
+ return true;
3537
+ }
3538
+ }
3539
+ ] : [
3540
+ {
3541
+ type: "select",
3542
+ name: "template",
3543
+ message: "Select a template",
3544
+ choices: templateOptions,
3545
+ initial: 0
3546
+ }
3547
+ ]
3548
+ );
3498
3549
  const defaultSrcDir = options.srcDir;
3499
3550
  const appConfig = await (0, import_prompts.default)([
3500
3551
  {
@@ -3509,34 +3560,71 @@ var getCnaOptions = async (options) => {
3509
3560
  message: "Import alias to use for the project, e.g. `@`",
3510
3561
  initial: options.alias
3511
3562
  },
3563
+ // The following prompts are placeholders for future inputs
3512
3564
  {
3513
- type: "multiselect",
3565
+ type: null,
3514
3566
  name: "addons",
3515
- message: `Select extensions to extend your ${baseInput.appType} project`,
3516
- hint: "- Space to select. Return to submit",
3517
- choices: extensions.map((option) => {
3567
+ message: "Select extensions",
3568
+ initial: 0
3569
+ },
3570
+ {
3571
+ type: null,
3572
+ name: "extend",
3573
+ message: "Enter extra extensions",
3574
+ initial: 0
3575
+ }
3576
+ ]);
3577
+ appConfig.addons = [];
3578
+ appConfig.extend = [];
3579
+ const extensionsGroupedByCategory = await getExtensionsGroupedByCategory(
3580
+ templateInput.template
3581
+ );
3582
+ for (const [category, extensions] of Object.entries(
3583
+ extensionsGroupedByCategory
3584
+ )) {
3585
+ const { selected } = await (0, import_prompts.default)({
3586
+ type: "multiselect",
3587
+ name: "selected",
3588
+ message: `Select extensions for ${category}`,
3589
+ choices: extensions.map((extension) => {
3518
3590
  var _a2;
3519
3591
  return {
3520
- title: option.name,
3521
- value: option.url,
3522
- description: option.description + " - " + ((_a2 = option.labels) == null ? void 0 : _a2.join(", "))
3592
+ title: extension.name,
3593
+ value: extension.url,
3594
+ description: extension.description + " Keywords: " + ((_a2 = extension.labels) == null ? void 0 : _a2.join(", "))
3523
3595
  };
3524
- })
3525
- },
3596
+ }),
3597
+ initial: 0
3598
+ });
3599
+ appConfig.addons = appConfig.addons ? [...appConfig.addons, ...selected] : [];
3600
+ }
3601
+ const askForExtend = await (0, import_prompts.default)([
3526
3602
  {
3527
- type: "list",
3603
+ type: "confirm",
3528
3604
  name: "extend",
3529
- message: "Enter extra extensions separater by comma. e.g: https://github.com/username/repository/tree/main/extension1,https://github.com/username/repository/tree/main/extension2",
3530
- initial: "",
3531
- separator: ","
3605
+ message: "Do you want to extend the app with more extensions?",
3606
+ initial: false
3532
3607
  }
3533
3608
  ]);
3609
+ if (askForExtend.extend) {
3610
+ const { extend } = await (0, import_prompts.default)([
3611
+ {
3612
+ type: "list",
3613
+ name: "extend",
3614
+ message: "Enter extra extensions separater by comma. e.g: https://github.com/username/repository/tree/main/extension1,https://github.com/username/repository/tree/main/extension2",
3615
+ initial: "",
3616
+ separator: ","
3617
+ }
3618
+ ]);
3619
+ appConfig.extend = extend;
3620
+ }
3534
3621
  const { ...nextAppOptions } = {
3535
3622
  ...options,
3536
3623
  ...baseInput,
3624
+ ...templateInput,
3537
3625
  ...appConfig
3538
3626
  };
3539
- const templateAddon = baseInput.template || ((_a = templates.find((template) => template.type === nextAppOptions.appType)) == null ? void 0 : _a.url);
3627
+ const templateAddon = baseInput.category === "custom" ? templateInput.template : (_a = templates.find((template) => template.type === templateInput.template)) == null ? void 0 : _a.url;
3540
3628
  const addons = [
3541
3629
  templateAddon,
3542
3630
  ...nextAppOptions.addons,
@@ -3552,7 +3640,7 @@ var getCnaOptions = async (options) => {
3552
3640
  // package.json
3553
3641
  var package_default = {
3554
3642
  name: "create-awesome-node-app",
3555
- version: "0.0.0",
3643
+ version: "0.1.0",
3556
3644
  type: "module",
3557
3645
  description: "Command line tool to create Node apps with a lot of different addons.",
3558
3646
  license: "MIT",
@@ -3599,6 +3687,7 @@ var package_default = {
3599
3687
  dependencies: {
3600
3688
  "@create-node-app/core": "*",
3601
3689
  prompts: "^2.4.1",
3690
+ semver: "^7.3.8",
3602
3691
  yargs: "^17.0.1"
3603
3692
  },
3604
3693
  devDependencies: {
@@ -3629,18 +3718,24 @@ var main = async () => {
3629
3718
  ).option(
3630
3719
  "--nodeps",
3631
3720
  "generate package.json file without installing dependencies"
3632
- ).option("--inplace", "apply setup to an existing project");
3633
- import_commander.default.allowUnknownOption().on("--help", () => {
3721
+ ).option("--inplace", "apply setup to an existing project").parse(process.argv);
3722
+ const latest = await (0, import_helpers.checkForLatestVersion)("create-awesome-node-app");
3723
+ if (latest && import_semver.default.lt(package_default.version, latest)) {
3634
3724
  console.log();
3635
- console.log(
3636
- ` Only ${import_chalk.default.green("[project-directory]")} is required.`
3725
+ console.error(
3726
+ import_chalk.default.yellow(
3727
+ `You are running \`create-react-app\` ${package_default.version}, which is behind the latest release (${latest}).
3728
+
3729
+ We recommend always using the latest version of create-react-app if possible.`
3730
+ )
3637
3731
  );
3638
3732
  console.log();
3639
3733
  console.log(
3640
- ` If you have any problems, do not hesitate to file an issue:`
3734
+ "The latest instructions for creating a new app can be found here:\nhttps://create-react-app.dev/docs/getting-started/"
3641
3735
  );
3642
- console.log(` ${import_chalk.default.cyan(`${package_default.bugs.url}/new`)}`);
3643
- }).parse(process.argv);
3736
+ console.log();
3737
+ return;
3738
+ }
3644
3739
  return (0, import_core.createNodeApp)(
3645
3740
  projectName,
3646
3741
  { ...import_commander.default.opts(), projectName },
package/dist/index.js CHANGED
@@ -3429,7 +3429,9 @@ var require_chalk = __commonJS({
3429
3429
  // src/index.ts
3430
3430
  var import_commander = __toESM(require_commander(), 1);
3431
3431
  var import_chalk = __toESM(require_chalk(), 1);
3432
+ import semver from "semver";
3432
3433
  import { createNodeApp } from "@create-node-app/core";
3434
+ import { checkForLatestVersion } from "@create-node-app/core/helpers";
3433
3435
 
3434
3436
  // src/options.ts
3435
3437
  import prompts from "prompts";
@@ -3447,30 +3449,53 @@ var getTemplateData = async () => {
3447
3449
  templateDataMap.set(TEMPLATE_DATA_FILE_URL, templateData);
3448
3450
  return templateData;
3449
3451
  };
3450
- var getBaseTemplates = async () => {
3452
+ var getTemplateCategories = async () => {
3451
3453
  const templateData = await getTemplateData();
3452
- return templateData.templates;
3454
+ const categories = /* @__PURE__ */ new Set();
3455
+ templateData.templates.forEach((template) => {
3456
+ categories.add(template.category);
3457
+ });
3458
+ return Array.from(categories);
3459
+ };
3460
+ var getTemplatesForCategory = async (category) => {
3461
+ const templateData = await getTemplateData();
3462
+ const templates = templateData.templates.filter(
3463
+ (template) => template.category === category
3464
+ );
3465
+ return templates;
3453
3466
  };
3454
- var getCnaExtensions = async (appType) => {
3467
+ var getExtensionsGroupedByCategory = async (type) => {
3455
3468
  const templateData = await getTemplateData();
3456
- return templateData.extensions.filter(
3457
- (extension) => extension.type === appType
3469
+ const extensions = templateData.extensions.filter(
3470
+ (extension) => extension.type === type
3458
3471
  );
3472
+ const extensionsGroupedByCategory = extensions.reduce((acc, extension) => {
3473
+ const category = extension.category;
3474
+ if (!acc[category]) {
3475
+ acc[category] = [];
3476
+ }
3477
+ acc[category].push(extension);
3478
+ return acc;
3479
+ }, {});
3480
+ return extensionsGroupedByCategory;
3459
3481
  };
3460
3482
 
3461
3483
  // src/options.ts
3462
3484
  prompts.override(yargs.argv);
3463
3485
  var getCnaOptions = async (options) => {
3464
3486
  var _a;
3465
- const templates = await getBaseTemplates();
3466
- const appTypeOptions = templates.map((template) => {
3467
- var _a2;
3468
- return {
3469
- title: template.name,
3470
- value: template.type,
3471
- description: template.description + " - " + ((_a2 = template.labels) == null ? void 0 : _a2.join(", "))
3472
- };
3473
- });
3487
+ const categories = await getTemplateCategories();
3488
+ const categoriesOptions = [
3489
+ ...categories.map((category) => ({
3490
+ title: category,
3491
+ value: category
3492
+ })),
3493
+ {
3494
+ title: "None of the above",
3495
+ value: "custom",
3496
+ description: "I have my own template"
3497
+ }
3498
+ ];
3474
3499
  const baseInput = await prompts([
3475
3500
  {
3476
3501
  type: "text",
@@ -3488,19 +3513,45 @@ var getCnaOptions = async (options) => {
3488
3513
  },
3489
3514
  {
3490
3515
  type: "select",
3491
- name: "appType",
3516
+ name: "category",
3492
3517
  message: "What type of app do you want to create?",
3493
- choices: appTypeOptions,
3518
+ choices: categoriesOptions,
3494
3519
  initial: 0
3495
- },
3496
- {
3497
- type: "text",
3498
- name: "template",
3499
- message: "Template to use to bootstrap application. e.g: https://github.com/username/repository/tree/main/subdir",
3500
- initial: ""
3501
3520
  }
3502
3521
  ]);
3503
- const extensions = await getCnaExtensions(baseInput.appType);
3522
+ const templates = await getTemplatesForCategory(baseInput.category);
3523
+ const templateOptions = templates.map((template) => {
3524
+ var _a2;
3525
+ return {
3526
+ title: template.name,
3527
+ value: template.type,
3528
+ description: template.description + " Keywords: " + ((_a2 = template.labels) == null ? void 0 : _a2.join(", "))
3529
+ };
3530
+ });
3531
+ const templateInput = await prompts(
3532
+ baseInput.category === "custom" ? [
3533
+ {
3534
+ type: "text",
3535
+ name: "template",
3536
+ message: "Enter the URL of your template. e.g: https://github.com/username/repository/tree/main/subdir",
3537
+ initial: "",
3538
+ validate: (value) => {
3539
+ if (!value) {
3540
+ return "Template URL is required";
3541
+ }
3542
+ return true;
3543
+ }
3544
+ }
3545
+ ] : [
3546
+ {
3547
+ type: "select",
3548
+ name: "template",
3549
+ message: "Select a template",
3550
+ choices: templateOptions,
3551
+ initial: 0
3552
+ }
3553
+ ]
3554
+ );
3504
3555
  const defaultSrcDir = options.srcDir;
3505
3556
  const appConfig = await prompts([
3506
3557
  {
@@ -3515,34 +3566,71 @@ var getCnaOptions = async (options) => {
3515
3566
  message: "Import alias to use for the project, e.g. `@`",
3516
3567
  initial: options.alias
3517
3568
  },
3569
+ // The following prompts are placeholders for future inputs
3518
3570
  {
3519
- type: "multiselect",
3571
+ type: null,
3520
3572
  name: "addons",
3521
- message: `Select extensions to extend your ${baseInput.appType} project`,
3522
- hint: "- Space to select. Return to submit",
3523
- choices: extensions.map((option) => {
3573
+ message: "Select extensions",
3574
+ initial: 0
3575
+ },
3576
+ {
3577
+ type: null,
3578
+ name: "extend",
3579
+ message: "Enter extra extensions",
3580
+ initial: 0
3581
+ }
3582
+ ]);
3583
+ appConfig.addons = [];
3584
+ appConfig.extend = [];
3585
+ const extensionsGroupedByCategory = await getExtensionsGroupedByCategory(
3586
+ templateInput.template
3587
+ );
3588
+ for (const [category, extensions] of Object.entries(
3589
+ extensionsGroupedByCategory
3590
+ )) {
3591
+ const { selected } = await prompts({
3592
+ type: "multiselect",
3593
+ name: "selected",
3594
+ message: `Select extensions for ${category}`,
3595
+ choices: extensions.map((extension) => {
3524
3596
  var _a2;
3525
3597
  return {
3526
- title: option.name,
3527
- value: option.url,
3528
- description: option.description + " - " + ((_a2 = option.labels) == null ? void 0 : _a2.join(", "))
3598
+ title: extension.name,
3599
+ value: extension.url,
3600
+ description: extension.description + " Keywords: " + ((_a2 = extension.labels) == null ? void 0 : _a2.join(", "))
3529
3601
  };
3530
- })
3531
- },
3602
+ }),
3603
+ initial: 0
3604
+ });
3605
+ appConfig.addons = appConfig.addons ? [...appConfig.addons, ...selected] : [];
3606
+ }
3607
+ const askForExtend = await prompts([
3532
3608
  {
3533
- type: "list",
3609
+ type: "confirm",
3534
3610
  name: "extend",
3535
- message: "Enter extra extensions separater by comma. e.g: https://github.com/username/repository/tree/main/extension1,https://github.com/username/repository/tree/main/extension2",
3536
- initial: "",
3537
- separator: ","
3611
+ message: "Do you want to extend the app with more extensions?",
3612
+ initial: false
3538
3613
  }
3539
3614
  ]);
3615
+ if (askForExtend.extend) {
3616
+ const { extend } = await prompts([
3617
+ {
3618
+ type: "list",
3619
+ name: "extend",
3620
+ message: "Enter extra extensions separater by comma. e.g: https://github.com/username/repository/tree/main/extension1,https://github.com/username/repository/tree/main/extension2",
3621
+ initial: "",
3622
+ separator: ","
3623
+ }
3624
+ ]);
3625
+ appConfig.extend = extend;
3626
+ }
3540
3627
  const { ...nextAppOptions } = {
3541
3628
  ...options,
3542
3629
  ...baseInput,
3630
+ ...templateInput,
3543
3631
  ...appConfig
3544
3632
  };
3545
- const templateAddon = baseInput.template || ((_a = templates.find((template) => template.type === nextAppOptions.appType)) == null ? void 0 : _a.url);
3633
+ const templateAddon = baseInput.category === "custom" ? templateInput.template : (_a = templates.find((template) => template.type === templateInput.template)) == null ? void 0 : _a.url;
3546
3634
  const addons = [
3547
3635
  templateAddon,
3548
3636
  ...nextAppOptions.addons,
@@ -3558,7 +3646,7 @@ var getCnaOptions = async (options) => {
3558
3646
  // package.json
3559
3647
  var package_default = {
3560
3648
  name: "create-awesome-node-app",
3561
- version: "0.0.0",
3649
+ version: "0.1.0",
3562
3650
  type: "module",
3563
3651
  description: "Command line tool to create Node apps with a lot of different addons.",
3564
3652
  license: "MIT",
@@ -3605,6 +3693,7 @@ var package_default = {
3605
3693
  dependencies: {
3606
3694
  "@create-node-app/core": "*",
3607
3695
  prompts: "^2.4.1",
3696
+ semver: "^7.3.8",
3608
3697
  yargs: "^17.0.1"
3609
3698
  },
3610
3699
  devDependencies: {
@@ -3635,18 +3724,24 @@ var main = async () => {
3635
3724
  ).option(
3636
3725
  "--nodeps",
3637
3726
  "generate package.json file without installing dependencies"
3638
- ).option("--inplace", "apply setup to an existing project");
3639
- import_commander.default.allowUnknownOption().on("--help", () => {
3727
+ ).option("--inplace", "apply setup to an existing project").parse(process.argv);
3728
+ const latest = await checkForLatestVersion("create-awesome-node-app");
3729
+ if (latest && semver.lt(package_default.version, latest)) {
3640
3730
  console.log();
3641
- console.log(
3642
- ` Only ${import_chalk.default.green("[project-directory]")} is required.`
3731
+ console.error(
3732
+ import_chalk.default.yellow(
3733
+ `You are running \`create-react-app\` ${package_default.version}, which is behind the latest release (${latest}).
3734
+
3735
+ We recommend always using the latest version of create-react-app if possible.`
3736
+ )
3643
3737
  );
3644
3738
  console.log();
3645
3739
  console.log(
3646
- ` If you have any problems, do not hesitate to file an issue:`
3740
+ "The latest instructions for creating a new app can be found here:\nhttps://create-react-app.dev/docs/getting-started/"
3647
3741
  );
3648
- console.log(` ${import_chalk.default.cyan(`${package_default.bugs.url}/new`)}`);
3649
- }).parse(process.argv);
3742
+ console.log();
3743
+ return;
3744
+ }
3650
3745
  return createNodeApp(
3651
3746
  projectName,
3652
3747
  { ...import_commander.default.opts(), projectName },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-awesome-node-app",
3
- "version": "0.0.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Command line tool to create Node apps with a lot of different addons.",
6
6
  "license": "MIT",
@@ -47,6 +47,7 @@
47
47
  "dependencies": {
48
48
  "@create-node-app/core": "*",
49
49
  "prompts": "^2.4.1",
50
+ "semver": "^7.3.8",
50
51
  "yargs": "^17.0.1"
51
52
  },
52
53
  "devDependencies": {