@cellajs/create-cella 0.1.5 → 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 +57 -0
- package/index.js +1 -1
- package/package.json +32 -20
- package/src/add-remote.ts +17 -27
- package/src/constants.ts +77 -33
- package/src/create-cella-cli.ts +141 -0
- package/src/create.ts +82 -161
- package/src/modules/cli/commands.ts +58 -0
- package/src/modules/cli/display.ts +62 -0
- package/src/modules/cli/index.ts +3 -0
- package/src/modules/cli/types.ts +35 -0
- package/src/utils/clean-template.ts +24 -15
- package/src/utils/detect-used-ports.ts +57 -0
- package/src/utils/extract-package-json-version-from-uri.ts +29 -0
- package/src/utils/git/command.ts +89 -0
- package/src/utils/git/index.ts +11 -0
- package/src/utils/is-empty-directory.ts +1 -1
- package/src/utils/progress.ts +118 -0
- package/src/utils/run-package-manager-command.ts +12 -37
- package/src/utils/validate-project-name.ts +1 -4
- package/tests/e2e.test.ts +108 -0
- package/tests/validate-project-name.test.ts +22 -0
- package/tsconfig.json +19 -14
- package/tsup.config.ts +6 -5
- package/vitest.config.ts +17 -0
- package/dist/index.js +0 -617
- package/dist/index.js.map +0 -1
- package/src/cli.ts +0 -106
- package/src/index.ts +0 -132
- package/src/utils/run-git-command.ts +0 -57
package/dist/index.js
DELETED
|
@@ -1,617 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
|
|
3
|
-
// src/index.ts
|
|
4
|
-
import { basename as basename2, resolve as resolve2 } from "node:path";
|
|
5
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
6
|
-
import colors3 from "picocolors";
|
|
7
|
-
import { input, confirm, select } from "@inquirer/prompts";
|
|
8
|
-
|
|
9
|
-
// src/cli.ts
|
|
10
|
-
import { basename, resolve } from "node:path";
|
|
11
|
-
import { Command, InvalidArgumentError } from "commander";
|
|
12
|
-
|
|
13
|
-
// package.json
|
|
14
|
-
var package_default = {
|
|
15
|
-
name: "@cellajs/create-cella",
|
|
16
|
-
version: "0.1.5",
|
|
17
|
-
private: false,
|
|
18
|
-
license: "MIT",
|
|
19
|
-
description: "Cella is a TypeScript template to create web apps with sync and offline capabilities.",
|
|
20
|
-
publishConfig: {
|
|
21
|
-
access: "public"
|
|
22
|
-
},
|
|
23
|
-
repository: {
|
|
24
|
-
type: "git",
|
|
25
|
-
url: "https://github.com/cellajs/cella",
|
|
26
|
-
directory: "cli/create-cella"
|
|
27
|
-
},
|
|
28
|
-
homepage: "https://cellajs.com",
|
|
29
|
-
author: "CellaJS <info@cellajs.com>",
|
|
30
|
-
engines: {
|
|
31
|
-
node: ">=20.14.0"
|
|
32
|
-
},
|
|
33
|
-
type: "module",
|
|
34
|
-
main: "./src/index.ts",
|
|
35
|
-
bin: {
|
|
36
|
-
"create-cella": "index.js"
|
|
37
|
-
},
|
|
38
|
-
scripts: {
|
|
39
|
-
start: "tsx ./src/index.ts",
|
|
40
|
-
clean: "rimraf ./dist",
|
|
41
|
-
build: "tsup",
|
|
42
|
-
"test-build": "pnpm run build && node index.js",
|
|
43
|
-
prepublishOnly: "pnpm run build"
|
|
44
|
-
},
|
|
45
|
-
packageManager: "pnpm@9.11.0",
|
|
46
|
-
dependencies: {
|
|
47
|
-
"@inquirer/prompts": "^6.0.1",
|
|
48
|
-
commander: "^12.1.0",
|
|
49
|
-
"cross-spawn": "^7.0.3",
|
|
50
|
-
giget: "^1.2.3",
|
|
51
|
-
picocolors: "^1.1.0",
|
|
52
|
-
"validate-npm-package-name": "^5.0.1",
|
|
53
|
-
"yocto-spinner": "^0.1.0"
|
|
54
|
-
},
|
|
55
|
-
devDependencies: {
|
|
56
|
-
tsup: "^8.3.5",
|
|
57
|
-
tsx: "^4.19.2"
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// src/constants.ts
|
|
62
|
-
var NAME = "create-cella";
|
|
63
|
-
var TEMPLATE_URL = "github:cellajs/cella";
|
|
64
|
-
var CELLA_REMOTE_URL = "git@github.com:cellajs/cella.git";
|
|
65
|
-
var DESCRIPTION = package_default.description;
|
|
66
|
-
var VERSION = package_default.version;
|
|
67
|
-
var AUTHOR = package_default.author;
|
|
68
|
-
var WEBSITE = package_default.homepage;
|
|
69
|
-
var GITHUB = package_default.repository.url;
|
|
70
|
-
var TO_REMOVE = [
|
|
71
|
-
"info",
|
|
72
|
-
"./cli/create-cella"
|
|
73
|
-
];
|
|
74
|
-
var TO_CLEAN = [
|
|
75
|
-
"./backend/drizzle"
|
|
76
|
-
];
|
|
77
|
-
var TO_COPY = {
|
|
78
|
-
"./backend/.env.example": "./backend/.env",
|
|
79
|
-
"./frontend/.env.example": "./frontend/.env",
|
|
80
|
-
"./tus/.env.example": "./tus/.env",
|
|
81
|
-
"./info/QUICKSTART.md": "README.md"
|
|
82
|
-
};
|
|
83
|
-
var TO_EDIT = {
|
|
84
|
-
"./config/default.ts": [
|
|
85
|
-
{
|
|
86
|
-
regexMatch: /enabledAuthenticationStrategies:\s*\[[^\]]+\]\s*as\s*const,/g,
|
|
87
|
-
replaceWith: "enabledAuthenticationStrategies: ['password', 'passkey'] as const,"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
regexMatch: /imado\:\s*(true|false),/g,
|
|
91
|
-
replaceWith: "imado: false,"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
regexMatch: /enabledOauthProviders:\s*\[[^\]]+\]\s*as\s*const,/g,
|
|
95
|
-
replaceWith: "enabledOauthProviders: [] as const,"
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
};
|
|
99
|
-
var LOGO = `
|
|
100
|
-
_ _
|
|
101
|
-
\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2593\u2592 ___ ___| | | __ _
|
|
102
|
-
\u2592\u2593\u2588 \u2588\u2593\u2592 / __/ _ \\ | |/ _\` |
|
|
103
|
-
\u2592\u2593\u2588 \u2588\u2593\u2592 | (_| __/ | | (_| |
|
|
104
|
-
\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2593\u2592 \\___\\___|_|_|\\__,_|
|
|
105
|
-
`;
|
|
106
|
-
|
|
107
|
-
// src/utils/validate-project-name.ts
|
|
108
|
-
import validate from "validate-npm-package-name";
|
|
109
|
-
function validateProjectName(name) {
|
|
110
|
-
const nameValidation = validate(name);
|
|
111
|
-
if (nameValidation.validForNewPackages) {
|
|
112
|
-
return { valid: true };
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
valid: false,
|
|
116
|
-
problems: [
|
|
117
|
-
...nameValidation.errors || [],
|
|
118
|
-
...nameValidation.warnings || []
|
|
119
|
-
]
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/cli.ts
|
|
124
|
-
var directory = null;
|
|
125
|
-
var newBranchName = null;
|
|
126
|
-
var createNewBranch = null;
|
|
127
|
-
var packageManager = "pnpm";
|
|
128
|
-
var command = new Command(NAME).version(
|
|
129
|
-
VERSION,
|
|
130
|
-
"-v, --version",
|
|
131
|
-
`Output the current version of ${NAME}.`
|
|
132
|
-
).argument("[directory]", "The directory name for the new project.").usage("[directory] [options]").helpOption("-h, --help", "Display this help message.").option("--skip-new-branch", "Skip creating a new branch during initialization.", false).option("--skip-install", "Skip the installation of packages.", false).option("--skip-generate", "Skip generating SQL files.", false).option("--skip-clean", "Skip cleaning the `cella` template.", false).option("--skip-git", "Skip initializing a git repository.", false).option(
|
|
133
|
-
"--new-branch-name <name>",
|
|
134
|
-
"Specify a new branch name to create and use.",
|
|
135
|
-
(name) => {
|
|
136
|
-
if (typeof name === "string") {
|
|
137
|
-
name = name.trim();
|
|
138
|
-
}
|
|
139
|
-
if (name) {
|
|
140
|
-
const validation = validateProjectName(basename(resolve(name)));
|
|
141
|
-
if (!validation.valid) {
|
|
142
|
-
throw new InvalidArgumentError(
|
|
143
|
-
`Invalid branch name: ${validation.problems[0]}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
createNewBranch = true;
|
|
147
|
-
newBranchName = name;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
).action((name) => {
|
|
151
|
-
if (typeof name === "string") {
|
|
152
|
-
name = name.trim();
|
|
153
|
-
}
|
|
154
|
-
if (name) {
|
|
155
|
-
const validation = validateProjectName(basename(resolve(name)));
|
|
156
|
-
if (!validation.valid) {
|
|
157
|
-
throw new InvalidArgumentError(
|
|
158
|
-
`Invalid project name: ${validation.problems[0]}`
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
directory = name;
|
|
162
|
-
}
|
|
163
|
-
}).parse();
|
|
164
|
-
var options = command.opts({
|
|
165
|
-
skipNewBranch: false,
|
|
166
|
-
skipClean: false,
|
|
167
|
-
skipGit: false,
|
|
168
|
-
skipInstall: false,
|
|
169
|
-
skipGenerate: false
|
|
170
|
-
});
|
|
171
|
-
var cli = {
|
|
172
|
-
options,
|
|
173
|
-
args: command.args,
|
|
174
|
-
directory,
|
|
175
|
-
newBranchName,
|
|
176
|
-
createNewBranch,
|
|
177
|
-
packageManager
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
// src/utils/is-empty-directory.ts
|
|
181
|
-
import { readdir } from "node:fs/promises";
|
|
182
|
-
async function isEmptyDirectory(path2) {
|
|
183
|
-
const files = await readdir(path2);
|
|
184
|
-
return files.length === 0 || files.length === 1 && files[0] === ".git";
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// src/create.ts
|
|
188
|
-
import { mkdir } from "node:fs/promises";
|
|
189
|
-
import { existsSync } from "node:fs";
|
|
190
|
-
import { join, relative } from "node:path";
|
|
191
|
-
import colors2 from "picocolors";
|
|
192
|
-
import { downloadTemplate } from "giget";
|
|
193
|
-
import yoctoSpinner2 from "yocto-spinner";
|
|
194
|
-
|
|
195
|
-
// src/utils/run-package-manager-command.ts
|
|
196
|
-
import spawn from "cross-spawn";
|
|
197
|
-
async function runPackageManagerCommand(packageManager2, args, env = {}) {
|
|
198
|
-
return new Promise((resolve3, reject) => {
|
|
199
|
-
const child = spawn(packageManager2, args, {
|
|
200
|
-
env: {
|
|
201
|
-
...process.env,
|
|
202
|
-
...env
|
|
203
|
-
},
|
|
204
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
205
|
-
});
|
|
206
|
-
let stderrBuffer = "";
|
|
207
|
-
let stdoutBuffer = "";
|
|
208
|
-
child.stderr?.on("data", (data) => {
|
|
209
|
-
stderrBuffer += data.toString();
|
|
210
|
-
});
|
|
211
|
-
child.stdout?.on("data", (data) => {
|
|
212
|
-
stdoutBuffer += data.toString();
|
|
213
|
-
});
|
|
214
|
-
child.on("close", (code) => {
|
|
215
|
-
if (code !== 0) {
|
|
216
|
-
reject(
|
|
217
|
-
`"${packageManager2} ${args.join(" ")}" failed ${stdoutBuffer} ${stderrBuffer}`
|
|
218
|
-
);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
resolve3();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
async function install(packageManager2) {
|
|
226
|
-
return runPackageManagerCommand(packageManager2, ["install"], {
|
|
227
|
-
NODE_ENV: "development"
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
async function generate(packageManager2) {
|
|
231
|
-
return runPackageManagerCommand(packageManager2, ["generate"], {
|
|
232
|
-
NODE_ENV: "development"
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// src/utils/clean-template.ts
|
|
237
|
-
import fs from "node:fs/promises";
|
|
238
|
-
import path from "node:path";
|
|
239
|
-
import colors from "picocolors";
|
|
240
|
-
async function cleanTemplate({
|
|
241
|
-
targetFolder,
|
|
242
|
-
projectName
|
|
243
|
-
}) {
|
|
244
|
-
if (process.cwd() !== targetFolder) {
|
|
245
|
-
process.chdir(targetFolder);
|
|
246
|
-
}
|
|
247
|
-
return new Promise(async (resolve3, reject) => {
|
|
248
|
-
try {
|
|
249
|
-
for (const [src, dest] of Object.entries(TO_COPY)) {
|
|
250
|
-
const srcAbsolutePath = path.resolve(targetFolder, src);
|
|
251
|
-
const destAbsolutePath = path.resolve(targetFolder, dest);
|
|
252
|
-
await copyFile(srcAbsolutePath, destAbsolutePath);
|
|
253
|
-
}
|
|
254
|
-
await Promise.all(
|
|
255
|
-
TO_CLEAN.map((folderPath) => {
|
|
256
|
-
const absolutePath = path.resolve(targetFolder, folderPath);
|
|
257
|
-
return removeFolderContents(absolutePath);
|
|
258
|
-
})
|
|
259
|
-
);
|
|
260
|
-
await Promise.all(
|
|
261
|
-
TO_REMOVE.map((filePath) => {
|
|
262
|
-
const absolutePath = path.resolve(targetFolder, filePath);
|
|
263
|
-
return removeFileOrFolder(absolutePath);
|
|
264
|
-
})
|
|
265
|
-
);
|
|
266
|
-
await Promise.all(
|
|
267
|
-
Object.entries(TO_EDIT).map(async ([filePath, edits]) => {
|
|
268
|
-
const absolutePath = path.resolve(targetFolder, filePath);
|
|
269
|
-
await editFile(absolutePath, edits);
|
|
270
|
-
})
|
|
271
|
-
);
|
|
272
|
-
resolve3();
|
|
273
|
-
} catch (err) {
|
|
274
|
-
reject(`Error during the cleaning process: ${err}`);
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
async function removeFolderContents(folderPath) {
|
|
279
|
-
const files = await fs.readdir(folderPath);
|
|
280
|
-
await Promise.all(
|
|
281
|
-
files.map(async (file) => {
|
|
282
|
-
const filePath = path.join(folderPath, file);
|
|
283
|
-
const stat = await fs.lstat(filePath);
|
|
284
|
-
if (stat.isDirectory()) {
|
|
285
|
-
await fs.rm(filePath, { recursive: true, force: true });
|
|
286
|
-
} else {
|
|
287
|
-
await fs.rm(filePath);
|
|
288
|
-
}
|
|
289
|
-
})
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
async function removeFileOrFolder(pathToRemove) {
|
|
293
|
-
await fs.rm(pathToRemove, { recursive: true, force: true });
|
|
294
|
-
}
|
|
295
|
-
async function copyFile(src, dest) {
|
|
296
|
-
try {
|
|
297
|
-
await fs.access(src);
|
|
298
|
-
await fs.mkdir(path.dirname(dest), { recursive: true });
|
|
299
|
-
await fs.copyFile(src, dest);
|
|
300
|
-
} catch (err) {
|
|
301
|
-
if (err.code === "ENOENT") {
|
|
302
|
-
console.info(`
|
|
303
|
-
${colors.yellow("\u26A0")} Source file "${src}" does not exist > Skip copy`);
|
|
304
|
-
} else {
|
|
305
|
-
throw err;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
async function editFile(filePath, edits) {
|
|
310
|
-
try {
|
|
311
|
-
await fs.access(filePath);
|
|
312
|
-
const fileContent = await fs.readFile(filePath, "utf8");
|
|
313
|
-
let updatedContent = fileContent;
|
|
314
|
-
edits.forEach(({ regexMatch, replaceWith }) => {
|
|
315
|
-
updatedContent = updatedContent.replace(regexMatch, replaceWith);
|
|
316
|
-
});
|
|
317
|
-
if (fileContent !== updatedContent) {
|
|
318
|
-
await fs.writeFile(filePath, updatedContent, "utf8");
|
|
319
|
-
}
|
|
320
|
-
} catch (err) {
|
|
321
|
-
if (err.code === "ENOENT") {
|
|
322
|
-
console.info(`
|
|
323
|
-
${colors.yellow("\u26A0")} Source file "${filePath}" does not exist > Skip edit`);
|
|
324
|
-
} else {
|
|
325
|
-
throw err;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// src/utils/run-git-command.ts
|
|
331
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
332
|
-
function getGitCommandType(command2) {
|
|
333
|
-
if (command2.startsWith("merge")) return "merge";
|
|
334
|
-
if (command2.startsWith("diff")) return "diff";
|
|
335
|
-
return "other";
|
|
336
|
-
}
|
|
337
|
-
function isGitCommandSuccess(gitCommand, code, errOutput) {
|
|
338
|
-
if (gitCommand === "merge") return code === 0 || code === 1 && !errOutput;
|
|
339
|
-
if (gitCommand === "diff") return code === 0 || code === 2 && !errOutput;
|
|
340
|
-
return code === 0;
|
|
341
|
-
}
|
|
342
|
-
async function runGitCommand({ targetFolder, command: command2 }) {
|
|
343
|
-
return new Promise((resolve3, reject) => {
|
|
344
|
-
const gitCommand = getGitCommandType(command2);
|
|
345
|
-
const child = spawn2(`git ${command2}`, [], { cwd: targetFolder, shell: true, timeout: 6e4 });
|
|
346
|
-
let output = "";
|
|
347
|
-
let errOutput = "";
|
|
348
|
-
child.on("error", (error) => {
|
|
349
|
-
reject(error);
|
|
350
|
-
});
|
|
351
|
-
child.on("exit", (code) => {
|
|
352
|
-
if (isGitCommandSuccess(gitCommand, code, errOutput)) {
|
|
353
|
-
resolve3(output.trim());
|
|
354
|
-
} else {
|
|
355
|
-
reject(
|
|
356
|
-
`Git ${gitCommand} command failed with exit code ${code}, stderr: "${errOutput.trim()}", stdout: "${output.trim()}"`
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
child.stdout.on("data", (data) => {
|
|
361
|
-
output += data.toString();
|
|
362
|
-
});
|
|
363
|
-
child.stderr.on("data", (data) => {
|
|
364
|
-
errOutput += data.toString();
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// src/add-remote.ts
|
|
370
|
-
import yoctoSpinner from "yocto-spinner";
|
|
371
|
-
async function addRemote({
|
|
372
|
-
targetFolder,
|
|
373
|
-
remoteUrl = CELLA_REMOTE_URL,
|
|
374
|
-
remoteName = "upstream"
|
|
375
|
-
}) {
|
|
376
|
-
const remoteSpinner = yoctoSpinner({
|
|
377
|
-
text: "Adding remote"
|
|
378
|
-
}).start();
|
|
379
|
-
try {
|
|
380
|
-
let remote = null;
|
|
381
|
-
try {
|
|
382
|
-
remote = await runGitCommand({ targetFolder, command: `remote get-url ${remoteName}` });
|
|
383
|
-
} catch (error) {
|
|
384
|
-
remote = null;
|
|
385
|
-
}
|
|
386
|
-
if (!remote) {
|
|
387
|
-
await runGitCommand({ targetFolder, command: `remote add ${remoteName} ${remoteUrl}` });
|
|
388
|
-
remoteSpinner.success("Remote added successfully.");
|
|
389
|
-
} else if (remote !== remoteUrl) {
|
|
390
|
-
await runGitCommand({ targetFolder, command: `remote remove ${remoteName}` });
|
|
391
|
-
await runGitCommand({ targetFolder, command: `remote add ${remoteName} ${remoteUrl}` });
|
|
392
|
-
remoteSpinner.success("Remote updated successfully.");
|
|
393
|
-
} else {
|
|
394
|
-
remoteSpinner.success("Remote is already configured correctly.");
|
|
395
|
-
}
|
|
396
|
-
} catch (error) {
|
|
397
|
-
console.error(error);
|
|
398
|
-
remoteSpinner.error("Failed to add remote.");
|
|
399
|
-
process.exit(1);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// src/create.ts
|
|
404
|
-
async function create({
|
|
405
|
-
projectName,
|
|
406
|
-
targetFolder,
|
|
407
|
-
newBranchName: newBranchName2,
|
|
408
|
-
skipInstall,
|
|
409
|
-
skipGit,
|
|
410
|
-
skipClean,
|
|
411
|
-
skipGenerate,
|
|
412
|
-
packageManager: packageManager2
|
|
413
|
-
}) {
|
|
414
|
-
const originalCwd = process.cwd();
|
|
415
|
-
console.info();
|
|
416
|
-
const createFolderSpinner = yoctoSpinner2({
|
|
417
|
-
text: "Creating project folder"
|
|
418
|
-
}).start();
|
|
419
|
-
await mkdir(targetFolder, { recursive: true });
|
|
420
|
-
process.chdir(targetFolder);
|
|
421
|
-
createFolderSpinner.success("Project folder created");
|
|
422
|
-
const downloadSpinner = yoctoSpinner2({
|
|
423
|
-
text: "Downloading `cella` template"
|
|
424
|
-
}).start();
|
|
425
|
-
await downloadTemplate(TEMPLATE_URL, {
|
|
426
|
-
cwd: process.cwd(),
|
|
427
|
-
dir: targetFolder,
|
|
428
|
-
force: true,
|
|
429
|
-
provider: "github"
|
|
430
|
-
});
|
|
431
|
-
downloadSpinner.success("`cella` template downloaded");
|
|
432
|
-
if (!skipClean) {
|
|
433
|
-
const cleanSpinner = yoctoSpinner2({
|
|
434
|
-
text: "cleaning `cella` template"
|
|
435
|
-
}).start();
|
|
436
|
-
try {
|
|
437
|
-
await cleanTemplate({
|
|
438
|
-
targetFolder,
|
|
439
|
-
projectName
|
|
440
|
-
});
|
|
441
|
-
cleanSpinner.success("`cella` template cleaned");
|
|
442
|
-
} catch (e) {
|
|
443
|
-
console.error(e);
|
|
444
|
-
cleanSpinner.error("Failed to clean `cella` template");
|
|
445
|
-
process.exit(1);
|
|
446
|
-
}
|
|
447
|
-
} else {
|
|
448
|
-
console.info(`${colors2.yellow("\u26A0")} --skip-clean > Skip cleaning \`cella\` template`);
|
|
449
|
-
}
|
|
450
|
-
if (!skipInstall) {
|
|
451
|
-
const installSpinner = yoctoSpinner2({
|
|
452
|
-
text: "installing dependencies"
|
|
453
|
-
}).start();
|
|
454
|
-
try {
|
|
455
|
-
await install(packageManager2);
|
|
456
|
-
installSpinner.success("Dependencies installed");
|
|
457
|
-
} catch (e) {
|
|
458
|
-
console.error(e);
|
|
459
|
-
installSpinner.error("Failed to install dependencies");
|
|
460
|
-
process.exit(1);
|
|
461
|
-
}
|
|
462
|
-
} else {
|
|
463
|
-
console.info(`${colors2.yellow("\u26A0")} --skip-install > Skip installing dependencies`);
|
|
464
|
-
}
|
|
465
|
-
if (!skipGenerate) {
|
|
466
|
-
const generateSpinner = yoctoSpinner2({
|
|
467
|
-
text: "generating SQL files"
|
|
468
|
-
}).start();
|
|
469
|
-
try {
|
|
470
|
-
await generate(packageManager2);
|
|
471
|
-
generateSpinner.success("SQL files generated");
|
|
472
|
-
} catch (e) {
|
|
473
|
-
console.error(e);
|
|
474
|
-
generateSpinner.error("Failed to generate SQL files");
|
|
475
|
-
process.exit(1);
|
|
476
|
-
}
|
|
477
|
-
} else {
|
|
478
|
-
console.info(`${colors2.yellow("\u26A0")} --skip-generate > Skip generating SQL files`);
|
|
479
|
-
}
|
|
480
|
-
if (!skipGit) {
|
|
481
|
-
const gitSpinner = yoctoSpinner2({
|
|
482
|
-
text: "initializing git repository"
|
|
483
|
-
}).start();
|
|
484
|
-
const gitFolderPath = join(targetFolder, ".git");
|
|
485
|
-
if (!existsSync(gitFolderPath)) {
|
|
486
|
-
try {
|
|
487
|
-
await runGitCommand({ targetFolder, command: "init" });
|
|
488
|
-
await runGitCommand({ targetFolder, command: "add ." });
|
|
489
|
-
await runGitCommand({ targetFolder, command: 'commit -m "Initial commit"' });
|
|
490
|
-
if (newBranchName2) {
|
|
491
|
-
await runGitCommand({ targetFolder, command: `branch ${newBranchName2}` });
|
|
492
|
-
await runGitCommand({ targetFolder, command: `checkout ${newBranchName2}` });
|
|
493
|
-
gitSpinner.success(`Git repository initialized, initial commit created, and new branch ${newBranchName2} created`);
|
|
494
|
-
} else {
|
|
495
|
-
gitSpinner.success("Git repository initialized and initial commit created");
|
|
496
|
-
}
|
|
497
|
-
} catch (e) {
|
|
498
|
-
console.error(e);
|
|
499
|
-
gitSpinner.error("Failed to initialize Git repository or create branch");
|
|
500
|
-
process.exit(1);
|
|
501
|
-
}
|
|
502
|
-
} else {
|
|
503
|
-
gitSpinner.warning("Git repository already initialized > Skip git init");
|
|
504
|
-
}
|
|
505
|
-
} else {
|
|
506
|
-
console.info(`${colors2.yellow("\u26A0")} --skip-git > Skip git init`);
|
|
507
|
-
}
|
|
508
|
-
await addRemote({ targetFolder });
|
|
509
|
-
console.info();
|
|
510
|
-
console.info(`${colors2.green("Success")} Created ${projectName} at ${targetFolder}`);
|
|
511
|
-
console.info();
|
|
512
|
-
const needsCd = originalCwd !== targetFolder;
|
|
513
|
-
const relativePath = relative(originalCwd, targetFolder);
|
|
514
|
-
if (needsCd) {
|
|
515
|
-
console.info("now go to your project using:");
|
|
516
|
-
console.info(colors2.cyan(` cd ${relativePath}`));
|
|
517
|
-
console.info();
|
|
518
|
-
}
|
|
519
|
-
console.info(`${needsCd ? "then " : ""}quick start using pglite with:`);
|
|
520
|
-
console.info(colors2.cyan(` ${packageManager2} quick`));
|
|
521
|
-
console.info();
|
|
522
|
-
console.info("Already have docker installed? Then you can run a full setup:");
|
|
523
|
-
console.info(colors2.cyan(` ${packageManager2} docker`));
|
|
524
|
-
console.info(colors2.cyan(` ${packageManager2} dev`));
|
|
525
|
-
console.info(colors2.cyan(` ${packageManager2} seed`));
|
|
526
|
-
console.info();
|
|
527
|
-
console.info(`Once running, you can sign in using:`);
|
|
528
|
-
console.info(`email: ${colors2.greenBright("admin-test@cellajs.com")}`);
|
|
529
|
-
console.info(`password: ${colors2.greenBright("12345678")}`);
|
|
530
|
-
console.info();
|
|
531
|
-
console.info(`For more info, check out: ${relativePath}/README.md`);
|
|
532
|
-
console.info(`Enjoy building ${projectName} using cella! \u{1F389}`);
|
|
533
|
-
console.info();
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
// src/index.ts
|
|
537
|
-
async function main() {
|
|
538
|
-
console.info(LOGO);
|
|
539
|
-
console.info();
|
|
540
|
-
console.info(DESCRIPTION);
|
|
541
|
-
console.info();
|
|
542
|
-
console.info(`Version ${colors3.green(VERSION)}`);
|
|
543
|
-
console.info(`Created by ${AUTHOR}`);
|
|
544
|
-
console.info(`${GITHUB} | ${WEBSITE}`);
|
|
545
|
-
console.info();
|
|
546
|
-
if (cli.options.skipNewBranch || cli.options.skipGit) {
|
|
547
|
-
cli.createNewBranch = false;
|
|
548
|
-
cli.newBranchName = null;
|
|
549
|
-
}
|
|
550
|
-
if (cli.options.skipGenerate === true) {
|
|
551
|
-
cli.options.skipGenerate = true;
|
|
552
|
-
}
|
|
553
|
-
if (cli.options.skipInstall === true) {
|
|
554
|
-
cli.options.skipInstall = true;
|
|
555
|
-
}
|
|
556
|
-
if (cli.options.skipClean === true) {
|
|
557
|
-
cli.options.skipClean = true;
|
|
558
|
-
}
|
|
559
|
-
if (cli.options.skipGit === true) {
|
|
560
|
-
cli.options.skipGit = true;
|
|
561
|
-
}
|
|
562
|
-
if (!cli.directory) {
|
|
563
|
-
cli.directory = await input({
|
|
564
|
-
message: "Enter your project name",
|
|
565
|
-
default: "my-cella-app",
|
|
566
|
-
validate: (name) => {
|
|
567
|
-
const validation = validateProjectName(basename2(resolve2(name)));
|
|
568
|
-
return validation.valid ? true : `Invalid project name: ${validation.problems[0]}`;
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
if (cli.createNewBranch === null) {
|
|
573
|
-
cli.createNewBranch = await confirm({
|
|
574
|
-
message: 'Would you like to create a new branch (besides "main")?',
|
|
575
|
-
default: true
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
if (!cli.newBranchName && cli.createNewBranch) {
|
|
579
|
-
cli.newBranchName = await input({
|
|
580
|
-
message: "Enter the new branch name",
|
|
581
|
-
default: "development",
|
|
582
|
-
validate: (name) => {
|
|
583
|
-
const validation = validateProjectName(basename2(resolve2(name)));
|
|
584
|
-
return validation.valid ? true : `Invalid branch name: ${validation.problems[0]}`;
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
const targetFolder = resolve2(cli.directory);
|
|
589
|
-
const projectName = basename2(targetFolder);
|
|
590
|
-
if (existsSync2(targetFolder) && !await isEmptyDirectory(targetFolder)) {
|
|
591
|
-
const dirName = cli.directory === "." ? "Current directory" : `Target directory "${targetFolder}"`;
|
|
592
|
-
const message = `${dirName} is not empty. Please choose how you would like to proceed:`;
|
|
593
|
-
const action = await select({
|
|
594
|
-
message,
|
|
595
|
-
choices: [
|
|
596
|
-
{ name: "Cancel and exit", value: "cancel" },
|
|
597
|
-
{ name: "Ignore existing files and continue", value: "ignore" }
|
|
598
|
-
]
|
|
599
|
-
});
|
|
600
|
-
if (action === "cancel") {
|
|
601
|
-
process.exit(1);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
const createOptions = {
|
|
605
|
-
projectName,
|
|
606
|
-
targetFolder,
|
|
607
|
-
newBranchName: cli.newBranchName,
|
|
608
|
-
skipInstall: cli.options.skipInstall,
|
|
609
|
-
skipGit: cli.options.skipGit,
|
|
610
|
-
skipClean: cli.options.skipClean,
|
|
611
|
-
skipGenerate: cli.options.skipGenerate,
|
|
612
|
-
packageManager: cli.packageManager
|
|
613
|
-
};
|
|
614
|
-
await create(createOptions);
|
|
615
|
-
}
|
|
616
|
-
main().catch(console.error);
|
|
617
|
-
//# sourceMappingURL=index.js.map
|