@jahia/cypress 3.17.7 → 3.17.9
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/utils/GraphQLHelper.d.ts +1 -0
- package/dist/utils/GraphQLHelper.js +163 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/fixtures/graphql/introspection.graphql +73 -0
- package/package.json +1 -1
- package/src/utils/GraphQLHelper.ts +179 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getDescriptions: (rootNode: string) => Cypress.Chainable;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint max-depth: ["error", 5] */
|
|
3
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
|
4
|
+
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
|
5
|
+
to[j] = from[i];
|
|
6
|
+
return to;
|
|
7
|
+
};
|
|
8
|
+
exports.__esModule = true;
|
|
9
|
+
exports.getDescriptions = void 0;
|
|
10
|
+
// The type name to be used for further introspection can be located either in
|
|
11
|
+
// the type object itself or in the ofType object
|
|
12
|
+
var addTypes = (function (type, atPath) {
|
|
13
|
+
var newTypes = [];
|
|
14
|
+
if (type.name !== null) {
|
|
15
|
+
newTypes.push({ typeName: type.name, atPath: atPath });
|
|
16
|
+
}
|
|
17
|
+
if (type.ofType && type.ofType.name !== null) {
|
|
18
|
+
newTypes.push({ typeName: type.ofType.name, atPath: atPath });
|
|
19
|
+
}
|
|
20
|
+
return newTypes;
|
|
21
|
+
});
|
|
22
|
+
// This returns a flat list of all children fields and args for a given GraphQL node
|
|
23
|
+
// This list can then be used in Cypress tests to look for missing descriptions
|
|
24
|
+
var getDescriptions = function (rootNode) {
|
|
25
|
+
cy.log('Starting analysis from GraphQL node: ' + rootNode);
|
|
26
|
+
return execIntrospection(rootNode, [], [rootNode]).then(function (descriptions) {
|
|
27
|
+
return descriptions;
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
exports.getDescriptions = getDescriptions;
|
|
31
|
+
var execIntrospection = function (typeName, descriptions, nodePath) {
|
|
32
|
+
return cy.apollo({
|
|
33
|
+
variables: {
|
|
34
|
+
typeName: typeName
|
|
35
|
+
},
|
|
36
|
+
queryFile: 'graphql/introspection.graphql'
|
|
37
|
+
}).then(function (response) {
|
|
38
|
+
var _a;
|
|
39
|
+
var responseDataType = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.__type;
|
|
40
|
+
if (responseDataType === null || responseDataType === undefined || responseDataType.kind === 'UNION') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (responseDataType) {
|
|
44
|
+
// This array will be populated with types identified in the introspection query
|
|
45
|
+
// These will then be further introspected to get their children fields and args
|
|
46
|
+
var fetchSubTypes_1 = [];
|
|
47
|
+
descriptions.push({
|
|
48
|
+
name: responseDataType.name,
|
|
49
|
+
description: responseDataType.description,
|
|
50
|
+
schemaType: '__Type',
|
|
51
|
+
schemaNode: responseDataType,
|
|
52
|
+
nodePath: nodePath
|
|
53
|
+
});
|
|
54
|
+
// The following exploration of the object follows precisely the Graphql Introspection
|
|
55
|
+
// spec available at https://github.com/graphql/graphql-spec/blob/main/spec/Section%204%20--%20Introspection.md
|
|
56
|
+
if (responseDataType.fields) {
|
|
57
|
+
for (var _i = 0, _b = responseDataType.fields; _i < _b.length; _i++) {
|
|
58
|
+
var graphqlField = _b[_i];
|
|
59
|
+
var fieldPath = __spreadArray(__spreadArray([], nodePath), [graphqlField.name]);
|
|
60
|
+
descriptions.push({
|
|
61
|
+
name: graphqlField.name,
|
|
62
|
+
description: graphqlField.description,
|
|
63
|
+
schemaType: '__Field',
|
|
64
|
+
schemaNode: graphqlField,
|
|
65
|
+
isDeprecated: graphqlField.isDeprecated,
|
|
66
|
+
deprecationReason: graphqlField.deprecationReason,
|
|
67
|
+
nodePath: fieldPath
|
|
68
|
+
});
|
|
69
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(graphqlField.type, fieldPath));
|
|
70
|
+
if (graphqlField.args) {
|
|
71
|
+
for (var _c = 0, _d = graphqlField.args; _c < _d.length; _c++) {
|
|
72
|
+
var graphQLInputValue = _d[_c];
|
|
73
|
+
var inputValuePath = __spreadArray(__spreadArray([], fieldPath), [graphQLInputValue.name]);
|
|
74
|
+
descriptions.push({
|
|
75
|
+
name: graphQLInputValue.name,
|
|
76
|
+
description: graphQLInputValue.description,
|
|
77
|
+
schemaType: '__InputValue',
|
|
78
|
+
schemaNode: graphQLInputValue,
|
|
79
|
+
isDeprecated: graphQLInputValue.isDeprecated,
|
|
80
|
+
deprecationReason: graphQLInputValue.deprecationReason,
|
|
81
|
+
nodePath: inputValuePath
|
|
82
|
+
});
|
|
83
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(graphQLInputValue.type, inputValuePath));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (responseDataType.interfaces) {
|
|
89
|
+
for (var _e = 0, _f = responseDataType.interfaces; _e < _f.length; _e++) {
|
|
90
|
+
var graphQLInterfaceType = _f[_e];
|
|
91
|
+
descriptions.push({
|
|
92
|
+
name: graphQLInterfaceType.name,
|
|
93
|
+
description: graphQLInterfaceType.description,
|
|
94
|
+
schemaType: '__Type',
|
|
95
|
+
schemaNode: graphQLInterfaceType,
|
|
96
|
+
nodePath: nodePath
|
|
97
|
+
});
|
|
98
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(graphQLInterfaceType, nodePath));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (responseDataType.possibleTypes) {
|
|
102
|
+
for (var _g = 0, _h = responseDataType.possibleTypes; _g < _h.length; _g++) {
|
|
103
|
+
var graphQLType = _h[_g];
|
|
104
|
+
var fieldPath = __spreadArray(__spreadArray([], nodePath), [responseDataType.name, graphQLType.name]);
|
|
105
|
+
descriptions.push({
|
|
106
|
+
name: graphQLType.name,
|
|
107
|
+
description: graphQLType.description,
|
|
108
|
+
schemaType: '__Type',
|
|
109
|
+
schemaNode: graphQLType,
|
|
110
|
+
nodePath: fieldPath
|
|
111
|
+
});
|
|
112
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(graphQLType, fieldPath));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (responseDataType.enumValues) {
|
|
116
|
+
for (var _j = 0, _k = responseDataType.enumValues; _j < _k.length; _j++) {
|
|
117
|
+
var graphQLEnumValue = _k[_j];
|
|
118
|
+
var enumPath = __spreadArray(__spreadArray([], nodePath), [responseDataType.name, graphQLEnumValue.name]);
|
|
119
|
+
descriptions.push({
|
|
120
|
+
name: graphQLEnumValue.name,
|
|
121
|
+
description: graphQLEnumValue.description,
|
|
122
|
+
schemaType: '__EnumValue',
|
|
123
|
+
schemaNode: graphQLEnumValue,
|
|
124
|
+
nodePath: enumPath,
|
|
125
|
+
isDeprecated: graphQLEnumValue.isDeprecated,
|
|
126
|
+
deprecationReason: graphQLEnumValue.deprecationReason
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (responseDataType.inputFields) {
|
|
131
|
+
for (var _l = 0, _m = responseDataType.inputFields; _l < _m.length; _l++) {
|
|
132
|
+
var graphQLInputValue = _m[_l];
|
|
133
|
+
var inputValuePath = __spreadArray(__spreadArray([], nodePath), [responseDataType.name, graphQLInputValue.name]);
|
|
134
|
+
descriptions.push({
|
|
135
|
+
name: graphQLInputValue.name,
|
|
136
|
+
description: graphQLInputValue.description,
|
|
137
|
+
schemaType: '__InputValue',
|
|
138
|
+
schemaNode: graphQLInputValue,
|
|
139
|
+
nodePath: inputValuePath
|
|
140
|
+
});
|
|
141
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(graphQLInputValue.type, inputValuePath));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (responseDataType.ofType) {
|
|
145
|
+
fetchSubTypes_1 = __spreadArray(__spreadArray([], fetchSubTypes_1), addTypes(responseDataType.ofType, nodePath));
|
|
146
|
+
}
|
|
147
|
+
var uniqueSubTypes = fetchSubTypes_1
|
|
148
|
+
// Filter out duplicate types to ensure we don't introspect the same type multiple times
|
|
149
|
+
.filter(function (obj, index) { return fetchSubTypes_1.findIndex(function (item) { return item.typeName === obj.typeName; }) === index; })
|
|
150
|
+
// Filter out types that have a name of null (e.g. List of non-null types)
|
|
151
|
+
.filter(function (subtype) { return subtype.typeName !== null; })
|
|
152
|
+
// Remove types that might have already been introspected
|
|
153
|
+
.filter(function (subtype) { return descriptions.find(function (d) { return d.schemaType === '__Type' && d.name === subtype.typeName; }) === undefined; });
|
|
154
|
+
// If there are no subtypes to introspect, we still need to return the descriptions
|
|
155
|
+
if (uniqueSubTypes.length === 0) {
|
|
156
|
+
return descriptions;
|
|
157
|
+
}
|
|
158
|
+
return Cypress.Promise.each(uniqueSubTypes, function (subType) {
|
|
159
|
+
return execIntrospection(subType.typeName, descriptions, __spreadArray(__spreadArray([], subType.atPath), [subType.typeName]));
|
|
160
|
+
}).then(function () { return descriptions; }); // Return descriptions after all recursive calls have completed
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -17,3 +17,4 @@ __exportStar(require("./UsersHelper"), exports);
|
|
|
17
17
|
__exportStar(require("./VanityUrlHelper"), exports);
|
|
18
18
|
__exportStar(require("./ClusterHelper"), exports);
|
|
19
19
|
__exportStar(require("./JahiaPlatformHelper"), exports);
|
|
20
|
+
__exportStar(require("./GraphQLHelper"), exports);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
query IntrospectionQuery($typeName: String!) {
|
|
2
|
+
__type(name: $typeName) {
|
|
3
|
+
kind
|
|
4
|
+
name
|
|
5
|
+
description
|
|
6
|
+
fields(includeDeprecated: true) {
|
|
7
|
+
name
|
|
8
|
+
description
|
|
9
|
+
deprecationReason
|
|
10
|
+
isDeprecated
|
|
11
|
+
args {
|
|
12
|
+
name
|
|
13
|
+
description
|
|
14
|
+
type {
|
|
15
|
+
kind
|
|
16
|
+
name
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
type {
|
|
20
|
+
kind
|
|
21
|
+
name
|
|
22
|
+
description
|
|
23
|
+
ofType {
|
|
24
|
+
name
|
|
25
|
+
description
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
interfaces {
|
|
30
|
+
name
|
|
31
|
+
description
|
|
32
|
+
ofType {
|
|
33
|
+
name
|
|
34
|
+
description
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
possibleTypes {
|
|
38
|
+
name
|
|
39
|
+
description
|
|
40
|
+
ofType {
|
|
41
|
+
name
|
|
42
|
+
description
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
enumValues(includeDeprecated: true) {
|
|
46
|
+
name
|
|
47
|
+
description
|
|
48
|
+
deprecationReason
|
|
49
|
+
isDeprecated
|
|
50
|
+
}
|
|
51
|
+
inputFields {
|
|
52
|
+
name
|
|
53
|
+
description
|
|
54
|
+
type {
|
|
55
|
+
kind
|
|
56
|
+
name
|
|
57
|
+
description
|
|
58
|
+
ofType {
|
|
59
|
+
name
|
|
60
|
+
description
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
ofType {
|
|
65
|
+
name
|
|
66
|
+
description
|
|
67
|
+
ofType {
|
|
68
|
+
name
|
|
69
|
+
description
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* eslint max-depth: ["error", 5] */
|
|
2
|
+
|
|
3
|
+
interface GraphQLField {
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface GraphQLDescription {
|
|
8
|
+
name: string; // Name of the element in the schema
|
|
9
|
+
description: string; // Description of the element in the schema
|
|
10
|
+
schemaType: string; // Type of the element in the schema according to the GraphQL spec
|
|
11
|
+
schemaNode: GraphQLField; // The actual node fetched from the schema
|
|
12
|
+
nodePath: string[]; // The path to the node in the schema
|
|
13
|
+
isDeprecated?: boolean;
|
|
14
|
+
deprecationReason?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// The type name to be used for further introspection can be located either in
|
|
18
|
+
// the type object itself or in the ofType object
|
|
19
|
+
const addTypes = ((type, atPath) => {
|
|
20
|
+
const newTypes = [];
|
|
21
|
+
if (type.name !== null) {
|
|
22
|
+
newTypes.push({typeName: type.name, atPath: atPath});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (type.ofType && type.ofType.name !== null) {
|
|
26
|
+
newTypes.push({typeName: type.ofType.name, atPath: atPath});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return newTypes;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// This returns a flat list of all children fields and args for a given GraphQL node
|
|
33
|
+
// This list can then be used in Cypress tests to look for missing descriptions
|
|
34
|
+
export const getDescriptions = (rootNode: string): Cypress.Chainable => {
|
|
35
|
+
cy.log('Starting analysis from GraphQL node: ' + rootNode);
|
|
36
|
+
return execIntrospection(rootNode, [], [rootNode]).then(descriptions => {
|
|
37
|
+
return descriptions;
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const execIntrospection = (typeName: string, descriptions: GraphQLDescription[], nodePath): Cypress.Chainable => {
|
|
42
|
+
return cy.apollo({
|
|
43
|
+
variables: {
|
|
44
|
+
typeName: typeName
|
|
45
|
+
},
|
|
46
|
+
queryFile: 'graphql/introspection.graphql'
|
|
47
|
+
}).then(response => {
|
|
48
|
+
const responseDataType = response?.data?.__type;
|
|
49
|
+
if (responseDataType === null || responseDataType === undefined || responseDataType.kind === 'UNION') {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (responseDataType) {
|
|
54
|
+
// This array will be populated with types identified in the introspection query
|
|
55
|
+
// These will then be further introspected to get their children fields and args
|
|
56
|
+
let fetchSubTypes: {typeName: string, atPath: string[]}[] = [];
|
|
57
|
+
|
|
58
|
+
descriptions.push({
|
|
59
|
+
name: responseDataType.name,
|
|
60
|
+
description: responseDataType.description,
|
|
61
|
+
schemaType: '__Type',
|
|
62
|
+
schemaNode: responseDataType,
|
|
63
|
+
nodePath
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// The following exploration of the object follows precisely the Graphql Introspection
|
|
67
|
+
// spec available at https://github.com/graphql/graphql-spec/blob/main/spec/Section%204%20--%20Introspection.md
|
|
68
|
+
if (responseDataType.fields) {
|
|
69
|
+
for (const graphqlField of responseDataType.fields) {
|
|
70
|
+
const fieldPath = [...nodePath, graphqlField.name];
|
|
71
|
+
descriptions.push({
|
|
72
|
+
name: graphqlField.name,
|
|
73
|
+
description: graphqlField.description,
|
|
74
|
+
schemaType: '__Field',
|
|
75
|
+
schemaNode: graphqlField,
|
|
76
|
+
isDeprecated: graphqlField.isDeprecated,
|
|
77
|
+
deprecationReason: graphqlField.deprecationReason,
|
|
78
|
+
nodePath: fieldPath
|
|
79
|
+
});
|
|
80
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(graphqlField.type, fieldPath)];
|
|
81
|
+
|
|
82
|
+
if (graphqlField.args) {
|
|
83
|
+
for (const graphQLInputValue of graphqlField.args) {
|
|
84
|
+
const inputValuePath = [...fieldPath, graphQLInputValue.name];
|
|
85
|
+
descriptions.push({
|
|
86
|
+
name: graphQLInputValue.name,
|
|
87
|
+
description: graphQLInputValue.description,
|
|
88
|
+
schemaType: '__InputValue',
|
|
89
|
+
schemaNode: graphQLInputValue,
|
|
90
|
+
isDeprecated: graphQLInputValue.isDeprecated,
|
|
91
|
+
deprecationReason: graphQLInputValue.deprecationReason,
|
|
92
|
+
nodePath: inputValuePath
|
|
93
|
+
});
|
|
94
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(graphQLInputValue.type, inputValuePath)];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (responseDataType.interfaces) {
|
|
101
|
+
for (const graphQLInterfaceType of responseDataType.interfaces) {
|
|
102
|
+
descriptions.push({
|
|
103
|
+
name: graphQLInterfaceType.name,
|
|
104
|
+
description: graphQLInterfaceType.description,
|
|
105
|
+
schemaType: '__Type',
|
|
106
|
+
schemaNode: graphQLInterfaceType,
|
|
107
|
+
nodePath
|
|
108
|
+
});
|
|
109
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(graphQLInterfaceType, nodePath)];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (responseDataType.possibleTypes) {
|
|
114
|
+
for (const graphQLType of responseDataType.possibleTypes) {
|
|
115
|
+
const fieldPath = [...nodePath, responseDataType.name, graphQLType.name];
|
|
116
|
+
descriptions.push({
|
|
117
|
+
name: graphQLType.name,
|
|
118
|
+
description: graphQLType.description,
|
|
119
|
+
schemaType: '__Type',
|
|
120
|
+
schemaNode: graphQLType,
|
|
121
|
+
nodePath: fieldPath
|
|
122
|
+
});
|
|
123
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(graphQLType, fieldPath)];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (responseDataType.enumValues) {
|
|
128
|
+
for (const graphQLEnumValue of responseDataType.enumValues) {
|
|
129
|
+
const enumPath = [...nodePath, responseDataType.name, graphQLEnumValue.name];
|
|
130
|
+
descriptions.push({
|
|
131
|
+
name: graphQLEnumValue.name,
|
|
132
|
+
description: graphQLEnumValue.description,
|
|
133
|
+
schemaType: '__EnumValue',
|
|
134
|
+
schemaNode: graphQLEnumValue,
|
|
135
|
+
nodePath: enumPath,
|
|
136
|
+
isDeprecated: graphQLEnumValue.isDeprecated,
|
|
137
|
+
deprecationReason: graphQLEnumValue.deprecationReason
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (responseDataType.inputFields) {
|
|
143
|
+
for (const graphQLInputValue of responseDataType.inputFields) {
|
|
144
|
+
const inputValuePath = [...nodePath, responseDataType.name, graphQLInputValue.name];
|
|
145
|
+
descriptions.push({
|
|
146
|
+
name: graphQLInputValue.name,
|
|
147
|
+
description: graphQLInputValue.description,
|
|
148
|
+
schemaType: '__InputValue',
|
|
149
|
+
schemaNode: graphQLInputValue,
|
|
150
|
+
nodePath: inputValuePath
|
|
151
|
+
});
|
|
152
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(graphQLInputValue.type, inputValuePath)];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (responseDataType.ofType) {
|
|
157
|
+
fetchSubTypes = [...fetchSubTypes, ...addTypes(responseDataType.ofType, nodePath)];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const uniqueSubTypes = fetchSubTypes
|
|
161
|
+
// Filter out duplicate types to ensure we don't introspect the same type multiple times
|
|
162
|
+
.filter((obj, index) => fetchSubTypes.findIndex(item => item.typeName === obj.typeName) === index)
|
|
163
|
+
// Filter out types that have a name of null (e.g. List of non-null types)
|
|
164
|
+
.filter(subtype => subtype.typeName !== null)
|
|
165
|
+
// Remove types that might have already been introspected
|
|
166
|
+
.filter(subtype => descriptions.find(d => d.schemaType === '__Type' && d.name === subtype.typeName) === undefined);
|
|
167
|
+
|
|
168
|
+
// If there are no subtypes to introspect, we still need to return the descriptions
|
|
169
|
+
if (uniqueSubTypes.length === 0) {
|
|
170
|
+
return descriptions;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return Cypress.Promise.each(uniqueSubTypes, subType => {
|
|
174
|
+
return execIntrospection(subType.typeName, descriptions, [...subType.atPath, subType.typeName]);
|
|
175
|
+
}).then(() => descriptions); // Return descriptions after all recursive calls have completed
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
|
package/src/utils/index.ts
CHANGED