@keq-request/cli 5.0.0-alpha.26 → 5.0.0-alpha.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/cli.cjs +132 -86
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +132 -86
- package/dist/cli.js.map +1 -1
- package/dist/compiler/compiler.d.ts.map +1 -1
- package/dist/compiler/tasks/setup/index.d.ts.map +1 -1
- package/dist/compiler/tasks/setup/utils/index.d.ts +0 -1
- package/dist/compiler/tasks/setup/utils/index.d.ts.map +1 -1
- package/dist/compiler/tasks/setup/utils/parse-runtime-config.d.ts +3 -0
- package/dist/compiler/tasks/setup/utils/parse-runtime-config.d.ts.map +1 -0
- package/dist/compiler/types/compiler-context.d.ts +1 -1
- package/dist/compiler/types/compiler-context.d.ts.map +1 -1
- package/dist/compiler/types/compiler-hooks.d.ts +2 -1
- package/dist/compiler/types/compiler-hooks.d.ts.map +1 -1
- package/dist/define-config.d.ts +3 -0
- package/dist/define-config.d.ts.map +1 -0
- package/dist/index.cjs +137 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +136 -91
- package/dist/index.js.map +1 -1
- package/dist/models/module-definition.d.ts +3 -2
- package/dist/models/module-definition.d.ts.map +1 -1
- package/dist/plugins/download-http-file/download-http-file.plugin.d.ts +2 -2
- package/dist/plugins/download-http-file/download-http-file.plugin.d.ts.map +1 -1
- package/dist/plugins/download-local-file/download-local-file.plugin.d.ts.map +1 -1
- package/dist/plugins/shaking/shaking.plugin.d.ts.map +1 -1
- package/dist/plugins.cjs +25 -12
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.js +25 -12
- package/dist/plugins.js.map +1 -1
- package/dist/types/address.d.ts +8 -0
- package/dist/types/address.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/runtime-config.d.ts +16 -7
- package/dist/types/runtime-config.d.ts.map +1 -1
- package/dist/utils/is-valid-url.d.ts +16 -0
- package/dist/utils/is-valid-url.d.ts.map +1 -0
- package/package.json +3 -3
- package/dist/compiler/tasks/setup/utils/validate-modules.d.ts +0 -2
- package/dist/compiler/tasks/setup/utils/validate-modules.d.ts.map +0 -1
- package/dist/define-keq-config.d.ts +0 -3
- package/dist/define-keq-config.d.ts.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -30,7 +30,6 @@ import { AsyncParallelHook, AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } fro
|
|
|
30
30
|
// src/compiler/tasks/setup/index.ts
|
|
31
31
|
import fs3 from "fs-extra";
|
|
32
32
|
import path2 from "path";
|
|
33
|
-
import { Value } from "@sinclair/typebox/value";
|
|
34
33
|
import { cosmiconfig } from "cosmiconfig";
|
|
35
34
|
|
|
36
35
|
// src/utils/ignore-matcher.ts
|
|
@@ -124,8 +123,51 @@ var IgnoreMatcher = class _IgnoreMatcher {
|
|
|
124
123
|
}
|
|
125
124
|
};
|
|
126
125
|
|
|
127
|
-
// src/
|
|
126
|
+
// src/compiler/tasks/setup/utils/find-nearest-package-json.ts
|
|
127
|
+
import fs2 from "fs";
|
|
128
|
+
import path from "path";
|
|
129
|
+
function findNearestPackageJson(startDir = process.cwd()) {
|
|
130
|
+
let dir = startDir;
|
|
131
|
+
while (true) {
|
|
132
|
+
const pkgPath = path.join(dir, "package.json");
|
|
133
|
+
if (fs2.existsSync(pkgPath)) {
|
|
134
|
+
const json = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
|
|
135
|
+
return { json, path: pkgPath };
|
|
136
|
+
}
|
|
137
|
+
const parent = path.dirname(dir);
|
|
138
|
+
if (parent === dir) break;
|
|
139
|
+
dir = parent;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/compiler/tasks/setup/utils/get-project-module-system.ts
|
|
145
|
+
function getProjectModuleSystem(pkgInfo) {
|
|
146
|
+
if (!pkgInfo?.json) return "cjs";
|
|
147
|
+
const { json } = pkgInfo;
|
|
148
|
+
if (json.type === "module") return "esm";
|
|
149
|
+
return "cjs";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/compiler/tasks/setup/utils/parse-runtime-config.ts
|
|
153
|
+
import { Value } from "@sinclair/typebox/value";
|
|
154
|
+
|
|
155
|
+
// src/types/address.ts
|
|
128
156
|
import { Type } from "@sinclair/typebox";
|
|
157
|
+
var Address = Type.Object({
|
|
158
|
+
url: Type.String(),
|
|
159
|
+
headers: Type.Optional(Type.Record(Type.String(), Type.String(), { default: {} })),
|
|
160
|
+
encoding: Type.Optional(
|
|
161
|
+
Type.Union([
|
|
162
|
+
Type.Literal("utf8"),
|
|
163
|
+
Type.Literal("ascii")
|
|
164
|
+
], { default: "utf8" })
|
|
165
|
+
)
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// src/types/runtime-config.ts
|
|
169
|
+
import * as R2 from "ramda";
|
|
170
|
+
import { Type as Type2 } from "@sinclair/typebox";
|
|
129
171
|
|
|
130
172
|
// src/constants/file-naming-style.ts
|
|
131
173
|
var FileNamingStyle = /* @__PURE__ */ ((FileNamingStyle2) => {
|
|
@@ -143,13 +185,48 @@ var FileNamingStyle = /* @__PURE__ */ ((FileNamingStyle2) => {
|
|
|
143
185
|
return FileNamingStyle2;
|
|
144
186
|
})(FileNamingStyle || {});
|
|
145
187
|
|
|
188
|
+
// src/utils/is-valid-url.ts
|
|
189
|
+
var URL_REGEX = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(?:[^\s@]+@)?[^\s/:?#]*(?::\d+)?(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/;
|
|
190
|
+
function isValidURL(url) {
|
|
191
|
+
return URL_REGEX.test(url);
|
|
192
|
+
}
|
|
193
|
+
|
|
146
194
|
// src/types/runtime-config.ts
|
|
147
|
-
var
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
195
|
+
var Modules = Type2.Transform(
|
|
196
|
+
Type2.Record(
|
|
197
|
+
Type2.String(),
|
|
198
|
+
Type2.Union([Type2.String(), Address])
|
|
199
|
+
)
|
|
200
|
+
).Decode((value) => {
|
|
201
|
+
const keys2 = Object.keys(value);
|
|
202
|
+
for (const key of keys2) {
|
|
203
|
+
if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(key)) {
|
|
204
|
+
throw new Error(`Module name "${key}" is not valid. It must start with a letter or underscore, and can only contain letters, numbers, and underscores.`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const keysGroupByLowerCase = R2.groupBy(R2.toLower, keys2);
|
|
208
|
+
for (const groupKey in keysGroupByLowerCase) {
|
|
209
|
+
const keys3 = keysGroupByLowerCase[groupKey] || [];
|
|
210
|
+
if (keys3.length > 1) {
|
|
211
|
+
throw new Error(`Module names ${keys3.map((name) => `"${name}"`).join(", ")} are case-insensitively duplicated.`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
for (const key in value) {
|
|
215
|
+
const url = typeof value[key] === "string" ? value[key] : value[key].url;
|
|
216
|
+
if (isValidURL(url)) continue;
|
|
217
|
+
throw new Error(`The ${JSON.stringify(url)} of module "${key}" is not a valid URL.`);
|
|
218
|
+
}
|
|
219
|
+
return R2.map(
|
|
220
|
+
(item) => typeof item !== "string" ? item : { url: item, headers: {}, encoding: "utf8" },
|
|
221
|
+
value
|
|
222
|
+
);
|
|
223
|
+
}).Encode((value) => value);
|
|
224
|
+
var RawConfig = Type2.Object({
|
|
225
|
+
mode: Type2.Optional(
|
|
226
|
+
Type2.Union([
|
|
227
|
+
Type2.Literal("micro-function"),
|
|
228
|
+
Type2.Literal("nestjs-module"),
|
|
229
|
+
Type2.Literal("none")
|
|
153
230
|
], { default: "micro-function" })
|
|
154
231
|
),
|
|
155
232
|
/**
|
|
@@ -158,77 +235,39 @@ var RuntimeConfig = Type.Object({
|
|
|
158
235
|
* If not specified, the module system will be inferred from the nearest package.json "type" field
|
|
159
236
|
* or defaults to "cjs" if no package.json is found.
|
|
160
237
|
*/
|
|
161
|
-
esm:
|
|
238
|
+
esm: Type2.Optional(Type2.Boolean({ default: false })),
|
|
162
239
|
/**
|
|
163
240
|
* Output directory for generated files
|
|
164
241
|
*/
|
|
165
|
-
outdir:
|
|
242
|
+
outdir: Type2.String({ default: `${process.cwd()}/api` }),
|
|
166
243
|
/**
|
|
167
244
|
* File naming style for generated files
|
|
168
245
|
*/
|
|
169
|
-
fileNamingStyle:
|
|
170
|
-
modules:
|
|
171
|
-
debug:
|
|
246
|
+
fileNamingStyle: Type2.Enum(FileNamingStyle, { default: "snakeCase" /* snakeCase */ }),
|
|
247
|
+
modules: Modules,
|
|
248
|
+
debug: Type2.Optional(Type2.Boolean({ default: false })),
|
|
172
249
|
/**
|
|
173
250
|
* Whether to tolerate wrong openapi/swagger structure
|
|
174
251
|
*/
|
|
175
|
-
tolerant:
|
|
176
|
-
plugins:
|
|
252
|
+
tolerant: Type2.Optional(Type2.Boolean({ default: false })),
|
|
253
|
+
plugins: Type2.Optional(Type2.Array(Type2.Unsafe(Type2.Any()), { default: [] }))
|
|
177
254
|
});
|
|
178
255
|
|
|
179
|
-
// src/compiler/tasks/setup/utils/
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
throw new Error(`Module name "${key}" is not valid. It must start with a letter or underscore, and can only contain letters, numbers, and underscores.`);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
const keysGroupByLowerCase = R2.groupBy(R2.toLower, keys2);
|
|
190
|
-
for (const groupKey in keysGroupByLowerCase) {
|
|
191
|
-
const keys3 = keysGroupByLowerCase[groupKey] || [];
|
|
192
|
-
if (keys3.length > 1) {
|
|
193
|
-
throw new Error(`Module names ${keys3.map((name) => `"${name}"`).join(", ")} are case-insensitively duplicated.`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
for (const key in modules) {
|
|
197
|
-
const address = modules[key];
|
|
198
|
-
if (validator.isURL(address, { require_host: true, require_protocol: true, protocols: ["http", "https"] })) {
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
if (/^(\/|\.\/|\.\.\/)/.test(address)) {
|
|
202
|
-
continue;
|
|
256
|
+
// src/compiler/tasks/setup/utils/parse-runtime-config.ts
|
|
257
|
+
function parseRuntimeConfig(data) {
|
|
258
|
+
try {
|
|
259
|
+
const originalPlugins = typeof data === "object" && data !== null && "plugins" in data ? data.plugins : void 0;
|
|
260
|
+
const parsed = Value.Parse(RawConfig, data);
|
|
261
|
+
if (originalPlugins !== void 0) {
|
|
262
|
+
parsed.plugins = originalPlugins;
|
|
203
263
|
}
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
// src/compiler/tasks/setup/utils/find-nearest-package-json.ts
|
|
209
|
-
import fs2 from "fs";
|
|
210
|
-
import path from "path";
|
|
211
|
-
function findNearestPackageJson(startDir = process.cwd()) {
|
|
212
|
-
let dir = startDir;
|
|
213
|
-
while (true) {
|
|
214
|
-
const pkgPath = path.join(dir, "package.json");
|
|
215
|
-
if (fs2.existsSync(pkgPath)) {
|
|
216
|
-
const json = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
|
|
217
|
-
return { json, path: pkgPath };
|
|
264
|
+
return parsed;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (error instanceof Error) {
|
|
267
|
+
error.message = `Invalid Config: ${error.message}`;
|
|
218
268
|
}
|
|
219
|
-
|
|
220
|
-
if (parent === dir) break;
|
|
221
|
-
dir = parent;
|
|
269
|
+
throw error;
|
|
222
270
|
}
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// src/compiler/tasks/setup/utils/get-project-module-system.ts
|
|
227
|
-
function getProjectModuleSystem(pkgInfo) {
|
|
228
|
-
if (!pkgInfo?.json) return "cjs";
|
|
229
|
-
const { json } = pkgInfo;
|
|
230
|
-
if (json.type === "module") return "esm";
|
|
231
|
-
return "cjs";
|
|
232
271
|
}
|
|
233
272
|
|
|
234
273
|
// src/compiler/tasks/setup/index.ts
|
|
@@ -240,13 +279,7 @@ function main(compiler, options) {
|
|
|
240
279
|
if (!result || "isEmpty" in result && result.isEmpty) {
|
|
241
280
|
throw new Error("Cannot find config file.");
|
|
242
281
|
}
|
|
243
|
-
|
|
244
|
-
const errors = [...Value.Errors(RuntimeConfig, result.config)];
|
|
245
|
-
const message = errors.map(({ path: path13, message: message2 }) => `${path13}: ${message2}`).join("\n");
|
|
246
|
-
throw new Error(`Invalid Config: ${message}`);
|
|
247
|
-
}
|
|
248
|
-
const rc = Value.Default(RuntimeConfig, result.config);
|
|
249
|
-
validateModules(rc.modules);
|
|
282
|
+
const rc = parseRuntimeConfig(result.config);
|
|
250
283
|
if (options?.debug) {
|
|
251
284
|
await fs3.ensureDir(".keq");
|
|
252
285
|
rc.debug = true;
|
|
@@ -410,10 +443,14 @@ var ModuleDefinition = class _ModuleDefinition {
|
|
|
410
443
|
address;
|
|
411
444
|
constructor(name, address) {
|
|
412
445
|
this.name = name;
|
|
413
|
-
|
|
446
|
+
if (typeof address === "string") {
|
|
447
|
+
this.address = { url: address, headers: {}, encoding: "utf8" };
|
|
448
|
+
} else {
|
|
449
|
+
this.address = address;
|
|
450
|
+
}
|
|
414
451
|
}
|
|
415
452
|
static unknown() {
|
|
416
|
-
return new _ModuleDefinition("", "");
|
|
453
|
+
return new _ModuleDefinition("", { url: "", headers: {}, encoding: "utf8" });
|
|
417
454
|
}
|
|
418
455
|
};
|
|
419
456
|
|
|
@@ -878,10 +915,10 @@ function main2(compiler, options) {
|
|
|
878
915
|
task2.skip(`(${moduleDefinition.name}) is ignored`);
|
|
879
916
|
return;
|
|
880
917
|
}
|
|
881
|
-
task2.output = `Downloaded from ${moduleDefinition.address}`;
|
|
918
|
+
task2.output = `Downloaded from ${moduleDefinition.address.url}`;
|
|
882
919
|
const content = await compiler.hooks.download.promise(moduleDefinition.address, moduleDefinition, task2);
|
|
883
920
|
if (!content) {
|
|
884
|
-
throw new Exception(moduleDefinition, `Cannot download document from ${moduleDefinition.address}`);
|
|
921
|
+
throw new Exception(moduleDefinition, `Cannot download document from ${moduleDefinition.address.url}`);
|
|
885
922
|
}
|
|
886
923
|
const spec = JSON.parse(content);
|
|
887
924
|
const { valid, errors } = await validate(spec);
|
|
@@ -2540,24 +2577,25 @@ var GenerateNestjsModulePlugin = class _GenerateNestjsModulePlugin {
|
|
|
2540
2577
|
import { fixSwagger } from "swagger-fix";
|
|
2541
2578
|
|
|
2542
2579
|
// src/plugins/download-http-file/download-http-file.plugin.ts
|
|
2543
|
-
import * as validUrl from "valid-url";
|
|
2544
2580
|
var DownloadHttpFilePlugin = class _DownloadHttpFilePlugin {
|
|
2545
2581
|
apply(compiler) {
|
|
2546
2582
|
compiler.hooks.download.tapPromise(_DownloadHttpFilePlugin.name, async (address, task) => {
|
|
2547
|
-
|
|
2583
|
+
const { url } = address;
|
|
2584
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) return void 0;
|
|
2548
2585
|
const content = await this.download(address);
|
|
2549
2586
|
const spec = this.deserialize(content);
|
|
2550
2587
|
return JSON.stringify(spec);
|
|
2551
2588
|
});
|
|
2552
2589
|
}
|
|
2553
2590
|
async download(address) {
|
|
2591
|
+
const { url, headers } = address;
|
|
2554
2592
|
try {
|
|
2555
|
-
const res = await fetch(
|
|
2593
|
+
const res = await fetch(url, { headers });
|
|
2556
2594
|
if (res.status >= 400) throw new Error(`failed with status code ${res.status}`);
|
|
2557
2595
|
return await res.text();
|
|
2558
2596
|
} catch (e) {
|
|
2559
2597
|
if (e instanceof Error) {
|
|
2560
|
-
e.message = `Unable get the openapi/swagger file from ${
|
|
2598
|
+
e.message = `Unable get the openapi/swagger file from ${url}: ${e.message}`;
|
|
2561
2599
|
}
|
|
2562
2600
|
throw e;
|
|
2563
2601
|
}
|
|
@@ -2573,17 +2611,21 @@ var DownloadHttpFilePlugin = class _DownloadHttpFilePlugin {
|
|
|
2573
2611
|
import * as path12 from "path";
|
|
2574
2612
|
import * as fs5 from "fs/promises";
|
|
2575
2613
|
import * as yaml from "js-yaml";
|
|
2614
|
+
import { fileURLToPath } from "url";
|
|
2576
2615
|
var DownloadLocalFilePlugin = class _DownloadLocalFilePlugin {
|
|
2577
2616
|
apply(compiler) {
|
|
2578
2617
|
compiler.hooks.download.tapPromise(_DownloadLocalFilePlugin.name, async (address, task) => {
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
const
|
|
2618
|
+
const { url, encoding } = address;
|
|
2619
|
+
if (!url.startsWith("file://")) return void 0;
|
|
2620
|
+
const filepath = fileURLToPath(url);
|
|
2621
|
+
const fileExt = path12.extname(filepath);
|
|
2622
|
+
const content = await fs5.readFile(filepath, encoding);
|
|
2623
|
+
const str = typeof content === "string" ? content : content.toString(encoding);
|
|
2582
2624
|
if ([".yml", ".yaml"].includes(fileExt)) {
|
|
2583
|
-
const value = yaml.load(
|
|
2625
|
+
const value = yaml.load(str);
|
|
2584
2626
|
return JSON.stringify(OpenapiUtils.to3_1(value));
|
|
2585
2627
|
} else if (fileExt === ".json") {
|
|
2586
|
-
return JSON.stringify(OpenapiUtils.to3_1(JSON.parse(
|
|
2628
|
+
return JSON.stringify(OpenapiUtils.to3_1(JSON.parse(str)));
|
|
2587
2629
|
}
|
|
2588
2630
|
});
|
|
2589
2631
|
}
|
|
@@ -2621,7 +2663,11 @@ var ShakingPlugin = class _ShakingPlugin {
|
|
|
2621
2663
|
sharkedSwagger,
|
|
2622
2664
|
new ModuleDefinition(
|
|
2623
2665
|
document.module.name,
|
|
2624
|
-
|
|
2666
|
+
{
|
|
2667
|
+
url: `memory://${document.module.name}.v3_1.sharked.json`,
|
|
2668
|
+
headers: {},
|
|
2669
|
+
encoding: "utf8"
|
|
2670
|
+
}
|
|
2625
2671
|
)
|
|
2626
2672
|
);
|
|
2627
2673
|
}
|