create-awesome-node-app 0.7.1 → 0.9.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 +5 -5
- package/dist/index.cjs +96 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +92 -34
- package/dist/index.js.map +1 -1
- package/package.json +10 -15
package/README.md
CHANGED
|
@@ -101,8 +101,8 @@ create-awesome-node-app --template react-vite-boilerplate --list-addons
|
|
|
101
101
|
|
|
102
102
|
## 🧱 Template Ecosystem
|
|
103
103
|
|
|
104
|
-
| Category
|
|
105
|
-
|
|
|
104
|
+
| Category | Example Templates |
|
|
105
|
+
| --------------- | ----------------------------------------------------------------- |
|
|
106
106
|
| 🖥 Frontend | `react-vite-boilerplate` — React 18 + Vite + TS + ESLint + Vitest |
|
|
107
107
|
| 🔧 Backend | `nestjs-boilerplate` — NestJS + TS + ESLint + Jest |
|
|
108
108
|
| 🌐 Full Stack | `nextjs-starter` — Next.js + SSR + TS + Prettier |
|
|
@@ -118,8 +118,8 @@ create-awesome-node-app --template react-vite-boilerplate --list-addons
|
|
|
118
118
|
|
|
119
119
|
Think of addons as _lego bricks_ — snap them onto any template to add exactly what you need:
|
|
120
120
|
|
|
121
|
-
| Category
|
|
122
|
-
|
|
|
121
|
+
| Category | Examples |
|
|
122
|
+
| -------------- | -------------------------------------------------------- |
|
|
123
123
|
| 🎨 UI Libraries | Material UI, Tailwind CSS, component libraries |
|
|
124
124
|
| 📊 State & Data | Jotai, tRPC, React Query, Zustand |
|
|
125
125
|
| 🔧 Tooling | GitHub Actions workflows, changesets, release automation |
|
|
@@ -184,7 +184,7 @@ npm create awesome-node-app@latest my-app
|
|
|
184
184
|
|
|
185
185
|
## 🔍 CLI Reference
|
|
186
186
|
|
|
187
|
-
```
|
|
187
|
+
```text
|
|
188
188
|
Usage: create-awesome-node-app [project-directory] [options]
|
|
189
189
|
```
|
|
190
190
|
|
package/dist/index.cjs
CHANGED
|
@@ -992,9 +992,9 @@ var require_color_convert = __commonJS({
|
|
|
992
992
|
}
|
|
993
993
|
});
|
|
994
994
|
|
|
995
|
-
// node_modules/ansi-styles/index.js
|
|
995
|
+
// ../../node_modules/chalk/node_modules/ansi-styles/index.js
|
|
996
996
|
var require_ansi_styles = __commonJS({
|
|
997
|
-
"node_modules/ansi-styles/index.js"(exports2, module2) {
|
|
997
|
+
"../../node_modules/chalk/node_modules/ansi-styles/index.js"(exports2, module2) {
|
|
998
998
|
"use strict";
|
|
999
999
|
var wrapAnsi16 = (fn, offset) => (...args) => {
|
|
1000
1000
|
const code = fn(...args);
|
|
@@ -1249,9 +1249,9 @@ var require_supports_color = __commonJS({
|
|
|
1249
1249
|
}
|
|
1250
1250
|
});
|
|
1251
1251
|
|
|
1252
|
-
// node_modules/chalk/source/util.js
|
|
1252
|
+
// ../../node_modules/chalk/source/util.js
|
|
1253
1253
|
var require_util = __commonJS({
|
|
1254
|
-
"node_modules/chalk/source/util.js"(exports2, module2) {
|
|
1254
|
+
"../../node_modules/chalk/source/util.js"(exports2, module2) {
|
|
1255
1255
|
"use strict";
|
|
1256
1256
|
var stringReplaceAll = (string, substring, replacer) => {
|
|
1257
1257
|
let index = string.indexOf(substring);
|
|
@@ -1288,9 +1288,9 @@ var require_util = __commonJS({
|
|
|
1288
1288
|
}
|
|
1289
1289
|
});
|
|
1290
1290
|
|
|
1291
|
-
// node_modules/chalk/source/templates.js
|
|
1291
|
+
// ../../node_modules/chalk/source/templates.js
|
|
1292
1292
|
var require_templates = __commonJS({
|
|
1293
|
-
"node_modules/chalk/source/templates.js"(exports2, module2) {
|
|
1293
|
+
"../../node_modules/chalk/source/templates.js"(exports2, module2) {
|
|
1294
1294
|
"use strict";
|
|
1295
1295
|
var TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
|
|
1296
1296
|
var STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
|
|
@@ -1402,9 +1402,9 @@ var require_templates = __commonJS({
|
|
|
1402
1402
|
}
|
|
1403
1403
|
});
|
|
1404
1404
|
|
|
1405
|
-
// node_modules/chalk/source/index.js
|
|
1405
|
+
// ../../node_modules/chalk/source/index.js
|
|
1406
1406
|
var require_source = __commonJS({
|
|
1407
|
-
"node_modules/chalk/source/index.js"(exports2, module2) {
|
|
1407
|
+
"../../node_modules/chalk/source/index.js"(exports2, module2) {
|
|
1408
1408
|
"use strict";
|
|
1409
1409
|
var ansiStyles = require_ansi_styles();
|
|
1410
1410
|
var { stdout: stdoutColor, stderr: stderrColor } = require_supports_color();
|
|
@@ -1591,12 +1591,12 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1591
1591
|
var import_commander = require("commander");
|
|
1592
1592
|
var import_chalk2 = __toESM(require_source(), 1);
|
|
1593
1593
|
var import_semver = __toESM(require("semver"), 1);
|
|
1594
|
-
var
|
|
1594
|
+
var import_core2 = require("@create-node-app/core");
|
|
1595
1595
|
|
|
1596
1596
|
// src/options.ts
|
|
1597
|
+
var import_core = require("@create-node-app/core");
|
|
1597
1598
|
var import_ci_info = require("ci-info");
|
|
1598
1599
|
var import_prompts = __toESM(require("prompts"), 1);
|
|
1599
|
-
var import_yargs = __toESM(require("yargs"), 1);
|
|
1600
1600
|
|
|
1601
1601
|
// src/templates.ts
|
|
1602
1602
|
var import_axios = __toESM(require("axios"), 1);
|
|
@@ -1681,10 +1681,7 @@ var getExtensionsGroupedByCategory = async (type, cliArgs) => {
|
|
|
1681
1681
|
};
|
|
1682
1682
|
|
|
1683
1683
|
// src/options.ts
|
|
1684
|
-
|
|
1685
|
-
(0, import_yargs.default)(process.argv.slice(2)).help(false).version(false).argv
|
|
1686
|
-
);
|
|
1687
|
-
var PACKAGE_MANAGERS = ["npm", "yarn", "pnpm"];
|
|
1684
|
+
var PACKAGE_MANAGERS = ["npm", "yarn", "pnpm", "bun"];
|
|
1688
1685
|
var isValidUrl = (url) => {
|
|
1689
1686
|
try {
|
|
1690
1687
|
new URL(url);
|
|
@@ -1694,9 +1691,12 @@ var isValidUrl = (url) => {
|
|
|
1694
1691
|
}
|
|
1695
1692
|
};
|
|
1696
1693
|
var processNonInteractiveOptions = async (options) => {
|
|
1694
|
+
const setOverrides = options.setOverrides ?? {};
|
|
1695
|
+
delete options.setOverrides;
|
|
1697
1696
|
const categories = await getTemplateCategories();
|
|
1698
1697
|
let matchedTemplate;
|
|
1699
1698
|
const templatesOrExtensions = [];
|
|
1699
|
+
let resolvedTemplateUrl;
|
|
1700
1700
|
if (options.template && !isValidUrl(options.template)) {
|
|
1701
1701
|
const allTemplates = (await Promise.all(
|
|
1702
1702
|
categories.map((category) => getTemplatesForCategory(category))
|
|
@@ -1706,6 +1706,7 @@ var processNonInteractiveOptions = async (options) => {
|
|
|
1706
1706
|
);
|
|
1707
1707
|
if (matchedTemplate) {
|
|
1708
1708
|
templatesOrExtensions.push({ url: matchedTemplate.url });
|
|
1709
|
+
resolvedTemplateUrl = matchedTemplate.url;
|
|
1709
1710
|
if (matchedTemplate.customOptions) {
|
|
1710
1711
|
matchedTemplate.customOptions.forEach((customOption) => {
|
|
1711
1712
|
if (customOption.name && customOption.initial !== void 0) {
|
|
@@ -1720,7 +1721,19 @@ var processNonInteractiveOptions = async (options) => {
|
|
|
1720
1721
|
}
|
|
1721
1722
|
} else if (options.template) {
|
|
1722
1723
|
templatesOrExtensions.push({ url: options.template });
|
|
1724
|
+
resolvedTemplateUrl = options.template;
|
|
1725
|
+
}
|
|
1726
|
+
if (resolvedTemplateUrl) {
|
|
1727
|
+
const cnaConfig = await (0, import_core.loadTemplateCnaConfig)(resolvedTemplateUrl);
|
|
1728
|
+
if (cnaConfig?.customOptions) {
|
|
1729
|
+
for (const opt of cnaConfig.customOptions) {
|
|
1730
|
+
if (opt.name && opt.initial !== void 0) {
|
|
1731
|
+
options[opt.name] = opt.initial;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1723
1735
|
}
|
|
1736
|
+
Object.assign(options, setOverrides);
|
|
1724
1737
|
if (options.addons && Array.isArray(options.addons)) {
|
|
1725
1738
|
const extensionsGroupedByCategory = await getExtensionsGroupedByCategory([
|
|
1726
1739
|
matchedTemplate?.type || "custom",
|
|
@@ -1758,6 +1771,9 @@ var processNonInteractiveOptions = async (options) => {
|
|
|
1758
1771
|
return options;
|
|
1759
1772
|
};
|
|
1760
1773
|
var processInteractiveOptions = async (options) => {
|
|
1774
|
+
const { setOverrides = {}, ...restOptions } = options;
|
|
1775
|
+
options = restOptions;
|
|
1776
|
+
import_prompts.default.override({ ...options, ...setOverrides });
|
|
1761
1777
|
const categories = await getTemplateCategories();
|
|
1762
1778
|
const categoryDataPromises = categories.map(async (categorySlug) => {
|
|
1763
1779
|
const categoryData = await getCategoryData(categorySlug);
|
|
@@ -1844,7 +1860,11 @@ var processInteractiveOptions = async (options) => {
|
|
|
1844
1860
|
(template) => template.url === templateInput.template
|
|
1845
1861
|
);
|
|
1846
1862
|
const templateTemplateOrExtension = templateInput.template;
|
|
1847
|
-
const
|
|
1863
|
+
const cnaConfig = templateTemplateOrExtension ? await (0, import_core.loadTemplateCnaConfig)(templateTemplateOrExtension) : null;
|
|
1864
|
+
const rawCustomOptions = cnaConfig?.customOptions ?? existingTemplate?.customOptions ?? [];
|
|
1865
|
+
const customOptions = rawCustomOptions.map(
|
|
1866
|
+
(opt) => opt.name && Object.prototype.hasOwnProperty.call(setOverrides, opt.name) ? { ...opt, initial: setOverrides[opt.name] } : opt
|
|
1867
|
+
);
|
|
1848
1868
|
const appConfig = await (0, import_prompts.default)([
|
|
1849
1869
|
// The following prompts are placeholders for future inputs
|
|
1850
1870
|
{
|
|
@@ -1922,6 +1942,8 @@ var processInteractiveOptions = async (options) => {
|
|
|
1922
1942
|
...nextAppOptions.extend || []
|
|
1923
1943
|
].filter(Boolean).map((templateOrExtension) => ({ url: templateOrExtension }));
|
|
1924
1944
|
const nextOptions = { ...nextAppOptions, templatesOrExtensions };
|
|
1945
|
+
Object.assign(nextOptions, setOverrides);
|
|
1946
|
+
delete nextOptions.setOverrides;
|
|
1925
1947
|
if (nextAppOptions.verbose) {
|
|
1926
1948
|
console.log(JSON.stringify(nextOptions, null, 2));
|
|
1927
1949
|
}
|
|
@@ -1941,10 +1963,41 @@ var getCnaOptions = async (options) => {
|
|
|
1941
1963
|
return processNonInteractiveOptions(options);
|
|
1942
1964
|
};
|
|
1943
1965
|
|
|
1966
|
+
// src/set-overrides.ts
|
|
1967
|
+
var unquoteSetValue = (value) => {
|
|
1968
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1969
|
+
return value.slice(1, -1);
|
|
1970
|
+
}
|
|
1971
|
+
return value;
|
|
1972
|
+
};
|
|
1973
|
+
var parseSetOverrides = (set) => {
|
|
1974
|
+
const setOverrides = {};
|
|
1975
|
+
if (!Array.isArray(set)) {
|
|
1976
|
+
return setOverrides;
|
|
1977
|
+
}
|
|
1978
|
+
const assignments = [];
|
|
1979
|
+
for (const part of set) {
|
|
1980
|
+
if (part.includes("=") || assignments.length === 0) {
|
|
1981
|
+
assignments.push(part);
|
|
1982
|
+
} else {
|
|
1983
|
+
assignments[assignments.length - 1] += ` ${part}`;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
for (const assignment of assignments) {
|
|
1987
|
+
const eqIdx = assignment.indexOf("=");
|
|
1988
|
+
if (eqIdx > 0) {
|
|
1989
|
+
setOverrides[assignment.slice(0, eqIdx).trim()] = unquoteSetValue(
|
|
1990
|
+
assignment.slice(eqIdx + 1).trim()
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
return setOverrides;
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1944
1997
|
// package.json
|
|
1945
1998
|
var package_default = {
|
|
1946
1999
|
name: "create-awesome-node-app",
|
|
1947
|
-
version: "0.
|
|
2000
|
+
version: "0.9.0",
|
|
1948
2001
|
type: "module",
|
|
1949
2002
|
description: "Command line tool to create Node apps with a lot of different templates and extensions.",
|
|
1950
2003
|
license: "MIT",
|
|
@@ -1998,27 +2051,22 @@ var package_default = {
|
|
|
1998
2051
|
"test:src": "npm run test"
|
|
1999
2052
|
},
|
|
2000
2053
|
dependencies: {
|
|
2001
|
-
"@create-node-app/core": "^0.
|
|
2002
|
-
axios: "^1.
|
|
2054
|
+
"@create-node-app/core": "^0.6.0",
|
|
2055
|
+
axios: "^1.16.0",
|
|
2003
2056
|
"ci-info": "^4.3.0",
|
|
2004
|
-
commander: "^14.0.
|
|
2057
|
+
commander: "^14.0.3",
|
|
2005
2058
|
prompts: "^2.4.2",
|
|
2006
|
-
semver: "^7.7.
|
|
2007
|
-
yargs: "^18.0.0"
|
|
2059
|
+
semver: "^7.7.4"
|
|
2008
2060
|
},
|
|
2009
2061
|
devDependencies: {
|
|
2010
|
-
"@create-node-app/core": "^0.
|
|
2011
|
-
"@
|
|
2012
|
-
"@types/node": "^24.5.2",
|
|
2062
|
+
"@create-node-app/core": "^0.6.0",
|
|
2063
|
+
"@types/node": "^26.0.1",
|
|
2013
2064
|
"@types/prompts": "^2.4.9",
|
|
2014
2065
|
"@types/semver": "^7.5.8",
|
|
2015
|
-
"@types/yargs": "^17.0.33",
|
|
2016
2066
|
eslint: "^9.35.0",
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
tsup: "^8.5.0",
|
|
2021
|
-
tsx: "^4.19.0"
|
|
2067
|
+
nock: "^14.0.15",
|
|
2068
|
+
tsup: "^8.5.1",
|
|
2069
|
+
tsx: "^4.22.4"
|
|
2022
2070
|
}
|
|
2023
2071
|
};
|
|
2024
2072
|
|
|
@@ -2111,20 +2159,23 @@ var main = async () => {
|
|
|
2111
2159
|
).option(
|
|
2112
2160
|
"--addons [extensions...]",
|
|
2113
2161
|
"specify extensions to apply for the boilerplate generation"
|
|
2114
|
-
).option("--use-yarn", "use yarn instead of npm or pnpm").option("--use-pnpm", "use pnpm instead of yarn or npm").option(
|
|
2162
|
+
).option("--use-yarn", "use yarn instead of npm or pnpm or bun").option("--use-pnpm", "use pnpm instead of yarn, npm, or bun").option("--use-bun", "use bun instead of npm, yarn, or pnpm").option(
|
|
2115
2163
|
"--interactive",
|
|
2116
2164
|
"force interactive mode (default outside CI unless --no-interactive)",
|
|
2117
2165
|
void 0
|
|
2118
2166
|
).option(
|
|
2119
2167
|
"--no-interactive",
|
|
2120
2168
|
"disable interactive mode (use only flags / non-interactive flow)"
|
|
2121
|
-
).option("--list-templates", "list all available templates").option("--list-addons", "list all available addons").
|
|
2169
|
+
).option("--list-templates", "list all available templates").option("--list-addons", "list all available addons").option(
|
|
2170
|
+
"--set <assignments...>",
|
|
2171
|
+
"set a custom template option (format: key=value; quote values with spaces: --set 'projectName=My App' or --set 'projectName=My App' --set 'author=Jane Doe')"
|
|
2172
|
+
).action((providedProjectName) => {
|
|
2122
2173
|
projectName = providedProjectName || projectName;
|
|
2123
2174
|
});
|
|
2124
2175
|
program.parse(process.argv);
|
|
2125
2176
|
const opts = program.opts();
|
|
2126
|
-
(0,
|
|
2127
|
-
const latestVersion = await (0,
|
|
2177
|
+
(0, import_core2.checkNodeVersion)(package_default.engines.node, package_default.name);
|
|
2178
|
+
const latestVersion = await (0, import_core2.checkForLatestVersion)("create-awesome-node-app");
|
|
2128
2179
|
if (latestVersion && import_semver.default.lt(package_default.version, latestVersion)) {
|
|
2129
2180
|
console.log();
|
|
2130
2181
|
console.error(
|
|
@@ -2146,15 +2197,22 @@ We recommend always using the latest version of create-awesome-node-app if possi
|
|
|
2146
2197
|
});
|
|
2147
2198
|
return;
|
|
2148
2199
|
}
|
|
2149
|
-
const { useYarn, usePnpm, ...restOpts } = opts;
|
|
2150
|
-
const packageManager = useYarn ? "yarn" : usePnpm ? "pnpm" : "npm";
|
|
2200
|
+
const { useYarn, usePnpm, useBun, set, ...restOpts } = opts;
|
|
2201
|
+
const packageManager = useYarn ? "yarn" : usePnpm ? "pnpm" : useBun ? "bun" : "npm";
|
|
2202
|
+
const setOverrides = parseSetOverrides(set);
|
|
2151
2203
|
const templatesOrExtensions = [restOpts.template].concat(Array.isArray(restOpts.extend) ? restOpts.extend : []).filter(Boolean).reduce((acc, templateOrExtension) => {
|
|
2152
2204
|
if (!templateOrExtension) return acc;
|
|
2153
2205
|
return acc.concat({ url: templateOrExtension });
|
|
2154
2206
|
}, []);
|
|
2155
|
-
return (0,
|
|
2207
|
+
return (0, import_core2.createNodeApp)(
|
|
2156
2208
|
projectName,
|
|
2157
|
-
{
|
|
2209
|
+
{
|
|
2210
|
+
...restOpts,
|
|
2211
|
+
packageManager,
|
|
2212
|
+
templatesOrExtensions,
|
|
2213
|
+
projectName,
|
|
2214
|
+
setOverrides
|
|
2215
|
+
},
|
|
2158
2216
|
getCnaOptions
|
|
2159
2217
|
);
|
|
2160
2218
|
};
|