vite-plugin-openapi-codegen 1.2.1 → 2.0.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/README.md CHANGED
@@ -239,6 +239,8 @@ interface Options {
239
239
  pathPrefix?: string;
240
240
  stripPrefix?: boolean;
241
241
  typeAliases?: boolean;
242
+ generateOnDev?: boolean;
243
+ generateOnHmr?: boolean;
242
244
  httpClient?: {
243
245
  module?: string;
244
246
  jsonFunction?: string;
@@ -255,6 +257,14 @@ Path or URL to the OpenAPI JSON/YAML document. Local paths are resolved relative
255
257
 
256
258
  In dev mode, generation errors are logged and do not stop Vite from starting. In build mode, the plugin is skipped entirely.
257
259
 
260
+ ### `generateOnDev`
261
+
262
+ Controls whether the plugin generates artifacts automatically when the Vite dev server starts. The default is `true`. Set it to `false` when you want dev startup to avoid touching generated files and rely on `vg` or another explicit generation step instead. This option only affects the Vite dev lifecycle; the `vg` CLI still generates when invoked.
263
+
264
+ ### `generateOnHmr`
265
+
266
+ Controls whether the plugin regenerates artifacts through Vite HMR when a local OpenAPI input file changes. The default is `true`. Set it to `false` when local spec edits should not automatically rewrite generated files during an active dev session. Online `http://` and `https://` inputs are still not watched.
267
+
258
268
  ### `output`
259
269
 
260
270
  Directory where generated files are written, relative to the Vite project root. The `vg` CLI reads this value from `vite.config.*` when present, unless you override it with `--output`.
package/dist/cli.mjs CHANGED
@@ -162,13 +162,29 @@ function createBodyRequestProperty(bodyChannel, bodyAssignment) {
162
162
  return ts.factory.createSpreadAssignment(ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createObjectLiteralExpression([], false), ts.factory.createToken(ts.SyntaxKind.ColonToken), bodyAssignment)));
163
163
  }
164
164
  function createBuildSearchParamsFunction() {
165
- return ts.factory.createFunctionDeclaration(void 0, void 0, ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("query"), void 0, createTypeNodeFromText("Record<string, unknown> | undefined"))], createTypeNodeFromText("URLSearchParams | undefined"), ts.factory.createBlock([
166
- ts.factory.createIfStatement(ts.factory.createBinaryExpression(ts.factory.createIdentifier("query"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
167
- ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier("entries"), void 0, void 0, parseExpression("Object.entries(query).filter(([, value]) => value != null)"))], ts.NodeFlags.Const)),
168
- ts.factory.createIfStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("entries"), "length"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createNumericLiteral("0")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
169
- ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier("searchParams"), void 0, void 0, ts.factory.createNewExpression(ts.factory.createIdentifier("URLSearchParams"), void 0, []))], ts.NodeFlags.Const)),
170
- ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createArrayBindingPattern([ts.factory.createBindingElement(void 0, void 0, "key"), ts.factory.createBindingElement(void 0, void 0, "value")]))], ts.NodeFlags.Const), ts.factory.createIdentifier("entries"), ts.factory.createBlock([ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("searchParams"), "set"), void 0, [ts.factory.createIdentifier("key"), ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [ts.factory.createIdentifier("value")])]))], true)),
171
- ts.factory.createReturnStatement(ts.factory.createIdentifier("searchParams"))
165
+ const queryIdentifier = ts.factory.createIdentifier("query");
166
+ const searchParamsIdentifier = ts.factory.createIdentifier("searchParams");
167
+ const hasParamsIdentifier = ts.factory.createIdentifier("hasParams");
168
+ const keyIdentifier = ts.factory.createIdentifier("key");
169
+ const valueIdentifier = ts.factory.createIdentifier("value");
170
+ const itemIdentifier = ts.factory.createIdentifier("item");
171
+ const isNullishOrEmptyString = (identifier) => ts.factory.createBinaryExpression(ts.factory.createBinaryExpression(identifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.factory.createNull()), ts.factory.createToken(ts.SyntaxKind.BarBarToken), ts.factory.createBinaryExpression(identifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createStringLiteral("")));
172
+ const assignHasParamsTrue = () => ts.factory.createExpressionStatement(ts.factory.createAssignment(hasParamsIdentifier, ts.factory.createTrue()));
173
+ return ts.factory.createFunctionDeclaration(void 0, void 0, ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, queryIdentifier, void 0, createTypeNodeFromText("Record<string, unknown> | undefined"))], createTypeNodeFromText("URLSearchParams | undefined"), ts.factory.createBlock([
174
+ ts.factory.createIfStatement(ts.factory.createBinaryExpression(queryIdentifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
175
+ ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(searchParamsIdentifier, void 0, void 0, ts.factory.createNewExpression(ts.factory.createIdentifier("URLSearchParams"), void 0, []))], ts.NodeFlags.Const)),
176
+ ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(hasParamsIdentifier, void 0, void 0, ts.factory.createFalse())], ts.NodeFlags.Let)),
177
+ ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createArrayBindingPattern([ts.factory.createBindingElement(void 0, void 0, keyIdentifier), ts.factory.createBindingElement(void 0, void 0, valueIdentifier)]))], ts.NodeFlags.Const), parseExpression("Object.entries(query)"), ts.factory.createBlock([
178
+ ts.factory.createIfStatement(isNullishOrEmptyString(valueIdentifier), ts.factory.createContinueStatement()),
179
+ ts.factory.createIfStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("Array"), "isArray"), void 0, [valueIdentifier]), ts.factory.createBlock([ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(itemIdentifier)], ts.NodeFlags.Const), valueIdentifier, ts.factory.createBlock([
180
+ ts.factory.createIfStatement(isNullishOrEmptyString(itemIdentifier), ts.factory.createContinueStatement()),
181
+ ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(searchParamsIdentifier, "append"), void 0, [keyIdentifier, ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [itemIdentifier])])),
182
+ assignHasParamsTrue()
183
+ ], true)), ts.factory.createContinueStatement()], true)),
184
+ ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(searchParamsIdentifier, "set"), void 0, [keyIdentifier, ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [valueIdentifier])])),
185
+ assignHasParamsTrue()
186
+ ], true)),
187
+ ts.factory.createReturnStatement(ts.factory.createConditionalExpression(hasParamsIdentifier, ts.factory.createToken(ts.SyntaxKind.QuestionToken), searchParamsIdentifier, ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createIdentifier("undefined")))
172
188
  ], true));
173
189
  }
174
190
  function capitalize$1(value) {
@@ -486,6 +502,7 @@ function renderPrimitiveSchemaType(schema) {
486
502
  const type = schema?.type;
487
503
  if (!type) return "unknown";
488
504
  if (Array.isArray(type)) return type.map((memberType) => mapPrimitiveType(memberType)).join(" | ");
505
+ if (type === "array") return `${renderPrimitiveSchemaType(schema.items)}[]`;
489
506
  return mapPrimitiveType(type);
490
507
  }
491
508
  function allocateOperationTypeName(context, funcName, suffix) {
package/dist/index.d.mts CHANGED
@@ -9,6 +9,9 @@ interface OpenAPIParameter {
9
9
  name: string;
10
10
  required?: boolean;
11
11
  schema?: {
12
+ items?: {
13
+ type?: string | string[];
14
+ };
12
15
  type?: string | string[];
13
16
  };
14
17
  }
@@ -32,6 +35,7 @@ interface OpenAPIOperation {
32
35
  }
33
36
  type OpenAPIPathItem = Partial<Record<HttpMethod, OpenAPIOperation>>;
34
37
  interface OpenAPISchema {
38
+ items?: unknown;
35
39
  properties?: Record<string, unknown>;
36
40
  required?: string[];
37
41
  type?: string;
@@ -78,6 +82,10 @@ interface Options {
78
82
  httpClient?: HttpClientConfig;
79
83
  /** Generate and consume top-level type aliases. Default: false */
80
84
  typeAliases?: boolean;
85
+ /** Whether to generate during Vite dev server startup. Default: true */
86
+ generateOnDev?: boolean;
87
+ /** Whether to regenerate through Vite HMR for local inputs. Default: true */
88
+ generateOnHmr?: boolean;
81
89
  }
82
90
  interface GeneratedArtifacts {
83
91
  api: string;
package/dist/index.mjs CHANGED
@@ -160,13 +160,29 @@ function createBodyRequestProperty(bodyChannel, bodyAssignment) {
160
160
  return ts.factory.createSpreadAssignment(ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createObjectLiteralExpression([], false), ts.factory.createToken(ts.SyntaxKind.ColonToken), bodyAssignment)));
161
161
  }
162
162
  function createBuildSearchParamsFunction() {
163
- return ts.factory.createFunctionDeclaration(void 0, void 0, ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("query"), void 0, createTypeNodeFromText("Record<string, unknown> | undefined"))], createTypeNodeFromText("URLSearchParams | undefined"), ts.factory.createBlock([
164
- ts.factory.createIfStatement(ts.factory.createBinaryExpression(ts.factory.createIdentifier("query"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
165
- ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier("entries"), void 0, void 0, parseExpression("Object.entries(query).filter(([, value]) => value != null)"))], ts.NodeFlags.Const)),
166
- ts.factory.createIfStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("entries"), "length"), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createNumericLiteral("0")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
167
- ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createIdentifier("searchParams"), void 0, void 0, ts.factory.createNewExpression(ts.factory.createIdentifier("URLSearchParams"), void 0, []))], ts.NodeFlags.Const)),
168
- ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createArrayBindingPattern([ts.factory.createBindingElement(void 0, void 0, "key"), ts.factory.createBindingElement(void 0, void 0, "value")]))], ts.NodeFlags.Const), ts.factory.createIdentifier("entries"), ts.factory.createBlock([ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("searchParams"), "set"), void 0, [ts.factory.createIdentifier("key"), ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [ts.factory.createIdentifier("value")])]))], true)),
169
- ts.factory.createReturnStatement(ts.factory.createIdentifier("searchParams"))
163
+ const queryIdentifier = ts.factory.createIdentifier("query");
164
+ const searchParamsIdentifier = ts.factory.createIdentifier("searchParams");
165
+ const hasParamsIdentifier = ts.factory.createIdentifier("hasParams");
166
+ const keyIdentifier = ts.factory.createIdentifier("key");
167
+ const valueIdentifier = ts.factory.createIdentifier("value");
168
+ const itemIdentifier = ts.factory.createIdentifier("item");
169
+ const isNullishOrEmptyString = (identifier) => ts.factory.createBinaryExpression(ts.factory.createBinaryExpression(identifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsToken), ts.factory.createNull()), ts.factory.createToken(ts.SyntaxKind.BarBarToken), ts.factory.createBinaryExpression(identifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createStringLiteral("")));
170
+ const assignHasParamsTrue = () => ts.factory.createExpressionStatement(ts.factory.createAssignment(hasParamsIdentifier, ts.factory.createTrue()));
171
+ return ts.factory.createFunctionDeclaration(void 0, void 0, ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, queryIdentifier, void 0, createTypeNodeFromText("Record<string, unknown> | undefined"))], createTypeNodeFromText("URLSearchParams | undefined"), ts.factory.createBlock([
172
+ ts.factory.createIfStatement(ts.factory.createBinaryExpression(queryIdentifier, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createIdentifier("undefined")), ts.factory.createReturnStatement(ts.factory.createIdentifier("undefined"))),
173
+ ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(searchParamsIdentifier, void 0, void 0, ts.factory.createNewExpression(ts.factory.createIdentifier("URLSearchParams"), void 0, []))], ts.NodeFlags.Const)),
174
+ ts.factory.createVariableStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(hasParamsIdentifier, void 0, void 0, ts.factory.createFalse())], ts.NodeFlags.Let)),
175
+ ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createArrayBindingPattern([ts.factory.createBindingElement(void 0, void 0, keyIdentifier), ts.factory.createBindingElement(void 0, void 0, valueIdentifier)]))], ts.NodeFlags.Const), parseExpression("Object.entries(query)"), ts.factory.createBlock([
176
+ ts.factory.createIfStatement(isNullishOrEmptyString(valueIdentifier), ts.factory.createContinueStatement()),
177
+ ts.factory.createIfStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("Array"), "isArray"), void 0, [valueIdentifier]), ts.factory.createBlock([ts.factory.createForOfStatement(void 0, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(itemIdentifier)], ts.NodeFlags.Const), valueIdentifier, ts.factory.createBlock([
178
+ ts.factory.createIfStatement(isNullishOrEmptyString(itemIdentifier), ts.factory.createContinueStatement()),
179
+ ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(searchParamsIdentifier, "append"), void 0, [keyIdentifier, ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [itemIdentifier])])),
180
+ assignHasParamsTrue()
181
+ ], true)), ts.factory.createContinueStatement()], true)),
182
+ ts.factory.createExpressionStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(searchParamsIdentifier, "set"), void 0, [keyIdentifier, ts.factory.createCallExpression(ts.factory.createIdentifier("String"), void 0, [valueIdentifier])])),
183
+ assignHasParamsTrue()
184
+ ], true)),
185
+ ts.factory.createReturnStatement(ts.factory.createConditionalExpression(hasParamsIdentifier, ts.factory.createToken(ts.SyntaxKind.QuestionToken), searchParamsIdentifier, ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createIdentifier("undefined")))
170
186
  ], true));
171
187
  }
172
188
  function capitalize$1(value) {
@@ -484,6 +500,7 @@ function renderPrimitiveSchemaType(schema) {
484
500
  const type = schema?.type;
485
501
  if (!type) return "unknown";
486
502
  if (Array.isArray(type)) return type.map((memberType) => mapPrimitiveType(memberType)).join(" | ");
503
+ if (type === "array") return `${renderPrimitiveSchemaType(schema.items)}[]`;
487
504
  return mapPrimitiveType(type);
488
505
  }
489
506
  function allocateOperationTypeName(context, funcName, suffix) {
@@ -677,12 +694,13 @@ function openapiCodegen(options) {
677
694
  command = config.command;
678
695
  },
679
696
  async buildStart() {
680
- if (command === "serve") {
697
+ if (command === "serve" && options.generateOnDev !== false) {
681
698
  runDevelopmentGeneration(root, options);
682
699
  return;
683
700
  }
684
701
  },
685
702
  async handleHotUpdate(ctx) {
703
+ if (options.generateOnHmr === false) return;
686
704
  if (isHttpUrl(options.input)) return;
687
705
  const inputPath = resolve(root, options.input);
688
706
  if (resolve(ctx.file) !== inputPath) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-openapi-codegen",
3
- "version": "1.2.1",
3
+ "version": "2.0.0",
4
4
  "description": "Vite plugin that generates typed API clients and route builders from OpenAPI specs",
5
5
  "keywords": [
6
6
  "api-client",