create-nextly-app 0.0.2-alpha.4 → 0.0.2-alpha.6
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-AYJ2RKVJ.mjs → chunk-6NVRVAZA.mjs} +431 -422
- package/dist/chunk-6NVRVAZA.mjs.map +1 -0
- package/dist/cli.cjs +430 -421
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +429 -420
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -4
- package/templates/base/src/app/admin/[[...params]]/page.tsx +0 -9
- package/dist/chunk-AYJ2RKVJ.mjs.map +0 -1
|
@@ -18003,9 +18003,6 @@ var import_fs_extra = __toESM(require_lib(), 1);
|
|
|
18003
18003
|
var ADMIN_PAGE_TEMPLATE = `"use client";
|
|
18004
18004
|
|
|
18005
18005
|
import "@nextlyhq/admin/style.css";
|
|
18006
|
-
import "@nextlyhq/plugin-form-builder/admin";
|
|
18007
|
-
import "@nextlyhq/plugin-form-builder/styles/builder.css";
|
|
18008
|
-
import "@nextlyhq/plugin-form-builder/styles/submissions-filter.css";
|
|
18009
18006
|
import { RootLayout, QueryProvider, ErrorBoundary } from "@nextlyhq/admin";
|
|
18010
18007
|
|
|
18011
18008
|
export default function AdminPage() {
|
|
@@ -24856,6 +24853,316 @@ createExeca(mapNode);
|
|
|
24856
24853
|
createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
24857
24854
|
getIpcExport();
|
|
24858
24855
|
|
|
24856
|
+
// src/utils/template.ts
|
|
24857
|
+
var import_fs_extra8 = __toESM(require_lib(), 1);
|
|
24858
|
+
var PROJECT_TYPES_WITH_FORM_BUILDER = /* @__PURE__ */ new Set([
|
|
24859
|
+
"blog"
|
|
24860
|
+
]);
|
|
24861
|
+
function projectUsesFormBuilder(projectType) {
|
|
24862
|
+
return PROJECT_TYPES_WITH_FORM_BUILDER.has(projectType);
|
|
24863
|
+
}
|
|
24864
|
+
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
24865
|
+
".ts",
|
|
24866
|
+
".tsx",
|
|
24867
|
+
".js",
|
|
24868
|
+
".jsx",
|
|
24869
|
+
".json",
|
|
24870
|
+
".env",
|
|
24871
|
+
".md",
|
|
24872
|
+
".css",
|
|
24873
|
+
".html",
|
|
24874
|
+
".mjs",
|
|
24875
|
+
".cjs"
|
|
24876
|
+
]);
|
|
24877
|
+
var SKIP_FILES = /* @__PURE__ */ new Set([".DS_Store", "Thumbs.db", ".gitkeep"]);
|
|
24878
|
+
function resolveTemplatePath(localTemplatePath) {
|
|
24879
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24880
|
+
const fromDist = path.resolve(__dirname, "../templates");
|
|
24881
|
+
if (import_fs_extra8.default.existsSync(fromDist)) {
|
|
24882
|
+
return fromDist;
|
|
24883
|
+
}
|
|
24884
|
+
const fromSrc = path.resolve(__dirname, "../../templates");
|
|
24885
|
+
if (import_fs_extra8.default.existsSync(fromSrc)) {
|
|
24886
|
+
return fromSrc;
|
|
24887
|
+
}
|
|
24888
|
+
throw new Error(
|
|
24889
|
+
"Could not find templates directory. Use --local-template to specify the templates path, or ensure templates are bundled."
|
|
24890
|
+
);
|
|
24891
|
+
}
|
|
24892
|
+
function buildPlaceholderMap(options) {
|
|
24893
|
+
const { database, databaseUrl } = options;
|
|
24894
|
+
return {
|
|
24895
|
+
"{{databaseDialect}}": database.type,
|
|
24896
|
+
"{{databaseUrl}}": databaseUrl || database.envExample
|
|
24897
|
+
};
|
|
24898
|
+
}
|
|
24899
|
+
async function replacePlaceholdersInFile(filePath, placeholders) {
|
|
24900
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
24901
|
+
const basename = path.basename(filePath);
|
|
24902
|
+
const isTextFile = TEXT_EXTENSIONS.has(ext) || basename.startsWith(".env") || basename === ".gitignore";
|
|
24903
|
+
if (!isTextFile) return;
|
|
24904
|
+
let content = await import_fs_extra8.default.readFile(filePath, "utf-8");
|
|
24905
|
+
let changed = false;
|
|
24906
|
+
for (const [placeholder, value] of Object.entries(placeholders)) {
|
|
24907
|
+
if (content.includes(placeholder)) {
|
|
24908
|
+
content = content.replaceAll(placeholder, value);
|
|
24909
|
+
changed = true;
|
|
24910
|
+
}
|
|
24911
|
+
}
|
|
24912
|
+
if (changed) {
|
|
24913
|
+
await import_fs_extra8.default.writeFile(filePath, content, "utf-8");
|
|
24914
|
+
}
|
|
24915
|
+
}
|
|
24916
|
+
async function replacePlaceholders(dir, placeholders) {
|
|
24917
|
+
const entries = await import_fs_extra8.default.readdir(dir, { withFileTypes: true });
|
|
24918
|
+
for (const entry of entries) {
|
|
24919
|
+
const fullPath = path.join(dir, entry.name);
|
|
24920
|
+
if (entry.isDirectory()) {
|
|
24921
|
+
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
24922
|
+
await replacePlaceholders(fullPath, placeholders);
|
|
24923
|
+
} else if (entry.isFile()) {
|
|
24924
|
+
await replacePlaceholdersInFile(fullPath, placeholders);
|
|
24925
|
+
}
|
|
24926
|
+
}
|
|
24927
|
+
}
|
|
24928
|
+
var PINNED_VERSIONS = {
|
|
24929
|
+
// Next.js ecosystem — resolved at runtime via fetchLatestVersion()
|
|
24930
|
+
// (see generatePackageJson)
|
|
24931
|
+
react: "^19.1.0",
|
|
24932
|
+
"react-dom": "^19.1.0",
|
|
24933
|
+
// Dev dependencies
|
|
24934
|
+
typescript: "^5",
|
|
24935
|
+
"@types/node": "^20",
|
|
24936
|
+
"@types/react": "^19",
|
|
24937
|
+
"@types/react-dom": "^19",
|
|
24938
|
+
"@tailwindcss/postcss": "^4",
|
|
24939
|
+
tailwindcss: "^4",
|
|
24940
|
+
eslint: "^9"
|
|
24941
|
+
};
|
|
24942
|
+
var RUNTIME_RESOLVED_PACKAGES = ["next", "eslint-config-next"];
|
|
24943
|
+
var NEXTLY_PACKAGES = [
|
|
24944
|
+
"nextly",
|
|
24945
|
+
"@nextlyhq/admin",
|
|
24946
|
+
"@nextlyhq/adapter-drizzle",
|
|
24947
|
+
"@nextlyhq/adapter-postgres",
|
|
24948
|
+
"@nextlyhq/adapter-mysql",
|
|
24949
|
+
"@nextlyhq/adapter-sqlite"
|
|
24950
|
+
];
|
|
24951
|
+
var resolvedNextlyVersions = null;
|
|
24952
|
+
async function fetchLatestVersion(pkg) {
|
|
24953
|
+
try {
|
|
24954
|
+
const res = await fetch(
|
|
24955
|
+
`https://registry.npmjs.org/-/package/${encodeURIComponent(pkg)}/dist-tags`,
|
|
24956
|
+
{ signal: AbortSignal.timeout(5e3) }
|
|
24957
|
+
);
|
|
24958
|
+
if (!res.ok) return "latest";
|
|
24959
|
+
const data = await res.json();
|
|
24960
|
+
return data.latest ? `^${data.latest}` : "latest";
|
|
24961
|
+
} catch {
|
|
24962
|
+
return "latest";
|
|
24963
|
+
}
|
|
24964
|
+
}
|
|
24965
|
+
async function resolveNextlyVersions() {
|
|
24966
|
+
if (resolvedNextlyVersions) return resolvedNextlyVersions;
|
|
24967
|
+
const entries = await Promise.all(
|
|
24968
|
+
NEXTLY_PACKAGES.map(
|
|
24969
|
+
async (pkg) => [pkg, await fetchLatestVersion(pkg)]
|
|
24970
|
+
)
|
|
24971
|
+
);
|
|
24972
|
+
resolvedNextlyVersions = Object.fromEntries(entries);
|
|
24973
|
+
return resolvedNextlyVersions;
|
|
24974
|
+
}
|
|
24975
|
+
var resolvedRuntimeVersions = null;
|
|
24976
|
+
async function resolveRuntimeVersions() {
|
|
24977
|
+
if (resolvedRuntimeVersions) return resolvedRuntimeVersions;
|
|
24978
|
+
const FALLBACKS = {
|
|
24979
|
+
next: "^16.1.0",
|
|
24980
|
+
"eslint-config-next": "^16.1.0"
|
|
24981
|
+
};
|
|
24982
|
+
const entries = await Promise.all(
|
|
24983
|
+
RUNTIME_RESOLVED_PACKAGES.map(async (pkg) => {
|
|
24984
|
+
const version2 = await fetchLatestVersion(pkg);
|
|
24985
|
+
return [pkg, version2 === "latest" ? FALLBACKS[pkg] : version2];
|
|
24986
|
+
})
|
|
24987
|
+
);
|
|
24988
|
+
resolvedRuntimeVersions = Object.fromEntries(entries);
|
|
24989
|
+
return resolvedRuntimeVersions;
|
|
24990
|
+
}
|
|
24991
|
+
async function generatePackageJson(projectName, database, useYalc = false, projectType = "blank") {
|
|
24992
|
+
const runtimeVersions = await resolveRuntimeVersions();
|
|
24993
|
+
const dependencies = {
|
|
24994
|
+
next: runtimeVersions.next,
|
|
24995
|
+
react: PINNED_VERSIONS.react,
|
|
24996
|
+
"react-dom": PINNED_VERSIONS["react-dom"]
|
|
24997
|
+
};
|
|
24998
|
+
dependencies["@tanstack/react-query"] = "^5.62.0";
|
|
24999
|
+
if (!useYalc) {
|
|
25000
|
+
const versions = await resolveNextlyVersions();
|
|
25001
|
+
dependencies["nextly"] = versions["nextly"];
|
|
25002
|
+
dependencies["@nextlyhq/admin"] = versions["@nextlyhq/admin"];
|
|
25003
|
+
dependencies["@nextlyhq/ui"] = versions["@nextlyhq/ui"] || "latest";
|
|
25004
|
+
dependencies["@nextlyhq/adapter-drizzle"] = versions["@nextlyhq/adapter-drizzle"];
|
|
25005
|
+
dependencies[database.adapter] = versions[database.adapter] || "latest";
|
|
25006
|
+
if (projectUsesFormBuilder(projectType)) {
|
|
25007
|
+
dependencies["@nextlyhq/plugin-form-builder"] = versions["@nextlyhq/plugin-form-builder"] || "latest";
|
|
25008
|
+
}
|
|
25009
|
+
}
|
|
25010
|
+
const devDependencies = {
|
|
25011
|
+
typescript: PINNED_VERSIONS.typescript,
|
|
25012
|
+
"@types/node": PINNED_VERSIONS["@types/node"],
|
|
25013
|
+
"@types/react": PINNED_VERSIONS["@types/react"],
|
|
25014
|
+
"@types/react-dom": PINNED_VERSIONS["@types/react-dom"],
|
|
25015
|
+
"@tailwindcss/postcss": PINNED_VERSIONS["@tailwindcss/postcss"],
|
|
25016
|
+
tailwindcss: PINNED_VERSIONS.tailwindcss,
|
|
25017
|
+
eslint: PINNED_VERSIONS.eslint,
|
|
25018
|
+
"eslint-config-next": runtimeVersions["eslint-config-next"],
|
|
25019
|
+
// Pagefind powers /search in the blog template. Zero-config
|
|
25020
|
+
// static index generated at `next build` time. Templates that
|
|
25021
|
+
// don't ship a /search page simply won't invoke it.
|
|
25022
|
+
pagefind: "^1.1.0"
|
|
25023
|
+
};
|
|
25024
|
+
const pkg = {
|
|
25025
|
+
name: projectName,
|
|
25026
|
+
version: "0.1.0",
|
|
25027
|
+
private: true,
|
|
25028
|
+
scripts: {
|
|
25029
|
+
// F1 PR 4: dev now boots Nextly in single-process mode via `next dev`.
|
|
25030
|
+
// The lazy drizzle-kit/api import (PR 1) plus the in-process HMR
|
|
25031
|
+
// listener (PR 2) replaced the wrapper that previously owned the
|
|
25032
|
+
// terminal, schema prompts, and child supervision. `nextly dev` is
|
|
25033
|
+
// gone; the only supported dev command is the standard `next dev`.
|
|
25034
|
+
dev: "next dev --turbopack",
|
|
25035
|
+
// Build: migrate DB + compile Next.js + (if present) generate
|
|
25036
|
+
// the Pagefind search index. Templates without the search
|
|
25037
|
+
// script silently skip the last step.
|
|
25038
|
+
build: "nextly migrate && next build && (test -f scripts/build-search-index.mjs && node scripts/build-search-index.mjs || true)",
|
|
25039
|
+
"search:index": "node scripts/build-search-index.mjs",
|
|
25040
|
+
start: "next start",
|
|
25041
|
+
lint: "next lint",
|
|
25042
|
+
nextly: "nextly",
|
|
25043
|
+
// First-time setup: sync schema + seed system permissions. Demo
|
|
25044
|
+
// content is seeded separately from the admin UI (visit /welcome
|
|
25045
|
+
// after running `pnpm dev` and completing /admin/setup).
|
|
25046
|
+
"db:setup": "nextly db:sync",
|
|
25047
|
+
"db:migrate": "nextly migrate",
|
|
25048
|
+
"db:migrate:status": "nextly migrate:status",
|
|
25049
|
+
"db:migrate:fresh": "nextly migrate:fresh",
|
|
25050
|
+
"db:migrate:reset": "nextly migrate:reset",
|
|
25051
|
+
"types:generate": "nextly generate:types"
|
|
25052
|
+
},
|
|
25053
|
+
dependencies,
|
|
25054
|
+
devDependencies
|
|
25055
|
+
};
|
|
25056
|
+
return JSON.stringify(pkg, null, 2) + "\n";
|
|
25057
|
+
}
|
|
25058
|
+
async function copyTemplate(options) {
|
|
25059
|
+
const {
|
|
25060
|
+
projectName,
|
|
25061
|
+
projectType,
|
|
25062
|
+
targetDir,
|
|
25063
|
+
database,
|
|
25064
|
+
databaseUrl,
|
|
25065
|
+
useYalc = false,
|
|
25066
|
+
approach,
|
|
25067
|
+
templateSource
|
|
25068
|
+
} = options;
|
|
25069
|
+
if (targetDir !== process.cwd() && await import_fs_extra8.default.pathExists(targetDir)) {
|
|
25070
|
+
throw new Error(
|
|
25071
|
+
`Directory "${path.basename(targetDir)}" already exists. Please choose a different name.`
|
|
25072
|
+
);
|
|
25073
|
+
}
|
|
25074
|
+
let baseDir;
|
|
25075
|
+
let typeDir;
|
|
25076
|
+
if (templateSource) {
|
|
25077
|
+
baseDir = templateSource.basePath;
|
|
25078
|
+
typeDir = templateSource.templatePath;
|
|
25079
|
+
} else {
|
|
25080
|
+
const templatesRoot = resolveTemplatePath();
|
|
25081
|
+
baseDir = path.join(templatesRoot, "base");
|
|
25082
|
+
typeDir = path.join(templatesRoot, projectType);
|
|
25083
|
+
}
|
|
25084
|
+
if (!await import_fs_extra8.default.pathExists(baseDir)) {
|
|
25085
|
+
throw new Error(
|
|
25086
|
+
`Base template not found at ${baseDir}. The package may be corrupted or the download failed.`
|
|
25087
|
+
);
|
|
25088
|
+
}
|
|
25089
|
+
if (!await import_fs_extra8.default.pathExists(typeDir)) {
|
|
25090
|
+
throw new Error(
|
|
25091
|
+
`Template "${projectType}" not found at ${typeDir}. Available templates: blank, blog.`
|
|
25092
|
+
);
|
|
25093
|
+
}
|
|
25094
|
+
await import_fs_extra8.default.copy(baseDir, targetDir, {
|
|
25095
|
+
filter: (_src) => {
|
|
25096
|
+
const basename = path.basename(_src);
|
|
25097
|
+
return !SKIP_FILES.has(basename);
|
|
25098
|
+
}
|
|
25099
|
+
});
|
|
25100
|
+
const templateSrcDir = path.join(typeDir, "src");
|
|
25101
|
+
if (await import_fs_extra8.default.pathExists(templateSrcDir)) {
|
|
25102
|
+
await import_fs_extra8.default.copy(templateSrcDir, path.join(targetDir, "src"), {
|
|
25103
|
+
overwrite: true,
|
|
25104
|
+
filter: (_src) => {
|
|
25105
|
+
const basename = path.basename(_src);
|
|
25106
|
+
return !SKIP_FILES.has(basename);
|
|
25107
|
+
}
|
|
25108
|
+
});
|
|
25109
|
+
}
|
|
25110
|
+
const templateRootConfig = path.join(typeDir, "nextly.config.ts");
|
|
25111
|
+
if (await import_fs_extra8.default.pathExists(templateRootConfig)) {
|
|
25112
|
+
await import_fs_extra8.default.copy(
|
|
25113
|
+
templateRootConfig,
|
|
25114
|
+
path.join(targetDir, "nextly.config.ts"),
|
|
25115
|
+
{ overwrite: true }
|
|
25116
|
+
);
|
|
25117
|
+
}
|
|
25118
|
+
const configsDir = path.join(typeDir, "configs");
|
|
25119
|
+
if (approach && await import_fs_extra8.default.pathExists(configsDir)) {
|
|
25120
|
+
const configFileName = approach === "code-first" ? "codefirst.config.ts" : `${approach}.config.ts`;
|
|
25121
|
+
const configSrc = path.join(configsDir, configFileName);
|
|
25122
|
+
if (await import_fs_extra8.default.pathExists(configSrc)) {
|
|
25123
|
+
await import_fs_extra8.default.copy(configSrc, path.join(targetDir, "nextly.config.ts"), {
|
|
25124
|
+
overwrite: true
|
|
25125
|
+
});
|
|
25126
|
+
}
|
|
25127
|
+
const sharedSrc = path.join(configsDir, "shared.ts");
|
|
25128
|
+
if (await import_fs_extra8.default.pathExists(sharedSrc)) {
|
|
25129
|
+
await import_fs_extra8.default.copy(sharedSrc, path.join(targetDir, "shared.ts"), {
|
|
25130
|
+
overwrite: true
|
|
25131
|
+
});
|
|
25132
|
+
}
|
|
25133
|
+
}
|
|
25134
|
+
const frontendPagePath = path.join(
|
|
25135
|
+
targetDir,
|
|
25136
|
+
"src",
|
|
25137
|
+
"app",
|
|
25138
|
+
"(frontend)",
|
|
25139
|
+
"page.tsx"
|
|
25140
|
+
);
|
|
25141
|
+
const basePagePath = path.join(targetDir, "src", "app", "page.tsx");
|
|
25142
|
+
if (await import_fs_extra8.default.pathExists(frontendPagePath) && await import_fs_extra8.default.pathExists(basePagePath)) {
|
|
25143
|
+
await import_fs_extra8.default.remove(basePagePath);
|
|
25144
|
+
}
|
|
25145
|
+
const packageJsonContent = await generatePackageJson(
|
|
25146
|
+
projectName,
|
|
25147
|
+
database,
|
|
25148
|
+
useYalc,
|
|
25149
|
+
projectType
|
|
25150
|
+
);
|
|
25151
|
+
await import_fs_extra8.default.writeFile(
|
|
25152
|
+
path.join(targetDir, "package.json"),
|
|
25153
|
+
packageJsonContent,
|
|
25154
|
+
"utf-8"
|
|
25155
|
+
);
|
|
25156
|
+
if (database.type === "sqlite") {
|
|
25157
|
+
await import_fs_extra8.default.ensureDir(path.join(targetDir, "data"));
|
|
25158
|
+
}
|
|
25159
|
+
const placeholders = buildPlaceholderMap({ database, databaseUrl });
|
|
25160
|
+
if (approach) {
|
|
25161
|
+
placeholders["{{approach}}"] = approach;
|
|
25162
|
+
}
|
|
25163
|
+
await replacePlaceholders(targetDir, placeholders);
|
|
25164
|
+
}
|
|
25165
|
+
|
|
24859
25166
|
// src/installers/dependencies.ts
|
|
24860
25167
|
var INSTALL_COMMANDS = {
|
|
24861
25168
|
npm: ["npm", "install"],
|
|
@@ -24875,14 +25182,16 @@ var ALL_ADAPTER_PACKAGES = [
|
|
|
24875
25182
|
"@nextlyhq/adapter-mysql",
|
|
24876
25183
|
"@nextlyhq/adapter-sqlite"
|
|
24877
25184
|
];
|
|
24878
|
-
var TEMPLATE_PLUGIN_PACKAGES = [
|
|
24879
|
-
|
|
24880
|
-
];
|
|
25185
|
+
var TEMPLATE_PLUGIN_PACKAGES = ["@nextlyhq/plugin-form-builder"];
|
|
25186
|
+
function templatePluginPackages(projectType) {
|
|
25187
|
+
return projectType && projectUsesFormBuilder(projectType) ? TEMPLATE_PLUGIN_PACKAGES : [];
|
|
25188
|
+
}
|
|
24881
25189
|
function getPackagesToInstall(database) {
|
|
24882
25190
|
return [...CORE_PACKAGES, database.adapter];
|
|
24883
25191
|
}
|
|
24884
|
-
async function installDependencies(cwd, projectInfo, database, useYalc = false, isFreshProject = false) {
|
|
25192
|
+
async function installDependencies(cwd, projectInfo, database, useYalc = false, isFreshProject = false, projectType) {
|
|
24885
25193
|
const pm = projectInfo.packageManager;
|
|
25194
|
+
const pluginPackages = templatePluginPackages(projectType);
|
|
24886
25195
|
if (isFreshProject) {
|
|
24887
25196
|
if (useYalc) {
|
|
24888
25197
|
const yalcPackages = [
|
|
@@ -24892,7 +25201,7 @@ async function installDependencies(cwd, projectInfo, database, useYalc = false,
|
|
|
24892
25201
|
"@nextlyhq/ui",
|
|
24893
25202
|
"@nextlyhq/adapter-drizzle",
|
|
24894
25203
|
...ALL_ADAPTER_PACKAGES,
|
|
24895
|
-
...
|
|
25204
|
+
...pluginPackages
|
|
24896
25205
|
])
|
|
24897
25206
|
];
|
|
24898
25207
|
await execa(pm, ["install"], { cwd });
|
|
@@ -24913,7 +25222,7 @@ async function installDependencies(cwd, projectInfo, database, useYalc = false,
|
|
|
24913
25222
|
"@nextlyhq/ui",
|
|
24914
25223
|
"@nextlyhq/adapter-drizzle",
|
|
24915
25224
|
...ALL_ADAPTER_PACKAGES,
|
|
24916
|
-
...
|
|
25225
|
+
...pluginPackages
|
|
24917
25226
|
])
|
|
24918
25227
|
];
|
|
24919
25228
|
for (const pkg of yalcPackages) {
|
|
@@ -24928,7 +25237,7 @@ async function installDependencies(cwd, projectInfo, database, useYalc = false,
|
|
|
24928
25237
|
}
|
|
24929
25238
|
|
|
24930
25239
|
// src/lib/download-template.ts
|
|
24931
|
-
var
|
|
25240
|
+
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
24932
25241
|
var kr = Object.defineProperty;
|
|
24933
25242
|
var vr = (s3, t2) => {
|
|
24934
25243
|
for (var e in t2) kr(s3, e, { get: t2[e], enumerable: true });
|
|
@@ -27004,7 +27313,7 @@ var Vn = 512 * 1024;
|
|
|
27004
27313
|
var $n = pr | ur | dr | mr;
|
|
27005
27314
|
var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
|
|
27006
27315
|
var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
|
|
27007
|
-
var
|
|
27316
|
+
var fs10 = (s3, t2, e) => {
|
|
27008
27317
|
try {
|
|
27009
27318
|
return fs.lchownSync(s3, t2, e);
|
|
27010
27319
|
} catch (i2) {
|
|
@@ -27044,7 +27353,7 @@ var ds = (s3, t2, e, i2) => {
|
|
|
27044
27353
|
});
|
|
27045
27354
|
};
|
|
27046
27355
|
var qn = (s3, t2, e, i2) => {
|
|
27047
|
-
t2.isDirectory() && us(path.resolve(s3, t2.name), e, i2),
|
|
27356
|
+
t2.isDirectory() && us(path.resolve(s3, t2.name), e, i2), fs10(path.resolve(s3, t2.name), e, i2);
|
|
27048
27357
|
};
|
|
27049
27358
|
var us = (s3, t2, e) => {
|
|
27050
27359
|
let i2;
|
|
@@ -27053,11 +27362,11 @@ var us = (s3, t2, e) => {
|
|
|
27053
27362
|
} catch (r) {
|
|
27054
27363
|
let n2 = r;
|
|
27055
27364
|
if (n2?.code === "ENOENT") return;
|
|
27056
|
-
if (n2?.code === "ENOTDIR" || n2?.code === "ENOTSUP") return
|
|
27365
|
+
if (n2?.code === "ENOTDIR" || n2?.code === "ENOTSUP") return fs10(s3, t2, e);
|
|
27057
27366
|
throw n2;
|
|
27058
27367
|
}
|
|
27059
27368
|
for (let r of i2) qn(s3, r, t2, e);
|
|
27060
|
-
return
|
|
27369
|
+
return fs10(s3, t2, e);
|
|
27061
27370
|
};
|
|
27062
27371
|
var we2 = class extends Error {
|
|
27063
27372
|
path;
|
|
@@ -27802,7 +28111,7 @@ async function downloadTemplate(templateName, branch = "main") {
|
|
|
27802
28111
|
process.env.TMPDIR || "/tmp",
|
|
27803
28112
|
`nextly-template-${Date.now()}`
|
|
27804
28113
|
);
|
|
27805
|
-
await
|
|
28114
|
+
await import_fs_extra9.default.ensureDir(tmpDir);
|
|
27806
28115
|
const repoPrefix = `${GITHUB_REPO}-${branch}`;
|
|
27807
28116
|
const baseFilter = `${repoPrefix}/templates/base/`;
|
|
27808
28117
|
const templateFilter = `${repoPrefix}/templates/${templateName}/`;
|
|
@@ -27831,7 +28140,7 @@ async function downloadTemplate(templateName, branch = "main") {
|
|
|
27831
28140
|
})
|
|
27832
28141
|
);
|
|
27833
28142
|
} catch (error) {
|
|
27834
|
-
await
|
|
28143
|
+
await import_fs_extra9.default.remove(tmpDir).catch(() => {
|
|
27835
28144
|
});
|
|
27836
28145
|
if (error instanceof Error && error.name === "TimeoutError") {
|
|
27837
28146
|
throw new Error(
|
|
@@ -27842,15 +28151,15 @@ async function downloadTemplate(templateName, branch = "main") {
|
|
|
27842
28151
|
}
|
|
27843
28152
|
const basePath = path.join(tmpDir, "templates", "base");
|
|
27844
28153
|
const templatePath = path.join(tmpDir, "templates", templateName);
|
|
27845
|
-
if (!await
|
|
27846
|
-
await
|
|
28154
|
+
if (!await import_fs_extra9.default.pathExists(basePath)) {
|
|
28155
|
+
await import_fs_extra9.default.remove(tmpDir).catch(() => {
|
|
27847
28156
|
});
|
|
27848
28157
|
throw new Error(
|
|
27849
28158
|
`Base template not found in downloaded archive. The branch "${branch}" may not contain templates.`
|
|
27850
28159
|
);
|
|
27851
28160
|
}
|
|
27852
|
-
if (!await
|
|
27853
|
-
await
|
|
28161
|
+
if (!await import_fs_extra9.default.pathExists(templatePath)) {
|
|
28162
|
+
await import_fs_extra9.default.remove(tmpDir).catch(() => {
|
|
27854
28163
|
});
|
|
27855
28164
|
throw new Error(
|
|
27856
28165
|
`Template "${templateName}" not found in downloaded archive. Available templates may differ on branch "${branch}".`
|
|
@@ -27861,12 +28170,12 @@ async function downloadTemplate(templateName, branch = "main") {
|
|
|
27861
28170
|
async function resolveLocalTemplate(localPath, templateName) {
|
|
27862
28171
|
const basePath = path.join(localPath, "base");
|
|
27863
28172
|
const templatePath = path.join(localPath, templateName);
|
|
27864
|
-
if (!await
|
|
28173
|
+
if (!await import_fs_extra9.default.pathExists(basePath)) {
|
|
27865
28174
|
throw new Error(
|
|
27866
28175
|
`Base template not found at ${basePath}. Check the --local-template path points to the templates/ directory.`
|
|
27867
28176
|
);
|
|
27868
28177
|
}
|
|
27869
|
-
if (!await
|
|
28178
|
+
if (!await import_fs_extra9.default.pathExists(templatePath)) {
|
|
27870
28179
|
throw new Error(
|
|
27871
28180
|
`Template "${templateName}" not found at ${templatePath}. Check the --local-template path points to the templates/ directory.`
|
|
27872
28181
|
);
|
|
@@ -27884,7 +28193,7 @@ async function cleanupDownload(source) {
|
|
|
27884
28193
|
const tmpBase = process.env.TMPDIR || "/tmp";
|
|
27885
28194
|
if (source.basePath.startsWith(tmpBase)) {
|
|
27886
28195
|
const extractionRoot = path.resolve(source.basePath, "../..");
|
|
27887
|
-
await
|
|
28196
|
+
await import_fs_extra9.default.remove(extractionRoot).catch(() => {
|
|
27888
28197
|
});
|
|
27889
28198
|
}
|
|
27890
28199
|
}
|
|
@@ -27984,419 +28293,118 @@ var DATABASE_LABELS = {
|
|
|
27984
28293
|
mysql: {
|
|
27985
28294
|
label: "MySQL",
|
|
27986
28295
|
hint: "Popular alternative for production"
|
|
27987
|
-
}
|
|
27988
|
-
};
|
|
27989
|
-
|
|
27990
|
-
// src/prompts/project-name.ts
|
|
27991
|
-
var
|
|
27992
|
-
async function isExistingNextProject(cwd) {
|
|
27993
|
-
const packageJsonPath = path.join(cwd, "package.json");
|
|
27994
|
-
if (!await
|
|
27995
|
-
try {
|
|
27996
|
-
const packageJson = await import_fs_extra9.default.readJson(packageJsonPath);
|
|
27997
|
-
const deps = {
|
|
27998
|
-
...packageJson.dependencies,
|
|
27999
|
-
...packageJson.devDependencies
|
|
28000
|
-
};
|
|
28001
|
-
return "next" in deps;
|
|
28002
|
-
} catch {
|
|
28003
|
-
return false;
|
|
28004
|
-
}
|
|
28005
|
-
}
|
|
28006
|
-
|
|
28007
|
-
// src/prompts/template.ts
|
|
28008
|
-
var import_picocolors2 = __toESM(require_picocolors2(), 1);
|
|
28009
|
-
function getTemplatePromptOptions() {
|
|
28010
|
-
return [
|
|
28011
|
-
{
|
|
28012
|
-
value: "blank",
|
|
28013
|
-
label: "Blank project",
|
|
28014
|
-
hint: "Start fresh with an empty config"
|
|
28015
|
-
},
|
|
28016
|
-
{
|
|
28017
|
-
value: "blog",
|
|
28018
|
-
label: "Blog",
|
|
28019
|
-
hint: "Posts, authors, categories, clean design"
|
|
28020
|
-
},
|
|
28021
|
-
{
|
|
28022
|
-
value: "_coming_soon",
|
|
28023
|
-
label: import_picocolors2.default.dim("More templates coming soon"),
|
|
28024
|
-
hint: "website, portfolio, e-commerce"
|
|
28025
|
-
}
|
|
28026
|
-
];
|
|
28027
|
-
}
|
|
28028
|
-
function isValidTemplateSelection(value) {
|
|
28029
|
-
return value !== "_coming_soon";
|
|
28030
|
-
}
|
|
28031
|
-
|
|
28032
|
-
// src/utils/detect.ts
|
|
28033
|
-
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
28034
|
-
|
|
28035
|
-
// src/utils/detect-pm-from-user-agent.ts
|
|
28036
|
-
function detectPmFromUserAgent(userAgent) {
|
|
28037
|
-
if (!userAgent) return null;
|
|
28038
|
-
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
28039
|
-
if (userAgent.startsWith("yarn/")) return "yarn";
|
|
28040
|
-
if (userAgent.startsWith("bun/")) return "bun";
|
|
28041
|
-
if (userAgent.startsWith("npm/")) return "npm";
|
|
28042
|
-
return null;
|
|
28043
|
-
}
|
|
28044
|
-
|
|
28045
|
-
// src/utils/detect.ts
|
|
28046
|
-
async function detectPackageManager2(cwd) {
|
|
28047
|
-
const fromUa = detectPmFromUserAgent(process.env.npm_config_user_agent);
|
|
28048
|
-
if (fromUa) return fromUa;
|
|
28049
|
-
if (await import_fs_extra10.default.pathExists(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
28050
|
-
if (await import_fs_extra10.default.pathExists(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
28051
|
-
if (await import_fs_extra10.default.pathExists(path.join(cwd, "bun.lockb"))) return "bun";
|
|
28052
|
-
return "npm";
|
|
28053
|
-
}
|
|
28054
|
-
async function detectProject(cwd) {
|
|
28055
|
-
const packageJsonPath = path.join(cwd, "package.json");
|
|
28056
|
-
if (!await import_fs_extra10.default.pathExists(packageJsonPath)) {
|
|
28057
|
-
throw new Error(
|
|
28058
|
-
"No package.json found. Please run this command in a Next.js project."
|
|
28059
|
-
);
|
|
28060
|
-
}
|
|
28061
|
-
const packageJson = await import_fs_extra10.default.readJson(packageJsonPath);
|
|
28062
|
-
const deps = {
|
|
28063
|
-
...packageJson.dependencies,
|
|
28064
|
-
...packageJson.devDependencies
|
|
28065
|
-
};
|
|
28066
|
-
const isNextJs = "next" in deps;
|
|
28067
|
-
if (!isNextJs) {
|
|
28068
|
-
throw new Error(
|
|
28069
|
-
"Next.js not found in dependencies. Please run this in a Next.js project."
|
|
28070
|
-
);
|
|
28071
|
-
}
|
|
28072
|
-
const nextVersion = deps.next?.replace(/[\^~]/, "") || null;
|
|
28073
|
-
const srcDir = await import_fs_extra10.default.pathExists(path.join(cwd, "src"));
|
|
28074
|
-
const appDirPaths = srcDir ? [path.join(cwd, "src", "app")] : [path.join(cwd, "app")];
|
|
28075
|
-
let isAppRouter = false;
|
|
28076
|
-
for (const appPath of appDirPaths) {
|
|
28077
|
-
if (await import_fs_extra10.default.pathExists(appPath)) {
|
|
28078
|
-
isAppRouter = true;
|
|
28079
|
-
break;
|
|
28080
|
-
}
|
|
28081
|
-
}
|
|
28082
|
-
if (!isAppRouter) {
|
|
28083
|
-
throw new Error(
|
|
28084
|
-
"App Router not detected. Nextly requires Next.js App Router (app/ directory)."
|
|
28085
|
-
);
|
|
28086
|
-
}
|
|
28087
|
-
const hasTypescript = await import_fs_extra10.default.pathExists(path.join(cwd, "tsconfig.json"));
|
|
28088
|
-
const packageManager = await detectPackageManager2(cwd);
|
|
28089
|
-
const appDir = srcDir ? "src/app" : "app";
|
|
28090
|
-
return {
|
|
28091
|
-
isNextJs,
|
|
28092
|
-
isAppRouter,
|
|
28093
|
-
hasTypescript,
|
|
28094
|
-
packageManager,
|
|
28095
|
-
nextVersion,
|
|
28096
|
-
srcDir,
|
|
28097
|
-
appDir
|
|
28098
|
-
};
|
|
28099
|
-
}
|
|
28100
|
-
|
|
28101
|
-
// src/utils/template.ts
|
|
28102
|
-
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
28103
|
-
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
28104
|
-
".ts",
|
|
28105
|
-
".tsx",
|
|
28106
|
-
".js",
|
|
28107
|
-
".jsx",
|
|
28108
|
-
".json",
|
|
28109
|
-
".env",
|
|
28110
|
-
".md",
|
|
28111
|
-
".css",
|
|
28112
|
-
".html",
|
|
28113
|
-
".mjs",
|
|
28114
|
-
".cjs"
|
|
28115
|
-
]);
|
|
28116
|
-
var SKIP_FILES = /* @__PURE__ */ new Set([".DS_Store", "Thumbs.db", ".gitkeep"]);
|
|
28117
|
-
function resolveTemplatePath(localTemplatePath) {
|
|
28118
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
28119
|
-
const fromDist = path.resolve(__dirname, "../templates");
|
|
28120
|
-
if (import_fs_extra11.default.existsSync(fromDist)) {
|
|
28121
|
-
return fromDist;
|
|
28122
|
-
}
|
|
28123
|
-
const fromSrc = path.resolve(__dirname, "../../templates");
|
|
28124
|
-
if (import_fs_extra11.default.existsSync(fromSrc)) {
|
|
28125
|
-
return fromSrc;
|
|
28126
|
-
}
|
|
28127
|
-
throw new Error(
|
|
28128
|
-
"Could not find templates directory. Use --local-template to specify the templates path, or ensure templates are bundled."
|
|
28129
|
-
);
|
|
28130
|
-
}
|
|
28131
|
-
function buildPlaceholderMap(options) {
|
|
28132
|
-
const { database, databaseUrl } = options;
|
|
28133
|
-
return {
|
|
28134
|
-
"{{databaseDialect}}": database.type,
|
|
28135
|
-
"{{databaseUrl}}": databaseUrl || database.envExample
|
|
28136
|
-
};
|
|
28137
|
-
}
|
|
28138
|
-
async function replacePlaceholdersInFile(filePath, placeholders) {
|
|
28139
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
28140
|
-
const basename = path.basename(filePath);
|
|
28141
|
-
const isTextFile = TEXT_EXTENSIONS.has(ext) || basename.startsWith(".env") || basename === ".gitignore";
|
|
28142
|
-
if (!isTextFile) return;
|
|
28143
|
-
let content = await import_fs_extra11.default.readFile(filePath, "utf-8");
|
|
28144
|
-
let changed = false;
|
|
28145
|
-
for (const [placeholder, value] of Object.entries(placeholders)) {
|
|
28146
|
-
if (content.includes(placeholder)) {
|
|
28147
|
-
content = content.replaceAll(placeholder, value);
|
|
28148
|
-
changed = true;
|
|
28149
|
-
}
|
|
28150
|
-
}
|
|
28151
|
-
if (changed) {
|
|
28152
|
-
await import_fs_extra11.default.writeFile(filePath, content, "utf-8");
|
|
28153
|
-
}
|
|
28154
|
-
}
|
|
28155
|
-
async function replacePlaceholders(dir, placeholders) {
|
|
28156
|
-
const entries = await import_fs_extra11.default.readdir(dir, { withFileTypes: true });
|
|
28157
|
-
for (const entry of entries) {
|
|
28158
|
-
const fullPath = path.join(dir, entry.name);
|
|
28159
|
-
if (entry.isDirectory()) {
|
|
28160
|
-
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
28161
|
-
await replacePlaceholders(fullPath, placeholders);
|
|
28162
|
-
} else if (entry.isFile()) {
|
|
28163
|
-
await replacePlaceholdersInFile(fullPath, placeholders);
|
|
28164
|
-
}
|
|
28165
|
-
}
|
|
28166
|
-
}
|
|
28167
|
-
var PINNED_VERSIONS = {
|
|
28168
|
-
// Next.js ecosystem — resolved at runtime via fetchLatestVersion()
|
|
28169
|
-
// (see generatePackageJson)
|
|
28170
|
-
react: "^19.1.0",
|
|
28171
|
-
"react-dom": "^19.1.0",
|
|
28172
|
-
// Dev dependencies
|
|
28173
|
-
typescript: "^5",
|
|
28174
|
-
"@types/node": "^20",
|
|
28175
|
-
"@types/react": "^19",
|
|
28176
|
-
"@types/react-dom": "^19",
|
|
28177
|
-
"@tailwindcss/postcss": "^4",
|
|
28178
|
-
tailwindcss: "^4",
|
|
28179
|
-
eslint: "^9"
|
|
28180
|
-
};
|
|
28181
|
-
var RUNTIME_RESOLVED_PACKAGES = ["next", "eslint-config-next"];
|
|
28182
|
-
var NEXTLY_PACKAGES = [
|
|
28183
|
-
"nextly",
|
|
28184
|
-
"@nextlyhq/admin",
|
|
28185
|
-
"@nextlyhq/adapter-drizzle",
|
|
28186
|
-
"@nextlyhq/adapter-postgres",
|
|
28187
|
-
"@nextlyhq/adapter-mysql",
|
|
28188
|
-
"@nextlyhq/adapter-sqlite"
|
|
28189
|
-
];
|
|
28190
|
-
var resolvedNextlyVersions = null;
|
|
28191
|
-
async function fetchLatestVersion(pkg) {
|
|
28296
|
+
}
|
|
28297
|
+
};
|
|
28298
|
+
|
|
28299
|
+
// src/prompts/project-name.ts
|
|
28300
|
+
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
28301
|
+
async function isExistingNextProject(cwd) {
|
|
28302
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
28303
|
+
if (!await import_fs_extra10.default.pathExists(packageJsonPath)) return false;
|
|
28192
28304
|
try {
|
|
28193
|
-
const
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
|
|
28198
|
-
|
|
28199
|
-
return data.latest ? `^${data.latest}` : "latest";
|
|
28305
|
+
const packageJson = await import_fs_extra10.default.readJson(packageJsonPath);
|
|
28306
|
+
const deps = {
|
|
28307
|
+
...packageJson.dependencies,
|
|
28308
|
+
...packageJson.devDependencies
|
|
28309
|
+
};
|
|
28310
|
+
return "next" in deps;
|
|
28200
28311
|
} catch {
|
|
28201
|
-
return
|
|
28312
|
+
return false;
|
|
28202
28313
|
}
|
|
28203
28314
|
}
|
|
28204
|
-
|
|
28205
|
-
|
|
28206
|
-
|
|
28207
|
-
|
|
28208
|
-
|
|
28209
|
-
|
|
28210
|
-
|
|
28211
|
-
|
|
28212
|
-
|
|
28315
|
+
|
|
28316
|
+
// src/prompts/template.ts
|
|
28317
|
+
var import_picocolors2 = __toESM(require_picocolors2(), 1);
|
|
28318
|
+
function getTemplatePromptOptions() {
|
|
28319
|
+
return [
|
|
28320
|
+
{
|
|
28321
|
+
value: "blank",
|
|
28322
|
+
label: "Blank project",
|
|
28323
|
+
hint: "Start fresh with an empty config"
|
|
28324
|
+
},
|
|
28325
|
+
{
|
|
28326
|
+
value: "blog",
|
|
28327
|
+
label: "Blog",
|
|
28328
|
+
hint: "Posts, authors, categories, clean design"
|
|
28329
|
+
},
|
|
28330
|
+
{
|
|
28331
|
+
value: "_coming_soon",
|
|
28332
|
+
label: import_picocolors2.default.dim("More templates coming soon"),
|
|
28333
|
+
hint: "website, portfolio, e-commerce"
|
|
28334
|
+
}
|
|
28335
|
+
];
|
|
28213
28336
|
}
|
|
28214
|
-
|
|
28215
|
-
|
|
28216
|
-
if (resolvedRuntimeVersions) return resolvedRuntimeVersions;
|
|
28217
|
-
const FALLBACKS = {
|
|
28218
|
-
next: "^16.1.0",
|
|
28219
|
-
"eslint-config-next": "^16.1.0"
|
|
28220
|
-
};
|
|
28221
|
-
const entries = await Promise.all(
|
|
28222
|
-
RUNTIME_RESOLVED_PACKAGES.map(async (pkg) => {
|
|
28223
|
-
const version2 = await fetchLatestVersion(pkg);
|
|
28224
|
-
return [pkg, version2 === "latest" ? FALLBACKS[pkg] : version2];
|
|
28225
|
-
})
|
|
28226
|
-
);
|
|
28227
|
-
resolvedRuntimeVersions = Object.fromEntries(entries);
|
|
28228
|
-
return resolvedRuntimeVersions;
|
|
28337
|
+
function isValidTemplateSelection(value) {
|
|
28338
|
+
return value !== "_coming_soon";
|
|
28229
28339
|
}
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
|
|
28233
|
-
|
|
28234
|
-
|
|
28235
|
-
|
|
28236
|
-
|
|
28237
|
-
|
|
28238
|
-
if (
|
|
28239
|
-
|
|
28240
|
-
|
|
28241
|
-
|
|
28242
|
-
dependencies["@nextlyhq/ui"] = versions["@nextlyhq/ui"] || "latest";
|
|
28243
|
-
dependencies["@nextlyhq/adapter-drizzle"] = versions["@nextlyhq/adapter-drizzle"];
|
|
28244
|
-
dependencies[database.adapter] = versions[database.adapter] || "latest";
|
|
28245
|
-
dependencies["@nextlyhq/plugin-form-builder"] = versions["@nextlyhq/plugin-form-builder"] || "latest";
|
|
28246
|
-
}
|
|
28247
|
-
const devDependencies = {
|
|
28248
|
-
typescript: PINNED_VERSIONS.typescript,
|
|
28249
|
-
"@types/node": PINNED_VERSIONS["@types/node"],
|
|
28250
|
-
"@types/react": PINNED_VERSIONS["@types/react"],
|
|
28251
|
-
"@types/react-dom": PINNED_VERSIONS["@types/react-dom"],
|
|
28252
|
-
"@tailwindcss/postcss": PINNED_VERSIONS["@tailwindcss/postcss"],
|
|
28253
|
-
tailwindcss: PINNED_VERSIONS.tailwindcss,
|
|
28254
|
-
eslint: PINNED_VERSIONS.eslint,
|
|
28255
|
-
"eslint-config-next": runtimeVersions["eslint-config-next"],
|
|
28256
|
-
// Pagefind powers /search in the blog template. Zero-config
|
|
28257
|
-
// static index generated at `next build` time. Templates that
|
|
28258
|
-
// don't ship a /search page simply won't invoke it.
|
|
28259
|
-
pagefind: "^1.1.0"
|
|
28260
|
-
};
|
|
28261
|
-
const pkg = {
|
|
28262
|
-
name: projectName,
|
|
28263
|
-
version: "0.1.0",
|
|
28264
|
-
private: true,
|
|
28265
|
-
scripts: {
|
|
28266
|
-
// F1 PR 4: dev now boots Nextly in single-process mode via `next dev`.
|
|
28267
|
-
// The lazy drizzle-kit/api import (PR 1) plus the in-process HMR
|
|
28268
|
-
// listener (PR 2) replaced the wrapper that previously owned the
|
|
28269
|
-
// terminal, schema prompts, and child supervision. `nextly dev` is
|
|
28270
|
-
// gone; the only supported dev command is the standard `next dev`.
|
|
28271
|
-
dev: "next dev --turbopack",
|
|
28272
|
-
// Build: migrate DB + compile Next.js + (if present) generate
|
|
28273
|
-
// the Pagefind search index. Templates without the search
|
|
28274
|
-
// script silently skip the last step.
|
|
28275
|
-
build: "nextly migrate && next build && (test -f scripts/build-search-index.mjs && node scripts/build-search-index.mjs || true)",
|
|
28276
|
-
"search:index": "node scripts/build-search-index.mjs",
|
|
28277
|
-
start: "next start",
|
|
28278
|
-
lint: "next lint",
|
|
28279
|
-
nextly: "nextly",
|
|
28280
|
-
// First-time setup: sync schema + seed system permissions. Demo
|
|
28281
|
-
// content is seeded separately from the admin UI (visit /welcome
|
|
28282
|
-
// after running `pnpm dev` and completing /admin/setup).
|
|
28283
|
-
"db:setup": "nextly db:sync",
|
|
28284
|
-
"db:migrate": "nextly migrate",
|
|
28285
|
-
"db:migrate:status": "nextly migrate:status",
|
|
28286
|
-
"db:migrate:fresh": "nextly migrate:fresh",
|
|
28287
|
-
"db:migrate:reset": "nextly migrate:reset",
|
|
28288
|
-
"types:generate": "nextly generate:types"
|
|
28289
|
-
},
|
|
28290
|
-
dependencies,
|
|
28291
|
-
devDependencies
|
|
28292
|
-
};
|
|
28293
|
-
return JSON.stringify(pkg, null, 2) + "\n";
|
|
28340
|
+
|
|
28341
|
+
// src/utils/detect.ts
|
|
28342
|
+
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
28343
|
+
|
|
28344
|
+
// src/utils/detect-pm-from-user-agent.ts
|
|
28345
|
+
function detectPmFromUserAgent(userAgent) {
|
|
28346
|
+
if (!userAgent) return null;
|
|
28347
|
+
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
28348
|
+
if (userAgent.startsWith("yarn/")) return "yarn";
|
|
28349
|
+
if (userAgent.startsWith("bun/")) return "bun";
|
|
28350
|
+
if (userAgent.startsWith("npm/")) return "npm";
|
|
28351
|
+
return null;
|
|
28294
28352
|
}
|
|
28295
|
-
|
|
28296
|
-
|
|
28297
|
-
|
|
28298
|
-
|
|
28299
|
-
|
|
28300
|
-
|
|
28301
|
-
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28305
|
-
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
`Directory "${path.basename(targetDir)}" already exists. Please choose a different name.`
|
|
28309
|
-
);
|
|
28310
|
-
}
|
|
28311
|
-
let baseDir;
|
|
28312
|
-
let typeDir;
|
|
28313
|
-
if (templateSource) {
|
|
28314
|
-
baseDir = templateSource.basePath;
|
|
28315
|
-
typeDir = templateSource.templatePath;
|
|
28316
|
-
} else {
|
|
28317
|
-
const templatesRoot = resolveTemplatePath();
|
|
28318
|
-
baseDir = path.join(templatesRoot, "base");
|
|
28319
|
-
typeDir = path.join(templatesRoot, projectType);
|
|
28320
|
-
}
|
|
28321
|
-
if (!await import_fs_extra11.default.pathExists(baseDir)) {
|
|
28353
|
+
|
|
28354
|
+
// src/utils/detect.ts
|
|
28355
|
+
async function detectPackageManager2(cwd) {
|
|
28356
|
+
const fromUa = detectPmFromUserAgent(process.env.npm_config_user_agent);
|
|
28357
|
+
if (fromUa) return fromUa;
|
|
28358
|
+
if (await import_fs_extra11.default.pathExists(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
28359
|
+
if (await import_fs_extra11.default.pathExists(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
28360
|
+
if (await import_fs_extra11.default.pathExists(path.join(cwd, "bun.lockb"))) return "bun";
|
|
28361
|
+
return "npm";
|
|
28362
|
+
}
|
|
28363
|
+
async function detectProject(cwd) {
|
|
28364
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
28365
|
+
if (!await import_fs_extra11.default.pathExists(packageJsonPath)) {
|
|
28322
28366
|
throw new Error(
|
|
28323
|
-
|
|
28367
|
+
"No package.json found. Please run this command in a Next.js project."
|
|
28324
28368
|
);
|
|
28325
28369
|
}
|
|
28326
|
-
|
|
28370
|
+
const packageJson = await import_fs_extra11.default.readJson(packageJsonPath);
|
|
28371
|
+
const deps = {
|
|
28372
|
+
...packageJson.dependencies,
|
|
28373
|
+
...packageJson.devDependencies
|
|
28374
|
+
};
|
|
28375
|
+
const isNextJs = "next" in deps;
|
|
28376
|
+
if (!isNextJs) {
|
|
28327
28377
|
throw new Error(
|
|
28328
|
-
|
|
28378
|
+
"Next.js not found in dependencies. Please run this in a Next.js project."
|
|
28329
28379
|
);
|
|
28330
28380
|
}
|
|
28331
|
-
|
|
28332
|
-
|
|
28333
|
-
|
|
28334
|
-
|
|
28381
|
+
const nextVersion = deps.next?.replace(/[\^~]/, "") || null;
|
|
28382
|
+
const srcDir = await import_fs_extra11.default.pathExists(path.join(cwd, "src"));
|
|
28383
|
+
const appDirPaths = srcDir ? [path.join(cwd, "src", "app")] : [path.join(cwd, "app")];
|
|
28384
|
+
let isAppRouter = false;
|
|
28385
|
+
for (const appPath of appDirPaths) {
|
|
28386
|
+
if (await import_fs_extra11.default.pathExists(appPath)) {
|
|
28387
|
+
isAppRouter = true;
|
|
28388
|
+
break;
|
|
28335
28389
|
}
|
|
28336
|
-
});
|
|
28337
|
-
const templateSrcDir = path.join(typeDir, "src");
|
|
28338
|
-
if (await import_fs_extra11.default.pathExists(templateSrcDir)) {
|
|
28339
|
-
await import_fs_extra11.default.copy(templateSrcDir, path.join(targetDir, "src"), {
|
|
28340
|
-
overwrite: true,
|
|
28341
|
-
filter: (_src) => {
|
|
28342
|
-
const basename = path.basename(_src);
|
|
28343
|
-
return !SKIP_FILES.has(basename);
|
|
28344
|
-
}
|
|
28345
|
-
});
|
|
28346
28390
|
}
|
|
28347
|
-
|
|
28348
|
-
|
|
28349
|
-
|
|
28350
|
-
templateRootConfig,
|
|
28351
|
-
path.join(targetDir, "nextly.config.ts"),
|
|
28352
|
-
{ overwrite: true }
|
|
28391
|
+
if (!isAppRouter) {
|
|
28392
|
+
throw new Error(
|
|
28393
|
+
"App Router not detected. Nextly requires Next.js App Router (app/ directory)."
|
|
28353
28394
|
);
|
|
28354
28395
|
}
|
|
28355
|
-
const
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
|
|
28359
|
-
|
|
28360
|
-
|
|
28361
|
-
|
|
28362
|
-
|
|
28363
|
-
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
|
|
28367
|
-
overwrite: true
|
|
28368
|
-
});
|
|
28369
|
-
}
|
|
28370
|
-
}
|
|
28371
|
-
const frontendPagePath = path.join(
|
|
28372
|
-
targetDir,
|
|
28373
|
-
"src",
|
|
28374
|
-
"app",
|
|
28375
|
-
"(frontend)",
|
|
28376
|
-
"page.tsx"
|
|
28377
|
-
);
|
|
28378
|
-
const basePagePath = path.join(targetDir, "src", "app", "page.tsx");
|
|
28379
|
-
if (await import_fs_extra11.default.pathExists(frontendPagePath) && await import_fs_extra11.default.pathExists(basePagePath)) {
|
|
28380
|
-
await import_fs_extra11.default.remove(basePagePath);
|
|
28381
|
-
}
|
|
28382
|
-
const packageJsonContent = await generatePackageJson(
|
|
28383
|
-
projectName,
|
|
28384
|
-
database,
|
|
28385
|
-
useYalc
|
|
28386
|
-
);
|
|
28387
|
-
await import_fs_extra11.default.writeFile(
|
|
28388
|
-
path.join(targetDir, "package.json"),
|
|
28389
|
-
packageJsonContent,
|
|
28390
|
-
"utf-8"
|
|
28391
|
-
);
|
|
28392
|
-
if (database.type === "sqlite") {
|
|
28393
|
-
await import_fs_extra11.default.ensureDir(path.join(targetDir, "data"));
|
|
28394
|
-
}
|
|
28395
|
-
const placeholders = buildPlaceholderMap({ database, databaseUrl });
|
|
28396
|
-
if (approach) {
|
|
28397
|
-
placeholders["{{approach}}"] = approach;
|
|
28398
|
-
}
|
|
28399
|
-
await replacePlaceholders(targetDir, placeholders);
|
|
28396
|
+
const hasTypescript = await import_fs_extra11.default.pathExists(path.join(cwd, "tsconfig.json"));
|
|
28397
|
+
const packageManager = await detectPackageManager2(cwd);
|
|
28398
|
+
const appDir = srcDir ? "src/app" : "app";
|
|
28399
|
+
return {
|
|
28400
|
+
isNextJs,
|
|
28401
|
+
isAppRouter,
|
|
28402
|
+
hasTypescript,
|
|
28403
|
+
packageManager,
|
|
28404
|
+
nextVersion,
|
|
28405
|
+
srcDir,
|
|
28406
|
+
appDir
|
|
28407
|
+
};
|
|
28400
28408
|
}
|
|
28401
28409
|
|
|
28402
28410
|
// src/create-nextly.ts
|
|
@@ -28652,7 +28660,8 @@ async function createNextly(options = {}) {
|
|
|
28652
28660
|
projectInfo,
|
|
28653
28661
|
database,
|
|
28654
28662
|
useYalc,
|
|
28655
|
-
isFreshProject
|
|
28663
|
+
isFreshProject,
|
|
28664
|
+
projectType
|
|
28656
28665
|
);
|
|
28657
28666
|
s3.stop("Dependencies installed");
|
|
28658
28667
|
capture("install_completed", {
|
|
@@ -28748,5 +28757,5 @@ async function createNextly(options = {}) {
|
|
|
28748
28757
|
*/
|
|
28749
28758
|
|
|
28750
28759
|
export { __commonJS, __require, __toESM, capture, createNextly, init, shutdown };
|
|
28751
|
-
//# sourceMappingURL=chunk-
|
|
28752
|
-
//# sourceMappingURL=chunk-
|
|
28760
|
+
//# sourceMappingURL=chunk-6NVRVAZA.mjs.map
|
|
28761
|
+
//# sourceMappingURL=chunk-6NVRVAZA.mjs.map
|