@apso/cli 0.5.0 → 0.7.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 (69) hide show
  1. package/README.md +510 -1
  2. package/dist/commands/server/new.js +1 -1
  3. package/dist/commands/server/scaffold.js +19 -10
  4. package/dist/lib/apsorc-parser.d.ts +3 -0
  5. package/dist/lib/apsorc-parser.js +11 -6
  6. package/dist/lib/controller.js +3 -1
  7. package/dist/lib/dto.js +9 -9
  8. package/dist/lib/entity.js +6 -5
  9. package/dist/lib/guards.d.ts +4 -3
  10. package/dist/lib/guards.js +64 -25
  11. package/dist/lib/module.js +3 -1
  12. package/dist/lib/templates/guards/auth.guard.eta +228 -0
  13. package/dist/lib/templates/guards/guards.module.eta +73 -13
  14. package/dist/lib/templates/guards/index.eta +18 -0
  15. package/dist/lib/templates/guards/scope.guard.eta +12 -4
  16. package/dist/lib/types/auth.d.ts +203 -0
  17. package/dist/lib/types/auth.js +60 -0
  18. package/dist/lib/types/entity.d.ts +2 -2
  19. package/dist/lib/types/index.d.ts +1 -0
  20. package/dist/lib/types/index.js +8 -0
  21. package/dist/lib/types/relationship.d.ts +1 -1
  22. package/dist/lib/utils/casing.js +5 -5
  23. package/dist/lib/utils/field.js +2 -1
  24. package/dist/lib/utils/file-system.js +1 -1
  25. package/dist/lib/utils/relationships/parse-v1.js +2 -1
  26. package/dist/lib/utils/relationships/parse.js +117 -32
  27. package/dist/lib/utils/relationships/parse.spec.js +168 -141
  28. package/dist/test-nested-relationships.js +10 -10
  29. package/dist/tests/templates/entities/types/array-template.spec.js +45 -45
  30. package/dist/tests/templates/entities/types/bigint-template.spec.js +43 -43
  31. package/dist/tests/templates/entities/types/boolean-template.spec.js +44 -44
  32. package/dist/tests/templates/entities/types/bytea-template.spec.js +35 -35
  33. package/dist/tests/templates/entities/types/char-template.spec.js +35 -35
  34. package/dist/tests/templates/entities/types/date-template.spec.js +29 -29
  35. package/dist/tests/templates/entities/types/decimal-field-validation.spec.js +46 -46
  36. package/dist/tests/templates/entities/types/decimal-template.spec.js +46 -46
  37. package/dist/tests/templates/entities/types/double-template.spec.js +37 -34
  38. package/dist/tests/templates/entities/types/enum-template.spec.js +42 -42
  39. package/dist/tests/templates/entities/types/float-template.spec.js +37 -34
  40. package/dist/tests/templates/entities/types/geometry-template.spec.js +31 -31
  41. package/dist/tests/templates/entities/types/inet-template.spec.js +36 -36
  42. package/dist/tests/templates/entities/types/int4range-template.spec.js +45 -33
  43. package/dist/tests/templates/entities/types/integer-template.spec.js +40 -40
  44. package/dist/tests/templates/entities/types/interval-template.spec.js +35 -35
  45. package/dist/tests/templates/entities/types/json-plain-template.spec.js +27 -27
  46. package/dist/tests/templates/entities/types/json-template.spec.js +19 -19
  47. package/dist/tests/templates/entities/types/jsonb-template.spec.js +19 -19
  48. package/dist/tests/templates/entities/types/money-template.spec.js +35 -35
  49. package/dist/tests/templates/entities/types/numeric-template.spec.js +44 -44
  50. package/dist/tests/templates/entities/types/point-template.spec.js +37 -31
  51. package/dist/tests/templates/entities/types/polygon-template.spec.js +43 -31
  52. package/dist/tests/templates/entities/types/real-template.spec.js +34 -34
  53. package/dist/tests/templates/entities/types/serial-template.spec.js +62 -62
  54. package/dist/tests/templates/entities/types/smallint-template.spec.js +43 -43
  55. package/dist/tests/templates/entities/types/string-template.spec.js +59 -59
  56. package/dist/tests/templates/entities/types/text-template.spec.js +37 -37
  57. package/dist/tests/templates/entities/types/time-template.spec.js +35 -35
  58. package/dist/tests/templates/entities/types/timestamp-template.spec.js +39 -39
  59. package/dist/tests/templates/entities/types/timetz-template.spec.js +35 -35
  60. package/dist/tests/templates/entities/types/tsvector-template.spec.js +28 -28
  61. package/dist/tests/templates/entities/types/uuid-template.spec.js +43 -43
  62. package/dist/tests/templates/entities/types/varchar-template.spec.js +59 -56
  63. package/dist/tests/templates/entities/types/xml-template.spec.js +28 -28
  64. package/dist/tests/templates/entities/utils/template-test-utils.d.ts +1 -1
  65. package/dist/tests/templates/entities/utils/template-test-utils.js +3 -3
  66. package/dist/tests/templates/entities/uuid-entity-template.spec.js +138 -138
  67. package/dist/tests/utils/relationship-deduplication.spec.js +11 -11
  68. package/oclif.manifest.json +1 -1
  69. package/package.json +1 -1
@@ -13,8 +13,27 @@ const casing_1 = require("../casing");
13
13
  */
14
14
  const parseOneToMany = (relationship) => {
15
15
  return {
16
- [relationship.from]: [{ name: relationship.to, type: "OneToMany", biDirectional: true, referenceName: relationship.to_name || relationship.to, inverseReferenceName: relationship.from }],
17
- [relationship.to]: [{ name: relationship.from, type: "ManyToOne", nullable: relationship.nullable || false, biDirectional: true, index: relationship.index || false, cascadeDelete: relationship.cascadeDelete || false, referenceName: relationship.from, inverseReferenceName: relationship.to_name || relationship.to }],
16
+ [relationship.from]: [
17
+ {
18
+ name: relationship.to,
19
+ type: "OneToMany",
20
+ biDirectional: true,
21
+ referenceName: relationship.to_name || relationship.to,
22
+ inverseReferenceName: relationship.from,
23
+ },
24
+ ],
25
+ [relationship.to]: [
26
+ {
27
+ name: relationship.from,
28
+ type: "ManyToOne",
29
+ nullable: relationship.nullable || false,
30
+ biDirectional: true,
31
+ index: relationship.index || false,
32
+ cascadeDelete: relationship.cascadeDelete || false,
33
+ referenceName: relationship.from,
34
+ inverseReferenceName: relationship.to_name || relationship.to,
35
+ },
36
+ ],
18
37
  };
19
38
  };
20
39
  exports.parseOneToMany = parseOneToMany;
@@ -51,9 +70,9 @@ exports.parseManytoOne = parseManytoOne;
51
70
  */
52
71
  const parseManyToMany = (relationship, allRelationships) => {
53
72
  // Find the inverse relationship definition (if exists)
54
- const inverseDefinition = allRelationships.find(def => def.from === relationship.to &&
73
+ const inverseDefinition = allRelationships.find((def) => def.from === relationship.to &&
55
74
  def.to === relationship.from &&
56
- def.type === 'ManyToMany');
75
+ def.type === "ManyToMany");
57
76
  // Determine if the relationship should be treated as bidirectional
58
77
  const isEffectivelyBiDirectional = Boolean(relationship.bi_directional || (inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.bi_directional));
59
78
  // For self-referencing relationships, find the matching inverse by to_name
@@ -61,19 +80,22 @@ const parseManyToMany = (relationship, allRelationships) => {
61
80
  let selfRefInverse = null;
62
81
  if (isSelfReferencing && relationship.bi_directional) {
63
82
  // Find the other relationship that completes the pair
64
- selfRefInverse = allRelationships.find(def => def.from === relationship.from &&
83
+ selfRefInverse = allRelationships.find((def) => def.from === relationship.from &&
65
84
  def.to === relationship.to &&
66
- def.type === 'ManyToMany' &&
85
+ def.type === "ManyToMany" &&
67
86
  def.bi_directional &&
68
87
  def.to_name !== relationship.to_name);
69
88
  }
70
- let isOwningSide = relationship.joinTableName || relationship.joinColumnName || relationship.inverseJoinColumnName
89
+ let isOwningSide = relationship.joinTableName ||
90
+ relationship.joinColumnName ||
91
+ relationship.inverseJoinColumnName
71
92
  ? true
72
93
  : undefined;
73
94
  if (isOwningSide === undefined && inverseDefinition) {
74
95
  // If current doesn't have details, check if inverse does
75
- isOwningSide =
76
- !(inverseDefinition.joinTableName || inverseDefinition.joinColumnName || inverseDefinition.inverseJoinColumnName);
96
+ isOwningSide = !(inverseDefinition.joinTableName ||
97
+ inverseDefinition.joinColumnName ||
98
+ inverseDefinition.inverseJoinColumnName);
77
99
  }
78
100
  if (isOwningSide === undefined) {
79
101
  // If neither has details, default to the current definition being the owner
@@ -113,10 +135,18 @@ const parseManyToMany = (relationship, allRelationships) => {
113
135
  referenceName: fromSideRefName,
114
136
  join: isOwningSide,
115
137
  biDirectional: isEffectivelyBiDirectional,
116
- joinTableName: isOwningSide ? (relationship.joinTableName || undefined) : undefined,
117
- joinColumnName: isOwningSide ? (relationship.joinColumnName || undefined) : undefined,
118
- inverseJoinColumnName: isOwningSide ? (relationship.inverseJoinColumnName || undefined) : undefined,
119
- inverseReferenceName: isEffectivelyBiDirectional ? toSideRefName : undefined, // Only add inverse name if bidirectional
138
+ joinTableName: isOwningSide
139
+ ? relationship.joinTableName || undefined
140
+ : undefined,
141
+ joinColumnName: isOwningSide
142
+ ? relationship.joinColumnName || undefined
143
+ : undefined,
144
+ inverseJoinColumnName: isOwningSide
145
+ ? relationship.inverseJoinColumnName || undefined
146
+ : undefined,
147
+ inverseReferenceName: isEffectivelyBiDirectional
148
+ ? toSideRefName
149
+ : undefined, // Only add inverse name if bidirectional
120
150
  };
121
151
  const response = {
122
152
  [relationship.from]: [fromSideRelationship],
@@ -135,14 +165,20 @@ const parseManyToMany = (relationship, allRelationships) => {
135
165
  join: isInverseOwningSide,
136
166
  biDirectional: true,
137
167
  // Add join details ONLY if the inverse side IS the owner
138
- joinTableName: isInverseOwningSide ? ((inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.joinTableName) || undefined) : undefined,
139
- joinColumnName: isInverseOwningSide ? ((inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.joinColumnName) || undefined) : undefined,
140
- inverseJoinColumnName: isInverseOwningSide ? ((inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.inverseJoinColumnName) || undefined) : undefined,
168
+ joinTableName: isInverseOwningSide
169
+ ? (inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.joinTableName) || undefined
170
+ : undefined,
171
+ joinColumnName: isInverseOwningSide
172
+ ? (inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.joinColumnName) || undefined
173
+ : undefined,
174
+ inverseJoinColumnName: isInverseOwningSide
175
+ ? (inverseDefinition === null || inverseDefinition === void 0 ? void 0 : inverseDefinition.inverseJoinColumnName) || undefined
176
+ : undefined,
141
177
  inverseReferenceName: fromSideRefName, // The reference name of the other side
142
178
  };
143
179
  response[relationship.to] = [
144
180
  ...(response[relationship.to] || []),
145
- toSideRelationship
181
+ toSideRelationship,
146
182
  ];
147
183
  }
148
184
  return response;
@@ -205,13 +241,40 @@ const parseRelationship = (relationship, allRelationships) => {
205
241
  const fromSideRefName = relationship.to_name || relationship.to;
206
242
  const toSideRefName = relationship.from;
207
243
  return {
208
- [relationship.from]: [{ name: relationship.to, type: "OneToMany", biDirectional: true, referenceName: fromSideRefName, inverseReferenceName: toSideRefName }],
209
- [relationship.to]: [{ name: relationship.from, type: "ManyToOne", nullable: relationship.nullable || false, biDirectional: true, index: relationship.index || false, cascadeDelete: relationship.cascadeDelete || false, referenceName: toSideRefName, inverseReferenceName: fromSideRefName }],
244
+ [relationship.from]: [
245
+ {
246
+ name: relationship.to,
247
+ type: "OneToMany",
248
+ biDirectional: true,
249
+ referenceName: fromSideRefName,
250
+ inverseReferenceName: toSideRefName,
251
+ },
252
+ ],
253
+ [relationship.to]: [
254
+ {
255
+ name: relationship.from,
256
+ type: "ManyToOne",
257
+ nullable: relationship.nullable || false,
258
+ biDirectional: true,
259
+ index: relationship.index || false,
260
+ cascadeDelete: relationship.cascadeDelete || false,
261
+ referenceName: toSideRefName,
262
+ inverseReferenceName: fromSideRefName,
263
+ },
264
+ ],
210
265
  };
211
266
  }
212
267
  case "ManyToOne":
213
268
  return {
214
- [relationship.from]: [{ name: relationship.to, type: "ManyToOne", referenceName: relationship.to_name || relationship.to, nullable: relationship.nullable || false, index: relationship.index || false }],
269
+ [relationship.from]: [
270
+ {
271
+ name: relationship.to,
272
+ type: "ManyToOne",
273
+ referenceName: relationship.to_name || relationship.to,
274
+ nullable: relationship.nullable || false,
275
+ index: relationship.index || false,
276
+ },
277
+ ],
215
278
  };
216
279
  case "OneToOne": {
217
280
  const inverseOnetoOneDef = allRelationships.find((def) => def.from === relationship.to &&
@@ -243,7 +306,7 @@ const parseRelationship = (relationship, allRelationships) => {
243
306
  biDirectional: true,
244
307
  join: !(fromRel.join || false),
245
308
  referenceName: relationship.from,
246
- inverseReferenceName: fromRel.referenceName || undefined // Reference the 'from' side's name, default to undefined if null
309
+ inverseReferenceName: fromRel.referenceName || undefined, // Reference the 'from' side's name, default to undefined if null
247
310
  };
248
311
  responseMap[relationship.to] = [
249
312
  ...(responseMap[relationship.to] || []),
@@ -300,7 +363,7 @@ exports.getRelationshipIdField = getRelationshipIdField;
300
363
  */
301
364
  const calculateInversePropertyName = (relationship, entityName, relationshipName, needsPluralInverse) => {
302
365
  const isSelfReferencing = relationship.name === entityName;
303
- if (isSelfReferencing && relationship.type === 'ManyToMany') {
366
+ if (isSelfReferencing && relationship.type === "ManyToMany") {
304
367
  if (relationship.inverseReferenceName) {
305
368
  return (0, casing_1.camelCase)(relationship.inverseReferenceName);
306
369
  }
@@ -314,9 +377,25 @@ const calculateInversePropertyName = (relationship, entityName, relationshipName
314
377
  }
315
378
  // Check for special plural terms
316
379
  const specialPlurals = [
317
- 'children', 'people', 'men', 'women', 'mice', 'geese', 'teeth', 'feet',
318
- 'oxen', 'cacti', 'indices', 'vertices', 'analyses', 'crises', 'diagnoses',
319
- 'media', 'criteria', 'data', 'parents'
380
+ "children",
381
+ "people",
382
+ "men",
383
+ "women",
384
+ "mice",
385
+ "geese",
386
+ "teeth",
387
+ "feet",
388
+ "oxen",
389
+ "cacti",
390
+ "indices",
391
+ "vertices",
392
+ "analyses",
393
+ "crises",
394
+ "diagnoses",
395
+ "media",
396
+ "criteria",
397
+ "data",
398
+ "parents",
320
399
  ];
321
400
  if (specialPlurals.includes(relationship.inverseReferenceName)) {
322
401
  return relationship.inverseReferenceName;
@@ -341,7 +420,7 @@ const getRelationshipForTemplate = (entityName, relationships, entities) => {
341
420
  // Create entity map for looking up primary key types
342
421
  const entityMap = new Map();
343
422
  if (entities) {
344
- entities.forEach(entity => {
423
+ entities.forEach((entity) => {
345
424
  entityMap.set(entity.name, entity);
346
425
  });
347
426
  }
@@ -353,7 +432,8 @@ const getRelationshipForTemplate = (entityName, relationships, entities) => {
353
432
  const refName = relationship.referenceName || "default";
354
433
  const key = `${name}:${refName}`;
355
434
  // Use the relationship with join=true if there are duplicates (this is the owning side)
356
- if (!processedRefs.has(key) || (relationship.join && !((_a = processedRefs.get(key)) === null || _a === void 0 ? void 0 : _a.join))) {
435
+ if (!processedRefs.has(key) ||
436
+ (relationship.join && !((_a = processedRefs.get(key)) === null || _a === void 0 ? void 0 : _a.join))) {
357
437
  processedRefs.set(key, relationship);
358
438
  }
359
439
  });
@@ -361,7 +441,7 @@ const getRelationshipForTemplate = (entityName, relationships, entities) => {
361
441
  return [...processedRefs.values()].map((relationship) => {
362
442
  const thisReferenceName = relationship.referenceName;
363
443
  const relationshipName = (0, casing_1.camelCase)(thisReferenceName || relationship.name);
364
- const needsPluralInverse = relationship.type === 'ManyToOne' || relationship.type === 'ManyToMany';
444
+ const needsPluralInverse = relationship.type === "ManyToOne" || relationship.type === "ManyToMany";
365
445
  // DEBUG LOGGING
366
446
  // if (process.env.DEBUG) {
367
447
  // console.log(
@@ -373,13 +453,16 @@ const getRelationshipForTemplate = (entityName, relationships, entities) => {
373
453
  // );
374
454
  // }
375
455
  const inverseSidePropertyName = calculateInversePropertyName(relationship, entityName, relationshipName, needsPluralInverse);
376
- if (relationship.biDirectional && !relationship.inverseReferenceName &&
377
- (relationship.type === 'ManyToMany' || relationship.type === 'OneToMany' || relationship.type === 'OneToOne')) {
456
+ if (relationship.biDirectional &&
457
+ !relationship.inverseReferenceName &&
458
+ (relationship.type === "ManyToMany" ||
459
+ relationship.type === "OneToMany" ||
460
+ relationship.type === "OneToOne")) {
378
461
  console.info(`[APSO INFO] Using default property name '${inverseSidePropertyName}' for ${relationship.name}->${entityName}. To customize, add 'to_name' in your relationship definition.`);
379
462
  }
380
463
  // Look up the referenced entity's primary key type
381
464
  const referencedEntity = entityMap.get(relationship.name);
382
- const referencedEntityPrimaryKeyType = (referencedEntity === null || referencedEntity === void 0 ? void 0 : referencedEntity.primaryKeyType) || 'serial'; // Default to 'serial' if not specified
465
+ const referencedEntityPrimaryKeyType = (referencedEntity === null || referencedEntity === void 0 ? void 0 : referencedEntity.primaryKeyType) || "serial"; // Default to 'serial' if not specified
383
466
  return {
384
467
  ...relationship,
385
468
  relationshipName,
@@ -477,7 +560,9 @@ function* generateNestedRelationships(entityName, relationshipMap, maxDepth = 4,
477
560
  exports.generateNestedRelationships = generateNestedRelationships;
478
561
  // In-memory collector
479
562
  function getNestedRelationships(entityName, relationshipMap, maxDepth) {
480
- return [...generateNestedRelationships(entityName, relationshipMap, maxDepth)];
563
+ return [
564
+ ...generateNestedRelationships(entityName, relationshipMap, maxDepth),
565
+ ];
481
566
  }
482
567
  exports.getNestedRelationships = getNestedRelationships;
483
568
  // Streaming function