@aponiajs/cli 0.3.22 → 0.5.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.
package/dist/index.mjs CHANGED
@@ -183,7 +183,7 @@ function readStringOption(options, name) {
183
183
  }
184
184
  //#endregion
185
185
  //#region src/version.ts
186
- const aponiaVersion = "0.3.22";
186
+ const aponiaVersion = "0.5.0";
187
187
  //#endregion
188
188
  //#region src/project-generator.ts
189
189
  const projectNamePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
@@ -471,7 +471,9 @@ function createResourceFiles(basePath, names, options, specEnabled) {
471
471
  const transportStem = resourceTransportStem(options.type);
472
472
  const dtoSuffix = options.type.startsWith("graphql") ? "input" : "dto";
473
473
  const files = [createFile(directory, `${names.fileName}.module.ts`, renderResourceModule(names, transportStem)), createFile(directory, `${names.fileName}.service.ts`, renderResourceService(names, options.crud, dtoSuffix))];
474
- if (options.crud) files.push(createFile(join(directory, "dto"), `create-${names.singularFileName}.${dtoSuffix}.ts`, renderCreateDto(names, dtoSuffix)), createFile(join(directory, "dto"), `update-${names.singularFileName}.${dtoSuffix}.ts`, renderUpdateDto(names, dtoSuffix)), createFile(join(directory, "entities"), `${names.singularFileName}.entity.ts`, renderEntity(names)));
474
+ const validated = options.crud && options.type === "rest";
475
+ if (validated) files.push(createFile(directory, `${names.fileName}.schema.ts`, renderResourceSchema(names)));
476
+ if (options.crud) files.push(createFile(join(directory, "dto"), `create-${names.singularFileName}.${dtoSuffix}.ts`, renderCreateDto(names, dtoSuffix, validated)), createFile(join(directory, "dto"), `update-${names.singularFileName}.${dtoSuffix}.ts`, renderUpdateDto(names, dtoSuffix, validated)), createFile(join(directory, "entities"), `${names.singularFileName}.entity.ts`, renderEntity(names)));
475
477
  if (options.type === "rest") files.push(createFile(directory, `${names.fileName}.controller.ts`, renderResourceController(names, options.crud)));
476
478
  else files.push(createFile(directory, `${names.fileName}.${transportStem}.ts`, renderResourceTransport(names, options.type, options.crud)));
477
479
  if (specEnabled) files.push(createFile(directory, `${names.fileName}.service.spec.ts`, options.crud ? renderResourceServiceSpec(names) : renderSimpleSpec(`./${names.fileName}.service.ts`, `${names.className}Service`)), createFile(directory, `${names.fileName}.${transportStem}.spec.ts`, renderResourceTransportSpec(names, transportStem)));
@@ -559,19 +561,25 @@ function renderResourceModule(names, transportStem) {
559
561
  }
560
562
  function renderResourceController(names, crud) {
561
563
  if (!crud) return `import { Controller } from "@aponiajs/common";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n}\n`;
562
- return `import { Controller, Delete, Get, Patch, Post } from "@aponiajs/common";\nimport type { Create${names.singularClassName}Dto } from "./dto/create-${names.singularFileName}.dto.ts";\nimport type { Update${names.singularClassName}Dto } from "./dto/update-${names.singularFileName}.dto.ts";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n\n @Post()\n create(input: Create${names.singularClassName}Dto) {\n return this.${names.propertyName}Service.create(input);\n }\n\n @Get()\n findAll() {\n return this.${names.propertyName}Service.findAll();\n }\n\n @Get(":id")\n findOne(id: string) {\n return this.${names.propertyName}Service.findOne(id);\n }\n\n @Patch(":id")\n update(id: string, input: Update${names.singularClassName}Dto) {\n return this.${names.propertyName}Service.update(id, input);\n }\n\n @Delete(":id")\n remove(id: string) {\n return this.${names.propertyName}Service.remove(id);\n }\n}\n`;
564
+ const single = names.singularClassName;
565
+ return `import { Body, Controller, Delete, Get, Param, Patch, Post } from "@aponiajs/common";\nimport type { Create${single}Dto } from "./dto/create-${names.singularFileName}.dto.ts";\nimport type { Update${single}Dto } from "./dto/update-${names.singularFileName}.dto.ts";\nimport {\n create${single}Route,\n find${single}Route,\n update${single}Route,\n} from "./${names.fileName}.schema.ts";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n\n @Post("/", create${single}Route)\n create(@Body() input: Create${single}Dto) {\n return this.${names.propertyName}Service.create(input);\n }\n\n @Get()\n findAll() {\n return this.${names.propertyName}Service.findAll();\n }\n\n @Get(":id", find${single}Route)\n findOne(@Param("id") id: string) {\n return this.${names.propertyName}Service.findOne(id);\n }\n\n @Patch(":id", update${single}Route)\n update(@Param("id") id: string, @Body() input: Update${single}Dto) {\n return this.${names.propertyName}Service.update(id, input);\n }\n\n @Delete(":id", find${single}Route)\n remove(@Param("id") id: string) {\n return this.${names.propertyName}Service.remove(id);\n }\n}\n`;
563
566
  }
564
567
  function renderResourceService(names, crud, dtoSuffix) {
565
568
  if (!crud) return `import { Injectable } from "@aponiajs/common";\n\n@Injectable()\nexport class ${names.className}Service {}\n`;
566
569
  const typeSuffix = pascalCase(dtoSuffix);
567
570
  return `import { Injectable } from "@aponiajs/common";\nimport type { Create${names.singularClassName}${typeSuffix} } from "./dto/create-${names.singularFileName}.${dtoSuffix}.ts";\nimport type { Update${names.singularClassName}${typeSuffix} } from "./dto/update-${names.singularFileName}.${dtoSuffix}.ts";\nimport type { ${names.singularClassName} } from "./entities/${names.singularFileName}.entity.ts";\n\n@Injectable()\nexport class ${names.className}Service {\n private readonly items: ${names.singularClassName}[] = [];\n\n create(input: Create${names.singularClassName}${typeSuffix}): ${names.singularClassName} {\n const item = { id: crypto.randomUUID(), ...input };\n this.items.push(item);\n return item;\n }\n\n findAll(): readonly ${names.singularClassName}[] {\n return this.items;\n }\n\n findOne(id: string): ${names.singularClassName} | undefined {\n return this.items.find((item) => item.id === id);\n }\n\n update(id: string, input: Update${names.singularClassName}${typeSuffix}): ${names.singularClassName} | undefined {\n const item = this.findOne(id);\n if (!item) return undefined;\n Object.assign(item, input);\n return item;\n }\n\n remove(id: string): boolean {\n const index = this.items.findIndex((item) => item.id === id);\n if (index < 0) return false;\n this.items.splice(index, 1);\n return true;\n }\n}\n`;
568
571
  }
569
- function renderCreateDto(names, suffix) {
572
+ function renderResourceSchema(names) {
573
+ return `import { t } from "elysia";\n\nexport const create${names.singularClassName}Schema = t.Object({\n name: t.String({ minLength: 1 }),\n});\n\nexport const update${names.singularClassName}Schema = t.Partial(create${names.singularClassName}Schema);\n\nexport const ${names.singularClassName.toLowerCase()}ParamsSchema = t.Object({\n id: t.String(),\n});\n\nexport const create${names.singularClassName}Route = {\n body: create${names.singularClassName}Schema,\n};\n\nexport const find${names.singularClassName}Route = {\n params: ${names.singularClassName.toLowerCase()}ParamsSchema,\n};\n\nexport const update${names.singularClassName}Route = {\n params: ${names.singularClassName.toLowerCase()}ParamsSchema,\n body: update${names.singularClassName}Schema,\n};\n`;
574
+ }
575
+ function renderCreateDto(names, suffix, validated) {
570
576
  const typeSuffix = pascalCase(suffix);
577
+ if (validated) return `import type { Static } from "elysia";\nimport type { create${names.singularClassName}Schema } from "../${names.fileName}.schema.ts";\n\nexport type Create${names.singularClassName}${typeSuffix} = Static<typeof create${names.singularClassName}Schema>;\n`;
571
578
  return `export class Create${names.singularClassName}${typeSuffix} {\n name = "";\n}\n`;
572
579
  }
573
- function renderUpdateDto(names, suffix) {
580
+ function renderUpdateDto(names, suffix, validated) {
574
581
  const typeSuffix = pascalCase(suffix);
582
+ if (validated) return `import type { Static } from "elysia";\nimport type { update${names.singularClassName}Schema } from "../${names.fileName}.schema.ts";\n\nexport type Update${names.singularClassName}${typeSuffix} = Static<typeof update${names.singularClassName}Schema>;\n`;
575
583
  return `import type { Create${names.singularClassName}${typeSuffix} } from "./create-${names.singularFileName}.${suffix}.ts";\n\nexport type Update${names.singularClassName}${typeSuffix} = Partial<Create${names.singularClassName}${typeSuffix}>;\n`;
576
584
  }
577
585
  function renderEntity(names) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aponiajs/cli",
3
- "version": "0.3.22",
3
+ "version": "0.5.0",
4
4
  "description": "Bun-native project generator and command-line interface for Aponia.",
5
5
  "homepage": "https://github.com/aponiajs/aponiajs#readme",
6
6
  "bugs": {
@@ -207,17 +207,22 @@ function createResourceFiles(
207
207
  ),
208
208
  ];
209
209
 
210
+ const validated = options.crud && options.type === "rest";
211
+ if (validated) {
212
+ files.push(createFile(directory, `${names.fileName}.schema.ts`, renderResourceSchema(names)));
213
+ }
214
+
210
215
  if (options.crud) {
211
216
  files.push(
212
217
  createFile(
213
218
  join(directory, "dto"),
214
219
  `create-${names.singularFileName}.${dtoSuffix}.ts`,
215
- renderCreateDto(names, dtoSuffix),
220
+ renderCreateDto(names, dtoSuffix, validated),
216
221
  ),
217
222
  createFile(
218
223
  join(directory, "dto"),
219
224
  `update-${names.singularFileName}.${dtoSuffix}.ts`,
220
- renderUpdateDto(names, dtoSuffix),
225
+ renderUpdateDto(names, dtoSuffix, validated),
221
226
  ),
222
227
  createFile(
223
228
  join(directory, "entities"),
@@ -425,7 +430,9 @@ function renderResourceController(names: ComponentNames, crud: boolean): string
425
430
  if (!crud) {
426
431
  return `import { Controller } from "@aponiajs/common";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n}\n`;
427
432
  }
428
- return `import { Controller, Delete, Get, Patch, Post } from "@aponiajs/common";\nimport type { Create${names.singularClassName}Dto } from "./dto/create-${names.singularFileName}.dto.ts";\nimport type { Update${names.singularClassName}Dto } from "./dto/update-${names.singularFileName}.dto.ts";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n\n @Post()\n create(input: Create${names.singularClassName}Dto) {\n return this.${names.propertyName}Service.create(input);\n }\n\n @Get()\n findAll() {\n return this.${names.propertyName}Service.findAll();\n }\n\n @Get(":id")\n findOne(id: string) {\n return this.${names.propertyName}Service.findOne(id);\n }\n\n @Patch(":id")\n update(id: string, input: Update${names.singularClassName}Dto) {\n return this.${names.propertyName}Service.update(id, input);\n }\n\n @Delete(":id")\n remove(id: string) {\n return this.${names.propertyName}Service.remove(id);\n }\n}\n`;
433
+
434
+ const single = names.singularClassName;
435
+ return `import { Body, Controller, Delete, Get, Param, Patch, Post } from "@aponiajs/common";\nimport type { Create${single}Dto } from "./dto/create-${names.singularFileName}.dto.ts";\nimport type { Update${single}Dto } from "./dto/update-${names.singularFileName}.dto.ts";\nimport {\n create${single}Route,\n find${single}Route,\n update${single}Route,\n} from "./${names.fileName}.schema.ts";\nimport { ${names.className}Service } from "./${names.fileName}.service.ts";\n\n@Controller("${names.routePath}")\nexport class ${names.className}Controller {\n constructor(private readonly ${names.propertyName}Service: ${names.className}Service) {}\n\n @Post("/", create${single}Route)\n create(@Body() input: Create${single}Dto) {\n return this.${names.propertyName}Service.create(input);\n }\n\n @Get()\n findAll() {\n return this.${names.propertyName}Service.findAll();\n }\n\n @Get(":id", find${single}Route)\n findOne(@Param("id") id: string) {\n return this.${names.propertyName}Service.findOne(id);\n }\n\n @Patch(":id", update${single}Route)\n update(@Param("id") id: string, @Body() input: Update${single}Dto) {\n return this.${names.propertyName}Service.update(id, input);\n }\n\n @Delete(":id", find${single}Route)\n remove(@Param("id") id: string) {\n return this.${names.propertyName}Service.remove(id);\n }\n}\n`;
429
436
  }
430
437
 
431
438
  function renderResourceService(
@@ -440,13 +447,31 @@ function renderResourceService(
440
447
  return `import { Injectable } from "@aponiajs/common";\nimport type { Create${names.singularClassName}${typeSuffix} } from "./dto/create-${names.singularFileName}.${dtoSuffix}.ts";\nimport type { Update${names.singularClassName}${typeSuffix} } from "./dto/update-${names.singularFileName}.${dtoSuffix}.ts";\nimport type { ${names.singularClassName} } from "./entities/${names.singularFileName}.entity.ts";\n\n@Injectable()\nexport class ${names.className}Service {\n private readonly items: ${names.singularClassName}[] = [];\n\n create(input: Create${names.singularClassName}${typeSuffix}): ${names.singularClassName} {\n const item = { id: crypto.randomUUID(), ...input };\n this.items.push(item);\n return item;\n }\n\n findAll(): readonly ${names.singularClassName}[] {\n return this.items;\n }\n\n findOne(id: string): ${names.singularClassName} | undefined {\n return this.items.find((item) => item.id === id);\n }\n\n update(id: string, input: Update${names.singularClassName}${typeSuffix}): ${names.singularClassName} | undefined {\n const item = this.findOne(id);\n if (!item) return undefined;\n Object.assign(item, input);\n return item;\n }\n\n remove(id: string): boolean {\n const index = this.items.findIndex((item) => item.id === id);\n if (index < 0) return false;\n this.items.splice(index, 1);\n return true;\n }\n}\n`;
441
448
  }
442
449
 
443
- function renderCreateDto(names: ComponentNames, suffix: "dto" | "input"): string {
450
+ function renderResourceSchema(names: ComponentNames): string {
451
+ return `import { t } from "elysia";\n\nexport const create${names.singularClassName}Schema = t.Object({\n name: t.String({ minLength: 1 }),\n});\n\nexport const update${names.singularClassName}Schema = t.Partial(create${names.singularClassName}Schema);\n\nexport const ${names.singularClassName.toLowerCase()}ParamsSchema = t.Object({\n id: t.String(),\n});\n\nexport const create${names.singularClassName}Route = {\n body: create${names.singularClassName}Schema,\n};\n\nexport const find${names.singularClassName}Route = {\n params: ${names.singularClassName.toLowerCase()}ParamsSchema,\n};\n\nexport const update${names.singularClassName}Route = {\n params: ${names.singularClassName.toLowerCase()}ParamsSchema,\n body: update${names.singularClassName}Schema,\n};\n`;
452
+ }
453
+
454
+ function renderCreateDto(
455
+ names: ComponentNames,
456
+ suffix: "dto" | "input",
457
+ validated: boolean,
458
+ ): string {
444
459
  const typeSuffix = pascalCase(suffix);
460
+ if (validated) {
461
+ return `import type { Static } from "elysia";\nimport type { create${names.singularClassName}Schema } from "../${names.fileName}.schema.ts";\n\nexport type Create${names.singularClassName}${typeSuffix} = Static<typeof create${names.singularClassName}Schema>;\n`;
462
+ }
445
463
  return `export class Create${names.singularClassName}${typeSuffix} {\n name = "";\n}\n`;
446
464
  }
447
465
 
448
- function renderUpdateDto(names: ComponentNames, suffix: "dto" | "input"): string {
466
+ function renderUpdateDto(
467
+ names: ComponentNames,
468
+ suffix: "dto" | "input",
469
+ validated: boolean,
470
+ ): string {
449
471
  const typeSuffix = pascalCase(suffix);
472
+ if (validated) {
473
+ return `import type { Static } from "elysia";\nimport type { update${names.singularClassName}Schema } from "../${names.fileName}.schema.ts";\n\nexport type Update${names.singularClassName}${typeSuffix} = Static<typeof update${names.singularClassName}Schema>;\n`;
474
+ }
450
475
  return `import type { Create${names.singularClassName}${typeSuffix} } from "./create-${names.singularFileName}.${suffix}.ts";\n\nexport type Update${names.singularClassName}${typeSuffix} = Partial<Create${names.singularClassName}${typeSuffix}>;\n`;
451
476
  }
452
477