create-magek 0.0.1

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +419 -0
  2. package/package.json +58 -0
package/dist/cli.cjs ADDED
@@ -0,0 +1,419 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+
34
+ // package.json
35
+ var require_package = __commonJS({
36
+ "package.json"(exports2, module2) {
37
+ module2.exports = {
38
+ name: "create-magek",
39
+ version: "0.0.1",
40
+ description: "Create Magek AI applications with one command",
41
+ type: "module",
42
+ main: "dist/cli.cjs",
43
+ bin: {
44
+ "create-magek": "dist/cli.cjs"
45
+ },
46
+ files: [
47
+ "dist/**/*"
48
+ ],
49
+ engines: {
50
+ node: ">=22.0.0 <23.0.0"
51
+ },
52
+ scripts: {
53
+ format: "prettier --write --ext '.js,.ts' **/*.ts **/*/*.ts",
54
+ "lint:check": 'eslint "**/*.ts"',
55
+ "lint:fix": 'eslint --quiet --fix "**/*.ts"',
56
+ build: "tsup src/cli.ts --format cjs --target node22 --outDir dist --clean",
57
+ clean: "rimraf ./dist tsconfig.tsbuildinfo",
58
+ prepack: "npm run build",
59
+ "test:create": "npm run test",
60
+ test: "mocha test/**/*.test.ts"
61
+ },
62
+ keywords: [
63
+ "magek",
64
+ "scaffold",
65
+ "generator",
66
+ "cli"
67
+ ],
68
+ author: "Boosterin Labs SLU",
69
+ license: "Apache-2.0",
70
+ dependencies: {
71
+ degit: "2.8.4",
72
+ prompts: "2.4.2",
73
+ kleur: "4.1.5",
74
+ globby: "16.1.0"
75
+ },
76
+ devDependencies: {
77
+ "@magek/eslint-config": "workspace:^0.0.1",
78
+ "@types/node": "22.19.3",
79
+ "@types/prompts": "2.4.9",
80
+ "@types/chai": "5.2.3",
81
+ "@types/mocha": "10.0.10",
82
+ "@types/sinon": "21.0.0",
83
+ chai: "6.2.2",
84
+ mocha: "11.7.5",
85
+ sinon: "21.0.1",
86
+ tsx: "^4.19.2",
87
+ tsup: "8.5.1",
88
+ typescript: "5.9.3",
89
+ "@types/degit": "~2.8.6",
90
+ rimraf: "6.1.2"
91
+ },
92
+ publishConfig: {
93
+ access: "public"
94
+ }
95
+ };
96
+ }
97
+ });
98
+
99
+ // src/cli.ts
100
+ var cli_exports = {};
101
+ __export(cli_exports, {
102
+ assertNameIsCorrect: () => assertNameIsCorrect,
103
+ checkProjectAlreadyExists: () => checkProjectAlreadyExists,
104
+ main: () => main,
105
+ replaceInFile: () => replaceInFile
106
+ });
107
+ module.exports = __toCommonJS(cli_exports);
108
+ var fs = __toESM(require("fs"), 1);
109
+ var path = __toESM(require("path"), 1);
110
+ var import_degit = __toESM(require("degit"), 1);
111
+ var import_prompts = __toESM(require("prompts"), 1);
112
+ var import_kleur = __toESM(require("kleur"), 1);
113
+ var import_globby = require("globby");
114
+ var import_child_process = require("child_process");
115
+ var defaultFileSystem = {
116
+ existsSync: fs.existsSync,
117
+ readFileSync: fs.readFileSync,
118
+ writeFileSync: fs.writeFileSync,
119
+ statSync: fs.statSync
120
+ };
121
+ function getMagekVersion() {
122
+ if (typeof require !== "undefined") {
123
+ try {
124
+ return require_package().version;
125
+ } catch {
126
+ }
127
+ }
128
+ return "0.0.1";
129
+ }
130
+ var ForbiddenProjectName = class extends Error {
131
+ constructor(name, restrictionText) {
132
+ super(`Project name cannot ${restrictionText}:
133
+
134
+ Found: '${name}'`);
135
+ this.name = name;
136
+ this.restrictionText = restrictionText;
137
+ }
138
+ };
139
+ function assertNameIsCorrect(name) {
140
+ const maxProjectNameLength = 214;
141
+ if (name.length > maxProjectNameLength)
142
+ throw new ForbiddenProjectName(name, `be longer than ${maxProjectNameLength} characters`);
143
+ if (name.includes(" ")) throw new ForbiddenProjectName(name, "contain spaces");
144
+ if (name.toLowerCase() !== name) throw new ForbiddenProjectName(name, "contain uppercase letters");
145
+ if (/[~)('!*]/.test(name)) throw new ForbiddenProjectName(name, "contain URL-unsafe characters (~)'(!*)");
146
+ if (name.startsWith(".") || name.startsWith("_")) throw new ForbiddenProjectName(name, "begin with . or _");
147
+ if (name.trim() !== name) throw new ForbiddenProjectName(name, "have leading or trailing spaces");
148
+ const reservedNames = ["http", "node_modules", "favicon.ico", "npm", "node", "js", "json"];
149
+ if (reservedNames.includes(name.toLowerCase())) throw new ForbiddenProjectName(name, `be a reserved name (${name})`);
150
+ }
151
+ function checkProjectAlreadyExists(name, fileSystem = defaultFileSystem) {
152
+ const projectPath = path.join(process.cwd(), name);
153
+ if (fileSystem.existsSync(projectPath)) {
154
+ throw new Error(
155
+ `Directory "${name}" already exists. Please choose a different project name or remove the existing directory.`
156
+ );
157
+ }
158
+ }
159
+ async function runCommand(command, args, cwd) {
160
+ return new Promise((resolve, reject) => {
161
+ const child = (0, import_child_process.spawn)(command, args, {
162
+ cwd,
163
+ stdio: "inherit",
164
+ shell: process.platform === "win32"
165
+ });
166
+ child.on("close", (code) => {
167
+ if (code === 0) {
168
+ resolve();
169
+ } else {
170
+ reject(new Error(`Command failed with exit code ${code}`));
171
+ }
172
+ });
173
+ child.on("error", reject);
174
+ });
175
+ }
176
+ async function replaceInFile(filePath, replacements, fileSystem = defaultFileSystem) {
177
+ if (!fileSystem.existsSync(filePath)) return;
178
+ let content = fileSystem.readFileSync(filePath, "utf-8");
179
+ for (const [placeholder, value] of Object.entries(replacements)) {
180
+ const regex = new RegExp(`\\{\\{${placeholder}\\}\\}`, "g");
181
+ content = content.replace(regex, value);
182
+ }
183
+ fileSystem.writeFileSync(filePath, content, "utf-8");
184
+ }
185
+ async function replaceInAllFiles(targetDir, replacements, fileSystem = defaultFileSystem) {
186
+ const files = await (0, import_globby.globby)(["**/*", "!node_modules/**", "!.git/**", "!**/node_modules/**"], {
187
+ cwd: targetDir,
188
+ dot: true,
189
+ absolute: true
190
+ });
191
+ for (const file of files) {
192
+ const stat = fileSystem.statSync(file);
193
+ if (stat.isFile()) {
194
+ await replaceInFile(file, replacements, fileSystem);
195
+ }
196
+ }
197
+ }
198
+ var defaults = {
199
+ description: "",
200
+ version: "0.1.0",
201
+ author: "",
202
+ homepage: "",
203
+ license: "MIT",
204
+ repository: "",
205
+ packageManager: "npm",
206
+ skipInstall: false,
207
+ skipGit: false
208
+ };
209
+ async function collectProjectInfo(args) {
210
+ const projectName = args[0];
211
+ if (!projectName) {
212
+ console.error(import_kleur.default.red("Error: Project name is required"));
213
+ console.log("Usage: npm create magek@latest <project-name>");
214
+ process.exit(1);
215
+ }
216
+ assertNameIsCorrect(projectName);
217
+ checkProjectAlreadyExists(projectName);
218
+ const flags = {};
219
+ for (let i = 1; i < args.length; i++) {
220
+ const arg = args[i];
221
+ if (arg.startsWith("--")) {
222
+ const key = arg.slice(2);
223
+ const nextArg = args[i + 1];
224
+ if (nextArg && !nextArg.startsWith("--")) {
225
+ flags[key] = nextArg;
226
+ i++;
227
+ } else {
228
+ flags[key] = true;
229
+ }
230
+ }
231
+ }
232
+ const shouldSkipPrompts = flags["skip-install"] || flags["skip-git"] || flags.description || flags.version || flags.author || flags.homepage || flags.license || flags.repository || flags["package-manager"];
233
+ let config;
234
+ if (shouldSkipPrompts) {
235
+ config = {
236
+ projectName,
237
+ description: flags.description || defaults.description,
238
+ version: flags.version || defaults.version,
239
+ author: flags.author || defaults.author,
240
+ homepage: flags.homepage || defaults.homepage,
241
+ license: flags.license || defaults.license,
242
+ repository: flags.repository || defaults.repository,
243
+ packageManager: flags["package-manager"] || defaults.packageManager,
244
+ template: flags.template,
245
+ skipInstall: flags["skip-install"] || defaults.skipInstall,
246
+ skipGit: flags["skip-git"] || defaults.skipGit
247
+ };
248
+ } else {
249
+ const responses = await (0, import_prompts.default)([
250
+ {
251
+ type: "text",
252
+ name: "description",
253
+ message: "What's your project description?",
254
+ initial: flags.description || defaults.description
255
+ },
256
+ {
257
+ type: "text",
258
+ name: "version",
259
+ message: "What's the first version?",
260
+ initial: flags.version || defaults.version
261
+ },
262
+ {
263
+ type: "text",
264
+ name: "author",
265
+ message: "Who's the author?",
266
+ initial: flags.author || defaults.author
267
+ },
268
+ {
269
+ type: "text",
270
+ name: "homepage",
271
+ message: "What's the website?",
272
+ initial: flags.homepage || defaults.homepage
273
+ },
274
+ {
275
+ type: "text",
276
+ name: "license",
277
+ message: "What license will you be publishing this under?",
278
+ initial: flags.license || defaults.license
279
+ },
280
+ {
281
+ type: "text",
282
+ name: "repository",
283
+ message: "What's the URL of the repository?",
284
+ initial: flags.repository || defaults.repository
285
+ },
286
+ {
287
+ type: "select",
288
+ name: "packageManager",
289
+ message: "Which package manager would you like to use?",
290
+ choices: [
291
+ { title: "npm", value: "npm" },
292
+ { title: "pnpm", value: "pnpm" }
293
+ ],
294
+ initial: flags["package-manager"] === "pnpm" ? 1 : 0
295
+ }
296
+ ]);
297
+ config = {
298
+ projectName,
299
+ description: responses.description || defaults.description,
300
+ version: responses.version || defaults.version,
301
+ author: responses.author || defaults.author,
302
+ homepage: responses.homepage || defaults.homepage,
303
+ license: responses.license || defaults.license,
304
+ repository: responses.repository || defaults.repository,
305
+ packageManager: responses.packageManager || defaults.packageManager,
306
+ template: flags.template,
307
+ skipInstall: flags["skip-install"] || defaults.skipInstall,
308
+ skipGit: flags["skip-git"] || defaults.skipGit
309
+ };
310
+ }
311
+ return config;
312
+ }
313
+ async function createProject(config) {
314
+ const targetDir = path.join(process.cwd(), config.projectName);
315
+ console.log(import_kleur.default.blue("\u{1F4E6} Creating project..."));
316
+ const templateSource = config.template || "github.com/theam/magek/templates/default";
317
+ try {
318
+ const isLocalPath = templateSource.startsWith("/") || templateSource.startsWith("./") || templateSource.startsWith("../");
319
+ if (isLocalPath) {
320
+ console.log(import_kleur.default.blue("\u{1F4C1} Copying local template..."));
321
+ const fs2 = await import("fs/promises");
322
+ try {
323
+ await fs2.access(templateSource);
324
+ } catch (error) {
325
+ throw new Error(`Template directory not found: ${templateSource}`);
326
+ }
327
+ await fs2.cp(templateSource, targetDir, { recursive: true });
328
+ console.log(import_kleur.default.green("\u2713 Template copied"));
329
+ } else {
330
+ console.log(import_kleur.default.blue("\u{1F310} Cloning template..."));
331
+ const emitter = (0, import_degit.default)(templateSource, { cache: false, force: true });
332
+ await emitter.clone(targetDir);
333
+ console.log(import_kleur.default.green("\u2713 Template copied"));
334
+ }
335
+ console.log(import_kleur.default.blue("\u{1F527} Configuring project..."));
336
+ const replacements = {
337
+ PROJECT_NAME: config.projectName,
338
+ PROJECT_NAME_UPPER: config.projectName.toUpperCase().replace(/-/g, "_"),
339
+ description: config.description,
340
+ version: config.version,
341
+ author: config.author,
342
+ homepage: config.homepage,
343
+ license: config.license,
344
+ repository: config.repository,
345
+ magekVersion: getMagekVersion()
346
+ };
347
+ await replaceInAllFiles(targetDir, replacements);
348
+ console.log(import_kleur.default.green("\u2713 Project configured"));
349
+ if (!config.skipInstall) {
350
+ console.log(import_kleur.default.blue("\u{1F4E6} Installing dependencies..."));
351
+ switch (config.packageManager) {
352
+ case "pnpm":
353
+ await runCommand("pnpm", ["install"], targetDir);
354
+ break;
355
+ case "npm":
356
+ await runCommand("npm", ["install"], targetDir);
357
+ break;
358
+ default:
359
+ throw new Error(`Unsupported package manager: ${config.packageManager}`);
360
+ }
361
+ const nodeModulesPath = path.join(targetDir, "node_modules");
362
+ const hasNodeModules = fs.existsSync(nodeModulesPath) && fs.readdirSync(nodeModulesPath).length > 0;
363
+ if (!hasNodeModules) {
364
+ throw new Error("Dependency installation finished without populating node_modules");
365
+ }
366
+ console.log(import_kleur.default.green("\u2713 Dependencies installed"));
367
+ }
368
+ if (!config.skipGit) {
369
+ console.log(import_kleur.default.blue("\u{1F504} Initializing git repository..."));
370
+ try {
371
+ await runCommand("git", ["init"], targetDir);
372
+ await runCommand("git", ["add", "-A"], targetDir);
373
+ await runCommand("git", ["commit", "-m", "Initial commit"], targetDir);
374
+ console.log(import_kleur.default.green("\u2713 Git repository initialized"));
375
+ } catch (error) {
376
+ console.log(import_kleur.default.yellow('\u26A0 Failed to initialize git repository. You can run "git init" manually.'));
377
+ }
378
+ }
379
+ console.log();
380
+ console.log(import_kleur.default.green("\u{1F389} Project created successfully!"));
381
+ console.log();
382
+ console.log("Next steps:");
383
+ console.log(import_kleur.default.cyan(` cd ${config.projectName}`));
384
+ if (config.skipInstall) {
385
+ console.log(import_kleur.default.cyan(` ${config.packageManager} install`));
386
+ }
387
+ console.log(import_kleur.default.cyan(` ${config.packageManager} run dev`));
388
+ console.log();
389
+ console.log("Learn more at: https://docs.magek.ai");
390
+ } catch (error) {
391
+ console.error(import_kleur.default.red("\u274C Failed to create project:"));
392
+ console.error(error);
393
+ process.exit(1);
394
+ }
395
+ }
396
+ async function main() {
397
+ const args = process.argv.slice(2);
398
+ try {
399
+ const config = await collectProjectInfo(args);
400
+ await createProject(config);
401
+ } catch (error) {
402
+ console.error(import_kleur.default.red("\u274C Error:"), error.message);
403
+ process.exit(1);
404
+ }
405
+ }
406
+ var isMainModule = typeof require !== "undefined" && typeof module !== "undefined" && require.main === module;
407
+ if (isMainModule) {
408
+ main().catch((error) => {
409
+ console.error(import_kleur.default.red("\u274C Unexpected error:"), error);
410
+ process.exit(1);
411
+ });
412
+ }
413
+ // Annotate the CommonJS export names for ESM import in node:
414
+ 0 && (module.exports = {
415
+ assertNameIsCorrect,
416
+ checkProjectAlreadyExists,
417
+ main,
418
+ replaceInFile
419
+ });
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "create-magek",
3
+ "version": "0.0.1",
4
+ "description": "Create Magek AI applications with one command",
5
+ "type": "module",
6
+ "main": "dist/cli.cjs",
7
+ "bin": {
8
+ "create-magek": "dist/cli.cjs"
9
+ },
10
+ "files": [
11
+ "dist/**/*"
12
+ ],
13
+ "engines": {
14
+ "node": ">=22.0.0 <23.0.0"
15
+ },
16
+ "keywords": [
17
+ "magek",
18
+ "scaffold",
19
+ "generator",
20
+ "cli"
21
+ ],
22
+ "author": "Boosterin Labs SLU",
23
+ "license": "Apache-2.0",
24
+ "dependencies": {
25
+ "degit": "2.8.4",
26
+ "prompts": "2.4.2",
27
+ "kleur": "4.1.5",
28
+ "globby": "16.1.0"
29
+ },
30
+ "devDependencies": {
31
+ "@magek/eslint-config": "^0.0.1",
32
+ "@types/node": "22.19.3",
33
+ "@types/prompts": "2.4.9",
34
+ "@types/chai": "5.2.3",
35
+ "@types/mocha": "10.0.10",
36
+ "@types/sinon": "21.0.0",
37
+ "chai": "6.2.2",
38
+ "mocha": "11.7.5",
39
+ "sinon": "21.0.1",
40
+ "tsx": "^4.19.2",
41
+ "tsup": "8.5.1",
42
+ "typescript": "5.9.3",
43
+ "@types/degit": "~2.8.6",
44
+ "rimraf": "6.1.2"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "scripts": {
50
+ "format": "prettier --write --ext '.js,.ts' **/*.ts **/*/*.ts",
51
+ "lint:check": "eslint \"**/*.ts\"",
52
+ "lint:fix": "eslint --quiet --fix \"**/*.ts\"",
53
+ "build": "tsup src/cli.ts --format cjs --target node22 --outDir dist --clean",
54
+ "clean": "rimraf ./dist tsconfig.tsbuildinfo",
55
+ "test:create": "npm run test",
56
+ "test": "mocha test/**/*.test.ts"
57
+ }
58
+ }