@dav3/gql-of-power 1.0.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.
Files changed (70) hide show
  1. package/.prettierrc +7 -0
  2. package/LICENSE +26 -0
  3. package/README.md +426 -0
  4. package/bunfig.toml +17 -0
  5. package/dist/src/entities/gql-entity.d.ts +39 -0
  6. package/dist/src/entities/gql-entity.js +381 -0
  7. package/dist/src/entities/index.d.ts +1 -0
  8. package/dist/src/entities/index.js +1 -0
  9. package/dist/src/index.d.ts +5 -0
  10. package/dist/src/index.js +5 -0
  11. package/dist/src/operations.d.ts +116 -0
  12. package/dist/src/operations.js +81 -0
  13. package/dist/src/queries/alias.d.ts +25 -0
  14. package/dist/src/queries/alias.js +66 -0
  15. package/dist/src/queries/filter-processor.d.ts +141 -0
  16. package/dist/src/queries/filter-processor.js +574 -0
  17. package/dist/src/queries/gql-to-sql-mapper.d.ts +44 -0
  18. package/dist/src/queries/gql-to-sql-mapper.js +309 -0
  19. package/dist/src/queries/index.d.ts +2 -0
  20. package/dist/src/queries/index.js +2 -0
  21. package/dist/src/queries/relationship-handler.d.ts +19 -0
  22. package/dist/src/queries/relationship-handler.js +144 -0
  23. package/dist/src/queries/sql-builder.d.ts +115 -0
  24. package/dist/src/queries/sql-builder.js +179 -0
  25. package/dist/src/queries/utils.d.ts +7 -0
  26. package/dist/src/queries/utils.js +58 -0
  27. package/dist/src/query-manager.d.ts +18 -0
  28. package/dist/src/query-manager.js +99 -0
  29. package/dist/src/types/access-control.d.ts +27 -0
  30. package/dist/src/types/access-control.js +7 -0
  31. package/dist/src/types/gql-to-sql-types.d.ts +27 -0
  32. package/dist/src/types/gql-to-sql-types.js +18 -0
  33. package/dist/src/types/gql-types.d.ts +86 -0
  34. package/dist/src/types/gql-types.js +102 -0
  35. package/dist/src/types/index.d.ts +4 -0
  36. package/dist/src/types/index.js +4 -0
  37. package/dist/src/types/sql-types.d.ts +135 -0
  38. package/dist/src/types/sql-types.js +12 -0
  39. package/dist/src/types/utils.d.ts +12 -0
  40. package/dist/src/types/utils.js +1 -0
  41. package/dist/src/utils/index.d.ts +1 -0
  42. package/dist/src/utils/index.js +1 -0
  43. package/dist/src/utils/object.d.ts +1 -0
  44. package/dist/src/utils/object.js +1 -0
  45. package/dist/src/variables.d.ts +2 -0
  46. package/dist/src/variables.js +77 -0
  47. package/jest.config.js +11 -0
  48. package/package.json +48 -0
  49. package/scripts/update-version.ts +19 -0
  50. package/src/entities/gql-entity.ts +472 -0
  51. package/src/entities/index.ts +1 -0
  52. package/src/index.ts +5 -0
  53. package/src/operations.ts +131 -0
  54. package/src/queries/alias.ts +70 -0
  55. package/src/queries/filter-processor.ts +1156 -0
  56. package/src/queries/gql-to-sql-mapper.ts +644 -0
  57. package/src/queries/index.ts +2 -0
  58. package/src/queries/relationship-handler.ts +354 -0
  59. package/src/queries/sql-builder.ts +282 -0
  60. package/src/queries/utils.ts +95 -0
  61. package/src/query-manager.ts +129 -0
  62. package/src/types/access-control.ts +35 -0
  63. package/src/types/gql-to-sql-types.ts +51 -0
  64. package/src/types/gql-types.ts +251 -0
  65. package/src/types/index.ts +4 -0
  66. package/src/types/sql-types.ts +204 -0
  67. package/src/types/utils.ts +27 -0
  68. package/src/utils/index.ts +1 -0
  69. package/src/utils/object.ts +2 -0
  70. package/src/variables.ts +81 -0
@@ -0,0 +1,381 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Field, FieldResolver, getMetadataStorage, InputType, Int, ObjectType, registerEnumType, Resolver, } from 'type-graphql';
8
+ import { Sort, } from '../types';
9
+ import { keys } from '../utils';
10
+ import { logger } from '../variables';
11
+ const TypeMap = {};
12
+ const FieldsOptionsMap = {};
13
+ const CustomFieldsMap = {};
14
+ const aclMap = {};
15
+ let gqlTypesSuffix = '';
16
+ export const setGlobalConfig = (config) => {
17
+ gqlTypesSuffix = config.gqlTypesSuffix;
18
+ };
19
+ export const getFieldsOptionsFor = (name) => FieldsOptionsMap[name] ?? {};
20
+ export const getFieldByAlias = (entityName, alias) => FieldsOptionsMap[entityName ?? '__no__use__']?.[alias] ?? alias;
21
+ export const getCustomFieldsFor = (name) => CustomFieldsMap[name] ?? {};
22
+ export const getACLFor = (name) => aclMap[name] ?? {};
23
+ export const getGQLEntityNameFor = (name) => `${name}${gqlTypesSuffix}`;
24
+ export const getGQLEntityNameForClass = (classType) => getGQLEntityNameFor(classType.name);
25
+ export const getGQLEntityFieldResolverName = (gqlEntityName) => `${gqlEntityName}FieldsResolver`;
26
+ export const getGQLEntityFieldResolverNameFor = (classType) => getGQLEntityFieldResolverName(getGQLEntityNameForClass(classType));
27
+ export const getGQLEntityTypeFor = (classType) => getGQLEntityFieldResolverName(TypeMap[getGQLEntityNameForClass(classType)]);
28
+ registerEnumType(Sort, {
29
+ name: `Sort${gqlTypesSuffix}`,
30
+ });
31
+ export function createGQLTypes(classType, opts, { customFields, acl, } = {}) {
32
+ const metadata = getMetadataStorage();
33
+ const gqlEntityName = getGQLEntityNameForClass(classType);
34
+ aclMap[gqlEntityName] = acl ?? {};
35
+ const fields = keys(opts);
36
+ class GQLEntity {
37
+ _____name = gqlEntityName;
38
+ }
39
+ Object.defineProperty(GQLEntity, 'name', { value: gqlEntityName });
40
+ TypeMap[gqlEntityName] = GQLEntity;
41
+ class GQLEntityFilterInput {
42
+ _and;
43
+ _or;
44
+ _not;
45
+ }
46
+ __decorate([
47
+ Field(() => [GQLEntityFilterInput], { nullable: true })
48
+ ], GQLEntityFilterInput.prototype, "_and", void 0);
49
+ __decorate([
50
+ Field(() => [GQLEntityFilterInput], { nullable: true })
51
+ ], GQLEntityFilterInput.prototype, "_or", void 0);
52
+ __decorate([
53
+ Field(() => [GQLEntityFilterInput], { nullable: true })
54
+ ], GQLEntityFilterInput.prototype, "_not", void 0);
55
+ Object.defineProperty(GQLEntityFilterInput, 'name', {
56
+ value: gqlEntityName + 'FilterInput',
57
+ });
58
+ TypeMap[gqlEntityName + 'FilterInput'] = GQLEntityFilterInput;
59
+ class GQLEntityOrderBy {
60
+ }
61
+ Object.defineProperty(GQLEntityOrderBy, 'name', {
62
+ value: gqlEntityName + 'OrderBy',
63
+ });
64
+ TypeMap[gqlEntityName + 'OrderBy'] = GQLEntityOrderBy;
65
+ let FieldsResolver = class FieldsResolver {
66
+ };
67
+ FieldsResolver = __decorate([
68
+ Resolver(() => GQLEntity)
69
+ ], FieldsResolver);
70
+ if (customFields) {
71
+ CustomFieldsMap[gqlEntityName] = customFields;
72
+ logger.info('CustomFieldsMap', gqlEntityName, customFields);
73
+ for (const fieldName of keys(customFields)) {
74
+ const fieldOptions = fieldName in customFields ? customFields[fieldName] : undefined;
75
+ if (!fieldOptions) {
76
+ continue;
77
+ }
78
+ const fieldNameOverride = fieldOptions.alias;
79
+ if (fieldNameOverride) {
80
+ FieldsOptionsMap[gqlEntityName] = FieldsOptionsMap[gqlEntityName] || {};
81
+ FieldsOptionsMap[gqlEntityName][fieldNameOverride] = fieldName;
82
+ }
83
+ const fieldNameToUse = fieldNameOverride ?? fieldName;
84
+ metadata.collectClassFieldMetadata({
85
+ target: GQLEntity,
86
+ name: fieldNameToUse,
87
+ schemaName: fieldNameToUse,
88
+ getType: fieldOptions.type,
89
+ typeOptions: {
90
+ ...('array' in fieldOptions && fieldOptions.array ? { array: true, arrayDepth: 1 } : {}),
91
+ ...fieldOptions.options,
92
+ },
93
+ complexity: undefined,
94
+ description: fieldNameToUse,
95
+ deprecationReason: undefined,
96
+ });
97
+ if (fieldOptions.resolve) {
98
+ Object.defineProperty(FieldsResolver.prototype, fieldNameToUse, {
99
+ // value: desc.value,
100
+ value: fieldOptions.resolve,
101
+ writable: true,
102
+ configurable: true,
103
+ });
104
+ FieldResolver(fieldOptions.type, {
105
+ ...('array' in fieldOptions && fieldOptions.array ? { array: true, arrayDepth: 1 } : {}),
106
+ ...fieldOptions.options,
107
+ name: fieldNameToUse,
108
+ })(FieldsResolver.prototype, fieldNameToUse, Object.getOwnPropertyDescriptor(FieldsResolver.prototype, fieldNameToUse));
109
+ fieldOptions.resolveDecorators?.forEach((decorator, i) => {
110
+ decorator(FieldsResolver.prototype, fieldNameToUse, i);
111
+ });
112
+ // Root()(FieldsResolver.prototype, fieldResolverName, 0);
113
+ }
114
+ }
115
+ }
116
+ InputType(gqlEntityName + 'OrderBy')(GQLEntityOrderBy);
117
+ const paginationTypeName = `${gqlEntityName}PaginationInput`;
118
+ let GQLEntityPaginationInputField = class GQLEntityPaginationInputField {
119
+ limit;
120
+ offset;
121
+ orderBy;
122
+ };
123
+ __decorate([
124
+ Field(() => Int, {
125
+ nullable: true,
126
+ })
127
+ ], GQLEntityPaginationInputField.prototype, "limit", void 0);
128
+ __decorate([
129
+ Field(() => Int, {
130
+ nullable: true,
131
+ })
132
+ ], GQLEntityPaginationInputField.prototype, "offset", void 0);
133
+ __decorate([
134
+ Field(() => [GQLEntityOrderBy], { nullable: true })
135
+ ], GQLEntityPaginationInputField.prototype, "orderBy", void 0);
136
+ GQLEntityPaginationInputField = __decorate([
137
+ InputType(paginationTypeName)
138
+ ], GQLEntityPaginationInputField);
139
+ Object.defineProperty(GQLEntityPaginationInputField, 'name', {
140
+ value: paginationTypeName,
141
+ });
142
+ TypeMap[paginationTypeName] = GQLEntityPaginationInputField;
143
+ for (const fieldName of fields) {
144
+ const fieldOptions = fieldName in opts ? opts[fieldName] : undefined;
145
+ if (!fieldOptions) {
146
+ continue;
147
+ }
148
+ const fieldNameOverride = fieldOptions.alias;
149
+ if (fieldNameOverride) {
150
+ FieldsOptionsMap[gqlEntityName] = FieldsOptionsMap[gqlEntityName] || {};
151
+ FieldsOptionsMap[gqlEntityName][fieldNameOverride] = fieldName;
152
+ }
153
+ const fieldNameToUse = fieldNameOverride ?? fieldName;
154
+ createGQLEntityFields(fieldOptions, fieldNameToUse, GQLEntity, metadata, GQLEntityOrderBy, gqlEntityName, GQLEntityFilterInput);
155
+ }
156
+ // acl && AuthorizeAccess(acl)({ name: gqlEntityName } as any);
157
+ ObjectType(gqlEntityName)(GQLEntity);
158
+ InputType(gqlEntityName + 'FilterInput')(GQLEntityFilterInput);
159
+ return {
160
+ GQLEntity,
161
+ GQLEntityFilterInput: GQLEntityFilterInput,
162
+ GQLEntityPaginationInputField: GQLEntityPaginationInputField,
163
+ /**
164
+ * this can be used alongside `getGQLEntityTypeFor` to get the type of the entity, not sure it will be ever needed
165
+ */
166
+ gqlEntityName,
167
+ relatedEntityName: classType.name,
168
+ FieldsResolver,
169
+ bindFieldResolvers: (c) => { },
170
+ };
171
+ }
172
+ export function createGQLEntityFields(fieldOptions, fieldName, GQLEntity, metadata, GQLEntityOrderBy, gqlEntityName, GQLEntityFilterInput) {
173
+ const getType = fieldOptions.type;
174
+ const isArray = 'array' in fieldOptions && fieldOptions.array;
175
+ const field = {
176
+ target: GQLEntity,
177
+ name: fieldName,
178
+ schemaName: fieldName,
179
+ getType: fieldOptions.type,
180
+ complexity: undefined,
181
+ description: fieldName,
182
+ deprecationReason: undefined,
183
+ options: {
184
+ ...fieldOptions.options,
185
+ ...(isArray ? { array: true, arrayDepth: 1 } : {}),
186
+ },
187
+ typeOptions: {
188
+ ...(isArray ? { array: true, arrayDepth: 1 } : {}),
189
+ ...fieldOptions.options,
190
+ },
191
+ };
192
+ metadata.collectClassFieldMetadata(field);
193
+ if (fieldOptions.enum) {
194
+ const enumObj = fieldOptions.enum[0];
195
+ const enumValues = fieldOptions.enum[1];
196
+ metadata.collectEnumMetadata({
197
+ enumObj,
198
+ description: enumValues.description ?? `${enumObj}`,
199
+ name: enumValues.name,
200
+ valuesConfig: enumValues.valuesConfig ?? {},
201
+ });
202
+ }
203
+ const UppercasedFieldName = fieldName[0].toUpperCase() + fieldName.slice(1);
204
+ if (fieldOptions.generateFilter) {
205
+ /**
206
+ * SORTING
207
+ * right now sorting by reference is not supported
208
+ */
209
+ if (!isArray) {
210
+ const orderByField = {
211
+ target: GQLEntityOrderBy,
212
+ name: fieldName,
213
+ schemaName: fieldName,
214
+ complexity: undefined,
215
+ description: fieldName,
216
+ deprecationReason: undefined,
217
+ getType: () => Sort,
218
+ options: { ...fieldOptions.options, nullable: true },
219
+ typeOptions: { ...fieldOptions.options, nullable: true },
220
+ };
221
+ metadata.collectClassFieldMetadata(orderByField);
222
+ }
223
+ /**
224
+ * FILTERING
225
+ */
226
+ const inputFieldName = `${gqlEntityName}_${UppercasedFieldName}`;
227
+ let GQLEntityFilterInputField = class GQLEntityFilterInputField {
228
+ _and;
229
+ _or;
230
+ _not;
231
+ };
232
+ __decorate([
233
+ Field(() => [GQLEntityFilterInputField], {
234
+ nullable: true,
235
+ deprecationReason: 'this is the same as using an object with multiple values',
236
+ })
237
+ ], GQLEntityFilterInputField.prototype, "_and", void 0);
238
+ __decorate([
239
+ Field(() => [GQLEntityFilterInputField], { nullable: true })
240
+ ], GQLEntityFilterInputField.prototype, "_or", void 0);
241
+ __decorate([
242
+ Field(() => [GQLEntityFilterInputField], { nullable: true })
243
+ ], GQLEntityFilterInputField.prototype, "_not", void 0);
244
+ GQLEntityFilterInputField = __decorate([
245
+ InputType(inputFieldName)
246
+ ], GQLEntityFilterInputField);
247
+ Object.defineProperty(GQLEntityFilterInputField, 'name', {
248
+ value: inputFieldName,
249
+ });
250
+ TypeMap[inputFieldName] = GQLEntityFilterInputField;
251
+ const options = [
252
+ { key: '_eq' },
253
+ { key: '_ne' },
254
+ { key: '_in', array: true },
255
+ { key: '_nin', array: true },
256
+ { key: '_gt' },
257
+ { key: '_gte' },
258
+ { key: '_lt' },
259
+ { key: '_lte' },
260
+ { key: '_like' },
261
+ { key: '_re' },
262
+ { key: '_ilike' },
263
+ { key: '_fulltext' },
264
+ { key: '_overlap', appliesToArray: true },
265
+ { key: '_contains', array: true, appliesToArray: true },
266
+ { key: '_contained' },
267
+ { key: '_exists' },
268
+ { key: '_between', array: true },
269
+ ];
270
+ const canFilterForField = 'type' in fieldOptions;
271
+ const includeNotArrays = !('relatedEntityName' in fieldOptions);
272
+ // const includeAppliesToArray = 'array' in fieldOptions && fieldOptions.array;
273
+ const getFilterType = 'getFilterType' in fieldOptions && fieldOptions.getFilterType;
274
+ const applicableOptions = canFilterForField
275
+ ? options.filter(({ appliesToArray }) => (!appliesToArray && includeNotArrays) || (appliesToArray && getFilterType))
276
+ : [];
277
+ if (canFilterForField && applicableOptions.length > 0) {
278
+ for (const option of applicableOptions) {
279
+ const optionGQLName = fieldName + option.key;
280
+ const backCompFieldFilterOpt = {
281
+ target: GQLEntityFilterInput,
282
+ name: optionGQLName,
283
+ schemaName: optionGQLName,
284
+ getType: option.appliesToArray && getFilterType ? getFilterType : getType,
285
+ options: {
286
+ ...fieldOptions.options,
287
+ ...(option.array || option.appliesToArray ? { array: true, arrayDepth: 1 } : {}),
288
+ nullable: true,
289
+ },
290
+ typeOptions: {
291
+ ...(option.array || option.appliesToArray ? { array: true, arrayDepth: 1 } : {}),
292
+ nullable: true,
293
+ },
294
+ complexity: undefined,
295
+ description: optionGQLName,
296
+ deprecationReason: undefined,
297
+ };
298
+ metadata.collectClassFieldMetadata(backCompFieldFilterOpt);
299
+ const fieldFilterOpt = {
300
+ target: GQLEntityFilterInputField,
301
+ name: option.key,
302
+ schemaName: option.key,
303
+ getType: option.appliesToArray && getFilterType ? getFilterType : getType,
304
+ options: {
305
+ ...fieldOptions.options,
306
+ ...(option.array || option.appliesToArray ? { array: true, arrayDepth: 1 } : {}),
307
+ nullable: true,
308
+ },
309
+ typeOptions: {
310
+ ...(option.array || option.appliesToArray ? { array: true, arrayDepth: 1 } : {}),
311
+ nullable: true,
312
+ },
313
+ complexity: undefined,
314
+ description: option.key,
315
+ deprecationReason: undefined,
316
+ };
317
+ metadata.collectClassFieldMetadata(fieldFilterOpt);
318
+ }
319
+ }
320
+ if (!('relatedEntityName' in fieldOptions)) {
321
+ const fieldFilterValue = {
322
+ target: GQLEntityFilterInput,
323
+ name: fieldName,
324
+ schemaName: fieldName,
325
+ getType: getType,
326
+ options: fieldOptions.options,
327
+ typeOptions: { nullable: true },
328
+ complexity: undefined,
329
+ description: fieldName,
330
+ deprecationReason: undefined,
331
+ };
332
+ metadata.collectClassFieldMetadata(fieldFilterValue);
333
+ }
334
+ const fieldFilter = {
335
+ target: GQLEntityFilterInput,
336
+ name: UppercasedFieldName,
337
+ schemaName: UppercasedFieldName,
338
+ getType: 'relatedEntityName' in fieldOptions
339
+ ? () => {
340
+ return (TypeMap[getGQLEntityNameFor(fieldOptions.relatedEntityName()) + 'FilterInput'] ??
341
+ GQLEntityFilterInputField);
342
+ }
343
+ : () => GQLEntityFilterInputField,
344
+ options: { ...fieldOptions.options, nullable: true },
345
+ typeOptions: { nullable: true },
346
+ complexity: undefined,
347
+ description: fieldName,
348
+ deprecationReason: undefined,
349
+ };
350
+ metadata.collectClassFieldMetadata(fieldFilter);
351
+ if ('array' in fieldOptions) {
352
+ const relatedEntityName = getGQLEntityNameFor(fieldOptions.relatedEntityName());
353
+ metadata.collectHandlerParamMetadata({
354
+ kind: 'arg',
355
+ name: 'filter',
356
+ description: undefined,
357
+ methodName: fieldName,
358
+ index: 0,
359
+ getType: () => TypeMap[relatedEntityName + 'FilterInput'],
360
+ target: GQLEntity,
361
+ typeOptions: { nullable: true },
362
+ deprecationReason: undefined,
363
+ validateFn: undefined,
364
+ validateSettings: undefined,
365
+ });
366
+ metadata.collectHandlerParamMetadata({
367
+ kind: 'arg',
368
+ name: 'pagination',
369
+ description: undefined,
370
+ methodName: fieldName,
371
+ index: 1,
372
+ getType: () => TypeMap[`${relatedEntityName}PaginationInput`],
373
+ target: GQLEntity,
374
+ typeOptions: { nullable: true },
375
+ deprecationReason: undefined,
376
+ validateFn: undefined,
377
+ validateSettings: undefined,
378
+ });
379
+ }
380
+ }
381
+ }
@@ -0,0 +1 @@
1
+ export * from './gql-entity';
@@ -0,0 +1 @@
1
+ export * from './gql-entity';
@@ -0,0 +1,5 @@
1
+ export * from './entities';
2
+ export * from './queries';
3
+ export * from './query-manager';
4
+ export * from './types';
5
+ export * from './utils';
@@ -0,0 +1,5 @@
1
+ export * from './entities';
2
+ export * from './queries';
3
+ export * from './query-manager';
4
+ export * from './types';
5
+ export * from './utils';
@@ -0,0 +1,116 @@
1
+ import { Alias } from './queries';
2
+ import { EntityMetadata, GQLEntityFilterInputFieldType, MappingsType } from './types';
3
+ export type ClassOperationInputType<T> = {
4
+ entityMetadata: EntityMetadata<T>;
5
+ gqlFilters: GQLEntityFilterInputFieldType<T>[];
6
+ fieldName: string & keyof Pick<MappingsType, '_and' | '_not' | '_or'>;
7
+ parentAlias: Alias;
8
+ alias: Alias;
9
+ mapping: MappingsType;
10
+ mappings: Map<string, MappingsType>;
11
+ };
12
+ export declare abstract class ClassOperations {
13
+ abstract _and(input: ClassOperationInputType<any>): any;
14
+ abstract _or(input: ClassOperationInputType<any>): any;
15
+ abstract _not(input: ClassOperationInputType<any>): any;
16
+ }
17
+ export declare abstract class ClassOperationsClass<T> {
18
+ abstract _and: T[];
19
+ abstract _or: T[];
20
+ abstract _not: T[];
21
+ }
22
+ export declare abstract class FieldOperationsClass<T> {
23
+ abstract _and: T;
24
+ abstract _eq: T;
25
+ abstract _ne: T;
26
+ abstract _in: T[];
27
+ abstract _nin: T[];
28
+ abstract _gt: T;
29
+ abstract _gte: T;
30
+ abstract _lt: T;
31
+ abstract _lte: T;
32
+ abstract _like: T;
33
+ abstract _re: T;
34
+ abstract _ilike: T;
35
+ abstract _fulltext: T;
36
+ abstract _overlap: T[];
37
+ abstract _contains: T;
38
+ abstract _contained: T;
39
+ abstract _between: T[];
40
+ abstract _exists: T;
41
+ }
42
+ export declare const FieldOperations: {
43
+ _and: ([l]: string[], [_]: Array<string | number | boolean | bigint | null>) => {
44
+ where: string;
45
+ value: undefined;
46
+ };
47
+ _eq: ([l, r]: string[], [_, rv]: Array<string | number | boolean | bigint | null>) => {
48
+ where: string;
49
+ value: undefined;
50
+ };
51
+ _ne: ([l, r]: string[], [_, rv]: Array<string | number | boolean | bigint | null>) => {
52
+ where: string;
53
+ value: undefined;
54
+ };
55
+ _in: ([l, r, ..._args]: string[], [_, ...values]: Array<string | number | boolean | bigint | null>) => {
56
+ where: string;
57
+ value: {};
58
+ };
59
+ _nin: ([l, r, ..._args]: string[], [_, ...values]: Array<string | number | boolean | bigint | null>) => {
60
+ where: string;
61
+ value: {};
62
+ };
63
+ _gt: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
64
+ where: string;
65
+ value: undefined;
66
+ };
67
+ _gte: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
68
+ where: string;
69
+ value: undefined;
70
+ };
71
+ _lt: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
72
+ where: string;
73
+ value: undefined;
74
+ };
75
+ _lte: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
76
+ where: string;
77
+ value: undefined;
78
+ };
79
+ _like: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
80
+ where: string;
81
+ value: undefined;
82
+ };
83
+ _re: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
84
+ where: string;
85
+ value: undefined;
86
+ };
87
+ _ilike: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
88
+ where: string;
89
+ value: undefined;
90
+ };
91
+ _fulltext: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
92
+ where: string;
93
+ value: undefined;
94
+ };
95
+ _overlap: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
96
+ where: string;
97
+ value: undefined;
98
+ };
99
+ _contains: ([l, r, ..._args]: string[], [_, ...values]: Array<string | number | boolean | bigint | null>) => {
100
+ where: string;
101
+ value: {};
102
+ };
103
+ _contained: ([l, r]: string[], []: Array<string | number | boolean | bigint | null>) => {
104
+ where: string;
105
+ value: undefined;
106
+ };
107
+ _between: ([l, r1, r2]: string[], []: Array<string | number | boolean | bigint | null>) => {
108
+ where: string;
109
+ value: undefined;
110
+ };
111
+ _exists: ([l]: string[], []: Array<string | number | boolean | bigint | null>) => {
112
+ where: string;
113
+ value: undefined;
114
+ };
115
+ };
116
+ export type FieldOperationsType = typeof FieldOperations;
@@ -0,0 +1,81 @@
1
+ export class ClassOperations {
2
+ }
3
+ export class ClassOperationsClass {
4
+ }
5
+ export class FieldOperationsClass {
6
+ }
7
+ export const FieldOperations = {
8
+ _and: ([l], [_]) => ({
9
+ where: `and (${l})`,
10
+ value: undefined,
11
+ }),
12
+ _eq: ([l, r], [_, rv]) => ({
13
+ where: `${l} ${rv !== null && rv !== 'null' ? `= ${r}` : 'is null'}`,
14
+ value: undefined,
15
+ }),
16
+ _ne: ([l, r], [_, rv]) => ({
17
+ where: `${l} ${rv !== null && rv !== 'null' ? `!= ${r}` : 'is not null'}`,
18
+ value: undefined,
19
+ }),
20
+ _in: ([l, r, ..._args], [_, ...values]) => ({
21
+ where: `${l} in (${values.map((_, i) => r + '__' + i).join(', ')})`,
22
+ value: values.reduce((acc, v, i) => ({ ...acc, [r.slice(1) + '__' + i]: v }), {}),
23
+ }),
24
+ _nin: ([l, r, ..._args], [_, ...values]) => ({
25
+ where: `${l} not in (${values.map((_, i) => r + '__' + i).join(', ')})`,
26
+ value: values.reduce((acc, v, i) => ({ ...acc, [r.slice(1) + '__' + i]: v }), {}),
27
+ }),
28
+ _gt: ([l, r], []) => ({
29
+ where: `${l} > ${r}`,
30
+ value: undefined,
31
+ }),
32
+ _gte: ([l, r], []) => ({
33
+ where: `${l} >= ${r}`,
34
+ value: undefined,
35
+ }),
36
+ _lt: ([l, r], []) => ({
37
+ where: `${l} < ${r}`,
38
+ value: undefined,
39
+ }),
40
+ _lte: ([l, r], []) => ({
41
+ where: `${l} <= ${r}`,
42
+ value: undefined,
43
+ }),
44
+ _like: ([l, r], []) => ({
45
+ where: `${l} like ${r}`,
46
+ value: undefined,
47
+ }),
48
+ _re: ([l, r], []) => ({
49
+ where: `${l} ~ ${r}`,
50
+ value: undefined,
51
+ }),
52
+ _ilike: ([l, r], []) => ({
53
+ where: `${l} ilike ${r}`,
54
+ value: undefined,
55
+ }),
56
+ _fulltext: ([l, r], []) => ({
57
+ where: `${l}::tsvector @@ ${r}::tsquery`,
58
+ value: undefined,
59
+ }),
60
+ _overlap: ([l, r], []) => ({
61
+ where: `ARRAY[${l}] && ARRAY[${r}]`,
62
+ value: undefined,
63
+ }),
64
+ // this is possibly not implemented correctly
65
+ _contains: ([l, r, ..._args], [_, ...values]) => ({
66
+ where: `ARRAY[${l}] @> ARRAY[${values.map((_, i) => r + '__' + i).join(', ')}]`,
67
+ value: values.reduce((acc, v, i) => ({ ...acc, [r.slice(1) + '__' + i]: v }), {}),
68
+ }),
69
+ _contained: ([l, r], []) => ({
70
+ where: `${l} contained ${r}`,
71
+ value: undefined,
72
+ }),
73
+ _between: ([l, r1, r2], []) => ({
74
+ where: `${l} between ${r1} and ${r2}`,
75
+ value: undefined,
76
+ }),
77
+ _exists: ([l], []) => ({
78
+ where: `exists ${l}`,
79
+ value: undefined,
80
+ }),
81
+ };
@@ -0,0 +1,25 @@
1
+ export declare enum AliasType {
2
+ entity = "entity",
3
+ field = "field",
4
+ value = "value"
5
+ }
6
+ export declare class Alias {
7
+ private type;
8
+ private index;
9
+ private prefix;
10
+ constructor(type: AliasType, index: number, prefix: string);
11
+ toString(): string;
12
+ toColumnName(value: string): string;
13
+ toParamName(childAlias: string | number): string;
14
+ concat(...text: string[]): string;
15
+ get pref(): string;
16
+ }
17
+ export declare class AliasManager {
18
+ private ALIAS_INDEX_MAP;
19
+ private checkMap;
20
+ resetAll(): void;
21
+ reset(type: AliasType, prefix: string): Alias;
22
+ restartFrom(type: AliasType, prefix: string, index: number): Alias;
23
+ start(prefix: string): Alias;
24
+ next(type: AliasType, prefix: string): Alias;
25
+ }
@@ -0,0 +1,66 @@
1
+ import { logger } from '../variables';
2
+ export var AliasType;
3
+ (function (AliasType) {
4
+ AliasType["entity"] = "entity";
5
+ AliasType["field"] = "field";
6
+ AliasType["value"] = "value";
7
+ })(AliasType || (AliasType = {}));
8
+ export class Alias {
9
+ type;
10
+ index;
11
+ prefix;
12
+ constructor(type, index, prefix) {
13
+ this.type = type;
14
+ this.index = index;
15
+ this.prefix = prefix;
16
+ }
17
+ toString() {
18
+ return `${this.type[0]}_${this.prefix}${this.index}`;
19
+ }
20
+ toColumnName(value) {
21
+ return `${this.type[0]}_${this.prefix}${this.index}.${value}`;
22
+ }
23
+ toParamName(childAlias) {
24
+ return `${this.type[0]}_${this.prefix}${this.index}_${childAlias}`;
25
+ }
26
+ concat(...text) {
27
+ return `${text.join('')} - ${this.type[0]}_${this.prefix}${this.index}`;
28
+ }
29
+ get pref() {
30
+ return this.prefix;
31
+ }
32
+ }
33
+ export class AliasManager {
34
+ ALIAS_INDEX_MAP = new Map();
35
+ checkMap(type, prefix) {
36
+ if (!this.ALIAS_INDEX_MAP.has(type)) {
37
+ this.ALIAS_INDEX_MAP.set(type, new Map());
38
+ }
39
+ if (!this.ALIAS_INDEX_MAP.get(type)?.has(prefix)) {
40
+ this.ALIAS_INDEX_MAP.get(type)?.set(prefix, 0);
41
+ }
42
+ }
43
+ resetAll() {
44
+ this.ALIAS_INDEX_MAP.clear();
45
+ }
46
+ reset(type, prefix) {
47
+ return this.restartFrom(type, prefix, 1);
48
+ }
49
+ restartFrom(type, prefix, index) {
50
+ this.checkMap(type, prefix);
51
+ this.ALIAS_INDEX_MAP.get(type)?.set(prefix, index);
52
+ return new Alias(type, index, prefix);
53
+ }
54
+ start(prefix) {
55
+ return this.next(AliasType.entity, prefix);
56
+ }
57
+ next(type, prefix) {
58
+ this.checkMap(type, prefix);
59
+ const existingIndex = this.ALIAS_INDEX_MAP.get(type)?.get(prefix) ?? 0;
60
+ logger.log('AliasManager.next', type, prefix, existingIndex);
61
+ const index = existingIndex + 1;
62
+ this.ALIAS_INDEX_MAP.get(type)?.set(prefix, index);
63
+ // this will automatically pick the last index
64
+ return new Alias(type, index, prefix);
65
+ }
66
+ }