@weclapp/sdk 2.0.0-dev.23 → 2.0.0-dev.25

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/cli.js CHANGED
@@ -1,17 +1,18 @@
1
1
  import { fileURLToPath } from 'url';
2
2
  import { resolve, dirname } from 'path';
3
- import { rmdir, stat, readFile, writeFile, rm, cp, mkdir } from 'fs/promises';
4
3
  import { rollup } from 'rollup';
5
4
  import terser from '@rollup/plugin-terser';
6
- import ts from 'rollup-plugin-ts';
5
+ import ts from '@rollup/plugin-typescript';
7
6
  import indentString from 'indent-string';
8
7
  import { snakeCase, pascalCase, camelCase } from 'change-case';
9
8
  import chalk from 'chalk';
10
9
  import { OpenAPIV3 } from 'openapi-types';
11
10
  import { createHash } from 'crypto';
11
+ import { stat, readFile, rm, cp, writeFile, mkdir } from 'fs/promises';
12
12
  import { config } from 'dotenv';
13
13
  import yargs from 'yargs';
14
14
  import { hideBin } from 'yargs/helpers';
15
+ import pkg from '../package.json' with { type: 'json' };
15
16
  import prettyMs from 'pretty-ms';
16
17
 
17
18
  var Target;
@@ -28,87 +29,74 @@ const isRXTarget = (target) => {
28
29
  return target === Target.BROWSER_RX || target === Target.NODE_RX;
29
30
  };
30
31
  const resolveResponseType = (target) => {
31
- return isRXTarget(target) ? 'Observable' : 'Promise';
32
+ return isRXTarget(target) ? "Observable" : "Promise";
32
33
  };
33
34
  const resolveBinaryType = (target) => {
34
- return isNodeTarget(target) ? 'Buffer' : 'Blob';
35
+ return isNodeTarget(target) ? "Buffer" : "Blob";
35
36
  };
36
37
 
37
38
  const currentDirname = () => {
38
39
  // Go one level up as the CLI is inside a folder
39
- return fileURLToPath(new URL('..', import.meta.url));
40
+ return fileURLToPath(new URL("..", import.meta.url));
40
41
  };
41
42
 
42
- const tsconfig = resolve(currentDirname(), './tsconfig.lib.json');
43
- const resolveGlobals = (...globals) => Object.fromEntries(globals.map(v => [v, '*']));
43
+ const tsconfig = resolve(currentDirname(), "./tsconfig.sdk.json");
44
+ const resolveGlobals = (...globals) => Object.fromEntries(globals.map((v) => [v, "*"]));
44
45
  const generateOutput = (config) => ({
45
46
  sourcemap: true,
46
47
  banner: `/* weclapp sdk */`,
47
- ...config
48
+ ...config,
48
49
  });
49
50
  const bundle = async (workingDirectory, target) => {
50
- const dist = (...paths) => resolve(workingDirectory, 'dist', ...paths);
51
- const src = (...paths) => resolve(workingDirectory, 'src', ...paths);
51
+ const dist = (...paths) => resolve(workingDirectory, "dist", ...paths);
52
+ const src = (...paths) => resolve(workingDirectory, "src", ...paths);
52
53
  const generateNodeOutput = () => [
53
54
  generateOutput({
54
- file: dist('index.cjs'),
55
- format: 'cjs',
56
- globals: resolveGlobals('node-fetch', 'url')
55
+ file: dist("index.cjs"),
56
+ format: "cjs",
57
+ globals: resolveGlobals("node-fetch", "url"),
57
58
  }),
58
59
  generateOutput({
59
- file: dist('index.js'),
60
- format: 'es',
61
- globals: resolveGlobals('node-fetch', 'url')
62
- })
60
+ file: dist("index.js"),
61
+ format: "es",
62
+ globals: resolveGlobals("node-fetch", "url"),
63
+ }),
63
64
  ];
64
- // Remove build dir
65
- await rmdir(dist()).catch(() => void 0);
66
65
  const bundles = {
67
66
  [Target.BROWSER_PROMISES]: () => ({
68
- input: src('browser.ts'),
67
+ input: src("index.ts"),
68
+ plugins: [ts({ tsconfig, declarationDir: dist() }), terser()],
69
69
  output: [
70
70
  generateOutput({
71
- file: dist('index.cjs'),
72
- name: 'Weclapp',
73
- format: 'umd'
71
+ file: dist("index.js"),
72
+ format: "es",
74
73
  }),
75
- generateOutput({
76
- file: dist('index.js'),
77
- format: 'es'
78
- })
79
74
  ],
80
- plugins: [ts({ tsconfig }), terser()]
81
75
  }),
82
76
  [Target.BROWSER_RX]: () => ({
83
- external: ['rxjs'],
84
- input: src('browser.rx.ts'),
85
- plugins: [ts({ tsconfig }), terser()],
77
+ input: src("index.ts"),
78
+ plugins: [ts({ tsconfig, declarationDir: dist() }), terser()],
79
+ external: ["rxjs"],
86
80
  output: [
87
81
  generateOutput({
88
- file: dist('index.cjs'),
89
- name: 'Weclapp',
90
- format: 'umd',
91
- globals: resolveGlobals('rxjs')
82
+ file: dist("index.js"),
83
+ format: "es",
84
+ globals: resolveGlobals("rxjs"),
92
85
  }),
93
- generateOutput({
94
- file: dist('index.js'),
95
- format: 'es',
96
- globals: resolveGlobals('rxjs')
97
- })
98
- ]
86
+ ],
99
87
  }),
100
88
  [Target.NODE_PROMISES]: () => ({
101
- input: src('node.ts'),
89
+ input: src("index.ts"),
90
+ plugins: [ts({ tsconfig, declarationDir: dist() }), terser()],
91
+ external: ["node-fetch", "url"],
102
92
  output: generateNodeOutput(),
103
- external: ['node-fetch', 'url'],
104
- plugins: [ts({ tsconfig })]
105
93
  }),
106
94
  [Target.NODE_RX]: () => ({
107
- input: src('node.rx.ts'),
95
+ input: src("index.ts"),
96
+ plugins: [ts({ tsconfig, declarationDir: dist() }), terser()],
97
+ external: ["node-fetch", "url", "rxjs"],
108
98
  output: generateNodeOutput(),
109
- external: ['node-fetch', 'url', 'rxjs'],
110
- plugins: [ts({ tsconfig })]
111
- })
99
+ }),
112
100
  };
113
101
  const config = bundles[target]();
114
102
  const bundle = await rollup(config);
@@ -125,8 +113,11 @@ const generateString = (str) => `'${str}'`;
125
113
  const generateStrings = (str) => str.map(generateString);
126
114
 
127
115
  const generateImport = (opt) => {
128
- const imports = [opt.default, opt.imports?.length ? `{${opt.imports.join(', ')}}` : ''];
129
- return `import ${imports.filter(Boolean).join(', ')} from ${generateString(opt.src)};`;
116
+ const imports = [
117
+ opt.default,
118
+ opt.imports?.length ? `{${opt.imports.join(", ")}}` : "",
119
+ ];
120
+ return `import ${imports.filter(Boolean).join(", ")} from ${generateString(opt.src)};`;
130
121
  };
131
122
 
132
123
  /**
@@ -139,9 +130,9 @@ const indent = (s, level = 1) => {
139
130
  };
140
131
 
141
132
  const generateStatements = (...statements) => statements
142
- .map(v => v.trim())
143
- .filter(v => v.length)
144
- .join('\n\n');
133
+ .map((v) => v.trim())
134
+ .filter((v) => v.length)
135
+ .join("\n\n");
145
136
  const generateBlockStatements = (...statements) => `{\n${indent(generateStatements(...statements))}\n}`;
146
137
 
147
138
  var globalConfig = "export type RequestPayloadMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';\n\nexport interface RequestPayload {\n method?: RequestPayloadMethod;\n query?: Record<string, any>;\n body?: any;\n unwrap?: boolean;\n forceBlob?: boolean;\n}\n\nexport interface ServiceConfig {\n\n // Your API-Key, this is optional in the sense of if you omit this, and you're in a browser, the\n // cookie-authentication (include-credentials) will be used.\n key?: string;\n\n // Your domain, if omitted location.host will be used (browser env).\n host?: string;\n\n // If you want to use https, defaults to location.protocol (browser env).\n secure?: boolean;\n\n // If you want that some and count requests are bundled into multi requests.\n multiRequest?: boolean;\n\n // If you want that the ignoreMissingProperties parameter to be set to true for every post request.\n ignoreMissingProperties?: boolean;\n\n // Optional request/response interceptors.\n interceptors?: {\n\n // Takes the generated request, you can either return a new request,\n // a response (which will be taken as \"the\" response) or nothing.\n // The payload contains the raw input generated by the SDK.\n request?: (request: Request, payload: RequestPayload) => Request | Response | void | Promise<Request | Response | void>;\n\n // Takes the response. This can either be the one from the server or an\n // artificially-crafted one by the request interceptor.\n response?: (response: Response) => Response | void | Promise<Response | void>;\n };\n}\n\ntype ServiceConfigWithoutMultiRequest = Omit<ServiceConfig, 'multiRequest'>;\n\nlet globalConfig: ServiceConfig | undefined;\nexport const getGlobalConfig = (): ServiceConfig | undefined => globalConfig;\nexport const setGlobalConfig = (cfg?: ServiceConfig) => globalConfig = cfg;\n\nexport const getHost = (cfg: ServiceConfig) => {\n let host = cfg.host?.replace(/^https?:\\/\\//, '');\n if (!host && typeof location !== 'undefined') {\n host = location.host;\n }\n\n if (!host) {\n throw new Error('Please specify a host');\n }\n\n return host;\n};\n\nexport const getProtocol = (cfg: ServiceConfig) => {\n const protocol =\n cfg.secure !== undefined\n ? cfg.secure\n ? 'https:'\n : 'http:'\n : typeof location !== 'undefined'\n ? location.protocol\n : undefined;\n\n if (!protocol) {\n throw new Error('Please specify a protocol (secure)');\n }\n\n return protocol;\n};";
@@ -155,11 +146,11 @@ var types = "export type DeepPartial<T> = T extends object ? {\n [P in keyof
155
146
  const resolveImports = (target) => {
156
147
  const imports = [];
157
148
  if (isRXTarget(target)) {
158
- imports.push(generateImport({ src: 'rxjs', imports: ['defer', 'Observable'] }));
149
+ imports.push(generateImport({ src: "rxjs", imports: ["defer", "Observable"] }));
159
150
  }
160
- return imports.join('\n');
151
+ return imports.join("\n");
161
152
  };
162
- const resolveMappings = (target) => `const wrapResponse = ${isRXTarget(target) ? 'defer' : '(v: (...args: any[]) => any) => v()'};`;
153
+ const resolveMappings = (target) => `const wrapResponse = ${isRXTarget(target) ? "defer" : "(v: (...args: any[]) => any) => v()"};`;
163
154
  const resolveBinaryClass = (target) => `const resolveBinaryObject = () => ${resolveBinaryType(target)};`;
164
155
  const generateBase = (target, apiVersion) => {
165
156
  return generateStatements(resolveImports(target), resolveMappings(target), resolveBinaryClass(target), `const apiVersion = ${apiVersion}`, globalConfig, multiRequest, types, root);
@@ -167,7 +158,7 @@ const generateBase = (target, apiVersion) => {
167
158
 
168
159
  const transformKey = (s) => snakeCase(s).toUpperCase();
169
160
  const generateEnum = (name, values) => {
170
- const props = indent(values.map(v => `${transformKey(v)} = ${generateString(v)}`).join(',\n'));
161
+ const props = indent(values.map((v) => `${transformKey(v)} = ${generateString(v)}`).join(",\n"));
171
162
  return `export enum ${name} {\n${props}\n}`;
172
163
  };
173
164
 
@@ -175,31 +166,34 @@ const generateEnum = (name, values) => {
175
166
  const loosePascalCase = (str) => str[0].toUpperCase() + str.slice(1);
176
167
 
177
168
  const isObject = (v) => {
178
- return v !== null && typeof v === 'object' && !Array.isArray(v);
169
+ return v !== null && typeof v === "object" && !Array.isArray(v);
179
170
  };
180
171
  const isParameterObject = (v) => {
181
- return isObject(v) && typeof v.name === 'string' && typeof v.in === 'string';
172
+ return isObject(v) && typeof v.name === "string" && typeof v.in === "string";
182
173
  };
183
174
  const isReferenceObject = (v) => {
184
- return isObject(v) && typeof v.$ref === 'string';
175
+ return isObject(v) && typeof v.$ref === "string";
185
176
  };
186
177
  const isObjectSchemaObject = (v) => {
187
- return isObject(v) && v.type === 'object' && isObject(v.properties);
178
+ return isObject(v) && v.type === "object" && isObject(v.properties);
188
179
  };
189
180
  const isEnumSchemaObject = (v) => {
190
- return isObject(v) && v.type === 'string' && Array.isArray(v.enum);
181
+ return isObject(v) && v.type === "string" && Array.isArray(v.enum);
191
182
  };
192
183
  const isArraySchemaObject = (v) => {
193
- return isObject(v) && v.type === 'array' && typeof v.items === 'object';
184
+ return isObject(v) && v.type === "array" && typeof v.items === "object";
194
185
  };
195
186
  const isResponseObject = (v) => {
196
- return isObject(v) && typeof v.description === 'string';
187
+ return isObject(v) && typeof v.description === "string";
197
188
  };
198
189
  const isNonArraySchemaObject = (v) => {
199
- return isObject(v) && ['string', 'undefined'].includes(typeof v.type);
190
+ return isObject(v) && ["string", "undefined"].includes(typeof v.type);
200
191
  };
201
192
  const isRelatedEntitySchema = (v) => {
202
- return isObject(v) && isNonArraySchemaObject(v) && 'x-weclapp' in v && isObject(v['x-weclapp']);
193
+ return (isObject(v) &&
194
+ isNonArraySchemaObject(v) &&
195
+ "x-weclapp" in v &&
196
+ isObject(v["x-weclapp"]));
203
197
  };
204
198
 
205
199
  const generateEnums = (schemas) => {
@@ -210,7 +204,7 @@ const generateEnums = (schemas) => {
210
204
  if (!enums.has(name)) {
211
205
  enums.set(name, {
212
206
  properties: schema.enum,
213
- source: generateEnum(name, schema.enum)
207
+ source: generateEnum(name, schema.enum),
214
208
  });
215
209
  }
216
210
  }
@@ -218,57 +212,62 @@ const generateEnums = (schemas) => {
218
212
  return enums;
219
213
  };
220
214
 
221
- const concat = (strings, separator = ', ', maxLength = 80) => {
215
+ const concat = (strings, separator = ", ", maxLength = 80) => {
222
216
  const joined = strings.join(separator);
223
217
  if (joined.length > maxLength) {
224
218
  const length = strings.length - 1;
225
219
  return `\n${indent(strings
226
220
  .map((value, index) => index === length ? value : `${(value + separator).trim()}\n`)
227
- .join(''))}\n`;
221
+ .join(""))}\n`;
228
222
  }
229
223
  else {
230
224
  return joined;
231
225
  }
232
226
  };
233
227
 
234
- /* eslint-disable no-use-before-define */
235
228
  const createReferenceType = (value) => ({
236
- type: 'reference',
237
- toString: () => loosePascalCase(value)
229
+ type: "reference",
230
+ toString: () => loosePascalCase(value),
238
231
  });
239
232
  const createRawType = (value) => ({
240
- type: 'raw',
241
- toString: () => value
233
+ type: "raw",
234
+ toString: () => value,
242
235
  });
243
236
  const createArrayType = (value) => ({
244
- type: 'array',
245
- toString: () => `(${value.toString()})[]`
237
+ type: "array",
238
+ toString: () => `(${value.toString()})[]`,
246
239
  });
247
240
  const createTupleType = (value) => ({
248
- type: 'tuple',
249
- toString: () => concat([...new Set(value.map(v => typeof v === 'string' ? `'${v}'` : v.toString()))], ' | ')
241
+ type: "tuple",
242
+ toString: () => concat([
243
+ ...new Set(value.map((v) => (typeof v === "string" ? `'${v}'` : v.toString()))),
244
+ ], " | "),
250
245
  });
251
246
  const createObjectType = (value, required = []) => ({
252
- type: 'object',
247
+ type: "object",
253
248
  isFullyOptional: () => {
254
- return !required.length && Object.values(value)
255
- .filter(v => v?.type === 'object')
256
- .every(v => v.isFullyOptional());
249
+ return (!required.length &&
250
+ Object.values(value)
251
+ .filter((v) => v?.type === "object")
252
+ .every((v) => v.isFullyOptional()));
257
253
  },
258
254
  toString: (propagateOptionalProperties = false) => {
259
255
  const properties = Object.entries(value)
260
- .filter(v => v[1])
261
- .map(v => {
256
+ .filter((v) => v[1])
257
+ .map((v) => {
262
258
  const name = v[0];
263
259
  const value = v[1];
264
- const isRequired = required.includes(name) || (value.type === 'object' && !value.isFullyOptional() && propagateOptionalProperties);
265
- return `${name + (isRequired ? '' : '?')}: ${value.toString()};`;
260
+ const isRequired = required.includes(name) ||
261
+ (value.type === "object" &&
262
+ !value.isFullyOptional() &&
263
+ propagateOptionalProperties);
264
+ return `${name + (isRequired ? "" : "?")}: ${value.toString()};`;
266
265
  });
267
- return properties.length ? `{\n${indent(properties.join('\n'))}\n}` : '{}';
268
- }
266
+ return properties.length ? `{\n${indent(properties.join("\n"))}\n}` : "{}";
267
+ },
269
268
  });
270
269
  const getRefName = (obj) => {
271
- return obj.$ref.replace(/.*\//, '');
270
+ return obj.$ref.replace(/.*\//, "");
272
271
  };
273
272
  const convertToTypeScriptType = (schema, property) => {
274
273
  if (isReferenceObject(schema)) {
@@ -276,27 +275,33 @@ const convertToTypeScriptType = (schema, property) => {
276
275
  }
277
276
  else {
278
277
  switch (schema.type) {
279
- case 'integer':
280
- case 'number':
281
- return createRawType('number');
282
- case 'string':
278
+ case "integer":
279
+ case "number":
280
+ return createRawType("number");
281
+ case "string":
283
282
  if (schema.enum) {
284
- return property ? createReferenceType(property) : createTupleType(schema.enum);
283
+ return property
284
+ ? createReferenceType(property)
285
+ : createTupleType(schema.enum);
285
286
  }
286
287
  else {
287
- return schema.format === 'binary' ? createRawType('binary') : createRawType('string');
288
+ return schema.format === "binary"
289
+ ? createRawType("binary")
290
+ : createRawType("string");
288
291
  }
289
- case 'boolean':
290
- return createRawType('boolean');
291
- case 'object': {
292
+ case "boolean":
293
+ return createRawType("boolean");
294
+ case "object": {
292
295
  const { properties = {}, required = [] } = schema;
293
- return createObjectType(Object.fromEntries(Object.entries(properties)
294
- .map(v => [v[0], convertToTypeScriptType(v[1])])), required);
296
+ return createObjectType(Object.fromEntries(Object.entries(properties).map((v) => [
297
+ v[0],
298
+ convertToTypeScriptType(v[1]),
299
+ ])), required);
295
300
  }
296
- case 'array':
301
+ case "array":
297
302
  return createArrayType(convertToTypeScriptType(schema.items, property));
298
303
  default:
299
- return createRawType('unknown');
304
+ return createRawType("unknown");
300
305
  }
301
306
  }
302
307
  };
@@ -312,10 +317,13 @@ const setEntityEnumProperty = (enums, prop, meta) => {
312
317
  }
313
318
  };
314
319
  const extractPropertyMetaData = (enums, meta, prop) => {
315
- const result = { service: meta.service, entity: meta.entity };
320
+ const result = {
321
+ service: meta.service,
322
+ entity: meta.entity,
323
+ };
316
324
  if (isReferenceObject(prop)) {
317
325
  setEntityEnumProperty(enums, prop, result);
318
- result.type = 'reference';
326
+ result.type = "reference";
319
327
  return result;
320
328
  }
321
329
  result.type = prop.type;
@@ -325,47 +333,47 @@ const extractPropertyMetaData = (enums, meta, prop) => {
325
333
  if (isArraySchemaObject(prop)) {
326
334
  if (isReferenceObject(prop.items)) {
327
335
  setEntityEnumProperty(enums, prop.items, result);
328
- result.format = 'reference';
336
+ result.format = "reference";
329
337
  }
330
338
  else {
331
- result.format = 'string';
339
+ result.format = "string";
332
340
  }
333
341
  }
334
342
  return result;
335
343
  };
336
344
 
337
345
  const generateInlineComment = (comment) => `/** ${comment} */`;
338
- const generateBlockComment = (comment, body) => `/**\n${comment.trim().replace(/^ */gm, ' * ')}\n */${body ? `\n${body}` : ''}`;
346
+ const generateBlockComment = (comment, body) => `/**\n${comment.trim().replace(/^ */gm, " * ")}\n */${body ? `\n${body}` : ""}`;
339
347
 
340
348
  const generateType = (name, value) => {
341
349
  return `export type ${name} = ${value.trim()};`;
342
350
  };
343
351
 
344
- const arrayify = (v) => Array.isArray(v) ? v : [v];
352
+ const arrayify = (v) => (Array.isArray(v) ? v : [v]);
345
353
 
346
354
  const generateInterfaceProperties = (entries) => {
347
355
  const properties = entries
348
- .filter(v => v.type !== undefined)
349
- .filter((value, index, array) => array.findIndex(v => v.name === value.name) === index)
356
+ .filter((v) => v.type !== undefined)
357
+ .filter((value, index, array) => array.findIndex((v) => v.name === value.name) === index)
350
358
  .map(({ name, type, required, readonly, comment }) => {
351
- const cmd = comment ? `${generateInlineComment(comment)}\n` : '';
352
- const req = required ? '' : '?';
353
- const rol = readonly ? 'readonly ' : '';
359
+ const cmd = comment ? `${generateInlineComment(comment)}\n` : "";
360
+ const req = required ? "" : "?";
361
+ const rol = readonly ? "readonly " : "";
354
362
  return `${cmd + rol + name + req}: ${type};`;
355
363
  })
356
- .join('\n');
364
+ .join("\n");
357
365
  return properties.length ? `{\n${indent(properties)}\n}` : `{}`;
358
366
  };
359
367
  const generateInterfaceFromObject = (name, obj, propagateOptionalProperties) => `export interface ${name} ${obj.toString(propagateOptionalProperties)}`;
360
368
  const generateInterface = (name, entries, extend) => {
361
- const signature = `${name} ${extend ? `extends ${arrayify(extend).join(', ')}` : ''}`.trim();
369
+ const signature = `${name} ${extend ? `extends ${arrayify(extend).join(", ")}` : ""}`.trim();
362
370
  const body = generateInterfaceProperties(entries);
363
371
  return `export interface ${signature} ${body}`;
364
372
  };
365
373
  const generateInterfaceType = (name, entries, extend) => {
366
374
  const body = generateInterfaceProperties(entries);
367
- const bases = extend ? arrayify(extend).join(' & ') : undefined;
368
- return generateType(name, `${bases ? `${bases} & ` : ''}${body}`);
375
+ const bases = extend ? arrayify(extend).join(" & ") : undefined;
376
+ return generateType(name, `${bases ? `${bases} & ` : ""}${body}`);
369
377
  };
370
378
 
371
379
  const generateEntities = (schemas, enums) => {
@@ -387,7 +395,9 @@ const generateEntities = (schemas, enums) => {
387
395
  let extend = undefined;
388
396
  const processProperties = (props = {}) => {
389
397
  for (const [name, property] of Object.entries(props)) {
390
- const meta = isRelatedEntitySchema(property) ? property['x-weclapp'] : {};
398
+ const meta = isRelatedEntitySchema(property)
399
+ ? property["x-weclapp"]
400
+ : {};
391
401
  if (meta.entity) {
392
402
  const type = `${pascalCase(meta.entity)}[]`;
393
403
  if (schemas.has(meta.entity)) {
@@ -405,14 +415,19 @@ const generateEntities = (schemas, enums) => {
405
415
  }
406
416
  }
407
417
  const type = convertToTypeScriptType(property, name).toString();
408
- const comment = isNonArraySchemaObject(property) ?
409
- property.deprecated ? '@deprecated will be removed.' :
410
- property.format ? `format: ${property.format}` :
411
- undefined : undefined;
418
+ const comment = isNonArraySchemaObject(property)
419
+ ? property.deprecated
420
+ ? "@deprecated will be removed."
421
+ : property.format
422
+ ? `format: ${property.format}`
423
+ : undefined
424
+ : undefined;
412
425
  entityInterface.push({
413
- name, type, comment,
426
+ name,
427
+ type,
428
+ comment,
414
429
  required: meta.required,
415
- readonly: !isReferenceObject(property) && property.readOnly
430
+ readonly: !isReferenceObject(property) && property.readOnly,
416
431
  });
417
432
  properties.set(name, extractPropertyMetaData(enums, meta, property));
418
433
  }
@@ -432,7 +447,7 @@ const generateEntities = (schemas, enums) => {
432
447
  entities.set(schemaName, {
433
448
  extends: extend ? camelCase(extend) : extend,
434
449
  properties,
435
- source
450
+ source,
436
451
  });
437
452
  }
438
453
  return entities;
@@ -443,20 +458,21 @@ const generateEntities = (schemas, enums) => {
443
458
  * @param s String to pluralize.
444
459
  */
445
460
  const pluralize = (s) => {
446
- return s.endsWith('s') ? s :
447
- s.endsWith('y') ? `${s.slice(0, -1)}ies` :
448
- `${s}s`;
461
+ return s.endsWith("s")
462
+ ? s
463
+ : s.endsWith("y")
464
+ ? `${s.slice(0, -1)}ies`
465
+ : `${s}s`;
449
466
  };
450
467
 
451
- /* eslint-disable no-console */
452
- const logger = new class {
468
+ const logger = new (class {
453
469
  active = true;
454
470
  warnings = 0;
455
471
  errors = 0;
456
- write(str = '') {
472
+ write(str = "") {
457
473
  process.stdout.write(str);
458
474
  }
459
- blankLn(str = '') {
475
+ blankLn(str = "") {
460
476
  this.blank(`${str}\n`);
461
477
  }
462
478
  warnLn(str) {
@@ -478,18 +494,18 @@ const logger = new class {
478
494
  this.write(str);
479
495
  }
480
496
  warn(str) {
481
- this.write(`${chalk.yellowBright('[!]')} ${str}`);
497
+ this.write(`${chalk.yellowBright("[!]")} ${str}`);
482
498
  this.warnings++;
483
499
  }
484
500
  error(str) {
485
- this.write(`${chalk.redBright('[X]')} ${str}`);
501
+ this.write(`${chalk.redBright("[X]")} ${str}`);
486
502
  this.errors++;
487
503
  }
488
504
  success(str) {
489
- this.write(`${chalk.greenBright('[✓]')} ${str}`);
505
+ this.write(`${chalk.greenBright("[✓]")} ${str}`);
490
506
  }
491
507
  info(str) {
492
- this.write(`${chalk.blueBright('[i]')} ${str}`);
508
+ this.write(`${chalk.blueBright("[i]")} ${str}`);
493
509
  }
494
510
  debug(str) {
495
511
  this.write(`[-] ${str}`);
@@ -497,15 +513,18 @@ const logger = new class {
497
513
  printSummary() {
498
514
  const format = (v, name, fail, ok) => {
499
515
  const color = v ? fail : ok;
500
- return v === 0 ? `${color('zero')} ${pluralize(name)}` :
501
- v === 1 ? `${color('one')} ${name}` : `${color(v)} ${pluralize(name)}`;
516
+ return v === 0
517
+ ? `${color("zero")} ${pluralize(name)}`
518
+ : v === 1
519
+ ? `${color("one")} ${name}`
520
+ : `${color(v)} ${pluralize(name)}`;
502
521
  };
503
- const warnings = format(this.warnings, 'warning', chalk.yellowBright, chalk.greenBright);
504
- const errors = format(this.errors, 'error', chalk.redBright, chalk.greenBright);
522
+ const warnings = format(this.warnings, "warning", chalk.yellowBright, chalk.greenBright);
523
+ const errors = format(this.errors, "error", chalk.redBright, chalk.greenBright);
505
524
  const info = `Finished with ${warnings} and ${errors}.`;
506
- this[this.errors ? 'errorLn' : this.warnings ? 'warnLn' : 'successLn'](info);
525
+ this[this.errors ? "errorLn" : this.warnings ? "warnLn" : "successLn"](info);
507
526
  }
508
- };
527
+ })();
509
528
 
510
529
  /**
511
530
  * ROOT => /article
@@ -523,34 +542,46 @@ var WeclappEndpointType;
523
542
  WeclappEndpointType["GENERIC_ENTITY"] = "GENERIC_ENTITY";
524
543
  })(WeclappEndpointType || (WeclappEndpointType = {}));
525
544
  const parseEndpointPath = (path) => {
526
- const [, entity, ...rest] = path.split('/');
545
+ const [, entity, ...rest] = path.split("/");
527
546
  if (!entity) {
528
547
  return undefined;
529
548
  }
530
549
  if (!rest.length) {
531
550
  return { path, entity, type: WeclappEndpointType.ROOT };
532
551
  }
533
- else if (rest[0] === 'count') {
552
+ else if (rest[0] === "count") {
534
553
  return { path, entity, type: WeclappEndpointType.COUNT };
535
554
  }
536
- else if (rest[0] === 'id') {
537
- return rest.length === 2 ?
538
- { path, entity, type: WeclappEndpointType.ENTITY } :
539
- { path, entity, method: rest[2], type: WeclappEndpointType.GENERIC_ENTITY };
555
+ else if (rest[0] === "id") {
556
+ return rest.length === 2
557
+ ? { path, entity, type: WeclappEndpointType.ENTITY }
558
+ : {
559
+ path,
560
+ entity,
561
+ method: rest[2],
562
+ type: WeclappEndpointType.GENERIC_ENTITY,
563
+ };
540
564
  }
541
565
  else if (rest.length === 1) {
542
- return { path, entity, method: rest[1], type: WeclappEndpointType.GENERIC_ROOT };
566
+ return {
567
+ path,
568
+ entity,
569
+ method: rest[1],
570
+ type: WeclappEndpointType.GENERIC_ROOT,
571
+ };
543
572
  }
544
573
  return undefined;
545
574
  };
546
575
 
547
- const generateArrowFunction = ({ name, signature, returns, params }) => {
548
- return `const ${name}: ${signature} = (${params?.join(', ') ?? ''}) =>\n${indent(returns)};`;
576
+ const generateArrowFunction = ({ name, signature, returns, params, }) => {
577
+ return `const ${name}: ${signature} = (${params?.join(", ") ?? ""}) =>\n${indent(returns)};`;
549
578
  };
550
579
 
551
- const generateArrowFunctionType = ({ type, returns = 'void', generics, params }) => {
552
- const genericsString = generics?.length ? `<\n${indent(generics.join(',\n'))}\n>` : '';
553
- const paramsString = params?.length ? `(${params.join(', ')})` : `()`;
580
+ const generateArrowFunctionType = ({ type, returns = "void", generics, params, }) => {
581
+ const genericsString = generics?.length
582
+ ? `<\n${indent(generics.join(",\n"))}\n>`
583
+ : "";
584
+ const paramsString = params?.length ? `(${params.join(", ")})` : `()`;
554
585
  return generateType(type, `${genericsString + paramsString} =>\n${indent(returns)}`);
555
586
  };
556
587
 
@@ -558,21 +589,23 @@ const convertParametersToSchema = (parameters = []) => {
558
589
  const properties = [];
559
590
  const required = [];
560
591
  for (const param of parameters) {
561
- if (isParameterObject(param) && param.in === 'query') {
592
+ if (isParameterObject(param) && param.in === "query") {
562
593
  if (param.schema) {
563
594
  properties.push([param.name, param.schema]);
564
- param.required && required.push(param.name);
595
+ if (param.required)
596
+ required.push(param.name);
565
597
  }
566
598
  }
567
599
  }
568
600
  return {
569
- type: 'object', required,
570
- properties: Object.fromEntries(properties)
601
+ type: "object",
602
+ required,
603
+ properties: Object.fromEntries(properties),
571
604
  };
572
605
  };
573
606
 
574
- const functionName$5 = 'count';
575
- const generateCountEndpoint = ({ aliases, path, target, endpoint }) => {
607
+ const functionName$5 = "count";
608
+ const generateCountEndpoint = ({ aliases, path, target, endpoint, }) => {
576
609
  const service = pascalCase(endpoint.entity);
577
610
  const entity = aliases.get(endpoint.entity) ?? service;
578
611
  const entityFilter = `${entity}_Filter`;
@@ -580,18 +613,20 @@ const generateCountEndpoint = ({ aliases, path, target, endpoint }) => {
580
613
  const entityParameters = `${interfaceName}_Parameters`;
581
614
  const parameterSchema = convertParametersToSchema(path.parameters);
582
615
  const parameters = createObjectType({
583
- params: convertToTypeScriptType(parameterSchema)
616
+ params: convertToTypeScriptType(parameterSchema),
584
617
  });
585
618
  const functionSource = generateArrowFunction({
586
619
  name: functionName$5,
587
620
  signature: interfaceName,
588
621
  returns: `_${functionName$5}(cfg, ${generateString(endpoint.path)}, query)`,
589
- params: ['query']
622
+ params: ["query"],
590
623
  });
591
624
  const interfaceSource = generateArrowFunctionType({
592
625
  type: interfaceName,
593
- params: [`query${parameters.isFullyOptional() ? '?' : ''}: CountQuery<${entityFilter}> & ${entityParameters}`],
594
- returns: `${resolveResponseType(target)}<number>`
626
+ params: [
627
+ `query${parameters.isFullyOptional() ? "?" : ""}: CountQuery<${entityFilter}> & ${entityParameters}`,
628
+ ],
629
+ returns: `${resolveResponseType(target)}<number>`,
595
630
  });
596
631
  return {
597
632
  entity,
@@ -601,9 +636,9 @@ const generateCountEndpoint = ({ aliases, path, target, endpoint }) => {
601
636
  interfaces: [
602
637
  {
603
638
  name: entityParameters,
604
- source: generateInterfaceFromObject(entityParameters, parameters, true)
605
- }
606
- ]
639
+ source: generateInterfaceFromObject(entityParameters, parameters, true),
640
+ },
641
+ ],
607
642
  };
608
643
  };
609
644
 
@@ -620,43 +655,40 @@ const generateBodyType = (body) => {
620
655
  return types.length ? createTupleType(types) : undefined;
621
656
  };
622
657
 
623
- const generateRequestBodyType = ({ requestBody }) => {
624
- return generateBodyType(requestBody) ?? createRawType('unknown');
658
+ const generateRequestBodyType = ({ requestBody, }) => {
659
+ return generateBodyType(requestBody) ?? createRawType("unknown");
625
660
  };
626
661
 
627
- const resolveBodyType = ({ responses }) => Object.entries(responses)
628
- .filter(v => v[0].startsWith('2'))[0]?.[1];
629
- const generateResponseBodyType = (object) => generateBodyType(resolveBodyType(object)) ?? createRawType('void');
662
+ const resolveBodyType = ({ responses, }) => Object.entries(responses).filter((v) => v[0].startsWith("2"))[0]?.[1];
663
+ const generateResponseBodyType = (object) => generateBodyType(resolveBodyType(object)) ?? createRawType("void");
630
664
 
631
- const functionName$4 = 'create';
632
- const generateCreateEndpoint = ({ target, path, endpoint }) => {
665
+ const functionName$4 = "create";
666
+ const generateCreateEndpoint = ({ target, path, endpoint, }) => {
633
667
  const entity = pascalCase(endpoint.entity);
634
668
  const interfaceName = `${entity}Service_${pascalCase(functionName$4)}`;
635
669
  const functionSource = generateArrowFunction({
636
670
  name: functionName$4,
637
671
  signature: interfaceName,
638
672
  returns: `_${functionName$4}(cfg, ${generateString(endpoint.path)}, data)`,
639
- params: ['data']
673
+ params: ["data"],
640
674
  });
641
675
  const interfaceSource = generateArrowFunctionType({
642
676
  type: interfaceName,
643
677
  params: [`data: DeepPartial<${generateRequestBodyType(path).toString()}>`],
644
- returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`
678
+ returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`,
645
679
  });
646
680
  return {
647
681
  entity,
648
682
  name: functionName$4,
649
683
  type: { name: interfaceName, source: interfaceSource },
650
- func: { name: functionName$4, source: functionSource }
684
+ func: { name: functionName$4, source: functionSource },
651
685
  };
652
686
  };
653
687
 
654
- const generateGenericFunctionName = (path, suffix = '', prefix = '') => {
688
+ const generateGenericFunctionName = (path, suffix = "", prefix = "") => {
655
689
  return camelCase(`${prefix}_` +
656
- path
657
- .replace(/.*\//, '')
658
- .replace(/\W+/, '_')
659
- .replace(/[_]+/, '_') + `_${suffix}`);
690
+ path.replace(/.*\//, "").replace(/\W+/, "_").replace(/[_]+/, "_") +
691
+ `_${suffix}`);
660
692
  };
661
693
 
662
694
  const insertPathPlaceholder = (path, record) => {
@@ -664,32 +696,37 @@ const insertPathPlaceholder = (path, record) => {
664
696
  };
665
697
 
666
698
  const wrapBody = (type, target) => {
667
- return type.toString() === 'binary' ?
668
- createRawType(isNodeTarget(target) ? 'BodyInit' : 'Blob') :
669
- type; // node-fetch returns a Blob as well
699
+ return type.toString() === "binary"
700
+ ? createRawType(isNodeTarget(target) ? "BodyInit" : "Blob")
701
+ : type; // node-fetch returns a Blob as well
670
702
  };
671
703
  const generateGenericEndpoint = (suffix) => ({ target, method, path, endpoint }) => {
672
704
  const functionName = generateGenericFunctionName(endpoint.path, suffix, method);
673
705
  const entity = pascalCase(endpoint.entity);
674
706
  const interfaceName = `${entity}Service_${pascalCase(functionName)}`;
675
707
  const entityQuery = `${interfaceName}_Query`;
676
- const hasId = endpoint.path.includes('{id}');
708
+ const hasId = endpoint.path.includes("{id}");
677
709
  const params = createObjectType({
678
710
  params: convertToTypeScriptType(convertParametersToSchema(path.parameters)),
679
- body: method === 'get' ? undefined : wrapBody(generateRequestBodyType(path), target)
711
+ body: method === "get"
712
+ ? undefined
713
+ : wrapBody(generateRequestBodyType(path), target),
680
714
  });
681
715
  const responseBody = generateResponseBodyType(path);
682
- const forceBlobResponse = String(responseBody.toString() === 'binary');
716
+ const forceBlobResponse = String(responseBody.toString() === "binary");
683
717
  const functionSource = generateArrowFunction({
684
718
  name: functionName,
685
719
  signature: interfaceName,
686
- params: hasId ? ['id', 'query'] : ['query'],
687
- returns: `_generic(cfg, ${generateString(method.toUpperCase())}, \`${insertPathPlaceholder(endpoint.path, { id: '${id}' })}\`, query, ${forceBlobResponse})`
720
+ params: hasId ? ["id", "query"] : ["query"],
721
+ returns: `_generic(cfg, ${generateString(method.toUpperCase())}, \`${insertPathPlaceholder(endpoint.path, { id: "${id}" })}\`, query, ${forceBlobResponse})`,
688
722
  });
689
723
  const interfaceSource = generateArrowFunctionType({
690
724
  type: interfaceName,
691
- params: [...(hasId ? ['id: string'] : []), `query${params.isFullyOptional() ? '?' : ''}: ${entityQuery}`],
692
- returns: `${resolveResponseType(target)}<${wrapBody(responseBody, target).toString()}>`
725
+ params: [
726
+ ...(hasId ? ["id: string"] : []),
727
+ `query${params.isFullyOptional() ? "?" : ""}: ${entityQuery}`,
728
+ ],
729
+ returns: `${resolveResponseType(target)}<${wrapBody(responseBody, target).toString()}>`,
693
730
  });
694
731
  return {
695
732
  entity,
@@ -699,44 +736,48 @@ const generateGenericEndpoint = (suffix) => ({ target, method, path, endpoint })
699
736
  interfaces: [
700
737
  {
701
738
  name: entityQuery,
702
- source: generateInterfaceFromObject(entityQuery, params, true)
703
- }
704
- ]
739
+ source: generateInterfaceFromObject(entityQuery, params, true),
740
+ },
741
+ ],
705
742
  };
706
743
  };
707
744
 
708
- const functionName$3 = 'remove';
709
- const generateRemoveEndpoint = ({ target, endpoint }) => {
745
+ const functionName$3 = "remove";
746
+ const generateRemoveEndpoint = ({ target, endpoint, }) => {
710
747
  const entity = pascalCase(endpoint.entity);
711
748
  const interfaceName = `${entity}Service_${pascalCase(functionName$3)}`;
712
749
  const functionSource = generateArrowFunction({
713
750
  name: functionName$3,
714
751
  signature: interfaceName,
715
- returns: `_${functionName$3}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: '${id}' })}\`, options)`,
716
- params: ['id', 'options?: RemoveQuery']
752
+ returns: `_${functionName$3}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: "${id}" })}\`, options)`,
753
+ params: ["id", "options?: RemoveQuery"],
717
754
  });
718
755
  const interfaceSource = generateArrowFunctionType({
719
756
  type: interfaceName,
720
- params: ['id: string', 'options?: RemoveQuery'],
721
- returns: `${resolveResponseType(target)}<void>`
757
+ params: ["id: string", "options?: RemoveQuery"],
758
+ returns: `${resolveResponseType(target)}<void>`,
722
759
  });
723
760
  return {
724
761
  entity,
725
762
  name: functionName$3,
726
763
  type: { name: interfaceName, source: interfaceSource },
727
- func: { name: functionName$3, source: functionSource }
764
+ func: { name: functionName$3, source: functionSource },
728
765
  };
729
766
  };
730
767
 
731
- const functionName$2 = 'some';
768
+ const functionName$2 = "some";
732
769
  const excludedParameters = [
733
- 'page', 'pageSize', 'sort',
734
- 'serializeNulls', 'properties', 'includeReferencedEntities'
770
+ "page",
771
+ "pageSize",
772
+ "sort",
773
+ "serializeNulls",
774
+ "properties",
775
+ "includeReferencedEntities",
735
776
  ];
736
777
  const resolveAdditionalProperties = (path) => {
737
778
  const body = resolveBodyType(path);
738
779
  if (isResponseObject(body)) {
739
- const schema = body?.content?.['application/json']?.schema;
780
+ const schema = body?.content?.["application/json"]?.schema;
740
781
  if (isObjectSchemaObject(schema)) {
741
782
  const obj = schema?.properties?.additionalProperties;
742
783
  if (isObjectSchemaObject(obj)) {
@@ -746,7 +787,7 @@ const resolveAdditionalProperties = (path) => {
746
787
  }
747
788
  return undefined;
748
789
  };
749
- const generateSomeEndpoint = ({ aliases, target, path, endpoint }) => {
790
+ const generateSomeEndpoint = ({ aliases, target, path, endpoint, }) => {
750
791
  // Required interface names
751
792
  const service = pascalCase(endpoint.entity);
752
793
  const entity = aliases.get(endpoint.entity) ?? service;
@@ -758,28 +799,33 @@ const generateSomeEndpoint = ({ aliases, target, path, endpoint }) => {
758
799
  const parameterSchema = convertParametersToSchema(path.parameters);
759
800
  const additionalProperties = resolveAdditionalProperties(path);
760
801
  const additionalPropertyNames = generateStrings(Object.keys(additionalProperties?.properties ?? {}));
761
- const additionalPropertyNamesType = additionalPropertyNames.length ? `(${concat(additionalPropertyNames, ' | ')})[]` : '[]';
802
+ const additionalPropertyNamesType = additionalPropertyNames.length
803
+ ? `(${concat(additionalPropertyNames, " | ")})[]`
804
+ : "[]";
762
805
  // We already cover some properties
763
- parameterSchema.properties = Object.fromEntries(Object.entries(parameterSchema.properties ?? {})
764
- .filter(v => !excludedParameters.includes(v[0])));
806
+ parameterSchema.properties = Object.fromEntries(Object.entries(parameterSchema.properties ?? {}).filter((v) => !excludedParameters.includes(v[0])));
765
807
  const parameters = createObjectType({
766
- params: convertToTypeScriptType(parameterSchema)
808
+ params: convertToTypeScriptType(parameterSchema),
767
809
  });
768
- const properties = additionalProperties ? convertToTypeScriptType(additionalProperties).toString() : '{}';
810
+ const properties = additionalProperties
811
+ ? convertToTypeScriptType(additionalProperties).toString()
812
+ : "{}";
769
813
  const interfaceSource = generateArrowFunctionType({
770
814
  type: interfaceName,
771
815
  generics: [
772
816
  `S extends (QuerySelect<${entity}> | undefined) = undefined`,
773
- `I extends (QuerySelect<${entityMappings}> | undefined) = undefined`
817
+ `I extends (QuerySelect<${entityMappings}> | undefined) = undefined`,
774
818
  ],
775
- params: [`query${parameters.isFullyOptional() ? '?' : ''}: SomeQuery<${entity}, ${entityFilter}, I, S, ${additionalPropertyNamesType}> & ${entityParameters}`],
776
- returns: `${resolveResponseType(target)}<SomeQueryReturn<${entity}, ${entityReferences}, ${entityMappings}, I, S, ${properties}>>`
819
+ params: [
820
+ `query${parameters.isFullyOptional() ? "?" : ""}: SomeQuery<${entity}, ${entityFilter}, I, S, ${additionalPropertyNamesType}> & ${entityParameters}`,
821
+ ],
822
+ returns: `${resolveResponseType(target)}<SomeQueryReturn<${entity}, ${entityReferences}, ${entityMappings}, I, S, ${properties}>>`,
777
823
  });
778
824
  const functionSource = generateArrowFunction({
779
825
  name: functionName$2,
780
826
  signature: interfaceName,
781
827
  returns: `_${functionName$2}(cfg, ${generateString(endpoint.path)}, query)`,
782
- params: ['query']
828
+ params: ["query"],
783
829
  });
784
830
  return {
785
831
  entity,
@@ -789,62 +835,66 @@ const generateSomeEndpoint = ({ aliases, target, path, endpoint }) => {
789
835
  interfaces: [
790
836
  {
791
837
  name: entityParameters,
792
- source: generateInterfaceFromObject(entityParameters, parameters, true)
793
- }
794
- ]
838
+ source: generateInterfaceFromObject(entityParameters, parameters, true),
839
+ },
840
+ ],
795
841
  };
796
842
  };
797
843
 
798
- const functionName$1 = 'unique';
799
- const generateUniqueEndpoint = ({ target, path, endpoint }) => {
844
+ const functionName$1 = "unique";
845
+ const generateUniqueEndpoint = ({ target, path, endpoint, }) => {
800
846
  const entity = pascalCase(endpoint.entity);
801
847
  const interfaceName = `${entity}Service_${pascalCase(functionName$1)}`;
802
848
  const functionSource = generateArrowFunction({
803
849
  name: functionName$1,
804
850
  signature: interfaceName,
805
- params: ['id', 'query'],
806
- returns: `_${functionName$1}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: '${id}' })}\`, query)`
851
+ params: ["id", "query"],
852
+ returns: `_${functionName$1}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: "${id}" })}\`, query)`,
807
853
  });
808
854
  const interfaceSource = generateArrowFunctionType({
809
855
  type: interfaceName,
810
- params: ['id: string', 'query?: Q'],
811
- generics: ['Q extends UniqueQuery'],
812
- returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`
856
+ params: ["id: string", "query?: Q"],
857
+ generics: ["Q extends UniqueQuery"],
858
+ returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`,
813
859
  });
814
860
  return {
815
861
  entity,
816
862
  name: functionName$1,
817
863
  type: { name: interfaceName, source: interfaceSource },
818
- func: { name: functionName$1, source: functionSource }
864
+ func: { name: functionName$1, source: functionSource },
819
865
  };
820
866
  };
821
867
 
822
- const functionName = 'update';
823
- const generateUpdateEndpoint = ({ target, path, endpoint }) => {
868
+ const functionName = "update";
869
+ const generateUpdateEndpoint = ({ target, path, endpoint, }) => {
824
870
  const entity = pascalCase(endpoint.entity);
825
871
  const interfaceName = `${entity}Service_${pascalCase(functionName)}`;
826
872
  const interfaceSource = generateArrowFunctionType({
827
873
  type: interfaceName,
828
- params: ['id: string', `data: DeepPartial<${generateRequestBodyType(path).toString()}>`, 'options?: UpdateQuery'],
829
- returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`
874
+ params: [
875
+ "id: string",
876
+ `data: DeepPartial<${generateRequestBodyType(path).toString()}>`,
877
+ "options?: UpdateQuery",
878
+ ],
879
+ returns: `${resolveResponseType(target)}<${generateResponseBodyType(path).toString()}>`,
830
880
  });
831
881
  const functionSource = generateArrowFunction({
832
882
  name: functionName,
833
883
  signature: interfaceName,
834
- returns: `_${functionName}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: '${id}' })}\`, data, options)`,
835
- params: ['id', 'data', 'options']
884
+ returns: `_${functionName}(cfg, \`${insertPathPlaceholder(endpoint.path, { id: "${id}" })}\`, data, options)`,
885
+ params: ["id", "data", "options"],
836
886
  });
837
887
  return {
838
888
  entity,
839
889
  name: functionName,
840
890
  type: { name: interfaceName, source: interfaceSource },
841
- func: { name: functionName, source: functionSource }
891
+ func: { name: functionName, source: functionSource },
842
892
  };
843
893
  };
844
894
 
845
895
  const isMultiPartUploadPath = (path) => {
846
- const [, entity, ...rest] = path.split('/');
847
- return entity && rest.length === 2 && rest[1] === 'multipartUpload';
896
+ const [, entity, ...rest] = path.split("/");
897
+ return entity && rest.length === 2 && rest[1] === "multipartUpload";
848
898
  };
849
899
  const groupEndpointsByEntity = (paths) => {
850
900
  const endpoints = new Map();
@@ -872,28 +922,28 @@ const generators = {
872
922
  /* /article */
873
923
  [WeclappEndpointType.ROOT]: {
874
924
  get: generateSomeEndpoint,
875
- post: generateCreateEndpoint
925
+ post: generateCreateEndpoint,
876
926
  },
877
927
  /* /article/count */
878
928
  [WeclappEndpointType.COUNT]: {
879
- get: generateCountEndpoint
929
+ get: generateCountEndpoint,
880
930
  },
881
931
  /* /article/:id */
882
932
  [WeclappEndpointType.ENTITY]: {
883
933
  get: generateUniqueEndpoint,
884
934
  delete: generateRemoveEndpoint,
885
- put: generateUpdateEndpoint
935
+ put: generateUpdateEndpoint,
886
936
  },
887
937
  /* /article/:id/method */
888
938
  [WeclappEndpointType.GENERIC_ENTITY]: {
889
- get: generateGenericEndpoint('ById'),
890
- post: generateGenericEndpoint('ById')
939
+ get: generateGenericEndpoint("ById"),
940
+ post: generateGenericEndpoint("ById"),
891
941
  },
892
942
  /* /article/method */
893
943
  [WeclappEndpointType.GENERIC_ROOT]: {
894
944
  get: generateGenericEndpoint(),
895
- post: generateGenericEndpoint()
896
- }
945
+ post: generateGenericEndpoint(),
946
+ },
897
947
  };
898
948
  const generateServices = (doc, aliases, options) => {
899
949
  const services = new Map();
@@ -906,7 +956,9 @@ const generateServices = (doc, aliases, options) => {
906
956
  for (const { path, endpoint } of paths) {
907
957
  const resolver = generators[endpoint.type];
908
958
  for (const [method, config] of Object.entries(path)) {
909
- if (method === 'get' && endpoint.type === WeclappEndpointType.ENTITY && !options.generateUnique) {
959
+ if (method === "get" &&
960
+ endpoint.type === WeclappEndpointType.ENTITY &&
961
+ !options.generateUnique) {
910
962
  continue;
911
963
  }
912
964
  if (resolver[method]) {
@@ -915,7 +967,7 @@ const generateServices = (doc, aliases, options) => {
915
967
  if (!path.deprecated || options.deprecated) {
916
968
  functions.push({
917
969
  ...resolver[method]({ endpoint, method, target, path, aliases }),
918
- path
970
+ path,
919
971
  });
920
972
  }
921
973
  }
@@ -928,33 +980,40 @@ const generateServices = (doc, aliases, options) => {
928
980
  continue;
929
981
  }
930
982
  // Construct service type
931
- const types = generateStatements(...functions.flatMap(v => v.interfaces?.map(v => v.source) ?? []), ...functions.map(v => v.type.source), generateInterface(serviceTypeName, [
932
- ...functions.map(v => ({
983
+ const types = generateStatements(...functions.flatMap((v) => v.interfaces?.map((v) => v.source) ?? []), ...functions.map((v) => v.type.source), generateInterface(serviceTypeName, [
984
+ ...functions.map((v) => ({
933
985
  required: true,
934
- comment: v.path.deprecated ? '@deprecated' : undefined,
986
+ comment: v.path.deprecated ? "@deprecated" : undefined,
935
987
  name: v.func.name,
936
- type: v.type.name
937
- }))
988
+ type: v.type.name,
989
+ })),
938
990
  ]));
939
991
  // Construct service value
940
- const funcBody = generateBlockStatements(...functions.map(v => v.func.source), `return {${concat(functions.map(v => v.func.name))}};`);
992
+ const funcBody = generateBlockStatements(...functions.map((v) => v.func.source), `return {${concat(functions.map((v) => v.func.name))}};`);
941
993
  const func = `export const ${serviceName} = (cfg?: ServiceConfig): ${serviceTypeName} => ${funcBody};`;
942
994
  const source = generateBlockComment(`${pascalCase(endpoint)} service`, generateStatements(types, func));
943
- const deprecated = functions.every(v => v.path.deprecated);
944
- services.set(endpoint, { entity: endpoint, deprecated, serviceName, serviceTypeName, source, functions });
995
+ const deprecated = functions.every((v) => v.path.deprecated);
996
+ services.set(endpoint, {
997
+ entity: endpoint,
998
+ deprecated,
999
+ serviceName,
1000
+ serviceTypeName,
1001
+ source,
1002
+ functions,
1003
+ });
945
1004
  }
946
1005
  return services;
947
1006
  };
948
1007
 
949
1008
  const generateCustomValueUtilities = (entities, services) => {
950
- const customValueEntity = entities.get('customValue');
1009
+ const customValueEntity = entities.get("customValue");
951
1010
  const customValueEntities = [];
952
1011
  if (!customValueEntity) {
953
- logger.warn('Cannot generate custom value utils, type not found.');
954
- return '';
1012
+ logger.warn("Cannot generate custom value utils, type not found.");
1013
+ return "";
955
1014
  }
956
1015
  serviceLoop: for (const service of services) {
957
- const someFunction = service.functions.find(v => v.name === 'some');
1016
+ const someFunction = service.functions.find((v) => v.name === "some");
958
1017
  if (!someFunction) {
959
1018
  continue;
960
1019
  }
@@ -969,7 +1028,7 @@ const generateCustomValueUtilities = (entities, services) => {
969
1028
  }
970
1029
  customValueEntities.push(service.entity);
971
1030
  }
972
- return generateBlockComment('Utilities to identify services that return an entity that is an alias to CustomValue.', generateStatements(generateType('WCustomValueService', concat(generateStrings(customValueEntities), ' | ')), `export const wCustomValueServiceNames: WCustomValueService[] = [${concat(generateStrings(customValueEntities))}];`, `export const isWCustomValueService = (service: string | undefined): service is WCustomValueService =>\n${indent('wCustomValueServiceNames.includes(service as WCustomValueService);')}`));
1031
+ return generateBlockComment("Utilities to identify services that return an entity that is an alias to CustomValue.", generateStatements(generateType("WCustomValueService", concat(generateStrings(customValueEntities), " | ")), `export const wCustomValueServiceNames: WCustomValueService[] = [${concat(generateStrings(customValueEntities))}];`, `export const isWCustomValueService = (service: string | undefined): service is WCustomValueService =>\n${indent("wCustomValueServiceNames.includes(service as WCustomValueService);")}`));
973
1032
  };
974
1033
 
975
1034
  const generateObject = (properties) => {
@@ -988,7 +1047,7 @@ const generateObject = (properties) => {
988
1047
  body.push(`${key}: ${String(value)}`);
989
1048
  }
990
1049
  }
991
- return body.length ? `{\n${indent(body.join(',\n'))}\n}` : `{}`;
1050
+ return body.length ? `{\n${indent(body.join(",\n"))}\n}` : `{}`;
992
1051
  };
993
1052
 
994
1053
  const resolveInheritedEntities = (root, entities) => {
@@ -996,34 +1055,42 @@ const resolveInheritedEntities = (root, entities) => {
996
1055
  return parent ? [parent, ...resolveInheritedEntities(parent, entities)] : [];
997
1056
  };
998
1057
  const generatePropertyDescriptors = (entity, entities, services, options) => [
999
- ...resolveInheritedEntities(entity, entities).flatMap(v => [...v.properties]),
1000
- ...entity.properties
1001
- ].filter(([, meta]) => {
1058
+ ...resolveInheritedEntities(entity, entities).flatMap((v) => [
1059
+ ...v.properties,
1060
+ ]),
1061
+ ...entity.properties,
1062
+ ]
1063
+ .filter(([, meta]) => {
1002
1064
  // If we generate deprecated things we can skip the filtering
1003
1065
  if (options.deprecated) {
1004
1066
  return true;
1005
1067
  }
1006
1068
  // Check if corresponding service is deprecated and can be removed
1007
- const service = services.find(v => v.entity === meta.service);
1069
+ const service = services.find((v) => v.entity === meta.service);
1008
1070
  return !meta.service || (service && !service.deprecated);
1009
- }).map(([property, meta]) => ({
1071
+ })
1072
+ .map(([property, meta]) => ({
1010
1073
  key: property,
1011
1074
  value: Object.entries(meta).map(([key, value]) => ({
1012
1075
  key,
1013
- value: value !== undefined ? typeof value === 'number' ? value : generateString(value) : undefined
1014
- }))
1076
+ value: value !== undefined
1077
+ ? typeof value === "number"
1078
+ ? value
1079
+ : generateString(value)
1080
+ : undefined,
1081
+ })),
1015
1082
  }));
1016
1083
  const generateEntityPropertyMap = (entities, services, options) => {
1017
- const typeName = 'WEntityProperties';
1084
+ const typeName = "WEntityProperties";
1018
1085
  const propertyMap = [...entities].map(([entity, data]) => ({
1019
1086
  key: entity,
1020
- value: generatePropertyDescriptors(data, entities, services, options)
1087
+ value: generatePropertyDescriptors(data, entities, services, options),
1021
1088
  }));
1022
1089
  return generateStatements(`export type ${typeName} = Partial<Record<WEntity, Partial<Record<string, WEntityPropertyMeta>>>>;`, `export const wEntityProperties: ${typeName} = ${generateObject(propertyMap)};`);
1023
1090
  };
1024
1091
 
1025
1092
  const generateArray = (values) => {
1026
- return `[${concat(values.map(v => generateString(String(v))))}]`;
1093
+ return `[${concat(values.map((v) => generateString(String(v))))}]`;
1027
1094
  };
1028
1095
 
1029
1096
  // Only functions matching this regex are included in the generation.
@@ -1042,11 +1109,12 @@ const generateGroupedServices = (services) => {
1042
1109
  continue;
1043
1110
  }
1044
1111
  entityDescriptors.set(name, [
1045
- ...(entityDescriptors.get(name) ?? []), {
1112
+ ...(entityDescriptors.get(name) ?? []),
1113
+ {
1046
1114
  name: entity,
1047
1115
  required: true,
1048
- type: `${pascalCase(entity)}Service_${pascalCase(name)}`
1049
- }
1116
+ type: `${pascalCase(entity)}Service_${pascalCase(name)}`,
1117
+ },
1050
1118
  ]);
1051
1119
  }
1052
1120
  }
@@ -1064,46 +1132,57 @@ const generateGroupedServices = (services) => {
1064
1132
  ...descriptors.map(([name, props]) => {
1065
1133
  const constant = camelCase(`wServiceWith_${name}_Names`);
1066
1134
  const type = pascalCase(`WServiceWith_${name}`);
1067
- const value = generateArray(props.map(v => v.name));
1135
+ const value = generateArray(props.map((v) => v.name));
1068
1136
  return `export const ${constant}: ${type}[] = ${value};`;
1069
1137
  }),
1070
- generateBlockComment('Type guards for service classes.', generateStatements(...typeGuards))
1138
+ generateBlockComment("Type guards for service classes.", generateStatements(...typeGuards)),
1071
1139
  ];
1072
1140
  };
1073
1141
 
1074
- const obj = (list) => `{\n${indent(list.join(',\n'))}\n}`;
1075
- const arr = (list) => `[\n${indent(list.join(',\n'))}\n]`;
1076
- const generateMaps = ({ services, entities, aliases, enums, options }) => {
1142
+ const obj = (list) => `{\n${indent(list.join(",\n"))}\n}`;
1143
+ const arr = (list) => `[\n${indent(list.join(",\n"))}\n]`;
1144
+ const generateMaps = ({ services, entities, aliases, enums, options, }) => {
1077
1145
  const entitiesKeys = [...entities.keys()];
1078
1146
  const enumsArray = `export const wEnums = ${obj(enums)};`;
1079
- const entityNames = `export const wEntityNames: WEntity[] = ${arr(entitiesKeys.map(v => `'${v}'`))};`;
1080
- const serviceNames = `export const wServiceNames: WService[] = ${arr(services.map(v => `'${v.entity}'`))};`;
1081
- const serviceValues = `export const wServiceFactories = ${obj(services.map(v => `${v.entity}: ${v.serviceName}`))};`;
1082
- const serviceInstanceValues = `export const wServices = ${obj(services.map(v => {
1147
+ const entityNames = `export const wEntityNames: WEntity[] = ${arr(entitiesKeys.map((v) => `'${v}'`))};`;
1148
+ const serviceNames = `export const wServiceNames: WService[] = ${arr(services.map((v) => `'${v.entity}'`))};`;
1149
+ const serviceValues = `export const wServiceFactories = ${obj(services.map((v) => `${v.entity}: ${v.serviceName}`))};`;
1150
+ const serviceInstanceValues = `export const wServices = ${obj(services.map((v) => {
1083
1151
  const src = `${v.entity}: ${v.serviceName}()`;
1084
- return v.deprecated ? generateInlineComment('@deprecated') + `\n${src}` : src;
1152
+ return v.deprecated
1153
+ ? generateInlineComment("@deprecated") + `\n${src}`
1154
+ : src;
1085
1155
  }))};`;
1086
1156
  const entityInterfaces = [
1087
- ...entitiesKeys.map(entity => ({
1157
+ ...entitiesKeys.map((entity) => ({
1088
1158
  name: entity,
1089
1159
  type: pascalCase(entity),
1090
- required: true
1160
+ required: true,
1091
1161
  })),
1092
- ...services.map(service => {
1162
+ ...services.map((service) => {
1093
1163
  const alias = aliases.get(service.entity);
1094
1164
  return {
1095
1165
  name: service.entity,
1096
- type: alias ?? 'never',
1166
+ type: alias ?? "never",
1097
1167
  required: true,
1098
- comment: alias ? undefined : 'no response defined or inlined'
1168
+ comment: alias ? undefined : "no response defined or inlined",
1099
1169
  };
1100
- })
1170
+ }),
1101
1171
  ];
1102
- const createMappingType = (type, prefix) => type !== 'never' ? `${type}_${prefix}` : type;
1103
- const entitiesList = generateInterface('WEntities', entityInterfaces);
1104
- const entityReferences = generateInterface('WEntityReferences', entityInterfaces.map(v => ({ ...v, type: createMappingType(v.type, 'References') })));
1105
- const entityMappings = generateInterface('WEntityMappings', entityInterfaces.map(v => ({ ...v, type: createMappingType(v.type, 'Mappings') })));
1106
- const entityFilter = generateInterface('WEntityFilters', entityInterfaces.map(v => ({ ...v, type: createMappingType(v.type, 'Filter') })));
1172
+ const createMappingType = (type, prefix) => type !== "never" ? `${type}_${prefix}` : type;
1173
+ const entitiesList = generateInterface("WEntities", entityInterfaces);
1174
+ const entityReferences = generateInterface("WEntityReferences", entityInterfaces.map((v) => ({
1175
+ ...v,
1176
+ type: createMappingType(v.type, "References"),
1177
+ })));
1178
+ const entityMappings = generateInterface("WEntityMappings", entityInterfaces.map((v) => ({
1179
+ ...v,
1180
+ type: createMappingType(v.type, "Mappings"),
1181
+ })));
1182
+ const entityFilter = generateInterface("WEntityFilters", entityInterfaces.map((v) => ({
1183
+ ...v,
1184
+ type: createMappingType(v.type, "Filter"),
1185
+ })));
1107
1186
  return {
1108
1187
  source: generateStatements(
1109
1188
  /* JS Values */
@@ -1127,16 +1206,15 @@ const generateMaps = ({ services, entities, aliases, enums, options }) => {
1127
1206
  - the type for what is returned by the api
1128
1207
  `, entitiesList),
1129
1208
  /* type-ofs and types */
1130
- generateType('WServices', 'typeof wServices'), generateType('WServiceFactories', 'typeof wServiceFactories'), generateType('WService', 'keyof WServices'), generateType('WEntity', 'keyof WEntities'), generateType('WEnums', 'typeof wEnums'), generateType('WEnum', 'keyof WEnums'),
1209
+ generateType("WServices", "typeof wServices"), generateType("WServiceFactories", "typeof wServiceFactories"), generateType("WService", "keyof WServices"), generateType("WEntity", "keyof WEntities"), generateType("WEnums", "typeof wEnums"), generateType("WEnum", "keyof WEnums"),
1131
1210
  /* Utilities. */
1132
1211
  generateCustomValueUtilities(entities, services),
1133
1212
  /* All functions grouped by service supporting it */
1134
- ...generateGroupedServices(services))
1213
+ ...generateGroupedServices(services)),
1135
1214
  };
1136
1215
  };
1137
1216
 
1138
- const parseReferencedEntity = (obj) => pascalCase(obj.$ref.replace(/.*\//, ''));
1139
- /* eslint-disable @typescript-eslint/no-unsafe-return */
1217
+ const parseReferencedEntity = (obj) => pascalCase(obj.$ref.replace(/.*\//, ""));
1140
1218
  const extractSchemas = (doc) => {
1141
1219
  const schemas = new Map();
1142
1220
  const aliases = new Map();
@@ -1155,7 +1233,7 @@ const extractSchemas = (doc) => {
1155
1233
  continue;
1156
1234
  }
1157
1235
  for (const method of Object.values(OpenAPIV3.HttpMethods)) {
1158
- const body = methods[method]?.responses['200'];
1236
+ const body = methods[method]?.responses["200"];
1159
1237
  if (isResponseObject(body) && body.content) {
1160
1238
  const responseSchema = Object.values(body.content)[0]?.schema;
1161
1239
  if (isReferenceObject(responseSchema)) {
@@ -1183,16 +1261,16 @@ const generate = (doc, options) => {
1183
1261
  const enums = generateEnums(schemas);
1184
1262
  const entities = generateEntities(schemas, enums);
1185
1263
  const services = generateServices(doc, aliases, options);
1186
- return generateStatements(generateBase(options.target, doc.info.version), generateBlockComment('ENUMS', generateStatements(...[...enums.values()].map(v => v.source))), generateBlockComment('ENTITIES', generateStatements(...[...entities.values()].map(v => v.source))), generateBlockComment('SERVICES', generateStatements(...[...services.values()].map(v => v.source))), generateBlockComment('MAPS', generateMaps({
1264
+ return generateStatements(generateBase(options.target, doc.info.version), generateBlockComment("ENUMS", generateStatements(...[...enums.values()].map((v) => v.source))), generateBlockComment("ENTITIES", generateStatements(...[...entities.values()].map((v) => v.source))), generateBlockComment("SERVICES", generateStatements(...[...services.values()].map((v) => v.source))), generateBlockComment("MAPS", generateMaps({
1187
1265
  services: [...services.values()],
1188
1266
  enums: [...enums.keys()],
1189
1267
  options,
1190
1268
  entities,
1191
- aliases
1269
+ aliases,
1192
1270
  }).source));
1193
1271
  };
1194
1272
 
1195
- const hash = (content, algorithm = 'sha256') => {
1273
+ const hash = (content, algorithm = "sha256") => {
1196
1274
  const hash = createHash(algorithm);
1197
1275
  if (Array.isArray(content)) {
1198
1276
  content.map(hash.update.bind(hash));
@@ -1200,99 +1278,103 @@ const hash = (content, algorithm = 'sha256') => {
1200
1278
  else {
1201
1279
  hash.update(content);
1202
1280
  }
1203
- return hash.digest('hex');
1281
+ return hash.digest("hex");
1204
1282
  };
1205
1283
 
1206
1284
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
1207
1285
  const cli = async () => {
1208
- const { default: { version } } = await import('../package.json', { assert: { type: 'json' } });
1286
+ const version = pkg.version;
1209
1287
  const { argv } = yargs(hideBin(process.argv))
1210
- .scriptName('build-weclapp-sdk')
1211
- .usage('Usage: $0 <source> [flags]')
1288
+ .scriptName("build-weclapp-sdk")
1289
+ .usage("Usage: $0 <source> [flags]")
1212
1290
  .version(version)
1213
- .example('$0 openapi.json', 'Generate the SDK based on a local openapi file')
1214
- .example('$0 xxx.weclapp.com --key ...', 'Generate the SDK based on the openapi file from the given weclapp instance')
1215
- .help('h')
1216
- .alias('v', 'version')
1217
- .alias('h', 'help')
1218
- .option('k', {
1219
- alias: 'key',
1220
- describe: 'API Key (only needed when not using a local file)',
1221
- type: 'string'
1291
+ .example("$0 openapi.json", "Generate the SDK based on a local openapi file")
1292
+ .example("$0 xxx.weclapp.com --key ...", "Generate the SDK based on the openapi file from the given weclapp instance")
1293
+ .help("h")
1294
+ .alias("v", "version")
1295
+ .alias("h", "help")
1296
+ .option("k", {
1297
+ alias: "key",
1298
+ describe: "API Key (only needed when not using a local file)",
1299
+ type: "string",
1222
1300
  })
1223
- .option('c', {
1224
- alias: 'cache',
1225
- describe: 'If the generated SDK should cached',
1226
- type: 'boolean'
1301
+ .option("c", {
1302
+ alias: "cache",
1303
+ describe: "If the generated SDK should cached",
1304
+ type: "boolean",
1227
1305
  })
1228
- .option('q', {
1229
- alias: 'query',
1230
- describe: 'Extra query params when fetching the openapi.json from a server',
1231
- type: 'string'
1306
+ .option("q", {
1307
+ alias: "query",
1308
+ describe: "Extra query params when fetching the openapi.json from a server",
1309
+ type: "string",
1232
1310
  })
1233
- .option('generate-unique', {
1234
- describe: 'Generate .unique functions',
1235
- type: 'boolean'
1311
+ .option("generate-unique", {
1312
+ describe: "Generate .unique functions",
1313
+ type: "boolean",
1236
1314
  })
1237
- .option('d', {
1238
- alias: 'deprecated',
1239
- describe: 'Include deprecated functions and services',
1240
- type: 'boolean'
1315
+ .option("d", {
1316
+ alias: "deprecated",
1317
+ describe: "Include deprecated functions and services",
1318
+ type: "boolean",
1241
1319
  })
1242
- .option('e', {
1243
- alias: 'from-env',
1244
- describe: 'Use env variables WECLAPP_BACKEND_URL and WECLAPP_API_KEY as credentials',
1245
- type: 'boolean'
1320
+ .option("e", {
1321
+ alias: "from-env",
1322
+ describe: "Use env variables WECLAPP_BACKEND_URL and WECLAPP_API_KEY as credentials",
1323
+ type: "boolean",
1246
1324
  })
1247
- .option('t', {
1248
- alias: 'target',
1249
- describe: 'Specify the target platform',
1250
- type: 'string',
1251
- choices: ['browser', 'browser.rx', 'node', 'node.rx']
1325
+ .option("t", {
1326
+ alias: "target",
1327
+ describe: "Specify the target platform",
1328
+ type: "string",
1329
+ choices: ["browser", "browser.rx", "node", "node.rx"],
1252
1330
  })
1253
- .option('d', {
1254
- alias: 'deprecated',
1255
- describe: 'Include deprecated functions and services',
1256
- type: 'boolean'
1331
+ .option("d", {
1332
+ alias: "deprecated",
1333
+ describe: "Include deprecated functions and services",
1334
+ type: "boolean",
1257
1335
  })
1258
1336
  .epilog(`Copyright ${new Date().getFullYear()} weclapp GmbH`);
1259
1337
  if (argv.fromEnv) {
1260
1338
  config();
1261
1339
  }
1262
1340
  const { WECLAPP_API_KEY, WECLAPP_BACKEND_URL } = process.env;
1263
- const { query, cache = false, deprecated = false, key = WECLAPP_API_KEY, _: [src = WECLAPP_BACKEND_URL] } = argv;
1341
+ const { query, cache = false, deprecated = false, key = WECLAPP_API_KEY, _: [src = WECLAPP_BACKEND_URL], } = argv;
1264
1342
  const options = {
1265
1343
  deprecated,
1266
1344
  generateUnique: argv.generateUnique ?? false,
1267
- target: argv.target ?? Target.BROWSER_PROMISES
1345
+ target: argv.target ?? Target.BROWSER_PROMISES,
1268
1346
  };
1269
- if (typeof src === 'number') {
1270
- return Promise.reject('Expected string as command');
1347
+ if (!src || typeof src === "number") {
1348
+ return Promise.reject(new Error("Expected string as command"));
1271
1349
  }
1272
1350
  if (!Object.values(Target).includes(options.target)) {
1273
- logger.errorLn(`Unknown target: ${options.target}. Possible values are ${Object.values(Target).join(', ')}`);
1274
- return Promise.reject();
1351
+ logger.errorLn(`Unknown target: ${options.target}. Possible values are ${Object.values(Target).join(", ")}`);
1352
+ return Promise.reject(new Error());
1275
1353
  }
1276
1354
  if (await stat(src).catch(() => false)) {
1277
- logger.infoLn(`Source is a file.`);
1278
- const content = JSON.parse(await readFile(src, 'utf-8'));
1355
+ logger.infoLn(`Source is a file`);
1356
+ const content = JSON.parse(await readFile(src, "utf-8"));
1279
1357
  return { cache, content, options };
1280
1358
  }
1281
- const url = new URL(src.startsWith('http') ? src : `https://${src}`);
1359
+ logger.infoLn(`Source is a URL`);
1360
+ if (!key) {
1361
+ return Promise.reject(new Error("API key is missing"));
1362
+ }
1363
+ const url = new URL(src.startsWith("http") ? src : `https://${src}`);
1282
1364
  // At the moment just v1
1283
- url.pathname = '/webapp/api/v1/meta/openapi.json';
1365
+ url.pathname = "/webapp/api/v1/meta/openapi.json";
1284
1366
  if (query?.length) {
1285
- for (const param of query.split(',')) {
1286
- const [name, value] = param.split('=');
1367
+ for (const param of query.split(",")) {
1368
+ const [name, value] = param.split("=");
1287
1369
  url.searchParams.set(name, value);
1288
1370
  }
1289
1371
  }
1290
1372
  const content = await fetch(url.toString(), {
1291
- headers: { 'Accept': 'application/json', 'AuthenticationToken': key }
1292
- }).then(res => res.ok ? res.json() : undefined);
1373
+ headers: { Accept: "application/json", AuthenticationToken: key },
1374
+ }).then((res) => (res.ok ? res.json() : undefined));
1293
1375
  if (!content) {
1294
1376
  logger.errorLn(`Couldn't fetch file ${url.toString()} `);
1295
- return Promise.reject();
1377
+ return Promise.reject(new Error());
1296
1378
  }
1297
1379
  else {
1298
1380
  logger.infoLn(`Use remote file: ${url.toString()}`);
@@ -1300,50 +1382,61 @@ const cli = async () => {
1300
1382
  return { cache, content, options };
1301
1383
  };
1302
1384
 
1303
- const workingDirectory = resolve(currentDirname(), './sdk');
1304
- const folders = ['docs', 'main', 'node', 'raw', 'rx', 'utils'];
1385
+ const workingDir = resolve(currentDirname(), "./sdk");
1386
+ const cacheDir = resolve(currentDirname(), "./.cache");
1305
1387
  void (async () => {
1306
1388
  const start = process.hrtime.bigint();
1307
- const { default: { version } } = await import('../package.json', { assert: { type: 'json' } });
1308
1389
  const { content: doc, cache: useCache, options } = await cli();
1309
- // Resolve cache dir and key
1310
- const cacheKey = hash([version, JSON.stringify(doc), JSON.stringify(options)]).slice(-8);
1311
- const cacheDir = resolve(currentDirname(), '.tmp', cacheKey);
1312
- const dist = (...paths) => resolve(workingDirectory, ...paths);
1313
- const tmp = async (...paths) => {
1314
- const fullPath = resolve(cacheDir, ...paths);
1315
- await mkdir(dirname(fullPath), { recursive: true }).catch(() => null);
1390
+ const workingDirPath = async (...paths) => {
1391
+ const fullPath = resolve(workingDir, ...paths);
1392
+ await mkdir(dirname(fullPath), { recursive: true });
1316
1393
  return fullPath;
1317
1394
  };
1395
+ // Resolve cache dir and key
1396
+ const cacheKey = hash([
1397
+ pkg.version,
1398
+ JSON.stringify(doc),
1399
+ JSON.stringify(options),
1400
+ ]).slice(-8);
1401
+ const cachedSdkDir = resolve(cacheDir, cacheKey);
1402
+ // Remove old SDK
1403
+ await rm(workingDir, { recursive: true, force: true });
1318
1404
  if (useCache) {
1319
1405
  logger.infoLn(`Cache ID: ${cacheKey}`);
1320
1406
  }
1321
- if (useCache && await stat(cacheDir).catch(() => false)) {
1322
- logger.successLn(`Cache match! (${cacheDir})`);
1407
+ if (useCache && (await stat(cachedSdkDir).catch(() => false))) {
1408
+ // Copy cached SDK to working dir
1409
+ logger.successLn(`Cache match! (${cachedSdkDir})`);
1410
+ await cp(cachedSdkDir, workingDir, { recursive: true });
1323
1411
  }
1324
1412
  else {
1325
- // Store swagger.json file
1326
- await writeFile(await tmp('openapi.json'), JSON.stringify(doc, null, 2));
1413
+ // Write swagger.json file
1414
+ await writeFile(await workingDirPath("openapi.json"), JSON.stringify(doc, null, 2));
1327
1415
  logger.infoLn(`Generate sdk (target: ${options.target})`);
1328
- // Generate SDKs
1416
+ // Generate and write SDK
1329
1417
  const sdk = generate(doc, options);
1330
- await writeFile(await tmp('src', `${options.target}.ts`), sdk.trim() + '\n');
1331
- // Bundle
1332
- logger.infoLn('Bundle... (this may take some time)');
1333
- await bundle(cacheDir, options.target);
1334
- // Remove old SDK
1335
- await Promise.all(folders.map(async (dir) => rm(dist(dir), { recursive: true }).catch(() => 0)));
1418
+ await writeFile(await workingDirPath("src", "index.ts"), sdk.trim() + "\n");
1419
+ // Bundle and write SDK
1420
+ logger.infoLn("Bundle... (this may take some time)");
1421
+ await bundle(workingDir, options.target);
1422
+ if (useCache) {
1423
+ // Copy SDK to cache
1424
+ logger.successLn(`Caching SDK: (${cachedSdkDir})`);
1425
+ await mkdir(cachedSdkDir, { recursive: true });
1426
+ await cp(workingDir, cachedSdkDir, { recursive: true });
1427
+ }
1336
1428
  }
1337
- // Copy bundled SDK
1338
- await cp(cacheDir, workingDirectory, { recursive: true });
1339
1429
  // Print job summary
1340
1430
  const duration = (process.hrtime.bigint() - start) / 1000000n;
1341
1431
  logger.successLn(`SDK built in ${prettyMs(Number(duration))}`);
1342
1432
  logger.printSummary();
1343
- })().catch((error) => {
1433
+ })()
1434
+ .catch((error) => {
1344
1435
  logger.errorLn(`Fatal error:`);
1345
1436
  /* eslint-disable no-console */
1346
1437
  console.error(error);
1347
- }).finally(() => {
1348
- logger.errors && process.exit(1);
1438
+ })
1439
+ .finally(() => {
1440
+ if (logger.errors)
1441
+ process.exit(1);
1349
1442
  });