@xeno-js/cli 0.1.3 → 0.1.4

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 (88) hide show
  1. package/LICENSE +18 -12
  2. package/README.md +461 -236
  3. package/dist/index.js +985 -653
  4. package/dist/index.js.map +1 -1
  5. package/package.json +91 -66
  6. package/.github/.copilot-instruction.md +0 -73
  7. package/.github/agents/git-operator.agent.md +0 -86
  8. package/.github/agents/unit-tester.agent.md +0 -68
  9. package/.husky/commit-msg +0 -1
  10. package/.husky/pre-commit +0 -1
  11. package/.husky/pre-push +0 -1
  12. package/.prettierignore +0 -7
  13. package/.prettierrc.json +0 -37
  14. package/commitlint.config.cjs +0 -39
  15. package/eslint.config.mjs +0 -306
  16. package/lint-staged.config.mjs +0 -5
  17. package/logo/logo.png +0 -0
  18. package/src/domain/contracts/icommand-cli.contracts.ts +0 -13
  19. package/src/domain/contracts/icommand-runner.contracts.ts +0 -3
  20. package/src/domain/contracts/idispatch.contracts.ts +0 -3
  21. package/src/domain/contracts/ifile-service.contracts.ts +0 -3
  22. package/src/domain/contracts/igenerator.contracts.ts +0 -5
  23. package/src/domain/contracts/index.ts +0 -6
  24. package/src/domain/contracts/iscaffold-strategy.contracts.ts +0 -7
  25. package/src/domain/index.ts +0 -1
  26. package/src/index.ts +0 -30
  27. package/src/infrastructure/bootstrap/bootstrapper.ts +0 -30
  28. package/src/infrastructure/bootstrap/index.ts +0 -1
  29. package/src/infrastructure/builder/builder.test.ts +0 -36
  30. package/src/infrastructure/builder/builder.ts +0 -15
  31. package/src/infrastructure/builder/index.ts +0 -1
  32. package/src/infrastructure/command_launcher/command.utils.ts +0 -31
  33. package/src/infrastructure/command_launcher/index.ts +0 -0
  34. package/src/infrastructure/commands/command-runner.service.ts +0 -36
  35. package/src/infrastructure/commands/generate.command.ts +0 -55
  36. package/src/infrastructure/commands/help.command.ts +0 -63
  37. package/src/infrastructure/commands/index.ts +0 -4
  38. package/src/infrastructure/commands/new-project.command.ts +0 -47
  39. package/src/infrastructure/dispatcher/dispatcher.ts +0 -45
  40. package/src/infrastructure/dispatcher/index.ts +0 -1
  41. package/src/infrastructure/file/file.service.ts +0 -14
  42. package/src/infrastructure/file/index.ts +0 -1
  43. package/src/infrastructure/generators/core/bootstrap.generator.ts +0 -118
  44. package/src/infrastructure/generators/core/command/cqrs.generator.ts +0 -63
  45. package/src/infrastructure/generators/core/command/generate-command.generator.ts +0 -191
  46. package/src/infrastructure/generators/core/command/generate-query.generator.ts +0 -150
  47. package/src/infrastructure/generators/core/drizzle-sql-lite.generator.ts +0 -77
  48. package/src/infrastructure/generators/core/drizzle.generator.ts +0 -87
  49. package/src/infrastructure/generators/core/env.generator.ts +0 -69
  50. package/src/infrastructure/generators/core/index.ts +0 -9
  51. package/src/infrastructure/generators/core/main.generator.ts +0 -41
  52. package/src/infrastructure/generators/core/packagejson.generator.ts +0 -70
  53. package/src/infrastructure/generators/core/readme.generator.ts +0 -427
  54. package/src/infrastructure/generators/core/registry.generator.ts +0 -40
  55. package/src/infrastructure/generators/core/tsconfig.generator.ts +0 -32
  56. package/src/infrastructure/generators/gitignore.generator.ts +0 -60
  57. package/src/infrastructure/generators/vue/app-vue.generator.ts +0 -21
  58. package/src/infrastructure/generators/vue/bootstrap-ts.generator.ts +0 -60
  59. package/src/infrastructure/generators/vue/command_query/cqrs.generator.ts +0 -36
  60. package/src/infrastructure/generators/vue/command_query/generate-command-vue.generator.ts +0 -153
  61. package/src/infrastructure/generators/vue/command_query/generate-query-vue.generator.ts +0 -161
  62. package/src/infrastructure/generators/vue/env.generator.ts +0 -39
  63. package/src/infrastructure/generators/vue/index-html.generator.ts +0 -24
  64. package/src/infrastructure/generators/vue/index.ts +0 -12
  65. package/src/infrastructure/generators/vue/main.generator.ts +0 -41
  66. package/src/infrastructure/generators/vue/packagejson.generator.ts +0 -50
  67. package/src/infrastructure/generators/vue/readme.generator.ts +0 -389
  68. package/src/infrastructure/generators/vue/registry-ts.generator.ts +0 -26
  69. package/src/infrastructure/generators/vue/router.generator.ts +0 -35
  70. package/src/infrastructure/generators/vue/tailwind.generator.ts +0 -17
  71. package/src/infrastructure/generators/vue/tsconfig.generator.ts +0 -38
  72. package/src/infrastructure/generators/vue/use-app.generator.ts +0 -38
  73. package/src/infrastructure/generators/vue/vite-config.generator.ts +0 -35
  74. package/src/infrastructure/index.ts +0 -5
  75. package/src/infrastructure/strategies/core-scaffold.strategy.ts +0 -100
  76. package/src/infrastructure/strategies/index.ts +0 -2
  77. package/src/infrastructure/strategies/vue-scaffold.strategy.ts +0 -79
  78. package/src/shared/constants/command.constants.ts +0 -18
  79. package/src/shared/constants/core.constants.ts +0 -7
  80. package/src/shared/constants/index.ts +0 -2
  81. package/src/shared/index.ts +0 -3
  82. package/src/shared/types/common.types.ts +0 -68
  83. package/src/shared/types/index.ts +0 -1
  84. package/src/shared/utils/guards.utils.ts +0 -334
  85. package/src/shared/utils/index.ts +0 -2
  86. package/src/shared/utils/string.utils.ts +0 -60
  87. package/tsconfig.json +0 -15
  88. package/tsup.config.ts +0 -13
package/eslint.config.mjs DELETED
@@ -1,306 +0,0 @@
1
- import eslint from '@eslint/js'
2
- import eslintConfigPrettier from 'eslint-config-prettier'
3
- import simpleImportSort from 'eslint-plugin-simple-import-sort'
4
- import tseslint from 'typescript-eslint'
5
-
6
- export default tseslint.config(
7
- // ── Global ignores ───────────────────────────────────────────────────────
8
- {
9
- ignores: [
10
- '**/node_modules/**',
11
- '**/dist/**',
12
- '**/coverage/**',
13
- '.husky/**',
14
- 'eslint.config.mjs',
15
- 'lint-staged.config.mjs',
16
- 'commitlint.config.cjs',
17
- 'vitest.config.ts',
18
- 'tsup.config.ts',
19
- 'demo/**',
20
- 'packages/**',
21
- ],
22
- },
23
-
24
- // ── Base configs ─────────────────────────────────────────────────────────
25
- eslint.configs.recommended,
26
- ...tseslint.configs.recommendedTypeChecked,
27
- ...tseslint.configs.stylisticTypeChecked,
28
-
29
- // ── Type-aware parser (project-wide) ─────────────────────────────────────
30
- {
31
- languageOptions: {
32
- parserOptions: {
33
- project: ['./tsconfig.json', './tsconfig.test.json'],
34
- tsconfigRootDir: import.meta.dirname,
35
- },
36
- },
37
- },
38
-
39
- // ── Source + test rules ──────────────────────────────────────────────────
40
- {
41
- files: ['src/**/*.ts', 'tests/**/*.ts'],
42
- plugins: {
43
- 'simple-import-sort': simpleImportSort,
44
- },
45
- rules: {
46
- // ── Core JS ──────────────────────────────────────────────────────────
47
- 'curly': ['error', 'all'],
48
- 'eqeqeq': ['error', 'always', { null: 'ignore' }],
49
- 'no-console': ['error', { allow: ['warn', 'error', 'info', 'debug'] }],
50
- // Disabled: the core rule does not understand TypeScript's `import type`
51
- // and flags intentional type/value split imports from the same module.
52
- // `@typescript-eslint/consistent-type-imports` already enforces correct usage.
53
- 'no-duplicate-imports': 'off',
54
- 'no-var': 'error',
55
- 'object-shorthand': ['error', 'always'],
56
- 'prefer-const': 'error',
57
- 'prefer-template': 'error',
58
-
59
- // ── Import order ──────────────────────────────────────────────────────
60
- 'simple-import-sort/imports': 'error',
61
- 'simple-import-sort/exports': 'error',
62
-
63
- // ── TypeScript: type-safe guarantees ──────────────────────────────────
64
- '@typescript-eslint/consistent-type-exports': 'error',
65
- '@typescript-eslint/consistent-type-imports': [
66
- 'error',
67
- { prefer: 'type-imports', fixStyle: 'inline-type-imports' },
68
- ],
69
- '@typescript-eslint/explicit-module-boundary-types': 'error',
70
- '@typescript-eslint/no-floating-promises': 'error',
71
- '@typescript-eslint/no-misused-promises': [
72
- 'error',
73
- { checksVoidReturn: { attributes: false } },
74
- ],
75
- '@typescript-eslint/only-throw-error': 'error',
76
- // '@typescript-eslint/return-await': ['error', 'in-try-catch'],
77
- '@typescript-eslint/strict-boolean-expressions': [
78
- 'error',
79
- {
80
- allowString: false,
81
- allowNumber: false,
82
- allowNullableObject: false,
83
- allowNullableBoolean: false,
84
- allowNullableString: false,
85
- allowNullableNumber: false,
86
- allowAny: false,
87
- },
88
- ],
89
- '@typescript-eslint/unbound-method': 'error',
90
- '@typescript-eslint/no-unsafe-assignment': 'error',
91
- '@typescript-eslint/no-unsafe-call': 'error',
92
- '@typescript-eslint/no-unsafe-member-access': 'error',
93
- '@typescript-eslint/no-unsafe-return': 'error',
94
- '@typescript-eslint/no-unsafe-argument': 'error',
95
- '@typescript-eslint/restrict-template-expressions': 'error',
96
- '@typescript-eslint/restrict-plus-operands': 'error',
97
- '@typescript-eslint/no-unsafe-enum-comparison': 'error',
98
- '@typescript-eslint/require-await': 'off',
99
- // ── TypeScript: code quality ──────────────────────────────────────────
100
- '@typescript-eslint/no-shadow': 'error',
101
- '@typescript-eslint/no-unused-vars': [
102
- 'error',
103
- {
104
- argsIgnorePattern: '^_',
105
- varsIgnorePattern: '^_',
106
- ignoreRestSiblings: true,
107
- },
108
- ],
109
-
110
- // ── TypeScript: naming conventions ────────────────────────────────────
111
- '@typescript-eslint/naming-convention': [
112
- 'error',
113
- // Type constructs → PascalCase
114
- { selector: 'typeLike', format: ['PascalCase'] },
115
- // Enum members → UPPER_CASE (PascalCase tolerated for legacy)
116
- { selector: 'enumMember', format: ['UPPER_CASE', 'PascalCase'] },
117
- // Default catch-all → camelCase (leading _ allowed for intentionally unused)
118
- {
119
- selector: 'default',
120
- format: ['camelCase'],
121
- leadingUnderscore: 'allow',
122
- trailingUnderscore: 'forbid',
123
- },
124
- // Variables: also allow UPPER_CASE for module-level constants, PascalCase for imported classes
125
- {
126
- selector: 'variable',
127
- format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
128
- leadingUnderscore: 'allow',
129
- },
130
- // Imports: PascalCase (classes/namespaces) and camelCase (functions/values)
131
- { selector: 'import', format: ['camelCase', 'PascalCase'] },
132
- // Object literal properties: no restriction (external API / DB column mapping)
133
- { selector: 'objectLiteralProperty', format: null },
134
- // Destructured variables: no restriction (external sources)
135
- { selector: 'variable', modifiers: ['destructured'], format: null },
136
- ],
137
-
138
- // ── Disabled / adjusted ───────────────────────────────────────────────
139
- 'dot-notation': 'off',
140
- '@typescript-eslint/dot-notation': 'off',
141
- },
142
- },
143
-
144
- // ── Test files: relax rules that conflict with test patterns ────────────
145
- {
146
- files: ['tests/**/*.ts'],
147
- rules: {
148
- '@typescript-eslint/explicit-module-boundary-types': 'off',
149
- '@typescript-eslint/no-explicit-any': 'off',
150
- '@typescript-eslint/no-non-null-assertion': 'off',
151
- },
152
- },
153
-
154
- // ── Layered architecture boundaries (DDD / Clean Architecture) ─────────
155
- {
156
- files: ['src/shared/**/*.ts'],
157
- rules: {
158
- 'no-restricted-imports': [
159
- 'error',
160
- {
161
- patterns: [
162
- {
163
- group: [
164
- '@/domain',
165
- '@/domain/**',
166
- '@/application',
167
- '@/application/**',
168
- '@/infrastructure',
169
- '@/infrastructure/**',
170
- '@/presentation',
171
- '@/presentation/**',
172
- ],
173
- message: 'shared can only import from shared and external libraries.',
174
- },
175
- {
176
- group: [
177
- '../**/domain',
178
- '../**/domain/**',
179
- '../**/application',
180
- '../**/application/**',
181
- '../**/infrastructure',
182
- '../**/infrastructure/**',
183
- '../**/presentation',
184
- '../**/presentation/**',
185
- ],
186
- message: 'shared can only import from shared and external libraries.',
187
- },
188
- ],
189
- },
190
- ],
191
- },
192
- },
193
- {
194
- files: ['src/domain/**/*.ts'],
195
- rules: {
196
- 'no-restricted-imports': [
197
- 'error',
198
- {
199
- patterns: [
200
- {
201
- group: [
202
- '@/application',
203
- '@/application/**',
204
- '@/infrastructure',
205
- '@/infrastructure/**',
206
- '@/presentation',
207
- '@/presentation/**',
208
- ],
209
- message: 'domain can only import from domain, shared, and external libraries.',
210
- },
211
- {
212
- group: [
213
- '../**/application',
214
- '../**/application/**',
215
- '../**/infrastructure',
216
- '../**/infrastructure/**',
217
- '../**/presentation',
218
- '../**/presentation/**',
219
- ],
220
- message: 'domain can only import from domain, shared, and external libraries.',
221
- },
222
- ],
223
- },
224
- ],
225
- },
226
- },
227
- {
228
- files: ['src/application/**/*.ts'],
229
- rules: {
230
- 'no-restricted-imports': [
231
- 'error',
232
- {
233
- patterns: [
234
- {
235
- group: [
236
- '@/infrastructure',
237
- '@/infrastructure/**',
238
- '@/presentation',
239
- '@/presentation/**',
240
- ],
241
- message:
242
- 'application can only import from application, domain, shared, and external libraries.',
243
- },
244
- {
245
- group: [
246
- '../**/infrastructure',
247
- '../**/infrastructure/**',
248
- '../**/presentation',
249
- '../**/presentation/**',
250
- ],
251
- message:
252
- 'application can only import from application, domain, shared, and external libraries.',
253
- },
254
- ],
255
- },
256
- ],
257
- },
258
- },
259
- {
260
- files: ['src/infrastructure/**/*.ts'],
261
- rules: {
262
- 'no-restricted-imports': [
263
- 'error',
264
- {
265
- patterns: [
266
- {
267
- group: ['@/presentation', '@/presentation/**'],
268
- message:
269
- 'infrastructure can only import from infrastructure, domain, application, shared, and external libraries.',
270
- },
271
- {
272
- group: ['../**/presentation', '../**/presentation/**'],
273
- message:
274
- 'infrastructure can only import from infrastructure, domain, application, shared, and external libraries.',
275
- },
276
- ],
277
- },
278
- ],
279
- },
280
- },
281
- {
282
- files: ['src/presentation/**/*.ts'],
283
- rules: {
284
- 'no-restricted-imports': [
285
- 'error',
286
- {
287
- patterns: [
288
- {
289
- group: ['@/infrastructure', '@/infrastructure/**'],
290
- message:
291
- 'presentation can only import from presentation, domain, application, shared, and external libraries.',
292
- },
293
- {
294
- group: ['../**/infrastructure', '../**/infrastructure/**'],
295
- message:
296
- 'presentation can only import from presentation, domain, application, shared, and external libraries.',
297
- },
298
- ],
299
- },
300
- ],
301
- },
302
- },
303
-
304
- // ── Prettier (must be last) ───────────────────────────────────────────────
305
- eslintConfigPrettier,
306
- )
@@ -1,5 +0,0 @@
1
- export default {
2
- 'src/**/*.ts': ['eslint --config eslint.config.mjs --fix --max-warnings=0', 'prettier --write'],
3
- '*.{json,md,yml,yaml,css,scss,html}': ['prettier --write'],
4
- '*.{js,mjs,cjs}': ['prettier --write'],
5
- }
package/logo/logo.png DELETED
Binary file
@@ -1,13 +0,0 @@
1
- export interface ICliCommand {
2
- /** Il nome principale del comando (es. 'new', 'generate') */
3
- get name(): string
4
-
5
- /** Eventuali alias (es. 'g' per 'generate') */
6
- get aliases(): string[]
7
-
8
- /**
9
- * Il metodo esecutivo.
10
- * Riceve solo gli argomenti di pertinenza (escludendo il nome del comando stesso).
11
- */
12
- execute(args: string[]): Promise<void>
13
- }
@@ -1,3 +0,0 @@
1
- export interface ICommandRunner {
2
- run(command: string, args: string[], cwd: string): Promise<void>
3
- }
@@ -1,3 +0,0 @@
1
- export interface IDispatcher {
2
- dispatch(rawArgs: string[]): Promise<void>
3
- }
@@ -1,3 +0,0 @@
1
- export interface IFileService {
2
- writeFileRecursive(filePath: string, content: string): Promise<void>
3
- }
@@ -1,5 +0,0 @@
1
- import { type BaseOptions, type ScaffoldingOptions } from '../../shared'
2
-
3
- export interface IGenerator<T extends BaseOptions = ScaffoldingOptions> {
4
- generate(projectPath: string, options: T): Promise<void>
5
- }
@@ -1,6 +0,0 @@
1
- export type * from './icommand-cli.contracts'
2
- export type * from './icommand-runner.contracts'
3
- export type * from './idispatch.contracts'
4
- export type * from './ifile-service.contracts'
5
- export type * from './igenerator.contracts'
6
- export type * from './iscaffold-strategy.contracts'
@@ -1,7 +0,0 @@
1
- import { type BaseOptions, type ScaffoldingOptions } from '../../shared'
2
- import { type IGenerator } from './igenerator.contracts'
3
-
4
- export interface IScaffoldStrategy<T extends BaseOptions> {
5
- promptOptions(targetDir: string): Promise<ScaffoldingOptions>
6
- getGenerators(options: ScaffoldingOptions): Promise<IGenerator<T>[]>
7
- }
@@ -1 +0,0 @@
1
- export type * from './contracts'
package/src/index.ts DELETED
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import pc from 'picocolors'
3
-
4
- import { Builder } from './infrastructure/builder'
5
-
6
- /**
7
- * @function init
8
- * @description Initializes the scaffolding process for a new Xeno project.
9
- *
10
- * @author Xeno
11
- * @version 1.0.0
12
- * @license ISC
13
- * @since 2025-09-30
14
- * @link https://github.com/xeno-js/xeno-js
15
- */
16
- async function init() {
17
- try {
18
- const dispatcher = Builder.getDispatcher()
19
-
20
- const rawArgs = process.argv.slice(2)
21
-
22
- await dispatcher.dispatch(rawArgs)
23
- } catch (error) {
24
- console.error(pc.red('\n❌ Execution interrupted:'))
25
- console.error(error instanceof Error ? error.message : error)
26
- process.exit(1)
27
- }
28
- }
29
-
30
- init().catch(console.error)
@@ -1,30 +0,0 @@
1
- // src/core/bootstrapper.ts
2
- import { mkdir } from 'node:fs/promises'
3
- import { resolve } from 'node:path'
4
-
5
- import pc from 'picocolors'
6
-
7
- import type { IGenerator } from '../../domain'
8
- import { type BaseOptions, type ScaffoldingOptions } from '../../shared'
9
-
10
- export class Bootstrapper<T extends BaseOptions = ScaffoldingOptions> {
11
- constructor(private readonly _generators: IGenerator<T>[]) {}
12
-
13
- public async run(projectPath: string, options: T): Promise<void> {
14
- console.info(pc.cyan('\n🚀 Initializing scaffolding...'))
15
-
16
- const absolutePath = resolve(process.cwd(), projectPath)
17
- await mkdir(absolutePath, { recursive: true })
18
-
19
- for (const generator of this._generators) {
20
- try {
21
- await generator.generate(absolutePath, options)
22
- } catch (error) {
23
- console.error(pc.red(`\n❌ Error during execution of ${generator.constructor.name}`))
24
- throw error
25
- }
26
- }
27
-
28
- console.info(pc.green('\n✨ Scaffolding completed succesfully!'))
29
- }
30
- }
@@ -1 +0,0 @@
1
- export * from './bootstrapper'
@@ -1,36 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
-
3
- import { GenerateCommandQuery, HelpCommand, NewProjectCommand } from '../commands'
4
- import { CliDispatcher } from '../dispatcher'
5
- import { Builder } from './builder'
6
-
7
- describe('Builder', () => {
8
- it('should create a dispatcher with the CLI commands registered', () => {
9
- const dispatcher = Builder.getDispatcher()
10
-
11
- expect(dispatcher).toBeInstanceOf(CliDispatcher)
12
- })
13
-
14
- it('should dispatch the registered commands through the built dispatcher', async () => {
15
- const dispatcher = Builder.getDispatcher()
16
-
17
- const newSpy = vi.spyOn(NewProjectCommand.prototype, 'execute').mockResolvedValue()
18
- const generateSpy = vi.spyOn(GenerateCommandQuery.prototype, 'execute').mockResolvedValue()
19
- const helpSpy = vi.spyOn(HelpCommand.prototype, 'execute').mockResolvedValue()
20
-
21
- await dispatcher.dispatch(['new', 'demo-app'])
22
- await dispatcher.dispatch(['generate', 'command', 'User'])
23
- await dispatcher.dispatch(['--help'])
24
- await dispatcher.dispatch(['-h'])
25
-
26
- expect(newSpy).toHaveBeenCalledWith(['demo-app'])
27
- expect(generateSpy).toHaveBeenCalledWith(['command', 'User'])
28
- expect(helpSpy).toHaveBeenCalledTimes(2)
29
- expect(helpSpy).toHaveBeenNthCalledWith(1, [])
30
- expect(helpSpy).toHaveBeenNthCalledWith(2, [])
31
-
32
- newSpy.mockRestore()
33
- generateSpy.mockRestore()
34
- helpSpy.mockRestore()
35
- })
36
- })
@@ -1,15 +0,0 @@
1
- import { type IDispatcher } from '../../domain'
2
- import { GenerateCommandQuery, HelpCommand, NewProjectCommand } from '../commands'
3
- import { CliDispatcher } from '../dispatcher'
4
-
5
- export class Builder {
6
- public static getDispatcher(): IDispatcher {
7
- const dispatcher = new CliDispatcher([
8
- new NewProjectCommand(),
9
- new GenerateCommandQuery(),
10
- new HelpCommand(),
11
- ])
12
-
13
- return dispatcher
14
- }
15
- }
@@ -1 +0,0 @@
1
- export * from './builder'
@@ -1,31 +0,0 @@
1
- // import { spawn } from 'node:child_process';
2
-
3
- // /**
4
- // * @class CommandUtils
5
- // * @description Utility class for executing shell commands in a cross-platform manner.
6
- // *
7
- // * @author Xeno
8
- // * @version 1.0.0
9
- // * @license ISC
10
- // * @since 2025-09-30
11
- // * @link https://github.com/xeno-js/xeno-js
12
- // */
13
- // export const CommandLauncher = {
14
- // runCommand: (command: string, args: string[], cwd: string): Promise<void> => {
15
- // return new Promise((resolve, reject) => {
16
- // const isWin = process.platform === "win32";
17
- // const cmd = isWin ? `${command}.cmd` : command;
18
-
19
- // const child = spawn(cmd, args, {
20
- // cwd,
21
- // stdio: 'inherit',
22
- // shell: true
23
- // });
24
-
25
- // child.on('close', (code) => {
26
- // if (code === 0) resolve();
27
- // else reject(new Error(`Command ${command} failed with code ${code}`));
28
- // });
29
- // });
30
- // }
31
- // };
File without changes
@@ -1,36 +0,0 @@
1
- import { spawn } from 'node:child_process'
2
-
3
- import { type ICommandRunner } from '../../domain'
4
-
5
- /**
6
- * @class CommandUtils
7
- * @description Utility class for executing shell commands in a cross-platform manner.
8
- *
9
- * @author Xeno
10
- * @version 1.0.0
11
- * @license ISC
12
- * @since 2025-09-30
13
- * @link https://github.com/xeno-js/xeno-js
14
- */
15
- export class CommandRunner implements ICommandRunner {
16
- public async run(command: string, args: string[], cwd: string, isWin = false): Promise<void> {
17
- return new Promise((resolve, reject) => {
18
- const cmd = isWin ? `${command}.cmd` : command
19
-
20
- const child = spawn(cmd, args, {
21
- cwd,
22
- stdio: 'inherit',
23
- shell: isWin,
24
- })
25
-
26
- child.on('error', (error) => {
27
- reject(new Error(`Error during execution of the command ${command}: ${error.message}`))
28
- })
29
-
30
- child.on('close', (code) => {
31
- if (code === 0) resolve()
32
- else reject(new Error(`Command ${command} failed with code ${code}`))
33
- })
34
- })
35
- }
36
- }
@@ -1,55 +0,0 @@
1
- import pc from 'picocolors'
2
-
3
- import type { ICliCommand } from '../../domain'
4
- import { Guards } from '../../shared'
5
- import { COMMAND_CONSTANTS } from '../../shared/constants/command.constants'
6
- import { FileUtils } from '../file'
7
-
8
- export class GenerateCommandQuery implements ICliCommand {
9
- public readonly name: string = 'generate'
10
- public readonly aliases: string[] = ['g']
11
-
12
- public async execute(args: string[]): Promise<void> {
13
- const type = args[0] // "command" o "query"
14
- const componentName = args[1] // es: "User"
15
- const isCore = args.includes('--core')
16
- const isVue = args.includes('--vue')
17
-
18
- if (Guards.isNullOrEmpty(type) || Guards.isNullOrEmpty(componentName)) {
19
- throw new Error(`Invalid syntax. Usage: xeno-js g [command | query] <Name> [--core | --vue]`)
20
- }
21
-
22
- let outputPath: string | undefined = undefined
23
- const outputIndex = args.findIndex((arg) => arg === '--output' || arg === '-o' || arg === '--o')
24
- if (outputIndex !== -1 && args.length > outputIndex + 1) {
25
- outputPath = args[outputIndex + 1]
26
- }
27
-
28
- const targetDir = process.cwd()
29
- const fileService = new FileUtils()
30
-
31
- if (isCore || !isVue) {
32
- const cqrsType =
33
- type === COMMAND_CONSTANTS.COMMAND ? COMMAND_CONSTANTS.COMMAND : COMMAND_CONSTANTS.QUERY
34
- const { CqrsGenerator } = await import('../generators/core/command/cqrs.generator.js')
35
- const generator = new CqrsGenerator(fileService)
36
-
37
- await generator.generate(targetDir, componentName, cqrsType, outputPath)
38
-
39
- console.info(pc.green(`\n Successfully generated ${type} component '${componentName}'!`))
40
- } else if (isVue) {
41
- const cqrsType =
42
- type === COMMAND_CONSTANTS.COMMAND ? COMMAND_CONSTANTS.COMMAND : COMMAND_CONSTANTS.QUERY
43
- const { CqrsVueGenerator } = await import('../generators/vue/command_query/cqrs.generator.js')
44
- const generator = new CqrsVueGenerator(fileService)
45
-
46
- await generator.generate(targetDir, componentName, cqrsType, outputPath)
47
-
48
- console.info(
49
- pc.green(`\n✅ Successfully generated Vue ${type} component '${componentName}'!`),
50
- )
51
- } else {
52
- throw new Error(`Unsupported generator type: '${type}'. Use 'command' or 'query'.`)
53
- }
54
- }
55
- }