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.
@@ -7,17 +7,48 @@ var __defProp = Object.defineProperty;
7
7
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
8
 
9
9
  // src/core/types.ts
10
- var BridgeError = class extends Error {
10
+ var BridgeError = class _BridgeError extends Error {
11
11
  static {
12
12
  __name(this, "BridgeError");
13
13
  }
14
14
  code;
15
15
  details;
16
- constructor(message, code, details) {
17
- super(message);
16
+ timestamp;
17
+ cause;
18
+ constructor(message, code, details, cause) {
19
+ super(message, { cause });
18
20
  this.name = "BridgeError";
19
21
  this.code = code;
20
22
  this.details = details;
23
+ this.timestamp = Date.now();
24
+ this.cause = cause;
25
+ if (Error.captureStackTrace) {
26
+ Error.captureStackTrace(this, _BridgeError);
27
+ }
28
+ }
29
+ /**
30
+ * Converts the error to a JSON-serializable object
31
+ *
32
+ * @returns JSON representation of the error
33
+ */
34
+ toJSON() {
35
+ return {
36
+ name: this.name,
37
+ message: this.message,
38
+ code: this.code,
39
+ details: this.details,
40
+ timestamp: this.timestamp,
41
+ stack: this.stack,
42
+ cause: this.cause?.message
43
+ };
44
+ }
45
+ /**
46
+ * Checks if this error is retryable
47
+ *
48
+ * @returns True if the operation that caused this error can be retried
49
+ */
50
+ isRetryable() {
51
+ return false;
21
52
  }
22
53
  };
23
54
  var ValidationError = class extends BridgeError {
@@ -25,28 +56,42 @@ var ValidationError = class extends BridgeError {
25
56
  __name(this, "ValidationError");
26
57
  }
27
58
  errors;
28
- constructor(message, errors) {
29
- super(message, "VALIDATION_ERROR", errors);
59
+ constructor(message, errors, cause) {
60
+ super(message, "VALIDATION_ERROR", errors, cause);
30
61
  this.errors = errors;
31
62
  }
63
+ /**
64
+ * Gets formatted validation error messages
65
+ *
66
+ * @returns Array of formatted error messages
67
+ */
68
+ getFormattedErrors() {
69
+ return this.errors.errors.map((err) => {
70
+ const path3 = err.path.join(".");
71
+ return `${path3}: ${err.message}`;
72
+ });
73
+ }
32
74
  };
33
75
  var SchemaParseError = class extends BridgeError {
34
76
  static {
35
77
  __name(this, "SchemaParseError");
36
78
  }
37
79
  schemaUrl;
38
- constructor(message, schemaUrl) {
39
- super(message, "SCHEMA_PARSE_ERROR", { schemaUrl });
80
+ constructor(message, schemaUrl, cause) {
81
+ super(message, "SCHEMA_PARSE_ERROR", { schemaUrl }, cause);
40
82
  this.schemaUrl = schemaUrl;
41
83
  }
84
+ isRetryable() {
85
+ return this.cause instanceof TypeError && this.cause.message.includes("fetch");
86
+ }
42
87
  };
43
88
  var GenerationError = class extends BridgeError {
44
89
  static {
45
90
  __name(this, "GenerationError");
46
91
  }
47
92
  file;
48
- constructor(message, file) {
49
- super(message, "GENERATION_ERROR", { file });
93
+ constructor(message, file, cause) {
94
+ super(message, "GENERATION_ERROR", { file }, cause);
50
95
  this.file = file;
51
96
  }
52
97
  };
@@ -134,8 +179,8 @@ var BridgeLogger = class {
134
179
  if (!this.options.colors || !process.stdout.isTTY) {
135
180
  console.log(message);
136
181
  return {
137
- succeed: /* @__PURE__ */ __name((msg) => console.log(colorize(`\u2713 ${msg || message || ""}`, "green")), "succeed"),
138
- fail: /* @__PURE__ */ __name((msg) => console.error(colorize(`\u2717 ${msg || message || ""}`, "red")), "fail"),
182
+ succeed: /* @__PURE__ */ __name((msg) => console.log(colorize(`\u2713 ${msg ?? message}`, "green")), "succeed"),
183
+ fail: /* @__PURE__ */ __name((msg) => console.error(colorize(`\u2717 ${msg ?? message}`, "red")), "fail"),
139
184
  stop: /* @__PURE__ */ __name(() => {
140
185
  }, "stop")
141
186
  };
@@ -143,17 +188,20 @@ var BridgeLogger = class {
143
188
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
144
189
  let i = 0;
145
190
  const interval = setInterval(() => {
146
- process.stdout.write(`\r${colorize(frames[i++ % frames.length], "cyan")} ${message}`);
191
+ const frame = frames[i++ % frames.length];
192
+ if (frame) {
193
+ process.stdout.write(`\r${colorize(frame, "cyan")} ${message}`);
194
+ }
147
195
  }, 100);
148
196
  return {
149
197
  succeed: /* @__PURE__ */ __name((msg) => {
150
198
  clearInterval(interval);
151
- process.stdout.write(`\r${colorize("\u2713", "green")} ${msg || message || ""}
199
+ process.stdout.write(`\r${colorize("\u2713", "green")} ${msg ?? message}
152
200
  `);
153
201
  }, "succeed"),
154
202
  fail: /* @__PURE__ */ __name((msg) => {
155
203
  clearInterval(interval);
156
- process.stdout.write(`\r${colorize("\u2717", "red")} ${msg || message || ""}
204
+ process.stdout.write(`\r${colorize("\u2717", "red")} ${msg ?? message}
157
205
  `);
158
206
  }, "fail"),
159
207
  stop: /* @__PURE__ */ __name(() => {
@@ -176,7 +224,7 @@ var VersionChecker = class {
176
224
  constructor(packageName, currentVersion, logger) {
177
225
  this.packageName = packageName;
178
226
  this.currentVersion = currentVersion;
179
- this.logger = logger || new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
227
+ this.logger = logger ?? new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
180
228
  }
181
229
  /**
182
230
  * Check if a new version is available
@@ -231,7 +279,7 @@ var VersionChecker = class {
231
279
  /**
232
280
  * Get the appropriate upgrade command for the detected package manager
233
281
  */
234
- getUpgradeCommand(versionInfo) {
282
+ getUpgradeCommand(_versionInfo) {
235
283
  const packageManager = this.detectPackageManager();
236
284
  switch (packageManager) {
237
285
  case "yarn":
@@ -305,8 +353,8 @@ var VersionChecker = class {
305
353
  const currentParts = this.parseVersion(current);
306
354
  const latestParts = this.parseVersion(latest);
307
355
  for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
308
- const currentPart = currentParts[i] || 0;
309
- const latestPart = latestParts[i] || 0;
356
+ const currentPart = currentParts[i] ?? 0;
357
+ const latestPart = latestParts[i] ?? 0;
310
358
  if (latestPart > currentPart) {
311
359
  return true;
312
360
  } else if (latestPart < currentPart) {
@@ -380,7 +428,7 @@ function createBridgeVersionChecker(logger) {
380
428
  if (existsSync(pkgPath)) {
381
429
  const pkgRaw = readFileSync(pkgPath, { encoding: "utf-8" });
382
430
  const pkg = JSON.parse(pkgRaw);
383
- if (pkg && pkg.version) {
431
+ if (pkg.version) {
384
432
  currentVersion = pkg.version;
385
433
  }
386
434
  } else {
@@ -388,13 +436,13 @@ function createBridgeVersionChecker(logger) {
388
436
  if (existsSync(cwdPkg)) {
389
437
  const pkgRaw = readFileSync(cwdPkg, { encoding: "utf-8" });
390
438
  const pkg = JSON.parse(pkgRaw);
391
- if (pkg && pkg.version) {
439
+ if (pkg.version) {
392
440
  currentVersion = pkg.version;
393
441
  }
394
442
  }
395
443
  }
396
444
  } catch (err) {
397
- const l = logger || new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
445
+ const l = logger ?? new BridgeLogger({ prefix: "\u{1F50D} Version Check" });
398
446
  l.debug("Failed to read package.json for current version, falling back to default", err);
399
447
  }
400
448
  return new VersionChecker(packageName, currentVersion, logger);
@@ -432,7 +480,7 @@ var OpenApiSchemaParser = class {
432
480
  async fetchSchema(schemaUrl) {
433
481
  const versionChecker = createBridgeVersionChecker();
434
482
  const currentVersion = versionChecker.getCurrentVersion();
435
- if (!schemaUrl?.trim()) {
483
+ if (!schemaUrl.trim()) {
436
484
  throw new SchemaParseError("Schema URL is required and cannot be empty", schemaUrl);
437
485
  }
438
486
  if (schemaUrl.startsWith("http")) {
@@ -453,7 +501,7 @@ var OpenApiSchemaParser = class {
453
501
  schemaUrl
454
502
  );
455
503
  }
456
- const contentType = response.headers.get("content-type") || "";
504
+ const contentType = response.headers.get("content-type") ?? "";
457
505
  if (!contentType.includes("application/json") && !contentType.includes("application/yaml") && !contentType.includes("text/yaml")) {
458
506
  throw new SchemaParseError(
459
507
  `Unsupported content type: ${contentType}. Expected JSON or YAML.`,
@@ -483,10 +531,10 @@ var OpenApiSchemaParser = class {
483
531
  );
484
532
  }
485
533
  }
486
- async parseDocument(document) {
534
+ parseDocument(document) {
487
535
  const version = this.detectVersion(document);
488
536
  const normalizedDocument = this.normalizeDocument(document, version);
489
- return {
537
+ return Promise.resolve({
490
538
  version,
491
539
  document: normalizedDocument,
492
540
  openApiSpec: normalizedDocument,
@@ -495,7 +543,7 @@ var OpenApiSchemaParser = class {
495
543
  security: this.extractSecurity(normalizedDocument),
496
544
  servers: this.extractServers(normalizedDocument, document),
497
545
  metadata: this.extractMetadata(normalizedDocument)
498
- };
546
+ });
499
547
  }
500
548
  detectVersion(document) {
501
549
  if (!document || typeof document !== "object") {
@@ -530,7 +578,7 @@ var OpenApiSchemaParser = class {
530
578
  info: v2Doc.info,
531
579
  servers: v2Doc.host ? [
532
580
  {
533
- url: `${v2Doc.schemes?.[0] || "https"}://${v2Doc.host}${v2Doc.basePath || ""}`
581
+ url: `${v2Doc.schemes?.[0] ?? "https"}://${v2Doc.host}${v2Doc.basePath ?? ""}`
534
582
  }
535
583
  ] : [],
536
584
  paths: {},
@@ -675,20 +723,20 @@ var OpenApiSchemaParser = class {
675
723
  flows: {
676
724
  implicit: v2Scheme.flow === "implicit" ? {
677
725
  authorizationUrl: v2Scheme.authorizationUrl,
678
- scopes: v2Scheme.scopes || {}
726
+ scopes: v2Scheme.scopes ?? {}
679
727
  } : void 0,
680
728
  password: v2Scheme.flow === "password" ? {
681
729
  tokenUrl: v2Scheme.tokenUrl,
682
- scopes: v2Scheme.scopes || {}
730
+ scopes: v2Scheme.scopes ?? {}
683
731
  } : void 0,
684
732
  clientCredentials: v2Scheme.flow === "application" ? {
685
733
  tokenUrl: v2Scheme.tokenUrl,
686
- scopes: v2Scheme.scopes || {}
734
+ scopes: v2Scheme.scopes ?? {}
687
735
  } : void 0,
688
736
  authorizationCode: v2Scheme.flow === "accessCode" ? {
689
737
  authorizationUrl: v2Scheme.authorizationUrl,
690
738
  tokenUrl: v2Scheme.tokenUrl,
691
- scopes: v2Scheme.scopes || {}
739
+ scopes: v2Scheme.scopes ?? {}
692
740
  } : void 0
693
741
  }
694
742
  };
@@ -714,18 +762,18 @@ var OpenApiSchemaParser = class {
714
762
  const operation = pathItem[method.toLowerCase()];
715
763
  if (!operation) continue;
716
764
  const endpoint = {
717
- id: operation.operationId || `${method.toLowerCase()}_${path3.replace(/[^a-zA-Z0-9]/g, "_")}`,
765
+ id: operation.operationId ?? `${method.toLowerCase()}_${path3.replace(/[^a-zA-Z0-9]/g, "_")}`,
718
766
  path: path3,
719
767
  method,
720
768
  operationId: operation.operationId,
721
769
  summary: operation.summary,
722
770
  description: operation.description,
723
- tags: operation.tags || [],
771
+ tags: operation.tags ?? [],
724
772
  parameters: this.extractParameters(operation.parameters, pathItem.parameters, document),
725
773
  requestBody: this.extractRequestBody(operation.requestBody, document),
726
774
  responses: this.extractResponses(operation.responses, document),
727
- security: operation.security || [],
728
- deprecated: operation.deprecated || false,
775
+ security: operation.security ?? [],
776
+ deprecated: operation.deprecated ?? false,
729
777
  metadata: this.extractEndpointMetadata(operation)
730
778
  };
731
779
  endpoints.push(endpoint);
@@ -735,7 +783,7 @@ var OpenApiSchemaParser = class {
735
783
  }
736
784
  extractParameters(operationParams, pathParams, document) {
737
785
  const parameters = [];
738
- const allParams = [...pathParams || [], ...operationParams || []];
786
+ const allParams = [...pathParams ?? [], ...operationParams ?? []];
739
787
  for (const param of allParams) {
740
788
  if (!param) continue;
741
789
  if ("$ref" in param) {
@@ -745,11 +793,11 @@ var OpenApiSchemaParser = class {
745
793
  const parameter = {
746
794
  name: param.name,
747
795
  in: param.in,
748
- required: param.required || param.in === "path",
796
+ required: param.required ?? param.in === "path",
749
797
  schema: this.convertSchemaToZod(param.schema, document),
750
798
  description: param.description,
751
799
  example: param.example,
752
- deprecated: param.deprecated || false
800
+ deprecated: param.deprecated ?? false
753
801
  };
754
802
  parameters.push(parameter);
755
803
  }
@@ -768,7 +816,7 @@ var OpenApiSchemaParser = class {
768
816
  }
769
817
  }
770
818
  return {
771
- required: requestBody.required || false,
819
+ required: requestBody.required ?? false,
772
820
  description: requestBody.description,
773
821
  content
774
822
  };
@@ -808,7 +856,7 @@ var OpenApiSchemaParser = class {
808
856
  schema: this.convertSchemaToZod(schema, document),
809
857
  description: schema.description,
810
858
  example: schema.example,
811
- deprecated: schema.deprecated || false
859
+ deprecated: schema.deprecated ?? false
812
860
  });
813
861
  }
814
862
  }
@@ -842,7 +890,7 @@ var OpenApiSchemaParser = class {
842
890
  const v2Doc = originalDoc;
843
891
  return [
844
892
  {
845
- url: `${v2Doc.schemes?.[0] || "https"}://${v2Doc.host}${v2Doc.basePath || ""}`,
893
+ url: `${v2Doc.schemes?.[0] ?? "https"}://${v2Doc.host}${v2Doc.basePath ?? ""}`,
846
894
  description: "Converted from Swagger 2.0"
847
895
  }
848
896
  ];
@@ -862,9 +910,9 @@ var OpenApiSchemaParser = class {
862
910
  }
863
911
  extractEndpointMetadata(operation) {
864
912
  return {
865
- requiresAuth: operation.security && operation.security.length > 0 || false,
913
+ requiresAuth: (operation.security?.length ?? 0) > 0,
866
914
  cacheStrategy: "default",
867
- revalidationTags: operation.tags || [],
915
+ revalidationTags: operation.tags ?? [],
868
916
  streaming: false,
869
917
  fileUpload: this.hasFileUpload(operation)
870
918
  };
@@ -872,7 +920,7 @@ var OpenApiSchemaParser = class {
872
920
  hasFileUpload(operation) {
873
921
  if (!operation.requestBody || "$ref" in operation.requestBody) return false;
874
922
  const content = operation.requestBody.content;
875
- return Object.keys(content || {}).some(
923
+ return Object.keys(content ?? {}).some(
876
924
  (mediaType) => mediaType.includes("multipart/form-data") || mediaType.includes("application/octet-stream")
877
925
  );
878
926
  }
@@ -960,7 +1008,7 @@ var OpenApiSchemaParser = class {
960
1008
  case "object":
961
1009
  if (schema.properties) {
962
1010
  const shape = {};
963
- const required = schema.required || [];
1011
+ const required = schema.required ?? [];
964
1012
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
965
1013
  let propZodSchema = this.convertSchemaToZod(propSchema, document);
966
1014
  if (!required.includes(propName)) {
@@ -992,7 +1040,7 @@ var ApiClientGenerator = class {
992
1040
  * Generate import paths based on configuration
993
1041
  */
994
1042
  buildImportPath(relativePath) {
995
- const outputDirectory = this.configuration.outputDir || "generated";
1043
+ const outputDirectory = this.configuration.outputDir ?? "generated";
996
1044
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
997
1045
  let importBasePath = outputDirectory;
998
1046
  if (importBasePath.startsWith("src/")) {
@@ -1000,24 +1048,24 @@ var ApiClientGenerator = class {
1000
1048
  }
1001
1049
  return `@/${importBasePath}/${cleanPath}`;
1002
1050
  }
1003
- async generate(context) {
1051
+ generate(context) {
1004
1052
  const { schema } = context;
1005
1053
  const generatedFiles = [];
1006
1054
  generatedFiles.push(this.generateEnhancedBaseClient());
1007
1055
  generatedFiles.push(...this.generateEndpointClients(schema.endpoints));
1008
1056
  generatedFiles.push(this.generateMainClient(schema.endpoints));
1009
1057
  generatedFiles.push(this.generateClientUtilities());
1010
- return generatedFiles;
1058
+ return Promise.resolve(generatedFiles);
1011
1059
  }
1012
1060
  generateEnhancedBaseClient() {
1013
1061
  const { api, auth } = this.configuration;
1014
1062
  const authUtilsImport = this.buildImportPath("auth/utils");
1015
- const authPath = auth?.authPath || "@/lib/auth";
1016
- const tokenGetter = auth?.tokenGetter || "auth";
1063
+ const authPath = auth?.authPath ?? "@/lib/auth";
1064
+ const tokenGetter = auth?.tokenGetter ?? "auth";
1017
1065
  const content = `/**
1018
1066
  * The HTTP client is automatically created by "mulink"
1019
1067
  *
1020
- * Next.js 16.0.1 Best Practices:
1068
+ * Next.js 16.0.7 Best Practices:
1021
1069
  * - Proper separation of client/server code
1022
1070
  * - Dynamic imports for server-only modules
1023
1071
  * - Works in both Server Components and Client Components
@@ -1028,7 +1076,7 @@ import { cache } from 'react'
1028
1076
 
1029
1077
  /**
1030
1078
  * Server-only modules interface
1031
- * Next.js 16.0.1: These modules are only available on the server
1079
+ * Next.js 16.0.7: These modules are only available on the server
1032
1080
  * We use dynamic imports to avoid bundling them in the client
1033
1081
  */
1034
1082
  type NextHeadersModule = typeof import('next/headers')
@@ -1052,7 +1100,7 @@ function toMutableHeaders(source: NextReadonlyHeaders) {
1052
1100
 
1053
1101
  /**
1054
1102
  * Lazy load server-only modules only when needed (server-side)
1055
- * Next.js 16.0.1: This ensures server-only code is not bundled in the client
1103
+ * Next.js 16.0.7: This ensures server-only code is not bundled in the client
1056
1104
  *
1057
1105
  * @returns Server-only modules or undefined if on client-side
1058
1106
  */
@@ -1060,7 +1108,7 @@ async function getServerModules() {
1060
1108
  if (serverOnlyModules !== null) return serverOnlyModules
1061
1109
 
1062
1110
  // Only attempt to import on server-side
1063
- // Next.js 16.0.1: typeof window check ensures we're on the server
1111
+ // Next.js 16.0.7: typeof window check ensures we're on the server
1064
1112
  if (typeof window === 'undefined') {
1065
1113
  try {
1066
1114
  const headersModule = await import('next/headers').catch(() => null)
@@ -1286,11 +1334,11 @@ export class BaseApiClient {
1286
1334
  private readonly middleware: RequestMiddleware[] = []
1287
1335
 
1288
1336
  constructor() {
1289
- this.baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.API_BASE_URL || '${api?.baseUrl || "http://localhost:3000/api"}'
1290
- this.defaultTimeout = ${api?.timeout || 3e4}
1291
- this.defaultRetries = ${api?.retries || 3}
1292
- this.defaultHeaders = ${JSON.stringify(api?.headers || {}, null, 6)}
1293
- this.defaultUserAgent = '${api?.userAgent || "Mulink-Client/3.4.5"}'
1337
+ this.baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.API_BASE_URL || '${api.baseUrl || "http://localhost:3000/api"}'
1338
+ this.defaultTimeout = ${api.timeout || 3e4}
1339
+ this.defaultRetries = ${api.retries || 3}
1340
+ this.defaultHeaders = ${JSON.stringify(api.headers || {}, null, 6)}
1341
+ this.defaultUserAgent = '${api.userAgent || "Mulink-Client/3.4.5"}'
1294
1342
 
1295
1343
  // Add default middleware
1296
1344
  this.addMiddleware({
@@ -1464,16 +1512,26 @@ export class BaseApiClient {
1464
1512
  }
1465
1513
 
1466
1514
  // Add query parameters with proper encoding
1515
+ // Filter out undefined, null, empty strings, and empty objects to prevent 422 errors
1467
1516
  const searchParams = new URLSearchParams()
1468
1517
  for (const [key, value] of Object.entries(queryParameters)) {
1469
- if (value !== undefined && value !== null && value !== '') {
1470
- if (Array.isArray(value)) {
1471
- value.forEach(v => searchParams.append(key, String(v)))
1472
- } else if (typeof value === 'object') {
1473
- searchParams.append(key, JSON.stringify(value))
1474
- } else {
1475
- searchParams.append(key, String(value))
1476
- }
1518
+ // Skip undefined, null, and empty strings
1519
+ if (value === undefined || value === null || value === '') {
1520
+ continue
1521
+ }
1522
+
1523
+ // Skip empty objects (like {})
1524
+ if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
1525
+ continue
1526
+ }
1527
+
1528
+ if (Array.isArray(value)) {
1529
+ value.forEach(v => searchParams.append(key, String(v)))
1530
+ } else if (typeof value === 'object') {
1531
+ // Only serialize non-empty objects
1532
+ searchParams.append(key, JSON.stringify(value))
1533
+ } else {
1534
+ searchParams.append(key, String(value))
1477
1535
  }
1478
1536
  }
1479
1537
 
@@ -1646,7 +1704,7 @@ export class BaseApiClient {
1646
1704
  controller.abort()
1647
1705
  }, timeout)
1648
1706
 
1649
- // Next.js 16.0.1: Build fetch options with cache tags and connection
1707
+ // Next.js 16.0.7: Build fetch options with cache tags and connection
1650
1708
  // Only include next options if we're on the server (Next.js App Router)
1651
1709
  const fetchInit: RequestInit & { next?: { tags?: string[]; revalidate?: number | false; connection?: string } } = {
1652
1710
  ...requestConfig,
@@ -1654,7 +1712,7 @@ export class BaseApiClient {
1654
1712
  }
1655
1713
 
1656
1714
  // Add Next.js-specific options only if we have cache tags, revalidate, or connection
1657
- // Next.js 16.0.1: Enhanced cache tag support with updateTag
1715
+ // Next.js 16.0.7: Enhanced cache tag support with updateTag
1658
1716
  if (cacheTags && cacheTags.length > 0 || revalidate !== undefined || connection) {
1659
1717
  fetchInit.next = {}
1660
1718
 
@@ -1666,7 +1724,7 @@ export class BaseApiClient {
1666
1724
  fetchInit.next.revalidate = revalidate === false ? false : revalidate
1667
1725
  }
1668
1726
 
1669
- // Next.js 16.0.1: Connection keep-alive for persistent connections
1727
+ // Next.js 16.0.7: Connection keep-alive for persistent connections
1670
1728
  if (connection) {
1671
1729
  fetchInit.next.connection = connection
1672
1730
  }
@@ -1674,7 +1732,7 @@ export class BaseApiClient {
1674
1732
 
1675
1733
  const response = await fetch(url, fetchInit)
1676
1734
 
1677
- // Next.js 16.0.1: Update cache tags dynamically using updateTag from next/cache
1735
+ // Next.js 16.0.7: Update cache tags dynamically using updateTag from next/cache
1678
1736
  // This allows for granular cache invalidation
1679
1737
  if (cacheTags && cacheTags.length > 0) {
1680
1738
  try {
@@ -1938,7 +1996,7 @@ async get<TData>(
1938
1996
  }
1939
1997
  generateClientUtilities() {
1940
1998
  const { api } = this.configuration;
1941
- const errorHandling = api?.errorHandling;
1999
+ const errorHandling = api.errorHandling;
1942
2000
  const enableAuthErrorHandling = errorHandling?.enableAuthErrorHandling !== false;
1943
2001
  const authErrorHandlerPath = errorHandling?.authErrorHandlerPath || "@/lib/auth-error-handler";
1944
2002
  const authErrorMiddlewareCode = enableAuthErrorHandling ? `
@@ -2335,7 +2393,7 @@ ${clientMethods}
2335
2393
  const requestOptionsString = requestOptions.join("\n");
2336
2394
  const methodSignature = parameterTypes.length > 1 ? `options: {
2337
2395
  ${parameterTypes.join("\n ")}
2338
- }` : parameterTypes.length === 1 && parameterTypes[0].includes("config?") ? "options?: { config?: RequestConfiguration }" : `options: { ${parameterTypes.join(", ")} }`;
2396
+ }` : parameterTypes.length === 1 && parameterTypes[0] && parameterTypes[0].includes("config?") ? "options?: { config?: RequestConfiguration }" : `options: { ${parameterTypes.join(", ")} }`;
2339
2397
  if (isQuery) {
2340
2398
  return `${documentation}
2341
2399
  ${methodName} = cache(async (${methodSignature}) => {
@@ -2606,7 +2664,7 @@ var SchemaGenerator = class {
2606
2664
  visiting.add(schemaName);
2607
2665
  const schema = schemaMap.get(schemaName);
2608
2666
  if (schema) {
2609
- const dependencies = dependencyGraph.get(schemaName) || /* @__PURE__ */ new Set();
2667
+ const dependencies = dependencyGraph.get(schemaName) ?? /* @__PURE__ */ new Set();
2610
2668
  for (const dep of dependencies) {
2611
2669
  if (schemaMap.has(dep)) {
2612
2670
  visit(dep);
@@ -2639,13 +2697,13 @@ var SchemaGenerator = class {
2639
2697
  findSchemaDependencies(schema) {
2640
2698
  const dependencies = [];
2641
2699
  const schemaObj = schema.schema;
2642
- if (schemaObj && schemaObj._def) {
2700
+ if (schemaObj?._def) {
2643
2701
  this.extractDependenciesFromZodSchema(schemaObj, dependencies);
2644
2702
  }
2645
2703
  return dependencies;
2646
2704
  }
2647
2705
  extractDependenciesFromZodSchema(zodSchema, dependencies, visited = /* @__PURE__ */ new Set()) {
2648
- if (!zodSchema || !zodSchema._def) return;
2706
+ if (!zodSchema?._def) return;
2649
2707
  const def = zodSchema._def;
2650
2708
  if (def._schemaRef) {
2651
2709
  const refName = def._schemaRef;
@@ -2668,7 +2726,7 @@ var SchemaGenerator = class {
2668
2726
  case "ZodObject":
2669
2727
  if (def.shape) {
2670
2728
  const shape = def.shape();
2671
- for (const [key, value] of Object.entries(shape)) {
2729
+ for (const [_key, value] of Object.entries(shape)) {
2672
2730
  this.extractDependenciesFromZodSchema(value, dependencies, visited);
2673
2731
  }
2674
2732
  }
@@ -2700,7 +2758,7 @@ var SchemaGenerator = class {
2700
2758
  break;
2701
2759
  }
2702
2760
  }
2703
- async generateSchemasFile(context) {
2761
+ generateSchemasFile(context) {
2704
2762
  const { schemas, endpoints } = context.schema;
2705
2763
  const imports = ['import { z } from "zod"'];
2706
2764
  const schemaExports = [];
@@ -2734,7 +2792,7 @@ var SchemaGenerator = class {
2734
2792
 
2735
2793
  ${content}`;
2736
2794
  }
2737
- return {
2795
+ return Promise.resolve({
2738
2796
  path: "schemas/index.ts",
2739
2797
  content,
2740
2798
  type: "typescript",
@@ -2743,7 +2801,7 @@ ${content}`;
2743
2801
  imports: ["zod"],
2744
2802
  dependencies: []
2745
2803
  }
2746
- };
2804
+ });
2747
2805
  }
2748
2806
  generateEndpointSchemas(endpoint) {
2749
2807
  const definitions = [];
@@ -2778,6 +2836,9 @@ ${content}`;
2778
2836
  }
2779
2837
  const exportName = `${operationName}RequestSchema`;
2780
2838
  const primaryContent = endpoint.requestBody.content[0];
2839
+ if (!primaryContent) {
2840
+ throw new Error(`No content found for request body in ${endpoint.method} ${endpoint.path}`);
2841
+ }
2781
2842
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2782
2843
  const definition = [
2783
2844
  `/**`,
@@ -2801,17 +2862,22 @@ ${content}`;
2801
2862
  );
2802
2863
  if (successResponses.length > 0) {
2803
2864
  const successResponse = successResponses[0];
2865
+ if (!successResponse) {
2866
+ return { definitions, exports };
2867
+ }
2804
2868
  let zodSchemaString = "z.void()";
2805
2869
  if (successResponse.content && successResponse.content.length > 0) {
2806
2870
  const primaryContent = successResponse.content[0];
2807
- zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2871
+ if (primaryContent) {
2872
+ zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2873
+ }
2808
2874
  }
2809
2875
  const exportName = `${operationName}ResponseSchema`;
2810
2876
  const definition = [
2811
2877
  `/**`,
2812
2878
  ` * Success response schema for ${endpoint.method} ${endpoint.path}`,
2813
2879
  ` * Status: ${successResponse.statusCode}`,
2814
- ` * ${successResponse.description}`,
2880
+ ` * ${successResponse.description ?? ""}`,
2815
2881
  ` */`,
2816
2882
  `export const ${exportName} = ${zodSchemaString}`,
2817
2883
  "",
@@ -2822,15 +2888,18 @@ ${content}`;
2822
2888
  }
2823
2889
  if (errorResponses.length > 0) {
2824
2890
  const errorResponse = errorResponses[0];
2825
- if (errorResponse.content && errorResponse.content.length > 0) {
2891
+ if (errorResponse?.content && errorResponse.content.length > 0) {
2826
2892
  const exportName = `${operationName}ErrorSchema`;
2827
2893
  const primaryContent = errorResponse.content[0];
2894
+ if (!primaryContent) {
2895
+ return { definitions, exports };
2896
+ }
2828
2897
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2829
2898
  const definition = [
2830
2899
  `/**`,
2831
2900
  ` * Error response schema for ${endpoint.method} ${endpoint.path}`,
2832
2901
  ` * Status: ${errorResponse.statusCode}`,
2833
- ` * ${errorResponse.description}`,
2902
+ ` * ${errorResponse.description ?? ""}`,
2834
2903
  ` */`,
2835
2904
  `export const ${exportName} = ${zodSchemaString}`,
2836
2905
  "",
@@ -2921,8 +2990,8 @@ ${schemaProperties.join(",\n")}
2921
2990
  };
2922
2991
  }
2923
2992
  zodSchemaToString(schema, context) {
2924
- if (!schema || !schema._def) {
2925
- if (schema && schema._schemaRef) {
2993
+ if (!schema?._def) {
2994
+ if (schema?._schemaRef) {
2926
2995
  const refName = schema._schemaRef;
2927
2996
  const registeredSchema = this.schemaRegistry.get(refName);
2928
2997
  if (registeredSchema) {
@@ -3090,15 +3159,21 @@ export const errorMessages = {
3090
3159
  const assignments = line.match(/(\w+)\s*[:=]/g);
3091
3160
  if (assignments) {
3092
3161
  assignments.forEach((match) => {
3093
- const identifier = match.split(/[:=]/)[0].trim();
3094
- usedIdentifiers.add(identifier);
3162
+ const parts = match.split(/[:=]/);
3163
+ if (parts[0]) {
3164
+ const identifier = parts[0].trim();
3165
+ usedIdentifiers.add(identifier);
3166
+ }
3095
3167
  });
3096
3168
  }
3097
3169
  const functionCalls = line.match(/(\w+)\s*\(/g);
3098
3170
  if (functionCalls) {
3099
3171
  functionCalls.forEach((match) => {
3100
- const identifier = match.split("(")[0].trim();
3101
- usedIdentifiers.add(identifier);
3172
+ const parts = match.split("(");
3173
+ if (parts[0]) {
3174
+ const identifier = parts[0].trim();
3175
+ usedIdentifiers.add(identifier);
3176
+ }
3102
3177
  });
3103
3178
  }
3104
3179
  if (line.includes("z.infer")) {
@@ -3116,10 +3191,10 @@ export const errorMessages = {
3116
3191
  continue;
3117
3192
  }
3118
3193
  const importMatch = line.match(/import\s*\{([^}]+)\}/);
3119
- if (importMatch) {
3194
+ if (importMatch?.[1]) {
3120
3195
  const imports = importMatch[1].split(",").map((imp) => imp.trim());
3121
3196
  const usedImports = imports.filter((imp) => usedIdentifiers.has(imp));
3122
- if (usedImports.length > 0) {
3197
+ if (usedImports.length > 0 && importMatch[1]) {
3123
3198
  cleanedLines.push(line.replace(importMatch[1], usedImports.join(", ")));
3124
3199
  } else {
3125
3200
  continue;
@@ -3166,7 +3241,7 @@ var ActionGenerator = class {
3166
3241
  if (!this.documentationEnabled) {
3167
3242
  return "";
3168
3243
  }
3169
- const summary = endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`;
3244
+ const summary = endpoint.summary ?? endpoint.description ?? `${endpoint.method} ${endpoint.path}`;
3170
3245
  return `/**
3171
3246
  * ${summary}
3172
3247
  * @generated from ${endpoint.method} ${endpoint.path}
@@ -3308,7 +3383,7 @@ ${" ".repeat(indent + 2)}error: error instanceof Error ? error.message : 'Unknow
3308
3383
  ${" ".repeat(indent)}})`;
3309
3384
  }
3310
3385
  buildImportPath(relativePath) {
3311
- const outputDirectory = this.configuration.outputDir || "generated";
3386
+ const outputDirectory = this.configuration.outputDir ?? "generated";
3312
3387
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
3313
3388
  let importBasePath = outputDirectory;
3314
3389
  if (importBasePath.startsWith("src/")) {
@@ -3316,7 +3391,7 @@ ${" ".repeat(indent)}})`;
3316
3391
  }
3317
3392
  return `@/${importBasePath}/${cleanPath}`;
3318
3393
  }
3319
- async generate(context) {
3394
+ generate(context) {
3320
3395
  const { schema, config } = context;
3321
3396
  const generatedFiles = [];
3322
3397
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3410,7 +3485,7 @@ ${actions}`;
3410
3485
  dependencies: Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)
3411
3486
  }
3412
3487
  });
3413
- return generatedFiles;
3488
+ return Promise.resolve(generatedFiles);
3414
3489
  }
3415
3490
  getOperationName(endpoint) {
3416
3491
  if (endpoint.operationId) {
@@ -3423,7 +3498,7 @@ ${actions}`;
3423
3498
  const method = this.toPascalCase(endpoint.method.toLowerCase());
3424
3499
  return [...pathParts, method].join("");
3425
3500
  }
3426
- generateOptimizedServerAction(endpoint, config) {
3501
+ generateOptimizedServerAction(endpoint, _config) {
3427
3502
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3428
3503
  const operationName = this.getOperationName(endpoint);
3429
3504
  const hasRequestBody = !!endpoint.requestBody;
@@ -3464,10 +3539,15 @@ ${actions}`;
3464
3539
  parameterProcessing = "";
3465
3540
  requestOptionsParams = "";
3466
3541
  }
3467
- const parsedInputType = hasRequestBody || hasAnyParams ? schemaName.includes("\n") ? `z.infer<typeof z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })>` : `z.infer<typeof ${schemaName}>` : "void";
3542
+ const schemaConstantName = hasRequestBody && hasAnyParams ? `${operationName}InputSchema` : null;
3543
+ const schemaConstantDefinition = schemaConstantName ? `const ${schemaConstantName} = z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })
3544
+
3545
+ ` : "";
3546
+ const parsedInputType = hasRequestBody || hasAnyParams ? schemaConstantName ? `z.infer<typeof ${schemaConstantName}>` : `z.infer<typeof ${schemaName}>` : "void";
3468
3547
  const ctxType = requiresAuth || hasRateLimit ? "{ user?: any; ratelimit?: { remaining: number } }" : "any";
3469
3548
  const ctxDeclaration = requiresAuth || hasRateLimit ? `ctx: ${ctxType}` : "ctx?: any";
3470
- const actionArgsType = schemaName.includes("\n") ? `{ parsedInput: z.infer<typeof z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })>; ${ctxDeclaration} }` : `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
3549
+ const actionArgsType = schemaConstantName ? `{ parsedInput: z.infer<typeof ${schemaConstantName}>; ${ctxDeclaration} }` : `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
3550
+ const actionArgsTypeForTemplate = actionArgsType.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
3471
3551
  const clientName = requiresAuth || hasRateLimit ? "authActionClient" : "actionClientWithMeta";
3472
3552
  const rateLimitCode = hasRateLimit ? `
3473
3553
  ${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await getClientInfo()
@@ -3490,15 +3570,15 @@ ${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await get
3490
3570
  endpoint,
3491
3571
  "React cache, input validation, error handling"
3492
3572
  );
3493
- return `${docBlock}export const ${actionName} = cache(
3573
+ return `${docBlock}${schemaConstantDefinition}export const ${actionName} = cache(
3494
3574
  ${clientName}
3495
3575
  .metadata({
3496
3576
  name: "${kebabActionName}",
3497
3577
  requiresAuth: ${requiresAuth}${hasRateLimit ? `,
3498
3578
  rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
3499
3579
  })
3500
- .schema(${schemaName.includes("\n") ? `z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })` : schemaName})
3501
- .action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
3580
+ .schema(${schemaConstantName || schemaName})
3581
+ .action(async ({ parsedInput, ctx }: ${actionArgsTypeForTemplate}) => {
3502
3582
  const startTime = Date.now()
3503
3583
 
3504
3584
  try {${rateLimitCode}${parameterProcessing}
@@ -3557,14 +3637,14 @@ ${this.commentLine("Process file with compression and validation if enabled", 10
3557
3637
  endpoint,
3558
3638
  "Input validation, revalidation, error handling"
3559
3639
  );
3560
- return `${mutationDocBlock}export const ${actionName} = ${clientName}
3640
+ return `${mutationDocBlock}${schemaConstantDefinition}export const ${actionName} = ${clientName}
3561
3641
  .metadata({
3562
3642
  name: "${kebabActionName}",
3563
3643
  requiresAuth: ${requiresAuth}${hasRateLimit ? `,
3564
3644
  rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
3565
3645
  })
3566
- .schema(${schemaName.includes("\n") ? `z.object({ body: ${operationName}RequestSchema, params: ${operationName}ParamsSchema })` : schemaName})
3567
- .action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
3646
+ .schema(${schemaConstantName || schemaName})
3647
+ .action(async ({ parsedInput, ctx }: ${actionArgsTypeForTemplate}) => {
3568
3648
  const startTime = Date.now()
3569
3649
 
3570
3650
  try {${rateLimitCode}${parameterProcessing}${fileUploadCode}
@@ -3692,7 +3772,7 @@ var HookGenerator = class {
3692
3772
  __name(this, "HookGenerator");
3693
3773
  }
3694
3774
  buildImportPath(relativePath) {
3695
- const outputDirectory = this.configuration.outputDir || "generated";
3775
+ const outputDirectory = this.configuration.outputDir ?? "generated";
3696
3776
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
3697
3777
  let importBasePath = outputDirectory;
3698
3778
  if (importBasePath.startsWith("src/")) {
@@ -3700,7 +3780,7 @@ var HookGenerator = class {
3700
3780
  }
3701
3781
  return `@/${importBasePath}/${cleanPath}`;
3702
3782
  }
3703
- async generate(context) {
3783
+ generate(context) {
3704
3784
  const { schema } = context;
3705
3785
  const generatedFiles = [];
3706
3786
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3833,7 +3913,7 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3833
3913
  dependencies: ["./useBridgeQuery", ...Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)]
3834
3914
  }
3835
3915
  });
3836
- return generatedFiles;
3916
+ return Promise.resolve(generatedFiles);
3837
3917
  }
3838
3918
  getOperationName(endpoint) {
3839
3919
  if (endpoint.operationId) {
@@ -3850,44 +3930,65 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3850
3930
  const hookName = toHookName(endpoint.operationId || endpoint.id, true);
3851
3931
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3852
3932
  const operationName = this.getOperationName(endpoint);
3853
- const queryKey = this.generateQueryKey(endpoint);
3854
3933
  const staleTime = this.getStaleTime(endpoint);
3855
3934
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
3856
3935
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
3857
3936
  const hasPageParam = queryParameters.some((param) => param.name === "page");
3858
3937
  const hasSearchParams = endpoint.path.includes("search") || endpoint.path.includes("list");
3859
- endpoint.parameters.length > 0;
3860
- const parameterTypes = [];
3938
+ const pathParamTypes = [];
3939
+ const queryParamTypes = [];
3861
3940
  pathParameters.forEach((param) => {
3862
3941
  const isRequired = param.required ? "" : "?";
3863
3942
  const paramType = this.getTypeFromZodSchema(param.schema);
3864
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
3943
+ pathParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3865
3944
  });
3866
3945
  queryParameters.forEach((param) => {
3867
3946
  const isRequired = param.required ? "" : "?";
3868
3947
  const paramType = this.getTypeFromZodSchema(param.schema);
3869
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
3948
+ queryParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3870
3949
  });
3871
3950
  const returnType = `z.infer<typeof ${operationName}ResponseSchema>`;
3872
3951
  const optionsType = `{ enabled?: boolean; suspense?: boolean; refetchInterval?: number; initialData?: ${returnType} }`;
3873
- const enabledCondition = pathParameters.length > 0 ? `!!${pathParameters.map((parameter) => parameter.name).join(" && !!")}` : "true";
3874
- const actionCallParams = this.buildActionCallParams(endpoint, false);
3952
+ const paramsTypeParts = [];
3953
+ if (pathParameters.length > 0) {
3954
+ paramsTypeParts.push(`path: { ${pathParamTypes.join("; ")} }`);
3955
+ }
3956
+ if (queryParameters.length > 0) {
3957
+ paramsTypeParts.push(`query?: { ${queryParamTypes.join("; ")} }`);
3958
+ }
3959
+ const paramsType = paramsTypeParts.length > 0 ? `{ ${paramsTypeParts.join("; ")} }` : "{}";
3960
+ const enabledCondition = pathParameters.length > 0 && pathParameters[0] ? `!!params?.path?.${pathParameters[0].name}` : "true";
3961
+ const pathParamsBuild = pathParameters.length > 0 ? `{ ${pathParameters.map((p) => `${p.name}: params.path.${p.name}`).join(", ")} }` : "{}";
3962
+ const queryParamsBuild = queryParameters.length > 0 ? `{ ${queryParameters.map((p) => `${p.name}: params?.query?.${p.name}`).join(", ")} }` : "{}";
3875
3963
  if (hasSearchParams) {
3876
- const queryParamObject = queryParameters.length > 0 ? `{ ${queryParameters.map((param) => `${param.name}`).join(", ")} }` : "{}";
3964
+ const queryParamsWithFallback = queryParameters.length > 0 ? `const queryParams = {
3965
+ ${queryParameters.map((param) => {
3966
+ if (param.name === "query") {
3967
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3968
+ } else if (param.name === "limit") {
3969
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3970
+ } else {
3971
+ return `${param.name}: params?.query?.${param.name}`;
3972
+ }
3973
+ }).join(",\n ")}
3974
+ }` : "const queryParams = {}";
3877
3975
  return `/**
3878
3976
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
3879
3977
  * Features: URL state sync, infinite loading, optimistic updates
3978
+ * @param params - Named parameters object with path and query parameters
3979
+ * @param options - Query options
3880
3980
  * @returns useQuery result with data of type ${returnType}
3881
3981
  */
3882
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
3982
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3883
3983
  const [searchParams] = useQueryStates(searchParamsParser)
3884
3984
  const { initialData, ...restOptions } = options ?? {}
3885
3985
 
3886
3986
  return useQuery({
3887
- queryKey: [...${queryKey}, searchParams],
3987
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query, searchParams],
3888
3988
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
3889
3989
  try {
3890
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams }")}))
3990
+ ${queryParamsWithFallback}
3991
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }"}))
3891
3992
  return result
3892
3993
  } catch (error) {
3893
3994
  handleActionError(error)
@@ -3915,29 +4016,33 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
3915
4016
 
3916
4017
  /**
3917
4018
  * Infinite query version for paginated ${endpoint.path}
4019
+ * @param params - Named parameters object with path and query parameters
4020
+ * @param options - Query options
3918
4021
  * @returns useInfiniteQuery result with data of type ${returnType}
3919
4022
  */
3920
- export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4023
+ export function ${hookName.replace("use", "useInfinite")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3921
4024
  const [searchParams] = useQueryStates(searchParamsParser)
3922
4025
  const { initialData, ...restOptions } = options ?? {}
3923
4026
 
3924
4027
  return useInfiniteQuery({
3925
- queryKey: [...${queryKey}, 'infinite', searchParams],
4028
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query, 'infinite', searchParams],
3926
4029
  initialPageParam: 1,
3927
4030
  queryFn: async ({ pageParam = 1, signal }: { pageParam?: number; signal?: AbortSignal }) => {
3928
4031
  try {
3929
- // Build query params object with only the parameters the endpoint expects
3930
- const queryParams: Record<string, any> = {}
3931
- ${queryParameters.map((param) => {
4032
+ const queryParams = {
4033
+ ${queryParameters.map((param) => {
3932
4034
  if (param.name === "page" && hasPageParam) {
3933
- return `queryParams.${param.name} = pageParam`;
4035
+ return `${param.name}: pageParam`;
4036
+ } else if (param.name === "query") {
4037
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3934
4038
  } else if (param.name === "limit") {
3935
- return `queryParams.${param.name} = searchParams.limit`;
4039
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3936
4040
  } else {
3937
- return `if ('${param.name}' in searchParams) queryParams.${param.name} = searchParams.${param.name}`;
4041
+ return `${param.name}: params?.query?.${param.name}`;
4042
+ }
4043
+ }).join(",\n ")}
3938
4044
  }
3939
- }).join("\n ")}
3940
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "queryParams")}))
4045
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }"}))
3941
4046
  return result
3942
4047
  } catch (error) {
3943
4048
  handleActionError(error)
@@ -3979,15 +4084,17 @@ export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.lengt
3979
4084
 
3980
4085
  /**
3981
4086
  * Suspense version for ${endpoint.path} - use in Server Components
4087
+ * @param params - Named parameters object with path and query parameters
4088
+ * @param options - Query options
3982
4089
  * @returns useSuspenseQuery result with data of type ${returnType}
3983
4090
  */
3984
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4091
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3985
4092
  const { initialData, ...restOptions } = options ?? {}
3986
4093
 
3987
4094
  return useSuspenseQuery({
3988
- queryKey: ${queryKey},
4095
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
3989
4096
  queryFn: async () => {
3990
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams}))
4097
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
3991
4098
  return result
3992
4099
  },
3993
4100
  staleTime: ${staleTime},
@@ -3999,16 +4106,18 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
3999
4106
  return `/**
4000
4107
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
4001
4108
  * Features: Smart caching, error handling, type safety
4109
+ * @param params - Named parameters object with path and query parameters
4110
+ * @param options - Query options
4002
4111
  * @returns useQuery result with data of type ${returnType}
4003
4112
  */
4004
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4113
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4005
4114
  const { initialData, ...restOptions } = options ?? {}
4006
4115
 
4007
4116
  return useQuery({
4008
- queryKey: ${queryKey},
4117
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
4009
4118
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
4010
4119
  try {
4011
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4120
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
4012
4121
  return result
4013
4122
  } catch (error) {
4014
4123
  handleActionError(error)
@@ -4036,15 +4145,17 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
4036
4145
 
4037
4146
  /**
4038
4147
  * Suspense version for ${endpoint.path}
4148
+ * @param params - Named parameters object with path and query parameters
4149
+ * @param options - Query options
4039
4150
  * @returns useSuspenseQuery result with data of type ${returnType}
4040
4151
  */
4041
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4152
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4042
4153
  const { initialData, ...restOptions } = options ?? {}
4043
4154
 
4044
4155
  return useSuspenseQuery({
4045
- queryKey: ${queryKey},
4156
+ queryKey: ['${toActionName(endpoint.operationId || endpoint.id)}', ${pathParameters.length > 0 ? "params?.path" : "null"}, params?.query],
4046
4157
  queryFn: async () => {
4047
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4158
+ const result = await resolveActionResult<${returnType}>(${actionName}(${pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : `{ query: ${queryParamsBuild} }`}))
4048
4159
  return result
4049
4160
  },
4050
4161
  staleTime: ${staleTime},
@@ -4159,7 +4270,7 @@ ${invalidationCode}
4159
4270
  * Find related queries that should be invalidated when this mutation runs
4160
4271
  */
4161
4272
  findRelatedQueries(endpoint, context) {
4162
- if (!context?.schema?.endpoints) {
4273
+ if (!context?.schema.endpoints) {
4163
4274
  return [];
4164
4275
  }
4165
4276
  const relatedQueries = [];
@@ -4293,7 +4404,6 @@ ${invalidationCode}
4293
4404
  buildActionCallParams(endpoint, isMutation) {
4294
4405
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
4295
4406
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
4296
- !!endpoint.requestBody;
4297
4407
  if (isMutation) {
4298
4408
  return "variables";
4299
4409
  }
@@ -4374,13 +4484,13 @@ ${invalidationCode}
4374
4484
  import { useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, type UseQueryOptions, type UseMutationOptions, type UseInfiniteQueryOptions, type UseSuspenseQueryOptions, type QueryKey, type QueryFunction } from '@tanstack/react-query'
4375
4485
 
4376
4486
  /**
4377
- * Enhanced React Query wrapper hook with Next.js 16.0.1 optimizations
4487
+ * Enhanced React Query wrapper hook with Next.js 16.0.7 optimizations
4378
4488
  * Provides consistent defaults across all queries following best practices
4379
4489
  *
4380
4490
  * Features:
4381
4491
  * - React Query v5: Uses gcTime instead of cacheTime
4382
4492
  * - React Query v5: Uses placeholderData instead of keepPreviousData
4383
- * - Next.js 16.0.1: Optimized for App Router and Server Components
4493
+ * - Next.js 16.0.7: Optimized for App Router and Server Components
4384
4494
  */
4385
4495
  export function useBridgeQuery<TData = unknown, TError = Error>(
4386
4496
  queryKey: QueryKey,
@@ -4395,14 +4505,8 @@ export function useBridgeQuery<TData = unknown, TError = Error>(
4395
4505
  refetchOnWindowFocus: true,
4396
4506
  refetchOnReconnect: true,
4397
4507
  refetchOnMount: 'always',
4398
- // React Query v5: placeholderData cannot be a function type
4399
- // Use keepPreviousData pattern: return previousData if it exists and is not a function
4400
- placeholderData: (previousData) => {
4401
- if (previousData === undefined) return undefined
4402
- // Type guard: ensure we don't return a function (React Query v5 requirement)
4403
- if (typeof previousData === 'function') return undefined
4404
- return previousData
4405
- } as any,
4508
+ // React Query v5: placeholderData returns previous data if available
4509
+ placeholderData: (previousData) => previousData,
4406
4510
  retry: (failureCount: number, error: TError) => {
4407
4511
  if (error instanceof Error && error.message.includes('4')) return false
4408
4512
  return failureCount < 3
@@ -4415,15 +4519,17 @@ export function useBridgeQuery<TData = unknown, TError = Error>(
4415
4519
  * Enhanced infinite query wrapper
4416
4520
  * React Query v5: Optimized for paginated data with infinite scrolling
4417
4521
  */
4418
- export function useBridgeInfiniteQuery<TData = unknown, TError = Error>(
4522
+ export function useBridgeInfiniteQuery<TData = unknown, TError = Error, TPageParam = number>(
4419
4523
  queryKey: QueryKey,
4420
- queryFn: QueryFunction<TData, QueryKey>,
4421
- options?: Partial<UseInfiniteQueryOptions<TData, TError, TData, QueryKey>>
4524
+ queryFn: QueryFunction<TData, QueryKey, TPageParam>,
4525
+ options?: Partial<UseInfiniteQueryOptions<TData, TError, TData, QueryKey, TPageParam>> & {
4526
+ getNextPageParam?: (lastPage: TData, allPages: TData[]) => TPageParam | undefined
4527
+ }
4422
4528
  ) {
4423
- return useInfiniteQuery<TData, TError>({
4529
+ return useInfiniteQuery<TData, TError, TData, QueryKey, TPageParam>({
4424
4530
  queryKey,
4425
- initialPageParam: 1,
4426
- queryFn: queryFn as QueryFunction<TData, QueryKey>,
4531
+ initialPageParam: 1 as TPageParam,
4532
+ queryFn,
4427
4533
  staleTime: 5 * 60 * 1000,
4428
4534
  gcTime: 10 * 60 * 1000,
4429
4535
  refetchOnWindowFocus: true,
@@ -4433,13 +4539,15 @@ export function useBridgeInfiniteQuery<TData = unknown, TError = Error>(
4433
4539
  if (error instanceof Error && error.message.includes('4')) return false
4434
4540
  return failureCount < 3
4435
4541
  },
4542
+ // Provide default getNextPageParam if not provided
4543
+ getNextPageParam: options?.getNextPageParam || (() => undefined),
4436
4544
  ...options,
4437
4545
  })
4438
4546
  }
4439
4547
 
4440
4548
  /**
4441
4549
  * Enhanced suspense query wrapper
4442
- * Next.js 16.0.1: Optimized for Server Components with Suspense
4550
+ * Next.js 16.0.7: Optimized for Server Components with Suspense
4443
4551
  */
4444
4552
  export function useBridgeSuspenseQuery<TData = unknown, TError = Error>(
4445
4553
  queryKey: QueryKey,
@@ -4495,7 +4603,7 @@ var AuthGenerator = class {
4495
4603
  __name(this, "AuthGenerator");
4496
4604
  }
4497
4605
  buildImportPath(relativePath) {
4498
- const outputDirectory = this.configuration.outputDir || "generated";
4606
+ const outputDirectory = this.configuration.outputDir ?? "generated";
4499
4607
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
4500
4608
  let importBasePath = outputDirectory;
4501
4609
  if (importBasePath.startsWith("src/")) {
@@ -4503,11 +4611,11 @@ var AuthGenerator = class {
4503
4611
  }
4504
4612
  return `@/${importBasePath}/${cleanPath}`;
4505
4613
  }
4506
- async generate(context) {
4614
+ generate(context) {
4507
4615
  const { config, schema } = context;
4508
4616
  const authConfig = config.auth;
4509
4617
  if (!authConfig?.enabled) {
4510
- return [];
4618
+ return Promise.resolve([]);
4511
4619
  }
4512
4620
  const files = [];
4513
4621
  const authEndpoints = this.findAuthEndpoints(schema.endpoints);
@@ -4522,7 +4630,7 @@ var AuthGenerator = class {
4522
4630
  files.push(...this.generateAuthComponents(authEndpoints));
4523
4631
  files.push(this.generateAuthMiddleware());
4524
4632
  files.push(this.generateAuthContext());
4525
- return files;
4633
+ return Promise.resolve(files);
4526
4634
  }
4527
4635
  findAuthEndpoints(endpoints) {
4528
4636
  const authEndpoints = {};
@@ -4555,12 +4663,12 @@ var AuthGenerator = class {
4555
4663
  }
4556
4664
  return userEndpoints;
4557
4665
  }
4558
- generateAuthSchemas(authEndpoints, schema) {
4666
+ generateAuthSchemas(_authEndpoints, _schema) {
4559
4667
  this.buildImportPath("schemas");
4560
- const loginRequestSchema = authEndpoints.login?.requestBody?.content?.find(
4668
+ const loginRequestSchema = _authEndpoints.login?.requestBody?.content?.find(
4561
4669
  (c) => c.type === "application/json"
4562
4670
  )?.schema;
4563
- const loginResponseSchema = authEndpoints.login?.responses?.find(
4671
+ const loginResponseSchema = _authEndpoints.login?.responses?.find(
4564
4672
  (r) => r.statusCode === "200"
4565
4673
  )?.content?.[0]?.schema;
4566
4674
  const content = `import { z } from "zod"
@@ -4661,7 +4769,7 @@ export type Session = z.infer<typeof sessionSchema>`;
4661
4769
  }
4662
4770
  };
4663
4771
  }
4664
- generateAuthTypes(authEndpoints, schema) {
4772
+ generateAuthTypes(_authEndpoints, _schema) {
4665
4773
  const schemasImport = this.buildImportPath("auth/schemas");
4666
4774
  const content = `// Auto-generated authentication types
4667
4775
  import type {
@@ -5207,7 +5315,7 @@ export const useRequireAuth = (redirectTo?: string) => {
5207
5315
  }
5208
5316
  };
5209
5317
  }
5210
- generateAuthActions(authEndpoints, userEndpoints) {
5318
+ generateAuthActions(_authEndpoints, _userEndpoints) {
5211
5319
  const safeActionImport = this.buildImportPath("lib/safe-action");
5212
5320
  const schemasImport = this.buildImportPath("auth/schemas");
5213
5321
  const clientImport = this.buildImportPath("auth/client");
@@ -5439,7 +5547,7 @@ export const useCredentialsLogin = () => {
5439
5547
  }
5440
5548
  };
5441
5549
  }
5442
- generateAuthComponents(authEndpoints) {
5550
+ generateAuthComponents(_authEndpoints) {
5443
5551
  const loginForm = {
5444
5552
  path: "auth/components/login-form.tsx",
5445
5553
  content: `"use client"
@@ -5559,7 +5667,6 @@ export function LoginForm() {
5559
5667
  return [loginForm];
5560
5668
  }
5561
5669
  generateAuthMiddleware() {
5562
- this.buildImportPath("auth/utils");
5563
5670
  const content = `import { NextResponse } from "next/server"
5564
5671
  import type { NextRequest } from "next/server"
5565
5672
 
@@ -5927,9 +6034,10 @@ var SchemaAnalyzer = class {
5927
6034
  }
5928
6035
  if (response.description) {
5929
6036
  const errorMatch = response.description.match(/error[_\s]?code[:\s]+(\w+)/i);
5930
- if (errorMatch) {
5931
- errorCodes.set(errorMatch[1].toLowerCase(), {
5932
- code: errorMatch[1],
6037
+ if (errorMatch?.[1]) {
6038
+ const errorCode = errorMatch[1];
6039
+ errorCodes.set(errorCode.toLowerCase(), {
6040
+ code: errorCode,
5933
6041
  status,
5934
6042
  message: response.description
5935
6043
  });
@@ -6015,7 +6123,7 @@ var SchemaAnalyzer = class {
6015
6123
  const endpoints = {};
6016
6124
  for (const endpoint of this.schema.endpoints) {
6017
6125
  const path3 = endpoint.path.toLowerCase();
6018
- const operationId = (endpoint.operationId || "").toLowerCase();
6126
+ const operationId = (endpoint.operationId ?? "").toLowerCase();
6019
6127
  if ((path3.includes("/auth/login/credentials") || operationId.includes("logincredentials") || operationId.includes("signin")) && endpoint.method === "POST") {
6020
6128
  endpoints.loginCredentials = endpoint;
6021
6129
  } else if ((path3.includes("/auth/login") || operationId.includes("login")) && endpoint.method === "POST" && !endpoints.loginCredentials) {
@@ -6063,12 +6171,12 @@ var SchemaAnalyzer = class {
6063
6171
  extractSessionConfig() {
6064
6172
  const config = {};
6065
6173
  const sessionEndpoints = this.schema.endpoints.filter(
6066
- (e) => e.path.toLowerCase().includes("/session") || (e.operationId || "").toLowerCase().includes("session")
6174
+ (e) => e.path.toLowerCase().includes("/session") || (e.operationId ?? "").toLowerCase().includes("session")
6067
6175
  );
6068
6176
  for (const endpoint of sessionEndpoints) {
6069
6177
  for (const response of endpoint.responses) {
6070
6178
  if (response.headers) {
6071
- for (const [headerName, headerDef] of Object.entries(response.headers)) {
6179
+ for (const [headerName, _headerDef] of Object.entries(response.headers)) {
6072
6180
  if (headerName.toLowerCase().includes("expires") || headerName.toLowerCase().includes("max-age")) ;
6073
6181
  }
6074
6182
  }
@@ -6148,7 +6256,7 @@ var SchemaAnalyzer = class {
6148
6256
  /**
6149
6257
  * Check if OAuth provider is supported
6150
6258
  */
6151
- isOAuthProviderSupported(provider) {
6259
+ isOAuthProviderSupported(_provider) {
6152
6260
  const extractedEndpoints = this.extractAuthEndpoints();
6153
6261
  return !!(extractedEndpoints.oauthAuthorize && extractedEndpoints.oauthCallback);
6154
6262
  }
@@ -6230,7 +6338,7 @@ var SchemaAnalyzer = class {
6230
6338
  errorCodes.set(code.toLowerCase(), {
6231
6339
  code,
6232
6340
  status,
6233
- message: schema.properties?.detail?.default || schema.properties?.message?.default || ""
6341
+ message: schema.properties?.detail?.default ?? schema.properties?.message?.default ?? ""
6234
6342
  });
6235
6343
  });
6236
6344
  }
@@ -6239,9 +6347,10 @@ var SchemaAnalyzer = class {
6239
6347
  const detail = schema.properties.detail;
6240
6348
  if (typeof detail === "string") {
6241
6349
  const codeMatch = detail.match(/(\w+)[_\s]?error/i);
6242
- if (codeMatch) {
6243
- errorCodes.set(codeMatch[1].toLowerCase(), {
6244
- code: codeMatch[1],
6350
+ if (codeMatch?.[1]) {
6351
+ const errorCode = codeMatch[1];
6352
+ errorCodes.set(errorCode.toLowerCase(), {
6353
+ code: errorCode,
6245
6354
  status,
6246
6355
  message: detail
6247
6356
  });
@@ -6253,11 +6362,11 @@ var SchemaAnalyzer = class {
6253
6362
  if (!schema || typeof schema !== "object") return;
6254
6363
  if (schema.properties?.file) {
6255
6364
  const fileSchema = schema.properties.file;
6256
- if (fileSchema.maxSize || fileSchema["x-max-size"]) {
6257
- config.maxSize = fileSchema.maxSize || fileSchema["x-max-size"];
6365
+ if (fileSchema.maxSize ?? fileSchema["x-max-size"]) {
6366
+ config.maxSize = fileSchema.maxSize ?? fileSchema["x-max-size"];
6258
6367
  }
6259
- if (fileSchema.allowedTypes || fileSchema["x-allowed-types"]) {
6260
- config.allowedTypes = fileSchema.allowedTypes || fileSchema["x-allowed-types"];
6368
+ if (fileSchema.allowedTypes ?? fileSchema["x-allowed-types"]) {
6369
+ config.allowedTypes = fileSchema.allowedTypes ?? fileSchema["x-allowed-types"];
6261
6370
  }
6262
6371
  }
6263
6372
  if (schema["x-file-constraints"]) {
@@ -6277,7 +6386,7 @@ var NextAuthGenerator = class {
6277
6386
  analyzer;
6278
6387
  accountStatusPatterns;
6279
6388
  buildImportPath(relativePath) {
6280
- const outputDirectory = this.configuration.outputDir || "generated";
6389
+ const outputDirectory = this.configuration.outputDir ?? "generated";
6281
6390
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
6282
6391
  let importBasePath = outputDirectory;
6283
6392
  if (importBasePath.startsWith("src/")) {
@@ -6285,11 +6394,11 @@ var NextAuthGenerator = class {
6285
6394
  }
6286
6395
  return `@/${importBasePath}/${cleanPath}`;
6287
6396
  }
6288
- async generate(context) {
6397
+ generate(context) {
6289
6398
  const { config, schema } = context;
6290
6399
  const authConfig = config.auth;
6291
6400
  if (!authConfig?.enabled || authConfig.provider !== "next-auth") {
6292
- return [];
6401
+ return Promise.resolve([]);
6293
6402
  }
6294
6403
  this.analyzer = new SchemaAnalyzer(schema);
6295
6404
  this.accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
@@ -6306,7 +6415,7 @@ var NextAuthGenerator = class {
6306
6415
  console.warn("These features will be disabled in generated code.\n");
6307
6416
  }
6308
6417
  const detectedOAuthProviders = this.analyzer.extractOAuthProviders();
6309
- const configuredOAuthProviders = authConfig.oauth?.providers || [];
6418
+ const configuredOAuthProviders = authConfig.oauth?.providers ?? [];
6310
6419
  const validOAuthProviders = configuredOAuthProviders.filter(
6311
6420
  (provider) => this.analyzer.isOAuthProviderSupported(provider)
6312
6421
  );
@@ -6317,7 +6426,7 @@ var NextAuthGenerator = class {
6317
6426
  console.warn(
6318
6427
  `\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.`
6319
6428
  );
6320
- return files;
6429
+ return Promise.resolve(files);
6321
6430
  }
6322
6431
  files.push(this.generateNextAuthConfig(
6323
6432
  extractedEndpoints,
@@ -6330,7 +6439,7 @@ var NextAuthGenerator = class {
6330
6439
  if (hasPasskeys) {
6331
6440
  files.push(this.generatePasskeyUtils(extractedEndpoints));
6332
6441
  }
6333
- return files;
6442
+ return Promise.resolve(files);
6334
6443
  }
6335
6444
  findAuthEndpoints(endpoints) {
6336
6445
  const authEndpoints = {};
@@ -6433,14 +6542,14 @@ var NextAuthGenerator = class {
6433
6542
  }
6434
6543
  generateNextAuthConfig(extractedEndpoints, oauthProviders, hasMFA, hasPasskeys) {
6435
6544
  const authConfig = this.configuration.auth;
6436
- const apiBaseUrl = this.configuration.api?.baseUrl || "http://localhost:8000";
6545
+ const apiBaseUrl = this.configuration.api.baseUrl || "http://localhost:8000";
6437
6546
  const apiUrl = `process.env.NEXT_PUBLIC_API_URL || '${apiBaseUrl}'`;
6438
6547
  const hasGoogle = oauthProviders.includes("google");
6439
6548
  const hasGitHub = oauthProviders.includes("github");
6440
6549
  oauthProviders.includes("discord");
6441
6550
  oauthProviders.includes("microsoft");
6442
6551
  oauthProviders.includes("apple");
6443
- const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses } = this.accountStatusPatterns;
6552
+ const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses: _lockedStatuses } = this.accountStatusPatterns;
6444
6553
  this.analyzer.extractErrorCodes();
6445
6554
  const sessionStrategy = authConfig.session?.strategy || "jwt";
6446
6555
  const sessionMaxAge = authConfig.session?.maxAge || 7 * 24 * 60 * 60;
@@ -6989,7 +7098,7 @@ export async function authenticateWithPasskey(email?: string) {
6989
7098
  }
6990
7099
  };
6991
7100
  }
6992
- generateAuthTypes(authEndpoints, accountStatusPatterns) {
7101
+ generateAuthTypes(_authEndpoints, _accountStatusPatterns) {
6993
7102
  const content = `/**
6994
7103
  * Authentication Types
6995
7104
  * Auto-generated by Mulink
@@ -7060,7 +7169,7 @@ export class AccountInactiveError extends AuthError {
7060
7169
  }
7061
7170
  };
7062
7171
  }
7063
- generateAuthUtils(authEndpoints) {
7172
+ generateAuthUtils(_authEndpoints) {
7064
7173
  const content = `/**
7065
7174
  * Authentication Utilities
7066
7175
  * Auto-generated by Mulink
@@ -7113,7 +7222,7 @@ export async function requireAuth() {
7113
7222
  }
7114
7223
  };
7115
7224
  }
7116
- generatePasskeyUtils(passkeyEndpoints) {
7225
+ generatePasskeyUtils(_passkeyEndpoints) {
7117
7226
  const content = `/**
7118
7227
  * Passkey (WebAuthn) Utilities
7119
7228
  * Auto-generated by Mulink
@@ -7166,7 +7275,7 @@ var MiddlewareGenerator = class {
7166
7275
  __name(this, "MiddlewareGenerator");
7167
7276
  }
7168
7277
  buildImportPath(relativePath) {
7169
- const outputDirectory = this.configuration.outputDir || "generated";
7278
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7170
7279
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7171
7280
  let importBasePath = outputDirectory;
7172
7281
  if (importBasePath.startsWith("src/")) {
@@ -7174,7 +7283,7 @@ var MiddlewareGenerator = class {
7174
7283
  }
7175
7284
  return `@/${importBasePath}/${cleanPath}`;
7176
7285
  }
7177
- async generate(context) {
7286
+ generate(_context) {
7178
7287
  const files = [];
7179
7288
  files.push(this.generateMainMiddleware());
7180
7289
  files.push(this.generateRateLimitMiddleware());
@@ -7182,7 +7291,7 @@ var MiddlewareGenerator = class {
7182
7291
  files.push(this.generateSecurityMiddleware());
7183
7292
  files.push(this.generateLoggingMiddleware());
7184
7293
  files.push(this.generateApiMiddleware());
7185
- return files;
7294
+ return Promise.resolve(files);
7186
7295
  }
7187
7296
  generateMainMiddleware() {
7188
7297
  const authImport = this.buildImportPath("auth/middleware");
@@ -7589,7 +7698,7 @@ var UploadGenerator = class {
7589
7698
  }
7590
7699
  analyzer;
7591
7700
  buildImportPath(relativePath) {
7592
- const outputDirectory = this.configuration.outputDir || "generated";
7701
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7593
7702
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7594
7703
  let importBasePath = outputDirectory;
7595
7704
  if (importBasePath.startsWith("src/")) {
@@ -7597,19 +7706,19 @@ var UploadGenerator = class {
7597
7706
  }
7598
7707
  return `@/${importBasePath}/${cleanPath}`;
7599
7708
  }
7600
- async generate(context) {
7709
+ generate(context) {
7601
7710
  const { schema } = context;
7602
7711
  const generatedFiles = [];
7603
7712
  this.analyzer = new SchemaAnalyzer(schema);
7604
7713
  const uploadEndpoints = schema.endpoints.filter(
7605
- (endpoint) => endpoint.requestBody?.content?.some(
7714
+ (endpoint) => endpoint.requestBody?.content.some(
7606
7715
  (content) => content.type === "multipart/form-data" || content.type === "application/octet-stream"
7607
7716
  )
7608
7717
  );
7609
7718
  if (uploadEndpoints.length === 0 || !this.configuration.uploads?.enabled) {
7610
- return generatedFiles;
7719
+ return Promise.resolve(generatedFiles);
7611
7720
  }
7612
- const presignedConfig = this.configuration.uploads?.presignedUploads;
7721
+ const presignedConfig = this.configuration.uploads.presignedUploads;
7613
7722
  if (presignedConfig?.enabled) {
7614
7723
  const isPresignedSupported = this.analyzer.isPresignedUploadsSupported();
7615
7724
  if (!isPresignedSupported) {
@@ -7620,14 +7729,14 @@ var UploadGenerator = class {
7620
7729
  }
7621
7730
  const extractedUploadConfig = this.analyzer.extractUploadConfig();
7622
7731
  const presignedEnabled = presignedConfig?.enabled && this.analyzer.isPresignedUploadsSupported();
7623
- const uploadProvider = this.configuration.uploads?.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7624
- const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads?.strategy || "standard";
7732
+ const uploadProvider = this.configuration.uploads.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7733
+ const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads.strategy || "standard";
7625
7734
  presignedEnabled ? {
7626
- presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig?.presignEndpoint || "/api/v1/files/presign-upload",
7627
- fallbackToBackend: presignedConfig?.fallbackToBackend !== false
7735
+ presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig.presignEndpoint || "/api/v1/files/presign-upload",
7736
+ fallbackToBackend: presignedConfig.fallbackToBackend !== false
7628
7737
  } : {
7629
7738
  };
7630
- const progressConfig = this.configuration.uploads?.progressTracking || {
7739
+ const progressConfig = this.configuration.uploads.progressTracking || {
7631
7740
  enabled: true,
7632
7741
  useXHR: true
7633
7742
  };
@@ -7644,7 +7753,7 @@ var UploadGenerator = class {
7644
7753
  progressConfig
7645
7754
  ));
7646
7755
  }
7647
- return generatedFiles;
7756
+ return Promise.resolve(generatedFiles);
7648
7757
  }
7649
7758
  /**
7650
7759
  * Find presigned upload endpoint in schema
@@ -7657,7 +7766,7 @@ var UploadGenerator = class {
7657
7766
  return pathLower.includes("presign") || pathLower.includes("presigned") || operationIdLower.includes("presign") || operationIdLower.includes("presigned");
7658
7767
  }) || null;
7659
7768
  }
7660
- generateUploadUtilities(uploadProvider, uploadStrategy, presignedEndpoint) {
7769
+ generateUploadUtilities(_uploadProvider, _uploadStrategy, _presignedEndpoint) {
7661
7770
  const { uploads } = this.configuration;
7662
7771
  const extractedConfig = this.analyzer.extractUploadConfig();
7663
7772
  const maxSize = uploads?.security?.maxSize || (extractedConfig.maxSize ? `${extractedConfig.maxSize}MB` : "10MB");
@@ -8008,8 +8117,8 @@ async function uploadViaBackendApi(
8008
8117
  xhr.responseType = 'json'
8009
8118
  // Use base URL from environment or configuration
8010
8119
  const baseUrl = typeof window !== 'undefined'
8011
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8012
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8120
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8121
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8013
8122
  xhr.open('POST', \`\${baseUrl}${endpoint.path}\`)
8014
8123
  xhr.send(formData)
8015
8124
  })
@@ -8284,8 +8393,8 @@ export function ${hookName}Upload(options?: {
8284
8393
  }
8285
8394
  generateUseUploadFileHook(uploadProvider, uploadStrategy, context) {
8286
8395
  const uploadUtilsImport = this.buildImportPath("services/uploadUtils");
8287
- const uploadEndpoints = context?.schema?.endpoints?.filter(
8288
- (e) => e.metadata?.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8396
+ const uploadEndpoints = context?.schema.endpoints.filter(
8397
+ (e) => e.metadata.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8289
8398
  ) || [];
8290
8399
  const firstUploadEndpoint = uploadEndpoints[0];
8291
8400
  let uploadMethodName = "uploadFile";
@@ -8425,7 +8534,7 @@ var ErrorHandlerGenerator = class {
8425
8534
  }
8426
8535
  analyzer;
8427
8536
  buildImportPath(relativePath) {
8428
- const outputDirectory = this.configuration.outputDir || "generated";
8537
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8429
8538
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8430
8539
  let importBasePath = outputDirectory;
8431
8540
  if (importBasePath.startsWith("src/")) {
@@ -8433,18 +8542,18 @@ var ErrorHandlerGenerator = class {
8433
8542
  }
8434
8543
  return `@/${importBasePath}/${cleanPath}`;
8435
8544
  }
8436
- async generate(context) {
8545
+ generate(context) {
8437
8546
  const files = [];
8438
- const { schema, config } = context;
8547
+ const { schema } = context;
8439
8548
  const { api } = this.configuration;
8440
- const errorHandling = api?.errorHandling;
8549
+ const errorHandling = api.errorHandling;
8441
8550
  this.analyzer = new SchemaAnalyzer(schema);
8442
8551
  const errorCodes = this.analyzer.extractErrorCodes();
8443
8552
  const accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
8444
8553
  const extractedAuthEndpoints = this.analyzer.extractAuthEndpoints();
8445
8554
  const hasAuthEndpoints = !!(extractedAuthEndpoints.login || extractedAuthEndpoints.loginCredentials);
8446
8555
  const hasAuthErrors = errorCodes.size > 0 || (accountStatusPatterns.inactiveStatuses.length > 0 || accountStatusPatterns.suspendedStatuses.length > 0);
8447
- const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling?.generateAuthErrorHandler !== false);
8556
+ const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling.generateAuthErrorHandler !== false);
8448
8557
  if (shouldGenerate) {
8449
8558
  files.push(this.generateAuthErrorHandler(errorCodes, accountStatusPatterns));
8450
8559
  } else if (errorHandling?.enableAuthErrorHandling === true && !hasAuthEndpoints) {
@@ -8452,11 +8561,11 @@ var ErrorHandlerGenerator = class {
8452
8561
  `\u26A0\uFE0F Auth error handling is enabled but auth endpoints are not found in OpenAPI schema. Auth error handler will not be generated.`
8453
8562
  );
8454
8563
  }
8455
- return files;
8564
+ return Promise.resolve(files);
8456
8565
  }
8457
8566
  generateAuthErrorHandler(errorCodes, accountStatusPatterns) {
8458
8567
  const authPath = this.configuration.auth?.authPath || "@/lib/auth";
8459
- const errorHandling = this.configuration.api?.errorHandling;
8568
+ const errorHandling = this.configuration.api.errorHandling;
8460
8569
  const authErrorHandlerPath = errorHandling?.authErrorHandlerPath || "@/lib/auth-error-handler";
8461
8570
  let handlerOutputPath = authErrorHandlerPath;
8462
8571
  if (handlerOutputPath.startsWith("@/")) {
@@ -8495,7 +8604,7 @@ async function getToast(): Promise<{
8495
8604
  try {
8496
8605
  // Try to import sonner (common toast library)
8497
8606
  const sonner = await import('sonner')
8498
- toast = sonner
8607
+ toast = sonner.toast
8499
8608
  return toast
8500
8609
  } catch {
8501
8610
  // Fallback to console if toast library not available
@@ -8669,7 +8778,7 @@ var SSEGenerator = class {
8669
8778
  }
8670
8779
  analyzer;
8671
8780
  buildImportPath(relativePath) {
8672
- const outputDirectory = this.configuration.outputDir || "generated";
8781
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8673
8782
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8674
8783
  let importBasePath = outputDirectory;
8675
8784
  if (importBasePath.startsWith("src/")) {
@@ -8701,11 +8810,11 @@ var SSEGenerator = class {
8701
8810
  );
8702
8811
  return hasEventStream;
8703
8812
  }
8704
- async generate(context) {
8813
+ generate(context) {
8705
8814
  const { schema } = context;
8706
8815
  const generatedFiles = [];
8707
8816
  this.analyzer = new SchemaAnalyzer(schema);
8708
- const streamingConfig = this.configuration.framework?.streaming;
8817
+ const streamingConfig = this.configuration.framework.streaming;
8709
8818
  const hasStreamingEndpoints = schema.endpoints.some((endpoint) => this.isSSEEndpoint(endpoint));
8710
8819
  if (streamingConfig?.enabled === true && !hasStreamingEndpoints) {
8711
8820
  console.warn(
@@ -8714,11 +8823,11 @@ var SSEGenerator = class {
8714
8823
  }
8715
8824
  const shouldEnableStreaming = streamingConfig?.enabled === true ? hasStreamingEndpoints : streamingConfig?.enabled !== false && hasStreamingEndpoints;
8716
8825
  if (!shouldEnableStreaming || streamingConfig?.sse?.enabled === false || !hasStreamingEndpoints) {
8717
- return generatedFiles;
8826
+ return Promise.resolve(generatedFiles);
8718
8827
  }
8719
8828
  const sseEndpoints = schema.endpoints.filter((endpoint) => this.isSSEEndpoint(endpoint));
8720
8829
  if (sseEndpoints.length === 0) {
8721
- return generatedFiles;
8830
+ return Promise.resolve(generatedFiles);
8722
8831
  }
8723
8832
  for (const endpoint of sseEndpoints) {
8724
8833
  generatedFiles.push(this.generateSSEClientMethod(endpoint));
@@ -8727,7 +8836,7 @@ var SSEGenerator = class {
8727
8836
  for (const [tag, tagEndpoints] of Object.entries(endpointsByTag)) {
8728
8837
  generatedFiles.push(this.generateSSEHooks(tag, tagEndpoints));
8729
8838
  }
8730
- return generatedFiles;
8839
+ return Promise.resolve(generatedFiles);
8731
8840
  }
8732
8841
  generateSSEClientMethod(endpoint) {
8733
8842
  const operationId = endpoint.operationId || endpoint.id;
@@ -8762,8 +8871,8 @@ var SSEGenerator = class {
8762
8871
  }): EventSource => {
8763
8872
  ${pathParamNames.length > 0 ? `const { ${pathParamNames.join(", ")}, ...restOptions } = options.params || {}
8764
8873
  ` : ""}const baseUrl = typeof window !== 'undefined'
8765
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8766
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8874
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8875
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8767
8876
  const sseUrl = \`\${baseUrl}${urlConstruction}\`
8768
8877
 
8769
8878
  // Create EventSource connection
@@ -8809,7 +8918,7 @@ var SSEGenerator = class {
8809
8918
  generateSSEHooks(tag, endpoints) {
8810
8919
  const tagName = toValidIdentifier(tag);
8811
8920
  const clientImport = this.buildImportPath("client");
8812
- const streamingConfig = this.configuration.framework?.streaming?.sse;
8921
+ const streamingConfig = this.configuration.framework.streaming?.sse;
8813
8922
  const autoReconnect = streamingConfig?.autoReconnect !== false;
8814
8923
  const reconnectDelay = streamingConfig?.reconnectDelay || 3e3;
8815
8924
  const maxReconnectAttempts = streamingConfig?.maxReconnectAttempts || 5;
@@ -9002,7 +9111,7 @@ var NextJsCodeGenerator = class {
9002
9111
  __name(this, "NextJsCodeGenerator");
9003
9112
  }
9004
9113
  buildImportPath(relativePath) {
9005
- const outputDirectory = this.configuration.outputDir || "generated";
9114
+ const outputDirectory = this.configuration.outputDir ?? "generated";
9006
9115
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
9007
9116
  let importBasePath = outputDirectory;
9008
9117
  if (importBasePath.startsWith("src/")) {
@@ -9016,9 +9125,9 @@ var NextJsCodeGenerator = class {
9016
9125
  path: file.path,
9017
9126
  metadata: {
9018
9127
  ...file.metadata,
9019
- exports: file.metadata?.exports || [],
9020
- imports: file.metadata?.imports || [],
9021
- dependencies: file.metadata?.dependencies?.map((dependency) => {
9128
+ exports: file.metadata?.exports ?? [],
9129
+ imports: file.metadata?.imports ?? [],
9130
+ dependencies: file.metadata?.dependencies.map((dependency) => {
9022
9131
  if (dependency.startsWith("@/generated/")) {
9023
9132
  return dependency;
9024
9133
  }
@@ -9027,7 +9136,7 @@ var NextJsCodeGenerator = class {
9027
9136
  return `@/generated/${relativePart}`;
9028
9137
  }
9029
9138
  return dependency;
9030
- }) || []
9139
+ }) ?? []
9031
9140
  }
9032
9141
  }));
9033
9142
  }
@@ -9060,11 +9169,11 @@ var NextJsCodeGenerator = class {
9060
9169
  const uploadGenerator = new UploadGenerator(this.configuration);
9061
9170
  generatedFiles.push(...await uploadGenerator.generate(context));
9062
9171
  }
9063
- if (this.configuration.api?.errorHandling?.generateAuthErrorHandler !== false) {
9172
+ if (this.configuration.api.errorHandling?.generateAuthErrorHandler !== false) {
9064
9173
  const errorHandlerGenerator = new ErrorHandlerGenerator(this.configuration);
9065
9174
  generatedFiles.push(...await errorHandlerGenerator.generate(context));
9066
9175
  }
9067
- if (this.configuration.framework?.streaming?.enabled) {
9176
+ if (this.configuration.framework.streaming?.enabled) {
9068
9177
  const sseGenerator = new SSEGenerator(this.configuration);
9069
9178
  generatedFiles.push(...await sseGenerator.generate(context));
9070
9179
  }
@@ -9074,14 +9183,14 @@ var NextJsCodeGenerator = class {
9074
9183
  throw new GenerationError(`Failed to generate Next.js files: ${errorMessage}`);
9075
9184
  }
9076
9185
  }
9077
- async generateSafeActionClient() {
9186
+ generateSafeActionClient() {
9078
9187
  const safeActionContent = `import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "next-safe-action";
9079
9188
  import { headers } from "next/headers";
9080
9189
  import { z } from "zod";
9081
9190
 
9082
9191
  /**
9083
9192
  * Enhanced Action Error class for better error handling
9084
- * Follows Next.js 16.0.1 best practices
9193
+ * Follows Next.js 16.0.7 best practices
9085
9194
  */
9086
9195
  export class ActionError extends Error {
9087
9196
  constructor(
@@ -9118,7 +9227,7 @@ export const actionClient = createSafeActionClient({
9118
9227
 
9119
9228
  /**
9120
9229
  * Enhanced action client with metadata support
9121
- * Next.js 16.0.1: Supports metadata for better action tracking and rate limiting
9230
+ * Next.js 16.0.7: Supports metadata for better action tracking and rate limiting
9122
9231
  */
9123
9232
  export const actionClientWithMeta = createSafeActionClient({
9124
9233
  handleServerError(e) {
@@ -9139,7 +9248,7 @@ export const actionClientWithMeta = createSafeActionClient({
9139
9248
  requests: z.number().int().positive().describe('Number of requests allowed'),
9140
9249
  window: z.string().describe('Time window (e.g., "10s", "1m", "1h")'),
9141
9250
  }).optional().describe('Rate limiting configuration'),
9142
- cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.1)'),
9251
+ cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.7)'),
9143
9252
  });
9144
9253
  },
9145
9254
  });
@@ -9230,7 +9339,7 @@ async function getCurrentUser() {
9230
9339
  // Implement your authentication logic here
9231
9340
  return null;
9232
9341
  }`;
9233
- return [
9342
+ return Promise.resolve([
9234
9343
  {
9235
9344
  path: "lib/safe-action.ts",
9236
9345
  content: safeActionContent,
@@ -9241,7 +9350,7 @@ async function getCurrentUser() {
9241
9350
  dependencies: []
9242
9351
  }
9243
9352
  }
9244
- ];
9353
+ ]);
9245
9354
  }
9246
9355
  };
9247
9356
  var FileSystemManager = class {
@@ -9249,7 +9358,7 @@ var FileSystemManager = class {
9249
9358
  __name(this, "FileSystemManager");
9250
9359
  }
9251
9360
  async writeFile(filePath, content, options = {}) {
9252
- if (!filePath?.trim()) {
9361
+ if (!filePath.trim()) {
9253
9362
  throw new Error("File path is required and cannot be empty");
9254
9363
  }
9255
9364
  if (typeof content !== "string") {
@@ -9286,7 +9395,7 @@ var FileSystemManager = class {
9286
9395
  }
9287
9396
  }
9288
9397
  async readFile(filePath, encoding = "utf8") {
9289
- if (!filePath?.trim()) {
9398
+ if (!filePath.trim()) {
9290
9399
  throw new Error("File path is required and cannot be empty");
9291
9400
  }
9292
9401
  try {
@@ -9313,7 +9422,7 @@ var FileSystemManager = class {
9313
9422
  }
9314
9423
  }
9315
9424
  async getFileHash(filePath) {
9316
- if (!filePath?.trim()) {
9425
+ if (!filePath.trim()) {
9317
9426
  throw new Error("File path is required and cannot be empty");
9318
9427
  }
9319
9428
  try {
@@ -9339,7 +9448,7 @@ var FileSystemManager = class {
9339
9448
  }
9340
9449
  }
9341
9450
  async findFiles(dir, pattern, recursive = true) {
9342
- if (!dir?.trim()) {
9451
+ if (!dir.trim()) {
9343
9452
  throw new Error("Directory path is required and cannot be empty");
9344
9453
  }
9345
9454
  if (!(pattern instanceof RegExp)) {
@@ -9382,16 +9491,52 @@ var BridgeCore = class {
9382
9491
  logger;
9383
9492
  schemaParser;
9384
9493
  fileManager;
9494
+ /**
9495
+ * Creates a new instance of BridgeCore
9496
+ *
9497
+ * Initializes all required dependencies including logger, schema parser, and file manager.
9498
+ * All dependencies are readonly to ensure immutability and thread safety.
9499
+ */
9385
9500
  constructor() {
9386
9501
  this.logger = new BridgeLogger({ prefix: "\u{1F517} Mulink" });
9387
9502
  this.schemaParser = new OpenApiSchemaParser();
9388
9503
  this.fileManager = new FileSystemManager();
9389
9504
  }
9505
+ /**
9506
+ * Generates type-safe API client code from OpenAPI schema
9507
+ *
9508
+ * This is the main entry point for code generation. It validates the configuration,
9509
+ * parses the OpenAPI schema, generates all necessary files, and writes them to disk.
9510
+ *
9511
+ * The generated code follows Next.js 16.0.7 best practices including:
9512
+ * - Server Actions with type safety
9513
+ * - React Query hooks with proper caching
9514
+ * - Middleware support
9515
+ * - Error handling
9516
+ * - Cache tag management
9517
+ *
9518
+ * @param configuration - The bridge configuration containing schema URL, output directory, and framework settings
9519
+ * @returns Promise that resolves when generation is complete
9520
+ * @throws {ValidationError} When configuration is invalid
9521
+ * @throws {SchemaParseError} When OpenAPI schema cannot be parsed
9522
+ * @throws {GenerationError} When code generation fails
9523
+ *
9524
+ * @example
9525
+ * ```typescript
9526
+ * const config: BridgeConfiguration = {
9527
+ * schema: 'https://api.example.com/openapi.json',
9528
+ * outputDir: 'src/generated',
9529
+ * framework: { type: 'nextjs', router: 'app', features: {...} },
9530
+ * api: { baseUrl: 'https://api.example.com', timeout: 30000, retries: 3 }
9531
+ * };
9532
+ * await bridge.generate(config);
9533
+ * ```
9534
+ */
9390
9535
  async generate(configuration) {
9391
9536
  const startTime = Date.now();
9392
9537
  try {
9393
9538
  this.logger.info("Starting code generation...");
9394
- await this.validateConfiguration(configuration);
9539
+ this.validateConfiguration(configuration);
9395
9540
  this.logger.info(`Parsing schema: ${configuration.schema}`);
9396
9541
  const parsedSchema = await this.schemaParser.parse(configuration.schema);
9397
9542
  this.logger.debug(
@@ -9420,16 +9565,17 @@ var BridgeCore = class {
9420
9565
  throw error;
9421
9566
  }
9422
9567
  }
9423
- async validateConfiguration(configuration) {
9568
+ validateConfiguration(configuration) {
9424
9569
  const errors = [];
9425
- if (!configuration.schema?.trim()) {
9570
+ if (!configuration.schema.trim()) {
9426
9571
  errors.push("Schema URL is required and cannot be empty");
9427
9572
  }
9428
- if (!configuration.outputDir?.trim()) {
9573
+ if (!configuration.outputDir.trim()) {
9429
9574
  errors.push("Output directory is required and cannot be empty");
9430
9575
  }
9431
9576
  if (configuration.framework.type !== "nextjs") {
9432
- errors.push(`Only Next.js framework is currently supported, got: ${configuration.framework.type}`);
9577
+ const frameworkType = configuration.framework.type;
9578
+ errors.push(`Only Next.js framework is currently supported, got: ${frameworkType}`);
9433
9579
  }
9434
9580
  if (errors.length > 0) {
9435
9581
  throw new ValidationError(
@@ -9446,8 +9592,10 @@ var BridgeCore = class {
9446
9592
  case "nextjs":
9447
9593
  const nextJsGenerator = new NextJsCodeGenerator(config);
9448
9594
  return await nextJsGenerator.generate(context);
9449
- default:
9450
- throw new GenerationError(`Unsupported framework: ${config.framework.type}`);
9595
+ default: {
9596
+ const frameworkType = config.framework.type;
9597
+ throw new GenerationError(`Unsupported framework: ${frameworkType}`);
9598
+ }
9451
9599
  }
9452
9600
  } catch (error) {
9453
9601
  if (error instanceof GenerationError) {
@@ -9481,7 +9629,7 @@ var BridgeCore = class {
9481
9629
  logGenerationSummary(files) {
9482
9630
  const fileTypes = files.reduce(
9483
9631
  (acc, file) => {
9484
- acc[file.type] = (acc[file.type] || 0) + 1;
9632
+ acc[file.type] = (acc[file.type] ?? 0) + 1;
9485
9633
  return acc;
9486
9634
  },
9487
9635
  {}
@@ -9500,9 +9648,24 @@ var BridgeCore = class {
9500
9648
  });
9501
9649
  }
9502
9650
  }
9503
- // Public API methods
9651
+ /**
9652
+ * Validates an OpenAPI schema without generating code
9653
+ *
9654
+ * Useful for checking schema validity before running full generation.
9655
+ *
9656
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9657
+ * @returns Promise resolving to true if schema is valid, false otherwise
9658
+ *
9659
+ * @example
9660
+ * ```typescript
9661
+ * const isValid = await bridge.validateSchema('https://api.example.com/openapi.json');
9662
+ * if (isValid) {
9663
+ * await bridge.generate(config);
9664
+ * }
9665
+ * ```
9666
+ */
9504
9667
  async validateSchema(schemaUrl) {
9505
- if (!schemaUrl?.trim()) {
9668
+ if (!schemaUrl.trim()) {
9506
9669
  this.logger.warn("Schema URL is empty or invalid");
9507
9670
  return false;
9508
9671
  }
@@ -9516,8 +9679,25 @@ var BridgeCore = class {
9516
9679
  return false;
9517
9680
  }
9518
9681
  }
9682
+ /**
9683
+ * Retrieves metadata from an OpenAPI schema
9684
+ *
9685
+ * Extracts schema metadata including title, version, description, and other
9686
+ * OpenAPI document information without parsing the entire schema.
9687
+ *
9688
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9689
+ * @returns Promise resolving to schema metadata
9690
+ * @throws {BridgeError} When schema URL is invalid
9691
+ * @throws {SchemaParseError} When schema cannot be parsed
9692
+ *
9693
+ * @example
9694
+ * ```typescript
9695
+ * const metadata = await bridge.getSchemaInfo('https://api.example.com/openapi.json');
9696
+ * console.log(`Schema: ${metadata.title} v${metadata.version}`);
9697
+ * ```
9698
+ */
9519
9699
  async getSchemaInfo(schemaUrl) {
9520
- if (!schemaUrl?.trim()) {
9700
+ if (!schemaUrl.trim()) {
9521
9701
  throw new BridgeError("Schema URL is required and cannot be empty", "INVALID_SCHEMA_URL");
9522
9702
  }
9523
9703
  try {
@@ -9529,6 +9709,18 @@ var BridgeCore = class {
9529
9709
  throw new SchemaParseError(`Failed to parse schema: ${errorMessage}`, schemaUrl);
9530
9710
  }
9531
9711
  }
9712
+ /**
9713
+ * Clears the internal schema cache
9714
+ *
9715
+ * Useful when you need to force re-fetching of schemas or during development.
9716
+ * The cache is automatically managed, but this method allows manual invalidation.
9717
+ *
9718
+ * @example
9719
+ * ```typescript
9720
+ * bridge.clearCache();
9721
+ * await bridge.generate(config); // Will fetch fresh schema
9722
+ * ```
9723
+ */
9532
9724
  clearCache() {
9533
9725
  try {
9534
9726
  this.schemaParser.clearCache();
@@ -9627,7 +9819,7 @@ var ConfigurationLoader = class {
9627
9819
  }
9628
9820
  async load(configPath) {
9629
9821
  if (!configPath?.trim()) {
9630
- configPath = "mulink.config.json";
9822
+ configPath = "link.config.json";
9631
9823
  }
9632
9824
  const resolvedPath = path2.resolve(process.cwd(), configPath);
9633
9825
  try {
@@ -9693,7 +9885,7 @@ ${errorMessages}`,
9693
9885
  );
9694
9886
  }
9695
9887
  }
9696
- async createDefault(framework = "nextjs") {
9888
+ createDefault(framework = "nextjs") {
9697
9889
  const defaultConfig = {
9698
9890
  schema: "https://petstore3.swagger.io/api/v3/openapi.json",
9699
9891
  outputDir: "src/generated",
@@ -9738,7 +9930,7 @@ ${errorMessages}`,
9738
9930
  }
9739
9931
  async save(config, configPath) {
9740
9932
  if (!configPath?.trim()) {
9741
- configPath = "mulink.config.json";
9933
+ configPath = "link.config.json";
9742
9934
  }
9743
9935
  const resolvedPath = path2.resolve(process.cwd(), configPath);
9744
9936
  try {
@@ -9782,5 +9974,5 @@ ${errorMessages}`,
9782
9974
  };
9783
9975
 
9784
9976
  export { BridgeCore, BridgeError, BridgeLogger, ConfigurationLoader, FileSystemManager, GenerationError, LogLevel, NextJsCodeGenerator, OpenApiSchemaParser, SchemaParseError, ValidationError, VersionChecker, __name, checkAndNotifyUpdates, createBridgeVersionChecker };
9785
- //# sourceMappingURL=chunk-SL4RMR26.js.map
9786
- //# sourceMappingURL=chunk-SL4RMR26.js.map
9977
+ //# sourceMappingURL=chunk-2WVV6AOO.js.map
9978
+ //# sourceMappingURL=chunk-2WVV6AOO.js.map