create-awesome-node-app 0.4.26 → 0.5.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/README.md +15 -0
- package/dist/index.cjs +241 -80
- package/dist/index.js +241 -80
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,6 +67,21 @@ create-awesome-node-app --template react-vite-boilerplate --addons jotai materia
|
|
|
67
67
|
|
|
68
68
|
This example uses the `react-vite-boilerplate` template and applies the `jotai`, `material-ui`, and `github-setup` extensions.
|
|
69
69
|
|
|
70
|
+
### Listing Templates and Addons
|
|
71
|
+
|
|
72
|
+
You can list all available templates and addons using the following flags:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
# List all available templates
|
|
76
|
+
create-awesome-node-app --list-templates
|
|
77
|
+
|
|
78
|
+
# List all available addons
|
|
79
|
+
create-awesome-node-app --list-addons
|
|
80
|
+
|
|
81
|
+
# List addons compatible with a specific template
|
|
82
|
+
create-awesome-node-app --template react-vite-boilerplate --list-addons
|
|
83
|
+
```
|
|
84
|
+
|
|
70
85
|
## 🔗 Full List of Templates and Extensions
|
|
71
86
|
|
|
72
87
|
You can find the full list of available templates and extensions in the [cna-templates repository](https://github.com/Create-Node-App/cna-templates).
|
package/dist/index.cjs
CHANGED
|
@@ -1342,14 +1342,14 @@ var require_templates = __commonJS({
|
|
|
1342
1342
|
}
|
|
1343
1343
|
return results;
|
|
1344
1344
|
}
|
|
1345
|
-
function buildStyle(
|
|
1345
|
+
function buildStyle(chalk3, styles) {
|
|
1346
1346
|
const enabled = {};
|
|
1347
1347
|
for (const layer of styles) {
|
|
1348
1348
|
for (const style of layer.styles) {
|
|
1349
1349
|
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
1350
1350
|
}
|
|
1351
1351
|
}
|
|
1352
|
-
let current =
|
|
1352
|
+
let current = chalk3;
|
|
1353
1353
|
for (const [styleName, styles2] of Object.entries(enabled)) {
|
|
1354
1354
|
if (!Array.isArray(styles2)) {
|
|
1355
1355
|
continue;
|
|
@@ -1361,7 +1361,7 @@ var require_templates = __commonJS({
|
|
|
1361
1361
|
}
|
|
1362
1362
|
return current;
|
|
1363
1363
|
}
|
|
1364
|
-
module2.exports = (
|
|
1364
|
+
module2.exports = (chalk3, temporary) => {
|
|
1365
1365
|
const styles = [];
|
|
1366
1366
|
const chunks = [];
|
|
1367
1367
|
let chunk = [];
|
|
@@ -1371,13 +1371,13 @@ var require_templates = __commonJS({
|
|
|
1371
1371
|
} else if (style) {
|
|
1372
1372
|
const string = chunk.join("");
|
|
1373
1373
|
chunk = [];
|
|
1374
|
-
chunks.push(styles.length === 0 ? string : buildStyle(
|
|
1374
|
+
chunks.push(styles.length === 0 ? string : buildStyle(chalk3, styles)(string));
|
|
1375
1375
|
styles.push({ inverse, styles: parseStyle(style) });
|
|
1376
1376
|
} else if (close) {
|
|
1377
1377
|
if (styles.length === 0) {
|
|
1378
1378
|
throw new Error("Found extraneous } in Chalk template literal");
|
|
1379
1379
|
}
|
|
1380
|
-
chunks.push(buildStyle(
|
|
1380
|
+
chunks.push(buildStyle(chalk3, styles)(chunk.join("")));
|
|
1381
1381
|
chunk = [];
|
|
1382
1382
|
styles.pop();
|
|
1383
1383
|
} else {
|
|
@@ -1425,16 +1425,16 @@ var require_source = __commonJS({
|
|
|
1425
1425
|
}
|
|
1426
1426
|
};
|
|
1427
1427
|
var chalkFactory = (options) => {
|
|
1428
|
-
const
|
|
1429
|
-
applyOptions(
|
|
1430
|
-
|
|
1431
|
-
Object.setPrototypeOf(
|
|
1432
|
-
Object.setPrototypeOf(
|
|
1433
|
-
|
|
1428
|
+
const chalk4 = {};
|
|
1429
|
+
applyOptions(chalk4, options);
|
|
1430
|
+
chalk4.template = (...arguments_) => chalkTag(chalk4.template, ...arguments_);
|
|
1431
|
+
Object.setPrototypeOf(chalk4, Chalk.prototype);
|
|
1432
|
+
Object.setPrototypeOf(chalk4.template, chalk4);
|
|
1433
|
+
chalk4.template.constructor = () => {
|
|
1434
1434
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
1435
1435
|
};
|
|
1436
|
-
|
|
1437
|
-
return
|
|
1436
|
+
chalk4.template.Instance = ChalkClass;
|
|
1437
|
+
return chalk4.template;
|
|
1438
1438
|
};
|
|
1439
1439
|
function Chalk(options) {
|
|
1440
1440
|
return chalkFactory(options);
|
|
@@ -1545,7 +1545,7 @@ var require_source = __commonJS({
|
|
|
1545
1545
|
return openAll + string + closeAll;
|
|
1546
1546
|
};
|
|
1547
1547
|
var template;
|
|
1548
|
-
var chalkTag = (
|
|
1548
|
+
var chalkTag = (chalk4, ...strings) => {
|
|
1549
1549
|
const [firstString] = strings;
|
|
1550
1550
|
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
1551
1551
|
return strings.join(" ");
|
|
@@ -1561,20 +1561,20 @@ var require_source = __commonJS({
|
|
|
1561
1561
|
if (template === void 0) {
|
|
1562
1562
|
template = require_templates();
|
|
1563
1563
|
}
|
|
1564
|
-
return template(
|
|
1564
|
+
return template(chalk4, parts.join(""));
|
|
1565
1565
|
};
|
|
1566
1566
|
Object.defineProperties(Chalk.prototype, styles);
|
|
1567
|
-
var
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
module2.exports =
|
|
1567
|
+
var chalk3 = Chalk();
|
|
1568
|
+
chalk3.supportsColor = stdoutColor;
|
|
1569
|
+
chalk3.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
1570
|
+
chalk3.stderr.supportsColor = stderrColor;
|
|
1571
|
+
module2.exports = chalk3;
|
|
1572
1572
|
}
|
|
1573
1573
|
});
|
|
1574
1574
|
|
|
1575
1575
|
// src/index.ts
|
|
1576
1576
|
var import_commander = require("commander");
|
|
1577
|
-
var
|
|
1577
|
+
var import_chalk2 = __toESM(require_source(), 1);
|
|
1578
1578
|
var import_semver = __toESM(require("semver"), 1);
|
|
1579
1579
|
var import_core = require("@create-node-app/core");
|
|
1580
1580
|
|
|
@@ -1612,12 +1612,24 @@ var getTemplateCategories = async (cliArgs) => {
|
|
|
1612
1612
|
return [cliArgs.category];
|
|
1613
1613
|
}
|
|
1614
1614
|
const templateData = await getTemplateData();
|
|
1615
|
+
if (templateData.categories && templateData.categories.length > 0) {
|
|
1616
|
+
return templateData.categories.map((category) => category.slug);
|
|
1617
|
+
}
|
|
1615
1618
|
const categories = /* @__PURE__ */ new Set();
|
|
1616
1619
|
templateData.templates.forEach((template) => {
|
|
1617
1620
|
categories.add(template.category);
|
|
1618
1621
|
});
|
|
1619
1622
|
return Array.from(categories);
|
|
1620
1623
|
};
|
|
1624
|
+
var getCategoryData = async (categorySlug) => {
|
|
1625
|
+
const templateData = await getTemplateData();
|
|
1626
|
+
if (templateData.categories && templateData.categories.length > 0) {
|
|
1627
|
+
return templateData.categories.find(
|
|
1628
|
+
(category) => category.slug === categorySlug
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
return void 0;
|
|
1632
|
+
};
|
|
1621
1633
|
var getTemplatesForCategory = async (category, cliArgs) => {
|
|
1622
1634
|
const selectedCategory = (cliArgs == null ? void 0 : cliArgs.category) || category;
|
|
1623
1635
|
if (!selectedCategory) {
|
|
@@ -1661,63 +1673,87 @@ var isValidUrl = (url) => {
|
|
|
1661
1673
|
return false;
|
|
1662
1674
|
}
|
|
1663
1675
|
};
|
|
1664
|
-
var
|
|
1676
|
+
var processNonInteractiveOptions = async (options) => {
|
|
1665
1677
|
const categories = await getTemplateCategories();
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1678
|
+
let matchedTemplate;
|
|
1679
|
+
const templatesOrExtensions = [];
|
|
1680
|
+
if (options.template && !isValidUrl(options.template)) {
|
|
1681
|
+
const allTemplates = (await Promise.all(
|
|
1682
|
+
categories.map((category) => getTemplatesForCategory(category))
|
|
1683
|
+
)).flat();
|
|
1684
|
+
matchedTemplate = allTemplates.find(
|
|
1685
|
+
(template) => template.slug === options.template
|
|
1686
|
+
);
|
|
1687
|
+
if (matchedTemplate) {
|
|
1688
|
+
templatesOrExtensions.push({ url: matchedTemplate.url });
|
|
1689
|
+
if (matchedTemplate.customOptions) {
|
|
1690
|
+
matchedTemplate.customOptions.forEach((customOption) => {
|
|
1691
|
+
if (customOption.name && customOption.initial !== void 0) {
|
|
1692
|
+
options[customOption.name] = customOption.initial;
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
} else {
|
|
1697
|
+
throw new Error(
|
|
1698
|
+
`Invalid template slug: '${options.template}'. Please provide a valid template slug.`
|
|
1674
1699
|
);
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1700
|
+
}
|
|
1701
|
+
} else if (options.template) {
|
|
1702
|
+
templatesOrExtensions.push({ url: options.template });
|
|
1703
|
+
}
|
|
1704
|
+
if (options.addons && Array.isArray(options.addons)) {
|
|
1705
|
+
const extensionsGroupedByCategory = await getExtensionsGroupedByCategory([
|
|
1706
|
+
(matchedTemplate == null ? void 0 : matchedTemplate.type) || "custom",
|
|
1707
|
+
"all"
|
|
1708
|
+
]);
|
|
1709
|
+
const extensions = options.addons.map((addon) => {
|
|
1710
|
+
if (!isValidUrl(addon)) {
|
|
1711
|
+
for (const extensions2 of Object.values(extensionsGroupedByCategory)) {
|
|
1712
|
+
const matchedExtension = extensions2.find(
|
|
1713
|
+
(extension) => extension.slug === addon
|
|
1714
|
+
);
|
|
1715
|
+
if (matchedExtension) {
|
|
1716
|
+
return matchedExtension.url;
|
|
1717
|
+
}
|
|
1683
1718
|
}
|
|
1684
|
-
} else {
|
|
1685
1719
|
throw new Error(
|
|
1686
|
-
`Invalid
|
|
1720
|
+
`Invalid extension slug: '${addon}'. Please provide a valid extension slug.`
|
|
1687
1721
|
);
|
|
1688
1722
|
}
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
(extension) => extension.slug === addon
|
|
1700
|
-
);
|
|
1701
|
-
if (matchedExtension) {
|
|
1702
|
-
return matchedExtension.url;
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
|
-
throw new Error(
|
|
1706
|
-
`Invalid extension slug: '${addon}'. Please provide a valid extension slug.`
|
|
1707
|
-
);
|
|
1708
|
-
}
|
|
1709
|
-
return addon;
|
|
1710
|
-
});
|
|
1711
|
-
}
|
|
1712
|
-
if (options.verbose) {
|
|
1713
|
-
console.log(JSON.stringify(options, null, 2));
|
|
1714
|
-
}
|
|
1715
|
-
return options;
|
|
1723
|
+
return addon;
|
|
1724
|
+
}).map((addon) => ({ url: addon }));
|
|
1725
|
+
templatesOrExtensions.push(...extensions);
|
|
1726
|
+
}
|
|
1727
|
+
if (options.extend && Array.isArray(options.extend)) {
|
|
1728
|
+
const additionalExtensions = options.extend.filter(Boolean).map((extension) => ({ url: extension }));
|
|
1729
|
+
templatesOrExtensions.push(...additionalExtensions);
|
|
1730
|
+
}
|
|
1731
|
+
if (options.aiTool && !["cursor", "copilot", "none"].includes(options.aiTool)) {
|
|
1732
|
+
throw new Error("Invalid --ai-tool option. Use: cursor, copilot, or none");
|
|
1716
1733
|
}
|
|
1734
|
+
options.aiTool = options.aiTool || "none";
|
|
1735
|
+
options.templatesOrExtensions = templatesOrExtensions;
|
|
1736
|
+
if (options.verbose) {
|
|
1737
|
+
console.log(JSON.stringify(options, null, 2));
|
|
1738
|
+
}
|
|
1739
|
+
return options;
|
|
1740
|
+
};
|
|
1741
|
+
var processInteractiveOptions = async (options) => {
|
|
1742
|
+
const categories = await getTemplateCategories();
|
|
1743
|
+
const categoryDataPromises = categories.map(async (categorySlug) => {
|
|
1744
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
1745
|
+
return {
|
|
1746
|
+
slug: categorySlug,
|
|
1747
|
+
name: (categoryData == null ? void 0 : categoryData.name) || categorySlug,
|
|
1748
|
+
description: (categoryData == null ? void 0 : categoryData.description) || ""
|
|
1749
|
+
};
|
|
1750
|
+
});
|
|
1751
|
+
const categoryDataList = await Promise.all(categoryDataPromises);
|
|
1717
1752
|
const categoriesOptions = [
|
|
1718
|
-
...
|
|
1719
|
-
title: category,
|
|
1720
|
-
value: category
|
|
1753
|
+
...categoryDataList.map((category) => ({
|
|
1754
|
+
title: category.name,
|
|
1755
|
+
value: category.slug,
|
|
1756
|
+
description: category.description
|
|
1721
1757
|
})),
|
|
1722
1758
|
{
|
|
1723
1759
|
title: "None of the above",
|
|
@@ -1742,6 +1778,30 @@ var getCnaOptions = async (options) => {
|
|
|
1742
1778
|
})),
|
|
1743
1779
|
initial: options.packageManager ? PACKAGE_MANAGERS.indexOf(options.packageManager) : 0
|
|
1744
1780
|
},
|
|
1781
|
+
{
|
|
1782
|
+
type: "select",
|
|
1783
|
+
name: "aiTool",
|
|
1784
|
+
message: "Which AI coding tool would you like to configure?",
|
|
1785
|
+
choices: [
|
|
1786
|
+
{
|
|
1787
|
+
title: "Cursor Rules",
|
|
1788
|
+
value: "cursor",
|
|
1789
|
+
description: "Add .cursorrules configuration for Cursor IDE"
|
|
1790
|
+
},
|
|
1791
|
+
{
|
|
1792
|
+
title: "GitHub Copilot Instructions",
|
|
1793
|
+
value: "copilot",
|
|
1794
|
+
description: "Add .github/copilot-instructions.md for GitHub Copilot"
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
title: "None",
|
|
1798
|
+
value: "none",
|
|
1799
|
+
description: "Don't add any AI tool configuration"
|
|
1800
|
+
}
|
|
1801
|
+
],
|
|
1802
|
+
initial: 2
|
|
1803
|
+
// Default to "None"
|
|
1804
|
+
},
|
|
1745
1805
|
{
|
|
1746
1806
|
type: "select",
|
|
1747
1807
|
name: "category",
|
|
@@ -1811,13 +1871,16 @@ var getCnaOptions = async (options) => {
|
|
|
1811
1871
|
(existingTemplate == null ? void 0 : existingTemplate.type) || "custom",
|
|
1812
1872
|
"all"
|
|
1813
1873
|
]);
|
|
1814
|
-
for (const [
|
|
1874
|
+
for (const [categorySlug, extensions] of Object.entries(
|
|
1815
1875
|
extensionsGroupedByCategory
|
|
1816
1876
|
)) {
|
|
1877
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
1878
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
1879
|
+
const categoryDescription = (categoryData == null ? void 0 : categoryData.description) || "";
|
|
1817
1880
|
const { selected } = await (0, import_prompts.default)({
|
|
1818
1881
|
type: "multiselect",
|
|
1819
1882
|
name: "selected",
|
|
1820
|
-
message: `Select extensions for ${
|
|
1883
|
+
message: `Select extensions for ${categoryName}${categoryDescription ? `: ${categoryDescription}` : ""}`,
|
|
1821
1884
|
choices: extensions.map((extension) => {
|
|
1822
1885
|
var _a;
|
|
1823
1886
|
return {
|
|
@@ -1852,6 +1915,8 @@ var getCnaOptions = async (options) => {
|
|
|
1852
1915
|
}
|
|
1853
1916
|
const { ...nextAppOptions } = {
|
|
1854
1917
|
extend: [],
|
|
1918
|
+
aiTool: "none",
|
|
1919
|
+
// Default value
|
|
1855
1920
|
...options,
|
|
1856
1921
|
...baseInput,
|
|
1857
1922
|
...templateInput,
|
|
@@ -1868,11 +1933,19 @@ var getCnaOptions = async (options) => {
|
|
|
1868
1933
|
}
|
|
1869
1934
|
return nextOptions;
|
|
1870
1935
|
};
|
|
1936
|
+
var getCnaOptions = async (options) => {
|
|
1937
|
+
const shouldUseInteractiveMode = !import_ci_info.isCI && options.interactive;
|
|
1938
|
+
if (shouldUseInteractiveMode) {
|
|
1939
|
+
return processInteractiveOptions(options);
|
|
1940
|
+
} else {
|
|
1941
|
+
return processNonInteractiveOptions(options);
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1871
1944
|
|
|
1872
1945
|
// package.json
|
|
1873
1946
|
var package_default = {
|
|
1874
1947
|
name: "create-awesome-node-app",
|
|
1875
|
-
version: "0.
|
|
1948
|
+
version: "0.5.0",
|
|
1876
1949
|
type: "module",
|
|
1877
1950
|
description: "Command line tool to create Node apps with a lot of different templates and extensions.",
|
|
1878
1951
|
license: "MIT",
|
|
@@ -1937,11 +2010,87 @@ var package_default = {
|
|
|
1937
2010
|
}
|
|
1938
2011
|
};
|
|
1939
2012
|
|
|
2013
|
+
// src/list.ts
|
|
2014
|
+
var import_chalk = __toESM(require_source(), 1);
|
|
2015
|
+
var listTemplates = async () => {
|
|
2016
|
+
const categories = await getTemplateCategories();
|
|
2017
|
+
console.log(import_chalk.default.bold.blue("\nAvailable Templates:"));
|
|
2018
|
+
for (const categorySlug of categories) {
|
|
2019
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
2020
|
+
const templates = await getTemplatesForCategory(categorySlug);
|
|
2021
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
2022
|
+
console.log(import_chalk.default.bold.green(`
|
|
2023
|
+
${categoryName}:`));
|
|
2024
|
+
if (categoryData == null ? void 0 : categoryData.description) {
|
|
2025
|
+
console.log(` ${categoryData.description}`);
|
|
2026
|
+
}
|
|
2027
|
+
templates.forEach((template) => {
|
|
2028
|
+
console.log(
|
|
2029
|
+
` ${import_chalk.default.yellow(template.name)} (${import_chalk.default.cyan(template.slug)})`
|
|
2030
|
+
);
|
|
2031
|
+
console.log(` ${template.description}`);
|
|
2032
|
+
if (template.labels && template.labels.length > 0) {
|
|
2033
|
+
console.log(` Keywords: ${template.labels.join(", ")}`);
|
|
2034
|
+
}
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
};
|
|
2038
|
+
var listAddons = async ({
|
|
2039
|
+
templateSlug,
|
|
2040
|
+
templateType
|
|
2041
|
+
}) => {
|
|
2042
|
+
if (templateSlug && !templateType) {
|
|
2043
|
+
templateType = await getTemplateTypeFromSlug(templateSlug);
|
|
2044
|
+
}
|
|
2045
|
+
const types = templateType ? [templateType, "all"] : ["all"];
|
|
2046
|
+
const extensionsGroupedByCategory = await getExtensionsGroupedByCategory(
|
|
2047
|
+
types
|
|
2048
|
+
);
|
|
2049
|
+
console.log(import_chalk.default.bold.blue("\nAvailable Addons:"));
|
|
2050
|
+
if (templateSlug) {
|
|
2051
|
+
console.log(
|
|
2052
|
+
import_chalk.default.bold.green(`
|
|
2053
|
+
Compatible with template: ${templateSlug}`)
|
|
2054
|
+
);
|
|
2055
|
+
}
|
|
2056
|
+
for (const [categorySlug, extensions] of Object.entries(
|
|
2057
|
+
extensionsGroupedByCategory
|
|
2058
|
+
)) {
|
|
2059
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
2060
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
2061
|
+
console.log(import_chalk.default.bold.green(`
|
|
2062
|
+
${categoryName}:`));
|
|
2063
|
+
if (categoryData == null ? void 0 : categoryData.description) {
|
|
2064
|
+
console.log(` ${categoryData.description}`);
|
|
2065
|
+
}
|
|
2066
|
+
extensions.forEach((extension) => {
|
|
2067
|
+
console.log(
|
|
2068
|
+
` ${import_chalk.default.yellow(extension.name)} (${import_chalk.default.cyan(extension.slug)})`
|
|
2069
|
+
);
|
|
2070
|
+
console.log(` ${extension.description}`);
|
|
2071
|
+
if (extension.labels && extension.labels.length > 0) {
|
|
2072
|
+
console.log(` Keywords: ${extension.labels.join(", ")}`);
|
|
2073
|
+
}
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
var getTemplateTypeFromSlug = async (templateSlug) => {
|
|
2078
|
+
const categories = await getTemplateCategories();
|
|
2079
|
+
for (const category of categories) {
|
|
2080
|
+
const templates = await getTemplatesForCategory(category);
|
|
2081
|
+
const template = templates.find((t) => t.slug === templateSlug);
|
|
2082
|
+
if (template) {
|
|
2083
|
+
return template.type;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
return void 0;
|
|
2087
|
+
};
|
|
2088
|
+
|
|
1940
2089
|
// src/index.ts
|
|
1941
2090
|
var program = new import_commander.Command();
|
|
1942
2091
|
var main = async () => {
|
|
1943
2092
|
let projectName = "my-project";
|
|
1944
|
-
program.version(package_default.version).arguments("[project-directory]").usage(`${
|
|
2093
|
+
program.version(package_default.version).arguments("[project-directory]").usage(`${import_chalk2.default.green("[project-directory]")} [options]`).option("-v, --verbose", "print additional logs").option("-i, --info", "print environment debug info").option(
|
|
1945
2094
|
"--no-install",
|
|
1946
2095
|
"Generate package.json without installing dependencies"
|
|
1947
2096
|
).option(
|
|
@@ -1950,7 +2099,10 @@ var main = async () => {
|
|
|
1950
2099
|
).option(
|
|
1951
2100
|
"--addons [extensions...]",
|
|
1952
2101
|
"specify extensions to apply for the boilerplate generation"
|
|
1953
|
-
).option("--use-yarn", "use yarn instead of npm or pnpm").option("--use-pnpm", "use pnpm instead of yarn or npm").option(
|
|
2102
|
+
).option("--use-yarn", "use yarn instead of npm or pnpm").option("--use-pnpm", "use pnpm instead of yarn or npm").option(
|
|
2103
|
+
"--ai-tool <tool>",
|
|
2104
|
+
"specify AI tool configuration (cursor, copilot, none)"
|
|
2105
|
+
).option("--interactive", "run in interactive mode to select options", false).option("--list-templates", "list all available templates").option("--list-addons", "list all available addons").action((providedProjectName) => {
|
|
1954
2106
|
projectName = providedProjectName || projectName;
|
|
1955
2107
|
});
|
|
1956
2108
|
program.parse(process.argv);
|
|
@@ -1960,7 +2112,7 @@ var main = async () => {
|
|
|
1960
2112
|
if (latest && import_semver.default.lt(package_default.version, latest)) {
|
|
1961
2113
|
console.log();
|
|
1962
2114
|
console.error(
|
|
1963
|
-
|
|
2115
|
+
import_chalk2.default.yellow(
|
|
1964
2116
|
`You are running \`create-awesome-node-app\` ${package_default.version}, which is behind the latest release (${latest}).
|
|
1965
2117
|
|
|
1966
2118
|
We recommend always using the latest version of create-awesome-node-app if possible.`
|
|
@@ -1968,10 +2120,19 @@ We recommend always using the latest version of create-awesome-node-app if possi
|
|
|
1968
2120
|
);
|
|
1969
2121
|
return;
|
|
1970
2122
|
}
|
|
1971
|
-
|
|
1972
|
-
|
|
2123
|
+
if (opts.listTemplates) {
|
|
2124
|
+
await listTemplates();
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
if (opts.listAddons) {
|
|
2128
|
+
await listAddons({
|
|
2129
|
+
templateSlug: opts.template
|
|
2130
|
+
});
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
2133
|
+
const { useYarn, usePnpm, ...restOpts } = opts;
|
|
1973
2134
|
const packageManager = useYarn ? "yarn" : usePnpm ? "pnpm" : "npm";
|
|
1974
|
-
const templatesOrExtensions = [
|
|
2135
|
+
const templatesOrExtensions = [restOpts.template].concat(Array.isArray(restOpts.extend) ? restOpts.extend : []).reduce((acc, templateOrExtension) => {
|
|
1975
2136
|
if (!templateOrExtension) {
|
|
1976
2137
|
return acc;
|
|
1977
2138
|
}
|
|
@@ -1981,7 +2142,7 @@ We recommend always using the latest version of create-awesome-node-app if possi
|
|
|
1981
2142
|
}, []);
|
|
1982
2143
|
return (0, import_core.createNodeApp)(
|
|
1983
2144
|
projectName,
|
|
1984
|
-
{ ...
|
|
2145
|
+
{ ...restOpts, packageManager, templatesOrExtensions, projectName },
|
|
1985
2146
|
getCnaOptions
|
|
1986
2147
|
);
|
|
1987
2148
|
};
|
package/dist/index.js
CHANGED
|
@@ -1348,14 +1348,14 @@ var require_templates = __commonJS({
|
|
|
1348
1348
|
}
|
|
1349
1349
|
return results;
|
|
1350
1350
|
}
|
|
1351
|
-
function buildStyle(
|
|
1351
|
+
function buildStyle(chalk3, styles) {
|
|
1352
1352
|
const enabled = {};
|
|
1353
1353
|
for (const layer of styles) {
|
|
1354
1354
|
for (const style of layer.styles) {
|
|
1355
1355
|
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
1356
1356
|
}
|
|
1357
1357
|
}
|
|
1358
|
-
let current =
|
|
1358
|
+
let current = chalk3;
|
|
1359
1359
|
for (const [styleName, styles2] of Object.entries(enabled)) {
|
|
1360
1360
|
if (!Array.isArray(styles2)) {
|
|
1361
1361
|
continue;
|
|
@@ -1367,7 +1367,7 @@ var require_templates = __commonJS({
|
|
|
1367
1367
|
}
|
|
1368
1368
|
return current;
|
|
1369
1369
|
}
|
|
1370
|
-
module.exports = (
|
|
1370
|
+
module.exports = (chalk3, temporary) => {
|
|
1371
1371
|
const styles = [];
|
|
1372
1372
|
const chunks = [];
|
|
1373
1373
|
let chunk = [];
|
|
@@ -1377,13 +1377,13 @@ var require_templates = __commonJS({
|
|
|
1377
1377
|
} else if (style) {
|
|
1378
1378
|
const string = chunk.join("");
|
|
1379
1379
|
chunk = [];
|
|
1380
|
-
chunks.push(styles.length === 0 ? string : buildStyle(
|
|
1380
|
+
chunks.push(styles.length === 0 ? string : buildStyle(chalk3, styles)(string));
|
|
1381
1381
|
styles.push({ inverse, styles: parseStyle(style) });
|
|
1382
1382
|
} else if (close) {
|
|
1383
1383
|
if (styles.length === 0) {
|
|
1384
1384
|
throw new Error("Found extraneous } in Chalk template literal");
|
|
1385
1385
|
}
|
|
1386
|
-
chunks.push(buildStyle(
|
|
1386
|
+
chunks.push(buildStyle(chalk3, styles)(chunk.join("")));
|
|
1387
1387
|
chunk = [];
|
|
1388
1388
|
styles.pop();
|
|
1389
1389
|
} else {
|
|
@@ -1431,16 +1431,16 @@ var require_source = __commonJS({
|
|
|
1431
1431
|
}
|
|
1432
1432
|
};
|
|
1433
1433
|
var chalkFactory = (options) => {
|
|
1434
|
-
const
|
|
1435
|
-
applyOptions(
|
|
1436
|
-
|
|
1437
|
-
Object.setPrototypeOf(
|
|
1438
|
-
Object.setPrototypeOf(
|
|
1439
|
-
|
|
1434
|
+
const chalk4 = {};
|
|
1435
|
+
applyOptions(chalk4, options);
|
|
1436
|
+
chalk4.template = (...arguments_) => chalkTag(chalk4.template, ...arguments_);
|
|
1437
|
+
Object.setPrototypeOf(chalk4, Chalk.prototype);
|
|
1438
|
+
Object.setPrototypeOf(chalk4.template, chalk4);
|
|
1439
|
+
chalk4.template.constructor = () => {
|
|
1440
1440
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
1441
1441
|
};
|
|
1442
|
-
|
|
1443
|
-
return
|
|
1442
|
+
chalk4.template.Instance = ChalkClass;
|
|
1443
|
+
return chalk4.template;
|
|
1444
1444
|
};
|
|
1445
1445
|
function Chalk(options) {
|
|
1446
1446
|
return chalkFactory(options);
|
|
@@ -1551,7 +1551,7 @@ var require_source = __commonJS({
|
|
|
1551
1551
|
return openAll + string + closeAll;
|
|
1552
1552
|
};
|
|
1553
1553
|
var template;
|
|
1554
|
-
var chalkTag = (
|
|
1554
|
+
var chalkTag = (chalk4, ...strings) => {
|
|
1555
1555
|
const [firstString] = strings;
|
|
1556
1556
|
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
1557
1557
|
return strings.join(" ");
|
|
@@ -1567,19 +1567,19 @@ var require_source = __commonJS({
|
|
|
1567
1567
|
if (template === void 0) {
|
|
1568
1568
|
template = require_templates();
|
|
1569
1569
|
}
|
|
1570
|
-
return template(
|
|
1570
|
+
return template(chalk4, parts.join(""));
|
|
1571
1571
|
};
|
|
1572
1572
|
Object.defineProperties(Chalk.prototype, styles);
|
|
1573
|
-
var
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
module.exports =
|
|
1573
|
+
var chalk3 = Chalk();
|
|
1574
|
+
chalk3.supportsColor = stdoutColor;
|
|
1575
|
+
chalk3.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
1576
|
+
chalk3.stderr.supportsColor = stderrColor;
|
|
1577
|
+
module.exports = chalk3;
|
|
1578
1578
|
}
|
|
1579
1579
|
});
|
|
1580
1580
|
|
|
1581
1581
|
// src/index.ts
|
|
1582
|
-
var
|
|
1582
|
+
var import_chalk2 = __toESM(require_source(), 1);
|
|
1583
1583
|
import { Command } from "commander";
|
|
1584
1584
|
import semver from "semver";
|
|
1585
1585
|
import {
|
|
@@ -1622,12 +1622,24 @@ var getTemplateCategories = async (cliArgs) => {
|
|
|
1622
1622
|
return [cliArgs.category];
|
|
1623
1623
|
}
|
|
1624
1624
|
const templateData = await getTemplateData();
|
|
1625
|
+
if (templateData.categories && templateData.categories.length > 0) {
|
|
1626
|
+
return templateData.categories.map((category) => category.slug);
|
|
1627
|
+
}
|
|
1625
1628
|
const categories = /* @__PURE__ */ new Set();
|
|
1626
1629
|
templateData.templates.forEach((template) => {
|
|
1627
1630
|
categories.add(template.category);
|
|
1628
1631
|
});
|
|
1629
1632
|
return Array.from(categories);
|
|
1630
1633
|
};
|
|
1634
|
+
var getCategoryData = async (categorySlug) => {
|
|
1635
|
+
const templateData = await getTemplateData();
|
|
1636
|
+
if (templateData.categories && templateData.categories.length > 0) {
|
|
1637
|
+
return templateData.categories.find(
|
|
1638
|
+
(category) => category.slug === categorySlug
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
return void 0;
|
|
1642
|
+
};
|
|
1631
1643
|
var getTemplatesForCategory = async (category, cliArgs) => {
|
|
1632
1644
|
const selectedCategory = (cliArgs == null ? void 0 : cliArgs.category) || category;
|
|
1633
1645
|
if (!selectedCategory) {
|
|
@@ -1671,63 +1683,87 @@ var isValidUrl = (url) => {
|
|
|
1671
1683
|
return false;
|
|
1672
1684
|
}
|
|
1673
1685
|
};
|
|
1674
|
-
var
|
|
1686
|
+
var processNonInteractiveOptions = async (options) => {
|
|
1675
1687
|
const categories = await getTemplateCategories();
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1688
|
+
let matchedTemplate;
|
|
1689
|
+
const templatesOrExtensions = [];
|
|
1690
|
+
if (options.template && !isValidUrl(options.template)) {
|
|
1691
|
+
const allTemplates = (await Promise.all(
|
|
1692
|
+
categories.map((category) => getTemplatesForCategory(category))
|
|
1693
|
+
)).flat();
|
|
1694
|
+
matchedTemplate = allTemplates.find(
|
|
1695
|
+
(template) => template.slug === options.template
|
|
1696
|
+
);
|
|
1697
|
+
if (matchedTemplate) {
|
|
1698
|
+
templatesOrExtensions.push({ url: matchedTemplate.url });
|
|
1699
|
+
if (matchedTemplate.customOptions) {
|
|
1700
|
+
matchedTemplate.customOptions.forEach((customOption) => {
|
|
1701
|
+
if (customOption.name && customOption.initial !== void 0) {
|
|
1702
|
+
options[customOption.name] = customOption.initial;
|
|
1703
|
+
}
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
} else {
|
|
1707
|
+
throw new Error(
|
|
1708
|
+
`Invalid template slug: '${options.template}'. Please provide a valid template slug.`
|
|
1684
1709
|
);
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1710
|
+
}
|
|
1711
|
+
} else if (options.template) {
|
|
1712
|
+
templatesOrExtensions.push({ url: options.template });
|
|
1713
|
+
}
|
|
1714
|
+
if (options.addons && Array.isArray(options.addons)) {
|
|
1715
|
+
const extensionsGroupedByCategory = await getExtensionsGroupedByCategory([
|
|
1716
|
+
(matchedTemplate == null ? void 0 : matchedTemplate.type) || "custom",
|
|
1717
|
+
"all"
|
|
1718
|
+
]);
|
|
1719
|
+
const extensions = options.addons.map((addon) => {
|
|
1720
|
+
if (!isValidUrl(addon)) {
|
|
1721
|
+
for (const extensions2 of Object.values(extensionsGroupedByCategory)) {
|
|
1722
|
+
const matchedExtension = extensions2.find(
|
|
1723
|
+
(extension) => extension.slug === addon
|
|
1724
|
+
);
|
|
1725
|
+
if (matchedExtension) {
|
|
1726
|
+
return matchedExtension.url;
|
|
1727
|
+
}
|
|
1693
1728
|
}
|
|
1694
|
-
} else {
|
|
1695
1729
|
throw new Error(
|
|
1696
|
-
`Invalid
|
|
1730
|
+
`Invalid extension slug: '${addon}'. Please provide a valid extension slug.`
|
|
1697
1731
|
);
|
|
1698
1732
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
(extension) => extension.slug === addon
|
|
1710
|
-
);
|
|
1711
|
-
if (matchedExtension) {
|
|
1712
|
-
return matchedExtension.url;
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
throw new Error(
|
|
1716
|
-
`Invalid extension slug: '${addon}'. Please provide a valid extension slug.`
|
|
1717
|
-
);
|
|
1718
|
-
}
|
|
1719
|
-
return addon;
|
|
1720
|
-
});
|
|
1721
|
-
}
|
|
1722
|
-
if (options.verbose) {
|
|
1723
|
-
console.log(JSON.stringify(options, null, 2));
|
|
1724
|
-
}
|
|
1725
|
-
return options;
|
|
1733
|
+
return addon;
|
|
1734
|
+
}).map((addon) => ({ url: addon }));
|
|
1735
|
+
templatesOrExtensions.push(...extensions);
|
|
1736
|
+
}
|
|
1737
|
+
if (options.extend && Array.isArray(options.extend)) {
|
|
1738
|
+
const additionalExtensions = options.extend.filter(Boolean).map((extension) => ({ url: extension }));
|
|
1739
|
+
templatesOrExtensions.push(...additionalExtensions);
|
|
1740
|
+
}
|
|
1741
|
+
if (options.aiTool && !["cursor", "copilot", "none"].includes(options.aiTool)) {
|
|
1742
|
+
throw new Error("Invalid --ai-tool option. Use: cursor, copilot, or none");
|
|
1726
1743
|
}
|
|
1744
|
+
options.aiTool = options.aiTool || "none";
|
|
1745
|
+
options.templatesOrExtensions = templatesOrExtensions;
|
|
1746
|
+
if (options.verbose) {
|
|
1747
|
+
console.log(JSON.stringify(options, null, 2));
|
|
1748
|
+
}
|
|
1749
|
+
return options;
|
|
1750
|
+
};
|
|
1751
|
+
var processInteractiveOptions = async (options) => {
|
|
1752
|
+
const categories = await getTemplateCategories();
|
|
1753
|
+
const categoryDataPromises = categories.map(async (categorySlug) => {
|
|
1754
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
1755
|
+
return {
|
|
1756
|
+
slug: categorySlug,
|
|
1757
|
+
name: (categoryData == null ? void 0 : categoryData.name) || categorySlug,
|
|
1758
|
+
description: (categoryData == null ? void 0 : categoryData.description) || ""
|
|
1759
|
+
};
|
|
1760
|
+
});
|
|
1761
|
+
const categoryDataList = await Promise.all(categoryDataPromises);
|
|
1727
1762
|
const categoriesOptions = [
|
|
1728
|
-
...
|
|
1729
|
-
title: category,
|
|
1730
|
-
value: category
|
|
1763
|
+
...categoryDataList.map((category) => ({
|
|
1764
|
+
title: category.name,
|
|
1765
|
+
value: category.slug,
|
|
1766
|
+
description: category.description
|
|
1731
1767
|
})),
|
|
1732
1768
|
{
|
|
1733
1769
|
title: "None of the above",
|
|
@@ -1752,6 +1788,30 @@ var getCnaOptions = async (options) => {
|
|
|
1752
1788
|
})),
|
|
1753
1789
|
initial: options.packageManager ? PACKAGE_MANAGERS.indexOf(options.packageManager) : 0
|
|
1754
1790
|
},
|
|
1791
|
+
{
|
|
1792
|
+
type: "select",
|
|
1793
|
+
name: "aiTool",
|
|
1794
|
+
message: "Which AI coding tool would you like to configure?",
|
|
1795
|
+
choices: [
|
|
1796
|
+
{
|
|
1797
|
+
title: "Cursor Rules",
|
|
1798
|
+
value: "cursor",
|
|
1799
|
+
description: "Add .cursorrules configuration for Cursor IDE"
|
|
1800
|
+
},
|
|
1801
|
+
{
|
|
1802
|
+
title: "GitHub Copilot Instructions",
|
|
1803
|
+
value: "copilot",
|
|
1804
|
+
description: "Add .github/copilot-instructions.md for GitHub Copilot"
|
|
1805
|
+
},
|
|
1806
|
+
{
|
|
1807
|
+
title: "None",
|
|
1808
|
+
value: "none",
|
|
1809
|
+
description: "Don't add any AI tool configuration"
|
|
1810
|
+
}
|
|
1811
|
+
],
|
|
1812
|
+
initial: 2
|
|
1813
|
+
// Default to "None"
|
|
1814
|
+
},
|
|
1755
1815
|
{
|
|
1756
1816
|
type: "select",
|
|
1757
1817
|
name: "category",
|
|
@@ -1821,13 +1881,16 @@ var getCnaOptions = async (options) => {
|
|
|
1821
1881
|
(existingTemplate == null ? void 0 : existingTemplate.type) || "custom",
|
|
1822
1882
|
"all"
|
|
1823
1883
|
]);
|
|
1824
|
-
for (const [
|
|
1884
|
+
for (const [categorySlug, extensions] of Object.entries(
|
|
1825
1885
|
extensionsGroupedByCategory
|
|
1826
1886
|
)) {
|
|
1887
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
1888
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
1889
|
+
const categoryDescription = (categoryData == null ? void 0 : categoryData.description) || "";
|
|
1827
1890
|
const { selected } = await prompts({
|
|
1828
1891
|
type: "multiselect",
|
|
1829
1892
|
name: "selected",
|
|
1830
|
-
message: `Select extensions for ${
|
|
1893
|
+
message: `Select extensions for ${categoryName}${categoryDescription ? `: ${categoryDescription}` : ""}`,
|
|
1831
1894
|
choices: extensions.map((extension) => {
|
|
1832
1895
|
var _a;
|
|
1833
1896
|
return {
|
|
@@ -1862,6 +1925,8 @@ var getCnaOptions = async (options) => {
|
|
|
1862
1925
|
}
|
|
1863
1926
|
const { ...nextAppOptions } = {
|
|
1864
1927
|
extend: [],
|
|
1928
|
+
aiTool: "none",
|
|
1929
|
+
// Default value
|
|
1865
1930
|
...options,
|
|
1866
1931
|
...baseInput,
|
|
1867
1932
|
...templateInput,
|
|
@@ -1878,11 +1943,19 @@ var getCnaOptions = async (options) => {
|
|
|
1878
1943
|
}
|
|
1879
1944
|
return nextOptions;
|
|
1880
1945
|
};
|
|
1946
|
+
var getCnaOptions = async (options) => {
|
|
1947
|
+
const shouldUseInteractiveMode = !isCI && options.interactive;
|
|
1948
|
+
if (shouldUseInteractiveMode) {
|
|
1949
|
+
return processInteractiveOptions(options);
|
|
1950
|
+
} else {
|
|
1951
|
+
return processNonInteractiveOptions(options);
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1881
1954
|
|
|
1882
1955
|
// package.json
|
|
1883
1956
|
var package_default = {
|
|
1884
1957
|
name: "create-awesome-node-app",
|
|
1885
|
-
version: "0.
|
|
1958
|
+
version: "0.5.0",
|
|
1886
1959
|
type: "module",
|
|
1887
1960
|
description: "Command line tool to create Node apps with a lot of different templates and extensions.",
|
|
1888
1961
|
license: "MIT",
|
|
@@ -1947,11 +2020,87 @@ var package_default = {
|
|
|
1947
2020
|
}
|
|
1948
2021
|
};
|
|
1949
2022
|
|
|
2023
|
+
// src/list.ts
|
|
2024
|
+
var import_chalk = __toESM(require_source(), 1);
|
|
2025
|
+
var listTemplates = async () => {
|
|
2026
|
+
const categories = await getTemplateCategories();
|
|
2027
|
+
console.log(import_chalk.default.bold.blue("\nAvailable Templates:"));
|
|
2028
|
+
for (const categorySlug of categories) {
|
|
2029
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
2030
|
+
const templates = await getTemplatesForCategory(categorySlug);
|
|
2031
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
2032
|
+
console.log(import_chalk.default.bold.green(`
|
|
2033
|
+
${categoryName}:`));
|
|
2034
|
+
if (categoryData == null ? void 0 : categoryData.description) {
|
|
2035
|
+
console.log(` ${categoryData.description}`);
|
|
2036
|
+
}
|
|
2037
|
+
templates.forEach((template) => {
|
|
2038
|
+
console.log(
|
|
2039
|
+
` ${import_chalk.default.yellow(template.name)} (${import_chalk.default.cyan(template.slug)})`
|
|
2040
|
+
);
|
|
2041
|
+
console.log(` ${template.description}`);
|
|
2042
|
+
if (template.labels && template.labels.length > 0) {
|
|
2043
|
+
console.log(` Keywords: ${template.labels.join(", ")}`);
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
};
|
|
2048
|
+
var listAddons = async ({
|
|
2049
|
+
templateSlug,
|
|
2050
|
+
templateType
|
|
2051
|
+
}) => {
|
|
2052
|
+
if (templateSlug && !templateType) {
|
|
2053
|
+
templateType = await getTemplateTypeFromSlug(templateSlug);
|
|
2054
|
+
}
|
|
2055
|
+
const types = templateType ? [templateType, "all"] : ["all"];
|
|
2056
|
+
const extensionsGroupedByCategory = await getExtensionsGroupedByCategory(
|
|
2057
|
+
types
|
|
2058
|
+
);
|
|
2059
|
+
console.log(import_chalk.default.bold.blue("\nAvailable Addons:"));
|
|
2060
|
+
if (templateSlug) {
|
|
2061
|
+
console.log(
|
|
2062
|
+
import_chalk.default.bold.green(`
|
|
2063
|
+
Compatible with template: ${templateSlug}`)
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
2066
|
+
for (const [categorySlug, extensions] of Object.entries(
|
|
2067
|
+
extensionsGroupedByCategory
|
|
2068
|
+
)) {
|
|
2069
|
+
const categoryData = await getCategoryData(categorySlug);
|
|
2070
|
+
const categoryName = (categoryData == null ? void 0 : categoryData.name) || categorySlug;
|
|
2071
|
+
console.log(import_chalk.default.bold.green(`
|
|
2072
|
+
${categoryName}:`));
|
|
2073
|
+
if (categoryData == null ? void 0 : categoryData.description) {
|
|
2074
|
+
console.log(` ${categoryData.description}`);
|
|
2075
|
+
}
|
|
2076
|
+
extensions.forEach((extension) => {
|
|
2077
|
+
console.log(
|
|
2078
|
+
` ${import_chalk.default.yellow(extension.name)} (${import_chalk.default.cyan(extension.slug)})`
|
|
2079
|
+
);
|
|
2080
|
+
console.log(` ${extension.description}`);
|
|
2081
|
+
if (extension.labels && extension.labels.length > 0) {
|
|
2082
|
+
console.log(` Keywords: ${extension.labels.join(", ")}`);
|
|
2083
|
+
}
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2087
|
+
var getTemplateTypeFromSlug = async (templateSlug) => {
|
|
2088
|
+
const categories = await getTemplateCategories();
|
|
2089
|
+
for (const category of categories) {
|
|
2090
|
+
const templates = await getTemplatesForCategory(category);
|
|
2091
|
+
const template = templates.find((t) => t.slug === templateSlug);
|
|
2092
|
+
if (template) {
|
|
2093
|
+
return template.type;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return void 0;
|
|
2097
|
+
};
|
|
2098
|
+
|
|
1950
2099
|
// src/index.ts
|
|
1951
2100
|
var program = new Command();
|
|
1952
2101
|
var main = async () => {
|
|
1953
2102
|
let projectName = "my-project";
|
|
1954
|
-
program.version(package_default.version).arguments("[project-directory]").usage(`${
|
|
2103
|
+
program.version(package_default.version).arguments("[project-directory]").usage(`${import_chalk2.default.green("[project-directory]")} [options]`).option("-v, --verbose", "print additional logs").option("-i, --info", "print environment debug info").option(
|
|
1955
2104
|
"--no-install",
|
|
1956
2105
|
"Generate package.json without installing dependencies"
|
|
1957
2106
|
).option(
|
|
@@ -1960,7 +2109,10 @@ var main = async () => {
|
|
|
1960
2109
|
).option(
|
|
1961
2110
|
"--addons [extensions...]",
|
|
1962
2111
|
"specify extensions to apply for the boilerplate generation"
|
|
1963
|
-
).option("--use-yarn", "use yarn instead of npm or pnpm").option("--use-pnpm", "use pnpm instead of yarn or npm").option(
|
|
2112
|
+
).option("--use-yarn", "use yarn instead of npm or pnpm").option("--use-pnpm", "use pnpm instead of yarn or npm").option(
|
|
2113
|
+
"--ai-tool <tool>",
|
|
2114
|
+
"specify AI tool configuration (cursor, copilot, none)"
|
|
2115
|
+
).option("--interactive", "run in interactive mode to select options", false).option("--list-templates", "list all available templates").option("--list-addons", "list all available addons").action((providedProjectName) => {
|
|
1964
2116
|
projectName = providedProjectName || projectName;
|
|
1965
2117
|
});
|
|
1966
2118
|
program.parse(process.argv);
|
|
@@ -1970,7 +2122,7 @@ var main = async () => {
|
|
|
1970
2122
|
if (latest && semver.lt(package_default.version, latest)) {
|
|
1971
2123
|
console.log();
|
|
1972
2124
|
console.error(
|
|
1973
|
-
|
|
2125
|
+
import_chalk2.default.yellow(
|
|
1974
2126
|
`You are running \`create-awesome-node-app\` ${package_default.version}, which is behind the latest release (${latest}).
|
|
1975
2127
|
|
|
1976
2128
|
We recommend always using the latest version of create-awesome-node-app if possible.`
|
|
@@ -1978,10 +2130,19 @@ We recommend always using the latest version of create-awesome-node-app if possi
|
|
|
1978
2130
|
);
|
|
1979
2131
|
return;
|
|
1980
2132
|
}
|
|
1981
|
-
|
|
1982
|
-
|
|
2133
|
+
if (opts.listTemplates) {
|
|
2134
|
+
await listTemplates();
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (opts.listAddons) {
|
|
2138
|
+
await listAddons({
|
|
2139
|
+
templateSlug: opts.template
|
|
2140
|
+
});
|
|
2141
|
+
return;
|
|
2142
|
+
}
|
|
2143
|
+
const { useYarn, usePnpm, ...restOpts } = opts;
|
|
1983
2144
|
const packageManager = useYarn ? "yarn" : usePnpm ? "pnpm" : "npm";
|
|
1984
|
-
const templatesOrExtensions = [
|
|
2145
|
+
const templatesOrExtensions = [restOpts.template].concat(Array.isArray(restOpts.extend) ? restOpts.extend : []).reduce((acc, templateOrExtension) => {
|
|
1985
2146
|
if (!templateOrExtension) {
|
|
1986
2147
|
return acc;
|
|
1987
2148
|
}
|
|
@@ -1991,7 +2152,7 @@ We recommend always using the latest version of create-awesome-node-app if possi
|
|
|
1991
2152
|
}, []);
|
|
1992
2153
|
return createNodeApp(
|
|
1993
2154
|
projectName,
|
|
1994
|
-
{ ...
|
|
2155
|
+
{ ...restOpts, packageManager, templatesOrExtensions, projectName },
|
|
1995
2156
|
getCnaOptions
|
|
1996
2157
|
);
|
|
1997
2158
|
};
|