@digilogiclabs/create-saas-app 1.9.3 → 1.10.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.
Files changed (86) hide show
  1. package/bin/index.js +1 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cli/commands/add.d.ts +6 -0
  4. package/dist/cli/commands/add.d.ts.map +1 -0
  5. package/dist/cli/commands/add.js +39 -0
  6. package/dist/cli/commands/add.js.map +1 -0
  7. package/dist/cli/commands/create.d.ts +28 -0
  8. package/dist/cli/commands/create.d.ts.map +1 -0
  9. package/dist/cli/commands/create.js +130 -0
  10. package/dist/cli/commands/create.js.map +1 -0
  11. package/dist/cli/commands/index.d.ts +4 -0
  12. package/dist/cli/commands/index.d.ts.map +1 -0
  13. package/dist/cli/commands/index.js +20 -0
  14. package/dist/cli/commands/index.js.map +1 -0
  15. package/dist/cli/commands/update.d.ts +6 -0
  16. package/dist/cli/commands/update.d.ts.map +1 -0
  17. package/dist/cli/commands/update.js +68 -0
  18. package/dist/cli/commands/update.js.map +1 -0
  19. package/dist/cli/index.d.ts +4 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +59 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/cli/prompts/index.d.ts +2 -0
  24. package/dist/cli/prompts/index.d.ts.map +1 -0
  25. package/dist/cli/prompts/index.js +18 -0
  26. package/dist/cli/prompts/index.js.map +1 -0
  27. package/dist/cli/prompts/project-setup.d.ts +5 -0
  28. package/dist/cli/prompts/project-setup.d.ts.map +1 -0
  29. package/dist/cli/prompts/project-setup.js +251 -0
  30. package/dist/cli/prompts/project-setup.js.map +1 -0
  31. package/dist/cli/utils/git.d.ts +9 -0
  32. package/dist/cli/utils/git.d.ts.map +1 -0
  33. package/dist/cli/utils/git.js +77 -0
  34. package/dist/cli/utils/git.js.map +1 -0
  35. package/dist/cli/utils/index.d.ts +5 -0
  36. package/dist/cli/utils/index.d.ts.map +1 -0
  37. package/dist/cli/utils/index.js +21 -0
  38. package/dist/cli/utils/index.js.map +1 -0
  39. package/dist/cli/utils/logger.d.ts +16 -0
  40. package/dist/cli/utils/logger.d.ts.map +1 -0
  41. package/dist/cli/utils/logger.js +55 -0
  42. package/dist/cli/utils/logger.js.map +1 -0
  43. package/dist/cli/utils/package-manager.d.ts +8 -0
  44. package/dist/cli/utils/package-manager.d.ts.map +1 -0
  45. package/dist/cli/utils/package-manager.js +92 -0
  46. package/dist/cli/utils/package-manager.js.map +1 -0
  47. package/dist/cli/utils/spinner.d.ts +7 -0
  48. package/dist/cli/utils/spinner.d.ts.map +1 -0
  49. package/dist/cli/utils/spinner.js +48 -0
  50. package/dist/cli/utils/spinner.js.map +1 -0
  51. package/dist/cli/validators/dependencies.d.ts +15 -0
  52. package/dist/cli/validators/dependencies.d.ts.map +1 -0
  53. package/dist/cli/validators/dependencies.js +108 -0
  54. package/dist/cli/validators/dependencies.js.map +1 -0
  55. package/dist/cli/validators/index.d.ts +3 -0
  56. package/dist/cli/validators/index.d.ts.map +1 -0
  57. package/dist/cli/validators/index.js +19 -0
  58. package/dist/cli/validators/index.js.map +1 -0
  59. package/dist/cli/validators/project-name.d.ts +5 -0
  60. package/dist/cli/validators/project-name.d.ts.map +1 -0
  61. package/dist/cli/validators/project-name.js +151 -0
  62. package/dist/cli/validators/project-name.js.map +1 -0
  63. package/dist/generators/file-processor.d.ts +28 -0
  64. package/dist/generators/file-processor.d.ts.map +1 -0
  65. package/dist/generators/file-processor.js +203 -0
  66. package/dist/generators/file-processor.js.map +1 -0
  67. package/dist/generators/index.d.ts +4 -0
  68. package/dist/generators/index.d.ts.map +1 -0
  69. package/dist/generators/index.js +20 -0
  70. package/dist/generators/index.js.map +1 -0
  71. package/dist/generators/package-installer.d.ts +29 -0
  72. package/dist/generators/package-installer.d.ts.map +1 -0
  73. package/dist/generators/package-installer.js +167 -0
  74. package/dist/generators/package-installer.js.map +1 -0
  75. package/dist/generators/template-generator.d.ts.map +1 -1
  76. package/dist/generators/template-generator.js +2 -1
  77. package/dist/generators/template-generator.js.map +1 -1
  78. package/dist/templates/web/ui-auth-payments-audio/template/package.json +2 -2
  79. package/dist/templates/web/ui-auth-payments-audio/template/src/app/globals.css +1 -0
  80. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +17 -17
  81. package/package.json +2 -2
  82. package/src/templates/web/ui-auth-payments-audio/template/package.json +2 -2
  83. package/src/templates/web/ui-auth-payments-audio/template/src/app/globals.css +1 -0
  84. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +17 -17
  85. package/dist/index.js +0 -1173
  86. package/dist/index.js.map +0 -1
package/dist/index.js DELETED
@@ -1,1173 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/cli/index.ts
31
- var cli_exports = {};
32
- __export(cli_exports, {
33
- default: () => cli_default
34
- });
35
- module.exports = __toCommonJS(cli_exports);
36
- var import_commander = require("commander");
37
-
38
- // src/cli/commands/create.ts
39
- var import_path5 = __toESM(require("path"));
40
-
41
- // src/cli/utils/logger.ts
42
- var import_chalk = __toESM(require("chalk"));
43
- var logger = {
44
- info: (message, ...args) => {
45
- console.log(import_chalk.default.blue("\u2139"), message, ...args);
46
- },
47
- success: (message, ...args) => {
48
- console.log(import_chalk.default.green("\u2713"), message, ...args);
49
- },
50
- warn: (message, ...args) => {
51
- console.log(import_chalk.default.yellow("\u26A0"), message, ...args);
52
- },
53
- error: (message, ...args) => {
54
- console.log(import_chalk.default.red("\u2717"), message, ...args);
55
- },
56
- debug: (message, ...args) => {
57
- if (process.env.DEBUG) {
58
- console.log(import_chalk.default.gray("\u{1F41B}"), message, ...args);
59
- }
60
- },
61
- log: (message, ...args) => {
62
- console.log(message, ...args);
63
- },
64
- newLine: () => {
65
- console.log();
66
- },
67
- divider: () => {
68
- console.log(import_chalk.default.gray("\u2500".repeat(50)));
69
- },
70
- title: (message) => {
71
- console.log();
72
- console.log(import_chalk.default.bold.cyan(message));
73
- console.log(import_chalk.default.gray("\u2500".repeat(message.length)));
74
- },
75
- step: (step, total, message) => {
76
- console.log(import_chalk.default.cyan(`[${step}/${total}]`), message);
77
- },
78
- highlight: (message) => {
79
- console.log(import_chalk.default.bold.magenta(message));
80
- },
81
- code: (code) => {
82
- console.log(import_chalk.default.gray(" " + code));
83
- },
84
- list: (items) => {
85
- items.forEach((item) => {
86
- console.log(import_chalk.default.gray(" \u2022"), item);
87
- });
88
- }
89
- };
90
-
91
- // src/cli/utils/spinner.ts
92
- var import_ora = __toESM(require("ora"));
93
- var import_chalk2 = __toESM(require("chalk"));
94
- function spinner(text) {
95
- return (0, import_ora.default)({
96
- text: import_chalk2.default.gray(text),
97
- spinner: "dots",
98
- color: "cyan"
99
- }).start();
100
- }
101
-
102
- // src/cli/validators/project-name.ts
103
- var import_validate_npm_package_name = __toESM(require("validate-npm-package-name"));
104
- var import_path = __toESM(require("path"));
105
- var import_fs_extra = __toESM(require("fs-extra"));
106
- function validateProjectName(name) {
107
- if (!name || name.trim().length === 0) {
108
- logger.error("Project name cannot be empty");
109
- return false;
110
- }
111
- const validation = (0, import_validate_npm_package_name.default)(name);
112
- if (!validation.validForNewPackages) {
113
- logger.error("Invalid project name:");
114
- if (validation.errors) {
115
- validation.errors.forEach((error) => logger.error(` \u2022 ${error}`));
116
- }
117
- if (validation.warnings) {
118
- validation.warnings.forEach((warning) => logger.warn(` \u2022 ${warning}`));
119
- }
120
- return false;
121
- }
122
- const reservedNames = [
123
- "node_modules",
124
- "package.json",
125
- "package-lock.json",
126
- "yarn.lock",
127
- "pnpm-lock.yaml",
128
- ".git",
129
- ".gitignore",
130
- "README.md",
131
- "LICENSE",
132
- "src",
133
- "dist",
134
- "build",
135
- "public",
136
- "static",
137
- "assets",
138
- "components",
139
- "pages",
140
- "app",
141
- "lib",
142
- "utils",
143
- "hooks",
144
- "types",
145
- "styles",
146
- "config",
147
- "test",
148
- "tests",
149
- "__tests__",
150
- "spec",
151
- "specs",
152
- "docs",
153
- "documentation"
154
- ];
155
- if (reservedNames.includes(name.toLowerCase())) {
156
- logger.error(`Project name "${name}" is reserved. Please choose a different name.`);
157
- return false;
158
- }
159
- if (name.startsWith(".")) {
160
- logger.error("Project name cannot start with a dot");
161
- return false;
162
- }
163
- if (name.startsWith("-")) {
164
- logger.error("Project name cannot start with a hyphen");
165
- return false;
166
- }
167
- if (name.endsWith("-")) {
168
- logger.error("Project name cannot end with a hyphen");
169
- return false;
170
- }
171
- if (name.includes("..")) {
172
- logger.error("Project name cannot contain consecutive dots");
173
- return false;
174
- }
175
- if (name.includes("//")) {
176
- logger.error("Project name cannot contain consecutive slashes");
177
- return false;
178
- }
179
- if (name.length > 214) {
180
- logger.error("Project name is too long (max 214 characters)");
181
- return false;
182
- }
183
- return true;
184
- }
185
- async function validateProjectPath(projectPath) {
186
- try {
187
- if (await import_fs_extra.default.pathExists(projectPath)) {
188
- const stats = await import_fs_extra.default.stat(projectPath);
189
- if (stats.isDirectory()) {
190
- const files = await import_fs_extra.default.readdir(projectPath);
191
- if (files.length > 0) {
192
- logger.error(`Directory "${import_path.default.basename(projectPath)}" already exists and is not empty`);
193
- return false;
194
- }
195
- } else {
196
- logger.error(`A file with the name "${import_path.default.basename(projectPath)}" already exists`);
197
- return false;
198
- }
199
- }
200
- const parentDir = import_path.default.dirname(projectPath);
201
- try {
202
- await import_fs_extra.default.access(parentDir, import_fs_extra.default.constants.W_OK);
203
- } catch {
204
- logger.error(`Cannot write to directory "${parentDir}"`);
205
- return false;
206
- }
207
- return true;
208
- } catch (error) {
209
- logger.error("Failed to validate project path:", error);
210
- return false;
211
- }
212
- }
213
- function sanitizeProjectName(name) {
214
- return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-");
215
- }
216
- function suggestProjectName(name) {
217
- const sanitized = sanitizeProjectName(name);
218
- if (validateProjectName(sanitized)) {
219
- return sanitized;
220
- }
221
- const suggested = `my-${sanitized}`;
222
- if (validateProjectName(suggested)) {
223
- return suggested;
224
- }
225
- return "my-saas-app";
226
- }
227
-
228
- // src/cli/validators/dependencies.ts
229
- var import_semver = __toESM(require("semver"));
230
- var import_execa = __toESM(require("execa"));
231
- async function validateNodeVersion() {
232
- const nodeVersion = process.version;
233
- const minVersion = "16.0.0";
234
- if (!import_semver.default.gte(nodeVersion, minVersion)) {
235
- logger.error(
236
- `Node.js version ${minVersion} or higher is required. Current version: ${nodeVersion}`
237
- );
238
- return false;
239
- }
240
- return true;
241
- }
242
-
243
- // src/cli/prompts/project-setup.ts
244
- var import_inquirer = __toESM(require("inquirer"));
245
- async function getProjectPrompts(initialConfig) {
246
- logger.title("\u{1F6E0}\uFE0F Project Configuration");
247
- const questions = [
248
- {
249
- type: "input",
250
- name: "name",
251
- message: "Project name:",
252
- default: initialConfig.name,
253
- validate: (input) => {
254
- if (!validateProjectName(input)) {
255
- const suggestion = suggestProjectName(input);
256
- return `Invalid project name. Try: ${suggestion}`;
257
- }
258
- return true;
259
- },
260
- filter: (input) => input.trim()
261
- },
262
- {
263
- type: "list",
264
- name: "platform",
265
- message: "Select platform:",
266
- choices: [
267
- { name: "\u{1F310} Web (Next.js)", value: "web" },
268
- { name: "\u{1F4F1} Mobile (Expo)", value: "mobile" },
269
- { name: "\u{1F680} Both (Full-stack)", value: "both" }
270
- ],
271
- default: initialConfig.platform
272
- },
273
- {
274
- type: "list",
275
- name: "template",
276
- message: "Select template:",
277
- choices: (answers2) => {
278
- if (answers2.platform === "web") {
279
- return [
280
- { name: "\u{1F4C4} Base - Clean starter template", value: "base" },
281
- {
282
- name: "\u{1F4E6} UI Only - With @digilogiclabs/saas-factory-ui (no auth)",
283
- value: "ui-only"
284
- },
285
- {
286
- name: "\u{1F510} UI + Auth - With UI components and authentication",
287
- value: "ui-auth"
288
- },
289
- {
290
- name: "\u{1F4B3} UI + Auth + Payments - Full SaaS with payments integration",
291
- value: "ui-auth-payments"
292
- },
293
- {
294
- name: "\u{1F3B5} Audio Player App - Full SaaS with audio streaming features",
295
- value: "ui-auth-payments-audio"
296
- },
297
- {
298
- name: "\u{1F3AC} Video Player App - Full SaaS with video streaming features",
299
- value: "ui-auth-payments-video"
300
- },
301
- { name: "\u{1F4CA} Dashboard - Admin dashboard with analytics", value: "dashboard" },
302
- { name: "\u{1F4BC} SaaS - Multi-tenant SaaS application", value: "saas" }
303
- ];
304
- } else if (answers2.platform === "mobile") {
305
- return [
306
- { name: "\u{1F4F1} Base - Simple mobile app", value: "base" },
307
- { name: "\u{1F4D1} Tabs - Tab navigation", value: "tabs" },
308
- { name: "\u{1F4DA} Stack - Stack navigation", value: "stack" }
309
- ];
310
- } else {
311
- return [{ name: "\u{1F680} Base - Web + Mobile starter", value: "base" }];
312
- }
313
- },
314
- default: initialConfig.template
315
- },
316
- {
317
- type: "list",
318
- name: "auth",
319
- message: "Select authentication provider:",
320
- choices: [
321
- { name: "\u26A1 Supabase - Open source alternative", value: "supabase" },
322
- { name: "\u{1F525} Firebase - Google's platform", value: "firebase" }
323
- ],
324
- default: initialConfig.auth
325
- },
326
- {
327
- type: "list",
328
- name: "database",
329
- message: "Select database provider:",
330
- choices: (answers2) => {
331
- const choices = [
332
- { name: "\u26A1 Supabase - PostgreSQL with real-time", value: "supabase" },
333
- { name: "\u{1F525} Firebase - NoSQL with real-time", value: "firebase" }
334
- ];
335
- if (answers2.auth === "firebase") {
336
- return choices.reverse();
337
- }
338
- return choices;
339
- },
340
- default: (answers2) => {
341
- return answers2.auth === "firebase" ? "firebase" : "supabase";
342
- }
343
- },
344
- {
345
- type: "list",
346
- name: "theme",
347
- message: "Select theme:",
348
- choices: [
349
- { name: "\u{1F3A8} Default - Clean and modern", value: "default" },
350
- { name: "\u{1F3E2} Corporate - Professional business theme", value: "corporate" },
351
- { name: "\u{1F680} Startup - Bold and innovative", value: "startup" }
352
- ],
353
- default: initialConfig.theme
354
- },
355
- {
356
- type: "list",
357
- name: "themeColor",
358
- message: "Select theme color:",
359
- choices: [
360
- { name: "\u{1F535} Blue - Classic and trustworthy", value: "blue" },
361
- { name: "\u{1F7E2} Green - Fresh and natural", value: "green" },
362
- { name: "\u{1F7E3} Purple - Creative and modern", value: "purple" },
363
- { name: "\u{1F7E0} Orange - Energetic and friendly", value: "orange" },
364
- { name: "\u{1F534} Red - Bold and attention-grabbing", value: "red" },
365
- { name: "\u26AB Slate - Professional and minimal", value: "slate" }
366
- ],
367
- default: initialConfig.themeColor
368
- },
369
- {
370
- type: "list",
371
- name: "defaultTheme",
372
- message: "Select default theme mode:",
373
- choices: [
374
- { name: "\u{1F319} System - Follow system preference", value: "system" },
375
- { name: "\u2600\uFE0F Light - Always light mode", value: "light" },
376
- { name: "\u{1F319} Dark - Always dark mode", value: "dark" }
377
- ],
378
- default: initialConfig.defaultTheme
379
- },
380
- {
381
- type: "confirm",
382
- name: "install",
383
- message: "Install dependencies?",
384
- default: initialConfig.install
385
- },
386
- {
387
- type: "confirm",
388
- name: "git",
389
- message: "Initialize git repository?",
390
- default: initialConfig.git
391
- }
392
- ];
393
- const answers = await import_inquirer.default.prompt(questions);
394
- return {
395
- ...initialConfig,
396
- ...answers
397
- };
398
- }
399
-
400
- // src/generators/template-generator.ts
401
- var import_path2 = __toESM(require("path"));
402
- var import_fs_extra2 = __toESM(require("fs-extra"));
403
- var import_mustache = __toESM(require("mustache"));
404
- var import_glob = require("glob");
405
- var TemplateGenerator = class {
406
- constructor(config) {
407
- this.config = config;
408
- this.templatesDir = import_path2.default.join(__dirname, "..", "templates");
409
- this.context = this.createTemplateContext();
410
- }
411
- createTemplateContext() {
412
- const projectName = this.config.name;
413
- const packageName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
414
- const className = this.toPascalCase(projectName);
415
- const camelCaseName = this.toCamelCase(projectName);
416
- const kebabCaseName = packageName;
417
- const titleCaseName = this.toTitleCase(projectName);
418
- const dependencies = this.getDependencies();
419
- const generatedDate = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
420
- year: "numeric",
421
- month: "short",
422
- day: "numeric"
423
- });
424
- return {
425
- projectName,
426
- platform: this.config.platform,
427
- template: this.config.template,
428
- auth: this.config.auth,
429
- database: this.config.database,
430
- theme: this.config.theme,
431
- themeColor: this.config.themeColor,
432
- defaultTheme: this.config.defaultTheme,
433
- packageName,
434
- className,
435
- camelCaseName,
436
- kebabCaseName,
437
- titleCaseName,
438
- description: `A modern SaaS application built with Digi Logic Labs`,
439
- author: "Digi Logic Labs",
440
- year: (/* @__PURE__ */ new Date()).getFullYear(),
441
- generatedDate,
442
- generatorVersion: "1.5.0",
443
- uiVersion: dependencies["@digilogiclabs/saas-factory-ui"]?.replace("^", "") || "0.15.6",
444
- authVersion: dependencies["@digilogiclabs/saas-factory-auth"]?.replace("^", "") || "1.0.0",
445
- paymentsVersion: dependencies["@digilogiclabs/saas-factory-payments"]?.replace("^", "") || "1.0.0",
446
- dependencies,
447
- devDependencies: this.getDevDependencies(),
448
- scripts: this.getScripts()
449
- };
450
- }
451
- getDependencies() {
452
- const baseDeps = {};
453
- if ([
454
- "ui-only",
455
- "ui-auth",
456
- "ui-auth-payments",
457
- "ui-auth-payments-audio",
458
- "ui-auth-payments-video"
459
- ].includes(this.config.template)) {
460
- baseDeps["@digilogiclabs/saas-factory-ui"] = "^0.15.6";
461
- }
462
- if (["ui-auth", "ui-auth-payments", "ui-auth-payments-audio", "ui-auth-payments-video"].includes(
463
- this.config.template
464
- )) {
465
- baseDeps["@digilogiclabs/saas-factory-auth"] = "^1.0.0";
466
- }
467
- if (["ui-auth-payments", "ui-auth-payments-audio", "ui-auth-payments-video"].includes(
468
- this.config.template
469
- )) {
470
- baseDeps["@digilogiclabs/saas-factory-payments"] = "^1.0.0";
471
- }
472
- if (this.config.platform === "web" || this.config.platform === "both") {
473
- Object.assign(baseDeps, {
474
- next: "^15.0.0",
475
- react: "^19.0.0",
476
- "react-dom": "^19.0.0",
477
- tailwindcss: "^3.3.0",
478
- typescript: "^5.0.0",
479
- clsx: "^2.0.0",
480
- "class-variance-authority": "^0.7.0",
481
- "tailwind-merge": "^2.0.0",
482
- "next-themes": "^0.2.1",
483
- "lucide-react": "^0.542.0",
484
- autoprefixer: "^10.4.16",
485
- postcss: "^8.4.31"
486
- });
487
- }
488
- if (this.config.platform === "mobile" || this.config.platform === "both") {
489
- Object.assign(baseDeps, {
490
- expo: "~49.0.0",
491
- "react-native": "0.72.0",
492
- "@expo/vector-icons": "^13.0.0"
493
- });
494
- }
495
- if (this.config.auth === "firebase") {
496
- baseDeps["firebase"] = "^10.0.0";
497
- } else if (this.config.auth === "supabase") {
498
- baseDeps["@supabase/supabase-js"] = "^2.0.0";
499
- }
500
- return baseDeps;
501
- }
502
- getDevDependencies() {
503
- const baseDeps = {
504
- "@types/node": "^20.0.0",
505
- eslint: "^8.0.0",
506
- prettier: "^3.0.0"
507
- };
508
- if (this.config.platform === "web" || this.config.platform === "both") {
509
- Object.assign(baseDeps, {
510
- "@types/react": "^18.0.0",
511
- "@types/react-dom": "^18.0.0",
512
- autoprefixer: "^10.0.0",
513
- postcss: "^8.0.0"
514
- });
515
- }
516
- return baseDeps;
517
- }
518
- getScripts() {
519
- const scripts = {};
520
- if (this.config.platform === "web" || this.config.platform === "both") {
521
- Object.assign(scripts, {
522
- dev: "next dev",
523
- build: "next build",
524
- start: "next start",
525
- lint: "next lint"
526
- });
527
- }
528
- if (this.config.platform === "mobile" || this.config.platform === "both") {
529
- Object.assign(scripts, {
530
- start: "expo start",
531
- android: "expo start --android",
532
- ios: "expo start --ios",
533
- web: "expo start --web"
534
- });
535
- }
536
- return scripts;
537
- }
538
- async generate(outputPath) {
539
- try {
540
- await import_fs_extra2.default.ensureDir(outputPath);
541
- if (this.config.platform === "web") {
542
- await this.generateWebProject(outputPath);
543
- } else if (this.config.platform === "mobile") {
544
- await this.generateMobileProject(outputPath);
545
- } else if (this.config.platform === "both") {
546
- await this.generateWebProject(outputPath);
547
- await this.generateMobileProject(import_path2.default.join(outputPath, "mobile"));
548
- }
549
- await this.copySharedResources(outputPath);
550
- logger.debug("Template generation completed");
551
- } catch (error) {
552
- logger.error("Template generation failed:", error);
553
- throw error;
554
- }
555
- }
556
- async generateWebProject(outputPath) {
557
- const templatePath = import_path2.default.join(this.templatesDir, "web", this.config.template);
558
- await this.copyTemplate(templatePath, outputPath);
559
- }
560
- async generateMobileProject(outputPath) {
561
- const templatePath = import_path2.default.join(this.templatesDir, "mobile", this.config.template);
562
- await this.copyTemplate(templatePath, outputPath);
563
- }
564
- async copyTemplate(templatePath, outputPath) {
565
- const templateDir = import_path2.default.join(templatePath, "template");
566
- if (!await import_fs_extra2.default.pathExists(templateDir)) {
567
- throw new Error(`Template not found: ${templateDir}`);
568
- }
569
- await this.copyAndProcessFiles(templateDir, outputPath);
570
- }
571
- async copyAndProcessFiles(sourceDir, targetDir) {
572
- if (!await import_fs_extra2.default.pathExists(sourceDir)) {
573
- logger.debug(`Template source directory not found: ${sourceDir}`);
574
- return;
575
- }
576
- const files = await (0, import_glob.glob)("**/*", {
577
- cwd: sourceDir,
578
- dot: true,
579
- nodir: true
580
- });
581
- for (const file of files) {
582
- const sourcePath = import_path2.default.join(sourceDir, file);
583
- const targetPath = import_path2.default.join(targetDir, file);
584
- await import_fs_extra2.default.ensureDir(import_path2.default.dirname(targetPath));
585
- const content = await import_fs_extra2.default.readFile(sourcePath, "utf-8");
586
- if (this.isTextFile(file)) {
587
- const processedContent = import_mustache.default.render(content, this.context);
588
- await import_fs_extra2.default.writeFile(targetPath, processedContent);
589
- } else {
590
- await import_fs_extra2.default.copy(sourcePath, targetPath);
591
- }
592
- }
593
- }
594
- async copySharedResources(outputPath) {
595
- if (this.config.template === "ui-only") {
596
- logger.debug("Skipping shared resources for UI-only template");
597
- return;
598
- }
599
- const sharedPath = import_path2.default.join(this.templatesDir, "shared");
600
- const authPath = import_path2.default.join(sharedPath, "auth", this.config.auth);
601
- await this.copyAndProcessFiles(authPath, outputPath);
602
- const themePath = import_path2.default.join(sharedPath, "themes", this.config.theme);
603
- await this.copyAndProcessFiles(themePath, outputPath);
604
- const dbPath = import_path2.default.join(sharedPath, "database", this.config.database);
605
- await this.copyAndProcessFiles(dbPath, outputPath);
606
- }
607
- isTextFile(filename) {
608
- const textExtensions = [
609
- ".js",
610
- ".jsx",
611
- ".ts",
612
- ".tsx",
613
- ".json",
614
- ".md",
615
- ".txt",
616
- ".yml",
617
- ".yaml",
618
- ".xml",
619
- ".html",
620
- ".css",
621
- ".scss",
622
- ".sass",
623
- ".less",
624
- ".env",
625
- ".gitignore",
626
- ".eslintrc",
627
- ".prettierrc",
628
- ".editorconfig",
629
- ".nvmrc"
630
- ];
631
- const ext = import_path2.default.extname(filename).toLowerCase();
632
- return textExtensions.includes(ext) || !ext;
633
- }
634
- toPascalCase(str) {
635
- return str.replace(/[^a-zA-Z0-9]/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
636
- }
637
- toCamelCase(str) {
638
- const pascal = this.toPascalCase(str);
639
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
640
- }
641
- toTitleCase(str) {
642
- return str.replace(/[^a-zA-Z0-9]/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
643
- }
644
- };
645
-
646
- // src/generators/package-installer.ts
647
- var import_path4 = __toESM(require("path"));
648
- var import_fs_extra4 = __toESM(require("fs-extra"));
649
- var import_execa3 = __toESM(require("execa"));
650
-
651
- // src/cli/utils/package-manager.ts
652
- var import_execa2 = __toESM(require("execa"));
653
- var import_fs_extra3 = __toESM(require("fs-extra"));
654
- var import_path3 = __toESM(require("path"));
655
- async function detectPackageManager(projectPath) {
656
- const cwd = projectPath || process.cwd();
657
- const lockFiles = [
658
- { file: "pnpm-lock.yaml", manager: "pnpm" },
659
- { file: "yarn.lock", manager: "yarn" },
660
- { file: "package-lock.json", manager: "npm" }
661
- ];
662
- for (const { file, manager } of lockFiles) {
663
- if (await import_fs_extra3.default.pathExists(import_path3.default.join(cwd, file))) {
664
- return manager;
665
- }
666
- }
667
- const managers = ["pnpm", "yarn", "npm"];
668
- for (const manager of managers) {
669
- try {
670
- await (0, import_execa2.default)(manager, ["--version"]);
671
- return manager;
672
- } catch {
673
- }
674
- }
675
- return "npm";
676
- }
677
- async function getInstallCommand(packageManager) {
678
- switch (packageManager) {
679
- case "yarn":
680
- return ["yarn", "install"];
681
- case "pnpm":
682
- return ["pnpm", "install"];
683
- default:
684
- return ["npm", "install"];
685
- }
686
- }
687
- async function getAddCommand(packageManager, packages, dev = false) {
688
- const devFlag = dev ? packageManager === "npm" ? "--save-dev" : "-D" : "";
689
- switch (packageManager) {
690
- case "yarn":
691
- return ["yarn", "add", ...dev ? ["-D"] : [], ...packages];
692
- case "pnpm":
693
- return ["pnpm", "add", ...dev ? ["-D"] : [], ...packages];
694
- default:
695
- return ["npm", "install", ...devFlag ? [devFlag] : [], ...packages];
696
- }
697
- }
698
- async function isPackageManagerAvailable(packageManager) {
699
- try {
700
- await (0, import_execa2.default)(packageManager, ["--version"]);
701
- return true;
702
- } catch {
703
- return false;
704
- }
705
- }
706
-
707
- // src/generators/package-installer.ts
708
- var PackageInstaller = class {
709
- constructor(projectPath) {
710
- this.projectPath = projectPath;
711
- }
712
- async install() {
713
- try {
714
- const packageJsonPath = import_path4.default.join(this.projectPath, "package.json");
715
- if (!await import_fs_extra4.default.pathExists(packageJsonPath)) {
716
- throw new Error("package.json not found in project directory");
717
- }
718
- const packageManager = await detectPackageManager(this.projectPath);
719
- if (!await isPackageManagerAvailable(packageManager)) {
720
- throw new Error(`Package manager "${packageManager}" is not available`);
721
- }
722
- logger.debug(`Installing dependencies with ${packageManager}...`);
723
- const command = await getInstallCommand(packageManager);
724
- await (0, import_execa3.default)(command[0], command.slice(1), {
725
- cwd: this.projectPath,
726
- stdio: "pipe"
727
- });
728
- logger.debug("Dependencies installed successfully");
729
- } catch (error) {
730
- logger.error("Package installation failed:", error);
731
- throw error;
732
- }
733
- }
734
- async installDependencies(dependencies, dev = false) {
735
- try {
736
- if (dependencies.length === 0) {
737
- return;
738
- }
739
- const packageManager = await detectPackageManager(this.projectPath);
740
- if (!await isPackageManagerAvailable(packageManager)) {
741
- throw new Error(`Package manager "${packageManager}" is not available`);
742
- }
743
- logger.debug(`Installing ${dev ? "dev " : ""}dependencies: ${dependencies.join(", ")}`);
744
- const command = packageManager === "yarn" ? ["yarn", "add", ...dev ? ["-D"] : [], ...dependencies] : packageManager === "pnpm" ? ["pnpm", "add", ...dev ? ["-D"] : [], ...dependencies] : ["npm", "install", ...dev ? ["--save-dev"] : [], ...dependencies];
745
- await (0, import_execa3.default)(command[0], command.slice(1), {
746
- cwd: this.projectPath,
747
- stdio: "pipe"
748
- });
749
- logger.debug(`${dev ? "Dev d" : "D"}ependencies installed successfully`);
750
- } catch (error) {
751
- logger.error(`Failed to install ${dev ? "dev " : ""}dependencies:`, error);
752
- throw error;
753
- }
754
- }
755
- async updatePackageJson(updates) {
756
- try {
757
- const packageJsonPath = import_path4.default.join(this.projectPath, "package.json");
758
- if (!await import_fs_extra4.default.pathExists(packageJsonPath)) {
759
- throw new Error("package.json not found");
760
- }
761
- const packageJson = await import_fs_extra4.default.readJson(packageJsonPath);
762
- const updatedPackageJson = { ...packageJson, ...updates };
763
- await import_fs_extra4.default.writeJson(packageJsonPath, updatedPackageJson, { spaces: 2 });
764
- logger.debug("package.json updated successfully");
765
- } catch (error) {
766
- logger.error("Failed to update package.json:", error);
767
- throw error;
768
- }
769
- }
770
- async addScript(name, command) {
771
- try {
772
- const packageJsonPath = import_path4.default.join(this.projectPath, "package.json");
773
- const packageJson = await import_fs_extra4.default.readJson(packageJsonPath);
774
- if (!packageJson.scripts) {
775
- packageJson.scripts = {};
776
- }
777
- packageJson.scripts[name] = command;
778
- await import_fs_extra4.default.writeJson(packageJsonPath, packageJson, { spaces: 2 });
779
- logger.debug(`Script "${name}" added to package.json`);
780
- } catch (error) {
781
- logger.error(`Failed to add script "${name}":`, error);
782
- throw error;
783
- }
784
- }
785
- async removeScript(name) {
786
- try {
787
- const packageJsonPath = import_path4.default.join(this.projectPath, "package.json");
788
- const packageJson = await import_fs_extra4.default.readJson(packageJsonPath);
789
- if (packageJson.scripts && packageJson.scripts[name]) {
790
- delete packageJson.scripts[name];
791
- await import_fs_extra4.default.writeJson(packageJsonPath, packageJson, { spaces: 2 });
792
- logger.debug(`Script "${name}" removed from package.json`);
793
- }
794
- } catch (error) {
795
- logger.error(`Failed to remove script "${name}":`, error);
796
- throw error;
797
- }
798
- }
799
- async getDependencies() {
800
- try {
801
- const packageJsonPath = import_path4.default.join(this.projectPath, "package.json");
802
- const packageJson = await import_fs_extra4.default.readJson(packageJsonPath);
803
- return {
804
- dependencies: packageJson.dependencies || {},
805
- devDependencies: packageJson.devDependencies || {}
806
- };
807
- } catch (error) {
808
- logger.error("Failed to read dependencies:", error);
809
- return { dependencies: {}, devDependencies: {} };
810
- }
811
- }
812
- async hasLockFile() {
813
- const lockFiles = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
814
- for (const lockFile of lockFiles) {
815
- if (await import_fs_extra4.default.pathExists(import_path4.default.join(this.projectPath, lockFile))) {
816
- return true;
817
- }
818
- }
819
- return false;
820
- }
821
- async cleanInstall() {
822
- try {
823
- const nodeModulesPath = import_path4.default.join(this.projectPath, "node_modules");
824
- const lockFiles = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
825
- if (await import_fs_extra4.default.pathExists(nodeModulesPath)) {
826
- await import_fs_extra4.default.remove(nodeModulesPath);
827
- }
828
- for (const lockFile of lockFiles) {
829
- const lockPath = import_path4.default.join(this.projectPath, lockFile);
830
- if (await import_fs_extra4.default.pathExists(lockPath)) {
831
- await import_fs_extra4.default.remove(lockPath);
832
- }
833
- }
834
- await this.install();
835
- logger.debug("Clean install completed");
836
- } catch (error) {
837
- logger.error("Clean install failed:", error);
838
- throw error;
839
- }
840
- }
841
- };
842
-
843
- // src/cli/utils/git.ts
844
- var import_execa4 = __toESM(require("execa"));
845
- var import_fs_extra5 = __toESM(require("fs-extra"));
846
- async function initializeGit(projectPath) {
847
- try {
848
- await (0, import_execa4.default)("git", ["--version"]);
849
- await (0, import_execa4.default)("git", ["init"], { cwd: projectPath });
850
- await (0, import_execa4.default)("git", ["add", "."], { cwd: projectPath });
851
- await (0, import_execa4.default)("git", ["commit", "-m", "Initial commit from @digilogiclabs/create-saas-app"], {
852
- cwd: projectPath
853
- });
854
- logger.debug("Git repository initialized successfully");
855
- } catch (error) {
856
- logger.warn("Git initialization failed. You can initialize it manually later.");
857
- logger.debug("Git error:", error);
858
- }
859
- }
860
-
861
- // src/cli/commands/create.ts
862
- async function createProject(platform, template, name, options = {}) {
863
- try {
864
- if (!await validateNodeVersion()) {
865
- process.exit(1);
866
- }
867
- const validPlatforms = ["web", "mobile", "both"];
868
- if (!validPlatforms.includes(platform)) {
869
- logger.error(`Invalid platform: ${platform}. Must be one of: ${validPlatforms.join(", ")}`);
870
- process.exit(1);
871
- }
872
- let config = {
873
- platform,
874
- template: template || "base",
875
- name: name || "my-saas-app",
876
- auth: options.auth || "supabase",
877
- database: options.database || "supabase",
878
- theme: options.theme || "default",
879
- themeColor: options.themeColor || "blue",
880
- defaultTheme: options.defaultTheme || "system",
881
- install: options.install !== false,
882
- git: options.git !== false
883
- };
884
- if (!options.yes) {
885
- config = await getProjectPrompts(config);
886
- }
887
- if (!validateProjectName(config.name)) {
888
- process.exit(1);
889
- }
890
- const projectPath = import_path5.default.resolve(process.cwd(), config.name);
891
- if (!await validateProjectPath(projectPath)) {
892
- process.exit(1);
893
- }
894
- logger.title("\u{1F680} Creating your SaaS application");
895
- logger.info(`Platform: ${config.platform}`);
896
- logger.info(`Template: ${config.template}`);
897
- logger.info(`Project: ${config.name}`);
898
- logger.info(`Auth: ${config.auth}`);
899
- logger.info(`Database: ${config.database}`);
900
- logger.info(`Theme: ${config.theme}`);
901
- logger.info(`Theme Color: ${config.themeColor}`);
902
- logger.info(`Default Theme: ${config.defaultTheme}`);
903
- logger.newLine();
904
- const templateSpinner = spinner("Generating project structure...");
905
- try {
906
- const generator = new TemplateGenerator(config);
907
- await generator.generate(projectPath);
908
- templateSpinner.succeed("Project structure created");
909
- } catch (_error) {
910
- templateSpinner.fail("Failed to generate project structure");
911
- throw _error;
912
- }
913
- if (config.install) {
914
- const installSpinner = spinner("Installing dependencies...");
915
- try {
916
- const installer = new PackageInstaller(projectPath);
917
- await installer.install();
918
- installSpinner.succeed("Dependencies installed");
919
- } catch (_error) {
920
- installSpinner.fail("Failed to install dependencies");
921
- logger.warn("You can install dependencies manually by running:");
922
- logger.code(`cd ${config.name} && npm install`);
923
- }
924
- }
925
- if (config.git) {
926
- const gitSpinner = spinner("Initializing git repository...");
927
- try {
928
- await initializeGit(projectPath);
929
- gitSpinner.succeed("Git repository initialized");
930
- } catch (_error) {
931
- gitSpinner.fail("Failed to initialize git repository");
932
- logger.warn("You can initialize git manually by running:");
933
- logger.code(`cd ${config.name} && git init`);
934
- }
935
- }
936
- logger.newLine();
937
- logger.success("\u{1F389} Project created successfully!");
938
- logger.newLine();
939
- logger.title("Next steps:");
940
- logger.code(`cd ${config.name}`);
941
- if (!config.install) {
942
- logger.code("npm install");
943
- }
944
- if (config.platform === "web" || config.platform === "both") {
945
- logger.code("npm run dev");
946
- logger.info("Open http://localhost:3000 in your browser");
947
- }
948
- if (config.platform === "mobile" || config.platform === "both") {
949
- logger.code("npx expo start");
950
- logger.info("Scan QR code with Expo Go app");
951
- }
952
- logger.newLine();
953
- logger.info("\u{1F4DA} Documentation: https://docs.digilogiclabs.com");
954
- logger.info("\u{1F4AC} Support: https://discord.gg/digilogiclabs");
955
- } catch (error) {
956
- logger.error("Failed to create project:");
957
- logger.error(error instanceof Error ? error.message : String(error));
958
- process.exit(1);
959
- }
960
- }
961
-
962
- // src/cli/commands/add.ts
963
- async function addFeature(feature, _options = {}) {
964
- try {
965
- logger.title(`Adding ${feature} feature`);
966
- const validFeatures = [
967
- "auth",
968
- "billing",
969
- "analytics",
970
- "teams",
971
- "notifications",
972
- "admin",
973
- "api",
974
- "docs"
975
- ];
976
- if (!validFeatures.includes(feature)) {
977
- logger.error(`Invalid feature: ${feature}`);
978
- logger.info("Available features:");
979
- logger.list(validFeatures);
980
- process.exit(1);
981
- }
982
- const addSpinner = spinner(`Adding ${feature} feature...`);
983
- await new Promise((resolve) => setTimeout(resolve, 2e3));
984
- addSpinner.succeed(`${feature} feature added successfully`);
985
- logger.newLine();
986
- logger.success("Feature added successfully!");
987
- logger.info("Don't forget to update your environment variables if needed.");
988
- } catch (error) {
989
- logger.error("Failed to add feature:");
990
- logger.error(error instanceof Error ? error.message : String(error));
991
- process.exit(1);
992
- }
993
- }
994
-
995
- // src/cli/commands/update.ts
996
- var import_execa5 = __toESM(require("execa"));
997
- var DIGILOGIC_PACKAGES = [
998
- "@digilogiclabs/saas-factory-ui",
999
- "@digilogiclabs/saas-factory-auth",
1000
- "@digilogiclabs/saas-factory-billing",
1001
- "@digilogiclabs/saas-factory-analytics"
1002
- ];
1003
- async function updateDependencies(options = {}) {
1004
- try {
1005
- logger.title("Updating Digi Logic Labs dependencies");
1006
- const packageManager = await detectPackageManager();
1007
- logger.info(`Using package manager: ${packageManager}`);
1008
- if (options.check) {
1009
- const checkSpinner = spinner("Checking for updates...");
1010
- try {
1011
- const result = await (0, import_execa5.default)(packageManager, ["outdated", ...DIGILOGIC_PACKAGES], {
1012
- reject: false
1013
- });
1014
- checkSpinner.succeed("Update check completed");
1015
- if (result.stdout) {
1016
- logger.info("Available updates:");
1017
- logger.log(result.stdout);
1018
- } else {
1019
- logger.success("All Digi Logic Labs packages are up to date!");
1020
- }
1021
- } catch (error) {
1022
- checkSpinner.fail("Failed to check for updates");
1023
- throw error;
1024
- }
1025
- } else {
1026
- const updateSpinner = spinner("Updating packages...");
1027
- try {
1028
- const command = await getAddCommand(packageManager, DIGILOGIC_PACKAGES);
1029
- await (0, import_execa5.default)(command[0], command.slice(1), {
1030
- stdio: "inherit"
1031
- });
1032
- updateSpinner.succeed("Packages updated successfully");
1033
- logger.newLine();
1034
- logger.success("All Digi Logic Labs packages have been updated!");
1035
- logger.info("Don't forget to test your application after updating.");
1036
- } catch (error) {
1037
- updateSpinner.fail("Failed to update packages");
1038
- throw error;
1039
- }
1040
- }
1041
- } catch (error) {
1042
- logger.error("Failed to update dependencies:");
1043
- logger.error(error instanceof Error ? error.message : String(error));
1044
- process.exit(1);
1045
- }
1046
- }
1047
-
1048
- // package.json
1049
- var package_default = {
1050
- name: "@digilogiclabs/create-saas-app",
1051
- version: "1.9.0",
1052
- description: "Create modern SaaS applications with Digi Logic Labs packages",
1053
- main: "dist/cli/index.js",
1054
- bin: {
1055
- "create-saas-app": "bin/index.js"
1056
- },
1057
- scripts: {
1058
- build: "tsc --project tsconfig.build.json && npm run copy-templates",
1059
- "copy-templates": `node -e "require('fs-extra').copySync('src/templates', 'dist/templates')"`,
1060
- dev: "tsup --watch",
1061
- test: "jest",
1062
- "test:templates": "tsx scripts/test-all-templates.ts",
1063
- lint: "eslint src",
1064
- "lint:fix": "eslint src --fix",
1065
- "type-check": "tsc --noEmit --skipLibCheck",
1066
- validate: "tsx scripts/validate-templates.ts",
1067
- changeset: "changeset",
1068
- version: "changeset version",
1069
- release: "npm run build && changeset publish",
1070
- prepublishOnly: "npm run build && npm run lint && npm run type-check"
1071
- },
1072
- keywords: [
1073
- "cli",
1074
- "saas",
1075
- "template",
1076
- "nextjs",
1077
- "react-native",
1078
- "expo",
1079
- "typescript",
1080
- "tailwind",
1081
- "firebase",
1082
- "supabase",
1083
- "digilogiclabs"
1084
- ],
1085
- author: "Digi Logic Labs",
1086
- license: "MIT",
1087
- repository: {
1088
- type: "git",
1089
- url: "git+https://github.com/DigiLogicLabs/create-saas-app.git"
1090
- },
1091
- bugs: {
1092
- url: "https://github.com/DigiLogicLabs/create-saas-app/issues"
1093
- },
1094
- homepage: "https://github.com/DigiLogicLabs/create-saas-app#readme",
1095
- files: [
1096
- "dist",
1097
- "bin",
1098
- "src/templates",
1099
- "README.md",
1100
- "CHANGELOG.md",
1101
- "LICENSE"
1102
- ],
1103
- engines: {
1104
- node: ">=18.0.0"
1105
- },
1106
- dependencies: {
1107
- chalk: "^4.1.2",
1108
- commander: "^11.1.0",
1109
- cosmiconfig: "^8.3.6",
1110
- execa: "^5.1.1",
1111
- "fs-extra": "^11.1.1",
1112
- glob: "^10.3.10",
1113
- inquirer: "^9.2.12",
1114
- listr2: "^7.0.2",
1115
- mustache: "^4.2.0",
1116
- ora: "^5.4.1",
1117
- semver: "^7.5.4",
1118
- "validate-npm-package-name": "^5.0.0",
1119
- zod: "^3.22.4"
1120
- },
1121
- devDependencies: {
1122
- "@changesets/cli": "^2.26.2",
1123
- "@supabase/supabase-js": "^2.39.2",
1124
- "@types/fs-extra": "^11.0.4",
1125
- "@types/inquirer": "^9.0.7",
1126
- "@types/jest": "^29.5.6",
1127
- "@types/mustache": "^4.2.5",
1128
- "@types/node": "^20.8.7",
1129
- "@types/semver": "^7.5.4",
1130
- "@types/validate-npm-package-name": "^4.0.2",
1131
- eslint: "^8.57.1",
1132
- "eslint-config-prettier": "^9.1.2",
1133
- "eslint-plugin-prettier": "^5.5.4",
1134
- firebase: "^10.7.1",
1135
- globals: "^16.3.0",
1136
- jest: "^29.7.0",
1137
- prettier: "^3.0.3",
1138
- "ts-jest": "^29.1.1",
1139
- tsup: "^7.2.0",
1140
- tsx: "^3.14.0",
1141
- typescript: "^5.2.2",
1142
- "typescript-eslint": "^8.40.0"
1143
- },
1144
- peerDependencies: {
1145
- typescript: ">=4.9.0"
1146
- },
1147
- publishConfig: {
1148
- access: "public"
1149
- },
1150
- directories: {
1151
- doc: "docs",
1152
- test: "tests"
1153
- }
1154
- };
1155
-
1156
- // src/cli/index.ts
1157
- var program = new import_commander.Command();
1158
- program.name("create-saas-app").description("Create modern SaaS applications with Digi Logic Labs packages").version(package_default.version);
1159
- program.command("create").alias("c").description("Create a new SaaS application").argument("<platform>", "Platform: web, mobile, or both").argument("[template]", "Template: base, dashboard, saas (web) | base, tabs, stack (mobile)").argument("[name]", "Project name").option("-a, --auth <provider>", "Auth provider: firebase, supabase").option("-d, --database <provider>", "Database provider: supabase, firebase").option("-t, --theme <theme>", "Theme: default, corporate, startup").option("-c, --theme-color <color>", "Theme color: blue, green, purple, orange, red, slate").option("--default-theme <mode>", "Default theme mode: light, dark, system").option("--no-install", "Skip package installation").option("--no-git", "Skip git initialization").option("-y, --yes", "Skip interactive prompts").action(createProject);
1160
- program.command("add").alias("a").description("Add features to existing project").argument("<feature>", "Feature to add: auth, billing, analytics, etc.").option("-p, --provider <provider>", "Service provider").action(addFeature);
1161
- program.command("update").alias("u").description("Update Digi Logic Labs dependencies").option("--check", "Check for updates without installing").action(updateDependencies);
1162
- program.on("command:*", () => {
1163
- logger.error(`Unknown command: ${program.args.join(" ")}`);
1164
- logger.info('Run "create-saas-app --help" for available commands');
1165
- process.exit(1);
1166
- });
1167
- if (!process.argv.slice(2).length) {
1168
- program.outputHelp();
1169
- process.exit(0);
1170
- }
1171
- program.parse();
1172
- var cli_default = program;
1173
- //# sourceMappingURL=index.js.map