mulink 1.1.7 → 1.1.9

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.
@@ -13,17 +13,48 @@ var __defProp = Object.defineProperty;
13
13
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
14
14
 
15
15
  // src/core/types.ts
16
- var BridgeError = class extends Error {
16
+ var BridgeError = class _BridgeError extends Error {
17
17
  static {
18
18
  __name(this, "BridgeError");
19
19
  }
20
20
  code;
21
21
  details;
22
- constructor(message, code, details) {
23
- super(message);
22
+ timestamp;
23
+ cause;
24
+ constructor(message, code, details, cause) {
25
+ super(message, { cause });
24
26
  this.name = "BridgeError";
25
27
  this.code = code;
26
28
  this.details = details;
29
+ this.timestamp = Date.now();
30
+ this.cause = cause;
31
+ if (Error.captureStackTrace) {
32
+ Error.captureStackTrace(this, _BridgeError);
33
+ }
34
+ }
35
+ /**
36
+ * Converts the error to a JSON-serializable object
37
+ *
38
+ * @returns JSON representation of the error
39
+ */
40
+ toJSON() {
41
+ return {
42
+ name: this.name,
43
+ message: this.message,
44
+ code: this.code,
45
+ details: this.details,
46
+ timestamp: this.timestamp,
47
+ stack: this.stack,
48
+ cause: this.cause?.message
49
+ };
50
+ }
51
+ /**
52
+ * Checks if this error is retryable
53
+ *
54
+ * @returns True if the operation that caused this error can be retried
55
+ */
56
+ isRetryable() {
57
+ return false;
27
58
  }
28
59
  };
29
60
  var ValidationError = class extends BridgeError {
@@ -31,28 +62,42 @@ var ValidationError = class extends BridgeError {
31
62
  __name(this, "ValidationError");
32
63
  }
33
64
  errors;
34
- constructor(message, errors) {
35
- super(message, "VALIDATION_ERROR", errors);
65
+ constructor(message, errors, cause) {
66
+ super(message, "VALIDATION_ERROR", errors, cause);
36
67
  this.errors = errors;
37
68
  }
69
+ /**
70
+ * Gets formatted validation error messages
71
+ *
72
+ * @returns Array of formatted error messages
73
+ */
74
+ getFormattedErrors() {
75
+ return this.errors.errors.map((err) => {
76
+ const path3 = err.path.join(".");
77
+ return `${path3}: ${err.message}`;
78
+ });
79
+ }
38
80
  };
39
81
  var SchemaParseError = class extends BridgeError {
40
82
  static {
41
83
  __name(this, "SchemaParseError");
42
84
  }
43
85
  schemaUrl;
44
- constructor(message, schemaUrl) {
45
- super(message, "SCHEMA_PARSE_ERROR", { schemaUrl });
86
+ constructor(message, schemaUrl, cause) {
87
+ super(message, "SCHEMA_PARSE_ERROR", { schemaUrl }, cause);
46
88
  this.schemaUrl = schemaUrl;
47
89
  }
90
+ isRetryable() {
91
+ return this.cause instanceof TypeError && this.cause.message.includes("fetch");
92
+ }
48
93
  };
49
94
  var GenerationError = class extends BridgeError {
50
95
  static {
51
96
  __name(this, "GenerationError");
52
97
  }
53
98
  file;
54
- constructor(message, file) {
55
- super(message, "GENERATION_ERROR", { file });
99
+ constructor(message, file, cause) {
100
+ super(message, "GENERATION_ERROR", { file }, cause);
56
101
  this.file = file;
57
102
  }
58
103
  };
@@ -140,8 +185,8 @@ var BridgeLogger = class {
140
185
  if (!this.options.colors || !process.stdout.isTTY) {
141
186
  console.log(message);
142
187
  return {
143
- succeed: /* @__PURE__ */ __name((msg) => console.log(colorize(`\u2713 ${msg || message || ""}`, "green")), "succeed"),
144
- fail: /* @__PURE__ */ __name((msg) => console.error(colorize(`\u2717 ${msg || message || ""}`, "red")), "fail"),
188
+ succeed: /* @__PURE__ */ __name((msg) => console.log(colorize(`\u2713 ${msg ?? message}`, "green")), "succeed"),
189
+ fail: /* @__PURE__ */ __name((msg) => console.error(colorize(`\u2717 ${msg ?? message}`, "red")), "fail"),
145
190
  stop: /* @__PURE__ */ __name(() => {
146
191
  }, "stop")
147
192
  };
@@ -149,17 +194,20 @@ var BridgeLogger = class {
149
194
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
150
195
  let i = 0;
151
196
  const interval = setInterval(() => {
152
- process.stdout.write(`\r${colorize(frames[i++ % frames.length], "cyan")} ${message}`);
197
+ const frame = frames[i++ % frames.length];
198
+ if (frame) {
199
+ process.stdout.write(`\r${colorize(frame, "cyan")} ${message}`);
200
+ }
153
201
  }, 100);
154
202
  return {
155
203
  succeed: /* @__PURE__ */ __name((msg) => {
156
204
  clearInterval(interval);
157
- process.stdout.write(`\r${colorize("\u2713", "green")} ${msg || message || ""}
205
+ process.stdout.write(`\r${colorize("\u2713", "green")} ${msg ?? message}
158
206
  `);
159
207
  }, "succeed"),
160
208
  fail: /* @__PURE__ */ __name((msg) => {
161
209
  clearInterval(interval);
162
- process.stdout.write(`\r${colorize("\u2717", "red")} ${msg || message || ""}
210
+ process.stdout.write(`\r${colorize("\u2717", "red")} ${msg ?? message}
163
211
  `);
164
212
  }, "fail"),
165
213
  stop: /* @__PURE__ */ __name(() => {
@@ -182,7 +230,7 @@ var VersionChecker = class {
182
230
  constructor(packageName, currentVersion, logger) {
183
231
  this.packageName = packageName;
184
232
  this.currentVersion = currentVersion;
185
- this.logger = logger || new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
233
+ this.logger = logger ?? new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
186
234
  }
187
235
  /**
188
236
  * Check if a new version is available
@@ -237,7 +285,7 @@ var VersionChecker = class {
237
285
  /**
238
286
  * Get the appropriate upgrade command for the detected package manager
239
287
  */
240
- getUpgradeCommand(versionInfo) {
288
+ getUpgradeCommand(_versionInfo) {
241
289
  const packageManager = this.detectPackageManager();
242
290
  switch (packageManager) {
243
291
  case "yarn":
@@ -311,8 +359,8 @@ var VersionChecker = class {
311
359
  const currentParts = this.parseVersion(current);
312
360
  const latestParts = this.parseVersion(latest);
313
361
  for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
314
- const currentPart = currentParts[i] || 0;
315
- const latestPart = latestParts[i] || 0;
362
+ const currentPart = currentParts[i] ?? 0;
363
+ const latestPart = latestParts[i] ?? 0;
316
364
  if (latestPart > currentPart) {
317
365
  return true;
318
366
  } else if (latestPart < currentPart) {
@@ -386,7 +434,7 @@ function createBridgeVersionChecker(logger) {
386
434
  if (fs.existsSync(pkgPath)) {
387
435
  const pkgRaw = fs.readFileSync(pkgPath, { encoding: "utf-8" });
388
436
  const pkg = JSON.parse(pkgRaw);
389
- if (pkg && pkg.version) {
437
+ if (pkg.version) {
390
438
  currentVersion = pkg.version;
391
439
  }
392
440
  } else {
@@ -394,13 +442,13 @@ function createBridgeVersionChecker(logger) {
394
442
  if (fs.existsSync(cwdPkg)) {
395
443
  const pkgRaw = fs.readFileSync(cwdPkg, { encoding: "utf-8" });
396
444
  const pkg = JSON.parse(pkgRaw);
397
- if (pkg && pkg.version) {
445
+ if (pkg.version) {
398
446
  currentVersion = pkg.version;
399
447
  }
400
448
  }
401
449
  }
402
450
  } catch (err) {
403
- const l = logger || new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
451
+ const l = logger ?? new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
404
452
  l.debug("Failed to read package.json for current version, falling back to default", err);
405
453
  }
406
454
  return new VersionChecker(packageName, currentVersion, logger);
@@ -438,7 +486,7 @@ var OpenApiSchemaParser = class {
438
486
  async fetchSchema(schemaUrl) {
439
487
  const versionChecker = createBridgeVersionChecker();
440
488
  const currentVersion = versionChecker.getCurrentVersion();
441
- if (!schemaUrl?.trim()) {
489
+ if (!schemaUrl.trim()) {
442
490
  throw new SchemaParseError("Schema URL is required and cannot be empty", schemaUrl);
443
491
  }
444
492
  if (schemaUrl.startsWith("http")) {
@@ -459,7 +507,7 @@ var OpenApiSchemaParser = class {
459
507
  schemaUrl
460
508
  );
461
509
  }
462
- const contentType = response.headers.get("content-type") || "";
510
+ const contentType = response.headers.get("content-type") ?? "";
463
511
  if (!contentType.includes("application/json") && !contentType.includes("application/yaml") && !contentType.includes("text/yaml")) {
464
512
  throw new SchemaParseError(
465
513
  `Unsupported content type: ${contentType}. Expected JSON or YAML.`,
@@ -489,10 +537,10 @@ var OpenApiSchemaParser = class {
489
537
  );
490
538
  }
491
539
  }
492
- async parseDocument(document) {
540
+ parseDocument(document) {
493
541
  const version = this.detectVersion(document);
494
542
  const normalizedDocument = this.normalizeDocument(document, version);
495
- return {
543
+ return Promise.resolve({
496
544
  version,
497
545
  document: normalizedDocument,
498
546
  openApiSpec: normalizedDocument,
@@ -501,7 +549,7 @@ var OpenApiSchemaParser = class {
501
549
  security: this.extractSecurity(normalizedDocument),
502
550
  servers: this.extractServers(normalizedDocument, document),
503
551
  metadata: this.extractMetadata(normalizedDocument)
504
- };
552
+ });
505
553
  }
506
554
  detectVersion(document) {
507
555
  if (!document || typeof document !== "object") {
@@ -536,7 +584,7 @@ var OpenApiSchemaParser = class {
536
584
  info: v2Doc.info,
537
585
  servers: v2Doc.host ? [
538
586
  {
539
- url: `${v2Doc.schemes?.[0] || "https"}://${v2Doc.host}${v2Doc.basePath || ""}`
587
+ url: `${v2Doc.schemes?.[0] ?? "https"}://${v2Doc.host}${v2Doc.basePath ?? ""}`
540
588
  }
541
589
  ] : [],
542
590
  paths: {},
@@ -681,20 +729,20 @@ var OpenApiSchemaParser = class {
681
729
  flows: {
682
730
  implicit: v2Scheme.flow === "implicit" ? {
683
731
  authorizationUrl: v2Scheme.authorizationUrl,
684
- scopes: v2Scheme.scopes || {}
732
+ scopes: v2Scheme.scopes ?? {}
685
733
  } : void 0,
686
734
  password: v2Scheme.flow === "password" ? {
687
735
  tokenUrl: v2Scheme.tokenUrl,
688
- scopes: v2Scheme.scopes || {}
736
+ scopes: v2Scheme.scopes ?? {}
689
737
  } : void 0,
690
738
  clientCredentials: v2Scheme.flow === "application" ? {
691
739
  tokenUrl: v2Scheme.tokenUrl,
692
- scopes: v2Scheme.scopes || {}
740
+ scopes: v2Scheme.scopes ?? {}
693
741
  } : void 0,
694
742
  authorizationCode: v2Scheme.flow === "accessCode" ? {
695
743
  authorizationUrl: v2Scheme.authorizationUrl,
696
744
  tokenUrl: v2Scheme.tokenUrl,
697
- scopes: v2Scheme.scopes || {}
745
+ scopes: v2Scheme.scopes ?? {}
698
746
  } : void 0
699
747
  }
700
748
  };
@@ -720,18 +768,18 @@ var OpenApiSchemaParser = class {
720
768
  const operation = pathItem[method.toLowerCase()];
721
769
  if (!operation) continue;
722
770
  const endpoint = {
723
- id: operation.operationId || `${method.toLowerCase()}_${path3.replace(/[^a-zA-Z0-9]/g, "_")}`,
771
+ id: operation.operationId ?? `${method.toLowerCase()}_${path3.replace(/[^a-zA-Z0-9]/g, "_")}`,
724
772
  path: path3,
725
773
  method,
726
774
  operationId: operation.operationId,
727
775
  summary: operation.summary,
728
776
  description: operation.description,
729
- tags: operation.tags || [],
777
+ tags: operation.tags ?? [],
730
778
  parameters: this.extractParameters(operation.parameters, pathItem.parameters, document),
731
779
  requestBody: this.extractRequestBody(operation.requestBody, document),
732
780
  responses: this.extractResponses(operation.responses, document),
733
- security: operation.security || [],
734
- deprecated: operation.deprecated || false,
781
+ security: operation.security ?? [],
782
+ deprecated: operation.deprecated ?? false,
735
783
  metadata: this.extractEndpointMetadata(operation)
736
784
  };
737
785
  endpoints.push(endpoint);
@@ -741,7 +789,7 @@ var OpenApiSchemaParser = class {
741
789
  }
742
790
  extractParameters(operationParams, pathParams, document) {
743
791
  const parameters = [];
744
- const allParams = [...pathParams || [], ...operationParams || []];
792
+ const allParams = [...pathParams ?? [], ...operationParams ?? []];
745
793
  for (const param of allParams) {
746
794
  if (!param) continue;
747
795
  if ("$ref" in param) {
@@ -751,11 +799,11 @@ var OpenApiSchemaParser = class {
751
799
  const parameter = {
752
800
  name: param.name,
753
801
  in: param.in,
754
- required: param.required || param.in === "path",
802
+ required: param.required ?? param.in === "path",
755
803
  schema: this.convertSchemaToZod(param.schema, document),
756
804
  description: param.description,
757
805
  example: param.example,
758
- deprecated: param.deprecated || false
806
+ deprecated: param.deprecated ?? false
759
807
  };
760
808
  parameters.push(parameter);
761
809
  }
@@ -774,7 +822,7 @@ var OpenApiSchemaParser = class {
774
822
  }
775
823
  }
776
824
  return {
777
- required: requestBody.required || false,
825
+ required: requestBody.required ?? false,
778
826
  description: requestBody.description,
779
827
  content
780
828
  };
@@ -814,7 +862,7 @@ var OpenApiSchemaParser = class {
814
862
  schema: this.convertSchemaToZod(schema, document),
815
863
  description: schema.description,
816
864
  example: schema.example,
817
- deprecated: schema.deprecated || false
865
+ deprecated: schema.deprecated ?? false
818
866
  });
819
867
  }
820
868
  }
@@ -848,7 +896,7 @@ var OpenApiSchemaParser = class {
848
896
  const v2Doc = originalDoc;
849
897
  return [
850
898
  {
851
- url: `${v2Doc.schemes?.[0] || "https"}://${v2Doc.host}${v2Doc.basePath || ""}`,
899
+ url: `${v2Doc.schemes?.[0] ?? "https"}://${v2Doc.host}${v2Doc.basePath ?? ""}`,
852
900
  description: "Converted from Swagger 2.0"
853
901
  }
854
902
  ];
@@ -868,9 +916,9 @@ var OpenApiSchemaParser = class {
868
916
  }
869
917
  extractEndpointMetadata(operation) {
870
918
  return {
871
- requiresAuth: operation.security && operation.security.length > 0 || false,
919
+ requiresAuth: (operation.security?.length ?? 0) > 0,
872
920
  cacheStrategy: "default",
873
- revalidationTags: operation.tags || [],
921
+ revalidationTags: operation.tags ?? [],
874
922
  streaming: false,
875
923
  fileUpload: this.hasFileUpload(operation)
876
924
  };
@@ -878,7 +926,7 @@ var OpenApiSchemaParser = class {
878
926
  hasFileUpload(operation) {
879
927
  if (!operation.requestBody || "$ref" in operation.requestBody) return false;
880
928
  const content = operation.requestBody.content;
881
- return Object.keys(content || {}).some(
929
+ return Object.keys(content ?? {}).some(
882
930
  (mediaType) => mediaType.includes("multipart/form-data") || mediaType.includes("application/octet-stream")
883
931
  );
884
932
  }
@@ -966,7 +1014,7 @@ var OpenApiSchemaParser = class {
966
1014
  case "object":
967
1015
  if (schema.properties) {
968
1016
  const shape = {};
969
- const required = schema.required || [];
1017
+ const required = schema.required ?? [];
970
1018
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
971
1019
  let propZodSchema = this.convertSchemaToZod(propSchema, document);
972
1020
  if (!required.includes(propName)) {
@@ -998,7 +1046,7 @@ var ApiClientGenerator = class {
998
1046
  * Generate import paths based on configuration
999
1047
  */
1000
1048
  buildImportPath(relativePath) {
1001
- const outputDirectory = this.configuration.outputDir || "generated";
1049
+ const outputDirectory = this.configuration.outputDir ?? "generated";
1002
1050
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
1003
1051
  let importBasePath = outputDirectory;
1004
1052
  if (importBasePath.startsWith("src/")) {
@@ -1006,24 +1054,24 @@ var ApiClientGenerator = class {
1006
1054
  }
1007
1055
  return `@/${importBasePath}/${cleanPath}`;
1008
1056
  }
1009
- async generate(context) {
1057
+ generate(context) {
1010
1058
  const { schema } = context;
1011
1059
  const generatedFiles = [];
1012
1060
  generatedFiles.push(this.generateEnhancedBaseClient());
1013
1061
  generatedFiles.push(...this.generateEndpointClients(schema.endpoints));
1014
1062
  generatedFiles.push(this.generateMainClient(schema.endpoints));
1015
1063
  generatedFiles.push(this.generateClientUtilities());
1016
- return generatedFiles;
1064
+ return Promise.resolve(generatedFiles);
1017
1065
  }
1018
1066
  generateEnhancedBaseClient() {
1019
1067
  const { api, auth } = this.configuration;
1020
1068
  const authUtilsImport = this.buildImportPath("auth/utils");
1021
- const authPath = auth?.authPath || "@/lib/auth";
1022
- const tokenGetter = auth?.tokenGetter || "auth";
1069
+ const authPath = auth?.authPath ?? "@/lib/auth";
1070
+ const tokenGetter = auth?.tokenGetter ?? "auth";
1023
1071
  const content = `/**
1024
1072
  * The HTTP client is automatically created by "mulink"
1025
1073
  *
1026
- * Next.js 16.0.1 Best Practices:
1074
+ * Next.js 16.0.7 Best Practices:
1027
1075
  * - Proper separation of client/server code
1028
1076
  * - Dynamic imports for server-only modules
1029
1077
  * - Works in both Server Components and Client Components
@@ -1034,7 +1082,7 @@ import { cache } from 'react'
1034
1082
 
1035
1083
  /**
1036
1084
  * Server-only modules interface
1037
- * Next.js 16.0.1: These modules are only available on the server
1085
+ * Next.js 16.0.7: These modules are only available on the server
1038
1086
  * We use dynamic imports to avoid bundling them in the client
1039
1087
  */
1040
1088
  type NextHeadersModule = typeof import('next/headers')
@@ -1058,7 +1106,7 @@ function toMutableHeaders(source: NextReadonlyHeaders) {
1058
1106
 
1059
1107
  /**
1060
1108
  * Lazy load server-only modules only when needed (server-side)
1061
- * Next.js 16.0.1: This ensures server-only code is not bundled in the client
1109
+ * Next.js 16.0.7: This ensures server-only code is not bundled in the client
1062
1110
  *
1063
1111
  * @returns Server-only modules or undefined if on client-side
1064
1112
  */
@@ -1066,7 +1114,7 @@ async function getServerModules() {
1066
1114
  if (serverOnlyModules !== null) return serverOnlyModules
1067
1115
 
1068
1116
  // Only attempt to import on server-side
1069
- // Next.js 16.0.1: typeof window check ensures we're on the server
1117
+ // Next.js 16.0.7: typeof window check ensures we're on the server
1070
1118
  if (typeof window === 'undefined') {
1071
1119
  try {
1072
1120
  const headersModule = await import('next/headers').catch(() => null)
@@ -1292,11 +1340,11 @@ export class BaseApiClient {
1292
1340
  private readonly middleware: RequestMiddleware[] = []
1293
1341
 
1294
1342
  constructor() {
1295
- this.baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.API_BASE_URL || '${api?.baseUrl || "http://localhost:3000/api"}'
1296
- this.defaultTimeout = ${api?.timeout || 3e4}
1297
- this.defaultRetries = ${api?.retries || 3}
1298
- this.defaultHeaders = ${JSON.stringify(api?.headers || {}, null, 6)}
1299
- this.defaultUserAgent = '${api?.userAgent || "Mulink-Client/3.4.5"}'
1343
+ this.baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.API_BASE_URL || '${api.baseUrl || "http://localhost:3000/api"}'
1344
+ this.defaultTimeout = ${api.timeout || 3e4}
1345
+ this.defaultRetries = ${api.retries || 3}
1346
+ this.defaultHeaders = ${JSON.stringify(api.headers || {}, null, 6)}
1347
+ this.defaultUserAgent = '${api.userAgent || "Mulink-Client/3.4.5"}'
1300
1348
 
1301
1349
  // Add default middleware
1302
1350
  this.addMiddleware({
@@ -1470,16 +1518,26 @@ export class BaseApiClient {
1470
1518
  }
1471
1519
 
1472
1520
  // Add query parameters with proper encoding
1521
+ // Filter out undefined, null, empty strings, and empty objects to prevent 422 errors
1473
1522
  const searchParams = new URLSearchParams()
1474
1523
  for (const [key, value] of Object.entries(queryParameters)) {
1475
- if (value !== undefined && value !== null && value !== '') {
1476
- if (Array.isArray(value)) {
1477
- value.forEach(v => searchParams.append(key, String(v)))
1478
- } else if (typeof value === 'object') {
1479
- searchParams.append(key, JSON.stringify(value))
1480
- } else {
1481
- searchParams.append(key, String(value))
1482
- }
1524
+ // Skip undefined, null, and empty strings
1525
+ if (value === undefined || value === null || value === '') {
1526
+ continue
1527
+ }
1528
+
1529
+ // Skip empty objects (like {})
1530
+ if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
1531
+ continue
1532
+ }
1533
+
1534
+ if (Array.isArray(value)) {
1535
+ value.forEach(v => searchParams.append(key, String(v)))
1536
+ } else if (typeof value === 'object') {
1537
+ // Only serialize non-empty objects
1538
+ searchParams.append(key, JSON.stringify(value))
1539
+ } else {
1540
+ searchParams.append(key, String(value))
1483
1541
  }
1484
1542
  }
1485
1543
 
@@ -1652,7 +1710,7 @@ export class BaseApiClient {
1652
1710
  controller.abort()
1653
1711
  }, timeout)
1654
1712
 
1655
- // Next.js 16.0.1: Build fetch options with cache tags and connection
1713
+ // Next.js 16.0.7: Build fetch options with cache tags and connection
1656
1714
  // Only include next options if we're on the server (Next.js App Router)
1657
1715
  const fetchInit: RequestInit & { next?: { tags?: string[]; revalidate?: number | false; connection?: string } } = {
1658
1716
  ...requestConfig,
@@ -1660,7 +1718,7 @@ export class BaseApiClient {
1660
1718
  }
1661
1719
 
1662
1720
  // Add Next.js-specific options only if we have cache tags, revalidate, or connection
1663
- // Next.js 16.0.1: Enhanced cache tag support with updateTag
1721
+ // Next.js 16.0.7: Enhanced cache tag support with updateTag
1664
1722
  if (cacheTags && cacheTags.length > 0 || revalidate !== undefined || connection) {
1665
1723
  fetchInit.next = {}
1666
1724
 
@@ -1672,7 +1730,7 @@ export class BaseApiClient {
1672
1730
  fetchInit.next.revalidate = revalidate === false ? false : revalidate
1673
1731
  }
1674
1732
 
1675
- // Next.js 16.0.1: Connection keep-alive for persistent connections
1733
+ // Next.js 16.0.7: Connection keep-alive for persistent connections
1676
1734
  if (connection) {
1677
1735
  fetchInit.next.connection = connection
1678
1736
  }
@@ -1680,7 +1738,7 @@ export class BaseApiClient {
1680
1738
 
1681
1739
  const response = await fetch(url, fetchInit)
1682
1740
 
1683
- // Next.js 16.0.1: Update cache tags dynamically using updateTag from next/cache
1741
+ // Next.js 16.0.7: Update cache tags dynamically using updateTag from next/cache
1684
1742
  // This allows for granular cache invalidation
1685
1743
  if (cacheTags && cacheTags.length > 0) {
1686
1744
  try {
@@ -1944,7 +2002,7 @@ async get<TData>(
1944
2002
  }
1945
2003
  generateClientUtilities() {
1946
2004
  const { api } = this.configuration;
1947
- const errorHandling = api?.errorHandling;
2005
+ const errorHandling = api.errorHandling;
1948
2006
  const enableAuthErrorHandling = errorHandling?.enableAuthErrorHandling !== false;
1949
2007
  const authErrorHandlerPath = errorHandling?.authErrorHandlerPath || "@/lib/auth-error-handler";
1950
2008
  const authErrorMiddlewareCode = enableAuthErrorHandling ? `
@@ -2341,7 +2399,7 @@ ${clientMethods}
2341
2399
  const requestOptionsString = requestOptions.join("\n");
2342
2400
  const methodSignature = parameterTypes.length > 1 ? `options: {
2343
2401
  ${parameterTypes.join("\n ")}
2344
- }` : parameterTypes.length === 1 && parameterTypes[0].includes("config?") ? "options?: { config?: RequestConfiguration }" : `options: { ${parameterTypes.join(", ")} }`;
2402
+ }` : parameterTypes.length === 1 && parameterTypes[0] && parameterTypes[0].includes("config?") ? "options?: { config?: RequestConfiguration }" : `options: { ${parameterTypes.join(", ")} }`;
2345
2403
  if (isQuery) {
2346
2404
  return `${documentation}
2347
2405
  ${methodName} = cache(async (${methodSignature}) => {
@@ -2612,7 +2670,7 @@ var SchemaGenerator = class {
2612
2670
  visiting.add(schemaName);
2613
2671
  const schema = schemaMap.get(schemaName);
2614
2672
  if (schema) {
2615
- const dependencies = dependencyGraph.get(schemaName) || /* @__PURE__ */ new Set();
2673
+ const dependencies = dependencyGraph.get(schemaName) ?? /* @__PURE__ */ new Set();
2616
2674
  for (const dep of dependencies) {
2617
2675
  if (schemaMap.has(dep)) {
2618
2676
  visit(dep);
@@ -2645,13 +2703,13 @@ var SchemaGenerator = class {
2645
2703
  findSchemaDependencies(schema) {
2646
2704
  const dependencies = [];
2647
2705
  const schemaObj = schema.schema;
2648
- if (schemaObj && schemaObj._def) {
2706
+ if (schemaObj?._def) {
2649
2707
  this.extractDependenciesFromZodSchema(schemaObj, dependencies);
2650
2708
  }
2651
2709
  return dependencies;
2652
2710
  }
2653
2711
  extractDependenciesFromZodSchema(zodSchema, dependencies, visited = /* @__PURE__ */ new Set()) {
2654
- if (!zodSchema || !zodSchema._def) return;
2712
+ if (!zodSchema?._def) return;
2655
2713
  const def = zodSchema._def;
2656
2714
  if (def._schemaRef) {
2657
2715
  const refName = def._schemaRef;
@@ -2674,7 +2732,7 @@ var SchemaGenerator = class {
2674
2732
  case "ZodObject":
2675
2733
  if (def.shape) {
2676
2734
  const shape = def.shape();
2677
- for (const [key, value] of Object.entries(shape)) {
2735
+ for (const [_key, value] of Object.entries(shape)) {
2678
2736
  this.extractDependenciesFromZodSchema(value, dependencies, visited);
2679
2737
  }
2680
2738
  }
@@ -2706,7 +2764,7 @@ var SchemaGenerator = class {
2706
2764
  break;
2707
2765
  }
2708
2766
  }
2709
- async generateSchemasFile(context) {
2767
+ generateSchemasFile(context) {
2710
2768
  const { schemas, endpoints } = context.schema;
2711
2769
  const imports = ['import { z } from "zod"'];
2712
2770
  const schemaExports = [];
@@ -2740,7 +2798,7 @@ var SchemaGenerator = class {
2740
2798
 
2741
2799
  ${content}`;
2742
2800
  }
2743
- return {
2801
+ return Promise.resolve({
2744
2802
  path: "schemas/index.ts",
2745
2803
  content,
2746
2804
  type: "typescript",
@@ -2749,7 +2807,7 @@ ${content}`;
2749
2807
  imports: ["zod"],
2750
2808
  dependencies: []
2751
2809
  }
2752
- };
2810
+ });
2753
2811
  }
2754
2812
  generateEndpointSchemas(endpoint) {
2755
2813
  const definitions = [];
@@ -2784,6 +2842,9 @@ ${content}`;
2784
2842
  }
2785
2843
  const exportName = `${operationName}RequestSchema`;
2786
2844
  const primaryContent = endpoint.requestBody.content[0];
2845
+ if (!primaryContent) {
2846
+ throw new Error(`No content found for request body in ${endpoint.method} ${endpoint.path}`);
2847
+ }
2787
2848
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2788
2849
  const definition = [
2789
2850
  `/**`,
@@ -2807,17 +2868,22 @@ ${content}`;
2807
2868
  );
2808
2869
  if (successResponses.length > 0) {
2809
2870
  const successResponse = successResponses[0];
2871
+ if (!successResponse) {
2872
+ return { definitions, exports };
2873
+ }
2810
2874
  let zodSchemaString = "z.void()";
2811
2875
  if (successResponse.content && successResponse.content.length > 0) {
2812
2876
  const primaryContent = successResponse.content[0];
2813
- zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2877
+ if (primaryContent) {
2878
+ zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2879
+ }
2814
2880
  }
2815
2881
  const exportName = `${operationName}ResponseSchema`;
2816
2882
  const definition = [
2817
2883
  `/**`,
2818
2884
  ` * Success response schema for ${endpoint.method} ${endpoint.path}`,
2819
2885
  ` * Status: ${successResponse.statusCode}`,
2820
- ` * ${successResponse.description}`,
2886
+ ` * ${successResponse.description ?? ""}`,
2821
2887
  ` */`,
2822
2888
  `export const ${exportName} = ${zodSchemaString}`,
2823
2889
  "",
@@ -2828,15 +2894,18 @@ ${content}`;
2828
2894
  }
2829
2895
  if (errorResponses.length > 0) {
2830
2896
  const errorResponse = errorResponses[0];
2831
- if (errorResponse.content && errorResponse.content.length > 0) {
2897
+ if (errorResponse?.content && errorResponse.content.length > 0) {
2832
2898
  const exportName = `${operationName}ErrorSchema`;
2833
2899
  const primaryContent = errorResponse.content[0];
2900
+ if (!primaryContent) {
2901
+ return { definitions, exports };
2902
+ }
2834
2903
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2835
2904
  const definition = [
2836
2905
  `/**`,
2837
2906
  ` * Error response schema for ${endpoint.method} ${endpoint.path}`,
2838
2907
  ` * Status: ${errorResponse.statusCode}`,
2839
- ` * ${errorResponse.description}`,
2908
+ ` * ${errorResponse.description ?? ""}`,
2840
2909
  ` */`,
2841
2910
  `export const ${exportName} = ${zodSchemaString}`,
2842
2911
  "",
@@ -2927,8 +2996,8 @@ ${schemaProperties.join(",\n")}
2927
2996
  };
2928
2997
  }
2929
2998
  zodSchemaToString(schema, context) {
2930
- if (!schema || !schema._def) {
2931
- if (schema && schema._schemaRef) {
2999
+ if (!schema?._def) {
3000
+ if (schema?._schemaRef) {
2932
3001
  const refName = schema._schemaRef;
2933
3002
  const registeredSchema = this.schemaRegistry.get(refName);
2934
3003
  if (registeredSchema) {
@@ -3096,15 +3165,21 @@ export const errorMessages = {
3096
3165
  const assignments = line.match(/(\w+)\s*[:=]/g);
3097
3166
  if (assignments) {
3098
3167
  assignments.forEach((match) => {
3099
- const identifier = match.split(/[:=]/)[0].trim();
3100
- usedIdentifiers.add(identifier);
3168
+ const parts = match.split(/[:=]/);
3169
+ if (parts[0]) {
3170
+ const identifier = parts[0].trim();
3171
+ usedIdentifiers.add(identifier);
3172
+ }
3101
3173
  });
3102
3174
  }
3103
3175
  const functionCalls = line.match(/(\w+)\s*\(/g);
3104
3176
  if (functionCalls) {
3105
3177
  functionCalls.forEach((match) => {
3106
- const identifier = match.split("(")[0].trim();
3107
- usedIdentifiers.add(identifier);
3178
+ const parts = match.split("(");
3179
+ if (parts[0]) {
3180
+ const identifier = parts[0].trim();
3181
+ usedIdentifiers.add(identifier);
3182
+ }
3108
3183
  });
3109
3184
  }
3110
3185
  if (line.includes("z.infer")) {
@@ -3122,10 +3197,10 @@ export const errorMessages = {
3122
3197
  continue;
3123
3198
  }
3124
3199
  const importMatch = line.match(/import\s*\{([^}]+)\}/);
3125
- if (importMatch) {
3200
+ if (importMatch?.[1]) {
3126
3201
  const imports = importMatch[1].split(",").map((imp) => imp.trim());
3127
3202
  const usedImports = imports.filter((imp) => usedIdentifiers.has(imp));
3128
- if (usedImports.length > 0) {
3203
+ if (usedImports.length > 0 && importMatch[1]) {
3129
3204
  cleanedLines.push(line.replace(importMatch[1], usedImports.join(", ")));
3130
3205
  } else {
3131
3206
  continue;
@@ -3172,7 +3247,7 @@ var ActionGenerator = class {
3172
3247
  if (!this.documentationEnabled) {
3173
3248
  return "";
3174
3249
  }
3175
- const summary = endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`;
3250
+ const summary = endpoint.summary ?? endpoint.description ?? `${endpoint.method} ${endpoint.path}`;
3176
3251
  return `/**
3177
3252
  * ${summary}
3178
3253
  * @generated from ${endpoint.method} ${endpoint.path}
@@ -3314,7 +3389,7 @@ ${" ".repeat(indent + 2)}error: error instanceof Error ? error.message : 'Unknow
3314
3389
  ${" ".repeat(indent)}})`;
3315
3390
  }
3316
3391
  buildImportPath(relativePath) {
3317
- const outputDirectory = this.configuration.outputDir || "generated";
3392
+ const outputDirectory = this.configuration.outputDir ?? "generated";
3318
3393
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
3319
3394
  let importBasePath = outputDirectory;
3320
3395
  if (importBasePath.startsWith("src/")) {
@@ -3322,7 +3397,7 @@ ${" ".repeat(indent)}})`;
3322
3397
  }
3323
3398
  return `@/${importBasePath}/${cleanPath}`;
3324
3399
  }
3325
- async generate(context) {
3400
+ generate(context) {
3326
3401
  const { schema, config } = context;
3327
3402
  const generatedFiles = [];
3328
3403
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3416,7 +3491,7 @@ ${actions}`;
3416
3491
  dependencies: Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)
3417
3492
  }
3418
3493
  });
3419
- return generatedFiles;
3494
+ return Promise.resolve(generatedFiles);
3420
3495
  }
3421
3496
  getOperationName(endpoint) {
3422
3497
  if (endpoint.operationId) {
@@ -3429,7 +3504,7 @@ ${actions}`;
3429
3504
  const method = this.toPascalCase(endpoint.method.toLowerCase());
3430
3505
  return [...pathParts, method].join("");
3431
3506
  }
3432
- generateOptimizedServerAction(endpoint, config) {
3507
+ generateOptimizedServerAction(endpoint, _config) {
3433
3508
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3434
3509
  const operationName = this.getOperationName(endpoint);
3435
3510
  const hasRequestBody = !!endpoint.requestBody;
@@ -3470,10 +3545,15 @@ ${actions}`;
3470
3545
  parameterProcessing = "";
3471
3546
  requestOptionsParams = "";
3472
3547
  }
3473
- const parsedInputType = hasRequestBody || hasAnyParams ? schemaName.includes("\n") ? `z.infer<typeof z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })>` : `z.infer<typeof ${schemaName}>` : "void";
3548
+ const schemaConstantName = hasRequestBody && hasAnyParams ? `${operationName}InputSchema` : null;
3549
+ const schemaConstantDefinition = schemaConstantName ? `const ${schemaConstantName} = z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })
3550
+
3551
+ ` : "";
3552
+ const parsedInputType = hasRequestBody || hasAnyParams ? schemaConstantName ? `z.infer<typeof ${schemaConstantName}>` : `z.infer<typeof ${schemaName}>` : "void";
3474
3553
  const ctxType = requiresAuth || hasRateLimit ? "{ user?: any; ratelimit?: { remaining: number } }" : "any";
3475
3554
  const ctxDeclaration = requiresAuth || hasRateLimit ? `ctx: ${ctxType}` : "ctx?: any";
3476
- const actionArgsType = schemaName.includes("\n") ? `{ parsedInput: z.infer<typeof z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })>; ${ctxDeclaration} }` : `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
3555
+ const actionArgsType = schemaConstantName ? `{ parsedInput: z.infer<typeof ${schemaConstantName}>; ${ctxDeclaration} }` : `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
3556
+ const actionArgsTypeForTemplate = actionArgsType.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
3477
3557
  const clientName = requiresAuth || hasRateLimit ? "authActionClient" : "actionClientWithMeta";
3478
3558
  const rateLimitCode = hasRateLimit ? `
3479
3559
  ${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await getClientInfo()
@@ -3496,15 +3576,15 @@ ${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await get
3496
3576
  endpoint,
3497
3577
  "React cache, input validation, error handling"
3498
3578
  );
3499
- return `${docBlock}export const ${actionName} = cache(
3579
+ return `${docBlock}${schemaConstantDefinition}export const ${actionName} = cache(
3500
3580
  ${clientName}
3501
3581
  .metadata({
3502
3582
  name: "${kebabActionName}",
3503
3583
  requiresAuth: ${requiresAuth}${hasRateLimit ? `,
3504
3584
  rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
3505
3585
  })
3506
- .schema(${schemaName.includes("\n") ? `z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })` : schemaName})
3507
- .action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
3586
+ .schema(${schemaConstantName || schemaName})
3587
+ .action(async ({ parsedInput, ctx }: ${actionArgsTypeForTemplate}) => {
3508
3588
  const startTime = Date.now()
3509
3589
 
3510
3590
  try {${rateLimitCode}${parameterProcessing}
@@ -3563,14 +3643,14 @@ ${this.commentLine("Process file with compression and validation if enabled", 10
3563
3643
  endpoint,
3564
3644
  "Input validation, revalidation, error handling"
3565
3645
  );
3566
- return `${mutationDocBlock}export const ${actionName} = ${clientName}
3646
+ return `${mutationDocBlock}${schemaConstantDefinition}export const ${actionName} = ${clientName}
3567
3647
  .metadata({
3568
3648
  name: "${kebabActionName}",
3569
3649
  requiresAuth: ${requiresAuth}${hasRateLimit ? `,
3570
3650
  rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
3571
3651
  })
3572
- .schema(${schemaName.includes("\n") ? `z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })` : schemaName})
3573
- .action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
3652
+ .schema(${schemaConstantName || schemaName})
3653
+ .action(async ({ parsedInput, ctx }: ${actionArgsTypeForTemplate}) => {
3574
3654
  const startTime = Date.now()
3575
3655
 
3576
3656
  try {${rateLimitCode}${parameterProcessing}${fileUploadCode}
@@ -3698,7 +3778,7 @@ var HookGenerator = class {
3698
3778
  __name(this, "HookGenerator");
3699
3779
  }
3700
3780
  buildImportPath(relativePath) {
3701
- const outputDirectory = this.configuration.outputDir || "generated";
3781
+ const outputDirectory = this.configuration.outputDir ?? "generated";
3702
3782
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
3703
3783
  let importBasePath = outputDirectory;
3704
3784
  if (importBasePath.startsWith("src/")) {
@@ -3706,7 +3786,7 @@ var HookGenerator = class {
3706
3786
  }
3707
3787
  return `@/${importBasePath}/${cleanPath}`;
3708
3788
  }
3709
- async generate(context) {
3789
+ generate(context) {
3710
3790
  const { schema } = context;
3711
3791
  const generatedFiles = [];
3712
3792
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3839,7 +3919,7 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3839
3919
  dependencies: ["./useBridgeQuery", ...Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)]
3840
3920
  }
3841
3921
  });
3842
- return generatedFiles;
3922
+ return Promise.resolve(generatedFiles);
3843
3923
  }
3844
3924
  getOperationName(endpoint) {
3845
3925
  if (endpoint.operationId) {
@@ -3856,44 +3936,65 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3856
3936
  const hookName = toHookName(endpoint.operationId || endpoint.id, true);
3857
3937
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3858
3938
  const operationName = this.getOperationName(endpoint);
3859
- const queryKey = this.generateQueryKey(endpoint);
3860
3939
  const staleTime = this.getStaleTime(endpoint);
3861
3940
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
3862
3941
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
3863
3942
  const hasPageParam = queryParameters.some((param) => param.name === "page");
3864
3943
  const hasSearchParams = endpoint.path.includes("search") || endpoint.path.includes("list");
3865
- endpoint.parameters.length > 0;
3866
- const parameterTypes = [];
3944
+ const pathParamTypes = [];
3945
+ const queryParamTypes = [];
3867
3946
  pathParameters.forEach((param) => {
3868
3947
  const isRequired = param.required ? "" : "?";
3869
3948
  const paramType = this.getTypeFromZodSchema(param.schema);
3870
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
3949
+ pathParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3871
3950
  });
3872
3951
  queryParameters.forEach((param) => {
3873
3952
  const isRequired = param.required ? "" : "?";
3874
3953
  const paramType = this.getTypeFromZodSchema(param.schema);
3875
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
3954
+ queryParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3876
3955
  });
3877
3956
  const returnType = `z.infer<typeof ${operationName}ResponseSchema>`;
3878
3957
  const optionsType = `{ enabled?: boolean; suspense?: boolean; refetchInterval?: number; initialData?: ${returnType} }`;
3879
- const enabledCondition = pathParameters.length > 0 ? `!!${pathParameters.map((parameter) => parameter.name).join(" && !!")}` : "true";
3880
- const actionCallParams = this.buildActionCallParams(endpoint, false);
3958
+ const paramsTypeParts = [];
3959
+ if (pathParameters.length > 0) {
3960
+ paramsTypeParts.push(`path: { ${pathParamTypes.join("; ")} }`);
3961
+ }
3962
+ if (queryParameters.length > 0) {
3963
+ paramsTypeParts.push(`query?: { ${queryParamTypes.join("; ")} }`);
3964
+ }
3965
+ const paramsType = paramsTypeParts.length > 0 ? `{ ${paramsTypeParts.join("; ")} }` : "{}";
3966
+ const enabledCondition = pathParameters.length > 0 && pathParameters[0] ? `!!params?.path?.${pathParameters[0].name}` : "true";
3967
+ const pathParamsBuild = pathParameters.length > 0 ? `{ ${pathParameters.map((p) => `${p.name}: params.path.${p.name}`).join(", ")} }` : "{}";
3968
+ const queryParamsBuild = queryParameters.length > 0 ? `{ ${queryParameters.map((p) => `${p.name}: params?.query?.${p.name}`).join(", ")} }` : "{}";
3881
3969
  if (hasSearchParams) {
3882
- const queryParamObject = queryParameters.length > 0 ? `{ ${queryParameters.map((param) => `${param.name}`).join(", ")} }` : "{}";
3970
+ const queryParamsWithFallback = queryParameters.length > 0 ? `const queryParams = {
3971
+ ${queryParameters.map((param) => {
3972
+ if (param.name === "query") {
3973
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3974
+ } else if (param.name === "limit") {
3975
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3976
+ } else {
3977
+ return `${param.name}: params?.query?.${param.name}`;
3978
+ }
3979
+ }).join(",\n ")}
3980
+ }` : "const queryParams = {}";
3883
3981
  return `/**
3884
3982
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
3885
3983
  * Features: URL state sync, infinite loading, optimistic updates
3984
+ * @param params - Named parameters object with path and query parameters
3985
+ * @param options - Query options
3886
3986
  * @returns useQuery result with data of type ${returnType}
3887
3987
  */
3888
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
3988
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3889
3989
  const [searchParams] = useQueryStates(searchParamsParser)
3890
3990
  const { initialData, ...restOptions } = options ?? {}
3891
3991
 
3892
3992
  return useQuery({
3893
- queryKey: [...${queryKey}, searchParams],
3993
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query, searchParams],
3894
3994
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
3895
3995
  try {
3896
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams }")}))
3996
+ ${queryParamsWithFallback}
3997
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }"}))
3897
3998
  return result
3898
3999
  } catch (error) {
3899
4000
  handleActionError(error)
@@ -3921,29 +4022,33 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
3921
4022
 
3922
4023
  /**
3923
4024
  * Infinite query version for paginated ${endpoint.path}
4025
+ * @param params - Named parameters object with path and query parameters
4026
+ * @param options - Query options
3924
4027
  * @returns useInfiniteQuery result with data of type ${returnType}
3925
4028
  */
3926
- export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4029
+ export function ${hookName.replace("use", "useInfinite")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3927
4030
  const [searchParams] = useQueryStates(searchParamsParser)
3928
4031
  const { initialData, ...restOptions } = options ?? {}
3929
4032
 
3930
4033
  return useInfiniteQuery({
3931
- queryKey: [...${queryKey}, 'infinite', searchParams],
4034
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query, 'infinite', searchParams],
3932
4035
  initialPageParam: 1,
3933
4036
  queryFn: async ({ pageParam = 1, signal }: { pageParam?: number; signal?: AbortSignal }) => {
3934
4037
  try {
3935
- // Build query params object with only the parameters the endpoint expects
3936
- const queryParams: Record<string, any> = {}
3937
- ${queryParameters.map((param) => {
4038
+ const queryParams = {
4039
+ ${queryParameters.map((param) => {
3938
4040
  if (param.name === "page" && hasPageParam) {
3939
- return `queryParams.${param.name} = pageParam`;
4041
+ return `${param.name}: pageParam`;
4042
+ } else if (param.name === "query") {
4043
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3940
4044
  } else if (param.name === "limit") {
3941
- return `queryParams.${param.name} = searchParams.limit`;
4045
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3942
4046
  } else {
3943
- return `if ('${param.name}' in searchParams) queryParams.${param.name} = searchParams.${param.name}`;
4047
+ return `${param.name}: params?.query?.${param.name}`;
4048
+ }
4049
+ }).join(",\n ")}
3944
4050
  }
3945
- }).join("\n ")}
3946
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "queryParams")}))
4051
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }"}))
3947
4052
  return result
3948
4053
  } catch (error) {
3949
4054
  handleActionError(error)
@@ -3985,15 +4090,17 @@ export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.lengt
3985
4090
 
3986
4091
  /**
3987
4092
  * Suspense version for ${endpoint.path} - use in Server Components
4093
+ * @param params - Named parameters object with path and query parameters
4094
+ * @param options - Query options
3988
4095
  * @returns useSuspenseQuery result with data of type ${returnType}
3989
4096
  */
3990
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4097
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3991
4098
  const { initialData, ...restOptions } = options ?? {}
3992
4099
 
3993
4100
  return useSuspenseQuery({
3994
- queryKey: ${queryKey},
4101
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
3995
4102
  queryFn: async () => {
3996
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams}))
4103
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
3997
4104
  return result
3998
4105
  },
3999
4106
  staleTime: ${staleTime},
@@ -4005,16 +4112,18 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
4005
4112
  return `/**
4006
4113
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
4007
4114
  * Features: Smart caching, error handling, type safety
4115
+ * @param params - Named parameters object with path and query parameters
4116
+ * @param options - Query options
4008
4117
  * @returns useQuery result with data of type ${returnType}
4009
4118
  */
4010
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4119
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4011
4120
  const { initialData, ...restOptions } = options ?? {}
4012
4121
 
4013
4122
  return useQuery({
4014
- queryKey: ${queryKey},
4123
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
4015
4124
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
4016
4125
  try {
4017
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4126
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
4018
4127
  return result
4019
4128
  } catch (error) {
4020
4129
  handleActionError(error)
@@ -4042,15 +4151,17 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
4042
4151
 
4043
4152
  /**
4044
4153
  * Suspense version for ${endpoint.path}
4154
+ * @param params - Named parameters object with path and query parameters
4155
+ * @param options - Query options
4045
4156
  * @returns useSuspenseQuery result with data of type ${returnType}
4046
4157
  */
4047
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4158
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4048
4159
  const { initialData, ...restOptions } = options ?? {}
4049
4160
 
4050
4161
  return useSuspenseQuery({
4051
- queryKey: ${queryKey},
4162
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
4052
4163
  queryFn: async () => {
4053
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4164
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
4054
4165
  return result
4055
4166
  },
4056
4167
  staleTime: ${staleTime},
@@ -4165,7 +4276,7 @@ ${invalidationCode}
4165
4276
  * Find related queries that should be invalidated when this mutation runs
4166
4277
  */
4167
4278
  findRelatedQueries(endpoint, context) {
4168
- if (!context?.schema?.endpoints) {
4279
+ if (!context?.schema.endpoints) {
4169
4280
  return [];
4170
4281
  }
4171
4282
  const relatedQueries = [];
@@ -4299,7 +4410,6 @@ ${invalidationCode}
4299
4410
  buildActionCallParams(endpoint, isMutation) {
4300
4411
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
4301
4412
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
4302
- !!endpoint.requestBody;
4303
4413
  if (isMutation) {
4304
4414
  return "variables";
4305
4415
  }
@@ -4380,13 +4490,13 @@ ${invalidationCode}
4380
4490
  import { useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, type UseQueryOptions, type UseMutationOptions, type UseInfiniteQueryOptions, type UseSuspenseQueryOptions, type QueryKey, type QueryFunction } from '@tanstack/react-query'
4381
4491
 
4382
4492
  /**
4383
- * Enhanced React Query wrapper hook with Next.js 16.0.1 optimizations
4493
+ * Enhanced React Query wrapper hook with Next.js 16.0.7 optimizations
4384
4494
  * Provides consistent defaults across all queries following best practices
4385
4495
  *
4386
4496
  * Features:
4387
4497
  * - React Query v5: Uses gcTime instead of cacheTime
4388
4498
  * - React Query v5: Uses placeholderData instead of keepPreviousData
4389
- * - Next.js 16.0.1: Optimized for App Router and Server Components
4499
+ * - Next.js 16.0.7: Optimized for App Router and Server Components
4390
4500
  */
4391
4501
  export function useBridgeQuery<TData = unknown, TError = Error>(
4392
4502
  queryKey: QueryKey,
@@ -4401,14 +4511,8 @@ export function useBridgeQuery<TData = unknown, TError = Error>(
4401
4511
  refetchOnWindowFocus: true,
4402
4512
  refetchOnReconnect: true,
4403
4513
  refetchOnMount: 'always',
4404
- // React Query v5: placeholderData cannot be a function type
4405
- // Use keepPreviousData pattern: return previousData if it exists and is not a function
4406
- placeholderData: (previousData) => {
4407
- if (previousData === undefined) return undefined
4408
- // Type guard: ensure we don't return a function (React Query v5 requirement)
4409
- if (typeof previousData === 'function') return undefined
4410
- return previousData
4411
- } as any,
4514
+ // React Query v5: placeholderData returns previous data if available
4515
+ placeholderData: (previousData) => previousData,
4412
4516
  retry: (failureCount: number, error: TError) => {
4413
4517
  if (error instanceof Error && error.message.includes('4')) return false
4414
4518
  return failureCount < 3
@@ -4421,15 +4525,17 @@ export function useBridgeQuery<TData = unknown, TError = Error>(
4421
4525
  * Enhanced infinite query wrapper
4422
4526
  * React Query v5: Optimized for paginated data with infinite scrolling
4423
4527
  */
4424
- export function useBridgeInfiniteQuery<TData = unknown, TError = Error>(
4528
+ export function useBridgeInfiniteQuery<TData = unknown, TError = Error, TPageParam = number>(
4425
4529
  queryKey: QueryKey,
4426
- queryFn: QueryFunction<TData, QueryKey>,
4427
- options?: Partial<UseInfiniteQueryOptions<TData, TError, TData, QueryKey>>
4530
+ queryFn: QueryFunction<TData, QueryKey, TPageParam>,
4531
+ options?: Partial<UseInfiniteQueryOptions<TData, TError, TData, QueryKey, TPageParam>> & {
4532
+ getNextPageParam?: (lastPage: TData, allPages: TData[]) => TPageParam | undefined
4533
+ }
4428
4534
  ) {
4429
- return useInfiniteQuery<TData, TError>({
4535
+ return useInfiniteQuery<TData, TError, TData, QueryKey, TPageParam>({
4430
4536
  queryKey,
4431
- initialPageParam: 1,
4432
- queryFn: queryFn as QueryFunction<TData, QueryKey>,
4537
+ initialPageParam: 1 as TPageParam,
4538
+ queryFn,
4433
4539
  staleTime: 5 * 60 * 1000,
4434
4540
  gcTime: 10 * 60 * 1000,
4435
4541
  refetchOnWindowFocus: true,
@@ -4439,13 +4545,15 @@ export function useBridgeInfiniteQuery<TData = unknown, TError = Error>(
4439
4545
  if (error instanceof Error && error.message.includes('4')) return false
4440
4546
  return failureCount < 3
4441
4547
  },
4548
+ // Provide default getNextPageParam if not provided
4549
+ getNextPageParam: options?.getNextPageParam || (() => undefined),
4442
4550
  ...options,
4443
4551
  })
4444
4552
  }
4445
4553
 
4446
4554
  /**
4447
4555
  * Enhanced suspense query wrapper
4448
- * Next.js 16.0.1: Optimized for Server Components with Suspense
4556
+ * Next.js 16.0.7: Optimized for Server Components with Suspense
4449
4557
  */
4450
4558
  export function useBridgeSuspenseQuery<TData = unknown, TError = Error>(
4451
4559
  queryKey: QueryKey,
@@ -4501,7 +4609,7 @@ var AuthGenerator = class {
4501
4609
  __name(this, "AuthGenerator");
4502
4610
  }
4503
4611
  buildImportPath(relativePath) {
4504
- const outputDirectory = this.configuration.outputDir || "generated";
4612
+ const outputDirectory = this.configuration.outputDir ?? "generated";
4505
4613
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
4506
4614
  let importBasePath = outputDirectory;
4507
4615
  if (importBasePath.startsWith("src/")) {
@@ -4509,11 +4617,11 @@ var AuthGenerator = class {
4509
4617
  }
4510
4618
  return `@/${importBasePath}/${cleanPath}`;
4511
4619
  }
4512
- async generate(context) {
4620
+ generate(context) {
4513
4621
  const { config, schema } = context;
4514
4622
  const authConfig = config.auth;
4515
4623
  if (!authConfig?.enabled) {
4516
- return [];
4624
+ return Promise.resolve([]);
4517
4625
  }
4518
4626
  const files = [];
4519
4627
  const authEndpoints = this.findAuthEndpoints(schema.endpoints);
@@ -4528,7 +4636,7 @@ var AuthGenerator = class {
4528
4636
  files.push(...this.generateAuthComponents(authEndpoints));
4529
4637
  files.push(this.generateAuthMiddleware());
4530
4638
  files.push(this.generateAuthContext());
4531
- return files;
4639
+ return Promise.resolve(files);
4532
4640
  }
4533
4641
  findAuthEndpoints(endpoints) {
4534
4642
  const authEndpoints = {};
@@ -4561,12 +4669,12 @@ var AuthGenerator = class {
4561
4669
  }
4562
4670
  return userEndpoints;
4563
4671
  }
4564
- generateAuthSchemas(authEndpoints, schema) {
4672
+ generateAuthSchemas(_authEndpoints, _schema) {
4565
4673
  this.buildImportPath("schemas");
4566
- const loginRequestSchema = authEndpoints.login?.requestBody?.content?.find(
4674
+ const loginRequestSchema = _authEndpoints.login?.requestBody?.content?.find(
4567
4675
  (c) => c.type === "application/json"
4568
4676
  )?.schema;
4569
- const loginResponseSchema = authEndpoints.login?.responses?.find(
4677
+ const loginResponseSchema = _authEndpoints.login?.responses?.find(
4570
4678
  (r) => r.statusCode === "200"
4571
4679
  )?.content?.[0]?.schema;
4572
4680
  const content = `import { z } from "zod"
@@ -4667,7 +4775,7 @@ export type Session = z.infer<typeof sessionSchema>`;
4667
4775
  }
4668
4776
  };
4669
4777
  }
4670
- generateAuthTypes(authEndpoints, schema) {
4778
+ generateAuthTypes(_authEndpoints, _schema) {
4671
4779
  const schemasImport = this.buildImportPath("auth/schemas");
4672
4780
  const content = `// Auto-generated authentication types
4673
4781
  import type {
@@ -5213,7 +5321,7 @@ export const useRequireAuth = (redirectTo?: string) => {
5213
5321
  }
5214
5322
  };
5215
5323
  }
5216
- generateAuthActions(authEndpoints, userEndpoints) {
5324
+ generateAuthActions(_authEndpoints, _userEndpoints) {
5217
5325
  const safeActionImport = this.buildImportPath("lib/safe-action");
5218
5326
  const schemasImport = this.buildImportPath("auth/schemas");
5219
5327
  const clientImport = this.buildImportPath("auth/client");
@@ -5445,7 +5553,7 @@ export const useCredentialsLogin = () => {
5445
5553
  }
5446
5554
  };
5447
5555
  }
5448
- generateAuthComponents(authEndpoints) {
5556
+ generateAuthComponents(_authEndpoints) {
5449
5557
  const loginForm = {
5450
5558
  path: "auth/components/login-form.tsx",
5451
5559
  content: `"use client"
@@ -5565,7 +5673,6 @@ export function LoginForm() {
5565
5673
  return [loginForm];
5566
5674
  }
5567
5675
  generateAuthMiddleware() {
5568
- this.buildImportPath("auth/utils");
5569
5676
  const content = `import { NextResponse } from "next/server"
5570
5677
  import type { NextRequest } from "next/server"
5571
5678
 
@@ -5933,9 +6040,10 @@ var SchemaAnalyzer = class {
5933
6040
  }
5934
6041
  if (response.description) {
5935
6042
  const errorMatch = response.description.match(/error[_\s]?code[:\s]+(\w+)/i);
5936
- if (errorMatch) {
5937
- errorCodes.set(errorMatch[1].toLowerCase(), {
5938
- code: errorMatch[1],
6043
+ if (errorMatch?.[1]) {
6044
+ const errorCode = errorMatch[1];
6045
+ errorCodes.set(errorCode.toLowerCase(), {
6046
+ code: errorCode,
5939
6047
  status,
5940
6048
  message: response.description
5941
6049
  });
@@ -6021,7 +6129,7 @@ var SchemaAnalyzer = class {
6021
6129
  const endpoints = {};
6022
6130
  for (const endpoint of this.schema.endpoints) {
6023
6131
  const path3 = endpoint.path.toLowerCase();
6024
- const operationId = (endpoint.operationId || "").toLowerCase();
6132
+ const operationId = (endpoint.operationId ?? "").toLowerCase();
6025
6133
  if ((path3.includes("/auth/login/credentials") || operationId.includes("logincredentials") || operationId.includes("signin")) && endpoint.method === "POST") {
6026
6134
  endpoints.loginCredentials = endpoint;
6027
6135
  } else if ((path3.includes("/auth/login") || operationId.includes("login")) && endpoint.method === "POST" && !endpoints.loginCredentials) {
@@ -6069,12 +6177,12 @@ var SchemaAnalyzer = class {
6069
6177
  extractSessionConfig() {
6070
6178
  const config = {};
6071
6179
  const sessionEndpoints = this.schema.endpoints.filter(
6072
- (e) => e.path.toLowerCase().includes("/session") || (e.operationId || "").toLowerCase().includes("session")
6180
+ (e) => e.path.toLowerCase().includes("/session") || (e.operationId ?? "").toLowerCase().includes("session")
6073
6181
  );
6074
6182
  for (const endpoint of sessionEndpoints) {
6075
6183
  for (const response of endpoint.responses) {
6076
6184
  if (response.headers) {
6077
- for (const [headerName, headerDef] of Object.entries(response.headers)) {
6185
+ for (const [headerName, _headerDef] of Object.entries(response.headers)) {
6078
6186
  if (headerName.toLowerCase().includes("expires") || headerName.toLowerCase().includes("max-age")) ;
6079
6187
  }
6080
6188
  }
@@ -6154,7 +6262,7 @@ var SchemaAnalyzer = class {
6154
6262
  /**
6155
6263
  * Check if OAuth provider is supported
6156
6264
  */
6157
- isOAuthProviderSupported(provider) {
6265
+ isOAuthProviderSupported(_provider) {
6158
6266
  const extractedEndpoints = this.extractAuthEndpoints();
6159
6267
  return !!(extractedEndpoints.oauthAuthorize && extractedEndpoints.oauthCallback);
6160
6268
  }
@@ -6236,7 +6344,7 @@ var SchemaAnalyzer = class {
6236
6344
  errorCodes.set(code.toLowerCase(), {
6237
6345
  code,
6238
6346
  status,
6239
- message: schema.properties?.detail?.default || schema.properties?.message?.default || ""
6347
+ message: schema.properties?.detail?.default ?? schema.properties?.message?.default ?? ""
6240
6348
  });
6241
6349
  });
6242
6350
  }
@@ -6245,9 +6353,10 @@ var SchemaAnalyzer = class {
6245
6353
  const detail = schema.properties.detail;
6246
6354
  if (typeof detail === "string") {
6247
6355
  const codeMatch = detail.match(/(\w+)[_\s]?error/i);
6248
- if (codeMatch) {
6249
- errorCodes.set(codeMatch[1].toLowerCase(), {
6250
- code: codeMatch[1],
6356
+ if (codeMatch?.[1]) {
6357
+ const errorCode = codeMatch[1];
6358
+ errorCodes.set(errorCode.toLowerCase(), {
6359
+ code: errorCode,
6251
6360
  status,
6252
6361
  message: detail
6253
6362
  });
@@ -6259,11 +6368,11 @@ var SchemaAnalyzer = class {
6259
6368
  if (!schema || typeof schema !== "object") return;
6260
6369
  if (schema.properties?.file) {
6261
6370
  const fileSchema = schema.properties.file;
6262
- if (fileSchema.maxSize || fileSchema["x-max-size"]) {
6263
- config.maxSize = fileSchema.maxSize || fileSchema["x-max-size"];
6371
+ if (fileSchema.maxSize ?? fileSchema["x-max-size"]) {
6372
+ config.maxSize = fileSchema.maxSize ?? fileSchema["x-max-size"];
6264
6373
  }
6265
- if (fileSchema.allowedTypes || fileSchema["x-allowed-types"]) {
6266
- config.allowedTypes = fileSchema.allowedTypes || fileSchema["x-allowed-types"];
6374
+ if (fileSchema.allowedTypes ?? fileSchema["x-allowed-types"]) {
6375
+ config.allowedTypes = fileSchema.allowedTypes ?? fileSchema["x-allowed-types"];
6267
6376
  }
6268
6377
  }
6269
6378
  if (schema["x-file-constraints"]) {
@@ -6283,7 +6392,7 @@ var NextAuthGenerator = class {
6283
6392
  analyzer;
6284
6393
  accountStatusPatterns;
6285
6394
  buildImportPath(relativePath) {
6286
- const outputDirectory = this.configuration.outputDir || "generated";
6395
+ const outputDirectory = this.configuration.outputDir ?? "generated";
6287
6396
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
6288
6397
  let importBasePath = outputDirectory;
6289
6398
  if (importBasePath.startsWith("src/")) {
@@ -6291,11 +6400,11 @@ var NextAuthGenerator = class {
6291
6400
  }
6292
6401
  return `@/${importBasePath}/${cleanPath}`;
6293
6402
  }
6294
- async generate(context) {
6403
+ generate(context) {
6295
6404
  const { config, schema } = context;
6296
6405
  const authConfig = config.auth;
6297
6406
  if (!authConfig?.enabled || authConfig.provider !== "next-auth") {
6298
- return [];
6407
+ return Promise.resolve([]);
6299
6408
  }
6300
6409
  this.analyzer = new SchemaAnalyzer(schema);
6301
6410
  this.accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
@@ -6312,7 +6421,7 @@ var NextAuthGenerator = class {
6312
6421
  console.warn("These features will be disabled in generated code.\n");
6313
6422
  }
6314
6423
  const detectedOAuthProviders = this.analyzer.extractOAuthProviders();
6315
- const configuredOAuthProviders = authConfig.oauth?.providers || [];
6424
+ const configuredOAuthProviders = authConfig.oauth?.providers ?? [];
6316
6425
  const validOAuthProviders = configuredOAuthProviders.filter(
6317
6426
  (provider) => this.analyzer.isOAuthProviderSupported(provider)
6318
6427
  );
@@ -6323,7 +6432,7 @@ var NextAuthGenerator = class {
6323
6432
  console.warn(
6324
6433
  `\u26A0\uFE0F NextAuth is enabled but login endpoints are not found in OpenAPI schema. Expected endpoints: /auth/login or /auth/login/credentials. NextAuth configuration will not be generated.`
6325
6434
  );
6326
- return files;
6435
+ return Promise.resolve(files);
6327
6436
  }
6328
6437
  files.push(this.generateNextAuthConfig(
6329
6438
  extractedEndpoints,
@@ -6336,7 +6445,7 @@ var NextAuthGenerator = class {
6336
6445
  if (hasPasskeys) {
6337
6446
  files.push(this.generatePasskeyUtils(extractedEndpoints));
6338
6447
  }
6339
- return files;
6448
+ return Promise.resolve(files);
6340
6449
  }
6341
6450
  findAuthEndpoints(endpoints) {
6342
6451
  const authEndpoints = {};
@@ -6439,14 +6548,14 @@ var NextAuthGenerator = class {
6439
6548
  }
6440
6549
  generateNextAuthConfig(extractedEndpoints, oauthProviders, hasMFA, hasPasskeys) {
6441
6550
  const authConfig = this.configuration.auth;
6442
- const apiBaseUrl = this.configuration.api?.baseUrl || "http://localhost:8000";
6551
+ const apiBaseUrl = this.configuration.api.baseUrl || "http://localhost:8000";
6443
6552
  const apiUrl = `process.env.NEXT_PUBLIC_API_URL || '${apiBaseUrl}'`;
6444
6553
  const hasGoogle = oauthProviders.includes("google");
6445
6554
  const hasGitHub = oauthProviders.includes("github");
6446
6555
  oauthProviders.includes("discord");
6447
6556
  oauthProviders.includes("microsoft");
6448
6557
  oauthProviders.includes("apple");
6449
- const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses } = this.accountStatusPatterns;
6558
+ const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses: _lockedStatuses } = this.accountStatusPatterns;
6450
6559
  this.analyzer.extractErrorCodes();
6451
6560
  const sessionStrategy = authConfig.session?.strategy || "jwt";
6452
6561
  const sessionMaxAge = authConfig.session?.maxAge || 7 * 24 * 60 * 60;
@@ -6995,7 +7104,7 @@ export async function authenticateWithPasskey(email?: string) {
6995
7104
  }
6996
7105
  };
6997
7106
  }
6998
- generateAuthTypes(authEndpoints, accountStatusPatterns) {
7107
+ generateAuthTypes(_authEndpoints, _accountStatusPatterns) {
6999
7108
  const content = `/**
7000
7109
  * Authentication Types
7001
7110
  * Auto-generated by Mulink
@@ -7066,7 +7175,7 @@ export class AccountInactiveError extends AuthError {
7066
7175
  }
7067
7176
  };
7068
7177
  }
7069
- generateAuthUtils(authEndpoints) {
7178
+ generateAuthUtils(_authEndpoints) {
7070
7179
  const content = `/**
7071
7180
  * Authentication Utilities
7072
7181
  * Auto-generated by Mulink
@@ -7119,7 +7228,7 @@ export async function requireAuth() {
7119
7228
  }
7120
7229
  };
7121
7230
  }
7122
- generatePasskeyUtils(passkeyEndpoints) {
7231
+ generatePasskeyUtils(_passkeyEndpoints) {
7123
7232
  const content = `/**
7124
7233
  * Passkey (WebAuthn) Utilities
7125
7234
  * Auto-generated by Mulink
@@ -7172,7 +7281,7 @@ var MiddlewareGenerator = class {
7172
7281
  __name(this, "MiddlewareGenerator");
7173
7282
  }
7174
7283
  buildImportPath(relativePath) {
7175
- const outputDirectory = this.configuration.outputDir || "generated";
7284
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7176
7285
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7177
7286
  let importBasePath = outputDirectory;
7178
7287
  if (importBasePath.startsWith("src/")) {
@@ -7180,7 +7289,7 @@ var MiddlewareGenerator = class {
7180
7289
  }
7181
7290
  return `@/${importBasePath}/${cleanPath}`;
7182
7291
  }
7183
- async generate(context) {
7292
+ generate(_context) {
7184
7293
  const files = [];
7185
7294
  files.push(this.generateMainMiddleware());
7186
7295
  files.push(this.generateRateLimitMiddleware());
@@ -7188,7 +7297,7 @@ var MiddlewareGenerator = class {
7188
7297
  files.push(this.generateSecurityMiddleware());
7189
7298
  files.push(this.generateLoggingMiddleware());
7190
7299
  files.push(this.generateApiMiddleware());
7191
- return files;
7300
+ return Promise.resolve(files);
7192
7301
  }
7193
7302
  generateMainMiddleware() {
7194
7303
  const authImport = this.buildImportPath("auth/middleware");
@@ -7595,7 +7704,7 @@ var UploadGenerator = class {
7595
7704
  }
7596
7705
  analyzer;
7597
7706
  buildImportPath(relativePath) {
7598
- const outputDirectory = this.configuration.outputDir || "generated";
7707
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7599
7708
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7600
7709
  let importBasePath = outputDirectory;
7601
7710
  if (importBasePath.startsWith("src/")) {
@@ -7603,19 +7712,19 @@ var UploadGenerator = class {
7603
7712
  }
7604
7713
  return `@/${importBasePath}/${cleanPath}`;
7605
7714
  }
7606
- async generate(context) {
7715
+ generate(context) {
7607
7716
  const { schema } = context;
7608
7717
  const generatedFiles = [];
7609
7718
  this.analyzer = new SchemaAnalyzer(schema);
7610
7719
  const uploadEndpoints = schema.endpoints.filter(
7611
- (endpoint) => endpoint.requestBody?.content?.some(
7720
+ (endpoint) => endpoint.requestBody?.content.some(
7612
7721
  (content) => content.type === "multipart/form-data" || content.type === "application/octet-stream"
7613
7722
  )
7614
7723
  );
7615
7724
  if (uploadEndpoints.length === 0 || !this.configuration.uploads?.enabled) {
7616
- return generatedFiles;
7725
+ return Promise.resolve(generatedFiles);
7617
7726
  }
7618
- const presignedConfig = this.configuration.uploads?.presignedUploads;
7727
+ const presignedConfig = this.configuration.uploads.presignedUploads;
7619
7728
  if (presignedConfig?.enabled) {
7620
7729
  const isPresignedSupported = this.analyzer.isPresignedUploadsSupported();
7621
7730
  if (!isPresignedSupported) {
@@ -7626,14 +7735,14 @@ var UploadGenerator = class {
7626
7735
  }
7627
7736
  const extractedUploadConfig = this.analyzer.extractUploadConfig();
7628
7737
  const presignedEnabled = presignedConfig?.enabled && this.analyzer.isPresignedUploadsSupported();
7629
- const uploadProvider = this.configuration.uploads?.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7630
- const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads?.strategy || "standard";
7738
+ const uploadProvider = this.configuration.uploads.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7739
+ const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads.strategy || "standard";
7631
7740
  presignedEnabled ? {
7632
- presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig?.presignEndpoint || "/api/v1/files/presign-upload",
7633
- fallbackToBackend: presignedConfig?.fallbackToBackend !== false
7741
+ presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig.presignEndpoint || "/api/v1/files/presign-upload",
7742
+ fallbackToBackend: presignedConfig.fallbackToBackend !== false
7634
7743
  } : {
7635
7744
  };
7636
- const progressConfig = this.configuration.uploads?.progressTracking || {
7745
+ const progressConfig = this.configuration.uploads.progressTracking || {
7637
7746
  enabled: true,
7638
7747
  useXHR: true
7639
7748
  };
@@ -7650,7 +7759,7 @@ var UploadGenerator = class {
7650
7759
  progressConfig
7651
7760
  ));
7652
7761
  }
7653
- return generatedFiles;
7762
+ return Promise.resolve(generatedFiles);
7654
7763
  }
7655
7764
  /**
7656
7765
  * Find presigned upload endpoint in schema
@@ -7663,7 +7772,7 @@ var UploadGenerator = class {
7663
7772
  return pathLower.includes("presign") || pathLower.includes("presigned") || operationIdLower.includes("presign") || operationIdLower.includes("presigned");
7664
7773
  }) || null;
7665
7774
  }
7666
- generateUploadUtilities(uploadProvider, uploadStrategy, presignedEndpoint) {
7775
+ generateUploadUtilities(_uploadProvider, _uploadStrategy, _presignedEndpoint) {
7667
7776
  const { uploads } = this.configuration;
7668
7777
  const extractedConfig = this.analyzer.extractUploadConfig();
7669
7778
  const maxSize = uploads?.security?.maxSize || (extractedConfig.maxSize ? `${extractedConfig.maxSize}MB` : "10MB");
@@ -8014,8 +8123,8 @@ async function uploadViaBackendApi(
8014
8123
  xhr.responseType = 'json'
8015
8124
  // Use base URL from environment or configuration
8016
8125
  const baseUrl = typeof window !== 'undefined'
8017
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8018
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8126
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8127
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8019
8128
  xhr.open('POST', \`\${baseUrl}${endpoint.path}\`)
8020
8129
  xhr.send(formData)
8021
8130
  })
@@ -8290,8 +8399,8 @@ export function ${hookName}Upload(options?: {
8290
8399
  }
8291
8400
  generateUseUploadFileHook(uploadProvider, uploadStrategy, context) {
8292
8401
  const uploadUtilsImport = this.buildImportPath("services/uploadUtils");
8293
- const uploadEndpoints = context?.schema?.endpoints?.filter(
8294
- (e) => e.metadata?.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8402
+ const uploadEndpoints = context?.schema.endpoints.filter(
8403
+ (e) => e.metadata.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8295
8404
  ) || [];
8296
8405
  const firstUploadEndpoint = uploadEndpoints[0];
8297
8406
  let uploadMethodName = "uploadFile";
@@ -8431,7 +8540,7 @@ var ErrorHandlerGenerator = class {
8431
8540
  }
8432
8541
  analyzer;
8433
8542
  buildImportPath(relativePath) {
8434
- const outputDirectory = this.configuration.outputDir || "generated";
8543
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8435
8544
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8436
8545
  let importBasePath = outputDirectory;
8437
8546
  if (importBasePath.startsWith("src/")) {
@@ -8439,18 +8548,18 @@ var ErrorHandlerGenerator = class {
8439
8548
  }
8440
8549
  return `@/${importBasePath}/${cleanPath}`;
8441
8550
  }
8442
- async generate(context) {
8551
+ generate(context) {
8443
8552
  const files = [];
8444
- const { schema, config } = context;
8553
+ const { schema } = context;
8445
8554
  const { api } = this.configuration;
8446
- const errorHandling = api?.errorHandling;
8555
+ const errorHandling = api.errorHandling;
8447
8556
  this.analyzer = new SchemaAnalyzer(schema);
8448
8557
  const errorCodes = this.analyzer.extractErrorCodes();
8449
8558
  const accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
8450
8559
  const extractedAuthEndpoints = this.analyzer.extractAuthEndpoints();
8451
8560
  const hasAuthEndpoints = !!(extractedAuthEndpoints.login || extractedAuthEndpoints.loginCredentials);
8452
8561
  const hasAuthErrors = errorCodes.size > 0 || (accountStatusPatterns.inactiveStatuses.length > 0 || accountStatusPatterns.suspendedStatuses.length > 0);
8453
- const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling?.generateAuthErrorHandler !== false);
8562
+ const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling.generateAuthErrorHandler !== false);
8454
8563
  if (shouldGenerate) {
8455
8564
  files.push(this.generateAuthErrorHandler(errorCodes, accountStatusPatterns));
8456
8565
  } else if (errorHandling?.enableAuthErrorHandling === true && !hasAuthEndpoints) {
@@ -8458,11 +8567,11 @@ var ErrorHandlerGenerator = class {
8458
8567
  `\u26A0\uFE0F Auth error handling is enabled but auth endpoints are not found in OpenAPI schema. Auth error handler will not be generated.`
8459
8568
  );
8460
8569
  }
8461
- return files;
8570
+ return Promise.resolve(files);
8462
8571
  }
8463
8572
  generateAuthErrorHandler(errorCodes, accountStatusPatterns) {
8464
8573
  const authPath = this.configuration.auth?.authPath || "@/lib/auth";
8465
- const errorHandling = this.configuration.api?.errorHandling;
8574
+ const errorHandling = this.configuration.api.errorHandling;
8466
8575
  const authErrorHandlerPath = errorHandling?.authErrorHandlerPath || "@/lib/auth-error-handler";
8467
8576
  let handlerOutputPath = authErrorHandlerPath;
8468
8577
  if (handlerOutputPath.startsWith("@/")) {
@@ -8501,7 +8610,7 @@ async function getToast(): Promise<{
8501
8610
  try {
8502
8611
  // Try to import sonner (common toast library)
8503
8612
  const sonner = await import('sonner')
8504
- toast = sonner
8613
+ toast = sonner.toast
8505
8614
  return toast
8506
8615
  } catch {
8507
8616
  // Fallback to console if toast library not available
@@ -8675,7 +8784,7 @@ var SSEGenerator = class {
8675
8784
  }
8676
8785
  analyzer;
8677
8786
  buildImportPath(relativePath) {
8678
- const outputDirectory = this.configuration.outputDir || "generated";
8787
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8679
8788
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8680
8789
  let importBasePath = outputDirectory;
8681
8790
  if (importBasePath.startsWith("src/")) {
@@ -8707,11 +8816,11 @@ var SSEGenerator = class {
8707
8816
  );
8708
8817
  return hasEventStream;
8709
8818
  }
8710
- async generate(context) {
8819
+ generate(context) {
8711
8820
  const { schema } = context;
8712
8821
  const generatedFiles = [];
8713
8822
  this.analyzer = new SchemaAnalyzer(schema);
8714
- const streamingConfig = this.configuration.framework?.streaming;
8823
+ const streamingConfig = this.configuration.framework.streaming;
8715
8824
  const hasStreamingEndpoints = schema.endpoints.some((endpoint) => this.isSSEEndpoint(endpoint));
8716
8825
  if (streamingConfig?.enabled === true && !hasStreamingEndpoints) {
8717
8826
  console.warn(
@@ -8720,11 +8829,11 @@ var SSEGenerator = class {
8720
8829
  }
8721
8830
  const shouldEnableStreaming = streamingConfig?.enabled === true ? hasStreamingEndpoints : streamingConfig?.enabled !== false && hasStreamingEndpoints;
8722
8831
  if (!shouldEnableStreaming || streamingConfig?.sse?.enabled === false || !hasStreamingEndpoints) {
8723
- return generatedFiles;
8832
+ return Promise.resolve(generatedFiles);
8724
8833
  }
8725
8834
  const sseEndpoints = schema.endpoints.filter((endpoint) => this.isSSEEndpoint(endpoint));
8726
8835
  if (sseEndpoints.length === 0) {
8727
- return generatedFiles;
8836
+ return Promise.resolve(generatedFiles);
8728
8837
  }
8729
8838
  for (const endpoint of sseEndpoints) {
8730
8839
  generatedFiles.push(this.generateSSEClientMethod(endpoint));
@@ -8733,7 +8842,7 @@ var SSEGenerator = class {
8733
8842
  for (const [tag, tagEndpoints] of Object.entries(endpointsByTag)) {
8734
8843
  generatedFiles.push(this.generateSSEHooks(tag, tagEndpoints));
8735
8844
  }
8736
- return generatedFiles;
8845
+ return Promise.resolve(generatedFiles);
8737
8846
  }
8738
8847
  generateSSEClientMethod(endpoint) {
8739
8848
  const operationId = endpoint.operationId || endpoint.id;
@@ -8768,8 +8877,8 @@ var SSEGenerator = class {
8768
8877
  }): EventSource => {
8769
8878
  ${pathParamNames.length > 0 ? `const { ${pathParamNames.join(", ")}, ...restOptions } = options.params || {}
8770
8879
  ` : ""}const baseUrl = typeof window !== 'undefined'
8771
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8772
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8880
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8881
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8773
8882
  const sseUrl = \`\${baseUrl}${urlConstruction}\`
8774
8883
 
8775
8884
  // Create EventSource connection
@@ -8815,7 +8924,7 @@ var SSEGenerator = class {
8815
8924
  generateSSEHooks(tag, endpoints) {
8816
8925
  const tagName = toValidIdentifier(tag);
8817
8926
  const clientImport = this.buildImportPath("client");
8818
- const streamingConfig = this.configuration.framework?.streaming?.sse;
8927
+ const streamingConfig = this.configuration.framework.streaming?.sse;
8819
8928
  const autoReconnect = streamingConfig?.autoReconnect !== false;
8820
8929
  const reconnectDelay = streamingConfig?.reconnectDelay || 3e3;
8821
8930
  const maxReconnectAttempts = streamingConfig?.maxReconnectAttempts || 5;
@@ -9008,7 +9117,7 @@ var NextJsCodeGenerator = class {
9008
9117
  __name(this, "NextJsCodeGenerator");
9009
9118
  }
9010
9119
  buildImportPath(relativePath) {
9011
- const outputDirectory = this.configuration.outputDir || "generated";
9120
+ const outputDirectory = this.configuration.outputDir ?? "generated";
9012
9121
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
9013
9122
  let importBasePath = outputDirectory;
9014
9123
  if (importBasePath.startsWith("src/")) {
@@ -9022,9 +9131,9 @@ var NextJsCodeGenerator = class {
9022
9131
  path: file.path,
9023
9132
  metadata: {
9024
9133
  ...file.metadata,
9025
- exports: file.metadata?.exports || [],
9026
- imports: file.metadata?.imports || [],
9027
- dependencies: file.metadata?.dependencies?.map((dependency) => {
9134
+ exports: file.metadata?.exports ?? [],
9135
+ imports: file.metadata?.imports ?? [],
9136
+ dependencies: file.metadata?.dependencies.map((dependency) => {
9028
9137
  if (dependency.startsWith("@/generated/")) {
9029
9138
  return dependency;
9030
9139
  }
@@ -9033,7 +9142,7 @@ var NextJsCodeGenerator = class {
9033
9142
  return `@/generated/${relativePart}`;
9034
9143
  }
9035
9144
  return dependency;
9036
- }) || []
9145
+ }) ?? []
9037
9146
  }
9038
9147
  }));
9039
9148
  }
@@ -9066,11 +9175,11 @@ var NextJsCodeGenerator = class {
9066
9175
  const uploadGenerator = new UploadGenerator(this.configuration);
9067
9176
  generatedFiles.push(...await uploadGenerator.generate(context));
9068
9177
  }
9069
- if (this.configuration.api?.errorHandling?.generateAuthErrorHandler !== false) {
9178
+ if (this.configuration.api.errorHandling?.generateAuthErrorHandler !== false) {
9070
9179
  const errorHandlerGenerator = new ErrorHandlerGenerator(this.configuration);
9071
9180
  generatedFiles.push(...await errorHandlerGenerator.generate(context));
9072
9181
  }
9073
- if (this.configuration.framework?.streaming?.enabled) {
9182
+ if (this.configuration.framework.streaming?.enabled) {
9074
9183
  const sseGenerator = new SSEGenerator(this.configuration);
9075
9184
  generatedFiles.push(...await sseGenerator.generate(context));
9076
9185
  }
@@ -9080,14 +9189,14 @@ var NextJsCodeGenerator = class {
9080
9189
  throw new GenerationError(`Failed to generate Next.js files: ${errorMessage}`);
9081
9190
  }
9082
9191
  }
9083
- async generateSafeActionClient() {
9192
+ generateSafeActionClient() {
9084
9193
  const safeActionContent = `import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "next-safe-action";
9085
9194
  import { headers } from "next/headers";
9086
9195
  import { z } from "zod";
9087
9196
 
9088
9197
  /**
9089
9198
  * Enhanced Action Error class for better error handling
9090
- * Follows Next.js 16.0.1 best practices
9199
+ * Follows Next.js 16.0.7 best practices
9091
9200
  */
9092
9201
  export class ActionError extends Error {
9093
9202
  constructor(
@@ -9124,7 +9233,7 @@ export const actionClient = createSafeActionClient({
9124
9233
 
9125
9234
  /**
9126
9235
  * Enhanced action client with metadata support
9127
- * Next.js 16.0.1: Supports metadata for better action tracking and rate limiting
9236
+ * Next.js 16.0.7: Supports metadata for better action tracking and rate limiting
9128
9237
  */
9129
9238
  export const actionClientWithMeta = createSafeActionClient({
9130
9239
  handleServerError(e) {
@@ -9145,7 +9254,7 @@ export const actionClientWithMeta = createSafeActionClient({
9145
9254
  requests: z.number().int().positive().describe('Number of requests allowed'),
9146
9255
  window: z.string().describe('Time window (e.g., "10s", "1m", "1h")'),
9147
9256
  }).optional().describe('Rate limiting configuration'),
9148
- cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.1)'),
9257
+ cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.7)'),
9149
9258
  });
9150
9259
  },
9151
9260
  });
@@ -9236,7 +9345,7 @@ async function getCurrentUser() {
9236
9345
  // Implement your authentication logic here
9237
9346
  return null;
9238
9347
  }`;
9239
- return [
9348
+ return Promise.resolve([
9240
9349
  {
9241
9350
  path: "lib/safe-action.ts",
9242
9351
  content: safeActionContent,
@@ -9247,7 +9356,7 @@ async function getCurrentUser() {
9247
9356
  dependencies: []
9248
9357
  }
9249
9358
  }
9250
- ];
9359
+ ]);
9251
9360
  }
9252
9361
  };
9253
9362
  var FileSystemManager = class {
@@ -9255,7 +9364,7 @@ var FileSystemManager = class {
9255
9364
  __name(this, "FileSystemManager");
9256
9365
  }
9257
9366
  async writeFile(filePath, content, options = {}) {
9258
- if (!filePath?.trim()) {
9367
+ if (!filePath.trim()) {
9259
9368
  throw new Error("File path is required and cannot be empty");
9260
9369
  }
9261
9370
  if (typeof content !== "string") {
@@ -9292,7 +9401,7 @@ var FileSystemManager = class {
9292
9401
  }
9293
9402
  }
9294
9403
  async readFile(filePath, encoding = "utf8") {
9295
- if (!filePath?.trim()) {
9404
+ if (!filePath.trim()) {
9296
9405
  throw new Error("File path is required and cannot be empty");
9297
9406
  }
9298
9407
  try {
@@ -9319,7 +9428,7 @@ var FileSystemManager = class {
9319
9428
  }
9320
9429
  }
9321
9430
  async getFileHash(filePath) {
9322
- if (!filePath?.trim()) {
9431
+ if (!filePath.trim()) {
9323
9432
  throw new Error("File path is required and cannot be empty");
9324
9433
  }
9325
9434
  try {
@@ -9345,7 +9454,7 @@ var FileSystemManager = class {
9345
9454
  }
9346
9455
  }
9347
9456
  async findFiles(dir, pattern, recursive = true) {
9348
- if (!dir?.trim()) {
9457
+ if (!dir.trim()) {
9349
9458
  throw new Error("Directory path is required and cannot be empty");
9350
9459
  }
9351
9460
  if (!(pattern instanceof RegExp)) {
@@ -9388,16 +9497,52 @@ var BridgeCore = class {
9388
9497
  logger;
9389
9498
  schemaParser;
9390
9499
  fileManager;
9500
+ /**
9501
+ * Creates a new instance of BridgeCore
9502
+ *
9503
+ * Initializes all required dependencies including logger, schema parser, and file manager.
9504
+ * All dependencies are readonly to ensure immutability and thread safety.
9505
+ */
9391
9506
  constructor() {
9392
9507
  this.logger = new BridgeLogger({ prefix: "\u{1F517} Mulink" });
9393
9508
  this.schemaParser = new OpenApiSchemaParser();
9394
9509
  this.fileManager = new FileSystemManager();
9395
9510
  }
9511
+ /**
9512
+ * Generates type-safe API client code from OpenAPI schema
9513
+ *
9514
+ * This is the main entry point for code generation. It validates the configuration,
9515
+ * parses the OpenAPI schema, generates all necessary files, and writes them to disk.
9516
+ *
9517
+ * The generated code follows Next.js 16.0.7 best practices including:
9518
+ * - Server Actions with type safety
9519
+ * - React Query hooks with proper caching
9520
+ * - Middleware support
9521
+ * - Error handling
9522
+ * - Cache tag management
9523
+ *
9524
+ * @param configuration - The bridge configuration containing schema URL, output directory, and framework settings
9525
+ * @returns Promise that resolves when generation is complete
9526
+ * @throws {ValidationError} When configuration is invalid
9527
+ * @throws {SchemaParseError} When OpenAPI schema cannot be parsed
9528
+ * @throws {GenerationError} When code generation fails
9529
+ *
9530
+ * @example
9531
+ * ```typescript
9532
+ * const config: BridgeConfiguration = {
9533
+ * schema: 'https://api.example.com/openapi.json',
9534
+ * outputDir: 'src/generated',
9535
+ * framework: { type: 'nextjs', router: 'app', features: {...} },
9536
+ * api: { baseUrl: 'https://api.example.com', timeout: 30000, retries: 3 }
9537
+ * };
9538
+ * await bridge.generate(config);
9539
+ * ```
9540
+ */
9396
9541
  async generate(configuration) {
9397
9542
  const startTime = Date.now();
9398
9543
  try {
9399
9544
  this.logger.info("Starting code generation...");
9400
- await this.validateConfiguration(configuration);
9545
+ this.validateConfiguration(configuration);
9401
9546
  this.logger.info(`Parsing schema: ${configuration.schema}`);
9402
9547
  const parsedSchema = await this.schemaParser.parse(configuration.schema);
9403
9548
  this.logger.debug(
@@ -9426,16 +9571,17 @@ var BridgeCore = class {
9426
9571
  throw error;
9427
9572
  }
9428
9573
  }
9429
- async validateConfiguration(configuration) {
9574
+ validateConfiguration(configuration) {
9430
9575
  const errors = [];
9431
- if (!configuration.schema?.trim()) {
9576
+ if (!configuration.schema.trim()) {
9432
9577
  errors.push("Schema URL is required and cannot be empty");
9433
9578
  }
9434
- if (!configuration.outputDir?.trim()) {
9579
+ if (!configuration.outputDir.trim()) {
9435
9580
  errors.push("Output directory is required and cannot be empty");
9436
9581
  }
9437
9582
  if (configuration.framework.type !== "nextjs") {
9438
- errors.push(`Only Next.js framework is currently supported, got: ${configuration.framework.type}`);
9583
+ const frameworkType = configuration.framework.type;
9584
+ errors.push(`Only Next.js framework is currently supported, got: ${frameworkType}`);
9439
9585
  }
9440
9586
  if (errors.length > 0) {
9441
9587
  throw new ValidationError(
@@ -9452,8 +9598,10 @@ var BridgeCore = class {
9452
9598
  case "nextjs":
9453
9599
  const nextJsGenerator = new NextJsCodeGenerator(config);
9454
9600
  return await nextJsGenerator.generate(context);
9455
- default:
9456
- throw new GenerationError(`Unsupported framework: ${config.framework.type}`);
9601
+ default: {
9602
+ const frameworkType = config.framework.type;
9603
+ throw new GenerationError(`Unsupported framework: ${frameworkType}`);
9604
+ }
9457
9605
  }
9458
9606
  } catch (error) {
9459
9607
  if (error instanceof GenerationError) {
@@ -9487,7 +9635,7 @@ var BridgeCore = class {
9487
9635
  logGenerationSummary(files) {
9488
9636
  const fileTypes = files.reduce(
9489
9637
  (acc, file) => {
9490
- acc[file.type] = (acc[file.type] || 0) + 1;
9638
+ acc[file.type] = (acc[file.type] ?? 0) + 1;
9491
9639
  return acc;
9492
9640
  },
9493
9641
  {}
@@ -9506,9 +9654,24 @@ var BridgeCore = class {
9506
9654
  });
9507
9655
  }
9508
9656
  }
9509
- // Public API methods
9657
+ /**
9658
+ * Validates an OpenAPI schema without generating code
9659
+ *
9660
+ * Useful for checking schema validity before running full generation.
9661
+ *
9662
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9663
+ * @returns Promise resolving to true if schema is valid, false otherwise
9664
+ *
9665
+ * @example
9666
+ * ```typescript
9667
+ * const isValid = await bridge.validateSchema('https://api.example.com/openapi.json');
9668
+ * if (isValid) {
9669
+ * await bridge.generate(config);
9670
+ * }
9671
+ * ```
9672
+ */
9510
9673
  async validateSchema(schemaUrl) {
9511
- if (!schemaUrl?.trim()) {
9674
+ if (!schemaUrl.trim()) {
9512
9675
  this.logger.warn("Schema URL is empty or invalid");
9513
9676
  return false;
9514
9677
  }
@@ -9522,8 +9685,25 @@ var BridgeCore = class {
9522
9685
  return false;
9523
9686
  }
9524
9687
  }
9688
+ /**
9689
+ * Retrieves metadata from an OpenAPI schema
9690
+ *
9691
+ * Extracts schema metadata including title, version, description, and other
9692
+ * OpenAPI document information without parsing the entire schema.
9693
+ *
9694
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9695
+ * @returns Promise resolving to schema metadata
9696
+ * @throws {BridgeError} When schema URL is invalid
9697
+ * @throws {SchemaParseError} When schema cannot be parsed
9698
+ *
9699
+ * @example
9700
+ * ```typescript
9701
+ * const metadata = await bridge.getSchemaInfo('https://api.example.com/openapi.json');
9702
+ * console.log(`Schema: ${metadata.title} v${metadata.version}`);
9703
+ * ```
9704
+ */
9525
9705
  async getSchemaInfo(schemaUrl) {
9526
- if (!schemaUrl?.trim()) {
9706
+ if (!schemaUrl.trim()) {
9527
9707
  throw new BridgeError("Schema URL is required and cannot be empty", "INVALID_SCHEMA_URL");
9528
9708
  }
9529
9709
  try {
@@ -9535,6 +9715,18 @@ var BridgeCore = class {
9535
9715
  throw new SchemaParseError(`Failed to parse schema: ${errorMessage}`, schemaUrl);
9536
9716
  }
9537
9717
  }
9718
+ /**
9719
+ * Clears the internal schema cache
9720
+ *
9721
+ * Useful when you need to force re-fetching of schemas or during development.
9722
+ * The cache is automatically managed, but this method allows manual invalidation.
9723
+ *
9724
+ * @example
9725
+ * ```typescript
9726
+ * bridge.clearCache();
9727
+ * await bridge.generate(config); // Will fetch fresh schema
9728
+ * ```
9729
+ */
9538
9730
  clearCache() {
9539
9731
  try {
9540
9732
  this.schemaParser.clearCache();
@@ -9633,7 +9825,7 @@ var ConfigurationLoader = class {
9633
9825
  }
9634
9826
  async load(configPath) {
9635
9827
  if (!configPath?.trim()) {
9636
- configPath = "mulink.config.json";
9828
+ configPath = "link.config.json";
9637
9829
  }
9638
9830
  const resolvedPath = path2__default.default.resolve(process.cwd(), configPath);
9639
9831
  try {
@@ -9699,7 +9891,7 @@ ${errorMessages}`,
9699
9891
  );
9700
9892
  }
9701
9893
  }
9702
- async createDefault(framework = "nextjs") {
9894
+ createDefault(framework = "nextjs") {
9703
9895
  const defaultConfig = {
9704
9896
  schema: "https://petstore3.swagger.io/api/v3/openapi.json",
9705
9897
  outputDir: "src/generated",
@@ -9744,7 +9936,7 @@ ${errorMessages}`,
9744
9936
  }
9745
9937
  async save(config, configPath) {
9746
9938
  if (!configPath?.trim()) {
9747
- configPath = "mulink.config.json";
9939
+ configPath = "link.config.json";
9748
9940
  }
9749
9941
  const resolvedPath = path2__default.default.resolve(process.cwd(), configPath);
9750
9942
  try {
@@ -9802,5 +9994,5 @@ exports.VersionChecker = VersionChecker;
9802
9994
  exports.__name = __name;
9803
9995
  exports.checkAndNotifyUpdates = checkAndNotifyUpdates;
9804
9996
  exports.createBridgeVersionChecker = createBridgeVersionChecker;
9805
- //# sourceMappingURL=chunk-RGFU7SMN.cjs.map
9806
- //# sourceMappingURL=chunk-RGFU7SMN.cjs.map
9997
+ //# sourceMappingURL=chunk-NC747MZJ.cjs.map
9998
+ //# sourceMappingURL=chunk-NC747MZJ.cjs.map