stackkit-cli 0.1.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 (64) hide show
  1. package/README.md +119 -0
  2. package/bin/stackkit.js +2 -0
  3. package/dist/commands/add.d.ts +9 -0
  4. package/dist/commands/add.d.ts.map +1 -0
  5. package/dist/commands/add.js +201 -0
  6. package/dist/commands/add.js.map +1 -0
  7. package/dist/commands/init.d.ts +11 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/init.js +153 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/list.d.ts +7 -0
  12. package/dist/commands/list.d.ts.map +1 -0
  13. package/dist/commands/list.js +107 -0
  14. package/dist/commands/list.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +50 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/types/index.d.ts +65 -0
  20. package/dist/types/index.d.ts.map +1 -0
  21. package/dist/types/index.js +3 -0
  22. package/dist/types/index.js.map +1 -0
  23. package/dist/utils/code-inject.d.ts +15 -0
  24. package/dist/utils/code-inject.d.ts.map +1 -0
  25. package/dist/utils/code-inject.js +71 -0
  26. package/dist/utils/code-inject.js.map +1 -0
  27. package/dist/utils/detect.d.ts +5 -0
  28. package/dist/utils/detect.d.ts.map +1 -0
  29. package/dist/utils/detect.js +79 -0
  30. package/dist/utils/detect.js.map +1 -0
  31. package/dist/utils/env-editor.d.ts +11 -0
  32. package/dist/utils/env-editor.d.ts.map +1 -0
  33. package/dist/utils/env-editor.js +92 -0
  34. package/dist/utils/env-editor.js.map +1 -0
  35. package/dist/utils/files.d.ts +7 -0
  36. package/dist/utils/files.d.ts.map +1 -0
  37. package/dist/utils/files.js +51 -0
  38. package/dist/utils/files.js.map +1 -0
  39. package/dist/utils/json-editor.d.ts +9 -0
  40. package/dist/utils/json-editor.d.ts.map +1 -0
  41. package/dist/utils/json-editor.js +50 -0
  42. package/dist/utils/json-editor.js.map +1 -0
  43. package/dist/utils/logger.d.ts +17 -0
  44. package/dist/utils/logger.d.ts.map +1 -0
  45. package/dist/utils/logger.js +58 -0
  46. package/dist/utils/logger.js.map +1 -0
  47. package/dist/utils/package-manager.d.ts +6 -0
  48. package/dist/utils/package-manager.d.ts.map +1 -0
  49. package/dist/utils/package-manager.js +79 -0
  50. package/dist/utils/package-manager.js.map +1 -0
  51. package/package.json +51 -0
  52. package/src/commands/add.ts +261 -0
  53. package/src/commands/init.ts +182 -0
  54. package/src/commands/list.ts +124 -0
  55. package/src/index.ts +53 -0
  56. package/src/types/index.ts +71 -0
  57. package/src/utils/code-inject.ts +85 -0
  58. package/src/utils/detect.ts +89 -0
  59. package/src/utils/env-editor.ts +127 -0
  60. package/src/utils/files.ts +59 -0
  61. package/src/utils/json-editor.ts +64 -0
  62. package/src/utils/logger.ts +62 -0
  63. package/src/utils/package-manager.ts +85 -0
  64. package/tsconfig.json +9 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const commander_1 = require("commander");
9
+ const add_1 = require("./commands/add");
10
+ const init_1 = require("./commands/init");
11
+ const list_1 = require("./commands/list");
12
+ const program = new commander_1.Command();
13
+ program
14
+ .name('stackkit')
15
+ .description('Production-ready project generator and module CLI')
16
+ .version('0.1.0');
17
+ // Init command
18
+ program
19
+ .command('init [project-name]')
20
+ .description('Create a new project from a template')
21
+ .option('-t, --template <template>', 'Template to use')
22
+ .option('--pm <pm>', 'Package manager to use (npm, yarn, pnpm)')
23
+ .option('--no-install', 'Skip installing dependencies')
24
+ .option('--no-git', 'Skip git initialization')
25
+ .option('-y, --yes', 'Skip prompts and use defaults')
26
+ .action(init_1.initCommand);
27
+ // List command
28
+ program
29
+ .command('list')
30
+ .description('List available templates and modules')
31
+ .option('-t, --templates', 'List only templates')
32
+ .option('-m, --modules', 'List only modules')
33
+ .action(list_1.listCommand);
34
+ // Add command
35
+ program
36
+ .command('add <module>')
37
+ .description('Add a module to your existing project')
38
+ .option('--provider <provider>', 'Specific provider/variant to use')
39
+ .option('--force', 'Overwrite existing files')
40
+ .option('--dry-run', 'Show what would be changed without making changes')
41
+ .option('--no-install', 'Skip installing dependencies')
42
+ .action(add_1.addCommand);
43
+ // Error handling
44
+ program.on('command:*', () => {
45
+ console.error(chalk_1.default.red(`\nInvalid command: ${program.args.join(' ')}\n`));
46
+ console.log(chalk_1.default.yellow('Run stackkit --help for a list of available commands.\n'));
47
+ process.exit(1);
48
+ });
49
+ program.parse();
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,kDAA0B;AAC1B,yCAAoC;AACpC,wCAA4C;AAC5C,0CAA8C;AAC9C,0CAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,2BAA2B,EAAE,iBAAiB,CAAC;KACtD,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;KAC/D,MAAM,CAAC,cAAc,EAAE,8BAA8B,CAAC;KACtD,MAAM,CAAC,UAAU,EAAE,yBAAyB,CAAC;KAC7C,MAAM,CAAC,WAAW,EAAE,+BAA+B,CAAC;KACpD,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;KAChD,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC;KAC5C,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,cAAc;AACd,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,uBAAuB,EAAE,kCAAkC,CAAC;KACnE,MAAM,CAAC,SAAS,EAAE,0BAA0B,CAAC;KAC7C,MAAM,CAAC,WAAW,EAAE,mDAAmD,CAAC;KACxE,MAAM,CAAC,cAAc,EAAE,8BAA8B,CAAC;KACtD,MAAM,CAAC,gBAAU,CAAC,CAAC;AAEtB,iBAAiB;AACjB,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;IAC3B,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAC5D,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,65 @@
1
+ export interface TemplateMetadata {
2
+ name: string;
3
+ displayName: string;
4
+ description: string;
5
+ tags: string[];
6
+ defaultPackageManager: 'pnpm' | 'npm' | 'yarn';
7
+ features: string[];
8
+ }
9
+ export interface ModuleMetadata {
10
+ name: string;
11
+ displayName: string;
12
+ description: string;
13
+ category: 'auth' | 'database' | 'ui' | 'other';
14
+ supportedFrameworks: string[];
15
+ dependencies: Record<string, string>;
16
+ devDependencies?: Record<string, string>;
17
+ envVars: EnvVar[];
18
+ patches: ModulePatch[];
19
+ }
20
+ export interface EnvVar {
21
+ key: string;
22
+ value?: string;
23
+ description: string;
24
+ required: boolean;
25
+ }
26
+ export interface ModulePatch {
27
+ type: 'create-file' | 'modify-json' | 'append-env' | 'inject-code';
28
+ description: string;
29
+ [key: string]: any;
30
+ }
31
+ export interface CreateFilePatch extends ModulePatch {
32
+ type: 'create-file';
33
+ source: string;
34
+ destination: string;
35
+ condition?: {
36
+ router?: 'app' | 'pages';
37
+ language?: 'ts' | 'js';
38
+ };
39
+ }
40
+ export interface ModifyJsonPatch extends ModulePatch {
41
+ type: 'modify-json';
42
+ file: string;
43
+ operations: {
44
+ path: string;
45
+ value: any;
46
+ merge?: boolean;
47
+ }[];
48
+ }
49
+ export interface ProjectInfo {
50
+ framework: 'nextjs' | 'unknown';
51
+ router: 'app' | 'pages' | 'unknown';
52
+ language: 'ts' | 'js';
53
+ packageManager: 'npm' | 'yarn' | 'pnpm';
54
+ hasAuth: boolean;
55
+ hasPrisma: boolean;
56
+ rootDir: string;
57
+ }
58
+ export interface CLIOptions {
59
+ force?: boolean;
60
+ dryRun?: boolean;
61
+ yes?: boolean;
62
+ noInstall?: boolean;
63
+ pm?: 'npm' | 'yarn' | 'pnpm';
64
+ }
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qBAAqB,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC/C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC;IAC/C,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,YAAY,GAAG,aAAa,CAAC;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;QACzB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ export interface CodeInjection {
2
+ id: string;
3
+ code: string;
4
+ description: string;
5
+ }
6
+ export declare function injectCode(filePath: string, injection: CodeInjection, position: 'append' | 'prepend' | {
7
+ after: string;
8
+ } | {
9
+ before: string;
10
+ }, options?: {
11
+ force?: boolean;
12
+ }): Promise<void>;
13
+ export declare function removeInjection(content: string, id: string): string;
14
+ export declare function hasInjection(content: string, id: string): boolean;
15
+ //# sourceMappingURL=code-inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-inject.d.ts","sourceRoot":"","sources":["../../src/utils/code-inject.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EACvE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAmBnE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjE"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.injectCode = injectCode;
7
+ exports.removeInjection = removeInjection;
8
+ exports.hasInjection = hasInjection;
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const CODE_MARKER_START = (id) => `// StackKit:${id}:start`;
11
+ const CODE_MARKER_END = (id) => `// StackKit:${id}:end`;
12
+ async function injectCode(filePath, injection, position, options = {}) {
13
+ if (!await fs_extra_1.default.pathExists(filePath)) {
14
+ throw new Error(`File not found: ${filePath}`);
15
+ }
16
+ let content = await fs_extra_1.default.readFile(filePath, 'utf-8');
17
+ // Check if already injected
18
+ const startMarker = CODE_MARKER_START(injection.id);
19
+ if (content.includes(startMarker) && !options.force) {
20
+ return; // Already injected, skip
21
+ }
22
+ // Remove old injection if force is true
23
+ if (options.force) {
24
+ content = removeInjection(content, injection.id);
25
+ }
26
+ // Prepare the code block with markers
27
+ const markedCode = `\n${startMarker}\n${injection.code}\n${CODE_MARKER_END(injection.id)}\n`;
28
+ // Inject based on position
29
+ if (position === 'append') {
30
+ content += markedCode;
31
+ }
32
+ else if (position === 'prepend') {
33
+ content = markedCode + content;
34
+ }
35
+ else if ('after' in position) {
36
+ const index = content.indexOf(position.after);
37
+ if (index === -1) {
38
+ throw new Error(`Could not find marker: ${position.after}`);
39
+ }
40
+ const insertPos = index + position.after.length;
41
+ content = content.slice(0, insertPos) + markedCode + content.slice(insertPos);
42
+ }
43
+ else if ('before' in position) {
44
+ const index = content.indexOf(position.before);
45
+ if (index === -1) {
46
+ throw new Error(`Could not find marker: ${position.before}`);
47
+ }
48
+ content = content.slice(0, index) + markedCode + content.slice(index);
49
+ }
50
+ await fs_extra_1.default.writeFile(filePath, content, 'utf-8');
51
+ }
52
+ function removeInjection(content, id) {
53
+ const startMarker = CODE_MARKER_START(id);
54
+ const endMarker = CODE_MARKER_END(id);
55
+ const startIndex = content.indexOf(startMarker);
56
+ if (startIndex === -1) {
57
+ return content;
58
+ }
59
+ const endIndex = content.indexOf(endMarker, startIndex);
60
+ if (endIndex === -1) {
61
+ return content;
62
+ }
63
+ // Remove everything from start marker to end marker (inclusive)
64
+ const before = content.slice(0, startIndex);
65
+ const after = content.slice(endIndex + endMarker.length);
66
+ return before + after;
67
+ }
68
+ function hasInjection(content, id) {
69
+ return content.includes(CODE_MARKER_START(id));
70
+ }
71
+ //# sourceMappingURL=code-inject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-inject.js","sourceRoot":"","sources":["../../src/utils/code-inject.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { ProjectInfo } from '../types';
2
+ export declare function detectProjectInfo(targetDir: string): Promise<ProjectInfo>;
3
+ export declare function getRouterBasePath(projectInfo: ProjectInfo): string;
4
+ export declare function getLibPath(projectInfo: ProjectInfo): string;
5
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/utils/detect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmE/E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAUlE;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAG3D"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.detectProjectInfo = detectProjectInfo;
7
+ exports.getRouterBasePath = getRouterBasePath;
8
+ exports.getLibPath = getLibPath;
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const path_1 = __importDefault(require("path"));
11
+ async function detectProjectInfo(targetDir) {
12
+ const packageJsonPath = path_1.default.join(targetDir, 'package.json');
13
+ if (!await fs_extra_1.default.pathExists(packageJsonPath)) {
14
+ throw new Error('No package.json found. This does not appear to be a Node.js project.');
15
+ }
16
+ const packageJson = await fs_extra_1.default.readJSON(packageJsonPath);
17
+ // Detect framework
18
+ const isNextJs = packageJson.dependencies?.next || packageJson.devDependencies?.next;
19
+ const framework = isNextJs ? 'nextjs' : 'unknown';
20
+ if (framework === 'unknown') {
21
+ throw new Error('Only Next.js projects are currently supported.');
22
+ }
23
+ // Detect router type
24
+ const appDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'app'));
25
+ const pagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pages'));
26
+ const srcAppDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'app'));
27
+ const srcPagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'pages'));
28
+ let router = 'unknown';
29
+ if (appDirExists || srcAppDirExists) {
30
+ router = 'app';
31
+ }
32
+ else if (pagesDirExists || srcPagesDirExists) {
33
+ router = 'pages';
34
+ }
35
+ // Detect TypeScript vs JavaScript
36
+ const tsconfigExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'tsconfig.json'));
37
+ const language = tsconfigExists ? 'ts' : 'js';
38
+ // Detect package manager
39
+ const yarnLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'yarn.lock'));
40
+ const pnpmLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pnpm-lock.yaml'));
41
+ let packageManager = 'npm';
42
+ if (pnpmLockExists) {
43
+ packageManager = 'pnpm';
44
+ }
45
+ else if (yarnLockExists) {
46
+ packageManager = 'yarn';
47
+ }
48
+ // Check for existing integrations
49
+ const hasAuth = !!(packageJson.dependencies?.['next-auth'] ||
50
+ packageJson.dependencies?.['@auth/core'] ||
51
+ packageJson.dependencies?.['@clerk/nextjs'] ||
52
+ packageJson.dependencies?.['@kinde-oss/kinde-auth-nextjs']);
53
+ const hasPrisma = !!(packageJson.dependencies?.['@prisma/client'] ||
54
+ packageJson.devDependencies?.['prisma']);
55
+ return {
56
+ framework,
57
+ router,
58
+ language,
59
+ packageManager,
60
+ hasAuth,
61
+ hasPrisma,
62
+ rootDir: targetDir,
63
+ };
64
+ }
65
+ function getRouterBasePath(projectInfo) {
66
+ const srcExists = fs_extra_1.default.existsSync(path_1.default.join(projectInfo.rootDir, 'src'));
67
+ if (projectInfo.router === 'app') {
68
+ return srcExists ? 'src/app' : 'app';
69
+ }
70
+ else if (projectInfo.router === 'pages') {
71
+ return srcExists ? 'src/pages' : 'pages';
72
+ }
73
+ throw new Error('Unknown router type');
74
+ }
75
+ function getLibPath(projectInfo) {
76
+ const srcExists = fs_extra_1.default.existsSync(path_1.default.join(projectInfo.rootDir, 'src'));
77
+ return srcExists ? 'src/lib' : 'lib';
78
+ }
79
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/utils/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface EnvVariable {
2
+ key: string;
3
+ value?: string;
4
+ description: string;
5
+ required: boolean;
6
+ }
7
+ export declare function addEnvVariables(projectRoot: string, variables: EnvVariable[], options?: {
8
+ force?: boolean;
9
+ }): Promise<void>;
10
+ export declare function removeEnvVariables(projectRoot: string, keys: string[]): Promise<void>;
11
+ //# sourceMappingURL=env-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-editor.d.ts","sourceRoot":"","sources":["../../src/utils/env-editor.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,WAAW,EAAE,EACxB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CAcf;AA8DD,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addEnvVariables = addEnvVariables;
7
+ exports.removeEnvVariables = removeEnvVariables;
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const logger_1 = require("./logger");
11
+ const ENV_MARKER_START = '# StackKit:';
12
+ const ENV_MARKER_END = '# End StackKit';
13
+ async function addEnvVariables(projectRoot, variables, options = {}) {
14
+ const envExamplePath = path_1.default.join(projectRoot, '.env.example');
15
+ const envPath = path_1.default.join(projectRoot, '.env');
16
+ // Add to .env.example
17
+ await appendToEnvFile(envExamplePath, variables, 'example', options);
18
+ // Add to .env if it exists or create it
19
+ const envExists = await fs_extra_1.default.pathExists(envPath);
20
+ if (envExists || options.force) {
21
+ await appendToEnvFile(envPath, variables, 'local', options);
22
+ }
23
+ logger_1.logger.success('Environment variables added');
24
+ }
25
+ async function appendToEnvFile(filePath, variables, fileType, options = {}) {
26
+ let content = '';
27
+ if (await fs_extra_1.default.pathExists(filePath)) {
28
+ content = await fs_extra_1.default.readFile(filePath, 'utf-8');
29
+ }
30
+ // Check if variables already exist
31
+ const existingKeys = new Set();
32
+ const lines = content.split('\n');
33
+ for (const line of lines) {
34
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
35
+ if (match) {
36
+ existingKeys.add(match[1]);
37
+ }
38
+ }
39
+ const newVariables = variables.filter((v) => {
40
+ if (existingKeys.has(v.key)) {
41
+ if (!options.force) {
42
+ logger_1.logger.warn(`Variable ${v.key} already exists in ${filePath}`);
43
+ return false;
44
+ }
45
+ }
46
+ return true;
47
+ });
48
+ if (newVariables.length === 0) {
49
+ return;
50
+ }
51
+ // Ensure file ends with newline
52
+ if (content && !content.endsWith('\n')) {
53
+ content += '\n';
54
+ }
55
+ // Add marker and variables
56
+ content += '\n';
57
+ content += `${ENV_MARKER_START} Added by StackKit\n`;
58
+ for (const variable of newVariables) {
59
+ if (variable.description) {
60
+ content += `# ${variable.description}\n`;
61
+ }
62
+ const value = fileType === 'example' ? (variable.value || '') : (variable.value || '');
63
+ content += `${variable.key}=${value}\n`;
64
+ }
65
+ content += `${ENV_MARKER_END}\n`;
66
+ await fs_extra_1.default.writeFile(filePath, content, 'utf-8');
67
+ }
68
+ async function removeEnvVariables(projectRoot, keys) {
69
+ const envExamplePath = path_1.default.join(projectRoot, '.env.example');
70
+ const envPath = path_1.default.join(projectRoot, '.env');
71
+ await removeFromEnvFile(envExamplePath, keys);
72
+ if (await fs_extra_1.default.pathExists(envPath)) {
73
+ await removeFromEnvFile(envPath, keys);
74
+ }
75
+ }
76
+ async function removeFromEnvFile(filePath, keys) {
77
+ if (!await fs_extra_1.default.pathExists(filePath)) {
78
+ return;
79
+ }
80
+ let content = await fs_extra_1.default.readFile(filePath, 'utf-8');
81
+ const lines = content.split('\n');
82
+ const newLines = [];
83
+ for (const line of lines) {
84
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
85
+ if (match && keys.includes(match[1])) {
86
+ continue; // Skip this line
87
+ }
88
+ newLines.push(line);
89
+ }
90
+ await fs_extra_1.default.writeFile(filePath, newLines.join('\n'), 'utf-8');
91
+ }
92
+ //# sourceMappingURL=env-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-editor.js","sourceRoot":"","sources":["../../src/utils/env-editor.ts"],"names":[],"mappings":";;;;;AAcA,0CAkBC;AA8DD,gDAYC;AA1GD,wDAA0B;AAC1B,gDAAwB;AACxB,qCAAkC;AAElC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AACvC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AASjC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,SAAwB,EACxB,UAA+B,EAAE;IAEjC,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE/C,sBAAsB;IACtB,MAAM,eAAe,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAErE,wCAAwC;IACxC,MAAM,SAAS,GAAG,MAAM,kBAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,QAAgB,EAChB,SAAwB,EACxB,QAA6B,EAC7B,UAA+B,EAAE;IAEjC,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,mCAAmC;IACnC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACjD,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC1C,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,eAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,sBAAsB,QAAQ,EAAE,CAAC,CAAC;gBAC/D,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,OAAO,IAAI,GAAG,gBAAgB,sBAAsB,CAAC;IAErD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO,IAAI,KAAK,QAAQ,CAAC,WAAW,IAAI,CAAC;QAC3C,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACvF,OAAO,IAAI,GAAG,QAAQ,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,GAAG,cAAc,IAAI,CAAC;IAEjC,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,IAAc;IAEd,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE/C,MAAM,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAE9C,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,QAAgB,EAAE,IAAc;IAC/D,IAAI,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,OAAO;IACT,CAAC;IAED,IAAI,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACjD,IAAI,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,SAAS,CAAC,iBAAiB;QAC7B,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function copyTemplate(templatePath: string, targetPath: string, projectName: string): Promise<void>;
2
+ export declare function createFile(targetPath: string, content: string, options?: {
3
+ force?: boolean;
4
+ }): Promise<void>;
5
+ export declare function readFile(filePath: string): Promise<string>;
6
+ export declare function fileExists(filePath: string): Promise<boolean>;
7
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhE;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnE"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.copyTemplate = copyTemplate;
7
+ exports.createFile = createFile;
8
+ exports.readFile = readFile;
9
+ exports.fileExists = fileExists;
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const logger_1 = require("./logger");
13
+ async function copyTemplate(templatePath, targetPath, projectName) {
14
+ if (!await fs_extra_1.default.pathExists(templatePath)) {
15
+ throw new Error(`Template not found: ${templatePath}`);
16
+ }
17
+ // Create target directory
18
+ await fs_extra_1.default.ensureDir(targetPath);
19
+ // Copy all files
20
+ await fs_extra_1.default.copy(templatePath, targetPath, {
21
+ filter: (src) => {
22
+ const basename = path_1.default.basename(src);
23
+ // Skip template.json metadata file and node_modules
24
+ return basename !== 'template.json' && basename !== 'node_modules';
25
+ },
26
+ });
27
+ // Update package.json with project name
28
+ const packageJsonPath = path_1.default.join(targetPath, 'package.json');
29
+ if (await fs_extra_1.default.pathExists(packageJsonPath)) {
30
+ const packageJson = await fs_extra_1.default.readJSON(packageJsonPath);
31
+ packageJson.name = projectName;
32
+ await fs_extra_1.default.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
33
+ }
34
+ logger_1.logger.success(`Template copied to ${targetPath}`);
35
+ }
36
+ async function createFile(targetPath, content, options = {}) {
37
+ const exists = await fs_extra_1.default.pathExists(targetPath);
38
+ if (exists && !options.force) {
39
+ logger_1.logger.warn(`File already exists: ${targetPath} (use --force to overwrite)`);
40
+ return;
41
+ }
42
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(targetPath));
43
+ await fs_extra_1.default.writeFile(targetPath, content, 'utf-8');
44
+ }
45
+ async function readFile(filePath) {
46
+ return fs_extra_1.default.readFile(filePath, 'utf-8');
47
+ }
48
+ async function fileExists(filePath) {
49
+ return fs_extra_1.default.pathExists(filePath);
50
+ }
51
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":";;;;;AAIA,oCA8BC;AAED,gCAcC;AAED,4BAEC;AAED,gCAEC;AA1DD,wDAA0B;AAC1B,gDAAwB;AACxB,qCAAkC;AAE3B,KAAK,UAAU,YAAY,CAChC,YAAoB,EACpB,UAAkB,EAClB,WAAmB;IAEnB,IAAI,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,0BAA0B;IAC1B,MAAM,kBAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAE/B,iBAAiB;IACjB,MAAM,kBAAE,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE;QACtC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE;YACd,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpC,oDAAoD;YACpD,OAAO,QAAQ,KAAK,eAAe,IAAI,QAAQ,KAAK,cAAc,CAAC;QACrE,CAAC;KACF,CAAC,CAAC;IAEH,wCAAwC;IACxC,MAAM,eAAe,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC9D,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACvD,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC;QAC/B,MAAM,kBAAE,CAAC,SAAS,CAAC,eAAe,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;AACrD,CAAC;AAEM,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,OAAe,EACf,UAA+B,EAAE;IAEjC,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAE/C,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC7B,eAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,6BAA6B,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,kBAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7C,MAAM,kBAAE,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,OAAO,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,OAAO,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function modifyJson(filePath: string, modifier: (json: any) => any, options?: {
2
+ create?: boolean;
3
+ force?: boolean;
4
+ }): Promise<void>;
5
+ export declare function addToPackageJson(filePath: string, section: 'dependencies' | 'devDependencies' | 'scripts', additions: Record<string, string>): Promise<void>;
6
+ export declare function setJsonValue(filePath: string, path: string, value: any, options?: {
7
+ merge?: boolean;
8
+ }): Promise<void>;
9
+ //# sourceMappingURL=json-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-editor.d.ts","sourceRoot":"","sources":["../../src/utils/json-editor.ts"],"names":[],"mappings":"AAGA,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,EAC5B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAClD,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS,EACvD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,EACV,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.modifyJson = modifyJson;
7
+ exports.addToPackageJson = addToPackageJson;
8
+ exports.setJsonValue = setJsonValue;
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ async function modifyJson(filePath, modifier, options = {}) {
11
+ const exists = await fs_extra_1.default.pathExists(filePath);
12
+ if (!exists && !options.create) {
13
+ throw new Error(`File not found: ${filePath}`);
14
+ }
15
+ let json = {};
16
+ if (exists) {
17
+ json = await fs_extra_1.default.readJSON(filePath);
18
+ }
19
+ const modified = modifier(json);
20
+ await fs_extra_1.default.writeJSON(filePath, modified, { spaces: 2 });
21
+ }
22
+ async function addToPackageJson(filePath, section, additions) {
23
+ await modifyJson(filePath, (json) => {
24
+ json[section] = json[section] || {};
25
+ Object.assign(json[section], additions);
26
+ return json;
27
+ });
28
+ }
29
+ async function setJsonValue(filePath, path, value, options = {}) {
30
+ await modifyJson(filePath, (json) => {
31
+ const keys = path.split('.');
32
+ let current = json;
33
+ for (let i = 0; i < keys.length - 1; i++) {
34
+ const key = keys[i];
35
+ if (!current[key]) {
36
+ current[key] = {};
37
+ }
38
+ current = current[key];
39
+ }
40
+ const lastKey = keys[keys.length - 1];
41
+ if (options.merge && typeof current[lastKey] === 'object' && typeof value === 'object') {
42
+ current[lastKey] = { ...current[lastKey], ...value };
43
+ }
44
+ else {
45
+ current[lastKey] = value;
46
+ }
47
+ return json;
48
+ });
49
+ }
50
+ //# sourceMappingURL=json-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-editor.js","sourceRoot":"","sources":["../../src/utils/json-editor.ts"],"names":[],"mappings":";;;;;AAGA,gCAkBC;AAED,4CAUC;AAED,oCA4BC;AA/DD,wDAA0B;AAGnB,KAAK,UAAU,UAAU,CAC9B,QAAgB,EAChB,QAA4B,EAC5B,UAAiD,EAAE;IAEnD,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAE7C,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,OAAuD,EACvD,SAAiC;IAEjC,MAAM,UAAU,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QAClC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,IAAY,EACZ,KAAU,EACV,UAA+B,EAAE;IAEjC,MAAM,UAAU,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC;YACD,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEtC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvF,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Ora } from 'ora';
2
+ export declare class Logger {
3
+ private spinner;
4
+ info(message: string): void;
5
+ success(message: string): void;
6
+ error(message: string): void;
7
+ warn(message: string): void;
8
+ log(message: string): void;
9
+ newLine(): void;
10
+ startSpinner(text: string): Ora;
11
+ stopSpinner(success?: boolean, text?: string): void;
12
+ updateSpinner(text: string): void;
13
+ header(text: string): void;
14
+ footer(): void;
15
+ }
16
+ export declare const logger: Logger;
17
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AACA,OAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAoB;IAEnC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1B,OAAO,IAAI,IAAI;IAIf,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;IAK/B,WAAW,CAAC,OAAO,UAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAWhD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1B,MAAM,IAAI,IAAI;CAGf;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}