@neohm/nh-cli 1.1.0 → 1.1.1

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/README.md CHANGED
@@ -67,7 +67,6 @@ shape/
67
67
  es6.classes.ts # barrel of controllers/services/jobs/subscribers
68
68
  controllers/shape.controller.ts
69
69
  dtos/add.shape.data.dto.ts
70
- dtos/shape.list.filter.dto.ts
71
70
  entities/shape.entity.ts
72
71
  libraries/shape.data.processor.ts
73
72
  libraries/shape.list.processor.ts
@@ -93,8 +92,7 @@ Generated artifacts extend the `@neohm/nestend` base classes:
93
92
  - Entity → `CommonEntity` (with an empty `attributes` jsonb column)
94
93
  - DTO → `CommonPayloadDto`
95
94
  - Data processor → `CommonDataProcessor` (`process()` → `validate()` → `set()`)
96
- - List filter DTO → `CommonListFilterDto` (plus a `custom_filter` example field)
97
- - Listing processor → `CommonListProcessor` (column allowlist config, `id` default sort, and an example custom filter)
95
+ - Listing processor → `CommonListProcessor` (column allowlist config, `id` default sort). It takes `CommonListFilterDto` directly — no per-list DTO is generated, since paging, sorting, filters and free-text search all live on the base DTO and the filterable columns are declared in the processor's `columns` config.
98
96
 
99
97
  When both a controller and a listing processor are generated, the controller
100
98
  ships with a `POST list` endpoint that runs the listing processor (with
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neohm/nh-cli",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "nh — Command Line Interface for neohm. NestJS projects",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -194,7 +194,7 @@ async function gen() {
194
194
  report(writeFile(procPath, tpl.processor(entityName)), procPath, paths.root);
195
195
  }
196
196
 
197
- // 6. Optional: listing processor (includes *ListFilterDto) -----------------
197
+ // 6. Optional: listing processor (takes CommonListFilterDto directly) ------
198
198
  const { listProcessor } = await inquirer.prompt([
199
199
  {
200
200
  type: "confirm",
@@ -205,13 +205,6 @@ async function gen() {
205
205
  ]);
206
206
 
207
207
  if (listProcessor) {
208
- const listDtoPath = path.join(moduleDir, "dtos", n.listFilterDtoFile);
209
- report(
210
- writeFile(listDtoPath, tpl.listFilterDto(entityName)),
211
- listDtoPath,
212
- paths.root,
213
- );
214
-
215
208
  const listProcPath = path.join(moduleDir, "libraries", n.listProcessorFile);
216
209
  report(
217
210
  writeFile(listProcPath, tpl.listProcessor(entityName, tableName)),
@@ -30,8 +30,6 @@ function names(base) {
30
30
  dtoFile: `add.${dot}.data.dto.ts`,
31
31
  processorClass: `${pascal}DataProcessor`,
32
32
  processorFile: `${dot}.data.processor.ts`,
33
- listFilterDtoClass: `${pascal}ListFilterDto`,
34
- listFilterDtoFile: `${dot}.list.filter.dto.ts`,
35
33
  listProcessorClass: `${pascal}ListProcessor`,
36
34
  listProcessorFile: `${dot}.list.processor.ts`,
37
35
  subscriberClass: `${pascal}Subscriber`,
@@ -78,8 +76,7 @@ export class ${n.controllerClass} {
78
76
  }
79
77
  return `import { Body, Controller, Post } from '@nestjs/common';
80
78
  import { ApiTags } from '@nestjs/swagger';
81
- import { SqlService } from '@neohm/nestend';
82
- import { ${n.listFilterDtoClass} } from '../dtos/${n.dot}.list.filter.dto';
79
+ import { CommonListFilterDto, SqlService } from '@neohm/nestend';
83
80
  import { ${n.listProcessorClass} } from '../libraries/${n.dot}.list.processor';
84
81
 
85
82
  @ApiTags('${n.kebab}')
@@ -88,7 +85,7 @@ export class ${n.controllerClass} {
88
85
  constructor(private readonly sqlService: SqlService) {}
89
86
 
90
87
  @Post('list')
91
- async list(@Body() body: ${n.listFilterDtoClass}) {
88
+ async list(@Body() body: CommonListFilterDto) {
92
89
  return new ${n.listProcessorClass}(this.sqlService).process(body);
93
90
  }
94
91
  }
@@ -133,31 +130,21 @@ export class ${n.processorClass} extends CommonDataProcessor {
133
130
  `;
134
131
  }
135
132
 
136
- function listFilterDto(base) {
137
- const n = names(base);
138
- return `import { CommonListFilterDto } from '@neohm/nestend';
139
- import { Expose } from 'class-transformer';
140
- import { IsOptional, IsString } from 'class-validator';
141
-
142
- export class ${n.listFilterDtoClass} extends CommonListFilterDto {
143
- @Expose()
144
- @IsOptional()
145
- @IsString()
146
- custom_filter?: string;
147
- }
148
- `;
149
- }
150
-
151
133
  function listProcessor(base, tableName) {
152
134
  const n = names(base);
153
135
  return `import {
154
136
  CommonListFilterConfig,
137
+ CommonListFilterDto,
155
138
  CommonListProcessor,
156
139
  SortDirection,
157
140
  SqlService,
158
141
  } from '@neohm/nestend';
159
- import { ${n.listFilterDtoClass} } from '../dtos/${n.dot}.list.filter.dto';
160
142
 
143
+ /**
144
+ * Lists / filters ${n.pascal}. The \`columns\` config below is the allowlist:
145
+ * an identifier must appear here before a caller can filter or sort on it.
146
+ * Mark a column \`searchable: true\` to include it in the free-text \`str\` sweep.
147
+ */
161
148
  export class ${n.listProcessorClass} extends CommonListProcessor {
162
149
  protected config: CommonListFilterConfig = {
163
150
  query: '${tableName} a',
@@ -173,25 +160,11 @@ export class ${n.listProcessorClass} extends CommonListProcessor {
173
160
  super();
174
161
  }
175
162
 
176
- async process(payload: ${n.listFilterDtoClass}) {
163
+ async process(payload: CommonListFilterDto) {
177
164
  this.payload = payload;
178
165
 
179
- this.applyCustomFilters(payload);
180
-
181
166
  return this.handle();
182
167
  }
183
-
184
- private async applyCustomFilters(payload: ${n.listFilterDtoClass}) {
185
- this.applyCustomFilter(payload.custom_filter);
186
- }
187
-
188
- private async applyCustomFilter(custom_filter: string) {
189
- if (!custom_filter) return;
190
-
191
- // Example of a hand-rolled condition beyond the config-driven filters.
192
- // TODO: replace test_column with a real filterable column of ${n.pascal}.
193
- this.conditions.push(\`test_column ilike '%\${custom_filter}%'\`);
194
- }
195
168
  }
196
169
  `;
197
170
  }
@@ -403,7 +376,6 @@ module.exports = {
403
376
  controller,
404
377
  dto,
405
378
  processor,
406
- listFilterDto,
407
379
  listProcessor,
408
380
  subscriber,
409
381
  job,