create-nextspark-app 0.1.0-beta.17 → 0.1.0-beta.171
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/bin/index.js +10 -0
- package/dist/index.js +91 -8
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Check Node.js version before importing anything
|
|
4
|
+
const nodeVersion = parseInt(process.versions.node.split('.')[0], 10);
|
|
5
|
+
if (nodeVersion < 18) {
|
|
6
|
+
console.error('\x1b[31m✗ NextSpark requires Node.js 18 or higher\x1b[0m');
|
|
7
|
+
console.error(` Current version: ${process.versions.node}`);
|
|
8
|
+
console.error(' Please upgrade Node.js: https://nodejs.org/');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
2
12
|
import '../dist/index.js'
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import chalk2 from "chalk";
|
|
6
|
+
import { readFileSync } from "fs";
|
|
6
7
|
|
|
7
8
|
// src/create.ts
|
|
8
9
|
import path from "path";
|
|
@@ -10,6 +11,27 @@ import fs from "fs-extra";
|
|
|
10
11
|
import chalk from "chalk";
|
|
11
12
|
import ora from "ora";
|
|
12
13
|
import { execSync, spawnSync } from "child_process";
|
|
14
|
+
function findLocalTarball(packageName) {
|
|
15
|
+
const tarballPrefix = packageName.replace("@", "").replace("/", "-");
|
|
16
|
+
const searchPaths = [
|
|
17
|
+
path.join(process.cwd(), ".packages"),
|
|
18
|
+
path.join(process.cwd(), "..", ".packages"),
|
|
19
|
+
path.join(process.cwd(), "..", "repo", ".packages"),
|
|
20
|
+
// projects/ -> repo/.packages
|
|
21
|
+
path.join(process.cwd(), "..", "..", ".packages"),
|
|
22
|
+
path.join(process.cwd(), "..", "..", "repo", ".packages")
|
|
23
|
+
];
|
|
24
|
+
for (const searchPath of searchPaths) {
|
|
25
|
+
if (fs.existsSync(searchPath)) {
|
|
26
|
+
const files = fs.readdirSync(searchPath);
|
|
27
|
+
const tarball = files.find((f) => f.startsWith(tarballPrefix) && f.endsWith(".tgz"));
|
|
28
|
+
if (tarball) {
|
|
29
|
+
return path.join(searchPath, tarball);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
13
35
|
async function createProject(options) {
|
|
14
36
|
const { projectName, projectPath, preset } = options;
|
|
15
37
|
if (await fs.pathExists(projectPath)) {
|
|
@@ -24,24 +46,79 @@ async function createProject(options) {
|
|
|
24
46
|
const dirSpinner = ora(" Creating project directory...").start();
|
|
25
47
|
await fs.ensureDir(projectPath);
|
|
26
48
|
dirSpinner.succeed(" Project directory created");
|
|
49
|
+
await fs.writeFile(
|
|
50
|
+
path.join(projectPath, ".npmrc"),
|
|
51
|
+
`shamefully-hoist=true
|
|
52
|
+
`
|
|
53
|
+
);
|
|
27
54
|
const pkgSpinner = ora(" Initializing package.json...").start();
|
|
28
55
|
const packageJson = {
|
|
29
56
|
name: projectName,
|
|
30
57
|
version: "0.1.0",
|
|
31
|
-
private: true
|
|
58
|
+
private: true,
|
|
59
|
+
pnpm: {
|
|
60
|
+
onlyBuiltDependencies: [
|
|
61
|
+
"@nextsparkjs/core",
|
|
62
|
+
"@nextsparkjs/ai-workflow"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
32
65
|
};
|
|
33
66
|
await fs.writeJson(path.join(projectPath, "package.json"), packageJson, { spaces: 2 });
|
|
34
67
|
pkgSpinner.succeed(" package.json created");
|
|
35
|
-
const cliSpinner = ora(" Installing @nextsparkjs/core
|
|
68
|
+
const cliSpinner = ora(" Installing @nextsparkjs/core, @nextsparkjs/cli, and dependencies...").start();
|
|
36
69
|
try {
|
|
37
|
-
|
|
70
|
+
const localCoreTarball = findLocalTarball("@nextsparkjs/core");
|
|
71
|
+
const localCliTarball = findLocalTarball("@nextsparkjs/cli");
|
|
72
|
+
const localUiTarball = findLocalTarball("@nextsparkjs/ui");
|
|
73
|
+
let ownVersion = "latest";
|
|
74
|
+
try {
|
|
75
|
+
const ownPkg = JSON.parse(
|
|
76
|
+
fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8")
|
|
77
|
+
);
|
|
78
|
+
if (ownPkg.version) ownVersion = ownPkg.version;
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
let corePackage = `@nextsparkjs/core@${ownVersion}`;
|
|
82
|
+
let cliPackage = `@nextsparkjs/cli@${ownVersion}`;
|
|
83
|
+
let uiPackage = `@nextsparkjs/ui@${ownVersion}`;
|
|
84
|
+
if (localCoreTarball && localCliTarball) {
|
|
85
|
+
corePackage = localCoreTarball;
|
|
86
|
+
cliPackage = localCliTarball;
|
|
87
|
+
if (localUiTarball) uiPackage = localUiTarball;
|
|
88
|
+
cliSpinner.text = " Installing from local tarballs...";
|
|
89
|
+
}
|
|
90
|
+
const essentialDeps = [
|
|
91
|
+
corePackage,
|
|
92
|
+
cliPackage,
|
|
93
|
+
uiPackage,
|
|
94
|
+
"next",
|
|
95
|
+
"react",
|
|
96
|
+
"react-dom",
|
|
97
|
+
"next-intl",
|
|
98
|
+
"better-auth",
|
|
99
|
+
"@better-fetch/fetch",
|
|
100
|
+
"jiti",
|
|
101
|
+
// Imported directly by shipped app routes (devtools docs/tests + media upload).
|
|
102
|
+
// Must be direct project deps, not phantom-hoisted from @nextsparkjs/core,
|
|
103
|
+
// otherwise `next build` fails to resolve them under pnpm.
|
|
104
|
+
"gray-matter",
|
|
105
|
+
"@vercel/blob"
|
|
106
|
+
].join(" ");
|
|
107
|
+
execSync(`pnpm add ${essentialDeps}`, {
|
|
38
108
|
cwd: projectPath,
|
|
39
109
|
stdio: "pipe"
|
|
40
110
|
});
|
|
41
|
-
cliSpinner.succeed(" @nextsparkjs/core
|
|
111
|
+
cliSpinner.succeed(" @nextsparkjs/core, @nextsparkjs/cli, and dependencies installed");
|
|
42
112
|
} catch (error) {
|
|
43
|
-
|
|
44
|
-
|
|
113
|
+
const coreInstalled = fs.existsSync(
|
|
114
|
+
path.join(projectPath, "node_modules", "@nextsparkjs", "core")
|
|
115
|
+
);
|
|
116
|
+
if (coreInstalled) {
|
|
117
|
+
cliSpinner.succeed(" @nextsparkjs/core, @nextsparkjs/cli, and dependencies installed");
|
|
118
|
+
} else {
|
|
119
|
+
cliSpinner.fail(" Failed to install dependencies");
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
45
122
|
}
|
|
46
123
|
console.log();
|
|
47
124
|
console.log(chalk.blue(" Starting NextSpark wizard..."));
|
|
@@ -50,6 +127,9 @@ async function createProject(options) {
|
|
|
50
127
|
if (preset) {
|
|
51
128
|
initArgs.push("--preset", preset);
|
|
52
129
|
}
|
|
130
|
+
if (options.type) {
|
|
131
|
+
initArgs.push("--type", options.type);
|
|
132
|
+
}
|
|
53
133
|
if (options.name) {
|
|
54
134
|
initArgs.push("--name", options.name);
|
|
55
135
|
}
|
|
@@ -70,8 +150,9 @@ async function createProject(options) {
|
|
|
70
150
|
}
|
|
71
151
|
const result = spawnSync("npx", initArgs, {
|
|
72
152
|
cwd: projectPath,
|
|
73
|
-
stdio: "inherit"
|
|
153
|
+
stdio: "inherit",
|
|
74
154
|
// Interactive mode
|
|
155
|
+
shell: true
|
|
75
156
|
});
|
|
76
157
|
if (result.status !== 0) {
|
|
77
158
|
throw new Error(`Wizard failed with exit code ${result.status}`);
|
|
@@ -123,8 +204,9 @@ async function getProjectOptions(projectName, skipPrompts) {
|
|
|
123
204
|
}
|
|
124
205
|
|
|
125
206
|
// src/index.ts
|
|
207
|
+
var pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
126
208
|
var program = new Command();
|
|
127
|
-
program.name("create-nextspark-app").description("Create a new NextSpark SaaS project").version(
|
|
209
|
+
program.name("create-nextspark-app").description("Create a new NextSpark SaaS project").version(pkg.version).argument("[project-name]", "Name of the project").option("--preset <preset>", "Use a preset (saas, blog, crm)").option("--type <type>", "Project type: web or web-mobile").option("--name <name>", "Project name (non-interactive mode)").option("--slug <slug>", "Project slug (non-interactive mode)").option("--description <desc>", "Project description (non-interactive mode)").option("--theme <theme>", "Theme to use (default, blog, crm, productivity, none)").option("--plugins <plugins>", "Plugins to install (comma-separated)").option("-y, --yes", "Skip prompts and use defaults", false).action(async (projectName, options) => {
|
|
128
210
|
console.log();
|
|
129
211
|
console.log(chalk2.bold.cyan(" NextSpark"));
|
|
130
212
|
console.log(chalk2.dim(" Create a new SaaS project"));
|
|
@@ -134,6 +216,7 @@ program.name("create-nextspark-app").description("Create a new NextSpark SaaS pr
|
|
|
134
216
|
await createProject({
|
|
135
217
|
...projectOptions,
|
|
136
218
|
preset: options.preset,
|
|
219
|
+
type: options.type,
|
|
137
220
|
name: options.name,
|
|
138
221
|
slug: options.slug,
|
|
139
222
|
description: options.description,
|