@strapi/typescript-utils 4.3.2 → 4.3.5

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.
@@ -23,11 +23,11 @@ describe('Attributes', () => {
23
23
  const schema = { uid: 'api::foo.foo' };
24
24
  const attributeName = 'foo';
25
25
 
26
- const toPropertySignature = attribute => {
26
+ const toPropertySignature = (attribute) => {
27
27
  return attributeToPropertySignature(schema, attributeName, attribute);
28
28
  };
29
29
 
30
- const defaultAssertion = node => {
30
+ const defaultAssertion = (node) => {
31
31
  expect(node.kind).toBe(ts.SyntaxKind.PropertySignature);
32
32
  expect(node.name.escapedText).toBe(attributeName);
33
33
  expect(node.type.kind).toBe(ts.SyntaxKind.IntersectionType);
@@ -17,7 +17,7 @@ describe('Global', () => {
17
17
  jest.resetAllMocks();
18
18
  });
19
19
 
20
- const assertGlobalNodeStructure = node => {
20
+ const assertGlobalNodeStructure = (node) => {
21
21
  // "declare global"
22
22
  expect(node.kind).toBe(ts.SyntaxKind.ModuleDeclaration);
23
23
  expect(node.modifiers).toHaveLength(1);
@@ -3,7 +3,7 @@
3
3
  const path = require('path');
4
4
  const fs = require('fs-extra');
5
5
 
6
- module.exports = async dest => {
6
+ module.exports = async (dest) => {
7
7
  const tsConfig = {
8
8
  compilerOptions: {
9
9
  lib: ['es2019', 'es2020.promise', 'es2020.bigint', 'es2020.string', 'DOM'],
@@ -10,7 +10,7 @@ const resolveConfigOptions = require('../utils/resolve-config-options');
10
10
  * Prints a diagnostic every time the watch status changes.
11
11
  * This is mainly for messages like "Starting compilation" or "Compilation completed".
12
12
  */
13
- const reportWatchStatusChanged = diagnostic => {
13
+ const reportWatchStatusChanged = (diagnostic) => {
14
14
  console.info(ts.formatDiagnostic(diagnostic, formatHost));
15
15
  };
16
16
 
@@ -18,9 +18,9 @@ module.exports = {
18
18
  run(configPath) {
19
19
  const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
20
20
 
21
- const { fileNames, options, projectReferences, watchOptions } = resolveConfigOptions(
22
- configPath
23
- );
21
+ const { fileNames, options, projectReferences, watchOptions } =
22
+ resolveConfigOptions(configPath);
23
+
24
24
  const host = ts.createWatchCompilerHost(
25
25
  fileNames,
26
26
  options,
@@ -1,38 +1,11 @@
1
1
  'use strict';
2
2
 
3
- const ts = require('typescript');
4
3
  const { factory } = require('typescript');
5
4
  const _ = require('lodash/fp');
6
5
 
7
6
  const { addImport } = require('./imports');
8
7
  const { getTypeNode, toTypeLiteral } = require('./utils');
9
-
10
- /**
11
- * Generate a property signature node for a given attribute
12
- *
13
- * @param {object} schema
14
- * @param {string} attributeName
15
- * @param {object} attribute
16
- * @returns {object}
17
- */
18
- const attributeToPropertySignature = (schema, attributeName, attribute) => {
19
- const baseType = getAttributeType(attributeName, attribute, schema.uid);
20
-
21
- if (baseType === null) {
22
- return null;
23
- }
24
-
25
- const modifiers = getAttributeModifiers(attribute);
26
-
27
- const nodes = [baseType, ...modifiers];
28
-
29
- return factory.createPropertySignature(
30
- undefined,
31
- factory.createIdentifier(attributeName),
32
- undefined,
33
- factory.createIntersectionTypeNode(nodes)
34
- );
35
- };
8
+ const mappers = require('./mappers');
36
9
 
37
10
  /**
38
11
  * Create the base type node for a given attribute
@@ -64,7 +37,7 @@ const getAttributeType = (attributeName, attribute, uid) => {
64
37
  * @param {object} attribute
65
38
  * @returns {object[]}
66
39
  */
67
- const getAttributeModifiers = attribute => {
40
+ const getAttributeModifiers = (attribute) => {
68
41
  const modifiers = [];
69
42
 
70
43
  // Required
@@ -151,127 +124,31 @@ const getAttributeModifiers = attribute => {
151
124
  return modifiers;
152
125
  };
153
126
 
154
- const mappers = {
155
- string() {
156
- return ['StringAttribute'];
157
- },
158
- text() {
159
- return ['TextAttribute'];
160
- },
161
- richtext() {
162
- return ['RichTextAttribute'];
163
- },
164
- password() {
165
- return ['PasswordAttribute'];
166
- },
167
- email() {
168
- return ['EmailAttribute'];
169
- },
170
- date() {
171
- return ['DateAttribute'];
172
- },
173
- time() {
174
- return ['TimeAttribute'];
175
- },
176
- datetime() {
177
- return ['DateTimeAttribute'];
178
- },
179
- timestamp() {
180
- return ['TimestampAttribute'];
181
- },
182
- integer() {
183
- return ['IntegerAttribute'];
184
- },
185
- biginteger() {
186
- return ['BigIntegerAttribute'];
187
- },
188
- float() {
189
- return ['FloatAttribute'];
190
- },
191
- decimal() {
192
- return ['DecimalAttribute'];
193
- },
194
- uid({ attribute, uid }) {
195
- const { targetField, options } = attribute;
196
-
197
- // If there are no params to compute, then return the attribute type alone
198
- if (targetField === undefined && options === undefined) {
199
- return ['UIDAttribute'];
200
- }
201
-
202
- const params = [];
203
-
204
- // If the targetField property is defined, then reference it,
205
- // otherwise, put `undefined` keyword type nodes as placeholders
206
- const targetFieldParams = _.isUndefined(targetField)
207
- ? [
208
- factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
209
- factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
210
- ]
211
- : [factory.createStringLiteral(uid), factory.createStringLiteral(targetField)];
212
-
213
- params.push(...targetFieldParams);
214
-
215
- // If the options property is defined, transform it to
216
- // a type literral node and add it to the params list
217
- if (_.isObject(options)) {
218
- params.push(toTypeLiteral(options));
219
- }
220
-
221
- return ['UIDAttribute', params];
222
- },
223
- enumeration({ attribute }) {
224
- const { enum: enumValues } = attribute;
225
-
226
- return ['EnumerationAttribute', [toTypeLiteral(enumValues)]];
227
- },
228
- boolean() {
229
- return ['BooleanAttribute'];
230
- },
231
- json() {
232
- return ['JSONAttribute'];
233
- },
234
- media() {
235
- return ['MediaAttribute'];
236
- },
237
- relation({ uid, attribute }) {
238
- const { relation, target } = attribute;
239
-
240
- const isMorphRelation = relation.toLowerCase().includes('morph');
241
-
242
- if (isMorphRelation) {
243
- return [
244
- 'RelationAttribute',
245
- [factory.createStringLiteral(uid, true), factory.createStringLiteral(relation, true)],
246
- ];
247
- }
248
-
249
- return [
250
- 'RelationAttribute',
251
- [
252
- factory.createStringLiteral(uid, true),
253
- factory.createStringLiteral(relation, true),
254
- factory.createStringLiteral(target, true),
255
- ],
256
- ];
257
- },
258
- component({ attribute }) {
259
- const target = attribute.component;
260
- const params = [factory.createStringLiteral(target, true)];
261
-
262
- if (attribute.repeatable) {
263
- params.push(factory.createTrue());
264
- }
265
-
266
- return ['ComponentAttribute', params];
267
- },
268
- dynamiczone({ attribute }) {
269
- const componentsParam = factory.createTupleTypeNode(
270
- attribute.components.map(component => factory.createStringLiteral(component))
271
- );
127
+ /**
128
+ * Generate a property signature node for a given attribute
129
+ *
130
+ * @param {object} schema
131
+ * @param {string} attributeName
132
+ * @param {object} attribute
133
+ * @returns {object}
134
+ */
135
+ const attributeToPropertySignature = (schema, attributeName, attribute) => {
136
+ const baseType = getAttributeType(attributeName, attribute, schema.uid);
137
+
138
+ if (baseType === null) {
139
+ return null;
140
+ }
141
+
142
+ const modifiers = getAttributeModifiers(attribute);
143
+
144
+ const nodes = [baseType, ...modifiers];
272
145
 
273
- return ['DynamicZoneAttribute', [componentsParam]];
274
- },
146
+ return factory.createPropertySignature(
147
+ undefined,
148
+ factory.createIdentifier(attributeName),
149
+ undefined,
150
+ factory.createIntersectionTypeNode(nodes)
151
+ );
275
152
  };
276
153
 
277
154
  module.exports = attributeToPropertySignature;
@@ -1,10 +1,31 @@
1
1
  'use strict';
2
2
 
3
+ /* eslint-disable no-bitwise */
4
+
3
5
  const ts = require('typescript');
4
6
  const { factory } = require('typescript');
5
7
 
6
8
  const { getSchemaInterfaceName } = require('./utils');
7
9
 
10
+ /**
11
+ *
12
+ * @param {object} schemaDefinition
13
+ * @param {ts.InterfaceDeclaration} schemaDefinition.definition
14
+ * @param {object} schemaDefinition.schema
15
+ */
16
+ const schemaDefinitionToPropertySignature = ({ schema }) => {
17
+ const { uid } = schema;
18
+
19
+ const interfaceTypeName = getSchemaInterfaceName(uid);
20
+
21
+ return factory.createPropertySignature(
22
+ undefined,
23
+ factory.createStringLiteral(uid, true),
24
+ undefined,
25
+ factory.createTypeReferenceNode(factory.createIdentifier(interfaceTypeName))
26
+ );
27
+ };
28
+
8
29
  /**
9
30
  * Generate the global module augmentation block
10
31
  *
@@ -46,23 +67,4 @@ const generateGlobalDefinition = (schemasDefinitions = []) => {
46
67
  );
47
68
  };
48
69
 
49
- /**
50
- *
51
- * @param {object} schemaDefinition
52
- * @param {ts.InterfaceDeclaration} schemaDefinition.definition
53
- * @param {object} schemaDefinition.schema
54
- */
55
- const schemaDefinitionToPropertySignature = ({ schema }) => {
56
- const { uid } = schema;
57
-
58
- const interfaceTypeName = getSchemaInterfaceName(uid);
59
-
60
- return factory.createPropertySignature(
61
- undefined,
62
- factory.createStringLiteral(uid, true),
63
- undefined,
64
- factory.createTypeReferenceNode(factory.createIdentifier(interfaceTypeName))
65
- );
66
- };
67
-
68
70
  module.exports = { generateGlobalDefinition };
@@ -18,7 +18,7 @@ module.exports = {
18
18
  },
19
19
 
20
20
  generateImportDefinition() {
21
- const formattedImports = imports.map(key =>
21
+ const formattedImports = imports.map((key) =>
22
22
  factory.createImportSpecifier(false, undefined, factory.createIdentifier(key))
23
23
  );
24
24
 
@@ -23,67 +23,7 @@ const {
23
23
 
24
24
  const DEFAULT_OUT_FILENAME = 'schemas.d.ts';
25
25
 
26
- /**
27
- * Generate type definitions for Strapi schemas
28
- *
29
- * @param {object} options
30
- * @param {Strapi} options.strapi
31
- * @param {{ distDir: string; appDir: string; }} options.dirs
32
- * @param {string} [options.outDir]
33
- * @param {string} [options.file]
34
- * @param {boolean} [options.verbose]
35
- */
36
- const generateSchemasDefinitions = async (options = {}) => {
37
- const {
38
- strapi,
39
- outDir = process.cwd(),
40
- file = DEFAULT_OUT_FILENAME,
41
- verbose = false,
42
- silent = false,
43
- } = options;
44
-
45
- const schemas = getAllStrapiSchemas(strapi);
46
-
47
- const schemasDefinitions = Object.values(schemas).map(schema => ({
48
- schema,
49
- definition: generateSchemaDefinition(schema),
50
- }));
51
-
52
- const formattedSchemasDefinitions = schemasDefinitions.reduce((acc, def) => {
53
- acc.push(
54
- // Definition
55
- def.definition,
56
-
57
- // Add a newline between each interface declaration
58
- factory.createIdentifier('\n')
59
- );
60
-
61
- return acc;
62
- }, []);
63
-
64
- const allDefinitions = [
65
- // Imports
66
- generateImportDefinition(),
67
-
68
- // Add a newline after the import statement
69
- factory.createIdentifier('\n'),
70
-
71
- // Schemas
72
- ...formattedSchemasDefinitions,
73
-
74
- // Global
75
- generateGlobalDefinition(schemasDefinitions),
76
- ];
77
-
78
- const output = emitDefinitions(allDefinitions);
79
- const formattedOutput = await format(output);
80
-
81
- const definitionFilepath = await saveDefinitionToFileSystem(outDir, file, formattedOutput);
82
-
83
- logDebugInformation(schemasDefinitions, { filepath: definitionFilepath, verbose, silent });
84
- };
85
-
86
- const emitDefinitions = definitions => {
26
+ const emitDefinitions = (definitions) => {
87
27
  const nodeArray = factory.createNodeArray(definitions);
88
28
 
89
29
  const sourceFile = ts.createSourceFile(
@@ -114,7 +54,7 @@ const saveDefinitionToFileSystem = async (dir, file, content) => {
114
54
  * @param {string} content
115
55
  * @returns {Promise<string>}
116
56
  */
117
- const format = async content => {
57
+ const format = async (content) => {
118
58
  const configFile = await prettier.resolveConfigFile();
119
59
  const config = configFile
120
60
  ? await prettier.resolveConfig(configFile)
@@ -144,7 +84,7 @@ const logDebugInformation = (definitions, options = {}) => {
144
84
  colAligns: ['center', 'left', 'left', 'center'],
145
85
  });
146
86
 
147
- const sortedDefinitions = definitions.map(def => ({
87
+ const sortedDefinitions = definitions.map((def) => ({
148
88
  ...def,
149
89
  attributesCount: getDefinitionAttributesCount(def.definition),
150
90
  }));
@@ -182,4 +122,64 @@ const logDebugInformation = (definitions, options = {}) => {
182
122
  }
183
123
  };
184
124
 
125
+ /**
126
+ * Generate type definitions for Strapi schemas
127
+ *
128
+ * @param {object} options
129
+ * @param {Strapi} options.strapi
130
+ * @param {{ distDir: string; appDir: string; }} options.dirs
131
+ * @param {string} [options.outDir]
132
+ * @param {string} [options.file]
133
+ * @param {boolean} [options.verbose]
134
+ */
135
+ const generateSchemasDefinitions = async (options = {}) => {
136
+ const {
137
+ strapi,
138
+ outDir = process.cwd(),
139
+ file = DEFAULT_OUT_FILENAME,
140
+ verbose = false,
141
+ silent = false,
142
+ } = options;
143
+
144
+ const schemas = getAllStrapiSchemas(strapi);
145
+
146
+ const schemasDefinitions = Object.values(schemas).map((schema) => ({
147
+ schema,
148
+ definition: generateSchemaDefinition(schema),
149
+ }));
150
+
151
+ const formattedSchemasDefinitions = schemasDefinitions.reduce((acc, def) => {
152
+ acc.push(
153
+ // Definition
154
+ def.definition,
155
+
156
+ // Add a newline between each interface declaration
157
+ factory.createIdentifier('\n')
158
+ );
159
+
160
+ return acc;
161
+ }, []);
162
+
163
+ const allDefinitions = [
164
+ // Imports
165
+ generateImportDefinition(),
166
+
167
+ // Add a newline after the import statement
168
+ factory.createIdentifier('\n'),
169
+
170
+ // Schemas
171
+ ...formattedSchemasDefinitions,
172
+
173
+ // Global
174
+ generateGlobalDefinition(schemasDefinitions),
175
+ ];
176
+
177
+ const output = emitDefinitions(allDefinitions);
178
+ const formattedOutput = await format(output);
179
+
180
+ const definitionFilepath = await saveDefinitionToFileSystem(outDir, file, formattedOutput);
181
+
182
+ logDebugInformation(schemasDefinitions, { filepath: definitionFilepath, verbose, silent });
183
+ };
184
+
185
185
  module.exports = generateSchemasDefinitions;
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const ts = require('typescript');
4
+ const _ = require('lodash/fp');
5
+
6
+ const { toTypeLiteral } = require('./utils');
7
+
8
+ const { factory } = ts;
9
+
10
+ module.exports = {
11
+ string() {
12
+ return ['StringAttribute'];
13
+ },
14
+ text() {
15
+ return ['TextAttribute'];
16
+ },
17
+ richtext() {
18
+ return ['RichTextAttribute'];
19
+ },
20
+ password() {
21
+ return ['PasswordAttribute'];
22
+ },
23
+ email() {
24
+ return ['EmailAttribute'];
25
+ },
26
+ date() {
27
+ return ['DateAttribute'];
28
+ },
29
+ time() {
30
+ return ['TimeAttribute'];
31
+ },
32
+ datetime() {
33
+ return ['DateTimeAttribute'];
34
+ },
35
+ timestamp() {
36
+ return ['TimestampAttribute'];
37
+ },
38
+ integer() {
39
+ return ['IntegerAttribute'];
40
+ },
41
+ biginteger() {
42
+ return ['BigIntegerAttribute'];
43
+ },
44
+ float() {
45
+ return ['FloatAttribute'];
46
+ },
47
+ decimal() {
48
+ return ['DecimalAttribute'];
49
+ },
50
+ uid({ attribute, uid }) {
51
+ const { targetField, options } = attribute;
52
+
53
+ // If there are no params to compute, then return the attribute type alone
54
+ if (targetField === undefined && options === undefined) {
55
+ return ['UIDAttribute'];
56
+ }
57
+
58
+ const params = [];
59
+
60
+ // If the targetField property is defined, then reference it,
61
+ // otherwise, put `undefined` keyword type nodes as placeholders
62
+ const targetFieldParams = _.isUndefined(targetField)
63
+ ? [
64
+ factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
65
+ factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
66
+ ]
67
+ : [factory.createStringLiteral(uid), factory.createStringLiteral(targetField)];
68
+
69
+ params.push(...targetFieldParams);
70
+
71
+ // If the options property is defined, transform it to
72
+ // a type literral node and add it to the params list
73
+ if (_.isObject(options)) {
74
+ params.push(toTypeLiteral(options));
75
+ }
76
+
77
+ return ['UIDAttribute', params];
78
+ },
79
+ enumeration({ attribute }) {
80
+ const { enum: enumValues } = attribute;
81
+
82
+ return ['EnumerationAttribute', [toTypeLiteral(enumValues)]];
83
+ },
84
+ boolean() {
85
+ return ['BooleanAttribute'];
86
+ },
87
+ json() {
88
+ return ['JSONAttribute'];
89
+ },
90
+ media() {
91
+ return ['MediaAttribute'];
92
+ },
93
+ relation({ uid, attribute }) {
94
+ const { relation, target } = attribute;
95
+
96
+ const isMorphRelation = relation.toLowerCase().includes('morph');
97
+
98
+ if (isMorphRelation) {
99
+ return [
100
+ 'RelationAttribute',
101
+ [factory.createStringLiteral(uid, true), factory.createStringLiteral(relation, true)],
102
+ ];
103
+ }
104
+
105
+ return [
106
+ 'RelationAttribute',
107
+ [
108
+ factory.createStringLiteral(uid, true),
109
+ factory.createStringLiteral(relation, true),
110
+ factory.createStringLiteral(target, true),
111
+ ],
112
+ ];
113
+ },
114
+ component({ attribute }) {
115
+ const target = attribute.component;
116
+ const params = [factory.createStringLiteral(target, true)];
117
+
118
+ if (attribute.repeatable) {
119
+ params.push(factory.createTrue());
120
+ }
121
+
122
+ return ['ComponentAttribute', params];
123
+ },
124
+ dynamiczone({ attribute }) {
125
+ const componentsParam = factory.createTupleTypeNode(
126
+ attribute.components.map((component) => factory.createStringLiteral(component))
127
+ );
128
+
129
+ return ['DynamicZoneAttribute', [componentsParam]];
130
+ },
131
+ };
@@ -8,13 +8,43 @@ const { getSchemaExtendsTypeName, getSchemaInterfaceName, toTypeLiteral } = requ
8
8
  const attributeToPropertySignature = require('./attributes');
9
9
  const { addImport } = require('./imports');
10
10
 
11
+ /**
12
+ * Generate a property signature for the schema's `attributes` field
13
+ *
14
+ * @param {object} schema
15
+ * @returns {ts.PropertySignature}
16
+ */
17
+ const generateAttributePropertySignature = (schema) => {
18
+ const { attributes } = schema;
19
+
20
+ const properties = Object.entries(attributes).map(([attributeName, attribute]) => {
21
+ return attributeToPropertySignature(schema, attributeName, attribute);
22
+ });
23
+
24
+ return factory.createPropertySignature(
25
+ undefined,
26
+ factory.createIdentifier('attributes'),
27
+ undefined,
28
+ factory.createTypeLiteralNode(properties)
29
+ );
30
+ };
31
+
32
+ const generatePropertyLiteralDefinitionFactory = (schema) => (key) => {
33
+ return factory.createPropertySignature(
34
+ undefined,
35
+ factory.createIdentifier(key),
36
+ undefined,
37
+ toTypeLiteral(schema[key])
38
+ );
39
+ };
40
+
11
41
  /**
12
42
  * Generate an interface declaration for a given schema
13
43
  *
14
44
  * @param {object} schema
15
45
  * @returns {ts.InterfaceDeclaration}
16
46
  */
17
- const generateSchemaDefinition = schema => {
47
+ const generateSchemaDefinition = (schema) => {
18
48
  const { uid } = schema;
19
49
 
20
50
  // Resolve the different interface names needed to declare the schema's interface
@@ -27,7 +57,7 @@ const generateSchemaDefinition = schema => {
27
57
  // Properties whose values can be mapped to a literal type expression
28
58
  const literalPropertiesDefinitions = ['info', 'options', 'pluginOptions']
29
59
  // Ignore non-existent or empty declarations
30
- .filter(key => !isEmpty(schema[key]))
60
+ .filter((key) => !isEmpty(schema[key]))
31
61
  // Generate literal definition for each property
32
62
  .map(generatePropertyLiteralDefinitionFactory(schema));
33
63
 
@@ -54,34 +84,4 @@ const generateSchemaDefinition = schema => {
54
84
  return schemaType;
55
85
  };
56
86
 
57
- /**
58
- * Generate a property signature for the schema's `attributes` field
59
- *
60
- * @param {object} schema
61
- * @returns {ts.PropertySignature}
62
- */
63
- const generateAttributePropertySignature = schema => {
64
- const { attributes } = schema;
65
-
66
- const properties = Object.entries(attributes).map(([attributeName, attribute]) => {
67
- return attributeToPropertySignature(schema, attributeName, attribute);
68
- });
69
-
70
- return factory.createPropertySignature(
71
- undefined,
72
- factory.createIdentifier('attributes'),
73
- undefined,
74
- factory.createTypeLiteralNode(properties)
75
- );
76
- };
77
-
78
- const generatePropertyLiteralDefinitionFactory = schema => key => {
79
- return factory.createPropertySignature(
80
- undefined,
81
- factory.createIdentifier(key),
82
- undefined,
83
- toTypeLiteral(schema[key])
84
- );
85
- };
86
-
87
87
  module.exports = { generateSchemaDefinition };
@@ -23,7 +23,7 @@ const {
23
23
  * @param {Strapi} strapi
24
24
  * @returns {object}
25
25
  */
26
- const getAllStrapiSchemas = strapi => ({ ...strapi.contentTypes, ...strapi.components });
26
+ const getAllStrapiSchemas = (strapi) => ({ ...strapi.contentTypes, ...strapi.components });
27
27
 
28
28
  /**
29
29
  * Extract a valid interface name from a schema uid
@@ -33,19 +33,7 @@ const getAllStrapiSchemas = strapi => ({ ...strapi.contentTypes, ...strapi.compo
33
33
  */
34
34
  const getSchemaInterfaceName = pipe(replace(/(:.)/, ' '), camelCase, upperFirst);
35
35
 
36
- /**
37
- * Get the parent type name to extend based on the schema's nature
38
- *
39
- * @param {object} schema
40
- * @returns {string}
41
- */
42
- const getSchemaExtendsTypeName = schema => {
43
- const base = getSchemaModelType(schema);
44
-
45
- return upperFirst(base) + 'Schema';
46
- };
47
-
48
- const getSchemaModelType = schema => {
36
+ const getSchemaModelType = (schema) => {
49
37
  const { modelType, kind } = schema;
50
38
 
51
39
  // Components
@@ -54,13 +42,25 @@ const getSchemaModelType = schema => {
54
42
  }
55
43
 
56
44
  // Content-Types
57
- else if (modelType === 'contentType') {
45
+ if (modelType === 'contentType') {
58
46
  return kind;
59
47
  }
60
48
 
61
49
  return null;
62
50
  };
63
51
 
52
+ /**
53
+ * Get the parent type name to extend based on the schema's nature
54
+ *
55
+ * @param {object} schema
56
+ * @returns {string}
57
+ */
58
+ const getSchemaExtendsTypeName = (schema) => {
59
+ const base = getSchemaModelType(schema);
60
+
61
+ return `${upperFirst(base)}Schema`;
62
+ };
63
+
64
64
  /**
65
65
  * Get a type node based on a type and its params
66
66
  *
@@ -77,7 +77,7 @@ const getTypeNode = (typeName, params = []) => {
77
77
  * @param data
78
78
  * @returns {ts.TypeNode}
79
79
  */
80
- const toTypeLiteral = data => {
80
+ const toTypeLiteral = (data) => {
81
81
  if (isUndefined(data)) {
82
82
  return factory.createLiteralTypeNode(ts.SyntaxKind.UndefinedKeyword);
83
83
  }
@@ -99,7 +99,7 @@ const toTypeLiteral = data => {
99
99
  }
100
100
 
101
101
  if (isArray(data)) {
102
- return factory.createTupleTypeNode(data.map(item => toTypeLiteral(item)));
102
+ return factory.createTupleTypeNode(data.map((item) => toTypeLiteral(item)));
103
103
  }
104
104
 
105
105
  if (isDate(data)) {
@@ -139,7 +139,7 @@ const toTypeLiteral = data => {
139
139
  * @param {ts.TypeNode} definition
140
140
  * @returns {number | null}
141
141
  */
142
- const getDefinitionAttributesCount = definition => {
142
+ const getDefinitionAttributesCount = (definition) => {
143
143
  const attributesNode = definition.members.find(propEq('name.escapedText', 'attributes'));
144
144
 
145
145
  if (!attributesNode) {
@@ -1,9 +1,27 @@
1
1
  'use strict';
2
2
 
3
+ const path = require('path');
3
4
  const ts = require('typescript');
4
5
 
5
6
  const DEFAULT_TS_CONFIG_FILENAME = 'tsconfig.json';
6
7
 
7
- module.exports = (dir, filename = DEFAULT_TS_CONFIG_FILENAME) => {
8
- return ts.findConfigFile(dir, ts.sys.fileExists, filename);
8
+ /**
9
+ * Get the path of the typescript config file for a given directory
10
+ *
11
+ * @param {string} dir
12
+ * @param {object} [options]
13
+ * @param {string} [options.filename]
14
+ * @param {boolean} [options.ancestorsLookup]
15
+ *
16
+ * @return {string | undefined}
17
+ */
18
+ module.exports = (dir, { filename = DEFAULT_TS_CONFIG_FILENAME, ancestorsLookup = false } = {}) => {
19
+ const dirAbsolutePath = path.resolve(dir);
20
+ const configFilePath = ts.findConfigFile(dirAbsolutePath, ts.sys.fileExists, filename);
21
+
22
+ if (!configFilePath || ancestorsLookup) {
23
+ return configFilePath;
24
+ }
25
+
26
+ return configFilePath.startsWith(dirAbsolutePath) ? configFilePath : undefined;
9
27
  };
@@ -11,7 +11,7 @@ const getConfigPath = require('./get-config-path');
11
11
  * @returns {boolean}
12
12
  */
13
13
  module.exports = (dir, filename = undefined) => {
14
- const filePath = getConfigPath(dir, filename);
14
+ const filePath = getConfigPath(dir, { filename });
15
15
 
16
16
  return fse.pathExistsSync(filePath);
17
17
  };
@@ -11,7 +11,7 @@ const getConfigPath = require('./get-config-path');
11
11
  * @returns {Promise<boolean>}
12
12
  */
13
13
  module.exports = (dir, filename = undefined) => {
14
- const filePath = getConfigPath(dir, filename);
14
+ const filePath = getConfigPath(dir, { filename });
15
15
 
16
16
  return fse.pathExists(filePath);
17
17
  };
@@ -8,7 +8,7 @@ const formatHost = require('./format-host');
8
8
  * Report one or several diagnostic to the console
9
9
  * @param {ts.Diagnostic[] | ts.Diagnostic} diagnostics
10
10
  */
11
- module.exports = diagnostics => {
11
+ module.exports = (diagnostics) => {
12
12
  const formattedDiagnostics = ts.formatDiagnosticsWithColorAndContext(
13
13
  Array.isArray(diagnostics) ? diagnostics : [diagnostics],
14
14
  formatHost
@@ -4,7 +4,7 @@ const ts = require('typescript');
4
4
 
5
5
  const logDiagnostics = require('./report-diagnostics');
6
6
 
7
- module.exports = configPath => {
7
+ module.exports = (configPath) => {
8
8
  // Parse the tsconfig.json file and resolve every file name & compiler options
9
9
  const { errors, ...configOptions } = ts.getParsedCommandLineOfConfigFile(
10
10
  configPath,
@@ -1,4 +1,5 @@
1
1
  'use strict';
2
+
2
3
  const path = require('path');
3
4
  const resolveConfigOptions = require('./resolve-config-options');
4
5
  const isUsingTypescript = require('./is-using-typescript');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/typescript-utils",
3
- "version": "4.3.2",
3
+ "version": "4.3.5",
4
4
  "description": "Typescript support for Strapi",
5
5
  "keywords": [
6
6
  "strapi",
@@ -35,5 +35,5 @@
35
35
  "node": ">=12.22.0 <=16.x.x",
36
36
  "npm": ">=6.0.0"
37
37
  },
38
- "gitHead": "7039c0d22836c94457130515b3a55eb93d2411f8"
38
+ "gitHead": "a52b0535513ff35b4ef46c9daf7be48f2ba71737"
39
39
  }