@postxl/generator 0.15.6 → 0.15.7

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.
@@ -33,72 +33,90 @@ const Types = __importStar(require("../../lib/schema/types"));
33
33
  */
34
34
  function generateModelBusinessLogic({ model, meta }) {
35
35
  const imports = imports_1.ImportsGenerator.from(meta.businessLogic.serviceFilePath);
36
- const dependencies = new Map();
37
36
  imports.addImport({ from: meta.data.importPath, items: [meta.data.repositoryClassName] });
38
37
  imports.addImport({ from: meta.types.importPath, items: [model.brandedIdType, meta.types.typeName] });
39
38
  /**
40
- * Set of repositories (one for each referenced model) to be injected into the constructor.
39
+ * The name of the variable that holds the repository instance for the current model
40
+ * (e.g. when we generate business logic service for Aggregation, the AggregationRepository
41
+ * would be referenced using `this.data` variable).
42
+ */
43
+ const modelRepositoryVariableName = Types.toVariableName('data');
44
+ /**
45
+ * A map of referenced models indexed by the name of model's repository class.
46
+ */
47
+ const dependencies = new Map();
48
+ /**
49
+ * Variable names and their definitions indexed by the name of the relation they represent.
41
50
  */
42
- const dataRepositoryVariableName = Types.toVariableName('data');
43
- dependencies.set(meta.data.repositoryClassName, {
44
- repositoryClassName: meta.data.repositoryClassName,
45
- localRepositoryVariableName: dataRepositoryVariableName,
46
- });
47
- const linkedForeignBacklinkFields = new Map();
48
- // Converts each relationship to a variable that is pulled from the referenced model's repository - and validates
49
- // that it exists in case the relationship is required.
50
- // Variable definition and name of the variable is stored in a Map for each relationship - and is referenced in
51
- // the `getLinkedItem` function.
51
+ const variables = new Map();
52
52
  for (const relation of (0, fields_1.getRelationFields)(model)) {
53
53
  const refModel = relation.relationToModel;
54
54
  const refMeta = (0, meta_1.getModelMetadata)({ model: refModel });
55
55
  imports.addImport({ from: refMeta.data.importPath, items: [refMeta.data.repositoryClassName] });
56
- /**
57
- * Internal variable pointing to an instance of a referenced repository.
58
- */
59
- const repoReferenceName = relation.relationToModel.typeName !== model.typeName ? refMeta.internalPluralName : dataRepositoryVariableName;
60
- dependencies.set(refMeta.data.repositoryClassName, {
61
- localRepositoryVariableName: repoReferenceName,
62
- repositoryClassName: refMeta.data.repositoryClassName,
63
- });
64
- const variableDefinition = `
65
- const ${relation.relatedModelBacklinkFieldName} = this.${repoReferenceName}.get(itemRaw.${relation.name})
66
- ${!relation.isRequired
67
- ? ''
68
- : `if (!${relation.relatedModelBacklinkFieldName}) {
69
- throw new Error(\`Could not find ${refMeta.types.typeName} with id \${itemRaw.${relation.name}} for ${model.typeName}.${relation.name}!\`)
70
- }`}
71
- `;
72
- linkedForeignBacklinkFields.set(relation.name, {
73
- fieldName: relation.relatedModelBacklinkFieldName,
74
- variableDefinition,
75
- });
56
+ const variablePresenceCheck = `
57
+ if (!${relation.relatedModelBacklinkFieldName}) {
58
+ throw new Error(\`Could not find ${refMeta.types.typeName} with id \${itemRaw.${relation.name}} for ${model.typeName}.${relation.name}!\`)
59
+ }
60
+ `;
61
+ const relationVariableName = relation.relatedModelBacklinkFieldName;
62
+ if (relation.relationToModel.typeName === model.typeName) {
63
+ // NOTE: If the referenced model is a self-relation, we want to reuse the instance of the repository
64
+ // that is already injected into the constructor meaning that we don't need to set up a dependency and a local variable.
65
+ variables.set(relation.name, {
66
+ variableName: relationVariableName,
67
+ variableDefinition: `
68
+ const ${relationVariableName} = this.data.get(itemRaw.${relation.name})
69
+ ${relation.isRequired ? variablePresenceCheck : ``}
70
+ `,
71
+ });
72
+ }
73
+ else {
74
+ const refRepoVariableName = refMeta.internalPluralName;
75
+ dependencies.set(refMeta.data.repositoryClassName, {
76
+ localRepositoryVariableName: refRepoVariableName,
77
+ repositoryClassName: refMeta.data.repositoryClassName,
78
+ });
79
+ variables.set(relation.name, {
80
+ variableName: relationVariableName,
81
+ variableDefinition: `
82
+ const ${relationVariableName} = this.${refRepoVariableName}.get(itemRaw.${relation.name})
83
+ ${relation.isRequired ? variablePresenceCheck : ``}
84
+ `,
85
+ });
86
+ }
76
87
  }
77
- const hasLinkedItems = linkedForeignBacklinkFields.size > 0;
88
+ const hasLinkedItems = variables.size > 0;
78
89
  if (hasLinkedItems) {
79
90
  imports.addImport({ from: meta.types.importPath, items: [meta.types.linkedTypeName] });
80
91
  }
81
- const constructorParameters = [...dependencies.values()].map(({ localRepositoryVariableName, repositoryClassName }) => `private readonly ${localRepositoryVariableName}: ${repositoryClassName}`);
92
+ const constructorParameters = [`public readonly ${modelRepositoryVariableName}: ${meta.data.repositoryClassName}`];
93
+ for (const [, { localRepositoryVariableName, repositoryClassName }] of dependencies) {
94
+ constructorParameters.push(`private readonly ${localRepositoryVariableName}: ${repositoryClassName}`);
95
+ }
82
96
  const linkedItemsGetterFn = `
83
97
  /**
84
98
  * Returns the linked ${meta.userFriendlyName} with the given id or null if it does not exist.
85
99
  * Linked: The ${meta.userFriendlyName} contains the linked (raw) items themselves, not only the ids.
86
100
  */
87
101
  public getLinkedItem(id: ${model.brandedIdType}): ${meta.types.linkedTypeName} | null {
88
- const itemRaw = this.${dataRepositoryVariableName}.get(id)
89
- if (!itemRaw) return null
90
- ${[...linkedForeignBacklinkFields.values()].map(({ variableDefinition }) => variableDefinition).join('\n')}
102
+ const itemRaw = this.${modelRepositoryVariableName}.get(id)
103
+ if (!itemRaw) {
104
+ return null
105
+ }
106
+
107
+ ${[...variables.values()].map((r) => r.variableDefinition).join('\n')}
108
+
91
109
  const item: ${meta.types.linkedTypeName} = {
92
110
  ${model.fields
93
111
  .map((f) => {
94
112
  if (f.kind !== 'relation') {
95
113
  return `${f.name}: itemRaw.${f.name}`;
96
114
  }
97
- const linked = linkedForeignBacklinkFields.get(f.name);
98
- if (!linked) {
115
+ const linkedRel = variables.get(f.name);
116
+ if (!linkedRel) {
99
117
  throw new Error(`Could not find linked item for ${model.typeName}.${f.name}`);
100
118
  }
101
- return `${linked.fieldName}`;
119
+ return `${linkedRel.variableName}`;
102
120
  })
103
121
  .join(',\n')}
104
122
  }
@@ -119,7 +137,7 @@ export class ${meta.businessLogic.serviceClassName} {
119
137
  * Raw: The ${meta.userFriendlyName} only contains linked Ids, not the linked items themselves.
120
138
  */
121
139
  public get(id: ${model.brandedIdType}): ${meta.types.typeName} | null {
122
- return this.${dataRepositoryVariableName}.get(id)
140
+ return this.${modelRepositoryVariableName}.get(id)
123
141
  }
124
142
 
125
143
  ${hasLinkedItems ? linkedItemsGetterFn : ''}
@@ -128,14 +146,14 @@ export class ${meta.businessLogic.serviceClassName} {
128
146
  * Returns a map of all ${meta.userFriendlyName}s.
129
147
  */
130
148
  public getAll(): Map<${meta.types.brandedIdType}, ${model.typeName}> {
131
- return this.${dataRepositoryVariableName}.getAll()
149
+ return this.${modelRepositoryVariableName}.getAll()
132
150
  }
133
151
 
134
152
  /**
135
153
  * Creates a new ${meta.userFriendlyName}.
136
154
  */
137
155
  public async create(item: Omit<${model.typeName}, 'id'>): Promise<${model.typeName}> {
138
- return this.${dataRepositoryVariableName}.create(item)
156
+ return this.${modelRepositoryVariableName}.create(item)
139
157
  }
140
158
 
141
159
  /**
@@ -144,7 +162,7 @@ export class ${meta.businessLogic.serviceClassName} {
144
162
  public async update(item: Partial<${model.typeName}> & {
145
163
  id: ${model.brandedIdType}
146
164
  }): Promise<${model.typeName}> {
147
- return this.${dataRepositoryVariableName}.update(item)
165
+ return this.${modelRepositoryVariableName}.update(item)
148
166
  }
149
167
 
150
168
  /**
@@ -154,7 +172,7 @@ export class ${meta.businessLogic.serviceClassName} {
154
172
  * If the items is a dependency of another item, the deletion will fail!
155
173
  */
156
174
  public async delete(id: ${model.brandedIdType}): Promise<void> {
157
- return this.${dataRepositoryVariableName}.delete(id)
175
+ return this.${modelRepositoryVariableName}.delete(id)
158
176
  }
159
177
  }
160
178
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.15.6",
3
+ "version": "0.15.7",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {