@igniter-js/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 (35) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +358 -0
  3. package/dist/templates/components.json.hbs +21 -0
  4. package/dist/templates/copilot.instructions.hbs +117 -0
  5. package/dist/templates/docker-compose.hbs +15 -0
  6. package/dist/templates/env.hbs +33 -0
  7. package/dist/templates/eslintrc.hbs +3 -0
  8. package/dist/templates/feature.controller.hbs +83 -0
  9. package/dist/templates/feature.index.hbs +5 -0
  10. package/dist/templates/feature.interface.hbs +71 -0
  11. package/dist/templates/feature.procedure.hbs +76 -0
  12. package/dist/templates/globals.hbs +198 -0
  13. package/dist/templates/igniter.client.hbs +21 -0
  14. package/dist/templates/igniter.context.hbs +23 -0
  15. package/dist/templates/igniter.hbs +8 -0
  16. package/dist/templates/igniter.router.hbs +29 -0
  17. package/dist/templates/layout.hbs +54 -0
  18. package/dist/templates/page.hbs +313 -0
  19. package/dist/templates/prisma.hbs +9 -0
  20. package/dist/templates/readme.hbs +136 -0
  21. package/dist/templates/vitest.config.hbs +11 -0
  22. package/dist/utils/analyze.d.ts +17 -0
  23. package/dist/utils/analyze.js +187 -0
  24. package/dist/utils/consts.d.ts +26 -0
  25. package/dist/utils/consts.js +34 -0
  26. package/dist/utils/handlebars-helpers.d.ts +1 -0
  27. package/dist/utils/handlebars-helpers.js +43 -0
  28. package/dist/utils/helpers.d.ts +12 -0
  29. package/dist/utils/helpers.js +102 -0
  30. package/dist/utils/prisma-schema-parser.d.ts +59 -0
  31. package/dist/utils/prisma-schema-parser.js +197 -0
  32. package/dist/utils/template-handler.d.ts +6 -0
  33. package/dist/utils/template-handler.js +33 -0
  34. package/package.json +73 -0
  35. package/readme.md +143 -0
@@ -0,0 +1,26 @@
1
+ export declare const PROJECT_STRUCTURE: {
2
+ docs: string[];
3
+ public: never[];
4
+ scripts: string[];
5
+ '.github/actions': string[];
6
+ 'src/configs': string[];
7
+ 'src/core/design-system': never[];
8
+ 'src/core/utils': never[];
9
+ 'src/core/providers': never[];
10
+ 'src/features': string[];
11
+ };
12
+ export declare const LIA_FILES: {
13
+ 'project_requirement.md': string;
14
+ 'detailed_app_flow.md': string;
15
+ 'tech_stack_and_packages.md': string;
16
+ 'file_structure.md': string;
17
+ 'schema_design.md': string;
18
+ };
19
+ export declare const DEPENDENCIES: {
20
+ required: string[];
21
+ };
22
+ export declare const CONFIG_FILES: {
23
+ name: string;
24
+ template: string;
25
+ }[];
26
+ export declare const INTERACTIVE_COMMANDS: string[];
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INTERACTIVE_COMMANDS = exports.CONFIG_FILES = exports.DEPENDENCIES = exports.LIA_FILES = exports.PROJECT_STRUCTURE = void 0;
4
+ exports.PROJECT_STRUCTURE = {
5
+ docs: ['.gitkeep'],
6
+ public: [],
7
+ scripts: ['.gitkeep'],
8
+ '.github/actions': ['.gitkeep'],
9
+ 'src/configs': ['.gitkeep'],
10
+ 'src/core/design-system': [],
11
+ 'src/core/utils': [],
12
+ 'src/core/providers': [],
13
+ 'src/features': ['.gitkeep'],
14
+ };
15
+ exports.LIA_FILES = {
16
+ 'project_requirement.md': '',
17
+ 'detailed_app_flow.md': '',
18
+ 'tech_stack_and_packages.md': '',
19
+ 'file_structure.md': '',
20
+ 'schema_design.md': ''
21
+ };
22
+ exports.DEPENDENCIES = {
23
+ required: ['docker', 'node', 'npm'],
24
+ };
25
+ exports.CONFIG_FILES = [
26
+ { name: 'README.md', template: 'readme' },
27
+ { name: 'eslintrc.json', template: 'eslintrc' },
28
+ { name: 'components.json', template: 'components.json' },
29
+ { name: 'docker-compose.yml', template: 'docker-compose' },
30
+ { name: 'vitest.config.ts', template: 'vitest.config' },
31
+ ];
32
+ exports.INTERACTIVE_COMMANDS = [
33
+ 'shadcn',
34
+ ];
@@ -0,0 +1 @@
1
+ export declare function registerHelpers(): void;
@@ -0,0 +1,43 @@
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.registerHelpers = registerHelpers;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ function registerHelpers() {
9
+ handlebars_1.default.registerHelper('camelCase', (str) => {
10
+ return str.replace(/[-_]([a-z])/g, (g) => g[1].toUpperCase());
11
+ });
12
+ handlebars_1.default.registerHelper('pascalCase', (str) => {
13
+ const camelCase = str.replace(/[-_]([a-z])/g, (g) => g[1].toUpperCase());
14
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
15
+ });
16
+ handlebars_1.default.registerHelper('kebabCase', (str) => {
17
+ return str
18
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
19
+ .replace(/[\s_]+/g, '-')
20
+ .toLowerCase();
21
+ });
22
+ handlebars_1.default.registerHelper('snakeCase', (str) => {
23
+ return str
24
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
25
+ .replace(/[\s-]+/g, '_')
26
+ .toLowerCase();
27
+ });
28
+ handlebars_1.default.registerHelper('lowerFirstLetter', (str) => {
29
+ return str.charAt(0).toLowerCase() + str.slice(1);
30
+ });
31
+ handlebars_1.default.registerHelper('lowerCase', (str) => {
32
+ return str.toLowerCase();
33
+ });
34
+ /**
35
+ * Handlebars helper to compare if two values are equal
36
+ * @param {string} firstValue - First value to compare
37
+ * @param {string} secondValue - Second value to compare
38
+ * @returns {boolean} Returns true if values are equal, false otherwise
39
+ */
40
+ handlebars_1.default.registerHelper('equals', (firstValue, secondValue) => {
41
+ return firstValue === secondValue;
42
+ });
43
+ }
@@ -0,0 +1,12 @@
1
+ export declare abstract class CLIHelper {
2
+ protected execCommand(command: string): void;
3
+ protected createDir(dir: string): void;
4
+ protected createFile(filePath: string, content?: string): void;
5
+ protected updateFile(filePath: string, content: string): void;
6
+ protected checkDependencies(dependencies: string[]): void;
7
+ protected delay(ms: number): Promise<void>;
8
+ protected loadJSON(filePath: string): any;
9
+ protected saveJSON(filePath: string, data: any): void;
10
+ protected createDirectoryStructure(structure: Record<string, any>, basePath?: string): void;
11
+ protected installDependencies(dependencies: Record<string, string>, dev?: boolean): void;
12
+ }
@@ -0,0 +1,102 @@
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.CLIHelper = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const consts_1 = require("./consts");
11
+ class CLIHelper {
12
+ execCommand(command) {
13
+ try {
14
+ const needsInteraction = consts_1.INTERACTIVE_COMMANDS.some((cmd) => command.includes(cmd));
15
+ if (needsInteraction) {
16
+ console.log(`\n📦 Executing: ${command}\n`);
17
+ (0, child_process_1.execSync)(command, { stdio: 'inherit' });
18
+ console.log('\n✅ Command completed successfully\n');
19
+ }
20
+ else {
21
+ (0, child_process_1.execSync)(command, {
22
+ stdio: ['pipe', 'pipe', 'pipe'],
23
+ encoding: 'utf-8'
24
+ });
25
+ }
26
+ }
27
+ catch (error) {
28
+ console.error(`Failed to execute command: ${command} \n${error}`);
29
+ process.exit(1);
30
+ }
31
+ }
32
+ createDir(dir) {
33
+ if (!fs_1.default.existsSync(dir)) {
34
+ fs_1.default.mkdirSync(dir, { recursive: true });
35
+ }
36
+ }
37
+ createFile(filePath, content = '') {
38
+ const dir = path_1.default.dirname(filePath);
39
+ if (!fs_1.default.existsSync(dir)) {
40
+ fs_1.default.mkdirSync(dir, { recursive: true });
41
+ }
42
+ fs_1.default.writeFileSync(filePath, content);
43
+ }
44
+ updateFile(filePath, content) {
45
+ fs_1.default.writeFileSync(filePath, content);
46
+ }
47
+ checkDependencies(dependencies) {
48
+ for (const dep of dependencies) {
49
+ try {
50
+ (0, child_process_1.execSync)(`${dep} --version`, { stdio: 'pipe' });
51
+ }
52
+ catch (error) {
53
+ console.error(`Required dependency not found: ${dep}. Please install it before proceeding. \n${error}`);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ }
58
+ async delay(ms) {
59
+ return new Promise(resolve => setTimeout(resolve, ms));
60
+ }
61
+ loadJSON(filePath) {
62
+ try {
63
+ return JSON.parse(fs_1.default.readFileSync(filePath, 'utf8'));
64
+ }
65
+ catch (error) {
66
+ console.error(`Failed to load JSON file: ${filePath} \n${error}`);
67
+ process.exit(1);
68
+ }
69
+ }
70
+ saveJSON(filePath, data) {
71
+ try {
72
+ fs_1.default.writeFileSync(filePath, JSON.stringify(data, null, 2));
73
+ }
74
+ catch (error) {
75
+ console.error(`Failed to save JSON file: ${filePath} \n${error}`);
76
+ process.exit(1);
77
+ }
78
+ }
79
+ createDirectoryStructure(structure, basePath = '') {
80
+ Object.entries(structure).forEach(([dir, content]) => {
81
+ const fullPath = path_1.default.join(basePath, dir);
82
+ this.createDir(fullPath);
83
+ if (Array.isArray(content)) {
84
+ content.forEach(file => {
85
+ if (typeof file === 'string') {
86
+ this.createFile(path_1.default.join(fullPath, file));
87
+ }
88
+ });
89
+ }
90
+ else if (content && typeof content === 'object') {
91
+ this.createDirectoryStructure(content, fullPath);
92
+ }
93
+ });
94
+ }
95
+ installDependencies(dependencies, dev = false) {
96
+ const deps = Object.entries(dependencies)
97
+ .map(([name, version]) => `${name}@${version}`)
98
+ .join(' ');
99
+ this.execCommand(`npm install ${dev ? '-D ' : ''}${deps}`);
100
+ }
101
+ }
102
+ exports.CLIHelper = CLIHelper;
@@ -0,0 +1,59 @@
1
+ interface ParsedField {
2
+ name: string;
3
+ type: string;
4
+ zodType: string;
5
+ description: string;
6
+ isOptional: boolean;
7
+ isList: boolean;
8
+ hasDefault: boolean;
9
+ isEnum?: boolean;
10
+ enumValues?: string[];
11
+ relations?: {
12
+ type: 'one-to-one' | 'one-to-many' | 'many-to-many';
13
+ model: string;
14
+ fields: string[];
15
+ references: string[];
16
+ };
17
+ }
18
+ export declare class PrismaSchemaParser {
19
+ private readonly schemaPath;
20
+ private schemaContent;
21
+ constructor(basePath?: string);
22
+ /**
23
+ * Loads the Prisma schema file content
24
+ */
25
+ private loadSchema;
26
+ /**
27
+ * Gets the raw schema content
28
+ */
29
+ getSchemaContent(): string;
30
+ /**
31
+ * Checks if a model exists in the Prisma schema
32
+ */
33
+ hasModel(modelName: string): boolean;
34
+ /**
35
+ * Gets fields from a specific model
36
+ */
37
+ getModelFields(modelName: string): ParsedField[];
38
+ /**
39
+ * Parses field strings into structured field objects
40
+ */
41
+ private parseFields;
42
+ /**
43
+ * Parses a single field line into a structured field object
44
+ */
45
+ private parseFieldLine;
46
+ /**
47
+ * Parses a relation decorator into a structured object
48
+ */
49
+ private parseRelation;
50
+ /**
51
+ * Decodes HTML entities in a string
52
+ */
53
+ private decodeHtmlEntities;
54
+ /**
55
+ * Converts Prisma types to Zod types
56
+ */
57
+ private getZodType;
58
+ }
59
+ export {};
@@ -0,0 +1,197 @@
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.PrismaSchemaParser = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ class PrismaSchemaParser {
10
+ constructor(basePath = process.cwd()) {
11
+ this.schemaContent = '';
12
+ this.schemaPath = path_1.default.join(basePath, 'prisma/schema.prisma');
13
+ }
14
+ /**
15
+ * Loads the Prisma schema file content
16
+ */
17
+ loadSchema() {
18
+ if (!fs_1.default.existsSync(this.schemaPath)) {
19
+ throw new Error('Prisma schema file not found');
20
+ }
21
+ this.schemaContent = fs_1.default.readFileSync(this.schemaPath, 'utf-8');
22
+ }
23
+ /**
24
+ * Gets the raw schema content
25
+ */
26
+ getSchemaContent() {
27
+ this.loadSchema();
28
+ return this.schemaContent;
29
+ }
30
+ /**
31
+ * Checks if a model exists in the Prisma schema
32
+ */
33
+ hasModel(modelName) {
34
+ this.loadSchema();
35
+ const modelRegex = new RegExp(`model\\s+${modelName}\\s*{`, 'i');
36
+ return modelRegex.test(this.schemaContent);
37
+ }
38
+ /**
39
+ * Gets fields from a specific model
40
+ */
41
+ getModelFields(modelName) {
42
+ this.loadSchema();
43
+ if (!this.hasModel(modelName)) {
44
+ return [];
45
+ }
46
+ const modelRegex = new RegExp(`model\\s+${modelName}\\s*{([^}]*)}`, 'i');
47
+ const modelMatch = this.schemaContent.match(modelRegex);
48
+ if (!modelMatch || !modelMatch[1]) {
49
+ return [];
50
+ }
51
+ const fieldsContent = modelMatch[1].trim();
52
+ return this.parseFields(fieldsContent);
53
+ }
54
+ /**
55
+ * Parses field strings into structured field objects
56
+ */
57
+ parseFields(fieldsContent) {
58
+ this.loadSchema();
59
+ const fieldLines = fieldsContent.split('\n');
60
+ const fields = [];
61
+ for (const line of fieldLines) {
62
+ const trimmedLine = line.trim();
63
+ if (!trimmedLine || trimmedLine.startsWith('@@'))
64
+ continue;
65
+ const field = this.parseFieldLine(trimmedLine);
66
+ if (field) {
67
+ fields.push(field);
68
+ }
69
+ }
70
+ return fields;
71
+ }
72
+ /**
73
+ * Parses a single field line into a structured field object
74
+ */
75
+ parseFieldLine(line) {
76
+ this.loadSchema();
77
+ // Basic field pattern: name type modifiers
78
+ const fieldPattern = /^(\w+)\s+(\w+)(\?|\[\])?\s*(@\w+(?:\([^)]*\))?)*$/;
79
+ const match = line.match(fieldPattern);
80
+ if (!match)
81
+ return null;
82
+ const [, name, type] = match;
83
+ const modifiers = line.slice(match[0].length).trim();
84
+ const isOptional = line.includes('?');
85
+ const isList = line.includes('[]');
86
+ const hasDefault = modifiers.includes('@default');
87
+ // Skip internal Prisma fields
88
+ if (['id', 'createdAt', 'updatedAt'].includes(name)) {
89
+ return null;
90
+ }
91
+ // Verifica se é um enum
92
+ const isEnum = this.schemaContent.includes(`enum ${type} {`);
93
+ // Parse relations
94
+ let relations = undefined;
95
+ if (line.includes('@relation')) {
96
+ const relationMatch = line.match(/@relation\([^)]*\)/);
97
+ if (relationMatch) {
98
+ relations = this.parseRelation(relationMatch[0], isList);
99
+ }
100
+ }
101
+ return {
102
+ name,
103
+ type,
104
+ zodType: this.getZodType(type, isOptional, isList),
105
+ description: `${name} field`,
106
+ isOptional,
107
+ isList,
108
+ hasDefault,
109
+ isEnum,
110
+ relations
111
+ };
112
+ }
113
+ /**
114
+ * Parses a relation decorator into a structured object
115
+ */
116
+ parseRelation(relationString, isList) {
117
+ var _a;
118
+ const relationDetails = (_a = relationString.match(/@relation\(([^)]+)\)/)) === null || _a === void 0 ? void 0 : _a[1].split(',');
119
+ if (!relationDetails)
120
+ return undefined;
121
+ const nameMatch = relationDetails.find(detail => detail.trim().startsWith('name:'));
122
+ const fieldsMatch = relationDetails.find(detail => detail.trim().startsWith('fields:'));
123
+ const referencesMatch = relationDetails.find(detail => detail.trim().startsWith('references:'));
124
+ if (nameMatch && fieldsMatch && referencesMatch) {
125
+ const model = nameMatch.split(':')[1].trim().replace(/['"]/g, '');
126
+ const fields = fieldsMatch.split(':')[1].trim().replace(/\[|\]/g, '').split(',').map(f => f.trim());
127
+ const references = referencesMatch.split(':')[1].trim().replace(/\[|\]/g, '').split(',').map(f => f.trim());
128
+ return {
129
+ type: fields.length > 1 || references.length > 1 ? 'many-to-many' : (isList ? 'one-to-many' : 'one-to-one'),
130
+ model,
131
+ fields,
132
+ references
133
+ };
134
+ }
135
+ return undefined;
136
+ }
137
+ /**
138
+ * Decodes HTML entities in a string
139
+ */
140
+ decodeHtmlEntities(text) {
141
+ return text
142
+ .replace(/&amp;/g, '&')
143
+ .replace(/&lt;/g, '<')
144
+ .replace(/&gt;/g, '>')
145
+ .replace(/&quot;/g, '"')
146
+ .replace(/&#x27;/g, "'")
147
+ .replace(/&#x60;/g, '`');
148
+ }
149
+ /**
150
+ * Converts Prisma types to Zod types
151
+ */
152
+ getZodType(type, isOptional = false, isList = false) {
153
+ this.loadSchema();
154
+ // Verifica se é um enum primeiro
155
+ const enumMatch = this.schemaContent.match(new RegExp(`enum\\s+${type}\\s*{([^}]*)}`, 'i'));
156
+ if (enumMatch) {
157
+ const enumValues = enumMatch[1]
158
+ .trim()
159
+ .split('\n')
160
+ .map(v => v.trim())
161
+ .filter(Boolean)
162
+ .map(v => this.decodeHtmlEntities(v)) // Decodifica HTML entities
163
+ .map(v => v.replace(/['"]/g, '').trim());
164
+ return `z.enum([${enumValues.map(v => `'${v}'`).join(', ')}])`;
165
+ }
166
+ const uuidMatch = this.schemaContent.match(/@default\(uuid\((\d+)?\)\)/);
167
+ const uuidVersion = uuidMatch ? (uuidMatch[1] || '4') : null;
168
+ const typeMap = {
169
+ 'String': 'z.string()',
170
+ 'Int': 'z.number().int()',
171
+ 'Float': 'z.number()',
172
+ 'Boolean': 'z.boolean()',
173
+ 'DateTime': 'z.date()',
174
+ 'Json': 'z.any()',
175
+ 'BigInt': 'z.bigint()',
176
+ 'Decimal': 'z.number()',
177
+ 'Bytes': 'z.instanceof(Buffer)',
178
+ 'UUID': `z.string().uuid(${uuidVersion ? `{ version: ${uuidVersion} }` : ''})`,
179
+ };
180
+ // Handle relationships
181
+ if (!typeMap[type]) {
182
+ if (isList) {
183
+ return 'z.array(z.string().min(1))';
184
+ }
185
+ return 'z.string().min(1)';
186
+ }
187
+ let zodType = typeMap[type] || 'z.any()';
188
+ if (isList) {
189
+ zodType = `z.array(${zodType})`;
190
+ }
191
+ if (isOptional) {
192
+ zodType = `${zodType}.optional().nullable()`;
193
+ }
194
+ return zodType;
195
+ }
196
+ }
197
+ exports.PrismaSchemaParser = PrismaSchemaParser;
@@ -0,0 +1,6 @@
1
+ import Handlebars from 'handlebars';
2
+ export declare class TemplateHandler {
3
+ private static templatesPath;
4
+ static render(templateName: string, data: any, customPath?: string): string;
5
+ static registerHelper(name: string, fn: Handlebars.HelperDelegate): void;
6
+ }
@@ -0,0 +1,33 @@
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.TemplateHandler = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const fs_1 = require("fs");
9
+ const path_1 = __importDefault(require("path"));
10
+ class TemplateHandler {
11
+ static render(templateName, data, customPath) {
12
+ if (!templateName.endsWith('.hbs')) {
13
+ templateName = `${templateName}.hbs`;
14
+ }
15
+ if (customPath) {
16
+ this.templatesPath = path_1.default.join(__dirname, '..', customPath);
17
+ }
18
+ const templatePath = path_1.default.join(this.templatesPath, templateName);
19
+ const templateContent = (0, fs_1.readFileSync)(templatePath, 'utf-8');
20
+ const template = handlebars_1.default.compile(templateContent);
21
+ const result = template(data);
22
+ // If template is for .env file, add an extra line before appending
23
+ if (templateName === '.env' || templateName.endsWith('env')) {
24
+ return '\n' + result;
25
+ }
26
+ return result;
27
+ }
28
+ static registerHelper(name, fn) {
29
+ handlebars_1.default.registerHelper(name, fn);
30
+ }
31
+ }
32
+ exports.TemplateHandler = TemplateHandler;
33
+ TemplateHandler.templatesPath = path_1.default.join(__dirname, '..', 'templates');
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@igniter-js/cli",
3
+ "version": "0.1.0",
4
+ "description": "Igniter CLI for projects using Igniter Framework",
5
+ "main": "dist/index.js",
6
+ "homepage": "https://felipebarcelospro.github.io/igniter",
7
+ "bin": {
8
+ "igniter": "dist/index.js"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/felipebarcelospro/igniter-cli.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/felipebarcelospro/igniter-cli/issues"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc && mkdir -p dist/templates && cp -r src/templates/* dist/templates",
19
+ "dev": "ts-node src/index.ts",
20
+ "lint": "eslint src --ext .ts",
21
+ "lint:fix": "eslint src --ext .ts --fix",
22
+ "format": "prettier --write \"src/**/*.{ts,hbs}\"",
23
+ "prepublishOnly": "bun run build",
24
+ "test": "echo \"No tests specified\" && exit 0",
25
+ "release": "npm publish --access public"
26
+ },
27
+ "keywords": [
28
+ "igniter",
29
+ "igniter-js",
30
+ "next.js",
31
+ "cli",
32
+ "generator",
33
+ "feature-first",
34
+ "typescript",
35
+ "scaffolding",
36
+ "boilerplate",
37
+ "code-generation"
38
+ ],
39
+ "author": "Felipe Barcelos <felipe.barcelos@nubler.io>",
40
+ "license": "MIT",
41
+ "dependencies": {
42
+ "chalk": "^4.1.2",
43
+ "commander": "^11.1.0",
44
+ "handlebars": "^4.7.8",
45
+ "inquirer": "^8.2.6",
46
+ "ora": "^5.4.1",
47
+ "reflect-metadata": "^0.2.2",
48
+ "zod": "^3.23.8"
49
+ },
50
+ "devDependencies": {
51
+ "@types/inquirer": "^8.2.10",
52
+ "@types/node": "^20.10.2",
53
+ "@typescript-eslint/eslint-plugin": "^6.13.1",
54
+ "@typescript-eslint/parser": "^6.13.1",
55
+ "eslint": "^8.55.0",
56
+ "prettier": "^3.1.0",
57
+ "ts-node": "^10.9.1",
58
+ "typescript": "^5.3.2"
59
+ },
60
+ "engines": {
61
+ "node": ">=16"
62
+ },
63
+ "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
64
+ "types": "./dist/index.d.ts",
65
+ "files": [
66
+ "dist",
67
+ "LICENSE",
68
+ "README.md"
69
+ ],
70
+ "publishConfig": {
71
+ "access": "public"
72
+ }
73
+ }