vite-plugin-openapi-codegen 1.2.0 → 1.2.2

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
@@ -147,14 +147,20 @@ function createClientFunctionDeclaration(operation) {
147
147
  const requestProperties = [ts.factory.createSpreadAssignment(ts.factory.createIdentifier("requestOptions")), ts.factory.createPropertyAssignment(ts.factory.createIdentifier("method"), ts.factory.createStringLiteral(operation.methodUpper))];
148
148
  if (operation.queryChannel.present) requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("searchParams"), ts.factory.createCallExpression(ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "query")])));
149
149
  if (operation.bodyChannel.present) {
150
- if (operation.bodyContentType === "json") requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("json"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body")));
151
- else requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("body"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body")));
150
+ const bodyPropertyName = operation.bodyContentType === "json" ? "json" : "body";
151
+ const bodyAssignment = ts.factory.createObjectLiteralExpression([ts.factory.createPropertyAssignment(ts.factory.createIdentifier(bodyPropertyName), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body"))], false);
152
+ if (operation.bodyContentType === "json") requestProperties.push(createBodyRequestProperty(operation.bodyChannel, bodyAssignment));
153
+ else requestProperties.push(createBodyRequestProperty(operation.bodyChannel, bodyAssignment));
152
154
  if (operation.bodyContentType === "binary") requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("contentType"), ts.factory.createStringLiteral("application/octet-stream")));
153
155
  }
154
156
  requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("signal"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "signal")));
155
157
  const requestCall = ts.factory.createCallExpression(ts.factory.createIdentifier(operation.requestFunction), operation.responseTypeExpr ? [createTypeNodeFromText(operation.responseTypeExpr)] : void 0, [parseExpression(operation.pathInvocationExpr), ts.factory.createObjectLiteralExpression(requestProperties, true)]);
156
158
  return ts.factory.createFunctionDeclaration([createExportModifier()], void 0, ts.factory.createIdentifier(operation.funcName), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("options"), void 0, ts.factory.createTypeReferenceNode(operation.optionTypeName)), ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("requestOptions"), void 0, ts.factory.createTypeReferenceNode("RuntimeRequestOptions"), ts.factory.createObjectLiteralExpression())], createTypeNodeFromText(operation.returnTypeExpr), ts.factory.createBlock([ts.factory.createReturnStatement(requestCall)], true));
157
159
  }
160
+ function createBodyRequestProperty(bodyChannel, bodyAssignment) {
161
+ if (bodyChannel.required) return bodyAssignment.properties[0];
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
+ }
158
164
  function createBuildSearchParamsFunction() {
159
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([
160
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"))),
@@ -398,7 +404,7 @@ function createRequestBodyChannel(entry, context, body, kind) {
398
404
  };
399
405
  return {
400
406
  present: true,
401
- required: entry.operation.requestBody?.required !== false,
407
+ required: entry.operation.requestBody?.required === true,
402
408
  typeRef
403
409
  };
404
410
  }
package/dist/index.d.mts CHANGED
@@ -33,6 +33,7 @@ interface OpenAPIOperation {
33
33
  type OpenAPIPathItem = Partial<Record<HttpMethod, OpenAPIOperation>>;
34
34
  interface OpenAPISchema {
35
35
  properties?: Record<string, unknown>;
36
+ required?: string[];
36
37
  type?: string;
37
38
  }
38
39
  interface OpenAPISpec {
@@ -77,6 +78,10 @@ interface Options {
77
78
  httpClient?: HttpClientConfig;
78
79
  /** Generate and consume top-level type aliases. Default: false */
79
80
  typeAliases?: boolean;
81
+ /** Whether to generate during Vite dev server startup. Default: true */
82
+ generateOnDev?: boolean;
83
+ /** Whether to regenerate through Vite HMR for local inputs. Default: true */
84
+ generateOnHmr?: boolean;
80
85
  }
81
86
  interface GeneratedArtifacts {
82
87
  api: string;
package/dist/index.mjs CHANGED
@@ -145,14 +145,20 @@ function createClientFunctionDeclaration(operation) {
145
145
  const requestProperties = [ts.factory.createSpreadAssignment(ts.factory.createIdentifier("requestOptions")), ts.factory.createPropertyAssignment(ts.factory.createIdentifier("method"), ts.factory.createStringLiteral(operation.methodUpper))];
146
146
  if (operation.queryChannel.present) requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("searchParams"), ts.factory.createCallExpression(ts.factory.createIdentifier("buildSearchParams"), void 0, [ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "query")])));
147
147
  if (operation.bodyChannel.present) {
148
- if (operation.bodyContentType === "json") requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("json"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body")));
149
- else requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("body"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body")));
148
+ const bodyPropertyName = operation.bodyContentType === "json" ? "json" : "body";
149
+ const bodyAssignment = ts.factory.createObjectLiteralExpression([ts.factory.createPropertyAssignment(ts.factory.createIdentifier(bodyPropertyName), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "body"))], false);
150
+ if (operation.bodyContentType === "json") requestProperties.push(createBodyRequestProperty(operation.bodyChannel, bodyAssignment));
151
+ else requestProperties.push(createBodyRequestProperty(operation.bodyChannel, bodyAssignment));
150
152
  if (operation.bodyContentType === "binary") requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("contentType"), ts.factory.createStringLiteral("application/octet-stream")));
151
153
  }
152
154
  requestProperties.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier("signal"), ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("options"), "signal")));
153
155
  const requestCall = ts.factory.createCallExpression(ts.factory.createIdentifier(operation.requestFunction), operation.responseTypeExpr ? [createTypeNodeFromText(operation.responseTypeExpr)] : void 0, [parseExpression(operation.pathInvocationExpr), ts.factory.createObjectLiteralExpression(requestProperties, true)]);
154
156
  return ts.factory.createFunctionDeclaration([createExportModifier()], void 0, ts.factory.createIdentifier(operation.funcName), void 0, [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("options"), void 0, ts.factory.createTypeReferenceNode(operation.optionTypeName)), ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("requestOptions"), void 0, ts.factory.createTypeReferenceNode("RuntimeRequestOptions"), ts.factory.createObjectLiteralExpression())], createTypeNodeFromText(operation.returnTypeExpr), ts.factory.createBlock([ts.factory.createReturnStatement(requestCall)], true));
155
157
  }
158
+ function createBodyRequestProperty(bodyChannel, bodyAssignment) {
159
+ if (bodyChannel.required) return bodyAssignment.properties[0];
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
+ }
156
162
  function createBuildSearchParamsFunction() {
157
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([
158
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"))),
@@ -396,7 +402,7 @@ function createRequestBodyChannel(entry, context, body, kind) {
396
402
  };
397
403
  return {
398
404
  present: true,
399
- required: entry.operation.requestBody?.required !== false,
405
+ required: entry.operation.requestBody?.required === true,
400
406
  typeRef
401
407
  };
402
408
  }
@@ -671,12 +677,13 @@ function openapiCodegen(options) {
671
677
  command = config.command;
672
678
  },
673
679
  async buildStart() {
674
- if (command === "serve") {
680
+ if (command === "serve" && options.generateOnDev !== false) {
675
681
  runDevelopmentGeneration(root, options);
676
682
  return;
677
683
  }
678
684
  },
679
685
  async handleHotUpdate(ctx) {
686
+ if (options.generateOnHmr === false) return;
680
687
  if (isHttpUrl(options.input)) return;
681
688
  const inputPath = resolve(root, options.input);
682
689
  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.0",
3
+ "version": "1.2.2",
4
4
  "description": "Vite plugin that generates typed API clients and route builders from OpenAPI specs",
5
5
  "keywords": [
6
6
  "api-client",