@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 +1 -3
- package/package.json +1 -1
- package/src/commands/gen.js +1 -8
- package/src/lib/templates.js +9 -37
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
|
-
-
|
|
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
package/src/commands/gen.js
CHANGED
|
@@ -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 (
|
|
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)),
|
package/src/lib/templates.js
CHANGED
|
@@ -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:
|
|
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:
|
|
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,
|