create-nextly-app 0.0.2-alpha.57 → 0.0.2-alpha.58
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/{chunk-6434MGWG.mjs → chunk-E6IFBI6N.mjs} +141 -18
- package/dist/chunk-E6IFBI6N.mjs.map +1 -0
- package/dist/cli.cjs +140 -17
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +139 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -4
- package/templates/base/gitignore +42 -0
- package/templates/base/src/app/globals.css +10 -0
- package/templates/base/src/app/layout.tsx +24 -19
- package/templates/base/tsconfig.json +7 -1
- package/templates/blank/src/app/globals.css +32 -0
- package/templates/blank/src/app/layout.tsx +26 -15
- package/templates/plugin/gitignore +10 -0
- package/dist/chunk-6434MGWG.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -6259,7 +6259,7 @@ var require_package = __commonJS({
|
|
|
6259
6259
|
"package.json"(exports$1, module) {
|
|
6260
6260
|
module.exports = {
|
|
6261
6261
|
name: "create-nextly-app",
|
|
6262
|
-
version: "0.0.2-alpha.
|
|
6262
|
+
version: "0.0.2-alpha.58",
|
|
6263
6263
|
description: "CLI to scaffold Nextly in your Next.js project",
|
|
6264
6264
|
license: "MIT",
|
|
6265
6265
|
type: "module",
|
|
@@ -28670,6 +28670,47 @@ var import_fs_extra8 = __toESM(require_lib());
|
|
|
28670
28670
|
var PROJECT_TYPES_WITH_FORM_BUILDER = /* @__PURE__ */ new Set([
|
|
28671
28671
|
"blog"
|
|
28672
28672
|
]);
|
|
28673
|
+
var FONT_PACKAGE_RANGE = "^5.3.0";
|
|
28674
|
+
var FONT_PACKAGE_PATTERN = /@fontsource(?:-variable)?\/[a-z0-9-]+/g;
|
|
28675
|
+
async function collectFontDependencies(templateDirs) {
|
|
28676
|
+
const effective = await effectiveTemplateFiles(templateDirs);
|
|
28677
|
+
const found = /* @__PURE__ */ new Set();
|
|
28678
|
+
for (const file of effective.values()) {
|
|
28679
|
+
const contents = await import_fs_extra8.default.readFile(file, "utf8");
|
|
28680
|
+
for (const match of contents.matchAll(FONT_PACKAGE_PATTERN)) {
|
|
28681
|
+
found.add(match[0]);
|
|
28682
|
+
}
|
|
28683
|
+
}
|
|
28684
|
+
return [...found].sort();
|
|
28685
|
+
}
|
|
28686
|
+
async function effectiveTemplateFiles(templateDirs) {
|
|
28687
|
+
const effective = /* @__PURE__ */ new Map();
|
|
28688
|
+
for (const root of templateDirs) {
|
|
28689
|
+
if (!root || !await import_fs_extra8.default.pathExists(root)) continue;
|
|
28690
|
+
for (const file of await walkSourceFiles(root)) {
|
|
28691
|
+
effective.set(path15__default.default.relative(root, file), file);
|
|
28692
|
+
}
|
|
28693
|
+
}
|
|
28694
|
+
return effective;
|
|
28695
|
+
}
|
|
28696
|
+
var SEARCH_INDEX_SCRIPT = path15__default.default.join("scripts", "build-search-index.mjs");
|
|
28697
|
+
async function projectHasSearchIndexScript(targetDir) {
|
|
28698
|
+
return import_fs_extra8.default.pathExists(path15__default.default.join(targetDir, SEARCH_INDEX_SCRIPT));
|
|
28699
|
+
}
|
|
28700
|
+
async function walkSourceFiles(root) {
|
|
28701
|
+
const out = [];
|
|
28702
|
+
const entries = await import_fs_extra8.default.readdir(root, { withFileTypes: true });
|
|
28703
|
+
for (const entry of entries) {
|
|
28704
|
+
const full = path15__default.default.join(root, entry.name);
|
|
28705
|
+
if (entry.isDirectory()) {
|
|
28706
|
+
if (entry.name === "node_modules" || entry.name === ".next") continue;
|
|
28707
|
+
out.push(...await walkSourceFiles(full));
|
|
28708
|
+
} else if (/\.(?:tsx?|jsx?|mjs|cjs|css)$/.test(entry.name)) {
|
|
28709
|
+
out.push(full);
|
|
28710
|
+
}
|
|
28711
|
+
}
|
|
28712
|
+
return out;
|
|
28713
|
+
}
|
|
28673
28714
|
function projectUsesFormBuilder(projectType) {
|
|
28674
28715
|
return PROJECT_TYPES_WITH_FORM_BUILDER.has(projectType);
|
|
28675
28716
|
}
|
|
@@ -28691,6 +28732,15 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
28691
28732
|
".cjs"
|
|
28692
28733
|
]);
|
|
28693
28734
|
var SKIP_FILES = /* @__PURE__ */ new Set([".DS_Store", "Thumbs.db", ".gitkeep"]);
|
|
28735
|
+
var IGNORE_FILE_IN_TEMPLATE = "gitignore";
|
|
28736
|
+
var IGNORE_FILE_IN_PROJECT = ".gitignore";
|
|
28737
|
+
async function restoreIgnoreFile(targetDir) {
|
|
28738
|
+
const shipped = path15__default.default.join(targetDir, IGNORE_FILE_IN_TEMPLATE);
|
|
28739
|
+
if (!await import_fs_extra8.default.pathExists(shipped)) return;
|
|
28740
|
+
await import_fs_extra8.default.move(shipped, path15__default.default.join(targetDir, IGNORE_FILE_IN_PROJECT), {
|
|
28741
|
+
overwrite: true
|
|
28742
|
+
});
|
|
28743
|
+
}
|
|
28694
28744
|
function resolveTemplatePath(localTemplatePath) {
|
|
28695
28745
|
const __dirname = path15__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href))));
|
|
28696
28746
|
const fromDist = path15__default.default.resolve(__dirname, "../templates");
|
|
@@ -28814,7 +28864,7 @@ async function resolveRuntimeVersions() {
|
|
|
28814
28864
|
resolvedRuntimeVersions = Object.fromEntries(entries);
|
|
28815
28865
|
return resolvedRuntimeVersions;
|
|
28816
28866
|
}
|
|
28817
|
-
async function generatePackageJson(projectName, database, useYalc = false, projectType = "blank") {
|
|
28867
|
+
async function generatePackageJson(projectName, database, useYalc = false, projectType = "blank", templateDirs = [], targetDir) {
|
|
28818
28868
|
if (projectType === "plugin") {
|
|
28819
28869
|
return generatePluginPackageJson(projectName, useYalc);
|
|
28820
28870
|
}
|
|
@@ -28826,6 +28876,9 @@ async function generatePackageJson(projectName, database, useYalc = false, proje
|
|
|
28826
28876
|
};
|
|
28827
28877
|
dependencies["@tanstack/react-query"] = "^5.62.0";
|
|
28828
28878
|
dependencies["lucide-react"] = "^0.544.0";
|
|
28879
|
+
for (const font of await collectFontDependencies(templateDirs)) {
|
|
28880
|
+
dependencies[font] = FONT_PACKAGE_RANGE;
|
|
28881
|
+
}
|
|
28829
28882
|
if (!useYalc) {
|
|
28830
28883
|
const versions = await resolveNextlyVersions(
|
|
28831
28884
|
templateNextlyChannel(projectType)
|
|
@@ -28848,12 +28901,10 @@ async function generatePackageJson(projectName, database, useYalc = false, proje
|
|
|
28848
28901
|
"@tailwindcss/postcss": PINNED_VERSIONS["@tailwindcss/postcss"],
|
|
28849
28902
|
tailwindcss: PINNED_VERSIONS.tailwindcss,
|
|
28850
28903
|
eslint: PINNED_VERSIONS.eslint,
|
|
28851
|
-
"eslint-config-next": runtimeVersions["eslint-config-next"]
|
|
28852
|
-
// Pagefind powers /search in the blog template. Zero-config
|
|
28853
|
-
// static index generated at `next build` time. Templates that
|
|
28854
|
-
// don't ship a /search page simply won't invoke it.
|
|
28855
|
-
pagefind: "^1.1.0"
|
|
28904
|
+
"eslint-config-next": runtimeVersions["eslint-config-next"]
|
|
28856
28905
|
};
|
|
28906
|
+
const shipsSearchIndex = targetDir ? await projectHasSearchIndexScript(targetDir) : false;
|
|
28907
|
+
if (shipsSearchIndex) devDependencies.pagefind = "^1.1.0";
|
|
28857
28908
|
const pkg2 = {
|
|
28858
28909
|
name: projectName,
|
|
28859
28910
|
version: "0.1.0",
|
|
@@ -28865,11 +28916,25 @@ async function generatePackageJson(projectName, database, useYalc = false, proje
|
|
|
28865
28916
|
// prompts, and child supervision. `nextly dev` is gone; the only
|
|
28866
28917
|
// supported dev command is the standard `next dev`.
|
|
28867
28918
|
dev: "next dev --turbopack",
|
|
28868
|
-
// Build: migrate
|
|
28869
|
-
//
|
|
28870
|
-
//
|
|
28871
|
-
|
|
28872
|
-
|
|
28919
|
+
// Build: migrate the database, compile Next.js, and generate the Pagefind
|
|
28920
|
+
// search index for the templates that ship its builder.
|
|
28921
|
+
//
|
|
28922
|
+
// Whether that last step appears is decided HERE, from the files the
|
|
28923
|
+
// scaffold actually received, rather than by a shell conditional in the
|
|
28924
|
+
// script. Two reasons, and both were live:
|
|
28925
|
+
//
|
|
28926
|
+
// `npm run` uses cmd.exe on Windows, which has no `test` and no `true` —
|
|
28927
|
+
// so the `(test -f … || true)` form this replaces failed for every Windows
|
|
28928
|
+
// user, after `next build` had already succeeded. `&&` is all that remains,
|
|
28929
|
+
// and cmd.exe understands it.
|
|
28930
|
+
//
|
|
28931
|
+
// And `|| true` turned a failed index build into a successful one. The
|
|
28932
|
+
// search page then ships pointing at an index that was never written,
|
|
28933
|
+
// which fails in the browser rather than in CI.
|
|
28934
|
+
build: shipsSearchIndex ? "nextly migrate && next build && node scripts/build-search-index.mjs" : "nextly migrate && next build",
|
|
28935
|
+
// Offered only where the file exists. A script that always fails is worse
|
|
28936
|
+
// than an absent one: it reads as a supported command.
|
|
28937
|
+
...shipsSearchIndex ? { "search:index": "node scripts/build-search-index.mjs" } : {},
|
|
28873
28938
|
start: "next start",
|
|
28874
28939
|
lint: "next lint",
|
|
28875
28940
|
nextly: "nextly",
|
|
@@ -28879,8 +28944,11 @@ async function generatePackageJson(projectName, database, useYalc = false, proje
|
|
|
28879
28944
|
"db:setup": "nextly db:sync",
|
|
28880
28945
|
"db:migrate": "nextly migrate",
|
|
28881
28946
|
"db:migrate:status": "nextly migrate:status",
|
|
28947
|
+
// No `db:migrate:reset`: `nextly migrate:reset` is not a command the CLI
|
|
28948
|
+
// registers, so the script it generated failed for every scaffolded
|
|
28949
|
+
// project. `migrate:fresh` is the one that drops all tables and re-runs
|
|
28950
|
+
// the migrations, and it is already exposed above.
|
|
28882
28951
|
"db:migrate:fresh": "nextly migrate:fresh",
|
|
28883
|
-
"db:migrate:reset": "nextly migrate:reset",
|
|
28884
28952
|
"types:generate": "nextly generate:types"
|
|
28885
28953
|
},
|
|
28886
28954
|
dependencies,
|
|
@@ -28982,13 +29050,46 @@ function generatePnpmWorkspaceYaml() {
|
|
|
28982
29050
|
# compiled binding (sqlite apps crash at boot) and sharp/esbuild degrade.
|
|
28983
29051
|
#
|
|
28984
29052
|
# pnpm 11+ reads \`allowBuilds\`; pnpm 10.6+ reads \`onlyBuiltDependencies\`.
|
|
28985
|
-
# npm
|
|
29053
|
+
# npm and yarn ignore this file; pnpm 9 needs neither key, because it runs
|
|
29054
|
+
# build scripts by default.
|
|
29055
|
+
#
|
|
29056
|
+
# It does still READ the file, which is what the empty \`packages\` list is
|
|
29057
|
+
# for: through pnpm 9.3 the presence of this file declares a workspace, and
|
|
29058
|
+
# a missing \`packages\` key fails the install outright. This app has no
|
|
29059
|
+
# workspace members.
|
|
29060
|
+
packages: []
|
|
28986
29061
|
allowBuilds:
|
|
28987
29062
|
${allowBuilds}
|
|
28988
29063
|
onlyBuiltDependencies:
|
|
28989
29064
|
${onlyBuilt}
|
|
28990
29065
|
`;
|
|
28991
29066
|
}
|
|
29067
|
+
function generateNpmrc(packageManager) {
|
|
29068
|
+
if (packageManager !== "pnpm") return null;
|
|
29069
|
+
return `# This project is a single package, not a monorepo. pnpm 9 treats the
|
|
29070
|
+
# pnpm-workspace.yaml shipped for its build allowlist as declaring a
|
|
29071
|
+
# workspace root, which makes \`pnpm add <pkg>\` demand a -w flag. There is no
|
|
29072
|
+
# other package here for that check to protect.
|
|
29073
|
+
${NPMRC_WORKSPACE_ROOT_KEY}=true
|
|
29074
|
+
`;
|
|
29075
|
+
}
|
|
29076
|
+
var NPMRC_WORKSPACE_ROOT_KEY = "ignore-workspace-root-check";
|
|
29077
|
+
async function writeScaffoldNpmrc(targetDir, packageManager) {
|
|
29078
|
+
const addition = generateNpmrc(packageManager);
|
|
29079
|
+
if (!addition) return;
|
|
29080
|
+
const npmrcPath = path15__default.default.join(targetDir, ".npmrc");
|
|
29081
|
+
const link = await import_fs_extra8.default.lstat(npmrcPath).catch(() => null);
|
|
29082
|
+
if (link?.isSymbolicLink()) return;
|
|
29083
|
+
if (link && link.nlink > 1) return;
|
|
29084
|
+
const existing = link ? await import_fs_extra8.default.readFile(npmrcPath, "utf-8") : "";
|
|
29085
|
+
const alreadyDeclared = new RegExp(
|
|
29086
|
+
`^\\s*${NPMRC_WORKSPACE_ROOT_KEY}\\s*=`,
|
|
29087
|
+
"m"
|
|
29088
|
+
).test(existing);
|
|
29089
|
+
if (alreadyDeclared) return;
|
|
29090
|
+
const separator = existing === "" || existing.endsWith("\n") ? "" : "\n";
|
|
29091
|
+
await import_fs_extra8.default.writeFile(npmrcPath, existing + separator + addition, "utf-8");
|
|
29092
|
+
}
|
|
28992
29093
|
async function copyTemplate(options) {
|
|
28993
29094
|
const {
|
|
28994
29095
|
projectName,
|
|
@@ -28999,6 +29100,7 @@ async function copyTemplate(options) {
|
|
|
28999
29100
|
useYalc = false,
|
|
29000
29101
|
approach,
|
|
29001
29102
|
templateSource,
|
|
29103
|
+
packageManager,
|
|
29002
29104
|
allowExistingTarget = false
|
|
29003
29105
|
} = options;
|
|
29004
29106
|
if (!allowExistingTarget && targetDir !== process.cwd() && await import_fs_extra8.default.pathExists(targetDir)) {
|
|
@@ -29017,7 +29119,13 @@ async function copyTemplate(options) {
|
|
|
29017
29119
|
typeDir = path15__default.default.join(templatesRoot, projectType);
|
|
29018
29120
|
}
|
|
29019
29121
|
if (projectType === "plugin") {
|
|
29020
|
-
await copyPluginTemplate({
|
|
29122
|
+
await copyPluginTemplate({
|
|
29123
|
+
projectName,
|
|
29124
|
+
typeDir,
|
|
29125
|
+
targetDir,
|
|
29126
|
+
useYalc,
|
|
29127
|
+
packageManager
|
|
29128
|
+
});
|
|
29021
29129
|
return;
|
|
29022
29130
|
}
|
|
29023
29131
|
if (!await import_fs_extra8.default.pathExists(baseDir)) {
|
|
@@ -29076,6 +29184,13 @@ async function copyTemplate(options) {
|
|
|
29076
29184
|
overwrite: false
|
|
29077
29185
|
});
|
|
29078
29186
|
}
|
|
29187
|
+
const templateScriptsDir = path15__default.default.join(typeDir, "scripts");
|
|
29188
|
+
if (await import_fs_extra8.default.pathExists(templateScriptsDir)) {
|
|
29189
|
+
await import_fs_extra8.default.copy(templateScriptsDir, path15__default.default.join(targetDir, "scripts"), {
|
|
29190
|
+
overwrite: false,
|
|
29191
|
+
filter: (src) => !SKIP_FILES.has(path15__default.default.basename(src))
|
|
29192
|
+
});
|
|
29193
|
+
}
|
|
29079
29194
|
const frontendPagePath = path15__default.default.join(
|
|
29080
29195
|
targetDir,
|
|
29081
29196
|
"src",
|
|
@@ -29091,7 +29206,9 @@ async function copyTemplate(options) {
|
|
|
29091
29206
|
projectName,
|
|
29092
29207
|
database,
|
|
29093
29208
|
useYalc,
|
|
29094
|
-
projectType
|
|
29209
|
+
projectType,
|
|
29210
|
+
[baseDir, typeDir],
|
|
29211
|
+
targetDir
|
|
29095
29212
|
);
|
|
29096
29213
|
await import_fs_extra8.default.writeFile(
|
|
29097
29214
|
path15__default.default.join(targetDir, "package.json"),
|
|
@@ -29103,6 +29220,8 @@ async function copyTemplate(options) {
|
|
|
29103
29220
|
generatePnpmWorkspaceYaml(),
|
|
29104
29221
|
"utf-8"
|
|
29105
29222
|
);
|
|
29223
|
+
await restoreIgnoreFile(targetDir);
|
|
29224
|
+
await writeScaffoldNpmrc(targetDir, packageManager);
|
|
29106
29225
|
if (database.type === "sqlite") {
|
|
29107
29226
|
await import_fs_extra8.default.ensureDir(path15__default.default.join(targetDir, "data"));
|
|
29108
29227
|
}
|
|
@@ -29118,7 +29237,7 @@ async function copyTemplate(options) {
|
|
|
29118
29237
|
await replacePlaceholders(targetDir, placeholders);
|
|
29119
29238
|
}
|
|
29120
29239
|
async function copyPluginTemplate(opts) {
|
|
29121
|
-
const { projectName, typeDir, targetDir, useYalc } = opts;
|
|
29240
|
+
const { projectName, typeDir, targetDir, useYalc, packageManager } = opts;
|
|
29122
29241
|
if (!await import_fs_extra8.default.pathExists(typeDir)) {
|
|
29123
29242
|
throw new Error(
|
|
29124
29243
|
`Plugin template not found at ${typeDir}. The package may be corrupted or the download failed.`
|
|
@@ -29147,6 +29266,8 @@ async function copyPluginTemplate(opts) {
|
|
|
29147
29266
|
generatePnpmWorkspaceYaml(),
|
|
29148
29267
|
"utf-8"
|
|
29149
29268
|
);
|
|
29269
|
+
await restoreIgnoreFile(targetDir);
|
|
29270
|
+
await writeScaffoldNpmrc(targetDir, packageManager);
|
|
29150
29271
|
const nextlyRange = await resolvePluginNextlyRange(useYalc);
|
|
29151
29272
|
await replacePlaceholders(
|
|
29152
29273
|
targetDir,
|
|
@@ -32727,6 +32848,7 @@ async function createNextly(options = {}) {
|
|
|
32727
32848
|
} else {
|
|
32728
32849
|
s3.start("Scaffolding project...");
|
|
32729
32850
|
}
|
|
32851
|
+
const scaffoldPackageManager = await detectPackageManager2(targetDir);
|
|
32730
32852
|
await copyTemplate({
|
|
32731
32853
|
projectName,
|
|
32732
32854
|
projectType,
|
|
@@ -32736,6 +32858,7 @@ async function createNextly(options = {}) {
|
|
|
32736
32858
|
useYalc,
|
|
32737
32859
|
approach,
|
|
32738
32860
|
templateSource,
|
|
32861
|
+
packageManager: scaffoldPackageManager,
|
|
32739
32862
|
// Suppress copyTemplate's "directory already exists" guard when the
|
|
32740
32863
|
// installer has already negotiated the conflict with the user
|
|
32741
32864
|
// (either by emptying the dir or accepting an overlay). Without
|