@postxl/generator 0.67.0 → 0.69.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 (28) hide show
  1. package/dist/generator.js +0 -10
  2. package/dist/generators/indices/dataservice.generator.js +1 -1
  3. package/dist/generators/indices/dispatcher-service.generator.js +1 -1
  4. package/dist/generators/indices/importexport-convert-import-functions.generator.js +1 -23
  5. package/dist/generators/indices/importexport-exporter-class.generator.js +1 -1
  6. package/dist/generators/indices/importexport-import-service.generator.js +1 -1
  7. package/dist/generators/models/businesslogic-update.generator.js +12 -25
  8. package/dist/generators/models/businesslogic-view.generator.js +30 -2
  9. package/dist/generators/models/importexport-decoder.generator.js +10 -15
  10. package/dist/generators/models/react.generator/context.generator.js +1 -1
  11. package/dist/generators/models/repository.generator.d.ts +0 -7
  12. package/dist/generators/models/repository.generator.js +274 -656
  13. package/dist/generators/models/route.generator.js +11 -8
  14. package/dist/lib/attributes.d.ts +0 -5
  15. package/dist/lib/meta.d.ts +21 -69
  16. package/dist/lib/meta.js +6 -27
  17. package/dist/lib/schema/types.d.ts +8 -1
  18. package/dist/lib/schema/types.js +3 -1
  19. package/dist/prisma/attributes.js +0 -2
  20. package/package.json +1 -1
  21. package/dist/generators/indices/datamock-module.generator.d.ts +0 -9
  22. package/dist/generators/indices/datamock-module.generator.js +0 -64
  23. package/dist/generators/indices/datamocker.generator.d.ts +0 -9
  24. package/dist/generators/indices/datamocker.generator.js +0 -88
  25. package/dist/generators/indices/emptydatabasemigration.generator.d.ts +0 -11
  26. package/dist/generators/indices/emptydatabasemigration.generator.js +0 -34
  27. package/dist/generators/indices/testdata-service.generator.d.ts +0 -9
  28. package/dist/generators/indices/testdata-service.generator.js +0 -84
package/dist/generator.js CHANGED
@@ -47,12 +47,9 @@ const businesslogic_update_service_generator_1 = require("./generators/indices/b
47
47
  const businesslogic_view_module_generator_1 = require("./generators/indices/businesslogic-view-module.generator");
48
48
  const businesslogic_view_service_generator_1 = require("./generators/indices/businesslogic-view-service.generator");
49
49
  const data_types_generator_1 = require("./generators/indices/data-types.generator");
50
- const datamock_module_generator_1 = require("./generators/indices/datamock-module.generator");
51
- const datamocker_generator_1 = require("./generators/indices/datamocker.generator");
52
50
  const datamodule_generator_1 = require("./generators/indices/datamodule.generator");
53
51
  const dataservice_generator_1 = require("./generators/indices/dataservice.generator");
54
52
  const dispatcher_service_generator_1 = require("./generators/indices/dispatcher-service.generator");
55
- const emptydatabasemigration_generator_1 = require("./generators/indices/emptydatabasemigration.generator");
56
53
  const importexport_convert_import_functions_generator_1 = require("./generators/indices/importexport-convert-import-functions.generator");
57
54
  const importexport_exporter_class_generator_1 = require("./generators/indices/importexport-exporter-class.generator");
58
55
  const importexport_import_service_generator_1 = require("./generators/indices/importexport-import-service.generator");
@@ -61,7 +58,6 @@ const repositories_generator_1 = require("./generators/indices/repositories.gene
61
58
  const routes_index_generator_1 = require("./generators/indices/routes-index.generator");
62
59
  const seed_migration_generator_1 = require("./generators/indices/seed-migration.generator");
63
60
  const seed_template_generator_1 = require("./generators/indices/seed-template.generator");
64
- const testdata_service_generator_1 = require("./generators/indices/testdata-service.generator");
65
61
  const testids_generator_1 = require("./generators/indices/testids.generator");
66
62
  const types_generator_2 = require("./generators/indices/types.generator");
67
63
  const admin_page_generator_1 = require("./generators/models/admin.page.generator");
@@ -175,8 +171,6 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
175
171
  // Data
176
172
  generated.write(`/${meta.data.stubLocation.path}.ts`, (0, stub_generator_1.generateStub)({ model, meta }));
177
173
  generated.write(`/${meta.data.repository.location.path}.ts`, (0, repository_generator_1.generateRepository)({ model, meta }));
178
- generated.write(`/${meta.data.mockRepository.location.path}.ts`, (0, repository_generator_1.generateMockRepository)({ model, meta }));
179
- generated.write(`/${meta.e2e.stubLocation.path}.ts`, (0, stub_generator_1.generateStub)({ model, meta }));
180
174
  // Import-Export
181
175
  generated.write(`/${meta.importExport.decoder.filePath}.ts`, (0, importexport_decoder_generator_1.generateModelImportExportDecoder)({ model, meta, schemaMeta: (0, meta_1.getSchemaMetadata)({ config }) }));
182
176
  // Business Logic
@@ -199,12 +193,8 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
199
193
  // Generate Index Files and Services
200
194
  const meta = (0, meta_1.getSchemaMetadata)({ config });
201
195
  // Data
202
- generated.write(`/${meta.data.mockModule.location.path}.ts`, (0, datamock_module_generator_1.generateDataMockModule)({ models, meta }));
203
196
  generated.write(`/${meta.data.moduleLocation.path}.ts`, (0, datamodule_generator_1.generateDataModule)({ models, meta }));
204
- generated.write(`/${meta.data.emptyDbCommandFilePath}.ts`, (0, emptydatabasemigration_generator_1.generateEmptyDatabaseCommand)({ models, meta }));
205
197
  generated.write(`/${meta.data.dataService.location.path}.ts`, (0, dataservice_generator_1.generateDataService)({ models, meta }));
206
- generated.write(`/${meta.data.testDataServiceFilePath}.ts`, (0, testdata_service_generator_1.generateTestDataService)({ models, meta }));
207
- generated.write(`/${meta.e2e.dataMockerLocation.path}.ts`, (0, datamocker_generator_1.generateDataMocker)({ models, meta }));
208
198
  generated.write(`/${meta.e2e.testIdsFilePath}.ts`, (0, testids_generator_1.generateTestIds)());
209
199
  generated.write(`/${meta.data.repository.constFilePath}.ts`, (0, repositories_generator_1.generateRepositoriesArray)({ models, meta }));
210
200
  generated.write(`/${meta.data.types.location.path}.ts`, (0, data_types_generator_1.generateDataTypes)({ models, meta }));
@@ -45,7 +45,7 @@ function generateDataService({ models, meta }) {
45
45
  return /* ts */ `
46
46
  import { Injectable, Logger } from '@nestjs/common'
47
47
 
48
- import { format, mapValues, pluralize } from '@backend/common'
48
+ import { format, mapValues, pluralize } from '@postxl/runtime'
49
49
 
50
50
  ${imports.generate()}
51
51
 
@@ -24,7 +24,7 @@ function generateActionsDispatcherService({ models, meta }) {
24
24
  return /* ts */ `
25
25
  import { Injectable } from '@nestjs/common'
26
26
 
27
- import { ExhaustiveSwitchCheck } from '@backend/common'
27
+ import { ExhaustiveSwitchCheck } from '@postxl/runtime'
28
28
 
29
29
  ${imports.generate()}
30
30
 
@@ -22,7 +22,6 @@ function generateImportExportConvertImportFunctions({ models, meta, }) {
22
22
  (0, types_1.toAnnotatedTypeName)(meta.data.types.bulkMutation),
23
23
  (0, types_1.toAnnotatedTypeName)(meta.data.types.bulkMutationForModel),
24
24
  ],
25
- [meta.data.mockModule.location.import]: [(0, types_1.toAnnotatedTypeName)(meta.data.dataMockDataType)],
26
25
  [meta.types.importPath]: [(0, types_1.toAnnotatedTypeName)(dto.genericModel), (0, types_1.toAnnotatedTypeName)(dto.idType)],
27
26
  [types.location.path]: [(0, types_1.toAnnotatedTypeName)(types.delta), (0, types_1.toAnnotatedTypeName)(types.delta_Model.type)],
28
27
  });
@@ -42,7 +41,7 @@ function generateImportExportConvertImportFunctions({ models, meta, }) {
42
41
  // logState({ state, nextStep, lastStep: 'updateModelState' })
43
42
  }
44
43
  return /* ts */ `
45
- import { ExhaustiveSwitchCheck } from '@backend/common'
44
+ import { ExhaustiveSwitchCheck } from '@postxl/runtime'
46
45
  ${imports.generate()}
47
46
 
48
47
  /**
@@ -120,8 +119,6 @@ function deltaModelTo${meta.data.types.bulkMutation}<
120
119
 
121
120
  return _removeBlank${meta.data.types.bulkMutation}(result)
122
121
  }
123
-
124
- ${generateMockDataToBulkFunction({ models, meta })}
125
122
  `;
126
123
  }
127
124
  exports.generateImportExportConvertImportFunctions = generateImportExportConvertImportFunctions;
@@ -512,22 +509,3 @@ function generateFieldAssignmentBlocks({ fieldsGrouped, }) {
512
509
  }
513
510
  return result;
514
511
  }
515
- function generateMockDataToBulkFunction({ models, meta }) {
516
- const mockConverters = [];
517
- for (const model of models) {
518
- const modelMeta = (0, meta_1.getModelMetadata)({ model });
519
- mockConverters.push(`${modelMeta.seed.constantName}: { create: data.${modelMeta.seed.constantName} }`);
520
- }
521
- return /* ts */ `
522
- /**
523
- * Converts MockData from the DataMocker to ${meta.data.types.bulkMutation}, so it can be
524
- * imported during the E2E seed process.
525
- */
526
- export function ${meta.importExport.converterFunctions.mockDataToBulkMutations}(
527
- data: ${meta.data.dataMockDataType}
528
- ): ${meta.data.types.bulkMutation} {
529
- return {
530
- ${mockConverters.join(',\n')}
531
- }
532
- }`;
533
- }
@@ -95,7 +95,7 @@ function generateImportExportExporterClass({ models, meta }) {
95
95
 
96
96
  import { Logger } from '@nestjs/common'
97
97
 
98
- import { mapValues } from '@backend/common'
98
+ import { mapValues } from '@postxl/runtime'
99
99
  ${imports.generate()}
100
100
 
101
101
  /**
@@ -46,7 +46,7 @@ function generateImportExportImportService({ models, meta }) {
46
46
  }
47
47
  return /* ts */ `
48
48
  import { Injectable } from '@nestjs/common'
49
- import { ExhaustiveSwitchCheck } from '@backend/common'
49
+ import { ExhaustiveSwitchCheck } from '@postxl/runtime'
50
50
 
51
51
  ${imports.generate()}
52
52
 
@@ -42,12 +42,6 @@ function generateModelBusinessLogicUpdate({ model, meta }) {
42
42
  iExecution: schemaMeta.actions.execution.interface,
43
43
  typeName: meta.types.typeName,
44
44
  brandedId: model.brandedIdType,
45
- decoders: {
46
- name: meta.update.decoders.name,
47
- createType: `Create${meta.internalSingularNameCapitalized}`,
48
- updateType: `Update${meta.internalSingularNameCapitalized}`,
49
- upsertType: `Upsert${meta.internalSingularNameCapitalized}`,
50
- },
51
45
  };
52
46
  const imports = imports_1.ImportsGenerator.from(meta.update.serviceClassLocation.path);
53
47
  imports.addImports({
@@ -96,7 +90,6 @@ function generateModelBusinessLogicUpdate({ model, meta }) {
96
90
  `@Inject(forwardRef(() => ${schemaMeta.update.serviceClassName})) private readonly updateService: ${schemaMeta.update.serviceClassName}`,
97
91
  `@Inject(forwardRef(() => ${schemaMeta.view.serviceClassName})) private readonly viewService: ${schemaMeta.view.serviceClassName}`,
98
92
  ];
99
- const decoders = meta.update.decoders;
100
93
  const { view, update } = meta;
101
94
  const deleteFn = generateDeleteFn({ model, meta, m });
102
95
  const deleteManyFn = generateDeleteManyFn({ imports, model, meta, m });
@@ -113,19 +106,19 @@ function generateModelBusinessLogicUpdate({ model, meta }) {
113
106
  export type Actions = {
114
107
  ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} and returns it.`])}
115
108
  create: {
116
- payload: ${m.decoders.createType}
109
+ payload: CreatePayload
117
110
  result: ${m.typeName}
118
111
  }
119
112
 
120
113
  ${(0, jsdoc_1.toJsDocComment)([`Updates a ${meta.userFriendlyName} and returns it.`])}
121
114
  update: {
122
- payload: ${m.decoders.updateType}
115
+ payload: UpdatePayload
123
116
  result: ${m.typeName}
124
117
  }
125
118
 
126
119
  ${(0, jsdoc_1.toJsDocComment)([`Creates or updates a ${meta.userFriendlyName} and returns it.`])}
127
120
  upsert: {
128
- payload: ${m.decoders.upsertType}
121
+ payload: UpsertPayload
129
122
  result: ${m.typeName}
130
123
  }
131
124
 
@@ -139,40 +132,34 @@ function generateModelBusinessLogicUpdate({ model, meta }) {
139
132
  /**
140
133
  * Zod decoder for validating the create input of a ${meta.userFriendlyName}.
141
134
  */
142
- export const ${decoders.create} = z.object({
135
+ export const ${meta.update.createInputDecoder} = z.object({
143
136
  ${model.fields
144
137
  .filter((f) => !f.attributes.isReadonly)
145
138
  .map((f) => `${f.name}: z.${(0, zod_1.getZodDecoderDefinition)({ field: f })}`)
146
139
  .join(',')}
147
140
  })
148
141
 
149
- type ${m.decoders.createType} = z.infer<typeof ${decoders.create}>
142
+ type CreatePayload = z.infer<typeof ${meta.update.createInputDecoder}>
150
143
 
151
144
  /**
152
145
  * Zod decoder for validating the update input of a ${meta.userFriendlyName} .
153
146
  */
154
- export const ${decoders.update} = z.object({
147
+ export const ${meta.update.updateInputDecoder} = z.object({
155
148
  ${model.fields
156
149
  .filter((f) => !f.attributes.isReadonly || f.kind === 'id')
157
150
  .map((f) => `${f.name}: z.${(0, zod_1.getZodDecoderDefinition)({ field: f, allowAnyOptionalField: f.kind !== 'id' })}`)
158
151
  .join(',')}
159
152
  })
160
153
 
161
- type ${m.decoders.updateType} = z.infer<typeof ${decoders.update}>
154
+ type UpdatePayload = z.infer<typeof ${meta.update.updateInputDecoder}>
162
155
 
163
156
  /**
164
157
  * Zod decoder for validating the upsert input of a ${meta.userFriendlyName} .
165
158
  */
166
- export const ${decoders.upsert} = z.union([${decoders.update}, ${decoders.create}])
159
+ export const ${meta.update.upsertInputDecoder} = z.union([${meta.update.updateInputDecoder}, ${meta.update.createInputDecoder}])
167
160
 
168
- type ${m.decoders.upsertType} = z.infer<typeof ${decoders.upsert}>
161
+ type UpsertPayload = z.infer<typeof ${meta.update.upsertInputDecoder}>
169
162
 
170
- export const ${decoders.name} = {
171
- create: ${decoders.create},
172
- update: ${decoders.update},
173
- upsert: ${decoders.upsert},
174
- }
175
-
176
163
  export type ${update.serviceInterfaceName} = ${schemaMeta.actions.dispatcher.definition}<Actions>
177
164
 
178
165
  @Injectable()
@@ -188,17 +175,17 @@ function generateModelBusinessLogicUpdate({ model, meta }) {
188
175
  }
189
176
 
190
177
  ${(0, jsdoc_1.toJsDocComment)([`Creates a new ${meta.userFriendlyName} and returns it.`])}
191
- public async create({ data, execution }: { data: ${m.decoders.createType}; execution: ${m.iExecution} }): Promise<${m.typeName}> {
178
+ public async create({ data, execution }: { data: CreatePayload; execution: ${m.iExecution} }): Promise<${m.typeName}> {
192
179
  return this.data.create({ item: data, execution })
193
180
  }
194
181
 
195
182
  ${(0, jsdoc_1.toJsDocComment)([`Updates a ${meta.userFriendlyName} and returns it.`])}
196
- public async update({ data, execution }: { data: ${m.decoders.updateType}; execution: ${m.iExecution} }): Promise<${m.typeName}> {
183
+ public async update({ data, execution }: { data: UpdatePayload; execution: ${m.iExecution} }): Promise<${m.typeName}> {
197
184
  return this.data.update({ item: data, execution })
198
185
  }
199
186
 
200
187
  ${(0, jsdoc_1.toJsDocComment)([`Creates or updates a ${meta.userFriendlyName} and returns it.`])}
201
- public async upsert({ data, execution }: { data: ${m.decoders.upsertType}; execution: ${m.iExecution} }): Promise<${m.typeName}> {
188
+ public async upsert({ data, execution }: { data: UpsertPayload; execution: ${m.iExecution} }): Promise<${m.typeName}> {
202
189
  return this.data.upsert({ item: data, execution })
203
190
  }
204
191
 
@@ -113,13 +113,41 @@ function generateModelBusinessLogicView({ model, meta }) {
113
113
  `;
114
114
  return /* ts */ `
115
115
  /* eslint-disable @typescript-eslint/no-unused-vars */
116
+ import z from 'zod'
117
+
116
118
  import { Inject, Injectable, forwardRef } from '@nestjs/common'
117
- import { FilterOperator } from '@backend/common'
118
119
 
119
120
  ${imports.generate()}
120
121
 
121
122
  ${hasLinkedItems ? linkedTypeDefinition : ''}
122
123
 
124
+ /**
125
+ * Cursor decoder.
126
+ */
127
+ export const ${meta.view.cursorDecoder} = z.object({ startRow: z.number(), endRow: z.number() })
128
+
129
+ type Cursor = z.infer<typeof ${meta.view.cursorDecoder}>
130
+
131
+ /**
132
+ * Filter operator decoder.
133
+ */
134
+ export const ${meta.view.filterOperatorDecoder} = z.enum([
135
+ 'eq',
136
+ 'neq',
137
+ 'gt',
138
+ 'gte',
139
+ 'lt',
140
+ 'lte',
141
+ 'in',
142
+ 'nin',
143
+ 'contains',
144
+ 'ncontains',
145
+ 'starts',
146
+ 'ends',
147
+ ])
148
+
149
+ type FilterOperator = z.infer<typeof ${meta.view.filterOperatorDecoder}>
150
+
123
151
  @Injectable()
124
152
  export class ${meta.view.serviceClassName} {
125
153
  constructor(${constructorParameters.join(',\n')}) {}
@@ -151,7 +179,7 @@ export class ${meta.view.serviceClassName} {
151
179
  }: {
152
180
  filter?: { field: keyof ${model.typeName}; operator: FilterOperator; value: string | number }
153
181
  sort?: { field: keyof ${model.typeName}; ascending: boolean }
154
- cursor?: { startRow: number; endRow: number }
182
+ cursor?: Cursor
155
183
  }) {
156
184
  const items = await this.${modelRepositoryVariableName}.getAllAsArray()
157
185
  const filtered = !filter
@@ -10,19 +10,17 @@ const types_2 = require("../../lib/types");
10
10
  */
11
11
  function generateModelImportExportDecoder({ model, meta, schemaMeta, }) {
12
12
  const { filePath: decoderFilePath, itemEncoderFunctionName: rowExportFunctionName, encodedExcelType: excelType, arrayEncoderFunctionName: tableExportFunctionName, tableDecoder: tableImportDecoder, } = meta.importExport.decoder;
13
- const imports = imports_1.ImportsGenerator.from(decoderFilePath);
14
- imports.addImports({
15
- [schemaMeta.backendModules.common.importPath]: [
16
- schemaMeta.backendModules.common.functions.uncapitalizeKeys,
17
- schemaMeta.backendModules.common.functions.capitalizeKeys,
18
- schemaMeta.backendModules.common.functions.nullOrBlankDecoder,
19
- ],
13
+ const imports = imports_1.ImportsGenerator.from(decoderFilePath).addImports({
14
+ [schemaMeta.backendModules.common.importPath]: [schemaMeta.backendModules.common.functions.excelNullOrBlankDecoder],
20
15
  [meta.types.importPath]: [(0, types_1.toAnnotatedTypeName)(meta.types.typeName)],
21
16
  });
22
17
  const { userFriendlyName: userFriendly, userFriendlyNamePlural: userFriendlyPlural, internalSingularName: singular, internalSingularNameCapitalized: singularCapitalized, } = meta;
23
18
  const { fieldDecoders, blankFieldDecoders } = generateFieldDecoders({ model, meta, schemaMeta, imports });
24
19
  return `
25
20
  import * as z from 'zod'
21
+
22
+ import { uncapitalizeKeys, capitalizeKeys } from '@postxl/runtime'
23
+
26
24
  ${imports.generate()}
27
25
 
28
26
  /**
@@ -80,7 +78,7 @@ function generateFieldDecoders({ model, meta, schemaMeta, imports, }) {
80
78
  for (const field of model.fields) {
81
79
  const fieldMeta = (0, meta_1.getFieldMetadata)({ field });
82
80
  const optionalModifier = field.attributes.isUpdatedAt || field.attributes.isCreatedAt ? '.optional()' : '';
83
- blankFieldDecoders.push(`${fieldMeta.excelColumnName}: nullOrBlankDecoder${optionalModifier}`);
81
+ blankFieldDecoders.push(`${fieldMeta.excelColumnName}: excelNullOrBlankDecoder${optionalModifier}`);
84
82
  switch (field.kind) {
85
83
  case 'id': {
86
84
  imports.addImport({ items: [meta.types.toBrandedIdTypeFnName], from: meta.types.importPath });
@@ -140,10 +138,7 @@ dbTypeName, nullable, imports, schemaMeta, }) {
140
138
  switch (tsTypeName) {
141
139
  case 'string': {
142
140
  const decoder = schemaMeta.backendModules.common.functions[nullable ? 'excelStringNullableDecoder' : 'excelStringDecoder'];
143
- imports.addImport({
144
- items: [decoder],
145
- from: schemaMeta.backendModules.common.importPath,
146
- });
141
+ imports.addImport({ items: [decoder], from: schemaMeta.backendModules.common.importPath });
147
142
  return decoder;
148
143
  }
149
144
  case 'boolean':
@@ -192,9 +187,6 @@ dbTypeName, nullable, imports, schemaMeta, }) {
192
187
  function generateImportExportDecoder({ models, meta }) {
193
188
  const { decodedPXLModelDataTypeName, encodedExcelDataTypeName, fullDecoderName, fullEncoderFunctionName } = meta.importExport.decoder;
194
189
  const imports = imports_1.ImportsGenerator.from(meta.importExport.decoder.location.path);
195
- imports.addImports({
196
- [meta.backendModules.common.importPath]: (0, types_1.toFunctionName)('uncapitalizeKeys'),
197
- });
198
190
  const importTypes = [];
199
191
  const decoderEntries = [];
200
192
  const exportFields = [];
@@ -217,6 +209,9 @@ function generateImportExportDecoder({ models, meta }) {
217
209
  }
218
210
  return `
219
211
  import * as z from 'zod'
212
+
213
+ import { uncapitalizeKeys } from '@postxl/runtime'
214
+
220
215
  ${imports.generate()}
221
216
 
222
217
  export type ${encodedExcelDataTypeName} = {
@@ -18,7 +18,7 @@ function generateModelContext({ model, meta }) {
18
18
  import React, { useMemo } from 'react'
19
19
 
20
20
  import { trpc } from '@lib/trpc'
21
- import { filterMap, mapMap } from '@lib/utils'
21
+ import { filterMap, mapMap } from '@postxl/runtime'
22
22
 
23
23
  ${imports.generate()}
24
24
 
@@ -7,13 +7,6 @@ export declare function generateRepository({ model, meta }: {
7
7
  model: Model;
8
8
  meta: ModelMetaData;
9
9
  }): string;
10
- /**
11
- * Generates a mock repository data structure for a given model: same a repository, but in memory only.
12
- */
13
- export declare function generateMockRepository({ model: modelSource, meta: metaSource, }: {
14
- model: Model;
15
- meta: ModelMetaData;
16
- }): string;
17
10
  type FnSignature = {
18
11
  /**
19
12
  * A list of ordered TypeScript types where the first type in the list corresponds to the type of the