@flusys/nestjs-form-builder 5.4.1 → 6.0.0-beta.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/cjs/dtos/form.dto.js +23 -1
- package/cjs/entities/form.entity.js +8 -1
- package/cjs/services/form.service.js +35 -0
- package/dtos/form.dto.d.ts +2 -0
- package/entities/form.entity.d.ts +1 -0
- package/fesm/dtos/form.dto.js +23 -1
- package/fesm/entities/form.entity.js +8 -1
- package/fesm/services/form.service.js +35 -0
- package/interfaces/form.interface.d.ts +1 -0
- package/package.json +5 -5
- package/services/form.service.d.ts +5 -0
package/cjs/dtos/form.dto.js
CHANGED
|
@@ -60,6 +60,7 @@ let CreateFormDto = class CreateFormDto {
|
|
|
60
60
|
_define_property(this, "schema", void 0);
|
|
61
61
|
_define_property(this, "accessType", void 0);
|
|
62
62
|
_define_property(this, "actionGroups", void 0);
|
|
63
|
+
_define_property(this, "tags", void 0);
|
|
63
64
|
_define_property(this, "companyId", void 0);
|
|
64
65
|
_define_property(this, "isActive", void 0);
|
|
65
66
|
}
|
|
@@ -135,6 +136,22 @@ _ts_decorate([
|
|
|
135
136
|
(0, _classvalidator.IsOptional)(),
|
|
136
137
|
_ts_metadata("design:type", Array)
|
|
137
138
|
], CreateFormDto.prototype, "actionGroups", void 0);
|
|
139
|
+
_ts_decorate([
|
|
140
|
+
(0, _swagger.ApiProperty)({
|
|
141
|
+
description: 'Tags used by consuming modules to fetch this form (e.g. survey, review)',
|
|
142
|
+
example: [
|
|
143
|
+
'survey',
|
|
144
|
+
'review'
|
|
145
|
+
],
|
|
146
|
+
required: false
|
|
147
|
+
}),
|
|
148
|
+
(0, _classvalidator.IsArray)(),
|
|
149
|
+
(0, _classvalidator.IsString)({
|
|
150
|
+
each: true
|
|
151
|
+
}),
|
|
152
|
+
(0, _classvalidator.IsOptional)(),
|
|
153
|
+
_ts_metadata("design:type", Array)
|
|
154
|
+
], CreateFormDto.prototype, "tags", void 0);
|
|
138
155
|
_ts_decorate([
|
|
139
156
|
(0, _swagger.ApiProperty)({
|
|
140
157
|
description: 'Company ID - Only available when company feature is enabled',
|
|
@@ -179,7 +196,7 @@ _ts_decorate([
|
|
|
179
196
|
], UpdateFormDto.prototype, "schemaVersion", void 0);
|
|
180
197
|
let FormResponseDto = class FormResponseDto extends _dtos.IdentityResponseDto {
|
|
181
198
|
constructor(...args){
|
|
182
|
-
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "companyId", void 0), _define_property(this, "isActive", void 0);
|
|
199
|
+
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "tags", void 0), _define_property(this, "companyId", void 0), _define_property(this, "isActive", void 0);
|
|
183
200
|
}
|
|
184
201
|
};
|
|
185
202
|
_ts_decorate([
|
|
@@ -219,6 +236,11 @@ _ts_decorate([
|
|
|
219
236
|
(0, _swagger.ApiProperty)(),
|
|
220
237
|
_ts_metadata("design:type", Object)
|
|
221
238
|
], FormResponseDto.prototype, "actionGroups", void 0);
|
|
239
|
+
_ts_decorate([
|
|
240
|
+
(0, _classtransformer.Expose)(),
|
|
241
|
+
(0, _swagger.ApiProperty)(),
|
|
242
|
+
_ts_metadata("design:type", Object)
|
|
243
|
+
], FormResponseDto.prototype, "tags", void 0);
|
|
222
244
|
_ts_decorate([
|
|
223
245
|
(0, _classtransformer.Expose)(),
|
|
224
246
|
(0, _swagger.ApiProperty)(),
|
|
@@ -36,7 +36,7 @@ function _ts_metadata(k, v) {
|
|
|
36
36
|
}
|
|
37
37
|
let Form = class Form extends _entities.Identity {
|
|
38
38
|
constructor(...args){
|
|
39
|
-
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "isActive", void 0);
|
|
39
|
+
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "tags", void 0), _define_property(this, "isActive", void 0);
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
_ts_decorate([
|
|
@@ -96,6 +96,13 @@ _ts_decorate([
|
|
|
96
96
|
}),
|
|
97
97
|
_ts_metadata("design:type", Object)
|
|
98
98
|
], Form.prototype, "actionGroups", void 0);
|
|
99
|
+
_ts_decorate([
|
|
100
|
+
(0, _typeorm.Column)({
|
|
101
|
+
type: (0, _nestjsshared.getJsonColumnType)(),
|
|
102
|
+
nullable: true
|
|
103
|
+
}),
|
|
104
|
+
_ts_metadata("design:type", Object)
|
|
105
|
+
], Form.prototype, "tags", void 0);
|
|
99
106
|
_ts_decorate([
|
|
100
107
|
(0, _typeorm.Column)({
|
|
101
108
|
type: 'boolean',
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "FormService", {
|
|
|
8
8
|
return FormService;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _nestjscore = require("@flusys/nestjs-core");
|
|
11
12
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
13
|
const _modules = require("@flusys/nestjs-shared/modules");
|
|
13
14
|
const _utils = require("@flusys/nestjs-shared/utils");
|
|
@@ -109,6 +110,7 @@ let FormService = class FormService extends _classes.ApiService {
|
|
|
109
110
|
'schemaVersion',
|
|
110
111
|
'accessType',
|
|
111
112
|
'actionGroups',
|
|
113
|
+
'tags',
|
|
112
114
|
'isActive',
|
|
113
115
|
'createdAt',
|
|
114
116
|
'updatedAt'
|
|
@@ -125,6 +127,38 @@ let FormService = class FormService extends _classes.ApiService {
|
|
|
125
127
|
isRaw: false
|
|
126
128
|
};
|
|
127
129
|
}
|
|
130
|
+
// Supports filtering by one or more tags (array-contains-all) via the generic get-all filter,
|
|
131
|
+
// e.g. { filter: { tags: ['survey', 'review'] } }, since tags is a JSON array column.
|
|
132
|
+
async getFilterQuery(query, filter, user) {
|
|
133
|
+
const { tags, ...rest } = filter;
|
|
134
|
+
if (tags !== undefined && tags !== null) {
|
|
135
|
+
const tagList = (Array.isArray(tags) ? tags : [
|
|
136
|
+
tags
|
|
137
|
+
]).map(String);
|
|
138
|
+
if (tagList.length > 0) {
|
|
139
|
+
this.applyTagFilter(query, tagList);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return super.getFilterQuery(query, rest, user);
|
|
143
|
+
}
|
|
144
|
+
applyTagFilter(query, tags) {
|
|
145
|
+
const driver = _nestjscore.envConfig.getTypeOrmConfig().type;
|
|
146
|
+
if (driver === 'postgres') {
|
|
147
|
+
query.andWhere(`${this.entityName}.tags @> :tagValues::jsonb`, {
|
|
148
|
+
tagValues: JSON.stringify(tags)
|
|
149
|
+
});
|
|
150
|
+
} else if (driver === 'mysql') {
|
|
151
|
+
query.andWhere(`JSON_CONTAINS(${this.entityName}.tags, :tagValues)`, {
|
|
152
|
+
tagValues: JSON.stringify(tags)
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
tags.forEach((tag, index)=>{
|
|
156
|
+
query.andWhere(`${this.entityName}.tags LIKE :tagValue${index}`, {
|
|
157
|
+
[`tagValue${index}`]: `%"${tag}"%`
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
128
162
|
async getExtraManipulateQuery(query, filterDto, user) {
|
|
129
163
|
const result = await super.getExtraManipulateQuery(query, filterDto, user);
|
|
130
164
|
// Apply company filter using shared utility
|
|
@@ -146,6 +180,7 @@ let FormService = class FormService extends _classes.ApiService {
|
|
|
146
180
|
schemaVersion: entity.schemaVersion,
|
|
147
181
|
accessType: entity.accessType,
|
|
148
182
|
actionGroups: entity.actionGroups,
|
|
183
|
+
tags: entity.tags,
|
|
149
184
|
isActive: entity.isActive,
|
|
150
185
|
companyId: entityWithCompany.companyId ?? null,
|
|
151
186
|
createdAt: entity.createdAt,
|
package/dtos/form.dto.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare class CreateFormDto {
|
|
|
7
7
|
schema: Record<string, unknown>;
|
|
8
8
|
accessType?: FormAccessType;
|
|
9
9
|
actionGroups?: string[];
|
|
10
|
+
tags?: string[];
|
|
10
11
|
companyId?: string;
|
|
11
12
|
isActive?: boolean;
|
|
12
13
|
}
|
|
@@ -23,6 +24,7 @@ export declare class FormResponseDto extends IdentityResponseDto {
|
|
|
23
24
|
schemaVersion: number;
|
|
24
25
|
accessType: FormAccessType;
|
|
25
26
|
actionGroups: string[] | null;
|
|
27
|
+
tags: string[] | null;
|
|
26
28
|
companyId: string | null;
|
|
27
29
|
isActive: boolean;
|
|
28
30
|
}
|
package/fesm/dtos/form.dto.js
CHANGED
|
@@ -33,6 +33,7 @@ export class CreateFormDto {
|
|
|
33
33
|
_define_property(this, "schema", void 0);
|
|
34
34
|
_define_property(this, "accessType", void 0);
|
|
35
35
|
_define_property(this, "actionGroups", void 0);
|
|
36
|
+
_define_property(this, "tags", void 0);
|
|
36
37
|
_define_property(this, "companyId", void 0);
|
|
37
38
|
_define_property(this, "isActive", void 0);
|
|
38
39
|
}
|
|
@@ -108,6 +109,22 @@ _ts_decorate([
|
|
|
108
109
|
IsOptional(),
|
|
109
110
|
_ts_metadata("design:type", Array)
|
|
110
111
|
], CreateFormDto.prototype, "actionGroups", void 0);
|
|
112
|
+
_ts_decorate([
|
|
113
|
+
ApiProperty({
|
|
114
|
+
description: 'Tags used by consuming modules to fetch this form (e.g. survey, review)',
|
|
115
|
+
example: [
|
|
116
|
+
'survey',
|
|
117
|
+
'review'
|
|
118
|
+
],
|
|
119
|
+
required: false
|
|
120
|
+
}),
|
|
121
|
+
IsArray(),
|
|
122
|
+
IsString({
|
|
123
|
+
each: true
|
|
124
|
+
}),
|
|
125
|
+
IsOptional(),
|
|
126
|
+
_ts_metadata("design:type", Array)
|
|
127
|
+
], CreateFormDto.prototype, "tags", void 0);
|
|
111
128
|
_ts_decorate([
|
|
112
129
|
ApiProperty({
|
|
113
130
|
description: 'Company ID - Only available when company feature is enabled',
|
|
@@ -152,7 +169,7 @@ _ts_decorate([
|
|
|
152
169
|
], UpdateFormDto.prototype, "schemaVersion", void 0);
|
|
153
170
|
export class FormResponseDto extends IdentityResponseDto {
|
|
154
171
|
constructor(...args){
|
|
155
|
-
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "companyId", void 0), _define_property(this, "isActive", void 0);
|
|
172
|
+
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "tags", void 0), _define_property(this, "companyId", void 0), _define_property(this, "isActive", void 0);
|
|
156
173
|
}
|
|
157
174
|
}
|
|
158
175
|
_ts_decorate([
|
|
@@ -192,6 +209,11 @@ _ts_decorate([
|
|
|
192
209
|
ApiProperty(),
|
|
193
210
|
_ts_metadata("design:type", Object)
|
|
194
211
|
], FormResponseDto.prototype, "actionGroups", void 0);
|
|
212
|
+
_ts_decorate([
|
|
213
|
+
Expose(),
|
|
214
|
+
ApiProperty(),
|
|
215
|
+
_ts_metadata("design:type", Object)
|
|
216
|
+
], FormResponseDto.prototype, "tags", void 0);
|
|
195
217
|
_ts_decorate([
|
|
196
218
|
Expose(),
|
|
197
219
|
ApiProperty(),
|
|
@@ -26,7 +26,7 @@ import { Column, Entity, Index } from 'typeorm';
|
|
|
26
26
|
import { FormAccessType } from '../enums/form-access-type.enum';
|
|
27
27
|
export class Form extends Identity {
|
|
28
28
|
constructor(...args){
|
|
29
|
-
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "isActive", void 0);
|
|
29
|
+
super(...args), _define_property(this, "name", void 0), _define_property(this, "description", void 0), _define_property(this, "slug", void 0), _define_property(this, "schema", void 0), _define_property(this, "schemaVersion", void 0), _define_property(this, "accessType", void 0), _define_property(this, "actionGroups", void 0), _define_property(this, "tags", void 0), _define_property(this, "isActive", void 0);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
_ts_decorate([
|
|
@@ -86,6 +86,13 @@ _ts_decorate([
|
|
|
86
86
|
}),
|
|
87
87
|
_ts_metadata("design:type", Object)
|
|
88
88
|
], Form.prototype, "actionGroups", void 0);
|
|
89
|
+
_ts_decorate([
|
|
90
|
+
Column({
|
|
91
|
+
type: getJsonColumnType(),
|
|
92
|
+
nullable: true
|
|
93
|
+
}),
|
|
94
|
+
_ts_metadata("design:type", Object)
|
|
95
|
+
], Form.prototype, "tags", void 0);
|
|
89
96
|
_ts_decorate([
|
|
90
97
|
Column({
|
|
91
98
|
type: 'boolean',
|
|
@@ -25,6 +25,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
import { envConfig } from '@flusys/nestjs-core';
|
|
28
29
|
import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
|
|
29
30
|
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
30
31
|
import { applyCompanyFilter } from '@flusys/nestjs-shared/utils';
|
|
@@ -99,6 +100,7 @@ export class FormService extends ApiService {
|
|
|
99
100
|
'schemaVersion',
|
|
100
101
|
'accessType',
|
|
101
102
|
'actionGroups',
|
|
103
|
+
'tags',
|
|
102
104
|
'isActive',
|
|
103
105
|
'createdAt',
|
|
104
106
|
'updatedAt'
|
|
@@ -115,6 +117,38 @@ export class FormService extends ApiService {
|
|
|
115
117
|
isRaw: false
|
|
116
118
|
};
|
|
117
119
|
}
|
|
120
|
+
// Supports filtering by one or more tags (array-contains-all) via the generic get-all filter,
|
|
121
|
+
// e.g. { filter: { tags: ['survey', 'review'] } }, since tags is a JSON array column.
|
|
122
|
+
async getFilterQuery(query, filter, user) {
|
|
123
|
+
const { tags, ...rest } = filter;
|
|
124
|
+
if (tags !== undefined && tags !== null) {
|
|
125
|
+
const tagList = (Array.isArray(tags) ? tags : [
|
|
126
|
+
tags
|
|
127
|
+
]).map(String);
|
|
128
|
+
if (tagList.length > 0) {
|
|
129
|
+
this.applyTagFilter(query, tagList);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return super.getFilterQuery(query, rest, user);
|
|
133
|
+
}
|
|
134
|
+
applyTagFilter(query, tags) {
|
|
135
|
+
const driver = envConfig.getTypeOrmConfig().type;
|
|
136
|
+
if (driver === 'postgres') {
|
|
137
|
+
query.andWhere(`${this.entityName}.tags @> :tagValues::jsonb`, {
|
|
138
|
+
tagValues: JSON.stringify(tags)
|
|
139
|
+
});
|
|
140
|
+
} else if (driver === 'mysql') {
|
|
141
|
+
query.andWhere(`JSON_CONTAINS(${this.entityName}.tags, :tagValues)`, {
|
|
142
|
+
tagValues: JSON.stringify(tags)
|
|
143
|
+
});
|
|
144
|
+
} else {
|
|
145
|
+
tags.forEach((tag, index)=>{
|
|
146
|
+
query.andWhere(`${this.entityName}.tags LIKE :tagValue${index}`, {
|
|
147
|
+
[`tagValue${index}`]: `%"${tag}"%`
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
118
152
|
async getExtraManipulateQuery(query, filterDto, user) {
|
|
119
153
|
const result = await super.getExtraManipulateQuery(query, filterDto, user);
|
|
120
154
|
// Apply company filter using shared utility
|
|
@@ -136,6 +170,7 @@ export class FormService extends ApiService {
|
|
|
136
170
|
schemaVersion: entity.schemaVersion,
|
|
137
171
|
accessType: entity.accessType,
|
|
138
172
|
actionGroups: entity.actionGroups,
|
|
173
|
+
tags: entity.tags,
|
|
139
174
|
isActive: entity.isActive,
|
|
140
175
|
companyId: entityWithCompany.companyId ?? null,
|
|
141
176
|
createdAt: entity.createdAt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-form-builder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-beta.1",
|
|
4
4
|
"description": "Dynamic form builder module with schema versioning and access control",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -79,12 +79,12 @@
|
|
|
79
79
|
"@nestjs/swagger": "^11.0.0",
|
|
80
80
|
"@nestjs/typeorm": "^11.0.0",
|
|
81
81
|
"class-transformer": "^0.5.1",
|
|
82
|
-
"class-validator": "^0.
|
|
82
|
+
"class-validator": "^0.15.0",
|
|
83
83
|
"typeorm": "^0.3.0",
|
|
84
|
-
"express": "^
|
|
84
|
+
"express": "^5.0.0"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@flusys/nestjs-core": "
|
|
88
|
-
"@flusys/nestjs-shared": "
|
|
87
|
+
"@flusys/nestjs-core": "6.0.0-beta.1",
|
|
88
|
+
"@flusys/nestjs-shared": "6.0.0-beta.1"
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -20,6 +20,11 @@ export declare class FormService extends ApiService<CreateFormDto, UpdateFormDto
|
|
|
20
20
|
query: SelectQueryBuilder<Form>;
|
|
21
21
|
isRaw: boolean;
|
|
22
22
|
}>;
|
|
23
|
+
protected getFilterQuery(query: SelectQueryBuilder<Form>, filter: Record<string, unknown>, user: ILoggedUserInfo | null): Promise<{
|
|
24
|
+
query: SelectQueryBuilder<Form>;
|
|
25
|
+
isRaw: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
private applyTagFilter;
|
|
23
28
|
protected getExtraManipulateQuery(query: SelectQueryBuilder<Form>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
|
|
24
29
|
query: SelectQueryBuilder<Form>;
|
|
25
30
|
isRaw: boolean;
|