create-next-hydra 0.1.0 → 0.2.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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/cli.js +0 -0
- package/dist/composition/add.d.ts +14 -0
- package/dist/composition/add.d.ts.map +1 -0
- package/dist/composition/add.js +453 -0
- package/dist/composition/catalog.d.ts +23 -0
- package/dist/composition/catalog.d.ts.map +1 -0
- package/dist/composition/catalog.js +301 -0
- package/dist/composition/errors.d.ts +5 -0
- package/dist/composition/errors.d.ts.map +1 -0
- package/dist/composition/errors.js +8 -0
- package/dist/composition/format.d.ts +6 -0
- package/dist/composition/format.d.ts.map +1 -0
- package/dist/composition/format.js +63 -0
- package/dist/composition/install.d.ts +16 -0
- package/dist/composition/install.d.ts.map +1 -0
- package/dist/composition/install.js +175 -0
- package/dist/composition/packages.d.ts +6 -0
- package/dist/composition/packages.d.ts.map +1 -0
- package/dist/composition/packages.js +54 -0
- package/dist/composition/paths.d.ts +4 -0
- package/dist/composition/paths.d.ts.map +1 -0
- package/dist/composition/paths.js +47 -0
- package/dist/composition/planner.d.ts +4 -0
- package/dist/composition/planner.d.ts.map +1 -0
- package/dist/composition/planner.js +320 -0
- package/dist/composition/schema.d.ts +235 -0
- package/dist/composition/schema.d.ts.map +1 -0
- package/dist/composition/schema.js +115 -0
- package/dist/composition/types.d.ts +87 -0
- package/dist/composition/types.d.ts.map +1 -0
- package/dist/composition/types.js +6 -0
- package/dist/composition/use.d.ts +23 -0
- package/dist/composition/use.d.ts.map +1 -0
- package/dist/composition/use.js +182 -0
- package/dist/composition/workspace.d.ts +10 -0
- package/dist/composition/workspace.d.ts.map +1 -0
- package/dist/composition/workspace.js +208 -0
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +26 -1
- package/dist/fs-utils.js +3 -3
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +12 -12
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -6
- package/dist/instruction-renderer.d.ts +17 -0
- package/dist/instruction-renderer.d.ts.map +1 -0
- package/dist/instruction-renderer.js +132 -0
- package/dist/logger.d.ts +2 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +7 -3
- package/dist/prompts.d.ts +2 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +25 -2
- package/dist/sanitize.d.ts +2 -1
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/sanitize.js +13 -4
- package/dist/scaffold.d.ts +5 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +247 -71
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/package.json +35 -23
- package/schema/selection-definition.json +237 -0
- package/schema/source-registry.json +37 -0
package/dist/scaffold.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
import { stat } from "node:fs/promises";
|
|
1
2
|
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
2
4
|
import { intro } from "@clack/prompts";
|
|
3
5
|
import { cloneStarter } from "./clone.js";
|
|
6
|
+
import { addCatalogReferences, loadGitHubSourceRegistryCatalog, loadSourceRegistryCatalog, } from "./composition/catalog.js";
|
|
7
|
+
import { formatCompositionPlan } from "./composition/format.js";
|
|
8
|
+
import { installPreparedComposition, prepareComposition, validatePackageRequirementTargets, } from "./composition/install.js";
|
|
9
|
+
import { planComposition, selectionFromPreset } from "./composition/planner.js";
|
|
10
|
+
import { applyPackageRequirements, applyPnpmPatches, removeWorkspaceTargets, } from "./composition/workspace.js";
|
|
4
11
|
import { DEFAULT_PACKAGE_MANAGER } from "./constants.js";
|
|
5
|
-
import { ensureParentDirectory, isDirectoryEmpty, pathExists,
|
|
6
|
-
import { CommandExecutionError, ensureGitInstalled, initializeGitRepository, } from "./git.js";
|
|
7
|
-
import { createSpinner, finish, info,
|
|
12
|
+
import { ensureParentDirectory, isDirectoryEmpty, pathExists, toDisplayPath, } from "./fs-utils.js";
|
|
13
|
+
import { CommandExecutionError, ensureGitInstalled, initializeGitRepository, runCommand, } from "./git.js";
|
|
14
|
+
import { createSpinner, finish, info, printInstructions, success, warn, } from "./logger.js";
|
|
15
|
+
import { promptForProvider } from "./prompts.js";
|
|
8
16
|
import { sanitizeStarter } from "./sanitize.js";
|
|
9
17
|
const SHELL_NEEDS_QUOTING_REGEX = /[\s"'\\]/;
|
|
18
|
+
const GITHUB_SCP_REPOSITORY = /^(?:git@|ssh:\/\/git@)github\.com[:/]([^/]+)\/([^/]+?)(?:\.git)?$/;
|
|
19
|
+
const LEADING_SLASH = /^\//;
|
|
20
|
+
const GIT_SUFFIX = /\.git$/;
|
|
10
21
|
function quotePathForShell(value) {
|
|
11
22
|
if (!SHELL_NEEDS_QUOTING_REGEX.test(value)) {
|
|
12
23
|
return value;
|
|
13
24
|
}
|
|
14
|
-
return `'${value.
|
|
25
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
15
26
|
}
|
|
16
27
|
async function resolveAndValidateTarget(inputTargetDir) {
|
|
17
28
|
const targetDir = inputTargetDir.trim();
|
|
@@ -20,8 +31,7 @@ async function resolveAndValidateTarget(inputTargetDir) {
|
|
|
20
31
|
if (!targetName) {
|
|
21
32
|
throw new Error("Please provide a valid target folder.");
|
|
22
33
|
}
|
|
23
|
-
|
|
24
|
-
if (existedBefore) {
|
|
34
|
+
if (await pathExists(targetPath)) {
|
|
25
35
|
const isEmpty = await isDirectoryEmpty(targetPath);
|
|
26
36
|
if (!isEmpty) {
|
|
27
37
|
throw new Error(`Target directory is not empty: ${toDisplayPath(targetPath)}`);
|
|
@@ -30,46 +40,117 @@ async function resolveAndValidateTarget(inputTargetDir) {
|
|
|
30
40
|
else {
|
|
31
41
|
await ensureParentDirectory(targetPath);
|
|
32
42
|
}
|
|
33
|
-
return { targetDir, targetName, targetPath
|
|
43
|
+
return { targetDir, targetName, targetPath };
|
|
34
44
|
}
|
|
35
45
|
function formatGitError(error) {
|
|
36
|
-
const isCloneCommand = error.command.startsWith("git clone ");
|
|
37
46
|
const stderr = error.stderr.trim();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return [
|
|
43
|
-
error.command,
|
|
44
|
-
"",
|
|
45
|
-
stderr,
|
|
47
|
+
const stdout = error.stdout.trim();
|
|
48
|
+
const detail = stderr || stdout || error.message;
|
|
49
|
+
const hint = error.command.startsWith("git clone ")
|
|
50
|
+
? [
|
|
46
51
|
"",
|
|
47
52
|
"Hint: If the starter repo is private or you are testing locally, use `--repo-url`.",
|
|
48
53
|
"Example: create-next-hydra my-app --repo-url /path/to/next-hydra",
|
|
49
|
-
]
|
|
54
|
+
]
|
|
55
|
+
: [];
|
|
56
|
+
return [error.command, "", detail, ...hint].join("\n");
|
|
57
|
+
}
|
|
58
|
+
async function localRepositoryPath(repoUrl) {
|
|
59
|
+
let candidate;
|
|
60
|
+
if (repoUrl.startsWith("file:")) {
|
|
61
|
+
candidate = fileURLToPath(repoUrl);
|
|
50
62
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
else if (path.isAbsolute(repoUrl) ||
|
|
64
|
+
repoUrl.startsWith(".") ||
|
|
65
|
+
!repoUrl.includes(":")) {
|
|
66
|
+
candidate = path.resolve(repoUrl);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return (await stat(candidate)).isDirectory() ? candidate : null;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function githubRepository(repoUrl) {
|
|
79
|
+
const scpMatch = GITHUB_SCP_REPOSITORY.exec(repoUrl);
|
|
80
|
+
if (scpMatch?.[1] && scpMatch[2]) {
|
|
81
|
+
return `${scpMatch[1]}/${scpMatch[2]}`;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const url = new URL(repoUrl);
|
|
85
|
+
if (url.hostname !== "github.com") {
|
|
86
|
+
return null;
|
|
55
87
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
88
|
+
const parts = url.pathname
|
|
89
|
+
.replace(LEADING_SLASH, "")
|
|
90
|
+
.replace(GIT_SUFFIX, "")
|
|
91
|
+
.split("/");
|
|
92
|
+
return parts.length === 2 && parts[0] && parts[1]
|
|
93
|
+
? `${parts[0]}/${parts[1]}`
|
|
94
|
+
: null;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
64
98
|
}
|
|
65
|
-
return `${error.command}\n\n${error.message}`;
|
|
66
99
|
}
|
|
67
|
-
|
|
100
|
+
async function requestedSelection(options, catalog) {
|
|
101
|
+
if (options.preset && (options.auth || options.cms || options.commerce)) {
|
|
102
|
+
throw new Error("`--preset` cannot be combined with provider flags.");
|
|
103
|
+
}
|
|
104
|
+
if (options.preset) {
|
|
105
|
+
const preset = selectionFromPreset(catalog, options.preset);
|
|
106
|
+
return {
|
|
107
|
+
...preset,
|
|
108
|
+
addOns: [...new Set([...preset.addOns, ...(options.addOns ?? [])])],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (options.yes && !(options.auth && options.cms && options.commerce)) {
|
|
112
|
+
throw new Error("`--yes` requires `--auth`, `--cms`, and `--commerce`, or one `--preset`.");
|
|
113
|
+
}
|
|
114
|
+
const auth = options.auth ?? (await promptForProvider("auth", "workos"));
|
|
115
|
+
const cms = options.cms ?? (await promptForProvider("cms", "drupal"));
|
|
116
|
+
const commerce = options.commerce ?? (await promptForProvider("commerce", "commercetools"));
|
|
117
|
+
return {
|
|
118
|
+
addOns: options.addOns ?? [],
|
|
119
|
+
providers: { auth, cms, commerce },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function explicitSelectionReferences(options) {
|
|
123
|
+
return [
|
|
124
|
+
options.auth,
|
|
125
|
+
options.cms,
|
|
126
|
+
options.commerce,
|
|
127
|
+
options.preset,
|
|
128
|
+
...(options.addOns ?? []),
|
|
129
|
+
].filter((value) => Boolean(value));
|
|
130
|
+
}
|
|
131
|
+
function scaffoldFailure(error, targetPath, failedStep, completed, pending) {
|
|
132
|
+
let cause = String(error);
|
|
133
|
+
if (error instanceof Error) {
|
|
134
|
+
cause = error.message;
|
|
135
|
+
}
|
|
136
|
+
if (error instanceof CommandExecutionError) {
|
|
137
|
+
cause = formatGitError(error);
|
|
138
|
+
}
|
|
139
|
+
return new Error([
|
|
140
|
+
`Scaffolding stopped while ${failedStep}.`,
|
|
141
|
+
`Target: ${targetPath}`,
|
|
142
|
+
`Completed: ${completed.length > 0 ? completed.join(", ") : "none"}.`,
|
|
143
|
+
`Not attempted: ${pending.length > 0 ? pending.join(", ") : "none"}.`,
|
|
144
|
+
"The partial project has been left exactly as it stands for inspection or repair.",
|
|
145
|
+
"",
|
|
146
|
+
cause,
|
|
147
|
+
].join("\n"), { cause: error });
|
|
148
|
+
}
|
|
149
|
+
export async function scaffoldProject(options, dependencies = {}) {
|
|
68
150
|
intro("create-next-hydra");
|
|
69
151
|
const spin = createSpinner();
|
|
70
152
|
const { repoUrl, ref, skipGit, commit, verbose } = options;
|
|
71
|
-
|
|
72
|
-
if (!targetDir) {
|
|
153
|
+
if (!options.targetDir) {
|
|
73
154
|
throw new Error("Missing target directory.");
|
|
74
155
|
}
|
|
75
156
|
spin.start("Checking git availability");
|
|
@@ -77,40 +158,124 @@ export async function scaffoldProject(options) {
|
|
|
77
158
|
await ensureGitInstalled(verbose);
|
|
78
159
|
spin.stop("Git detected");
|
|
79
160
|
}
|
|
80
|
-
catch {
|
|
161
|
+
catch (error) {
|
|
81
162
|
spin.stop("Git not available");
|
|
82
|
-
throw new Error("Git is required to scaffold a project. Please install git and try again.");
|
|
163
|
+
throw new Error("Git is required to scaffold a project. Please install git and try again.", { cause: error });
|
|
164
|
+
}
|
|
165
|
+
const sourcePath = await localRepositoryPath(repoUrl);
|
|
166
|
+
const remoteRepository = sourcePath ? null : githubRepository(repoUrl);
|
|
167
|
+
let sourceCatalog;
|
|
168
|
+
if (sourcePath) {
|
|
169
|
+
sourceCatalog = await loadSourceRegistryCatalog(sourcePath);
|
|
83
170
|
}
|
|
84
|
-
|
|
85
|
-
|
|
171
|
+
else if (remoteRepository) {
|
|
172
|
+
sourceCatalog = await loadGitHubSourceRegistryCatalog(remoteRepository, ref);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
throw new Error("Composition preflight supports a local starter path or a public GitHub repository. Use one of those forms with `--repo-url`.");
|
|
176
|
+
}
|
|
177
|
+
sourceCatalog = await addCatalogReferences(sourceCatalog, explicitSelectionReferences(options), process.cwd());
|
|
178
|
+
const selection = await requestedSelection(options, sourceCatalog);
|
|
179
|
+
sourceCatalog = await addCatalogReferences(sourceCatalog, [...Object.values(selection.providers), ...selection.addOns], process.cwd());
|
|
180
|
+
planComposition(sourceCatalog, selection);
|
|
181
|
+
const { targetPath, targetName } = await resolveAndValidateTarget(options.targetDir);
|
|
182
|
+
const completed = [];
|
|
183
|
+
const pending = [
|
|
184
|
+
"clone the starter",
|
|
185
|
+
"resolve the composition",
|
|
186
|
+
"remove variable provider source",
|
|
187
|
+
"install selected source",
|
|
188
|
+
"update package aliases",
|
|
189
|
+
"update pnpm patches",
|
|
190
|
+
"remove maintainer-only files",
|
|
191
|
+
"install dependencies",
|
|
192
|
+
"initialize Git",
|
|
193
|
+
];
|
|
194
|
+
let currentStep = "clone the starter";
|
|
195
|
+
const runStep = async (label, operation) => {
|
|
196
|
+
currentStep = label;
|
|
197
|
+
pending.shift();
|
|
198
|
+
const result = await operation();
|
|
199
|
+
completed.push(label);
|
|
200
|
+
return result;
|
|
201
|
+
};
|
|
86
202
|
try {
|
|
87
203
|
spin.start("Cloning next-hydra starter");
|
|
88
|
-
await
|
|
89
|
-
repoUrl,
|
|
90
|
-
targetPath,
|
|
91
|
-
ref,
|
|
92
|
-
verbose,
|
|
204
|
+
await runStep("clone the starter", async () => {
|
|
205
|
+
await cloneStarter({ ref, repoUrl, targetPath, verbose });
|
|
93
206
|
});
|
|
94
|
-
cloneCompleted = true;
|
|
95
207
|
spin.stop("Starter cloned");
|
|
96
|
-
spin.start("
|
|
97
|
-
const {
|
|
98
|
-
|
|
208
|
+
spin.start("Resolving workspace composition");
|
|
209
|
+
const { catalog, plan, prepared } = await runStep("resolve the composition", async () => {
|
|
210
|
+
let targetCatalog = await loadSourceRegistryCatalog(targetPath);
|
|
211
|
+
targetCatalog = await addCatalogReferences(targetCatalog, [
|
|
212
|
+
...explicitSelectionReferences(options),
|
|
213
|
+
...Object.values(selection.providers),
|
|
214
|
+
...selection.addOns,
|
|
215
|
+
], process.cwd());
|
|
216
|
+
const targetPlan = planComposition(targetCatalog, selection);
|
|
217
|
+
const targetPrepared = await prepareComposition(targetCatalog, targetPlan);
|
|
218
|
+
await validatePackageRequirementTargets(targetPath, targetPlan, targetPrepared, targetPlan.variableTargets);
|
|
219
|
+
return {
|
|
220
|
+
catalog: targetCatalog,
|
|
221
|
+
plan: targetPlan,
|
|
222
|
+
prepared: targetPrepared,
|
|
223
|
+
};
|
|
224
|
+
});
|
|
225
|
+
spin.stop("Composition resolved");
|
|
226
|
+
info(formatCompositionPlan(plan));
|
|
227
|
+
spin.start("Removing unselected provider source");
|
|
228
|
+
await runStep("remove variable provider source", async () => {
|
|
229
|
+
await removeWorkspaceTargets(targetPath, plan.variableTargets);
|
|
230
|
+
});
|
|
231
|
+
spin.stop("Variable provider source removed");
|
|
232
|
+
spin.start("Installing selected provider source");
|
|
233
|
+
await runStep("install selected source", async () => {
|
|
234
|
+
await installPreparedComposition(targetPath, prepared);
|
|
235
|
+
});
|
|
236
|
+
spin.stop("Selected provider source installed");
|
|
237
|
+
await runStep("update package aliases", async () => {
|
|
238
|
+
await applyPackageRequirements(targetPath, plan);
|
|
239
|
+
});
|
|
240
|
+
await runStep("update pnpm patches", async () => {
|
|
241
|
+
await applyPnpmPatches(targetPath, plan);
|
|
242
|
+
});
|
|
243
|
+
spin.start("Removing maintainer-only files");
|
|
244
|
+
const { packageName } = await runStep("remove maintainer-only files", async () => {
|
|
245
|
+
const result = await sanitizeStarter({
|
|
246
|
+
registryAuthoringPaths: catalog.authoringPaths,
|
|
247
|
+
targetName,
|
|
248
|
+
targetPath,
|
|
249
|
+
});
|
|
250
|
+
await removeWorkspaceTargets(targetPath, catalog.authoringPaths);
|
|
251
|
+
return result;
|
|
252
|
+
});
|
|
253
|
+
spin.stop("Maintainer-only files removed");
|
|
254
|
+
spin.start("Installing dependencies");
|
|
255
|
+
await runStep("install dependencies", async () => {
|
|
256
|
+
if (dependencies.install) {
|
|
257
|
+
await dependencies.install(targetPath, verbose);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
await runCommand(DEFAULT_PACKAGE_MANAGER, ["install"], {
|
|
261
|
+
cwd: targetPath,
|
|
262
|
+
verbose,
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
spin.stop("Dependencies installed");
|
|
99
266
|
let gitInitialized = false;
|
|
100
267
|
let committed = false;
|
|
101
268
|
if (skipGit) {
|
|
269
|
+
pending.shift();
|
|
270
|
+
completed.push("skip Git initialization");
|
|
102
271
|
info("Skipped git initialization (--skip-git).");
|
|
103
272
|
}
|
|
104
273
|
else {
|
|
105
274
|
spin.start(commit
|
|
106
275
|
? "Initializing git repo and creating initial commit"
|
|
107
276
|
: "Initializing git repo");
|
|
108
|
-
const gitResult = await initializeGitRepository(targetPath, {
|
|
109
|
-
|
|
110
|
-
verbose,
|
|
111
|
-
});
|
|
112
|
-
gitInitialized = gitResult.gitInitialized;
|
|
113
|
-
committed = gitResult.committed;
|
|
277
|
+
const gitResult = await runStep("initialize Git", async () => await initializeGitRepository(targetPath, { commit, verbose }));
|
|
278
|
+
({ committed, gitInitialized } = gitResult);
|
|
114
279
|
spin.stop(committed
|
|
115
280
|
? "Git repo initialized with initial commit"
|
|
116
281
|
: "Git repo initialized");
|
|
@@ -119,31 +284,42 @@ export async function scaffoldProject(options) {
|
|
|
119
284
|
}
|
|
120
285
|
}
|
|
121
286
|
const displayTarget = toDisplayPath(targetPath);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
287
|
+
printInstructions([
|
|
288
|
+
...(plan.instructions.length > 0
|
|
289
|
+
? [
|
|
290
|
+
{
|
|
291
|
+
entries: plan.instructions.map((text) => ({
|
|
292
|
+
kind: "text",
|
|
293
|
+
text,
|
|
294
|
+
})),
|
|
295
|
+
title: "Provider setup",
|
|
296
|
+
},
|
|
297
|
+
]
|
|
298
|
+
: []),
|
|
299
|
+
{
|
|
300
|
+
entries: [
|
|
301
|
+
{
|
|
302
|
+
command: `cd ${quotePathForShell(displayTarget)}`,
|
|
303
|
+
kind: "command",
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
command: `${DEFAULT_PACKAGE_MANAGER} dev`,
|
|
307
|
+
kind: "command",
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
title: "Next steps",
|
|
311
|
+
},
|
|
312
|
+
]);
|
|
128
313
|
success(`Created project in ${displayTarget}`);
|
|
129
314
|
finish("Scaffold complete.");
|
|
130
315
|
return {
|
|
131
|
-
projectPath: targetPath,
|
|
132
|
-
packageName,
|
|
133
|
-
gitInitialized,
|
|
134
316
|
committed,
|
|
317
|
+
gitInitialized,
|
|
318
|
+
packageName,
|
|
319
|
+
projectPath: targetPath,
|
|
135
320
|
};
|
|
136
321
|
}
|
|
137
322
|
catch (error) {
|
|
138
|
-
|
|
139
|
-
await removePath(targetPath);
|
|
140
|
-
}
|
|
141
|
-
if (error instanceof CommandExecutionError) {
|
|
142
|
-
throw new Error(formatGitError(error));
|
|
143
|
-
}
|
|
144
|
-
if (error instanceof Error) {
|
|
145
|
-
throw error;
|
|
146
|
-
}
|
|
147
|
-
throw new Error("Failed to scaffold project.");
|
|
323
|
+
throw scaffoldFailure(error, targetPath, currentStep, completed, pending);
|
|
148
324
|
}
|
|
149
325
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ export type CreateOptions = {
|
|
|
6
6
|
ref?: string;
|
|
7
7
|
repoUrl: string;
|
|
8
8
|
verbose: boolean;
|
|
9
|
+
auth?: string;
|
|
10
|
+
cms?: string;
|
|
11
|
+
commerce?: string;
|
|
12
|
+
addOns?: string[];
|
|
13
|
+
preset?: string;
|
|
9
14
|
};
|
|
10
15
|
export type ResolvedCreateOptions = CreateOptions & {
|
|
11
16
|
targetDir: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,QAA0B,CAAC"}
|
package/dist/version.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-next-hydra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI to scaffold a new next-hydra project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -13,14 +13,11 @@
|
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"type": "module",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/jakala-na/next-hydra",
|
|
19
|
+
"directory": "packages/create-next-hydra"
|
|
18
20
|
},
|
|
19
|
-
"files": [
|
|
20
|
-
"dist"
|
|
21
|
-
],
|
|
22
|
-
"main": "./dist/index.js",
|
|
23
|
-
"types": "./dist/index.d.ts",
|
|
24
21
|
"exports": {
|
|
25
22
|
".": {
|
|
26
23
|
"types": "./dist/index.d.ts",
|
|
@@ -30,27 +27,42 @@
|
|
|
30
27
|
"import": "./dist/cli.js"
|
|
31
28
|
}
|
|
32
29
|
},
|
|
33
|
-
"
|
|
34
|
-
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"bin": {
|
|
33
|
+
"create-next-hydra": "dist/cli.js"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"schema"
|
|
38
|
+
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@clack/prompts": "^0.11.0",
|
|
41
|
+
"commander": "^14.0.0",
|
|
42
|
+
"shadcn": "^4.16.2",
|
|
43
|
+
"yaml": "^2.9.0",
|
|
44
|
+
"zod": "^3.25.28"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "24.13.3",
|
|
48
|
+
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
49
|
+
"vitest": "4.1.11",
|
|
50
|
+
"@repo/typescript-config": "0.0.0"
|
|
35
51
|
},
|
|
36
52
|
"engines": {
|
|
37
|
-
"node": "
|
|
53
|
+
"node": "24.x"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
38
57
|
},
|
|
39
58
|
"scripts": {
|
|
59
|
+
"prebuild": "node scripts/clean-dist.js",
|
|
40
60
|
"build": "tsc -p tsconfig.json",
|
|
41
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
42
61
|
"pack": "npm pack",
|
|
43
62
|
"publish:dry-run": "npm publish --access public --dry-run",
|
|
44
63
|
"publish:public": "npm publish --access public",
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"@clack/prompts": "^0.11.0",
|
|
49
|
-
"commander": "^14.0.0"
|
|
50
|
-
},
|
|
51
|
-
"devDependencies": {
|
|
52
|
-
"@repo/typescript-config": "workspace:*",
|
|
53
|
-
"@types/node": "^22.15.21",
|
|
54
|
-
"typescript": "^5.8.3"
|
|
64
|
+
"test": "vitest run --exclude 'tests/e2e/**'",
|
|
65
|
+
"test:e2e": "vitest run tests/e2e",
|
|
66
|
+
"typecheck": "pnpm --workspace-root exec tsc --noEmit --project packages/create-next-hydra/tsconfig.json"
|
|
55
67
|
}
|
|
56
|
-
}
|
|
68
|
+
}
|