@openapi-qraft/plugin 1.13.0 → 1.14.0-beta.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.
- package/CHANGELOG.md +7 -0
- package/dist/lib/QraftCommand.d.ts.map +1 -1
- package/dist/lib/QraftCommand.js +27 -8
- package/dist/lib/QraftCommand.js.map +1 -1
- package/dist/lib/createServicePathMatch.d.ts +0 -9
- package/dist/lib/createServicePathMatch.d.ts.map +1 -1
- package/dist/lib/createServicePathMatch.js +0 -15
- package/dist/lib/createServicePathMatch.js.map +1 -1
- package/dist/lib/filterDocumentPaths.d.ts +1 -1
- package/dist/lib/filterDocumentPaths.d.ts.map +1 -1
- package/dist/lib/filterDocumentPaths.js +1 -1
- package/dist/lib/filterDocumentPaths.js.map +1 -1
- package/dist/lib/parseOperationGlobs.d.ts +17 -0
- package/dist/lib/parseOperationGlobs.d.ts.map +1 -0
- package/dist/lib/parseOperationGlobs.js +37 -0
- package/dist/lib/parseOperationGlobs.js.map +1 -0
- package/dist/lib/predefineSchemaParameters.d.ts +15 -11
- package/dist/lib/predefineSchemaParameters.d.ts.map +1 -1
- package/dist/lib/predefineSchemaParameters.js +50 -30
- package/dist/lib/predefineSchemaParameters.js.map +1 -1
- package/dist/lib/processOperationNameModifierOption.d.ts +57 -0
- package/dist/lib/processOperationNameModifierOption.d.ts.map +1 -0
- package/dist/lib/processOperationNameModifierOption.js +102 -0
- package/dist/lib/processOperationNameModifierOption.js.map +1 -0
- package/dist/lib/splitCommaSeparatedGlobs.d.ts +7 -0
- package/dist/lib/splitCommaSeparatedGlobs.d.ts.map +1 -0
- package/dist/lib/splitCommaSeparatedGlobs.js +16 -0
- package/dist/lib/splitCommaSeparatedGlobs.js.map +1 -0
- package/package.json +3 -3
- package/src/lib/QraftCommand.ts +59 -10
- package/src/lib/createServicePathMatch.ts +0 -18
- package/src/lib/filterDocumentPaths.ts +2 -2
- package/src/lib/parseOperationGlobs.ts +54 -0
- package/src/lib/predefineSchemaParameters.ts +108 -71
- package/src/lib/processOperationNameModifierOption.ts +205 -0
- package/src/lib/splitCommaSeparatedGlobs.ts +16 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createServicePathMatch } from './createServicePathMatch.js';
|
|
2
|
+
import { Service } from './open-api/getServices.js';
|
|
3
|
+
import {
|
|
4
|
+
OperationGlobMethods,
|
|
5
|
+
parseOperationGlobs,
|
|
6
|
+
} from './parseOperationGlobs.js';
|
|
7
|
+
import { splitCommaSeparatedGlobs } from './splitCommaSeparatedGlobs.js';
|
|
8
|
+
|
|
9
|
+
export const processOperationNameModifierOption = (
|
|
10
|
+
modifiers: OperationNameModifier[],
|
|
11
|
+
services: Service[]
|
|
12
|
+
) => {
|
|
13
|
+
if (!modifiers.length)
|
|
14
|
+
return {
|
|
15
|
+
errors: [],
|
|
16
|
+
services,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const operationNameModifiers = modifiers.map((modifier) => ({
|
|
20
|
+
...modifier,
|
|
21
|
+
isPathMatch: createServicePathMatch(
|
|
22
|
+
splitCommaSeparatedGlobs(modifier.pathGlobs)
|
|
23
|
+
),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
type ServiceName = string;
|
|
27
|
+
type ReplacedOperationNameMap = string;
|
|
28
|
+
type OriginalOperationName = string;
|
|
29
|
+
|
|
30
|
+
const serviceOperationReplacements = new Map<
|
|
31
|
+
ServiceName,
|
|
32
|
+
Map<
|
|
33
|
+
ReplacedOperationNameMap,
|
|
34
|
+
Map<OriginalOperationName, OperationNameModifier[]>
|
|
35
|
+
>
|
|
36
|
+
>();
|
|
37
|
+
|
|
38
|
+
const replacedOperationNamesServices = services.map((service) => {
|
|
39
|
+
serviceOperationReplacements.set(service.name, new Map());
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
...service,
|
|
43
|
+
operations: service.operations.map((operation) => {
|
|
44
|
+
const operationReplacements = serviceOperationReplacements.get(
|
|
45
|
+
service.name
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (!operationReplacements)
|
|
49
|
+
throw new Error('operationReplacements not found');
|
|
50
|
+
|
|
51
|
+
const operationModifiers = operationNameModifiers.filter(
|
|
52
|
+
(modifier) =>
|
|
53
|
+
modifier.isPathMatch(operation.path) &&
|
|
54
|
+
(modifier.methods === undefined ||
|
|
55
|
+
modifier.methods.includes(operation.method)) &&
|
|
56
|
+
normalizeOperationNameModifierRegex(
|
|
57
|
+
modifier.operationNameModifierRegex
|
|
58
|
+
).test(operation.name)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const replacedOperationName = operationModifiers.reduce<string>(
|
|
62
|
+
(operationName, modifier) =>
|
|
63
|
+
operationName.replace(
|
|
64
|
+
normalizeOperationNameModifierRegex(
|
|
65
|
+
modifier.operationNameModifierRegex
|
|
66
|
+
),
|
|
67
|
+
modifier.operationNameModifierReplace
|
|
68
|
+
),
|
|
69
|
+
operation.name
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if (replacedOperationName !== operation.name) {
|
|
73
|
+
if (!operationReplacements.has(replacedOperationName))
|
|
74
|
+
operationReplacements.set(replacedOperationName, new Map());
|
|
75
|
+
operationReplacements.get(replacedOperationName)?.set(
|
|
76
|
+
operation.name,
|
|
77
|
+
operationModifiers.map(
|
|
78
|
+
({ isPathMatch: _, ...operationModifiersRest }) =>
|
|
79
|
+
operationModifiersRest
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
...operation,
|
|
86
|
+
name: replacedOperationName,
|
|
87
|
+
};
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const errors = Array.from(serviceOperationReplacements).flatMap(
|
|
93
|
+
([serviceName, modifiedOperations]) =>
|
|
94
|
+
Array.from(modifiedOperations).flatMap(
|
|
95
|
+
([replacedOperationName, operationModifierMap]) => {
|
|
96
|
+
if (operationModifierMap.size > 1) {
|
|
97
|
+
return Array.from(operationModifierMap).map(
|
|
98
|
+
([originalOperationName, modifiers]) => ({
|
|
99
|
+
serviceName,
|
|
100
|
+
replacedOperationName,
|
|
101
|
+
originalOperationName,
|
|
102
|
+
modifiers,
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const [originalOperationName, modifiers] =
|
|
108
|
+
Array.from(operationModifierMap).at(0) ?? [];
|
|
109
|
+
|
|
110
|
+
if (modifiers && modifiers.length > 1) {
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
serviceName,
|
|
114
|
+
replacedOperationName,
|
|
115
|
+
originalOperationName,
|
|
116
|
+
modifiers,
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
errors,
|
|
128
|
+
services: replacedOperationNamesServices,
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
function normalizeOperationNameModifierRegex(regex: string) {
|
|
133
|
+
return new RegExp(regex, 'g');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export type OperationNameModifier = {
|
|
137
|
+
methods: OperationGlobMethods[] | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Glob pattern to match service paths, eg: `/foo,/bar/**`
|
|
140
|
+
*/
|
|
141
|
+
pathGlobs: string;
|
|
142
|
+
/**
|
|
143
|
+
* Regular expression to match operation names
|
|
144
|
+
*/
|
|
145
|
+
operationNameModifierRegex: string;
|
|
146
|
+
/**
|
|
147
|
+
* Replacement string for matched operation names
|
|
148
|
+
*/
|
|
149
|
+
operationNameModifierReplace: string;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Parses the given options string into a structured format.
|
|
154
|
+
*
|
|
155
|
+
* @param optionItems - The configuration string to parse. Eg. `/foo,/bar/**:post[A-Z][A-Za-z]+sId[A-Z][A-Za-z]+ ==> createOne` or `post /** ==> createOne`
|
|
156
|
+
* @returns The parsed configuration.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const parsedConfig = parseOperationNameModifier("/foo,/bar/**:/**:post[A-Z][A-Za-z]+sId[A-Z][A-Za-z]+ ==> createOne");
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export function parseOperationNameModifier(
|
|
164
|
+
...optionItems: string[]
|
|
165
|
+
): OperationNameModifier[] {
|
|
166
|
+
const globOperationNameModifierMap: Array<OperationNameModifier> = [];
|
|
167
|
+
|
|
168
|
+
for (const optionItem of optionItems) {
|
|
169
|
+
const operationGlobsRaw = optionItem.slice(
|
|
170
|
+
0,
|
|
171
|
+
Math.max(0, optionItem.indexOf(':'))
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (!operationGlobsRaw.length)
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Invalid operation name modifier: ${optionItem}. Must be in the format of 'pathGlobs:operationNameModifierRegex ==> operationNameModifierReplace'`
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const modifierPattern = optionItem.slice(operationGlobsRaw.length + 1);
|
|
180
|
+
|
|
181
|
+
const patternRegex = modifierPattern.slice(
|
|
182
|
+
0,
|
|
183
|
+
modifierPattern.indexOf('==>')
|
|
184
|
+
);
|
|
185
|
+
const patternReplace = modifierPattern.slice(
|
|
186
|
+
modifierPattern.indexOf('==>') + '==>'.length + 1
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const { methods, pathGlobs } = parseOperationGlobs(operationGlobsRaw);
|
|
190
|
+
|
|
191
|
+
if (!splitCommaSeparatedGlobs(pathGlobs).length)
|
|
192
|
+
throw new Error(
|
|
193
|
+
`Invalid path glob: ${pathGlobs}. Must be a comma-separated list of globs.`
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
globOperationNameModifierMap.push({
|
|
197
|
+
methods,
|
|
198
|
+
pathGlobs,
|
|
199
|
+
operationNameModifierRegex: patternRegex.trim(),
|
|
200
|
+
operationNameModifierReplace: patternReplace.trim(),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return globOperationNameModifierMap;
|
|
205
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a comma-separated list of globs
|
|
3
|
+
* @param commaSeparatedGlobs - Example: `/foo , /bar/**, ,`
|
|
4
|
+
* @returns Example: `/foo,/bar/**`
|
|
5
|
+
*/
|
|
6
|
+
export function splitCommaSeparatedGlobs(
|
|
7
|
+
commaSeparatedGlobs: string | undefined
|
|
8
|
+
): string[] {
|
|
9
|
+
if (commaSeparatedGlobs === undefined) return [];
|
|
10
|
+
if (typeof commaSeparatedGlobs !== 'string') throw new Error('Invalid input');
|
|
11
|
+
|
|
12
|
+
return commaSeparatedGlobs
|
|
13
|
+
.split(',')
|
|
14
|
+
.map((path) => path.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
}
|