mulink 1.1.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,66 @@ 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
  }
2705
+ extractDependenciesFromDefinition(definition) {
2706
+ const dependencies = [];
2707
+ const schemaRefRegex = /([A-Z][a-zA-Z0-9]*Schema)\b/g;
2708
+ const matches = definition.matchAll(schemaRefRegex);
2709
+ for (const match of matches) {
2710
+ const schemaName = match[1];
2711
+ if (!schemaName) continue;
2712
+ const baseName = schemaName.replace(/Schema$/, "");
2713
+ if (!dependencies.includes(baseName)) {
2714
+ dependencies.push(baseName);
2715
+ }
2716
+ }
2717
+ return dependencies;
2718
+ }
2719
+ orderDefinitionsByDependencies(definitions) {
2720
+ const visited = /* @__PURE__ */ new Set();
2721
+ const visiting = /* @__PURE__ */ new Set();
2722
+ const result = [];
2723
+ const definitionMap = /* @__PURE__ */ new Map();
2724
+ for (const def of definitions) {
2725
+ const baseName = def.exportName.replace(/Schema$/, "");
2726
+ definitionMap.set(baseName, def);
2727
+ }
2728
+ const visit = /* @__PURE__ */ __name((exportName) => {
2729
+ const baseName = exportName.replace(/Schema$/, "");
2730
+ if (visiting.has(baseName)) {
2731
+ console.warn(`Circular dependency detected for schema: ${exportName}`);
2732
+ return;
2733
+ }
2734
+ if (visited.has(baseName)) {
2735
+ return;
2736
+ }
2737
+ visiting.add(baseName);
2738
+ const def = definitionMap.get(baseName);
2739
+ if (def) {
2740
+ for (const dep of def.dependencies) {
2741
+ if (definitionMap.has(dep)) {
2742
+ visit(`${dep}Schema`);
2743
+ }
2744
+ }
2745
+ result.push(def);
2746
+ }
2747
+ visiting.delete(baseName);
2748
+ visited.add(baseName);
2749
+ }, "visit");
2750
+ for (const def of definitions) {
2751
+ const baseName = def.exportName.replace(/Schema$/, "");
2752
+ if (!visited.has(baseName)) {
2753
+ visit(def.exportName);
2754
+ }
2755
+ }
2756
+ return result;
2757
+ }
2647
2758
  extractDependenciesFromZodSchema(zodSchema, dependencies, visited = /* @__PURE__ */ new Set()) {
2648
- if (!zodSchema || !zodSchema._def) return;
2759
+ if (!zodSchema?._def) return;
2649
2760
  const def = zodSchema._def;
2650
2761
  if (def._schemaRef) {
2651
2762
  const refName = def._schemaRef;
@@ -2668,7 +2779,7 @@ var SchemaGenerator = class {
2668
2779
  case "ZodObject":
2669
2780
  if (def.shape) {
2670
2781
  const shape = def.shape();
2671
- for (const [key, value] of Object.entries(shape)) {
2782
+ for (const [_key, value] of Object.entries(shape)) {
2672
2783
  this.extractDependenciesFromZodSchema(value, dependencies, visited);
2673
2784
  }
2674
2785
  }
@@ -2700,22 +2811,31 @@ var SchemaGenerator = class {
2700
2811
  break;
2701
2812
  }
2702
2813
  }
2703
- async generateSchemasFile(context) {
2814
+ generateSchemasFile(context) {
2704
2815
  const { schemas, endpoints } = context.schema;
2705
2816
  const imports = ['import { z } from "zod"'];
2706
2817
  const schemaExports = [];
2707
- const schemaDefinitions = [];
2818
+ const allSchemaDefinitions = [];
2708
2819
  const orderedSchemas = this.orderSchemasByDependencies(schemas);
2709
2820
  for (const schema of orderedSchemas) {
2710
2821
  const { definition, exportName } = this.generateSchemaDefinition(schema);
2711
- schemaDefinitions.push(definition);
2822
+ const dependencies = this.findSchemaDependencies(schema);
2823
+ allSchemaDefinitions.push({ definition, exportName, dependencies });
2712
2824
  schemaExports.push(exportName);
2713
2825
  }
2714
2826
  for (const endpoint of endpoints) {
2715
2827
  const endpointSchemas = this.generateEndpointSchemas(endpoint);
2716
- schemaDefinitions.push(...endpointSchemas.definitions);
2717
- schemaExports.push(...endpointSchemas.exports);
2828
+ for (let i = 0; i < endpointSchemas.definitions.length; i++) {
2829
+ const definition = endpointSchemas.definitions[i];
2830
+ const exportName = endpointSchemas.exports[i];
2831
+ if (!definition || !exportName) continue;
2832
+ const dependencies = this.extractDependenciesFromDefinition(definition);
2833
+ allSchemaDefinitions.push({ definition, exportName, dependencies });
2834
+ schemaExports.push(exportName);
2835
+ }
2718
2836
  }
2837
+ const orderedDefinitions = this.orderDefinitionsByDependencies(allSchemaDefinitions);
2838
+ const schemaDefinitions = orderedDefinitions.map((item) => item.definition);
2719
2839
  const validationHelpers = this.generateValidationHelpers();
2720
2840
  const contentWithImports = [
2721
2841
  ...imports,
@@ -2734,7 +2854,7 @@ var SchemaGenerator = class {
2734
2854
 
2735
2855
  ${content}`;
2736
2856
  }
2737
- return {
2857
+ return Promise.resolve({
2738
2858
  path: "schemas/index.ts",
2739
2859
  content,
2740
2860
  type: "typescript",
@@ -2743,7 +2863,7 @@ ${content}`;
2743
2863
  imports: ["zod"],
2744
2864
  dependencies: []
2745
2865
  }
2746
- };
2866
+ });
2747
2867
  }
2748
2868
  generateEndpointSchemas(endpoint) {
2749
2869
  const definitions = [];
@@ -2778,6 +2898,9 @@ ${content}`;
2778
2898
  }
2779
2899
  const exportName = `${operationName}RequestSchema`;
2780
2900
  const primaryContent = endpoint.requestBody.content[0];
2901
+ if (!primaryContent) {
2902
+ throw new Error(`No content found for request body in ${endpoint.method} ${endpoint.path}`);
2903
+ }
2781
2904
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2782
2905
  const definition = [
2783
2906
  `/**`,
@@ -2801,17 +2924,22 @@ ${content}`;
2801
2924
  );
2802
2925
  if (successResponses.length > 0) {
2803
2926
  const successResponse = successResponses[0];
2927
+ if (!successResponse) {
2928
+ return { definitions, exports };
2929
+ }
2804
2930
  let zodSchemaString = "z.void()";
2805
2931
  if (successResponse.content && successResponse.content.length > 0) {
2806
2932
  const primaryContent = successResponse.content[0];
2807
- zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2933
+ if (primaryContent) {
2934
+ zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2935
+ }
2808
2936
  }
2809
2937
  const exportName = `${operationName}ResponseSchema`;
2810
2938
  const definition = [
2811
2939
  `/**`,
2812
2940
  ` * Success response schema for ${endpoint.method} ${endpoint.path}`,
2813
2941
  ` * Status: ${successResponse.statusCode}`,
2814
- ` * ${successResponse.description}`,
2942
+ ` * ${successResponse.description ?? ""}`,
2815
2943
  ` */`,
2816
2944
  `export const ${exportName} = ${zodSchemaString}`,
2817
2945
  "",
@@ -2822,15 +2950,18 @@ ${content}`;
2822
2950
  }
2823
2951
  if (errorResponses.length > 0) {
2824
2952
  const errorResponse = errorResponses[0];
2825
- if (errorResponse.content && errorResponse.content.length > 0) {
2953
+ if (errorResponse?.content && errorResponse.content.length > 0) {
2826
2954
  const exportName = `${operationName}ErrorSchema`;
2827
2955
  const primaryContent = errorResponse.content[0];
2956
+ if (!primaryContent) {
2957
+ return { definitions, exports };
2958
+ }
2828
2959
  const zodSchemaString = this.zodSchemaToString(primaryContent.schema);
2829
2960
  const definition = [
2830
2961
  `/**`,
2831
2962
  ` * Error response schema for ${endpoint.method} ${endpoint.path}`,
2832
2963
  ` * Status: ${errorResponse.statusCode}`,
2833
- ` * ${errorResponse.description}`,
2964
+ ` * ${errorResponse.description ?? ""}`,
2834
2965
  ` */`,
2835
2966
  `export const ${exportName} = ${zodSchemaString}`,
2836
2967
  "",
@@ -2921,8 +3052,8 @@ ${schemaProperties.join(",\n")}
2921
3052
  };
2922
3053
  }
2923
3054
  zodSchemaToString(schema, context) {
2924
- if (!schema || !schema._def) {
2925
- if (schema && schema._schemaRef) {
3055
+ if (!schema?._def) {
3056
+ if (schema?._schemaRef) {
2926
3057
  const refName = schema._schemaRef;
2927
3058
  const registeredSchema = this.schemaRegistry.get(refName);
2928
3059
  if (registeredSchema) {
@@ -3090,15 +3221,21 @@ export const errorMessages = {
3090
3221
  const assignments = line.match(/(\w+)\s*[:=]/g);
3091
3222
  if (assignments) {
3092
3223
  assignments.forEach((match) => {
3093
- const identifier = match.split(/[:=]/)[0].trim();
3094
- usedIdentifiers.add(identifier);
3224
+ const parts = match.split(/[:=]/);
3225
+ if (parts[0]) {
3226
+ const identifier = parts[0].trim();
3227
+ usedIdentifiers.add(identifier);
3228
+ }
3095
3229
  });
3096
3230
  }
3097
3231
  const functionCalls = line.match(/(\w+)\s*\(/g);
3098
3232
  if (functionCalls) {
3099
3233
  functionCalls.forEach((match) => {
3100
- const identifier = match.split("(")[0].trim();
3101
- usedIdentifiers.add(identifier);
3234
+ const parts = match.split("(");
3235
+ if (parts[0]) {
3236
+ const identifier = parts[0].trim();
3237
+ usedIdentifiers.add(identifier);
3238
+ }
3102
3239
  });
3103
3240
  }
3104
3241
  if (line.includes("z.infer")) {
@@ -3116,10 +3253,10 @@ export const errorMessages = {
3116
3253
  continue;
3117
3254
  }
3118
3255
  const importMatch = line.match(/import\s*\{([^}]+)\}/);
3119
- if (importMatch) {
3256
+ if (importMatch?.[1]) {
3120
3257
  const imports = importMatch[1].split(",").map((imp) => imp.trim());
3121
3258
  const usedImports = imports.filter((imp) => usedIdentifiers.has(imp));
3122
- if (usedImports.length > 0) {
3259
+ if (usedImports.length > 0 && importMatch[1]) {
3123
3260
  cleanedLines.push(line.replace(importMatch[1], usedImports.join(", ")));
3124
3261
  } else {
3125
3262
  continue;
@@ -3166,7 +3303,7 @@ var ActionGenerator = class {
3166
3303
  if (!this.documentationEnabled) {
3167
3304
  return "";
3168
3305
  }
3169
- const summary = endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`;
3306
+ const summary = endpoint.summary ?? endpoint.description ?? `${endpoint.method} ${endpoint.path}`;
3170
3307
  return `/**
3171
3308
  * ${summary}
3172
3309
  * @generated from ${endpoint.method} ${endpoint.path}
@@ -3308,7 +3445,7 @@ ${" ".repeat(indent + 2)}error: error instanceof Error ? error.message : 'Unknow
3308
3445
  ${" ".repeat(indent)}})`;
3309
3446
  }
3310
3447
  buildImportPath(relativePath) {
3311
- const outputDirectory = this.configuration.outputDir || "generated";
3448
+ const outputDirectory = this.configuration.outputDir ?? "generated";
3312
3449
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
3313
3450
  let importBasePath = outputDirectory;
3314
3451
  if (importBasePath.startsWith("src/")) {
@@ -3316,7 +3453,7 @@ ${" ".repeat(indent)}})`;
3316
3453
  }
3317
3454
  return `@/${importBasePath}/${cleanPath}`;
3318
3455
  }
3319
- async generate(context) {
3456
+ generate(context) {
3320
3457
  const { schema, config } = context;
3321
3458
  const generatedFiles = [];
3322
3459
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3410,7 +3547,7 @@ ${actions}`;
3410
3547
  dependencies: Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)
3411
3548
  }
3412
3549
  });
3413
- return generatedFiles;
3550
+ return Promise.resolve(generatedFiles);
3414
3551
  }
3415
3552
  getOperationName(endpoint) {
3416
3553
  if (endpoint.operationId) {
@@ -3423,7 +3560,7 @@ ${actions}`;
3423
3560
  const method = this.toPascalCase(endpoint.method.toLowerCase());
3424
3561
  return [...pathParts, method].join("");
3425
3562
  }
3426
- generateOptimizedServerAction(endpoint, config) {
3563
+ generateOptimizedServerAction(endpoint, _config) {
3427
3564
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3428
3565
  const operationName = this.getOperationName(endpoint);
3429
3566
  const hasRequestBody = !!endpoint.requestBody;
@@ -3705,7 +3842,7 @@ var HookGenerator = class {
3705
3842
  }
3706
3843
  return `@/${importBasePath}/${cleanPath}`;
3707
3844
  }
3708
- async generate(context) {
3845
+ generate(context) {
3709
3846
  const { schema } = context;
3710
3847
  const generatedFiles = [];
3711
3848
  const endpointsByTag = this.groupEndpointsByTag(schema.endpoints);
@@ -3838,7 +3975,7 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3838
3975
  dependencies: ["./useBridgeQuery", ...Object.keys(endpointsByTag).map((tag) => `./${toValidIdentifier(tag)}`)]
3839
3976
  }
3840
3977
  });
3841
- return generatedFiles;
3978
+ return Promise.resolve(generatedFiles);
3842
3979
  }
3843
3980
  getOperationName(endpoint) {
3844
3981
  if (endpoint.operationId) {
@@ -3855,62 +3992,78 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
3855
3992
  const hookName = toHookName(endpoint.operationId || endpoint.id, true);
3856
3993
  const actionName = toActionName(endpoint.operationId || endpoint.id);
3857
3994
  const operationName = this.getOperationName(endpoint);
3858
- const queryKey = this.generateQueryKey(endpoint);
3859
3995
  const staleTime = this.getStaleTime(endpoint);
3860
3996
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
3861
3997
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
3862
3998
  const hasPageParam = queryParameters.some((param) => param.name === "page");
3863
3999
  const hasSearchParams = endpoint.path.includes("search") || endpoint.path.includes("list");
3864
- endpoint.parameters.length > 0;
3865
- const parameterTypes = [];
4000
+ const pathParamTypes = [];
4001
+ const queryParamTypes = [];
3866
4002
  pathParameters.forEach((param) => {
3867
4003
  const isRequired = param.required ? "" : "?";
3868
4004
  const paramType = this.getTypeFromZodSchema(param.schema);
3869
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
4005
+ pathParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3870
4006
  });
3871
4007
  queryParameters.forEach((param) => {
3872
4008
  const isRequired = param.required ? "" : "?";
3873
4009
  const paramType = this.getTypeFromZodSchema(param.schema);
3874
- parameterTypes.push(`${param.name}${isRequired}: ${paramType}`);
4010
+ queryParamTypes.push(`${param.name}${isRequired}: ${paramType}`);
3875
4011
  });
3876
4012
  const returnType = `z.infer<typeof ${operationName}ResponseSchema>`;
3877
4013
  const optionsType = `{ enabled?: boolean; suspense?: boolean; refetchInterval?: number; initialData?: ${returnType} }`;
3878
- const enabledCondition = pathParameters.length > 0 ? `!!${pathParameters.map((parameter) => parameter.name).join(" && !!")}` : "true";
3879
- const actionCallParams = this.buildActionCallParams(endpoint, false);
4014
+ const paramsTypeParts = [];
4015
+ if (pathParameters.length > 0) {
4016
+ paramsTypeParts.push(`path: { ${pathParamTypes.join("; ")} }`);
4017
+ }
4018
+ if (queryParameters.length > 0) {
4019
+ paramsTypeParts.push(`query?: { ${queryParamTypes.join("; ")} }`);
4020
+ }
4021
+ const paramsType = paramsTypeParts.length > 0 ? `{ ${paramsTypeParts.join("; ")} }` : "{}";
4022
+ const enabledCondition = pathParameters.length > 0 && pathParameters[0] ? `!!params?.path?.${pathParameters[0].name}` : "true";
4023
+ const pathParamsBuild = pathParameters.length > 0 ? `{ ${pathParameters.map((p) => `${p.name}: params.path.${p.name}`).join(", ")} }` : "{}";
4024
+ const queryParamsBuild = queryParameters.length > 0 ? `{ ${queryParameters.map((p) => `${p.name}: params?.query?.${p.name}`).join(", ")} }` : "{}";
4025
+ const queryKeyParts = [`'${toActionName(endpoint.operationId || endpoint.id)}'`];
4026
+ if (pathParameters.length > 0) {
4027
+ queryKeyParts.push("params?.path");
4028
+ } else {
4029
+ queryKeyParts.push("null");
4030
+ }
4031
+ if (queryParameters.length > 0) {
4032
+ queryKeyParts.push("params?.query");
4033
+ }
4034
+ const queryKeyString = `[${queryKeyParts.join(", ")}]`;
4035
+ const hasAnyParams = pathParameters.length > 0 || queryParameters.length > 0;
4036
+ const actionCallString = pathParameters.length > 0 && queryParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: ${queryParamsBuild} }` : pathParameters.length > 0 ? `{ path: ${pathParamsBuild} }` : queryParameters.length > 0 ? `{ query: ${queryParamsBuild} }` : "";
3880
4037
  if (hasSearchParams) {
3881
- const queryParamTypes = queryParameters.map((param) => {
3882
- const isRequired = param.required;
3883
- const paramType = this.getTypeFromZodSchema(param.schema);
3884
- return `${param.name}${isRequired ? "" : "?"}: ${paramType}`;
3885
- }).join("; ");
3886
- const queryParamsBuild = queryParameters.length > 0 ? `// Build query params object with only the parameters the endpoint expects
3887
- const queryParams: { ${queryParamTypes} } = {
4038
+ const queryParamsWithFallback = queryParameters.length > 0 ? `const queryParams = {
3888
4039
  ${queryParameters.map((param) => {
3889
4040
  if (param.name === "query") {
3890
- return `${param.name}: ${param.name} || searchParams.search || ''`;
4041
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3891
4042
  } else if (param.name === "limit") {
3892
- return `${param.name}: ${param.name} !== undefined ? ${param.name} : searchParams.limit`;
4043
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3893
4044
  } else {
3894
- return `${param.name}: ${param.name} !== undefined ? ${param.name} : undefined`;
4045
+ return `${param.name}: params?.query?.${param.name}`;
3895
4046
  }
3896
4047
  }).join(",\n ")}
3897
4048
  }` : "";
3898
- const queryParamObject = queryParameters.length > 0 ? `{ ${queryParameters.map((param) => `${param.name}`).join(", ")} }` : "{}";
4049
+ const actionCallForSearchParams = queryParameters.length > 0 ? pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }" : pathParameters.length > 0 ? `{ path: ${pathParamsBuild} }` : hasAnyParams ? actionCallString : "";
3899
4050
  return `/**
3900
4051
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
3901
4052
  * Features: URL state sync, infinite loading, optimistic updates
4053
+ * @param params - Named parameters object with path and query parameters
4054
+ * @param options - Query options
3902
4055
  * @returns useQuery result with data of type ${returnType}
3903
4056
  */
3904
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4057
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3905
4058
  const [searchParams] = useQueryStates(searchParamsParser)
3906
4059
  const { initialData, ...restOptions } = options ?? {}
3907
4060
 
3908
4061
  return useQuery({
3909
- queryKey: [...${queryKey}, searchParams],
4062
+ queryKey: [${queryKeyString}, searchParams],
3910
4063
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
3911
4064
  try {
3912
- ${queryParamsBuild}
3913
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "queryParams")}))
4065
+ ${queryParamsWithFallback}
4066
+ const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallForSearchParams}))
3914
4067
  return result
3915
4068
  } catch (error) {
3916
4069
  handleActionError(error)
@@ -3938,32 +4091,33 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
3938
4091
 
3939
4092
  /**
3940
4093
  * Infinite query version for paginated ${endpoint.path}
4094
+ * @param params - Named parameters object with path and query parameters
4095
+ * @param options - Query options
3941
4096
  * @returns useInfiniteQuery result with data of type ${returnType}
3942
4097
  */
3943
- export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4098
+ export function ${hookName.replace("use", "useInfinite")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
3944
4099
  const [searchParams] = useQueryStates(searchParamsParser)
3945
4100
  const { initialData, ...restOptions } = options ?? {}
3946
4101
 
3947
4102
  return useInfiniteQuery({
3948
- queryKey: [...${queryKey}, 'infinite', searchParams],
4103
+ queryKey: [${queryKeyString}, 'infinite', searchParams],
3949
4104
  initialPageParam: 1,
3950
4105
  queryFn: async ({ pageParam = 1, signal }: { pageParam?: number; signal?: AbortSignal }) => {
3951
4106
  try {
3952
- // Build query params object with only the parameters the endpoint expects
3953
- const queryParams: { ${queryParamTypes} } = {
4107
+ const queryParams = {
3954
4108
  ${queryParameters.map((param) => {
3955
4109
  if (param.name === "page" && hasPageParam) {
3956
4110
  return `${param.name}: pageParam`;
3957
4111
  } else if (param.name === "query") {
3958
- return `${param.name}: ${param.name} || searchParams.search || ''`;
4112
+ return `${param.name}: params?.query?.${param.name} || searchParams.search || ''`;
3959
4113
  } else if (param.name === "limit") {
3960
- return `${param.name}: ${param.name} !== undefined ? ${param.name} : searchParams.limit`;
4114
+ return `${param.name}: params?.query?.${param.name} !== undefined ? params.query.${param.name} : searchParams.limit`;
3961
4115
  } else {
3962
- return `${param.name}: ${param.name} !== undefined ? ${param.name} : undefined`;
4116
+ return `${param.name}: params?.query?.${param.name}`;
3963
4117
  }
3964
4118
  }).join(",\n ")}
3965
4119
  }
3966
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams.replace(queryParamObject, "queryParams")}))
4120
+ const result = await resolveActionResult<${returnType}>(${actionName}(${queryParameters.length > 0 ? pathParameters.length > 0 ? `{ path: ${pathParamsBuild}, query: queryParams }` : "{ query: queryParams }" : pathParameters.length > 0 ? `{ path: ${pathParamsBuild} }` : hasAnyParams ? actionCallString : ""}))
3967
4121
  return result
3968
4122
  } catch (error) {
3969
4123
  handleActionError(error)
@@ -4005,15 +4159,17 @@ export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.lengt
4005
4159
 
4006
4160
  /**
4007
4161
  * Suspense version for ${endpoint.path} - use in Server Components
4162
+ * @param params - Named parameters object with path and query parameters
4163
+ * @param options - Query options
4008
4164
  * @returns useSuspenseQuery result with data of type ${returnType}
4009
4165
  */
4010
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4166
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4011
4167
  const { initialData, ...restOptions } = options ?? {}
4012
4168
 
4013
4169
  return useSuspenseQuery({
4014
- queryKey: ${queryKey},
4170
+ queryKey: ${queryKeyString},
4015
4171
  queryFn: async () => {
4016
- const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallParams}))
4172
+ const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallString}))
4017
4173
  return result
4018
4174
  },
4019
4175
  staleTime: ${staleTime},
@@ -4025,16 +4181,18 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
4025
4181
  return `/**
4026
4182
  * Optimized query hook for ${endpoint.method} ${endpoint.path}
4027
4183
  * Features: Smart caching, error handling, type safety
4184
+ * @param params - Named parameters object with path and query parameters
4185
+ * @param options - Query options
4028
4186
  * @returns useQuery result with data of type ${returnType}
4029
4187
  */
4030
- export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4188
+ export function ${hookName}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4031
4189
  const { initialData, ...restOptions } = options ?? {}
4032
4190
 
4033
4191
  return useQuery({
4034
- queryKey: ${queryKey},
4192
+ queryKey: ${queryKeyString},
4035
4193
  queryFn: async ({ signal }: { signal?: AbortSignal }) => {
4036
4194
  try {
4037
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4195
+ const result = await resolveActionResult<${returnType}>(${actionName}(${hasAnyParams ? actionCallString : ""}))
4038
4196
  return result
4039
4197
  } catch (error) {
4040
4198
  handleActionError(error)
@@ -4062,15 +4220,17 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
4062
4220
 
4063
4221
  /**
4064
4222
  * Suspense version for ${endpoint.path}
4223
+ * @param params - Named parameters object with path and query parameters
4224
+ * @param options - Query options
4065
4225
  * @returns useSuspenseQuery result with data of type ${returnType}
4066
4226
  */
4067
- export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
4227
+ export function ${hookName.replace("use", "useSuspense")}(params${pathParameters.length > 0 ? "" : "?"}: ${paramsType}, options?: ${optionsType}) {
4068
4228
  const { initialData, ...restOptions } = options ?? {}
4069
4229
 
4070
4230
  return useSuspenseQuery({
4071
- queryKey: ${queryKey},
4231
+ queryKey: ${queryKeyString},
4072
4232
  queryFn: async () => {
4073
- const result = await resolveActionResult<${returnType}>(${actionCallParams === "{}" ? `${actionName}()` : `${actionName}(${actionCallParams})`})
4233
+ const result = await resolveActionResult<${returnType}>(${actionName}(${actionCallString}))
4074
4234
  return result
4075
4235
  },
4076
4236
  staleTime: ${staleTime},
@@ -4185,7 +4345,7 @@ ${invalidationCode}
4185
4345
  * Find related queries that should be invalidated when this mutation runs
4186
4346
  */
4187
4347
  findRelatedQueries(endpoint, context) {
4188
- if (!context?.schema?.endpoints) {
4348
+ if (!context?.schema.endpoints) {
4189
4349
  return [];
4190
4350
  }
4191
4351
  const relatedQueries = [];
@@ -4319,7 +4479,6 @@ ${invalidationCode}
4319
4479
  buildActionCallParams(endpoint, isMutation) {
4320
4480
  const pathParameters = endpoint.parameters.filter((parameter) => parameter.in === "path");
4321
4481
  const queryParameters = endpoint.parameters.filter((parameter) => parameter.in === "query");
4322
- !!endpoint.requestBody;
4323
4482
  if (isMutation) {
4324
4483
  return "variables";
4325
4484
  }
@@ -4400,13 +4559,13 @@ ${invalidationCode}
4400
4559
  import { useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, type UseQueryOptions, type UseMutationOptions, type UseInfiniteQueryOptions, type UseSuspenseQueryOptions, type QueryKey, type QueryFunction } from '@tanstack/react-query'
4401
4560
 
4402
4561
  /**
4403
- * Enhanced React Query wrapper hook with Next.js 16.0.1 optimizations
4562
+ * Enhanced React Query wrapper hook with Next.js 16.0.7 optimizations
4404
4563
  * Provides consistent defaults across all queries following best practices
4405
4564
  *
4406
4565
  * Features:
4407
4566
  * - React Query v5: Uses gcTime instead of cacheTime
4408
4567
  * - React Query v5: Uses placeholderData instead of keepPreviousData
4409
- * - Next.js 16.0.1: Optimized for App Router and Server Components
4568
+ * - Next.js 16.0.7: Optimized for App Router and Server Components
4410
4569
  */
4411
4570
  export function useBridgeQuery<TData = unknown, TError = Error>(
4412
4571
  queryKey: QueryKey,
@@ -4463,7 +4622,7 @@ export function useBridgeInfiniteQuery<TData = unknown, TError = Error, TPagePar
4463
4622
 
4464
4623
  /**
4465
4624
  * Enhanced suspense query wrapper
4466
- * Next.js 16.0.1: Optimized for Server Components with Suspense
4625
+ * Next.js 16.0.7: Optimized for Server Components with Suspense
4467
4626
  */
4468
4627
  export function useBridgeSuspenseQuery<TData = unknown, TError = Error>(
4469
4628
  queryKey: QueryKey,
@@ -4519,7 +4678,7 @@ var AuthGenerator = class {
4519
4678
  __name(this, "AuthGenerator");
4520
4679
  }
4521
4680
  buildImportPath(relativePath) {
4522
- const outputDirectory = this.configuration.outputDir || "generated";
4681
+ const outputDirectory = this.configuration.outputDir ?? "generated";
4523
4682
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
4524
4683
  let importBasePath = outputDirectory;
4525
4684
  if (importBasePath.startsWith("src/")) {
@@ -4527,11 +4686,11 @@ var AuthGenerator = class {
4527
4686
  }
4528
4687
  return `@/${importBasePath}/${cleanPath}`;
4529
4688
  }
4530
- async generate(context) {
4689
+ generate(context) {
4531
4690
  const { config, schema } = context;
4532
4691
  const authConfig = config.auth;
4533
4692
  if (!authConfig?.enabled) {
4534
- return [];
4693
+ return Promise.resolve([]);
4535
4694
  }
4536
4695
  const files = [];
4537
4696
  const authEndpoints = this.findAuthEndpoints(schema.endpoints);
@@ -4546,7 +4705,7 @@ var AuthGenerator = class {
4546
4705
  files.push(...this.generateAuthComponents(authEndpoints));
4547
4706
  files.push(this.generateAuthMiddleware());
4548
4707
  files.push(this.generateAuthContext());
4549
- return files;
4708
+ return Promise.resolve(files);
4550
4709
  }
4551
4710
  findAuthEndpoints(endpoints) {
4552
4711
  const authEndpoints = {};
@@ -4579,12 +4738,12 @@ var AuthGenerator = class {
4579
4738
  }
4580
4739
  return userEndpoints;
4581
4740
  }
4582
- generateAuthSchemas(authEndpoints, schema) {
4741
+ generateAuthSchemas(_authEndpoints, _schema) {
4583
4742
  this.buildImportPath("schemas");
4584
- const loginRequestSchema = authEndpoints.login?.requestBody?.content?.find(
4743
+ const loginRequestSchema = _authEndpoints.login?.requestBody?.content?.find(
4585
4744
  (c) => c.type === "application/json"
4586
4745
  )?.schema;
4587
- const loginResponseSchema = authEndpoints.login?.responses?.find(
4746
+ const loginResponseSchema = _authEndpoints.login?.responses?.find(
4588
4747
  (r) => r.statusCode === "200"
4589
4748
  )?.content?.[0]?.schema;
4590
4749
  const content = `import { z } from "zod"
@@ -4685,7 +4844,7 @@ export type Session = z.infer<typeof sessionSchema>`;
4685
4844
  }
4686
4845
  };
4687
4846
  }
4688
- generateAuthTypes(authEndpoints, schema) {
4847
+ generateAuthTypes(_authEndpoints, _schema) {
4689
4848
  const schemasImport = this.buildImportPath("auth/schemas");
4690
4849
  const content = `// Auto-generated authentication types
4691
4850
  import type {
@@ -5231,7 +5390,7 @@ export const useRequireAuth = (redirectTo?: string) => {
5231
5390
  }
5232
5391
  };
5233
5392
  }
5234
- generateAuthActions(authEndpoints, userEndpoints) {
5393
+ generateAuthActions(_authEndpoints, _userEndpoints) {
5235
5394
  const safeActionImport = this.buildImportPath("lib/safe-action");
5236
5395
  const schemasImport = this.buildImportPath("auth/schemas");
5237
5396
  const clientImport = this.buildImportPath("auth/client");
@@ -5463,7 +5622,7 @@ export const useCredentialsLogin = () => {
5463
5622
  }
5464
5623
  };
5465
5624
  }
5466
- generateAuthComponents(authEndpoints) {
5625
+ generateAuthComponents(_authEndpoints) {
5467
5626
  const loginForm = {
5468
5627
  path: "auth/components/login-form.tsx",
5469
5628
  content: `"use client"
@@ -5583,7 +5742,6 @@ export function LoginForm() {
5583
5742
  return [loginForm];
5584
5743
  }
5585
5744
  generateAuthMiddleware() {
5586
- this.buildImportPath("auth/utils");
5587
5745
  const content = `import { NextResponse } from "next/server"
5588
5746
  import type { NextRequest } from "next/server"
5589
5747
 
@@ -5951,9 +6109,10 @@ var SchemaAnalyzer = class {
5951
6109
  }
5952
6110
  if (response.description) {
5953
6111
  const errorMatch = response.description.match(/error[_\s]?code[:\s]+(\w+)/i);
5954
- if (errorMatch) {
5955
- errorCodes.set(errorMatch[1].toLowerCase(), {
5956
- code: errorMatch[1],
6112
+ if (errorMatch?.[1]) {
6113
+ const errorCode = errorMatch[1];
6114
+ errorCodes.set(errorCode.toLowerCase(), {
6115
+ code: errorCode,
5957
6116
  status,
5958
6117
  message: response.description
5959
6118
  });
@@ -6039,7 +6198,7 @@ var SchemaAnalyzer = class {
6039
6198
  const endpoints = {};
6040
6199
  for (const endpoint of this.schema.endpoints) {
6041
6200
  const path3 = endpoint.path.toLowerCase();
6042
- const operationId = (endpoint.operationId || "").toLowerCase();
6201
+ const operationId = (endpoint.operationId ?? "").toLowerCase();
6043
6202
  if ((path3.includes("/auth/login/credentials") || operationId.includes("logincredentials") || operationId.includes("signin")) && endpoint.method === "POST") {
6044
6203
  endpoints.loginCredentials = endpoint;
6045
6204
  } else if ((path3.includes("/auth/login") || operationId.includes("login")) && endpoint.method === "POST" && !endpoints.loginCredentials) {
@@ -6087,12 +6246,12 @@ var SchemaAnalyzer = class {
6087
6246
  extractSessionConfig() {
6088
6247
  const config = {};
6089
6248
  const sessionEndpoints = this.schema.endpoints.filter(
6090
- (e) => e.path.toLowerCase().includes("/session") || (e.operationId || "").toLowerCase().includes("session")
6249
+ (e) => e.path.toLowerCase().includes("/session") || (e.operationId ?? "").toLowerCase().includes("session")
6091
6250
  );
6092
6251
  for (const endpoint of sessionEndpoints) {
6093
6252
  for (const response of endpoint.responses) {
6094
6253
  if (response.headers) {
6095
- for (const [headerName, headerDef] of Object.entries(response.headers)) {
6254
+ for (const [headerName, _headerDef] of Object.entries(response.headers)) {
6096
6255
  if (headerName.toLowerCase().includes("expires") || headerName.toLowerCase().includes("max-age")) ;
6097
6256
  }
6098
6257
  }
@@ -6172,7 +6331,7 @@ var SchemaAnalyzer = class {
6172
6331
  /**
6173
6332
  * Check if OAuth provider is supported
6174
6333
  */
6175
- isOAuthProviderSupported(provider) {
6334
+ isOAuthProviderSupported(_provider) {
6176
6335
  const extractedEndpoints = this.extractAuthEndpoints();
6177
6336
  return !!(extractedEndpoints.oauthAuthorize && extractedEndpoints.oauthCallback);
6178
6337
  }
@@ -6254,7 +6413,7 @@ var SchemaAnalyzer = class {
6254
6413
  errorCodes.set(code.toLowerCase(), {
6255
6414
  code,
6256
6415
  status,
6257
- message: schema.properties?.detail?.default || schema.properties?.message?.default || ""
6416
+ message: schema.properties?.detail?.default ?? schema.properties?.message?.default ?? ""
6258
6417
  });
6259
6418
  });
6260
6419
  }
@@ -6263,9 +6422,10 @@ var SchemaAnalyzer = class {
6263
6422
  const detail = schema.properties.detail;
6264
6423
  if (typeof detail === "string") {
6265
6424
  const codeMatch = detail.match(/(\w+)[_\s]?error/i);
6266
- if (codeMatch) {
6267
- errorCodes.set(codeMatch[1].toLowerCase(), {
6268
- code: codeMatch[1],
6425
+ if (codeMatch?.[1]) {
6426
+ const errorCode = codeMatch[1];
6427
+ errorCodes.set(errorCode.toLowerCase(), {
6428
+ code: errorCode,
6269
6429
  status,
6270
6430
  message: detail
6271
6431
  });
@@ -6277,11 +6437,11 @@ var SchemaAnalyzer = class {
6277
6437
  if (!schema || typeof schema !== "object") return;
6278
6438
  if (schema.properties?.file) {
6279
6439
  const fileSchema = schema.properties.file;
6280
- if (fileSchema.maxSize || fileSchema["x-max-size"]) {
6281
- config.maxSize = fileSchema.maxSize || fileSchema["x-max-size"];
6440
+ if (fileSchema.maxSize ?? fileSchema["x-max-size"]) {
6441
+ config.maxSize = fileSchema.maxSize ?? fileSchema["x-max-size"];
6282
6442
  }
6283
- if (fileSchema.allowedTypes || fileSchema["x-allowed-types"]) {
6284
- config.allowedTypes = fileSchema.allowedTypes || fileSchema["x-allowed-types"];
6443
+ if (fileSchema.allowedTypes ?? fileSchema["x-allowed-types"]) {
6444
+ config.allowedTypes = fileSchema.allowedTypes ?? fileSchema["x-allowed-types"];
6285
6445
  }
6286
6446
  }
6287
6447
  if (schema["x-file-constraints"]) {
@@ -6301,7 +6461,7 @@ var NextAuthGenerator = class {
6301
6461
  analyzer;
6302
6462
  accountStatusPatterns;
6303
6463
  buildImportPath(relativePath) {
6304
- const outputDirectory = this.configuration.outputDir || "generated";
6464
+ const outputDirectory = this.configuration.outputDir ?? "generated";
6305
6465
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
6306
6466
  let importBasePath = outputDirectory;
6307
6467
  if (importBasePath.startsWith("src/")) {
@@ -6309,11 +6469,11 @@ var NextAuthGenerator = class {
6309
6469
  }
6310
6470
  return `@/${importBasePath}/${cleanPath}`;
6311
6471
  }
6312
- async generate(context) {
6472
+ generate(context) {
6313
6473
  const { config, schema } = context;
6314
6474
  const authConfig = config.auth;
6315
6475
  if (!authConfig?.enabled || authConfig.provider !== "next-auth") {
6316
- return [];
6476
+ return Promise.resolve([]);
6317
6477
  }
6318
6478
  this.analyzer = new SchemaAnalyzer(schema);
6319
6479
  this.accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
@@ -6330,7 +6490,7 @@ var NextAuthGenerator = class {
6330
6490
  console.warn("These features will be disabled in generated code.\n");
6331
6491
  }
6332
6492
  const detectedOAuthProviders = this.analyzer.extractOAuthProviders();
6333
- const configuredOAuthProviders = authConfig.oauth?.providers || [];
6493
+ const configuredOAuthProviders = authConfig.oauth?.providers ?? [];
6334
6494
  const validOAuthProviders = configuredOAuthProviders.filter(
6335
6495
  (provider) => this.analyzer.isOAuthProviderSupported(provider)
6336
6496
  );
@@ -6341,7 +6501,7 @@ var NextAuthGenerator = class {
6341
6501
  console.warn(
6342
6502
  `\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.`
6343
6503
  );
6344
- return files;
6504
+ return Promise.resolve(files);
6345
6505
  }
6346
6506
  files.push(this.generateNextAuthConfig(
6347
6507
  extractedEndpoints,
@@ -6354,7 +6514,7 @@ var NextAuthGenerator = class {
6354
6514
  if (hasPasskeys) {
6355
6515
  files.push(this.generatePasskeyUtils(extractedEndpoints));
6356
6516
  }
6357
- return files;
6517
+ return Promise.resolve(files);
6358
6518
  }
6359
6519
  findAuthEndpoints(endpoints) {
6360
6520
  const authEndpoints = {};
@@ -6457,14 +6617,14 @@ var NextAuthGenerator = class {
6457
6617
  }
6458
6618
  generateNextAuthConfig(extractedEndpoints, oauthProviders, hasMFA, hasPasskeys) {
6459
6619
  const authConfig = this.configuration.auth;
6460
- const apiBaseUrl = this.configuration.api?.baseUrl || "http://localhost:8000";
6620
+ const apiBaseUrl = this.configuration.api.baseUrl || "http://localhost:8000";
6461
6621
  const apiUrl = `process.env.NEXT_PUBLIC_API_URL || '${apiBaseUrl}'`;
6462
6622
  const hasGoogle = oauthProviders.includes("google");
6463
6623
  const hasGitHub = oauthProviders.includes("github");
6464
6624
  oauthProviders.includes("discord");
6465
6625
  oauthProviders.includes("microsoft");
6466
6626
  oauthProviders.includes("apple");
6467
- const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses } = this.accountStatusPatterns;
6627
+ const { activeStatuses, inactiveStatuses, suspendedStatuses, lockedStatuses: _lockedStatuses } = this.accountStatusPatterns;
6468
6628
  this.analyzer.extractErrorCodes();
6469
6629
  const sessionStrategy = authConfig.session?.strategy || "jwt";
6470
6630
  const sessionMaxAge = authConfig.session?.maxAge || 7 * 24 * 60 * 60;
@@ -7013,7 +7173,7 @@ export async function authenticateWithPasskey(email?: string) {
7013
7173
  }
7014
7174
  };
7015
7175
  }
7016
- generateAuthTypes(authEndpoints, accountStatusPatterns) {
7176
+ generateAuthTypes(_authEndpoints, _accountStatusPatterns) {
7017
7177
  const content = `/**
7018
7178
  * Authentication Types
7019
7179
  * Auto-generated by Mulink
@@ -7084,7 +7244,7 @@ export class AccountInactiveError extends AuthError {
7084
7244
  }
7085
7245
  };
7086
7246
  }
7087
- generateAuthUtils(authEndpoints) {
7247
+ generateAuthUtils(_authEndpoints) {
7088
7248
  const content = `/**
7089
7249
  * Authentication Utilities
7090
7250
  * Auto-generated by Mulink
@@ -7137,7 +7297,7 @@ export async function requireAuth() {
7137
7297
  }
7138
7298
  };
7139
7299
  }
7140
- generatePasskeyUtils(passkeyEndpoints) {
7300
+ generatePasskeyUtils(_passkeyEndpoints) {
7141
7301
  const content = `/**
7142
7302
  * Passkey (WebAuthn) Utilities
7143
7303
  * Auto-generated by Mulink
@@ -7190,7 +7350,7 @@ var MiddlewareGenerator = class {
7190
7350
  __name(this, "MiddlewareGenerator");
7191
7351
  }
7192
7352
  buildImportPath(relativePath) {
7193
- const outputDirectory = this.configuration.outputDir || "generated";
7353
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7194
7354
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7195
7355
  let importBasePath = outputDirectory;
7196
7356
  if (importBasePath.startsWith("src/")) {
@@ -7198,7 +7358,7 @@ var MiddlewareGenerator = class {
7198
7358
  }
7199
7359
  return `@/${importBasePath}/${cleanPath}`;
7200
7360
  }
7201
- async generate(context) {
7361
+ generate(_context) {
7202
7362
  const files = [];
7203
7363
  files.push(this.generateMainMiddleware());
7204
7364
  files.push(this.generateRateLimitMiddleware());
@@ -7206,7 +7366,7 @@ var MiddlewareGenerator = class {
7206
7366
  files.push(this.generateSecurityMiddleware());
7207
7367
  files.push(this.generateLoggingMiddleware());
7208
7368
  files.push(this.generateApiMiddleware());
7209
- return files;
7369
+ return Promise.resolve(files);
7210
7370
  }
7211
7371
  generateMainMiddleware() {
7212
7372
  const authImport = this.buildImportPath("auth/middleware");
@@ -7613,7 +7773,7 @@ var UploadGenerator = class {
7613
7773
  }
7614
7774
  analyzer;
7615
7775
  buildImportPath(relativePath) {
7616
- const outputDirectory = this.configuration.outputDir || "generated";
7776
+ const outputDirectory = this.configuration.outputDir ?? "generated";
7617
7777
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
7618
7778
  let importBasePath = outputDirectory;
7619
7779
  if (importBasePath.startsWith("src/")) {
@@ -7621,19 +7781,19 @@ var UploadGenerator = class {
7621
7781
  }
7622
7782
  return `@/${importBasePath}/${cleanPath}`;
7623
7783
  }
7624
- async generate(context) {
7784
+ generate(context) {
7625
7785
  const { schema } = context;
7626
7786
  const generatedFiles = [];
7627
7787
  this.analyzer = new SchemaAnalyzer(schema);
7628
7788
  const uploadEndpoints = schema.endpoints.filter(
7629
- (endpoint) => endpoint.requestBody?.content?.some(
7789
+ (endpoint) => endpoint.requestBody?.content.some(
7630
7790
  (content) => content.type === "multipart/form-data" || content.type === "application/octet-stream"
7631
7791
  )
7632
7792
  );
7633
7793
  if (uploadEndpoints.length === 0 || !this.configuration.uploads?.enabled) {
7634
- return generatedFiles;
7794
+ return Promise.resolve(generatedFiles);
7635
7795
  }
7636
- const presignedConfig = this.configuration.uploads?.presignedUploads;
7796
+ const presignedConfig = this.configuration.uploads.presignedUploads;
7637
7797
  if (presignedConfig?.enabled) {
7638
7798
  const isPresignedSupported = this.analyzer.isPresignedUploadsSupported();
7639
7799
  if (!isPresignedSupported) {
@@ -7644,14 +7804,14 @@ var UploadGenerator = class {
7644
7804
  }
7645
7805
  const extractedUploadConfig = this.analyzer.extractUploadConfig();
7646
7806
  const presignedEnabled = presignedConfig?.enabled && this.analyzer.isPresignedUploadsSupported();
7647
- const uploadProvider = this.configuration.uploads?.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7648
- const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads?.strategy || "standard";
7807
+ const uploadProvider = this.configuration.uploads.provider || (extractedUploadConfig.presignedEndpoint ? "minio" : "standard");
7808
+ const uploadStrategy = presignedEnabled ? "presigned" : this.configuration.uploads.strategy || "standard";
7649
7809
  presignedEnabled ? {
7650
- presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig?.presignEndpoint || "/api/v1/files/presign-upload",
7651
- fallbackToBackend: presignedConfig?.fallbackToBackend !== false
7810
+ presignEndpoint: extractedUploadConfig.presignedEndpoint || presignedConfig.presignEndpoint || "/api/v1/files/presign-upload",
7811
+ fallbackToBackend: presignedConfig.fallbackToBackend !== false
7652
7812
  } : {
7653
7813
  };
7654
- const progressConfig = this.configuration.uploads?.progressTracking || {
7814
+ const progressConfig = this.configuration.uploads.progressTracking || {
7655
7815
  enabled: true,
7656
7816
  useXHR: true
7657
7817
  };
@@ -7668,7 +7828,7 @@ var UploadGenerator = class {
7668
7828
  progressConfig
7669
7829
  ));
7670
7830
  }
7671
- return generatedFiles;
7831
+ return Promise.resolve(generatedFiles);
7672
7832
  }
7673
7833
  /**
7674
7834
  * Find presigned upload endpoint in schema
@@ -7681,7 +7841,7 @@ var UploadGenerator = class {
7681
7841
  return pathLower.includes("presign") || pathLower.includes("presigned") || operationIdLower.includes("presign") || operationIdLower.includes("presigned");
7682
7842
  }) || null;
7683
7843
  }
7684
- generateUploadUtilities(uploadProvider, uploadStrategy, presignedEndpoint) {
7844
+ generateUploadUtilities(_uploadProvider, _uploadStrategy, _presignedEndpoint) {
7685
7845
  const { uploads } = this.configuration;
7686
7846
  const extractedConfig = this.analyzer.extractUploadConfig();
7687
7847
  const maxSize = uploads?.security?.maxSize || (extractedConfig.maxSize ? `${extractedConfig.maxSize}MB` : "10MB");
@@ -8032,8 +8192,8 @@ async function uploadViaBackendApi(
8032
8192
  xhr.responseType = 'json'
8033
8193
  // Use base URL from environment or configuration
8034
8194
  const baseUrl = typeof window !== 'undefined'
8035
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8036
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8195
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8196
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8037
8197
  xhr.open('POST', \`\${baseUrl}${endpoint.path}\`)
8038
8198
  xhr.send(formData)
8039
8199
  })
@@ -8308,8 +8468,8 @@ export function ${hookName}Upload(options?: {
8308
8468
  }
8309
8469
  generateUseUploadFileHook(uploadProvider, uploadStrategy, context) {
8310
8470
  const uploadUtilsImport = this.buildImportPath("services/uploadUtils");
8311
- const uploadEndpoints = context?.schema?.endpoints?.filter(
8312
- (e) => e.metadata?.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8471
+ const uploadEndpoints = context?.schema.endpoints.filter(
8472
+ (e) => e.metadata.fileUpload || e.path.toLowerCase().includes("upload") || e.operationId && e.operationId.toLowerCase().includes("upload")
8313
8473
  ) || [];
8314
8474
  const firstUploadEndpoint = uploadEndpoints[0];
8315
8475
  let uploadMethodName = "uploadFile";
@@ -8449,7 +8609,7 @@ var ErrorHandlerGenerator = class {
8449
8609
  }
8450
8610
  analyzer;
8451
8611
  buildImportPath(relativePath) {
8452
- const outputDirectory = this.configuration.outputDir || "generated";
8612
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8453
8613
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8454
8614
  let importBasePath = outputDirectory;
8455
8615
  if (importBasePath.startsWith("src/")) {
@@ -8457,18 +8617,18 @@ var ErrorHandlerGenerator = class {
8457
8617
  }
8458
8618
  return `@/${importBasePath}/${cleanPath}`;
8459
8619
  }
8460
- async generate(context) {
8620
+ generate(context) {
8461
8621
  const files = [];
8462
- const { schema, config } = context;
8622
+ const { schema } = context;
8463
8623
  const { api } = this.configuration;
8464
- const errorHandling = api?.errorHandling;
8624
+ const errorHandling = api.errorHandling;
8465
8625
  this.analyzer = new SchemaAnalyzer(schema);
8466
8626
  const errorCodes = this.analyzer.extractErrorCodes();
8467
8627
  const accountStatusPatterns = this.analyzer.extractAccountStatusPatterns();
8468
8628
  const extractedAuthEndpoints = this.analyzer.extractAuthEndpoints();
8469
8629
  const hasAuthEndpoints = !!(extractedAuthEndpoints.login || extractedAuthEndpoints.loginCredentials);
8470
8630
  const hasAuthErrors = errorCodes.size > 0 || (accountStatusPatterns.inactiveStatuses.length > 0 || accountStatusPatterns.suspendedStatuses.length > 0);
8471
- const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling?.generateAuthErrorHandler !== false);
8631
+ const shouldGenerate = hasAuthEndpoints && (errorHandling?.generateAuthErrorHandler !== false && errorHandling?.enableAuthErrorHandling !== false || hasAuthErrors && errorHandling.generateAuthErrorHandler !== false);
8472
8632
  if (shouldGenerate) {
8473
8633
  files.push(this.generateAuthErrorHandler(errorCodes, accountStatusPatterns));
8474
8634
  } else if (errorHandling?.enableAuthErrorHandling === true && !hasAuthEndpoints) {
@@ -8476,11 +8636,11 @@ var ErrorHandlerGenerator = class {
8476
8636
  `\u26A0\uFE0F Auth error handling is enabled but auth endpoints are not found in OpenAPI schema. Auth error handler will not be generated.`
8477
8637
  );
8478
8638
  }
8479
- return files;
8639
+ return Promise.resolve(files);
8480
8640
  }
8481
8641
  generateAuthErrorHandler(errorCodes, accountStatusPatterns) {
8482
8642
  const authPath = this.configuration.auth?.authPath || "@/lib/auth";
8483
- const errorHandling = this.configuration.api?.errorHandling;
8643
+ const errorHandling = this.configuration.api.errorHandling;
8484
8644
  const authErrorHandlerPath = errorHandling?.authErrorHandlerPath || "@/lib/auth-error-handler";
8485
8645
  let handlerOutputPath = authErrorHandlerPath;
8486
8646
  if (handlerOutputPath.startsWith("@/")) {
@@ -8693,7 +8853,7 @@ var SSEGenerator = class {
8693
8853
  }
8694
8854
  analyzer;
8695
8855
  buildImportPath(relativePath) {
8696
- const outputDirectory = this.configuration.outputDir || "generated";
8856
+ const outputDirectory = this.configuration.outputDir ?? "generated";
8697
8857
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
8698
8858
  let importBasePath = outputDirectory;
8699
8859
  if (importBasePath.startsWith("src/")) {
@@ -8725,11 +8885,11 @@ var SSEGenerator = class {
8725
8885
  );
8726
8886
  return hasEventStream;
8727
8887
  }
8728
- async generate(context) {
8888
+ generate(context) {
8729
8889
  const { schema } = context;
8730
8890
  const generatedFiles = [];
8731
8891
  this.analyzer = new SchemaAnalyzer(schema);
8732
- const streamingConfig = this.configuration.framework?.streaming;
8892
+ const streamingConfig = this.configuration.framework.streaming;
8733
8893
  const hasStreamingEndpoints = schema.endpoints.some((endpoint) => this.isSSEEndpoint(endpoint));
8734
8894
  if (streamingConfig?.enabled === true && !hasStreamingEndpoints) {
8735
8895
  console.warn(
@@ -8738,11 +8898,11 @@ var SSEGenerator = class {
8738
8898
  }
8739
8899
  const shouldEnableStreaming = streamingConfig?.enabled === true ? hasStreamingEndpoints : streamingConfig?.enabled !== false && hasStreamingEndpoints;
8740
8900
  if (!shouldEnableStreaming || streamingConfig?.sse?.enabled === false || !hasStreamingEndpoints) {
8741
- return generatedFiles;
8901
+ return Promise.resolve(generatedFiles);
8742
8902
  }
8743
8903
  const sseEndpoints = schema.endpoints.filter((endpoint) => this.isSSEEndpoint(endpoint));
8744
8904
  if (sseEndpoints.length === 0) {
8745
- return generatedFiles;
8905
+ return Promise.resolve(generatedFiles);
8746
8906
  }
8747
8907
  for (const endpoint of sseEndpoints) {
8748
8908
  generatedFiles.push(this.generateSSEClientMethod(endpoint));
@@ -8751,7 +8911,7 @@ var SSEGenerator = class {
8751
8911
  for (const [tag, tagEndpoints] of Object.entries(endpointsByTag)) {
8752
8912
  generatedFiles.push(this.generateSSEHooks(tag, tagEndpoints));
8753
8913
  }
8754
- return generatedFiles;
8914
+ return Promise.resolve(generatedFiles);
8755
8915
  }
8756
8916
  generateSSEClientMethod(endpoint) {
8757
8917
  const operationId = endpoint.operationId || endpoint.id;
@@ -8786,8 +8946,8 @@ var SSEGenerator = class {
8786
8946
  }): EventSource => {
8787
8947
  ${pathParamNames.length > 0 ? `const { ${pathParamNames.join(", ")}, ...restOptions } = options.params || {}
8788
8948
  ` : ""}const baseUrl = typeof window !== 'undefined'
8789
- ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api?.baseUrl || "http://localhost:8000"}')
8790
- : '${this.configuration.api?.baseUrl || "http://localhost:8000"}'
8949
+ ? (process.env.NEXT_PUBLIC_API_URL || '${this.configuration.api.baseUrl || "http://localhost:8000"}')
8950
+ : '${this.configuration.api.baseUrl || "http://localhost:8000"}'
8791
8951
  const sseUrl = \`\${baseUrl}${urlConstruction}\`
8792
8952
 
8793
8953
  // Create EventSource connection
@@ -8833,7 +8993,7 @@ var SSEGenerator = class {
8833
8993
  generateSSEHooks(tag, endpoints) {
8834
8994
  const tagName = toValidIdentifier(tag);
8835
8995
  const clientImport = this.buildImportPath("client");
8836
- const streamingConfig = this.configuration.framework?.streaming?.sse;
8996
+ const streamingConfig = this.configuration.framework.streaming?.sse;
8837
8997
  const autoReconnect = streamingConfig?.autoReconnect !== false;
8838
8998
  const reconnectDelay = streamingConfig?.reconnectDelay || 3e3;
8839
8999
  const maxReconnectAttempts = streamingConfig?.maxReconnectAttempts || 5;
@@ -9026,7 +9186,7 @@ var NextJsCodeGenerator = class {
9026
9186
  __name(this, "NextJsCodeGenerator");
9027
9187
  }
9028
9188
  buildImportPath(relativePath) {
9029
- const outputDirectory = this.configuration.outputDir || "generated";
9189
+ const outputDirectory = this.configuration.outputDir ?? "generated";
9030
9190
  const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
9031
9191
  let importBasePath = outputDirectory;
9032
9192
  if (importBasePath.startsWith("src/")) {
@@ -9040,9 +9200,9 @@ var NextJsCodeGenerator = class {
9040
9200
  path: file.path,
9041
9201
  metadata: {
9042
9202
  ...file.metadata,
9043
- exports: file.metadata?.exports || [],
9044
- imports: file.metadata?.imports || [],
9045
- dependencies: file.metadata?.dependencies?.map((dependency) => {
9203
+ exports: file.metadata?.exports ?? [],
9204
+ imports: file.metadata?.imports ?? [],
9205
+ dependencies: file.metadata?.dependencies.map((dependency) => {
9046
9206
  if (dependency.startsWith("@/generated/")) {
9047
9207
  return dependency;
9048
9208
  }
@@ -9051,7 +9211,7 @@ var NextJsCodeGenerator = class {
9051
9211
  return `@/generated/${relativePart}`;
9052
9212
  }
9053
9213
  return dependency;
9054
- }) || []
9214
+ }) ?? []
9055
9215
  }
9056
9216
  }));
9057
9217
  }
@@ -9084,11 +9244,11 @@ var NextJsCodeGenerator = class {
9084
9244
  const uploadGenerator = new UploadGenerator(this.configuration);
9085
9245
  generatedFiles.push(...await uploadGenerator.generate(context));
9086
9246
  }
9087
- if (this.configuration.api?.errorHandling?.generateAuthErrorHandler !== false) {
9247
+ if (this.configuration.api.errorHandling?.generateAuthErrorHandler !== false) {
9088
9248
  const errorHandlerGenerator = new ErrorHandlerGenerator(this.configuration);
9089
9249
  generatedFiles.push(...await errorHandlerGenerator.generate(context));
9090
9250
  }
9091
- if (this.configuration.framework?.streaming?.enabled) {
9251
+ if (this.configuration.framework.streaming?.enabled) {
9092
9252
  const sseGenerator = new SSEGenerator(this.configuration);
9093
9253
  generatedFiles.push(...await sseGenerator.generate(context));
9094
9254
  }
@@ -9098,14 +9258,14 @@ var NextJsCodeGenerator = class {
9098
9258
  throw new GenerationError(`Failed to generate Next.js files: ${errorMessage}`);
9099
9259
  }
9100
9260
  }
9101
- async generateSafeActionClient() {
9261
+ generateSafeActionClient() {
9102
9262
  const safeActionContent = `import { DEFAULT_SERVER_ERROR_MESSAGE, createSafeActionClient } from "next-safe-action";
9103
9263
  import { headers } from "next/headers";
9104
9264
  import { z } from "zod";
9105
9265
 
9106
9266
  /**
9107
9267
  * Enhanced Action Error class for better error handling
9108
- * Follows Next.js 16.0.1 best practices
9268
+ * Follows Next.js 16.0.7 best practices
9109
9269
  */
9110
9270
  export class ActionError extends Error {
9111
9271
  constructor(
@@ -9142,7 +9302,7 @@ export const actionClient = createSafeActionClient({
9142
9302
 
9143
9303
  /**
9144
9304
  * Enhanced action client with metadata support
9145
- * Next.js 16.0.1: Supports metadata for better action tracking and rate limiting
9305
+ * Next.js 16.0.7: Supports metadata for better action tracking and rate limiting
9146
9306
  */
9147
9307
  export const actionClientWithMeta = createSafeActionClient({
9148
9308
  handleServerError(e) {
@@ -9163,7 +9323,7 @@ export const actionClientWithMeta = createSafeActionClient({
9163
9323
  requests: z.number().int().positive().describe('Number of requests allowed'),
9164
9324
  window: z.string().describe('Time window (e.g., "10s", "1m", "1h")'),
9165
9325
  }).optional().describe('Rate limiting configuration'),
9166
- cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.1)'),
9326
+ cacheTags: z.array(z.string()).optional().describe('Cache tags for invalidation (Next.js 16.0.7)'),
9167
9327
  });
9168
9328
  },
9169
9329
  });
@@ -9254,7 +9414,7 @@ async function getCurrentUser() {
9254
9414
  // Implement your authentication logic here
9255
9415
  return null;
9256
9416
  }`;
9257
- return [
9417
+ return Promise.resolve([
9258
9418
  {
9259
9419
  path: "lib/safe-action.ts",
9260
9420
  content: safeActionContent,
@@ -9265,7 +9425,7 @@ async function getCurrentUser() {
9265
9425
  dependencies: []
9266
9426
  }
9267
9427
  }
9268
- ];
9428
+ ]);
9269
9429
  }
9270
9430
  };
9271
9431
  var FileSystemManager = class {
@@ -9273,7 +9433,7 @@ var FileSystemManager = class {
9273
9433
  __name(this, "FileSystemManager");
9274
9434
  }
9275
9435
  async writeFile(filePath, content, options = {}) {
9276
- if (!filePath?.trim()) {
9436
+ if (!filePath.trim()) {
9277
9437
  throw new Error("File path is required and cannot be empty");
9278
9438
  }
9279
9439
  if (typeof content !== "string") {
@@ -9310,7 +9470,7 @@ var FileSystemManager = class {
9310
9470
  }
9311
9471
  }
9312
9472
  async readFile(filePath, encoding = "utf8") {
9313
- if (!filePath?.trim()) {
9473
+ if (!filePath.trim()) {
9314
9474
  throw new Error("File path is required and cannot be empty");
9315
9475
  }
9316
9476
  try {
@@ -9337,7 +9497,7 @@ var FileSystemManager = class {
9337
9497
  }
9338
9498
  }
9339
9499
  async getFileHash(filePath) {
9340
- if (!filePath?.trim()) {
9500
+ if (!filePath.trim()) {
9341
9501
  throw new Error("File path is required and cannot be empty");
9342
9502
  }
9343
9503
  try {
@@ -9363,7 +9523,7 @@ var FileSystemManager = class {
9363
9523
  }
9364
9524
  }
9365
9525
  async findFiles(dir, pattern, recursive = true) {
9366
- if (!dir?.trim()) {
9526
+ if (!dir.trim()) {
9367
9527
  throw new Error("Directory path is required and cannot be empty");
9368
9528
  }
9369
9529
  if (!(pattern instanceof RegExp)) {
@@ -9406,16 +9566,52 @@ var BridgeCore = class {
9406
9566
  logger;
9407
9567
  schemaParser;
9408
9568
  fileManager;
9569
+ /**
9570
+ * Creates a new instance of BridgeCore
9571
+ *
9572
+ * Initializes all required dependencies including logger, schema parser, and file manager.
9573
+ * All dependencies are readonly to ensure immutability and thread safety.
9574
+ */
9409
9575
  constructor() {
9410
9576
  this.logger = new BridgeLogger({ prefix: "\u{1F517} Mulink" });
9411
9577
  this.schemaParser = new OpenApiSchemaParser();
9412
9578
  this.fileManager = new FileSystemManager();
9413
9579
  }
9580
+ /**
9581
+ * Generates type-safe API client code from OpenAPI schema
9582
+ *
9583
+ * This is the main entry point for code generation. It validates the configuration,
9584
+ * parses the OpenAPI schema, generates all necessary files, and writes them to disk.
9585
+ *
9586
+ * The generated code follows Next.js 16.0.7 best practices including:
9587
+ * - Server Actions with type safety
9588
+ * - React Query hooks with proper caching
9589
+ * - Middleware support
9590
+ * - Error handling
9591
+ * - Cache tag management
9592
+ *
9593
+ * @param configuration - The bridge configuration containing schema URL, output directory, and framework settings
9594
+ * @returns Promise that resolves when generation is complete
9595
+ * @throws {ValidationError} When configuration is invalid
9596
+ * @throws {SchemaParseError} When OpenAPI schema cannot be parsed
9597
+ * @throws {GenerationError} When code generation fails
9598
+ *
9599
+ * @example
9600
+ * ```typescript
9601
+ * const config: BridgeConfiguration = {
9602
+ * schema: 'https://api.example.com/openapi.json',
9603
+ * outputDir: 'src/generated',
9604
+ * framework: { type: 'nextjs', router: 'app', features: {...} },
9605
+ * api: { baseUrl: 'https://api.example.com', timeout: 30000, retries: 3 }
9606
+ * };
9607
+ * await bridge.generate(config);
9608
+ * ```
9609
+ */
9414
9610
  async generate(configuration) {
9415
9611
  const startTime = Date.now();
9416
9612
  try {
9417
9613
  this.logger.info("Starting code generation...");
9418
- await this.validateConfiguration(configuration);
9614
+ this.validateConfiguration(configuration);
9419
9615
  this.logger.info(`Parsing schema: ${configuration.schema}`);
9420
9616
  const parsedSchema = await this.schemaParser.parse(configuration.schema);
9421
9617
  this.logger.debug(
@@ -9444,16 +9640,17 @@ var BridgeCore = class {
9444
9640
  throw error;
9445
9641
  }
9446
9642
  }
9447
- async validateConfiguration(configuration) {
9643
+ validateConfiguration(configuration) {
9448
9644
  const errors = [];
9449
- if (!configuration.schema?.trim()) {
9645
+ if (!configuration.schema.trim()) {
9450
9646
  errors.push("Schema URL is required and cannot be empty");
9451
9647
  }
9452
- if (!configuration.outputDir?.trim()) {
9648
+ if (!configuration.outputDir.trim()) {
9453
9649
  errors.push("Output directory is required and cannot be empty");
9454
9650
  }
9455
9651
  if (configuration.framework.type !== "nextjs") {
9456
- errors.push(`Only Next.js framework is currently supported, got: ${configuration.framework.type}`);
9652
+ const frameworkType = configuration.framework.type;
9653
+ errors.push(`Only Next.js framework is currently supported, got: ${frameworkType}`);
9457
9654
  }
9458
9655
  if (errors.length > 0) {
9459
9656
  throw new ValidationError(
@@ -9470,8 +9667,10 @@ var BridgeCore = class {
9470
9667
  case "nextjs":
9471
9668
  const nextJsGenerator = new NextJsCodeGenerator(config);
9472
9669
  return await nextJsGenerator.generate(context);
9473
- default:
9474
- throw new GenerationError(`Unsupported framework: ${config.framework.type}`);
9670
+ default: {
9671
+ const frameworkType = config.framework.type;
9672
+ throw new GenerationError(`Unsupported framework: ${frameworkType}`);
9673
+ }
9475
9674
  }
9476
9675
  } catch (error) {
9477
9676
  if (error instanceof GenerationError) {
@@ -9505,7 +9704,7 @@ var BridgeCore = class {
9505
9704
  logGenerationSummary(files) {
9506
9705
  const fileTypes = files.reduce(
9507
9706
  (acc, file) => {
9508
- acc[file.type] = (acc[file.type] || 0) + 1;
9707
+ acc[file.type] = (acc[file.type] ?? 0) + 1;
9509
9708
  return acc;
9510
9709
  },
9511
9710
  {}
@@ -9524,9 +9723,24 @@ var BridgeCore = class {
9524
9723
  });
9525
9724
  }
9526
9725
  }
9527
- // Public API methods
9726
+ /**
9727
+ * Validates an OpenAPI schema without generating code
9728
+ *
9729
+ * Useful for checking schema validity before running full generation.
9730
+ *
9731
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9732
+ * @returns Promise resolving to true if schema is valid, false otherwise
9733
+ *
9734
+ * @example
9735
+ * ```typescript
9736
+ * const isValid = await bridge.validateSchema('https://api.example.com/openapi.json');
9737
+ * if (isValid) {
9738
+ * await bridge.generate(config);
9739
+ * }
9740
+ * ```
9741
+ */
9528
9742
  async validateSchema(schemaUrl) {
9529
- if (!schemaUrl?.trim()) {
9743
+ if (!schemaUrl.trim()) {
9530
9744
  this.logger.warn("Schema URL is empty or invalid");
9531
9745
  return false;
9532
9746
  }
@@ -9540,8 +9754,25 @@ var BridgeCore = class {
9540
9754
  return false;
9541
9755
  }
9542
9756
  }
9757
+ /**
9758
+ * Retrieves metadata from an OpenAPI schema
9759
+ *
9760
+ * Extracts schema metadata including title, version, description, and other
9761
+ * OpenAPI document information without parsing the entire schema.
9762
+ *
9763
+ * @param schemaUrl - URL or file path to the OpenAPI schema
9764
+ * @returns Promise resolving to schema metadata
9765
+ * @throws {BridgeError} When schema URL is invalid
9766
+ * @throws {SchemaParseError} When schema cannot be parsed
9767
+ *
9768
+ * @example
9769
+ * ```typescript
9770
+ * const metadata = await bridge.getSchemaInfo('https://api.example.com/openapi.json');
9771
+ * console.log(`Schema: ${metadata.title} v${metadata.version}`);
9772
+ * ```
9773
+ */
9543
9774
  async getSchemaInfo(schemaUrl) {
9544
- if (!schemaUrl?.trim()) {
9775
+ if (!schemaUrl.trim()) {
9545
9776
  throw new BridgeError("Schema URL is required and cannot be empty", "INVALID_SCHEMA_URL");
9546
9777
  }
9547
9778
  try {
@@ -9553,6 +9784,18 @@ var BridgeCore = class {
9553
9784
  throw new SchemaParseError(`Failed to parse schema: ${errorMessage}`, schemaUrl);
9554
9785
  }
9555
9786
  }
9787
+ /**
9788
+ * Clears the internal schema cache
9789
+ *
9790
+ * Useful when you need to force re-fetching of schemas or during development.
9791
+ * The cache is automatically managed, but this method allows manual invalidation.
9792
+ *
9793
+ * @example
9794
+ * ```typescript
9795
+ * bridge.clearCache();
9796
+ * await bridge.generate(config); // Will fetch fresh schema
9797
+ * ```
9798
+ */
9556
9799
  clearCache() {
9557
9800
  try {
9558
9801
  this.schemaParser.clearCache();
@@ -9651,7 +9894,7 @@ var ConfigurationLoader = class {
9651
9894
  }
9652
9895
  async load(configPath) {
9653
9896
  if (!configPath?.trim()) {
9654
- configPath = "mulink.config.json";
9897
+ configPath = "link.config.json";
9655
9898
  }
9656
9899
  const resolvedPath = path2.resolve(process.cwd(), configPath);
9657
9900
  try {
@@ -9717,7 +9960,7 @@ ${errorMessages}`,
9717
9960
  );
9718
9961
  }
9719
9962
  }
9720
- async createDefault(framework = "nextjs") {
9963
+ createDefault(framework = "nextjs") {
9721
9964
  const defaultConfig = {
9722
9965
  schema: "https://petstore3.swagger.io/api/v3/openapi.json",
9723
9966
  outputDir: "src/generated",
@@ -9762,7 +10005,7 @@ ${errorMessages}`,
9762
10005
  }
9763
10006
  async save(config, configPath) {
9764
10007
  if (!configPath?.trim()) {
9765
- configPath = "mulink.config.json";
10008
+ configPath = "link.config.json";
9766
10009
  }
9767
10010
  const resolvedPath = path2.resolve(process.cwd(), configPath);
9768
10011
  try {
@@ -9806,5 +10049,5 @@ ${errorMessages}`,
9806
10049
  };
9807
10050
 
9808
10051
  export { BridgeCore, BridgeError, BridgeLogger, ConfigurationLoader, FileSystemManager, GenerationError, LogLevel, NextJsCodeGenerator, OpenApiSchemaParser, SchemaParseError, ValidationError, VersionChecker, __name, checkAndNotifyUpdates, createBridgeVersionChecker };
9809
- //# sourceMappingURL=chunk-AHGDKSOY.js.map
9810
- //# sourceMappingURL=chunk-AHGDKSOY.js.map
10052
+ //# sourceMappingURL=chunk-BMHPB646.js.map
10053
+ //# sourceMappingURL=chunk-BMHPB646.js.map