@compassdigital/sdk.typescript 3.14.0 → 3.15.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/bin/gen.js DELETED
@@ -1,497 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
- if (ar || !(i in from)) {
41
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
- ar[i] = from[i];
43
- }
44
- }
45
- return to.concat(ar || Array.prototype.slice.call(from));
46
- };
47
- var __importDefault = (this && this.__importDefault) || function (mod) {
48
- return (mod && mod.__esModule) ? mod : { "default": mod };
49
- };
50
- exports.__esModule = true;
51
- exports.CodeGenerator = void 0;
52
- var fs_1 = __importDefault(require("fs"));
53
- var openapi_ts_1 = require("@icholy/openapi-ts");
54
- var prettier_1 = __importDefault(require("prettier"));
55
- var path_1 = __importDefault(require("path"));
56
- var ejs_1 = __importDefault(require("ejs"));
57
- var yargs_1 = __importDefault(require("yargs/yargs"));
58
- var helpers_1 = require("yargs/helpers");
59
- /**
60
- * This is a mapping between "${method} ${path}" and the default
61
- * operationId.
62
- */
63
- var operationIDs = {
64
- "get /location/group/{id}/deliverydestination": "get_location_group_deliverydestinations",
65
- "get /location/search": "get_location_search",
66
- "get /promo": "get_promos",
67
- "get /schedule": "get_schedules",
68
- "get /brand": "get_brands",
69
- "get /announcement/resource": "get_resources",
70
- "get /order/location/brand/{id}": "get_order_location_brand"
71
- };
72
- var CodeGenerator = /** @class */ (function () {
73
- function CodeGenerator() {
74
- this.imports = [];
75
- this.methods = [];
76
- }
77
- CodeGenerator.prototype.manifest = function (manifest) {
78
- return __awaiter(this, void 0, void 0, function () {
79
- var _i, _a, service, code_1, filename_1, code, filename;
80
- return __generator(this, function (_b) {
81
- switch (_b.label) {
82
- case 0:
83
- // generate service types
84
- return [4 /*yield*/, fs_1["default"].promises.mkdir(path_1["default"].join("src", "interface"), { recursive: true })];
85
- case 1:
86
- // generate service types
87
- _b.sent();
88
- _i = 0, _a = manifest.services;
89
- _b.label = 2;
90
- case 2:
91
- if (!(_i < _a.length)) return [3 /*break*/, 6];
92
- service = _a[_i];
93
- console.log("reading: ".concat(service.swagger));
94
- return [4 /*yield*/, this.service(service, false)];
95
- case 3:
96
- code_1 = _b.sent();
97
- filename_1 = path_1["default"].join("src", "interface", "".concat(service.name, ".ts"));
98
- return [4 /*yield*/, fs_1["default"].promises.writeFile(filename_1, code_1)];
99
- case 4:
100
- _b.sent();
101
- _b.label = 5;
102
- case 5:
103
- _i++;
104
- return [3 /*break*/, 2];
105
- case 6: return [4 /*yield*/, this.client()];
106
- case 7:
107
- code = _b.sent();
108
- filename = path_1["default"].join("src", "index.ts");
109
- return [4 /*yield*/, fs_1["default"].promises.writeFile(filename, code)];
110
- case 8:
111
- _b.sent();
112
- return [2 /*return*/];
113
- }
114
- });
115
- });
116
- };
117
- CodeGenerator.prototype.client = function () {
118
- var _a;
119
- var _b;
120
- return __awaiter(this, void 0, void 0, function () {
121
- var print, imports, _i, _c, _import, _d, _e, _f, path_2, names, template;
122
- return __generator(this, function (_g) {
123
- print = new openapi_ts_1.Printer();
124
- // "do not modify" warning
125
- print.comment("THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY");
126
- print.blank();
127
- imports = {};
128
- for (_i = 0, _c = this.imports; _i < _c.length; _i++) {
129
- _import = _c[_i];
130
- (_a = imports[_b = _import.path]) !== null && _a !== void 0 ? _a : (imports[_b] = []);
131
- imports[_import.path].push(_import.name);
132
- }
133
- for (_d = 0, _e = Object.entries(imports); _d < _e.length; _d++) {
134
- _f = _e[_d], path_2 = _f[0], names = _f[1];
135
- print["import"](path_2, names);
136
- print.blank();
137
- }
138
- template = fs_1["default"].readFileSync("template.ejs", "utf-8");
139
- print.raw(ejs_1["default"].render(template, { methods: this.methods }));
140
- return [2 /*return*/, prettier_1["default"].format(print.code(), { parser: "typescript", printWidth: 100 })];
141
- });
142
- });
143
- };
144
- CodeGenerator.prototype.service = function (service, ambient) {
145
- return __awaiter(this, void 0, void 0, function () {
146
- var print, doc, details;
147
- return __generator(this, function (_a) {
148
- switch (_a.label) {
149
- case 0:
150
- print = new openapi_ts_1.Printer();
151
- return [4 /*yield*/, (0, openapi_ts_1.load)(service.swagger)];
152
- case 1:
153
- doc = _a.sent();
154
- details = (0, openapi_ts_1.analyse)(doc);
155
- this.transform(details, print, service, ambient);
156
- return [2 /*return*/, prettier_1["default"].format(print.code(), { parser: "typescript", printWidth: 100 })];
157
- }
158
- });
159
- });
160
- };
161
- /**
162
- * Add an import that the client will need.
163
- */
164
- CodeGenerator.prototype.addImport = function (service, name) {
165
- this.imports.push({
166
- name: name,
167
- path: "./interface/".concat(service.name)
168
- });
169
- };
170
- /**
171
- * Generate typescript code from the document details.
172
- */
173
- CodeGenerator.prototype.transform = function (doc, print, service, ambient) {
174
- // "do not modify" warning
175
- print.comment("THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY");
176
- print.blank();
177
- // declaration if it's ambient
178
- if (ambient) {
179
- print.raw("declare module \"@compassdigital/sdk.typescript/interface/".concat(service.name, "\" {"));
180
- }
181
- // utility types
182
- if (ambient) {
183
- print.raw("export type RequestQuery<T extends object> = { [K in keyof T]: T[K] extends number|undefined ? string : T[K]; }");
184
- }
185
- else {
186
- print["import"]("./util", ["RequestQuery"]);
187
- }
188
- print.blank();
189
- // definitions
190
- for (var _i = 0, _a = Object.entries(doc.definitions); _i < _a.length; _i++) {
191
- var _b = _a[_i], name_1 = _b[0], schema = _b[1];
192
- // allow additional propties in meta objects.
193
- var meta = schema.properties.meta;
194
- if ((meta === null || meta === void 0 ? void 0 : meta.type) === "object" && !meta.additional) {
195
- meta.additional = new openapi_ts_1.Schema();
196
- }
197
- print.schema(schema, name_1);
198
- print.blank();
199
- }
200
- // routes
201
- for (var _c = 0, _d = doc.operations; _c < _d.length; _c++) {
202
- var op = _d[_c];
203
- var params = op.params, path_3 = op.path;
204
- for (var _e = 0, _f = params.skipped; _e < _f.length; _e++) {
205
- var skipped = _f[_e];
206
- console.warn("SKIPPED", skipped);
207
- }
208
- // add missing path parameters
209
- for (var _g = 0, _h = this.findPathParams(path_3); _g < _h.length; _g++) {
210
- var name_2 = _h[_g];
211
- if (!params.path.properties[name_2]) {
212
- params.path.setProperty(name_2, new openapi_ts_1.Schema("string", {
213
- required: true,
214
- description: "TODO: add parameter to swagger.json"
215
- }));
216
- }
217
- }
218
- // make all path parameters required and valid path types.
219
- for (var _j = 0, _k = Object.values(params.path.properties); _j < _k.length; _j++) {
220
- var param = _k[_j];
221
- if (!param.required) {
222
- param.required = true;
223
- if (param.description) {
224
- param.description += "; ";
225
- }
226
- param.description += "TODO: mark parameter as required in swagger";
227
- }
228
- if (param.isRef() || param.type === "object") {
229
- if (param.description) {
230
- param.description += "; ";
231
- }
232
- param.description += "TODO: cannot use ".concat(param.type, " as path parameter");
233
- param.type = "string";
234
- }
235
- }
236
- // add nocache query parameter if x-cache-control is specified
237
- if (this.hasCacheControl(op) && !params.query.properties["nocache"]) {
238
- params.query.setProperty("nocache", new openapi_ts_1.Schema("boolean"));
239
- }
240
- var name_3 = this.inferName(op, service);
241
- var comment = "".concat(op.method.toUpperCase(), " ").concat(path_3);
242
- if (op.obj.summary) {
243
- comment += " - ".concat(op.obj.summary);
244
- }
245
- print.comment(comment);
246
- print.blank();
247
- // path parameters
248
- if (!params.path.isEmpty()) {
249
- var pathT = "".concat(name_3.pascal, "Path");
250
- print.schema(params.path, pathT);
251
- print.blank();
252
- }
253
- // query parameters
254
- var queryT = "".concat(name_3.pascal, "Query");
255
- if (!params.query.isEmpty()) {
256
- this.addImport(service, queryT);
257
- print.schema(params.query, queryT);
258
- print.blank();
259
- }
260
- // body
261
- var bodyT = "".concat(name_3.pascal, "Body");
262
- if (!params.body.isEmpty()) {
263
- this.addImport(service, bodyT);
264
- print.schema(params.body, bodyT);
265
- print.blank();
266
- }
267
- // response
268
- var responseT = "".concat(name_3.pascal, "Response");
269
- this.addImport(service, responseT);
270
- print.schema(params.response, responseT);
271
- print.blank();
272
- // server request
273
- var requestT = "".concat(name_3.pascal, "Request");
274
- print.schema(this.toRequestSchema(name_3, op), requestT);
275
- print.blank();
276
- // method parameters
277
- var method = {
278
- comment: comment,
279
- name: name_3.snake,
280
- params: [],
281
- args: ["\"".concat(service.name, "\""), "\"".concat(name_3.snake, "\""), "\"".concat(op.method, "\"")],
282
- response: responseT
283
- };
284
- // turn the path into a template string and add the
285
- // corresponding method parameters.
286
- var pathexpr = "`" + path_3 + "`";
287
- for (var _l = 0, _m = this.findPathParams(path_3); _l < _m.length; _l++) {
288
- var name_4 = _m[_l];
289
- var schema = params.path.properties[name_4];
290
- method.params.push({
291
- name: name_4,
292
- type: openapi_ts_1.Printer.type(schema),
293
- required: true,
294
- description: schema.description
295
- });
296
- pathexpr = pathexpr.replace("{".concat(name_4, "}"), "${" + name_4 + "}");
297
- }
298
- method.args.push(pathexpr);
299
- // if there's a body, make that a parameter too.
300
- if (!params.body.isEmpty()) {
301
- method.params.push({
302
- name: "body",
303
- type: bodyT,
304
- required: true,
305
- description: params.body.description
306
- });
307
- method.args.push("body");
308
- }
309
- else {
310
- method.args.push("null");
311
- }
312
- // build the options type.
313
- var options = new openapi_ts_1.Schema("empty");
314
- if (!params.query.isEmpty()) {
315
- var query = new openapi_ts_1.Schema(queryT);
316
- if (params.query.hasRequired()) {
317
- query.required = true;
318
- options.required = true;
319
- }
320
- options.setProperty("query", query);
321
- }
322
- options.merge(new openapi_ts_1.Schema("RequestOptions"));
323
- method.params.push({
324
- name: "options",
325
- type: openapi_ts_1.Printer.type(options),
326
- required: options.required,
327
- description: "additional request options"
328
- });
329
- method.args.push("options");
330
- this.methods.push(method);
331
- }
332
- // close declaration
333
- if (ambient) {
334
- print.raw("}");
335
- }
336
- };
337
- /**
338
- * Infer the operation name from the method and parameter.
339
- * These are a bunch of dirty hacks to make the generated names consistent.
340
- */
341
- CodeGenerator.prototype.inferName = function (op, service) {
342
- var method = op.method, path = op.path;
343
- var path_segments = [];
344
- // use the operationId from our collection if we have one.
345
- // TODO: update the swagger.json definitions so we don't need to do this.
346
- var operationID = operationIDs["".concat(op.method, " ").concat(op.path)];
347
- if (!operationID) {
348
- operationID = op.obj.operationId;
349
- }
350
- if (operationID) {
351
- var parts_1 = operationID.split("_");
352
- if (parts_1.length > 1) {
353
- // replace common operationId values with the canonical ones.
354
- if (parts_1[0] === "create") {
355
- parts_1[0] = "post";
356
- }
357
- if (parts_1[0] === "update") {
358
- parts_1[0] = "put";
359
- }
360
- if (parts_1[0] === "remove") {
361
- parts_1[0] = "delete";
362
- }
363
- if (parts_1[0] === "find") {
364
- parts_1[0] = "get";
365
- }
366
- if (!(0, openapi_ts_1.isMethod)(parts_1[0])) {
367
- parts_1.unshift(method);
368
- }
369
- if (parts_1[0] === method) {
370
- parts_1.shift(); // remove the method
371
- if (!parts_1[0].startsWith(service.name)) {
372
- parts_1.unshift(service.name);
373
- }
374
- path_segments = parts_1;
375
- }
376
- }
377
- if (parts_1.length > 1 && parts_1[0] === method) {
378
- parts_1.shift(); // remove the method
379
- if (!parts_1[0].startsWith(service.name)) {
380
- parts_1.unshift(service.name);
381
- }
382
- path_segments = parts_1;
383
- }
384
- }
385
- // combined the path & method into a name.
386
- if (path_segments.length === 0) {
387
- if (path.endsWith(".json")) {
388
- path = path.slice(0, -5);
389
- }
390
- path_segments = path.split("/").filter(function (segment) {
391
- return segment != "" && !segment.includes("{");
392
- });
393
- }
394
- var parts = __spreadArray([method.toLowerCase()], path_segments, true);
395
- return {
396
- snake: parts.join("_"),
397
- pascal: parts.map(function (s) { return s.charAt(0).toUpperCase() + s.substr(1); }).join('')
398
- };
399
- };
400
- /**
401
- * Check if the any response has caching enabled.
402
- */
403
- CodeGenerator.prototype.hasCacheControl = function (op) {
404
- var _a;
405
- var responses = Object.values((_a = op.obj.responses) !== null && _a !== void 0 ? _a : {});
406
- return responses.some(function (response) { return "x-cache-control" in response; });
407
- };
408
- /**
409
- * Find all the path parameter names.
410
- */
411
- CodeGenerator.prototype.findPathParams = function (path) {
412
- var matches = path.matchAll(/{[^}]*}/g);
413
- return Array.from(matches).map(function (match) {
414
- return match[0].slice(1, -1);
415
- });
416
- };
417
- /**
418
- * Create a Response type by combining the Query, Path, and Body types.
419
- */
420
- CodeGenerator.prototype.toRequestSchema = function (name, details) {
421
- var request = new openapi_ts_1.Schema("empty");
422
- if (!details.params.body.isEmpty()) {
423
- var body = new openapi_ts_1.Schema("".concat(name.pascal, "Body"));
424
- body.required = true;
425
- request.setProperty("body", body);
426
- }
427
- if (!details.params.query.isEmpty()) {
428
- request.merge(new openapi_ts_1.Schema("RequestQuery<".concat(name.pascal, "Query>")));
429
- }
430
- if (!details.params.path.isEmpty()) {
431
- request.merge(new openapi_ts_1.Schema("".concat(name.pascal, "Path")));
432
- }
433
- return request;
434
- };
435
- return CodeGenerator;
436
- }());
437
- exports.CodeGenerator = CodeGenerator;
438
- /**
439
- * Main entry point.
440
- */
441
- function main() {
442
- return __awaiter(this, void 0, void 0, function () {
443
- var argv, data, manifest, gen, gen, code;
444
- return __generator(this, function (_a) {
445
- switch (_a.label) {
446
- case 0:
447
- argv = (0, yargs_1["default"])((0, helpers_1.hideBin)(process.argv))
448
- .options("manifest", {
449
- type: "string",
450
- description: "manifest.json file to generate sdk from"
451
- })
452
- .options("swagger", {
453
- type: "string",
454
- description: "swagger.json file to generate interfaces from"
455
- })
456
- .options("service", {
457
- type: "string",
458
- description: "service name for generated interfaces"
459
- })
460
- .options("ambient", {
461
- type: "boolean",
462
- description: "wrap the types in a declare module directive",
463
- "default": true
464
- }).argv;
465
- if (!argv.manifest) return [3 /*break*/, 3];
466
- return [4 /*yield*/, fs_1["default"].promises.readFile(argv.manifest, "utf-8")];
467
- case 1:
468
- data = _a.sent();
469
- manifest = JSON.parse(data);
470
- gen = new CodeGenerator();
471
- return [4 /*yield*/, gen.manifest(manifest)];
472
- case 2:
473
- _a.sent();
474
- return [2 /*return*/];
475
- case 3:
476
- if (!(argv.swagger || argv.service)) return [3 /*break*/, 5];
477
- if (!argv.swagger) {
478
- throw new Error("--swagger must be provided with --service");
479
- }
480
- if (!argv.service) {
481
- throw new Error("--service must be provided with --swagger");
482
- }
483
- gen = new CodeGenerator();
484
- return [4 /*yield*/, gen.service({
485
- name: argv.service,
486
- swagger: argv.swagger
487
- }, argv.ambient)];
488
- case 4:
489
- code = _a.sent();
490
- console.log(code);
491
- return [2 /*return*/];
492
- case 5: return [2 /*return*/];
493
- }
494
- });
495
- });
496
- }
497
- main()["catch"](function (err) { return console.error(err.message); });
package/bin/index.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- require("./gen");