@aloma.io/integration-sdk 3.8.68 → 3.8.70
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/FINDINGS-PLAT-47.md +253 -0
- package/OPENAPI_TO_CONNECTOR.md +4 -1
- package/build/internal/fetcher/fetcher.d.mts +8 -0
- package/build/internal/fetcher/fetcher.mjs +47 -3
- package/build/openapi-to-connector.mjs +5 -2
- package/build/transform/index.d.mts +2 -2
- package/build/transform/index.mjs +493 -78
- package/package.json +3 -3
- package/src/internal/fetcher/fetcher.mts +52 -3
- package/src/openapi-to-connector.mts +6 -2
- package/src/transform/index.mts +530 -96
- package/test/fetcher-query-params.test.mjs +294 -0
- package/test/fixtures/transform/basic/expected.json +9 -0
- package/test/fixtures/transform/basic/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/basic/src/controller/index.mts +30 -0
- package/test/fixtures/transform/basic/tsconfig.json +1 -0
- package/test/fixtures/transform/interface-param/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/interface-param/src/controller/index.mts +12 -0
- package/test/fixtures/transform/interface-param/tsconfig.json +1 -0
- package/test/fixtures/transform/overloads/expected.json +6 -0
- package/test/fixtures/transform/overloads/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/overloads/src/controller/index.mts +11 -0
- package/test/fixtures/transform/overloads/tsconfig.json +1 -0
- package/test/fixtures/transform/tdd-stub/expected.json +8 -0
- package/test/fixtures/transform/tdd-stub/src/controller/abstract.mts +6 -0
- package/test/fixtures/transform/tdd-stub/src/controller/index.mts +204 -0
- package/test/fixtures/transform/tdd-stub/tsconfig.json +1 -0
- package/test/fixtures/transform/two-exports/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/two-exports/src/controller/index.mts +9 -0
- package/test/fixtures/transform/two-exports/tsconfig.json +1 -0
- package/test/fixtures/transform/type-error/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/type-error/src/controller/index.mts +7 -0
- package/test/fixtures/transform/type-error/tsconfig.json +1 -0
- package/test/fixtures/transform/typed/expected.json +8 -0
- package/test/fixtures/transform/typed/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/typed/src/controller/index.mts +13 -0
- package/test/fixtures/transform/typed/tsconfig.json +1 -0
- package/test/fixtures/transform/visibility/expected.json +9 -0
- package/test/fixtures/transform/visibility/src/controller/abstract.mts +5 -0
- package/test/fixtures/transform/visibility/src/controller/index.mts +19 -0
- package/test/fixtures/transform/visibility/tsconfig.json +1 -0
- package/test/openapi-to-connector.test.mts +7 -0
- package/test/transform.test.mjs +68 -0
- package/tools/mutation-run.mjs +23 -5
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
import {unwrap} from '../util/index.mjs';
|
|
2
2
|
|
|
3
|
+
class ParamsError extends Error {}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* build a query string from request params: undefined and null are skipped, arrays become repeated keys,
|
|
7
|
+
* objects are refused; values are encoded by URLSearchParams
|
|
8
|
+
*/
|
|
9
|
+
const toQuery = (params: any): string => {
|
|
10
|
+
if (params == null) return '';
|
|
11
|
+
if (params instanceof URLSearchParams) return params.toString();
|
|
12
|
+
if (typeof params !== 'object' || Array.isArray(params)) throw new ParamsError('params must be an object');
|
|
13
|
+
|
|
14
|
+
const query = new URLSearchParams();
|
|
15
|
+
const add = (key: string, value: any) => {
|
|
16
|
+
if (value == null) return;
|
|
17
|
+
if (typeof value === 'object') {
|
|
18
|
+
throw new ParamsError(`params.${key} is an object; only strings, numbers, booleans and arrays of them are sent`);
|
|
19
|
+
}
|
|
20
|
+
query.append(key, String(value));
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
for (const [key, value] of Object.entries(params)) {
|
|
24
|
+
if (Array.isArray(value)) value.forEach((item) => add(key, item));
|
|
25
|
+
else add(key, value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return query.toString();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const withQuery = (url: string, query: string): string => {
|
|
32
|
+
if (!query) return url;
|
|
33
|
+
|
|
34
|
+
const hash = url.indexOf('#');
|
|
35
|
+
const base = hash < 0 ? url : url.slice(0, hash);
|
|
36
|
+
const sep = !base.includes('?') ? '?' : /[?&]$/.test(base) ? '' : '&';
|
|
37
|
+
|
|
38
|
+
return base + sep + query + (hash < 0 ? '' : url.slice(hash));
|
|
39
|
+
};
|
|
40
|
+
|
|
3
41
|
/**
|
|
4
42
|
* http request fetcher
|
|
5
43
|
*/
|
|
@@ -73,6 +111,11 @@ export default class Fetcher {
|
|
|
73
111
|
* request body like "hello world" or {hello: "world"}
|
|
74
112
|
*/
|
|
75
113
|
body?: any;
|
|
114
|
+
/**
|
|
115
|
+
* query parameters like {limit: 10, properties: ["a", "b"]}, appended to the url;
|
|
116
|
+
* undefined and null are skipped, arrays become repeated keys, objects are refused
|
|
117
|
+
*/
|
|
118
|
+
params?: {[key: string]: any} | URLSearchParams;
|
|
76
119
|
},
|
|
77
120
|
retries?: number,
|
|
78
121
|
args: any = {}
|
|
@@ -95,6 +138,8 @@ export default class Fetcher {
|
|
|
95
138
|
delete options0.url;
|
|
96
139
|
|
|
97
140
|
theURL = !baseUrl ? url : `${baseUrl?.endsWith('/') ? baseUrl : baseUrl + '/'}${url}`.replace(/\/\/+/gi, '/');
|
|
141
|
+
// after the slash collapse, so encoded values are not altered; options0 keeps params for retries
|
|
142
|
+
const fullURL = withQuery(theURL, toQuery(options0.params));
|
|
98
143
|
|
|
99
144
|
if (!options0?.headers || !options0?.headers?.Accept) {
|
|
100
145
|
options0.headers = {
|
|
@@ -120,8 +165,9 @@ export default class Fetcher {
|
|
|
120
165
|
}
|
|
121
166
|
|
|
122
167
|
const timeout = Math.min(options0?.timeout || 30 * 60 * 1000, 30 * 60 * 1000);
|
|
123
|
-
const
|
|
124
|
-
|
|
168
|
+
const {params, ...init} = options0;
|
|
169
|
+
const ret = await fetch(fullURL, {
|
|
170
|
+
...init,
|
|
125
171
|
signal: AbortSignal.timeout(timeout),
|
|
126
172
|
});
|
|
127
173
|
const status = await ret.status;
|
|
@@ -144,6 +190,8 @@ export default class Fetcher {
|
|
|
144
190
|
|
|
145
191
|
return unwrap(ret, options0);
|
|
146
192
|
} catch (e: any) {
|
|
193
|
+
if (e instanceof ParamsError) throw e;
|
|
194
|
+
|
|
147
195
|
// too many requests
|
|
148
196
|
if (e.status === 429) {
|
|
149
197
|
return local.onError(e, url, options0, retries, args, true);
|
|
@@ -156,7 +204,8 @@ export default class Fetcher {
|
|
|
156
204
|
|
|
157
205
|
--retries;
|
|
158
206
|
|
|
159
|
-
|
|
207
|
+
// without the query string: its values may hold ids or emails
|
|
208
|
+
console.log(theURL.split('?')[0], e);
|
|
160
209
|
|
|
161
210
|
if (retries <= 0) throw e;
|
|
162
211
|
|
|
@@ -126,10 +126,14 @@ export class OpenAPIToConnector {
|
|
|
126
126
|
const validationResult = OpenAPISchema.safeParse(parsed);
|
|
127
127
|
if (!validationResult.success) {
|
|
128
128
|
// Check if the errors are just about missing 'type' fields in schemas
|
|
129
|
-
|
|
129
|
+
// zod 4 reports .issues (zod 3's .errors is gone), and a missing field is an invalid_type issue whose message no
|
|
130
|
+
// longer reads 'Required'
|
|
131
|
+
const isMissing = (err: any) =>
|
|
132
|
+
err.message.includes('Required') || (err.code === 'invalid_type' && /received undefined/.test(err.message));
|
|
133
|
+
const criticalErrors = validationResult.error.issues.filter((err) => {
|
|
130
134
|
const path = err.path.join('.');
|
|
131
135
|
// Allow missing 'type' in schema definitions as many OpenAPI specs don't include it
|
|
132
|
-
return !path.includes('components.schemas') || !err
|
|
136
|
+
return !path.includes('components.schemas') || !isMissing(err);
|
|
133
137
|
});
|
|
134
138
|
|
|
135
139
|
if (criticalErrors.length > 0) {
|