rads-db 3.0.73 → 3.0.75

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.cjs CHANGED
@@ -662,6 +662,9 @@ async function handleInclude(computedContext, include, result, ctx) {
662
662
  const { schema, typeName } = computedContext;
663
663
  const fields = schema[typeName].fields || {};
664
664
  const fieldsToInclude = ___default.keys(include).filter((key) => include[key]);
665
+ const nestedFieldsToInclude = fieldsToInclude.filter(
666
+ (key) => !fields[key].isRelation && !fields[key].isInverseRelation && schema[fields[key].type]?.fields
667
+ );
665
668
  const relationsToInclude = fieldsToInclude.filter((key) => fields[key].isRelation);
666
669
  const args = {
667
670
  entityTypeName: typeName,
@@ -670,6 +673,15 @@ async function handleInclude(computedContext, include, result, ctx) {
670
673
  result,
671
674
  include
672
675
  };
676
+ for (const nf of nestedFieldsToInclude) {
677
+ const resultsWithNestedField = result.filter((item) => item[nf]);
678
+ await handleInclude(
679
+ { ...computedContext, typeName: fields[nf].type },
680
+ include[nf],
681
+ resultsWithNestedField.map((x) => x[nf]),
682
+ ctx
683
+ );
684
+ }
673
685
  const inverseRelationsToInclude = fieldsToInclude.filter((key) => fields[key].isInverseRelation);
674
686
  const downloadRelationsPromises = relationsToInclude.map(
675
687
  (fieldName) => downloadRelatedDocuments({ ...args, fieldName })
package/dist/index.d.ts CHANGED
@@ -42,12 +42,13 @@ type GetManyArgsAny = GetManyArgs<any>;
42
42
  type GetArgsAny = GetArgs<any>;
43
43
  type GetAggArgsAny = GetAggArgs<any>;
44
44
  type VerifyManyArgsAny = VerifyManyArgs<any>;
45
- type GetArgsInclude<EN extends keyof EntityMeta, R extends keyof EntityMeta[EN]['relations'] = keyof EntityMeta[EN]['relations']> = [R] extends [never] ? {
45
+ type RelationsAndNestedObjects<EN extends keyof EntityMeta> = EntityMeta[EN]['relations'] & EntityMeta[EN]['nestedObjects'];
46
+ type GetArgsInclude<EN extends keyof EntityMeta, R extends keyof RelationsAndNestedObjects<EN> = keyof RelationsAndNestedObjects<EN>> = [R] extends [never] ? {
46
47
  _pick?: EntityMeta[EN]['primitives'][];
47
48
  } : {
48
49
  _pick?: EntityMeta[EN]['primitives'][];
49
50
  } & {
50
- [K in R]?: GetArgsInclude<EntityMeta[EN]['relations'][K]['entityName']>;
51
+ [K in R]?: GetArgsInclude<RelationsAndNestedObjects<EN>[K]['entityName']>;
51
52
  };
52
53
  type GetAggResponse<EN extends keyof EntityMeta, A extends GetAggArgs<EN>> = {
53
54
  [K in A['agg'][0]]: K extends '_count' ? number : number | undefined;
@@ -250,6 +251,7 @@ interface TypeDefinition {
250
251
  handlePlural?: string;
251
252
  isExtending?: string;
252
253
  keepHistoryFields?: string[];
254
+ sourceFile?: string;
253
255
  }
254
256
  interface FileUploadResult {
255
257
  url: string;
package/dist/index.mjs CHANGED
@@ -655,6 +655,9 @@ async function handleInclude(computedContext, include, result, ctx) {
655
655
  const { schema, typeName } = computedContext;
656
656
  const fields = schema[typeName].fields || {};
657
657
  const fieldsToInclude = _.keys(include).filter((key) => include[key]);
658
+ const nestedFieldsToInclude = fieldsToInclude.filter(
659
+ (key) => !fields[key].isRelation && !fields[key].isInverseRelation && schema[fields[key].type]?.fields
660
+ );
658
661
  const relationsToInclude = fieldsToInclude.filter((key) => fields[key].isRelation);
659
662
  const args = {
660
663
  entityTypeName: typeName,
@@ -663,6 +666,15 @@ async function handleInclude(computedContext, include, result, ctx) {
663
666
  result,
664
667
  include
665
668
  };
669
+ for (const nf of nestedFieldsToInclude) {
670
+ const resultsWithNestedField = result.filter((item) => item[nf]);
671
+ await handleInclude(
672
+ { ...computedContext, typeName: fields[nf].type },
673
+ include[nf],
674
+ resultsWithNestedField.map((x) => x[nf]),
675
+ ctx
676
+ );
677
+ }
666
678
  const inverseRelationsToInclude = fieldsToInclude.filter((key) => fields[key].isInverseRelation);
667
679
  const downloadRelationsPromises = relationsToInclude.map(
668
680
  (fieldName) => downloadRelatedDocuments({ ...args, fieldName })
@@ -165,7 +165,7 @@ function parseClassDeclaration(typeDeclaration, typeName, ctx) {
165
165
  const nameNode = typeDeclaration.name;
166
166
  if (!nameNode || nameNode.kind !== _typescript.SyntaxKind.Identifier) throw new Error("Cannot detect class name");
167
167
  const name = nameNode.text;
168
- const comment = typeDeclaration.jsDoc?.[0]?.comment;
168
+ const comment = getCommentFromJsdocNode(typeDeclaration.jsDoc);
169
169
  const decorators = parseDecorators(modifiers, ctx);
170
170
  const classDeclaration = typeDeclaration;
171
171
  const {
@@ -193,7 +193,8 @@ function parseClassDeclaration(typeDeclaration, typeName, ctx) {
193
193
  decorators,
194
194
  fields,
195
195
  isExtending,
196
- comment
196
+ comment,
197
+ sourceFile: ctx.sourceFile.fileName
197
198
  };
198
199
  return result;
199
200
  }
@@ -202,7 +203,7 @@ function parseTypeAliasDeclaration(typeDeclaration, typeName, ctx) {
202
203
  const nameNode = typeDeclaration.name;
203
204
  if (!nameNode || nameNode.kind !== _typescript.SyntaxKind.Identifier) throw new Error("Cannot detect class name");
204
205
  const name = nameNode.text;
205
- const comment = typeDeclaration.jsDoc?.[0]?.comment;
206
+ const comment = getCommentFromJsdocNode(typeDeclaration.jsDoc);
206
207
  const typeAliasDeclaration = typeDeclaration;
207
208
  const typeAliasType = typeAliasDeclaration.type;
208
209
  if (typeAliasType.kind === _typescript.SyntaxKind.UnionType) {
@@ -212,7 +213,8 @@ function parseTypeAliasDeclaration(typeDeclaration, typeName, ctx) {
212
213
  name,
213
214
  enumValues,
214
215
  comment,
215
- decorators: {}
216
+ decorators: {},
217
+ sourceFile: ctx.sourceFile.fileName
216
218
  };
217
219
  }
218
220
  if (typeAliasType.kind === _typescript.SyntaxKind.TypeOperator && typeAliasType.operator === _typescript.SyntaxKind.KeyOfKeyword) {
@@ -221,7 +223,8 @@ function parseTypeAliasDeclaration(typeDeclaration, typeName, ctx) {
221
223
  name,
222
224
  enumValues,
223
225
  comment,
224
- decorators: {}
226
+ decorators: {},
227
+ sourceFile: ctx.sourceFile.fileName
225
228
  };
226
229
  }
227
230
  throw new Error(`Unexpected type definition - ${typeDeclaration.getText(ctx.sourceFile)}. Did you mean 'class'?`);
@@ -259,7 +262,7 @@ function parseClassMember(node, parentFields, parentName, ctx) {
259
262
  defaultValueClass
260
263
  } = parseDefaultValueExpression(node.initializer, ctx);
261
264
  const isRequired = !node.questionToken;
262
- const comment = node.jsDoc?.[0]?.comment;
265
+ const comment = getCommentFromJsdocNode(node.jsDoc);
263
266
  const decorators = parseDecorators(node.modifiers, ctx);
264
267
  let defaultValueType = defaultValueClass || getPrimitiveTypeFromDefaultValue(defaultValue);
265
268
  if (defaultValueCopyFrom) {
@@ -280,6 +283,12 @@ function parseClassMember(node, parentFields, parentName, ctx) {
280
283
  if (defaultValueClass) result.defaultValueClass = defaultValueClass;
281
284
  return result;
282
285
  }
286
+ function getCommentFromJsdocNode(jsDoc) {
287
+ const comment = jsDoc?.[0]?.comment;
288
+ const tags = jsDoc?.[0]?.tags;
289
+ const tagsStr = tags?.map(tag => [`@${tag.tagName.text}`, tag.comment || ""].filter(x => x).join(" "))?.join("\n") || "";
290
+ return [comment, tagsStr].filter(x => x).join("\n") || void 0;
291
+ }
283
292
  function getPrimitiveTypeFromDefaultValue(value) {
284
293
  if (_lodash.default.isString(value)) return "string";
285
294
  if (_lodash.default.isNumber(value)) return "number";
@@ -346,7 +355,8 @@ function parseFieldTypeRecordEnum(parsedType, parentName, fieldName, ctx) {
346
355
  ctx.result[newTypeName] = {
347
356
  name: newTypeName,
348
357
  decorators: {},
349
- fields: _lodash.default.keyBy(fieldsArray, "name")
358
+ fields: _lodash.default.keyBy(fieldsArray, "name"),
359
+ sourceFile: ctx.sourceFile.fileName
350
360
  };
351
361
  parsedType.type = newTypeName;
352
362
  }
@@ -404,7 +414,8 @@ function parseFieldTypeInlineEnum(parsedType, parentName, fieldName, ctx) {
404
414
  ctx.result[newTypeName] = {
405
415
  name: newTypeName,
406
416
  decorators: {},
407
- enumValues
417
+ enumValues,
418
+ sourceFile: ctx.sourceFile.fileName
408
419
  };
409
420
  parsedType.type = newTypeName;
410
421
  }
@@ -417,7 +428,8 @@ function parseFieldTypeKeyofEnum(parsedType, parentName, fieldName, ctx) {
417
428
  ctx.result[newTypeName] = {
418
429
  name: newTypeName,
419
430
  decorators: {},
420
- enumValues
431
+ enumValues,
432
+ sourceFile: ctx.sourceFile.fileName
421
433
  };
422
434
  parsedType.type = newTypeName;
423
435
  }
@@ -145,7 +145,7 @@ function parseClassDeclaration(typeDeclaration, typeName, ctx) {
145
145
  if (!nameNode || nameNode.kind !== SyntaxKind.Identifier)
146
146
  throw new Error("Cannot detect class name");
147
147
  const name = nameNode.text;
148
- const comment = typeDeclaration.jsDoc?.[0]?.comment;
148
+ const comment = getCommentFromJsdocNode(typeDeclaration.jsDoc);
149
149
  const decorators = parseDecorators(modifiers, ctx);
150
150
  const classDeclaration = typeDeclaration;
151
151
  const { members, heritageClauses } = classDeclaration;
@@ -170,7 +170,8 @@ function parseClassDeclaration(typeDeclaration, typeName, ctx) {
170
170
  decorators,
171
171
  fields,
172
172
  isExtending,
173
- comment
173
+ comment,
174
+ sourceFile: ctx.sourceFile.fileName
174
175
  };
175
176
  return result;
176
177
  }
@@ -181,17 +182,17 @@ function parseTypeAliasDeclaration(typeDeclaration, typeName, ctx) {
181
182
  if (!nameNode || nameNode.kind !== SyntaxKind.Identifier)
182
183
  throw new Error("Cannot detect class name");
183
184
  const name = nameNode.text;
184
- const comment = typeDeclaration.jsDoc?.[0]?.comment;
185
+ const comment = getCommentFromJsdocNode(typeDeclaration.jsDoc);
185
186
  const typeAliasDeclaration = typeDeclaration;
186
187
  const typeAliasType = typeAliasDeclaration.type;
187
188
  if (typeAliasType.kind === SyntaxKind.UnionType) {
188
189
  const typeAliasValue = typeAliasDeclaration.type;
189
190
  const enumValues = getEnumValues(typeAliasValue, typeDeclaration, ctx);
190
- return { name, enumValues, comment, decorators: {} };
191
+ return { name, enumValues, comment, decorators: {}, sourceFile: ctx.sourceFile.fileName };
191
192
  }
192
193
  if (typeAliasType.kind === SyntaxKind.TypeOperator && typeAliasType.operator === SyntaxKind.KeyOfKeyword) {
193
194
  const enumValues = getEnumValuesFromKeyOf(typeAliasType, ctx);
194
- return { name, enumValues, comment, decorators: {} };
195
+ return { name, enumValues, comment, decorators: {}, sourceFile: ctx.sourceFile.fileName };
195
196
  }
196
197
  throw new Error(`Unexpected type definition - ${typeDeclaration.getText(ctx.sourceFile)}. Did you mean 'class'?`);
197
198
  }
@@ -222,7 +223,7 @@ function parseClassMember(node, parentFields, parentName, ctx) {
222
223
  const name = node.name.getText(ctx.sourceFile);
223
224
  const { defaultValue, defaultValueCopyFrom, defaultValueClass } = parseDefaultValueExpression(node.initializer, ctx);
224
225
  const isRequired = !node.questionToken;
225
- const comment = node.jsDoc?.[0]?.comment;
226
+ const comment = getCommentFromJsdocNode(node.jsDoc);
226
227
  const decorators = parseDecorators(node.modifiers, ctx);
227
228
  let defaultValueType = defaultValueClass || getPrimitiveTypeFromDefaultValue(defaultValue);
228
229
  if (defaultValueCopyFrom) {
@@ -246,6 +247,12 @@ function parseClassMember(node, parentFields, parentName, ctx) {
246
247
  result.defaultValueClass = defaultValueClass;
247
248
  return result;
248
249
  }
250
+ function getCommentFromJsdocNode(jsDoc) {
251
+ const comment = jsDoc?.[0]?.comment;
252
+ const tags = jsDoc?.[0]?.tags;
253
+ const tagsStr = tags?.map((tag) => [`@${tag.tagName.text}`, tag.comment || ""].filter((x) => x).join(" "))?.join("\n") || "";
254
+ return [comment, tagsStr].filter((x) => x).join("\n") || void 0;
255
+ }
249
256
  function getPrimitiveTypeFromDefaultValue(value) {
250
257
  if (_.isString(value))
251
258
  return "string";
@@ -321,7 +328,8 @@ function parseFieldTypeRecordEnum(parsedType, parentName, fieldName, ctx) {
321
328
  ctx.result[newTypeName] = {
322
329
  name: newTypeName,
323
330
  decorators: {},
324
- fields: _.keyBy(fieldsArray, "name")
331
+ fields: _.keyBy(fieldsArray, "name"),
332
+ sourceFile: ctx.sourceFile.fileName
325
333
  };
326
334
  parsedType.type = newTypeName;
327
335
  }
@@ -382,7 +390,7 @@ function parseFieldTypeInlineEnum(parsedType, parentName, fieldName, ctx) {
382
390
  const nt = parsedType.nodeType;
383
391
  const enumValues = getEnumValues(nt, parsedType.node, ctx);
384
392
  const newTypeName = `${parentName}_${_.upperFirst(fieldName)}`;
385
- ctx.result[newTypeName] = { name: newTypeName, decorators: {}, enumValues };
393
+ ctx.result[newTypeName] = { name: newTypeName, decorators: {}, enumValues, sourceFile: ctx.sourceFile.fileName };
386
394
  parsedType.type = newTypeName;
387
395
  }
388
396
  function parseFieldTypeKeyofEnum(parsedType, parentName, fieldName, ctx) {
@@ -393,7 +401,7 @@ function parseFieldTypeKeyofEnum(parsedType, parentName, fieldName, ctx) {
393
401
  return;
394
402
  const enumValues = getEnumValuesFromKeyOf(nt, ctx);
395
403
  const newTypeName = `${parentName}_${_.upperFirst(fieldName)}`;
396
- ctx.result[newTypeName] = { name: newTypeName, decorators: {}, enumValues };
404
+ ctx.result[newTypeName] = { name: newTypeName, decorators: {}, enumValues, sourceFile: ctx.sourceFile.fileName };
397
405
  parsedType.type = newTypeName;
398
406
  }
399
407
  function getEnumValuesFromKeyOf(nodeType, ctx) {
@@ -104,11 +104,13 @@ function getIndexDts(schema, options) {
104
104
  const schemaTypesStr = options.entitiesDir ? "" : getEntityTypesStrFromSchema(schema);
105
105
  for (const key in schema) {
106
106
  const type = schema[key];
107
- if (!type.decorators.entity) continue;
108
- if (options.entitiesDir) {
109
- imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${key}'`);
107
+ if (!type.fields) continue;
108
+ if (options.entitiesDir && type.sourceFile) {
109
+ imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${type.sourceFile}'`);
110
+ }
111
+ if (type.decorators?.entity) {
112
+ rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}'>`);
110
113
  }
111
- rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}'>`);
112
114
  const fieldsArray = Object.values(type.fields);
113
115
  const relations = _lodash.default.fromPairs(fieldsArray.filter(f => f.isRelation).map(f => [f.name, {
114
116
  entity: f.type,
@@ -118,6 +120,7 @@ function getIndexDts(schema, options) {
118
120
  type: type.name,
119
121
  whereType: `${type.name}_Where`,
120
122
  relationsStr: _lodash.default.keys(relations).map(k => `${k}: { entityName: '${relations[k].entity}', entity: ${relations[k].entity}, denormFields: ${relations[k].denormFields} }`),
123
+ nestedObjectsStr: fieldsArray.filter(f => schema[f.type]?.fields && !f.isRelation && !f.isChange && !f.isInverseRelation).map(f => `${f.name}: { entityName: '${f.type}' }`),
121
124
  aggregates: fieldsArray.filter(f => f.type === "number" && !f.isArray).map(x => `'${x.name}'`).join(" | "),
122
125
  primitives: fieldsArray.filter(f => !schema[f.type]?.decorators?.entity).map(x => `'${x.name}'`).join(" | ")
123
126
  });
@@ -137,6 +140,7 @@ ${whereFields.join("\n")}
137
140
  whereType: ${x.whereType}
138
141
  primitives: ${x.primitives || "never"}
139
142
  aggregates: ${x.aggregates || "never"}
143
+ nestedObjects: {${x.nestedObjectsStr}}
140
144
  relations: {${x.relationsStr}}
141
145
  }
142
146
  `.trim()).join("\n");
@@ -94,12 +94,14 @@ export function getIndexDts(schema, options) {
94
94
  const schemaTypesStr = options.entitiesDir ? "" : getEntityTypesStrFromSchema(schema);
95
95
  for (const key in schema) {
96
96
  const type = schema[key];
97
- if (!type.decorators.entity)
97
+ if (!type.fields)
98
98
  continue;
99
- if (options.entitiesDir) {
100
- imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${key}'`);
99
+ if (options.entitiesDir && type.sourceFile) {
100
+ imports.push(`import type { ${type.name} } from '../../${options.entitiesDir}/${type.sourceFile}'`);
101
+ }
102
+ if (type.decorators?.entity) {
103
+ rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}'>`);
101
104
  }
102
- rootFields.push(`${type.handle}: EntityMethods<${type.name}, '${type.name}'>`);
103
105
  const fieldsArray = Object.values(type.fields);
104
106
  const relations = _.fromPairs(
105
107
  fieldsArray.filter((f) => f.isRelation).map((f) => [
@@ -113,6 +115,7 @@ export function getIndexDts(schema, options) {
113
115
  relationsStr: _.keys(relations).map(
114
116
  (k) => `${k}: { entityName: '${relations[k].entity}', entity: ${relations[k].entity}, denormFields: ${relations[k].denormFields} }`
115
117
  ),
118
+ nestedObjectsStr: fieldsArray.filter((f) => schema[f.type]?.fields && !f.isRelation && !f.isChange && !f.isInverseRelation).map((f) => `${f.name}: { entityName: '${f.type}' }`),
116
119
  aggregates: fieldsArray.filter((f) => f.type === "number" && !f.isArray).map((x) => `'${x.name}'`).join(" | "),
117
120
  primitives: fieldsArray.filter((f) => !schema[f.type]?.decorators?.entity).map((x) => `'${x.name}'`).join(" | ")
118
121
  });
@@ -136,6 +139,7 @@ ${whereFields.join("\n")}
136
139
  whereType: ${x.whereType}
137
140
  primitives: ${x.primitives || "never"}
138
141
  aggregates: ${x.aggregates || "never"}
142
+ nestedObjects: {${x.nestedObjectsStr}}
139
143
  relations: {${x.relationsStr}}
140
144
  }
141
145
  `.trim()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rads-db",
3
- "version": "3.0.73",
3
+ "version": "3.0.75",
4
4
  "packageManager": "pnpm@8.6.1",
5
5
  "description": "Say goodbye to boilerplate code and hello to efficient and elegant syntax.",
6
6
  "author": "",