prisma-swagger-autogen 1.0.10 → 1.0.11
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 +136 -25
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -28,18 +28,18 @@ var import_node_fs = __toESM(require("fs"), 1);
|
|
|
28
28
|
var import_node_path = __toESM(require("path"), 1);
|
|
29
29
|
var import_node_module = require("module");
|
|
30
30
|
var import_glob = require("glob");
|
|
31
|
-
var
|
|
31
|
+
var DEFAULT_CONFIG = {
|
|
32
32
|
projectRoot: process.cwd(),
|
|
33
|
-
controllersGlob: "
|
|
33
|
+
controllersGlob: "./**/controllers/**/*.ts",
|
|
34
34
|
outFile: "./swagger.config.js",
|
|
35
|
-
openapiOut: "
|
|
36
|
-
serviceTitle: "
|
|
37
|
-
serverUrl: "http://localhost:
|
|
35
|
+
openapiOut: "./**/openapi.json",
|
|
36
|
+
serviceTitle: "Microservice Swagger Docs",
|
|
37
|
+
serverUrl: "http://localhost:3000",
|
|
38
38
|
securitySchemeName: "keycloakOAuth",
|
|
39
39
|
oauth: {
|
|
40
|
-
tokenUrl: "http://
|
|
41
|
-
refreshUrl: "http://
|
|
42
|
-
scopes: { openid: "openid
|
|
40
|
+
tokenUrl: "http://localhost:8080/realms/master/protocol/openid-connect/token",
|
|
41
|
+
refreshUrl: "http://localhost:8080/realms/master/protocol/openid-connect/refresh",
|
|
42
|
+
scopes: { openid: "openid" }
|
|
43
43
|
},
|
|
44
44
|
omitFieldsInWriteDtos: /* @__PURE__ */ new Set(["id", "createdAt", "updatedAt", "v"])
|
|
45
45
|
};
|
|
@@ -53,6 +53,116 @@ function pluralize(name) {
|
|
|
53
53
|
function getRequire() {
|
|
54
54
|
return (0, import_node_module.createRequire)(typeof __filename !== "undefined" ? __filename : process.cwd() + "/");
|
|
55
55
|
}
|
|
56
|
+
function parseJsonObject(value, flagName) {
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(value);
|
|
59
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
60
|
+
throw new Error("must be a JSON object");
|
|
61
|
+
}
|
|
62
|
+
return parsed;
|
|
63
|
+
} catch (e) {
|
|
64
|
+
throw new Error(`Invalid JSON for ${flagName}: ${e?.message ?? String(e)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function parseCsv(value) {
|
|
68
|
+
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
69
|
+
}
|
|
70
|
+
function readFlagValue(args, flag) {
|
|
71
|
+
const i = args.findIndex((a) => a === flag);
|
|
72
|
+
if (i < 0) return void 0;
|
|
73
|
+
const v = args[i + 1];
|
|
74
|
+
if (!v || v.startsWith("--")) return void 0;
|
|
75
|
+
return v;
|
|
76
|
+
}
|
|
77
|
+
function hasFlag(args, flag) {
|
|
78
|
+
return args.includes(flag);
|
|
79
|
+
}
|
|
80
|
+
function parseArgs(args) {
|
|
81
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
82
|
+
const help = `
|
|
83
|
+
prisma-swagger-autogen
|
|
84
|
+
|
|
85
|
+
Usage:
|
|
86
|
+
prisma-swagger-autogen [options]
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
--schema <path> Prisma schema path (default: ./prisma/schema.prisma)
|
|
90
|
+
|
|
91
|
+
--projectRoot <path> Project root for resolving outFile/openapiOut (default: cwd)
|
|
92
|
+
--controllersGlob <glob> Glob for controller files (default: ./**/controllers/**/*.ts)
|
|
93
|
+
--outFile <path> Path to write swagger.config.js (default: ./swagger.config.js)
|
|
94
|
+
--openapiOut <path> Path swagger-autogen writes OpenAPI JSON (default: ./openapi.json)
|
|
95
|
+
|
|
96
|
+
--serviceTitle <string> OpenAPI title
|
|
97
|
+
--serverUrl <url> OpenAPI server url
|
|
98
|
+
--securitySchemeName <string> Security scheme name
|
|
99
|
+
|
|
100
|
+
--oauthTokenUrl <url> OAuth2 tokenUrl
|
|
101
|
+
--oauthRefreshUrl <url> OAuth2 refreshUrl
|
|
102
|
+
--oauthScopes <json> OAuth2 scopes as JSON object, e.g. {"openid":"openid scope"}
|
|
103
|
+
|
|
104
|
+
--omitFields <csv> Comma-separated fields to omit in write DTOs (default: id,createdAt,updatedAt,v)
|
|
105
|
+
|
|
106
|
+
Examples:
|
|
107
|
+
prisma-swagger-autogen
|
|
108
|
+
prisma-swagger-autogen --schema ./prisma/schema.prisma
|
|
109
|
+
prisma-swagger-autogen --controllersGlob "./src/api/**/*.ts" --outFile ./swagger.config.js
|
|
110
|
+
prisma-swagger-autogen --oauthScopes '{"openid":"openid scope","profile":"profile"}'
|
|
111
|
+
`.trim();
|
|
112
|
+
process.stdout.write(help + "\n");
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
const schemaPath = readFlagValue(args, "--schema");
|
|
116
|
+
const projectRoot = readFlagValue(args, "--projectRoot");
|
|
117
|
+
const controllersGlob = readFlagValue(args, "--controllersGlob");
|
|
118
|
+
const outFile = readFlagValue(args, "--outFile");
|
|
119
|
+
const openapiOut = readFlagValue(args, "--openapiOut");
|
|
120
|
+
const serviceTitle = readFlagValue(args, "--serviceTitle");
|
|
121
|
+
const serverUrl = readFlagValue(args, "--serverUrl");
|
|
122
|
+
const securitySchemeName = readFlagValue(args, "--securitySchemeName");
|
|
123
|
+
const oauthTokenUrl = readFlagValue(args, "--oauthTokenUrl");
|
|
124
|
+
const oauthRefreshUrl = readFlagValue(args, "--oauthRefreshUrl");
|
|
125
|
+
const oauthScopesRaw = readFlagValue(args, "--oauthScopes");
|
|
126
|
+
const omitFieldsRaw = readFlagValue(args, "--omitFields");
|
|
127
|
+
const oauthScopes = oauthScopesRaw ? parseJsonObject(oauthScopesRaw, "--oauthScopes") : void 0;
|
|
128
|
+
const omitFieldsInWriteDtos = omitFieldsRaw ? parseCsv(omitFieldsRaw) : void 0;
|
|
129
|
+
return {
|
|
130
|
+
schemaPath,
|
|
131
|
+
projectRoot,
|
|
132
|
+
controllersGlob,
|
|
133
|
+
outFile,
|
|
134
|
+
openapiOut,
|
|
135
|
+
serviceTitle,
|
|
136
|
+
serverUrl,
|
|
137
|
+
securitySchemeName,
|
|
138
|
+
oauthTokenUrl,
|
|
139
|
+
oauthRefreshUrl,
|
|
140
|
+
oauthScopes,
|
|
141
|
+
omitFieldsInWriteDtos
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function mergeConfig(base, parsed) {
|
|
145
|
+
const cfg = {
|
|
146
|
+
...base,
|
|
147
|
+
projectRoot: parsed.projectRoot ? import_node_path.default.resolve(process.cwd(), parsed.projectRoot) : base.projectRoot,
|
|
148
|
+
controllersGlob: parsed.controllersGlob ?? base.controllersGlob,
|
|
149
|
+
outFile: parsed.outFile ?? base.outFile,
|
|
150
|
+
openapiOut: parsed.openapiOut ?? base.openapiOut,
|
|
151
|
+
serviceTitle: parsed.serviceTitle ?? base.serviceTitle,
|
|
152
|
+
serverUrl: parsed.serverUrl ?? base.serverUrl,
|
|
153
|
+
securitySchemeName: parsed.securitySchemeName ?? base.securitySchemeName,
|
|
154
|
+
oauth: {
|
|
155
|
+
tokenUrl: parsed.oauthTokenUrl ?? base.oauth.tokenUrl,
|
|
156
|
+
refreshUrl: parsed.oauthRefreshUrl ?? base.oauth.refreshUrl,
|
|
157
|
+
scopes: parsed.oauthScopes ?? base.oauth.scopes
|
|
158
|
+
},
|
|
159
|
+
omitFieldsInWriteDtos: parsed.omitFieldsInWriteDtos ? new Set(parsed.omitFieldsInWriteDtos) : base.omitFieldsInWriteDtos
|
|
160
|
+
};
|
|
161
|
+
cfg.controllersGlob = ensurePosix(cfg.controllersGlob);
|
|
162
|
+
cfg.outFile = ensurePosix(cfg.outFile);
|
|
163
|
+
cfg.openapiOut = ensurePosix(cfg.openapiOut);
|
|
164
|
+
return cfg;
|
|
165
|
+
}
|
|
56
166
|
async function loadDmmfFromProject(schemaPath) {
|
|
57
167
|
const resolvedSchemaPath = schemaPath ? import_node_path.default.resolve(process.cwd(), schemaPath) : import_node_path.default.resolve(process.cwd(), "prisma/schema.prisma");
|
|
58
168
|
if (!import_node_fs.default.existsSync(resolvedSchemaPath)) {
|
|
@@ -156,7 +266,7 @@ function listResponseSchema(itemRef) {
|
|
|
156
266
|
required: ["count", "hasPreviousPage", "hasNextPage", "pageNumber", "pageSize", "totalPages", "items"]
|
|
157
267
|
};
|
|
158
268
|
}
|
|
159
|
-
async function buildSchemasFromPrismaDmmf(schemaPath) {
|
|
269
|
+
async function buildSchemasFromPrismaDmmf(cfg, schemaPath) {
|
|
160
270
|
const dmmf = await loadDmmfFromProject(schemaPath);
|
|
161
271
|
const schemas = {};
|
|
162
272
|
const getRefName = (modelName) => `Get${modelName}Response`;
|
|
@@ -169,7 +279,7 @@ async function buildSchemasFromPrismaDmmf(schemaPath) {
|
|
|
169
279
|
const putName = `Put${model.name}Request`;
|
|
170
280
|
const listName = `List${pluralize(model.name)}Response`;
|
|
171
281
|
const getSchema = modelToGetSchema(model, getRefName);
|
|
172
|
-
const postSchema = stripWriteFields(model, getSchema,
|
|
282
|
+
const postSchema = stripWriteFields(model, getSchema, cfg.omitFieldsInWriteDtos);
|
|
173
283
|
const putSchema = makeAllOptional(postSchema);
|
|
174
284
|
schemas[getName] = getSchema;
|
|
175
285
|
schemas[postName] = postSchema;
|
|
@@ -178,40 +288,41 @@ async function buildSchemasFromPrismaDmmf(schemaPath) {
|
|
|
178
288
|
}
|
|
179
289
|
return schemas;
|
|
180
290
|
}
|
|
181
|
-
function generateSwaggerConfigJs(schemas) {
|
|
182
|
-
const routes = (0, import_glob.globSync)(
|
|
291
|
+
function generateSwaggerConfigJs(cfg, schemas) {
|
|
292
|
+
const routes = (0, import_glob.globSync)(cfg.controllersGlob, { nodir: true }).map((p) => ensurePosix(p));
|
|
183
293
|
const docs = {
|
|
184
|
-
info: { title:
|
|
185
|
-
servers: [{ url:
|
|
294
|
+
info: { title: cfg.serviceTitle },
|
|
295
|
+
servers: [{ url: cfg.serverUrl }],
|
|
186
296
|
components: {
|
|
187
297
|
schemas,
|
|
188
298
|
securitySchemes: {
|
|
189
|
-
[
|
|
299
|
+
[cfg.securitySchemeName]: {
|
|
190
300
|
type: "oauth2",
|
|
191
301
|
description: "This API uses OAuth2 with the password flow.",
|
|
192
302
|
flows: {
|
|
193
303
|
password: {
|
|
194
|
-
tokenUrl:
|
|
195
|
-
refreshUrl:
|
|
196
|
-
scopes:
|
|
304
|
+
tokenUrl: cfg.oauth.tokenUrl,
|
|
305
|
+
refreshUrl: cfg.oauth.refreshUrl,
|
|
306
|
+
scopes: cfg.oauth.scopes
|
|
197
307
|
}
|
|
198
308
|
}
|
|
199
309
|
}
|
|
200
310
|
}
|
|
201
311
|
},
|
|
202
|
-
security: [{ [
|
|
312
|
+
security: [{ [cfg.securitySchemeName]: ["openid"] }]
|
|
203
313
|
};
|
|
204
314
|
const fileContent = `const swaggerAutogen = require('swagger-autogen')();
|
|
205
315
|
const docs = ${JSON.stringify(docs, null, 2)};
|
|
206
316
|
const routes = ${JSON.stringify(routes, null, 2)};
|
|
207
|
-
swaggerAutogen('${ensurePosix(
|
|
208
|
-
|
|
317
|
+
swaggerAutogen('${ensurePosix(cfg.openapiOut)}', routes, docs);`;
|
|
318
|
+
const outPath = import_node_path.default.resolve(cfg.projectRoot, cfg.outFile);
|
|
319
|
+
import_node_fs.default.writeFileSync(outPath, fileContent, "utf8");
|
|
209
320
|
}
|
|
210
321
|
async function run(args = []) {
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
const schemas = await buildSchemasFromPrismaDmmf(schemaPath);
|
|
214
|
-
generateSwaggerConfigJs(schemas);
|
|
322
|
+
const parsed = parseArgs(args);
|
|
323
|
+
const cfg = mergeConfig(DEFAULT_CONFIG, parsed);
|
|
324
|
+
const schemas = await buildSchemasFromPrismaDmmf(cfg, parsed.schemaPath);
|
|
325
|
+
generateSwaggerConfigJs(cfg, schemas);
|
|
215
326
|
}
|
|
216
327
|
|
|
217
328
|
// src/cli.ts
|
package/package.json
CHANGED