api-farmer 0.1.3 → 0.1.4

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.cjs DELETED
@@ -1,471 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __esm = (fn, res) => function __init() {
10
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
- };
12
- var __export = (target, all) => {
13
- for (var name in all)
14
- __defProp(target, name, { get: all[name], enumerable: true });
15
- };
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") {
18
- for (let key of __getOwnPropNames(from))
19
- if (!__hasOwnProp.call(to, key) && key !== except)
20
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
- }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
- // If the importer is in node compatibility mode or this is not an ESM
26
- // file that has been converted to a CommonJS file using a Babel-
27
- // compatible transform (i.e. "__esModule" has not been set), then set
28
- // "default" to the CommonJS "module.exports" for node compatibility.
29
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
- mod
31
- ));
32
-
33
- // node_modules/.pnpm/tsup@8.3.5_jiti@2.4.2_postcss@8.5.1_tsx@4.19.2_typescript@5.3.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js
34
- var init_cjs_shims = __esm({
35
- "node_modules/.pnpm/tsup@8.3.5_jiti@2.4.2_postcss@8.5.1_tsx@4.19.2_typescript@5.3.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js"() {
36
- "use strict";
37
- }
38
- });
39
-
40
- // src/constants.ts
41
- var import_path, CWD, CUSTOM_TEMPLATE_FILE, CLI_PACKAGE_JSON, SUPPORTED_HTTP_METHODS;
42
- var init_constants = __esm({
43
- "src/constants.ts"() {
44
- "use strict";
45
- init_cjs_shims();
46
- import_path = require("path");
47
- CWD = process.cwd();
48
- CUSTOM_TEMPLATE_FILE = (0, import_path.resolve)(CWD, `./api-farmer.ejs`);
49
- CLI_PACKAGE_JSON = (0, import_path.resolve)(__dirname, "../package.json");
50
- SUPPORTED_HTTP_METHODS = ["get", "post", "put", "delete", "patch", "options", "head"];
51
- }
52
- });
53
-
54
- // src/utils.ts
55
- async function readSchema(input) {
56
- const content = await readSchemaContent(input);
57
- const jsonSchema = (0, import_rattail.tryParseJSON)(content);
58
- const swaggerOrOpenapiSchema = jsonSchema ? jsonSchema : import_yaml.default.parse(content);
59
- const schema = swaggerOrOpenapiSchema.swagger ? (await import_swagger2openapi.default.convert(swaggerOrOpenapiSchema, {})).openapi : swaggerOrOpenapiSchema;
60
- return schema;
61
- }
62
- async function readSchemaContent(input) {
63
- if (isRemoteSchema(input)) {
64
- try {
65
- import_rslog.logger.info("Fetching remote schema...");
66
- const { data } = await (0, import_axle.createAxle)().get(input);
67
- return JSON.stringify(data);
68
- } catch {
69
- throw new Error("Failed to fetch remote schema");
70
- }
71
- }
72
- const path = (0, import_path2.resolve)(CWD, input);
73
- const content = import_fs_extra.default.readFileSync(path, "utf-8");
74
- return content;
75
- }
76
- function isRemoteSchema(path) {
77
- return path.startsWith("http://") || path.startsWith("https://");
78
- }
79
- function readTemplateFile(preset = "axle") {
80
- if (import_fs_extra.default.existsSync(CUSTOM_TEMPLATE_FILE)) {
81
- return import_fs_extra.default.readFileSync(CUSTOM_TEMPLATE_FILE, "utf-8");
82
- }
83
- return import_fs_extra.default.readFileSync((0, import_path2.resolve)(__dirname, `../templates/${preset}.ejs`), "utf-8");
84
- }
85
- function getCliVersion() {
86
- return import_fs_extra.default.readJsonSync(CLI_PACKAGE_JSON).version;
87
- }
88
- function isRequiredRequestBody(value) {
89
- return "required" in value && value.required === true;
90
- }
91
- function findObjectKey(object, targetKeys) {
92
- return Object.keys(object).find((key) => targetKeys.includes(key));
93
- }
94
- function getRequestBodyContentType(value) {
95
- if (!("content" in value)) {
96
- return "";
97
- }
98
- return findObjectKey(value.content, ["application/json", "application/x-www-form-urlencoded", "multipart/form-data"]);
99
- }
100
- function getResponseMetadataItems(operation, validateStatus) {
101
- const responses = operation.responses ?? {};
102
- const validStatusResults = Object.keys(responses).sort((a, b) => Number(a) - Number(b)).filter((key) => validateStatus(Number(key))).map(Number);
103
- const metadataItems = validStatusResults.map((status) => {
104
- const content = operation.responses?.[status]?.content ?? {};
105
- const responseContentType = findObjectKey(content, ["application/json", "application/octet-stream", "*/*"]);
106
- return {
107
- status,
108
- responseContentType
109
- };
110
- }).filter((result) => result.responseContentType);
111
- return metadataItems;
112
- }
113
- var import_path2, import_axle, import_fs_extra, import_rattail, import_rslog, import_swagger2openapi, import_yaml;
114
- var init_utils = __esm({
115
- "src/utils.ts"() {
116
- "use strict";
117
- init_cjs_shims();
118
- import_path2 = require("path");
119
- import_axle = require("@varlet/axle");
120
- import_fs_extra = __toESM(require("fs-extra"), 1);
121
- import_rattail = require("rattail");
122
- import_rslog = require("rslog");
123
- import_swagger2openapi = __toESM(require("swagger2openapi"), 1);
124
- import_yaml = __toESM(require("yaml"), 1);
125
- init_constants();
126
- }
127
- });
128
-
129
- // src/config.ts
130
- async function getConfig() {
131
- const { config } = await (0, import_unconfig.loadConfig)({
132
- sources: [
133
- {
134
- files: "api-farmer.config"
135
- }
136
- ]
137
- });
138
- return config ?? {};
139
- }
140
- var import_unconfig;
141
- var init_config = __esm({
142
- "src/config.ts"() {
143
- "use strict";
144
- init_cjs_shims();
145
- import_unconfig = require("unconfig");
146
- }
147
- });
148
-
149
- // src/transformer.ts
150
- function transformModuleName({ name }) {
151
- return (0, import_rattail2.camelize)(name);
152
- }
153
- function transformUrl({ path }) {
154
- return path.replace(/{/g, ":").replace(/}/g, "");
155
- }
156
- function transformComment({
157
- summary,
158
- description,
159
- path,
160
- method
161
- }) {
162
- return `
163
- /**${summary ? `
164
- * ${summary}` : ""}${description && summary !== description ? `
165
- * @description ${description}
166
- *` : ""}
167
- * @url ${path}
168
- * @method ${method.toLocaleUpperCase()}
169
- */
170
- `.trim();
171
- }
172
- function transformVerb({ method }) {
173
- switch (method) {
174
- case "post":
175
- return "Create";
176
- case "put":
177
- return "Update";
178
- default:
179
- return (0, import_rattail2.pascalCase)(method);
180
- }
181
- }
182
- function transformEntity({ path, method, uncountableNouns }) {
183
- const words = path.split("/").filter(Boolean);
184
- return words.reduce((entity, word, index) => {
185
- if (word.includes("{")) {
186
- return entity;
187
- }
188
- word = word.replace(/\.([a-z])/g, (_, p) => p.toUpperCase());
189
- const isUncountableNoun = uncountableNouns.includes(word);
190
- word = (0, import_rattail2.pascalCase)(word);
191
- word = isUncountableNoun ? word : import_pluralize.default.singular(word);
192
- if (method === "get" && index === words.length - 1) {
193
- word = isUncountableNoun ? `${word}List` : import_pluralize.default.plural(word);
194
- }
195
- return `${entity}${word}`;
196
- }, "");
197
- }
198
- function transformFn({ verb, entity }) {
199
- return `api${verb}${entity}`;
200
- }
201
- function transformType({ verb, entity }) {
202
- return `Api${verb}${entity}`;
203
- }
204
- function transformTypeValue({ fullPath, method }) {
205
- return `paths['${fullPath}']['${method}']`;
206
- }
207
- function transformTypeQuery({ type }) {
208
- return `${type}Query`;
209
- }
210
- function transformTypeQueryValue({
211
- type
212
- }) {
213
- return `${type}['parameters']['query']`;
214
- }
215
- function transformTypeRequestBody({
216
- type
217
- }) {
218
- return `${type}RequestBody`;
219
- }
220
- function transformTypeRequestBodyValue({
221
- type,
222
- required,
223
- requestContentType
224
- }) {
225
- return required ? `${type}['requestBody']['content']['${requestContentType}']` : `NonNullable<${type}['requestBody']>['content']['${requestContentType}'] | undefined`;
226
- }
227
- function transformTypeResponseBody({
228
- type
229
- }) {
230
- return `${type}ResponseBody`;
231
- }
232
- function transformTypeResponseBodyValue({
233
- type,
234
- responseMetadataItems
235
- }) {
236
- return responseMetadataItems.map(({ status, responseContentType }) => `${type}['responses']['${status}']['content']['${responseContentType}']`).join(" | ");
237
- }
238
- function createTransformer() {
239
- return {
240
- moduleName: transformModuleName,
241
- verb: transformVerb,
242
- url: transformUrl,
243
- comment: transformComment,
244
- entity: transformEntity,
245
- fn: transformFn,
246
- type: transformType,
247
- typeValue: transformTypeValue,
248
- typeQuery: transformTypeQuery,
249
- typeQueryValue: transformTypeQueryValue,
250
- typeRequestBody: transformTypeRequestBody,
251
- typeRequestBodyValue: transformTypeRequestBodyValue,
252
- typeResponseBody: transformTypeResponseBody,
253
- typeResponseBodyValue: transformTypeResponseBodyValue
254
- };
255
- }
256
- var import_pluralize, import_rattail2;
257
- var init_transformer = __esm({
258
- "src/transformer.ts"() {
259
- "use strict";
260
- init_cjs_shims();
261
- import_pluralize = __toESM(require("pluralize"), 1);
262
- import_rattail2 = require("rattail");
263
- }
264
- });
265
-
266
- // src/generate.ts
267
- var generate_exports = {};
268
- __export(generate_exports, {
269
- generate: () => generate,
270
- generateTypes: () => generateTypes,
271
- partitionApiModules: () => partitionApiModules,
272
- renderApiModules: () => renderApiModules,
273
- transformPayloads: () => transformPayloads
274
- });
275
- function transformPayloads(pathItems, options) {
276
- const { transformer, path, fullPath, base, uncountableNouns, validateStatus, excludeDeprecated } = options;
277
- return Object.entries(pathItems).filter(([key]) => SUPPORTED_HTTP_METHODS.includes(key)).filter(([, operation]) => !(excludeDeprecated && operation.deprecated)).reduce((payloads, [method, operation]) => {
278
- const url = transformer.url({ path, base, fullPath });
279
- const args = { path, base, fullPath, url, method, uncountableNouns, operation };
280
- const entity = transformer.entity(args);
281
- const verb = transformer.verb(args);
282
- const comment = transformer.comment({ ...args, ...operation });
283
- const requestContentType = operation.requestBody ? getRequestBodyContentType(operation.requestBody) : void 0;
284
- const responseMetadataItems = getResponseMetadataItems(operation, validateStatus);
285
- const fn = transformer.fn({ ...args, verb, entity });
286
- const type = transformer.type({ ...args, verb, entity });
287
- const typeValue = transformer.typeValue({ ...args, verb, entity });
288
- const typeQuery = transformer.typeQuery({ ...args, type, verb, entity });
289
- const typeQueryValue = transformer.typeQueryValue({ ...args, type, verb, entity });
290
- const typeRequestBody = transformer.typeRequestBody({ ...args, type, verb, entity });
291
- const typeRequestBodyValue = operation.requestBody && requestContentType ? transformer.typeRequestBodyValue({
292
- ...args,
293
- type,
294
- verb,
295
- entity,
296
- required: isRequiredRequestBody(operation.requestBody),
297
- requestContentType
298
- }) : "undefined";
299
- const typeResponseBody = transformer.typeResponseBody({ ...args, type, verb, entity });
300
- const typeResponseBodyValue = responseMetadataItems.length > 0 ? transformer.typeResponseBodyValue({ ...args, type, verb, entity, responseMetadataItems }) : "undefined";
301
- payloads.push({
302
- comment,
303
- fn,
304
- url,
305
- method,
306
- verb,
307
- entity,
308
- requestContentType,
309
- type,
310
- typeValue,
311
- typeQuery,
312
- typeQueryValue,
313
- typeRequestBody,
314
- typeRequestBodyValue,
315
- typeResponseBody,
316
- typeResponseBodyValue
317
- });
318
- return payloads;
319
- }, []);
320
- }
321
- function partitionApiModules(schema, options) {
322
- const { base, transformer, uncountableNouns, validateStatus, excludeDeprecated } = options;
323
- const schemaPaths = schema.paths ?? {};
324
- const schemaPathKeys = base ? Object.keys(schemaPaths).map((key) => key.replace(base, "")) : Object.keys(schemaPaths);
325
- const keyToPaths = (0, import_rattail3.groupBy)(schemaPathKeys, (key) => key.split("/")[1]);
326
- const apiModules = Object.entries(keyToPaths).reduce((apiModules2, [name, paths]) => {
327
- const payloads = paths.reduce((payloads2, path) => {
328
- const fullPath = base ? base + path : path;
329
- const pathItems = schemaPaths[fullPath];
330
- payloads2.push(
331
- ...transformPayloads(pathItems, {
332
- ...options,
333
- path,
334
- fullPath,
335
- transformer,
336
- uncountableNouns,
337
- validateStatus,
338
- excludeDeprecated
339
- })
340
- );
341
- return payloads2;
342
- }, []);
343
- apiModules2.push({ name: transformer.moduleName({ name }), payloads });
344
- return apiModules2;
345
- }, []);
346
- return apiModules;
347
- }
348
- function renderApiModules(apiModules, options) {
349
- const { output, ts: ts2, typesOnly, overrides, preset } = options;
350
- const templateFile = readTemplateFile(preset);
351
- const typesFilename = options.typesFilename.replace(".ts", "");
352
- return Promise.all(
353
- apiModules.map(
354
- (apiModule) => new Promise((promiseResolve) => {
355
- const data = {
356
- apiModule,
357
- typesFilename,
358
- ts: ts2,
359
- typesOnly
360
- };
361
- import_prettier.default.format(import_ejs.default.render(templateFile, data), {
362
- parser: "typescript",
363
- semi: false,
364
- singleQuote: true,
365
- printWidth: 120
366
- }).then((content) => {
367
- const path = (0, import_path3.resolve)(output, `${apiModule.name}.${ts2 ? "ts" : "js"}`);
368
- const shouldSkip = (!overrides || (0, import_rattail3.isArray)(overrides) && !overrides.includes(apiModule.name)) && import_fs_extra2.default.existsSync(path);
369
- if (shouldSkip) {
370
- import_rslog2.logger.warn(`File already exists, skip: ${path}`);
371
- promiseResolve(content);
372
- return;
373
- }
374
- import_fs_extra2.default.outputFileSync(path, content);
375
- import_rslog2.logger.success(`Generated ${path}`);
376
- promiseResolve(content);
377
- });
378
- })
379
- )
380
- );
381
- }
382
- async function generateTypes(schema, output, typesFilename, openapiTsOptions) {
383
- const BLOB = import_typescript.default.factory.createTypeReferenceNode(import_typescript.default.factory.createIdentifier("Blob"));
384
- const NULL = import_typescript.default.factory.createLiteralTypeNode(import_typescript.default.factory.createNull());
385
- const ast = await (0, import_openapi_typescript.default)(schema, {
386
- defaultNonNullable: false,
387
- transform(schemaObject) {
388
- if (schemaObject.format === "binary") {
389
- return schemaObject.nullable ? import_typescript.default.factory.createUnionTypeNode([BLOB, NULL]) : BLOB;
390
- }
391
- },
392
- ...openapiTsOptions
393
- });
394
- const contents = (0, import_openapi_typescript.astToString)(ast);
395
- const typesFilepath = (0, import_path3.resolve)(CWD, output, typesFilename);
396
- import_fs_extra2.default.outputFileSync(typesFilepath, contents);
397
- import_rslog2.logger.success(`Generated ${typesFilepath}`);
398
- }
399
- async function generate(userOptions = {}) {
400
- const config = await getConfig();
401
- const options = (0, import_rattail3.merge)(config, userOptions);
402
- const {
403
- base,
404
- ts: ts2 = true,
405
- typesOnly = false,
406
- overrides = true,
407
- preset = "axle",
408
- input = "./schema.json",
409
- output = "./src/apis/generated",
410
- typesFilename = "_types.ts",
411
- clean = false,
412
- validateStatus = (status) => status >= 200 && status < 300,
413
- transformer = {},
414
- uncountableNouns = [],
415
- openapiTsOptions = {},
416
- excludeDeprecated = false
417
- } = options;
418
- const mergedTransformer = { ...createTransformer(), ...transformer };
419
- const schema = await readSchema(input);
420
- if (clean) {
421
- import_fs_extra2.default.removeSync((0, import_path3.resolve)(CWD, output));
422
- import_rslog2.logger.info(`Cleaned output directory: ${(0, import_path3.resolve)(CWD, output)}`);
423
- }
424
- import_rslog2.logger.info("Generating API modules...");
425
- if (openapiTsOptions.excludeDeprecated === void 0) {
426
- openapiTsOptions.excludeDeprecated = excludeDeprecated;
427
- }
428
- if (ts2) {
429
- await generateTypes(schema, output, typesFilename, openapiTsOptions);
430
- }
431
- const apiModules = partitionApiModules(schema, {
432
- base,
433
- uncountableNouns,
434
- transformer: mergedTransformer,
435
- validateStatus,
436
- excludeDeprecated
437
- });
438
- await renderApiModules(apiModules, { output, typesFilename, ts: ts2, typesOnly, overrides, preset });
439
- import_rslog2.logger.success("Done");
440
- }
441
- var import_path3, import_ejs, import_fs_extra2, import_openapi_typescript, import_prettier, import_rattail3, import_rslog2, import_typescript;
442
- var init_generate = __esm({
443
- "src/generate.ts"() {
444
- "use strict";
445
- init_cjs_shims();
446
- import_path3 = require("path");
447
- import_ejs = __toESM(require("ejs"), 1);
448
- import_fs_extra2 = __toESM(require("fs-extra"), 1);
449
- import_openapi_typescript = __toESM(require("openapi-typescript"), 1);
450
- import_prettier = __toESM(require("prettier"), 1);
451
- import_rattail3 = require("rattail");
452
- import_rslog2 = require("rslog");
453
- import_typescript = __toESM(require("typescript"), 1);
454
- init_config();
455
- init_constants();
456
- init_transformer();
457
- init_utils();
458
- }
459
- });
460
-
461
- // src/cli.ts
462
- init_cjs_shims();
463
- var import_commander = require("commander");
464
- init_utils();
465
- var program = new import_commander.Command();
466
- program.version(getCliVersion());
467
- program.action(async () => {
468
- const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), generate_exports));
469
- return generate2();
470
- });
471
- program.parse();
package/dist/cli.d.cts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
package/dist/cli.d.ts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
package/dist/cli.js DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- getCliVersion
4
- } from "./chunk-2227C45C.js";
5
-
6
- // src/cli.ts
7
- import { Command } from "commander";
8
- var program = new Command();
9
- program.version(getCliVersion());
10
- program.action(async () => {
11
- const { generate } = await import("./generate-4J5VPBTS.js");
12
- return generate();
13
- });
14
- program.parse();
@@ -1,15 +0,0 @@
1
- import {
2
- generate,
3
- generateTypes,
4
- partitionApiModules,
5
- renderApiModules,
6
- transformPayloads
7
- } from "./chunk-RIXLRGPZ.js";
8
- import "./chunk-2227C45C.js";
9
- export {
10
- generate,
11
- generateTypes,
12
- partitionApiModules,
13
- renderApiModules,
14
- transformPayloads
15
- };