@bagelink/sdk 1.8.30 → 1.8.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -655,20 +655,20 @@ function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr
655
655
  headers: { 'Content-Type': 'multipart/form-data' },
656
656
  onUploadProgress: options?.onUploadProgress${paramStr ? `, ${paramStr}` : ""}
657
657
  })
658
- return new ApiResponse(response.data, response)`;
658
+ return ApiResponse.create(response.data, response)`;
659
659
  } else {
660
660
  axiosFunction += `
661
661
  const response = await axios.${method}(${formattedPath}, formData, {
662
662
  headers: { 'Content-Type': 'multipart/form-data' }${paramStr ? `, ${paramStr}` : ""}
663
663
  })
664
- return new ApiResponse(response.data, response)`;
664
+ return ApiResponse.create(response.data, response)`;
665
665
  }
666
666
  } else {
667
667
  const configParams = paramStr ? `, { ${paramStr} }` : "";
668
668
  const bodyVar = requestBodyPayload || "{}";
669
669
  axiosFunction += `
670
670
  const response = await axios.${method}(${formattedPath}${["get", "delete"].includes(method) ? configParams : `, ${bodyVar}${configParams}`})
671
- return new ApiResponse(response.data, response)`;
671
+ return ApiResponse.create(response.data, response)`;
672
672
  }
673
673
  axiosFunction += "}";
674
674
  return axiosFunction;
@@ -727,7 +727,8 @@ function generateFunctionForOperation(method, path, operation) {
727
727
  );
728
728
  const allParams = isFileUpload ? "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }" : combineAllParams(parameters, requestBodyParam);
729
729
  const responseType = generateResponseType(operation.responses);
730
- const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : "";
730
+ const isArrayResponse = responseType.endsWith("[]");
731
+ const responseTypeStr = responseType ? isArrayResponse ? `: Promise<ApiResponse<${responseType}>>` : `: Promise<${responseType} & { $raw?: any, $metadata?: any, totalCount?: number, page?: number, perPage?: number, totalPages?: number, rateLimit?: number, rateLimitReset?: number, getHeader?: (name: string) => string | undefined, hasPagination?: boolean, hasNextPage?: boolean, hasPrevPage?: boolean }>` : "";
731
732
  const functionComment = buildJSDocComment(operation, method, path);
732
733
  if (isStream) {
733
734
  const eventTypes = extractSSEEventTypes(operation);
@@ -1442,22 +1443,46 @@ class ApiResponse extends Array {
1442
1443
  /** All response metadata */
1443
1444
  $metadata;
1444
1445
  constructor(data, response) {
1445
- const items = Array.isArray(data) ? data : [data];
1446
- super(...items);
1447
- Object.setPrototypeOf(this, ApiResponse.prototype);
1448
- if (!response) {
1449
- return Object.setPrototypeOf([...items], Array.prototype);
1450
- }
1451
- this.$raw = response;
1452
- this.$metadata = this.parseMetadata(response);
1453
- this.totalCount = this.$metadata.totalCount;
1454
- this.page = this.$metadata.page;
1455
- this.perPage = this.$metadata.perPage;
1456
- this.totalPages = this.$metadata.totalPages;
1457
- this.rateLimit = this.$metadata.rateLimit;
1458
- this.rateLimitReset = this.$metadata.rateLimitReset;
1459
- }
1460
- parseMetadata(response) {
1446
+ super();
1447
+ if (Array.isArray(data)) {
1448
+ this.push(...data);
1449
+ if (response) {
1450
+ this.$raw = response;
1451
+ this.$metadata = ApiResponse.parseMetadataStatic(response);
1452
+ this.totalCount = this.$metadata.totalCount;
1453
+ this.page = this.$metadata.page;
1454
+ this.perPage = this.$metadata.perPage;
1455
+ this.totalPages = this.$metadata.totalPages;
1456
+ this.rateLimit = this.$metadata.rateLimit;
1457
+ this.rateLimitReset = this.$metadata.rateLimitReset;
1458
+ }
1459
+ }
1460
+ }
1461
+ /**
1462
+ * Create an ApiResponse from data and response
1463
+ * Factory method to handle both arrays and objects
1464
+ */
1465
+ static create(data, response) {
1466
+ if (!Array.isArray(data)) {
1467
+ const obj = Object.assign(/* @__PURE__ */ Object.create(null), data);
1468
+ obj.$raw = response;
1469
+ obj.$metadata = ApiResponse.parseMetadataStatic(response);
1470
+ obj.totalCount = obj.$metadata.totalCount;
1471
+ obj.page = obj.$metadata.page;
1472
+ obj.perPage = obj.$metadata.perPage;
1473
+ obj.totalPages = obj.$metadata.totalPages;
1474
+ obj.rateLimit = obj.$metadata.rateLimit;
1475
+ obj.rateLimitReset = obj.$metadata.rateLimitReset;
1476
+ obj.getHeader = (name) => response?.headers[name.toLowerCase()];
1477
+ obj.hasPagination = obj.totalCount !== void 0 || obj.page !== void 0;
1478
+ obj.hasNextPage = obj.page && obj.totalPages ? obj.page < obj.totalPages : false;
1479
+ obj.hasPrevPage = obj.page ? obj.page > 1 : false;
1480
+ return obj;
1481
+ }
1482
+ const instance = new ApiResponse(data, response);
1483
+ return instance;
1484
+ }
1485
+ static parseMetadataStatic(response) {
1461
1486
  const { headers } = response;
1462
1487
  const metadata = {};
1463
1488
  if (headers["x-total-count"]) {
@@ -1614,7 +1639,7 @@ function wrapApiForDirectReturn(apiObj) {
1614
1639
  return async (...args) => {
1615
1640
  const result = await apiObj(...args);
1616
1641
  if (result && typeof result === "object" && "data" in result && "status" in result) {
1617
- return new ApiResponse(result.data, result);
1642
+ return ApiResponse.create(result.data, result);
1618
1643
  }
1619
1644
  return result;
1620
1645
  };
package/dist/index.d.cts CHANGED
@@ -554,10 +554,12 @@ interface ResponseMetadata {
554
554
  [key: string]: any;
555
555
  }
556
556
  /**
557
- * Enhanced API response that acts as an array with metadata
558
- * @template TData - The data type (will be unwrapped if array)
557
+ * Enhanced API response that adds metadata to the response data
558
+ * - For arrays: acts as array with metadata properties
559
+ * - For objects: object with metadata properties (no array wrapping!)
560
+ * @template TData - The response data type
559
561
  */
560
- declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : TData> {
562
+ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : never> {
561
563
  /** Raw axios response */
562
564
  $raw: AxiosResponse<TData>;
563
565
  /** Total number of items (from x-total-count header) */
@@ -574,8 +576,13 @@ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U
574
576
  rateLimitReset?: number;
575
577
  /** All response metadata */
576
578
  $metadata: ResponseMetadata;
577
- constructor(data: TData, response?: AxiosResponse);
578
- private parseMetadata;
579
+ private constructor();
580
+ /**
581
+ * Create an ApiResponse from data and response
582
+ * Factory method to handle both arrays and objects
583
+ */
584
+ static create<T>(data: T, response: AxiosResponse): any;
585
+ private static parseMetadataStatic;
579
586
  getHeader(name: string): string | undefined;
580
587
  get hasPagination(): boolean;
581
588
  get hasNextPage(): boolean;
package/dist/index.d.mts CHANGED
@@ -554,10 +554,12 @@ interface ResponseMetadata {
554
554
  [key: string]: any;
555
555
  }
556
556
  /**
557
- * Enhanced API response that acts as an array with metadata
558
- * @template TData - The data type (will be unwrapped if array)
557
+ * Enhanced API response that adds metadata to the response data
558
+ * - For arrays: acts as array with metadata properties
559
+ * - For objects: object with metadata properties (no array wrapping!)
560
+ * @template TData - The response data type
559
561
  */
560
- declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : TData> {
562
+ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : never> {
561
563
  /** Raw axios response */
562
564
  $raw: AxiosResponse<TData>;
563
565
  /** Total number of items (from x-total-count header) */
@@ -574,8 +576,13 @@ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U
574
576
  rateLimitReset?: number;
575
577
  /** All response metadata */
576
578
  $metadata: ResponseMetadata;
577
- constructor(data: TData, response?: AxiosResponse);
578
- private parseMetadata;
579
+ private constructor();
580
+ /**
581
+ * Create an ApiResponse from data and response
582
+ * Factory method to handle both arrays and objects
583
+ */
584
+ static create<T>(data: T, response: AxiosResponse): any;
585
+ private static parseMetadataStatic;
579
586
  getHeader(name: string): string | undefined;
580
587
  get hasPagination(): boolean;
581
588
  get hasNextPage(): boolean;
package/dist/index.d.ts CHANGED
@@ -554,10 +554,12 @@ interface ResponseMetadata {
554
554
  [key: string]: any;
555
555
  }
556
556
  /**
557
- * Enhanced API response that acts as an array with metadata
558
- * @template TData - The data type (will be unwrapped if array)
557
+ * Enhanced API response that adds metadata to the response data
558
+ * - For arrays: acts as array with metadata properties
559
+ * - For objects: object with metadata properties (no array wrapping!)
560
+ * @template TData - The response data type
559
561
  */
560
- declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : TData> {
562
+ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : never> {
561
563
  /** Raw axios response */
562
564
  $raw: AxiosResponse<TData>;
563
565
  /** Total number of items (from x-total-count header) */
@@ -574,8 +576,13 @@ declare class ApiResponse<TData = any> extends Array<TData extends Array<infer U
574
576
  rateLimitReset?: number;
575
577
  /** All response metadata */
576
578
  $metadata: ResponseMetadata;
577
- constructor(data: TData, response?: AxiosResponse);
578
- private parseMetadata;
579
+ private constructor();
580
+ /**
581
+ * Create an ApiResponse from data and response
582
+ * Factory method to handle both arrays and objects
583
+ */
584
+ static create<T>(data: T, response: AxiosResponse): any;
585
+ private static parseMetadataStatic;
579
586
  getHeader(name: string): string | undefined;
580
587
  get hasPagination(): boolean;
581
588
  get hasNextPage(): boolean;
package/dist/index.mjs CHANGED
@@ -649,20 +649,20 @@ function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr
649
649
  headers: { 'Content-Type': 'multipart/form-data' },
650
650
  onUploadProgress: options?.onUploadProgress${paramStr ? `, ${paramStr}` : ""}
651
651
  })
652
- return new ApiResponse(response.data, response)`;
652
+ return ApiResponse.create(response.data, response)`;
653
653
  } else {
654
654
  axiosFunction += `
655
655
  const response = await axios.${method}(${formattedPath}, formData, {
656
656
  headers: { 'Content-Type': 'multipart/form-data' }${paramStr ? `, ${paramStr}` : ""}
657
657
  })
658
- return new ApiResponse(response.data, response)`;
658
+ return ApiResponse.create(response.data, response)`;
659
659
  }
660
660
  } else {
661
661
  const configParams = paramStr ? `, { ${paramStr} }` : "";
662
662
  const bodyVar = requestBodyPayload || "{}";
663
663
  axiosFunction += `
664
664
  const response = await axios.${method}(${formattedPath}${["get", "delete"].includes(method) ? configParams : `, ${bodyVar}${configParams}`})
665
- return new ApiResponse(response.data, response)`;
665
+ return ApiResponse.create(response.data, response)`;
666
666
  }
667
667
  axiosFunction += "}";
668
668
  return axiosFunction;
@@ -721,7 +721,8 @@ function generateFunctionForOperation(method, path, operation) {
721
721
  );
722
722
  const allParams = isFileUpload ? "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }" : combineAllParams(parameters, requestBodyParam);
723
723
  const responseType = generateResponseType(operation.responses);
724
- const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : "";
724
+ const isArrayResponse = responseType.endsWith("[]");
725
+ const responseTypeStr = responseType ? isArrayResponse ? `: Promise<ApiResponse<${responseType}>>` : `: Promise<${responseType} & { $raw?: any, $metadata?: any, totalCount?: number, page?: number, perPage?: number, totalPages?: number, rateLimit?: number, rateLimitReset?: number, getHeader?: (name: string) => string | undefined, hasPagination?: boolean, hasNextPage?: boolean, hasPrevPage?: boolean }>` : "";
725
726
  const functionComment = buildJSDocComment(operation, method, path);
726
727
  if (isStream) {
727
728
  const eventTypes = extractSSEEventTypes(operation);
@@ -1436,22 +1437,46 @@ class ApiResponse extends Array {
1436
1437
  /** All response metadata */
1437
1438
  $metadata;
1438
1439
  constructor(data, response) {
1439
- const items = Array.isArray(data) ? data : [data];
1440
- super(...items);
1441
- Object.setPrototypeOf(this, ApiResponse.prototype);
1442
- if (!response) {
1443
- return Object.setPrototypeOf([...items], Array.prototype);
1444
- }
1445
- this.$raw = response;
1446
- this.$metadata = this.parseMetadata(response);
1447
- this.totalCount = this.$metadata.totalCount;
1448
- this.page = this.$metadata.page;
1449
- this.perPage = this.$metadata.perPage;
1450
- this.totalPages = this.$metadata.totalPages;
1451
- this.rateLimit = this.$metadata.rateLimit;
1452
- this.rateLimitReset = this.$metadata.rateLimitReset;
1453
- }
1454
- parseMetadata(response) {
1440
+ super();
1441
+ if (Array.isArray(data)) {
1442
+ this.push(...data);
1443
+ if (response) {
1444
+ this.$raw = response;
1445
+ this.$metadata = ApiResponse.parseMetadataStatic(response);
1446
+ this.totalCount = this.$metadata.totalCount;
1447
+ this.page = this.$metadata.page;
1448
+ this.perPage = this.$metadata.perPage;
1449
+ this.totalPages = this.$metadata.totalPages;
1450
+ this.rateLimit = this.$metadata.rateLimit;
1451
+ this.rateLimitReset = this.$metadata.rateLimitReset;
1452
+ }
1453
+ }
1454
+ }
1455
+ /**
1456
+ * Create an ApiResponse from data and response
1457
+ * Factory method to handle both arrays and objects
1458
+ */
1459
+ static create(data, response) {
1460
+ if (!Array.isArray(data)) {
1461
+ const obj = Object.assign(/* @__PURE__ */ Object.create(null), data);
1462
+ obj.$raw = response;
1463
+ obj.$metadata = ApiResponse.parseMetadataStatic(response);
1464
+ obj.totalCount = obj.$metadata.totalCount;
1465
+ obj.page = obj.$metadata.page;
1466
+ obj.perPage = obj.$metadata.perPage;
1467
+ obj.totalPages = obj.$metadata.totalPages;
1468
+ obj.rateLimit = obj.$metadata.rateLimit;
1469
+ obj.rateLimitReset = obj.$metadata.rateLimitReset;
1470
+ obj.getHeader = (name) => response?.headers[name.toLowerCase()];
1471
+ obj.hasPagination = obj.totalCount !== void 0 || obj.page !== void 0;
1472
+ obj.hasNextPage = obj.page && obj.totalPages ? obj.page < obj.totalPages : false;
1473
+ obj.hasPrevPage = obj.page ? obj.page > 1 : false;
1474
+ return obj;
1475
+ }
1476
+ const instance = new ApiResponse(data, response);
1477
+ return instance;
1478
+ }
1479
+ static parseMetadataStatic(response) {
1455
1480
  const { headers } = response;
1456
1481
  const metadata = {};
1457
1482
  if (headers["x-total-count"]) {
@@ -1608,7 +1633,7 @@ function wrapApiForDirectReturn(apiObj) {
1608
1633
  return async (...args) => {
1609
1634
  const result = await apiObj(...args);
1610
1635
  if (result && typeof result === "object" && "data" in result && "status" in result) {
1611
- return new ApiResponse(result.data, result);
1636
+ return ApiResponse.create(result.data, result);
1612
1637
  }
1613
1638
  return result;
1614
1639
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/sdk",
3
3
  "type": "module",
4
- "version": "1.8.30",
4
+ "version": "1.8.33",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
package/src/index.ts CHANGED
@@ -39,10 +39,12 @@ export interface ResponseMetadata {
39
39
  }
40
40
 
41
41
  /**
42
- * Enhanced API response that acts as an array with metadata
43
- * @template TData - The data type (will be unwrapped if array)
42
+ * Enhanced API response that adds metadata to the response data
43
+ * - For arrays: acts as array with metadata properties
44
+ * - For objects: object with metadata properties (no array wrapping!)
45
+ * @template TData - The response data type
44
46
  */
45
- export class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : TData> {
47
+ export class ApiResponse<TData = any> extends Array<TData extends Array<infer U> ? U : never> {
46
48
  /** Raw axios response */
47
49
  public $raw!: AxiosResponse<TData>
48
50
 
@@ -67,29 +69,56 @@ export class ApiResponse<TData = any> extends Array<TData extends Array<infer U>
67
69
  /** All response metadata */
68
70
  public $metadata!: ResponseMetadata
69
71
 
70
- constructor(data: TData, response?: AxiosResponse) {
71
- const items = (Array.isArray(data) ? data : [data]) as Array<TData extends Array<infer U> ? U : TData>
72
- super(...items)
73
- Object.setPrototypeOf(this, ApiResponse.prototype)
74
-
75
- // Handle case where constructor is called without response (from array methods)
76
- if (!response) {
77
- // Return a plain array when array methods call the constructor
78
- return Object.setPrototypeOf([...items], Array.prototype) as any
72
+ private constructor(data: TData, response?: AxiosResponse) {
73
+ // Must call super first when extending Array
74
+ super()
75
+
76
+ // For arrays, add items and metadata
77
+ if (Array.isArray(data)) {
78
+ this.push(...data as any[])
79
+
80
+ if (response) {
81
+ this.$raw = response as AxiosResponse<TData>
82
+ this.$metadata = ApiResponse.parseMetadataStatic(response)
83
+ this.totalCount = this.$metadata.totalCount
84
+ this.page = this.$metadata.page
85
+ this.perPage = this.$metadata.perPage
86
+ this.totalPages = this.$metadata.totalPages
87
+ this.rateLimit = this.$metadata.rateLimit
88
+ this.rateLimitReset = this.$metadata.rateLimitReset
89
+ }
79
90
  }
91
+ }
80
92
 
81
- this.$raw = response as AxiosResponse<TData>
82
- this.$metadata = this.parseMetadata(response)
93
+ /**
94
+ * Create an ApiResponse from data and response
95
+ * Factory method to handle both arrays and objects
96
+ */
97
+ static create<T>(data: T, response: AxiosResponse): any {
98
+ // For single objects, attach metadata directly
99
+ if (!Array.isArray(data)) {
100
+ const obj = Object.assign(Object.create(null), data) as any
101
+ obj.$raw = response
102
+ obj.$metadata = ApiResponse.parseMetadataStatic(response)
103
+ obj.totalCount = obj.$metadata.totalCount
104
+ obj.page = obj.$metadata.page
105
+ obj.perPage = obj.$metadata.perPage
106
+ obj.totalPages = obj.$metadata.totalPages
107
+ obj.rateLimit = obj.$metadata.rateLimit
108
+ obj.rateLimitReset = obj.$metadata.rateLimitReset
109
+ obj.getHeader = (name: string) => response?.headers[name.toLowerCase()]
110
+ obj.hasPagination = obj.totalCount !== undefined || obj.page !== undefined
111
+ obj.hasNextPage = obj.page && obj.totalPages ? obj.page < obj.totalPages : false
112
+ obj.hasPrevPage = obj.page ? obj.page > 1 : false
113
+ return obj
114
+ }
83
115
 
84
- this.totalCount = this.$metadata.totalCount
85
- this.page = this.$metadata.page
86
- this.perPage = this.$metadata.perPage
87
- this.totalPages = this.$metadata.totalPages
88
- this.rateLimit = this.$metadata.rateLimit
89
- this.rateLimitReset = this.$metadata.rateLimitReset
116
+ // For arrays, create ApiResponse instance
117
+ const instance = new ApiResponse(data, response)
118
+ return instance
90
119
  }
91
120
 
92
- private parseMetadata(response: AxiosResponse): ResponseMetadata {
121
+ private static parseMetadataStatic(response: AxiosResponse): ResponseMetadata {
93
122
  const { headers } = response
94
123
  const metadata: ResponseMetadata = {}
95
124
 
@@ -365,7 +394,7 @@ export function wrapApiForDirectReturn(apiObj: any): any {
365
394
  return async (...args: any[]) => {
366
395
  const result = await apiObj(...args)
367
396
  if (result && typeof result === 'object' && 'data' in result && 'status' in result) {
368
- return new ApiResponse(result.data, result)
397
+ return ApiResponse.create(result.data, result)
369
398
  }
370
399
  return result
371
400
  }
@@ -511,14 +511,14 @@ function generateAxiosFunction(
511
511
  headers: { 'Content-Type': 'multipart/form-data' },
512
512
  onUploadProgress: options?.onUploadProgress${paramStr ? `, ${paramStr}` : ''}
513
513
  })
514
- return new ApiResponse(response.data, response)`
514
+ return ApiResponse.create(response.data, response)`
515
515
  } else {
516
516
  // Generic FormData handling
517
517
  axiosFunction += `
518
518
  const response = await axios.${method}(${formattedPath}, formData, {
519
519
  headers: { 'Content-Type': 'multipart/form-data' }${paramStr ? `, ${paramStr}` : ''}
520
520
  })
521
- return new ApiResponse(response.data, response)`
521
+ return ApiResponse.create(response.data, response)`
522
522
  }
523
523
  } else {
524
524
  const configParams = paramStr ? `, { ${paramStr} }` : ''
@@ -529,7 +529,7 @@ function generateAxiosFunction(
529
529
  ? configParams
530
530
  : `, ${bodyVar}${configParams}`
531
531
  })
532
- return new ApiResponse(response.data, response)`
532
+ return ApiResponse.create(response.data, response)`
533
533
  }
534
534
 
535
535
  axiosFunction += '}'
@@ -629,8 +629,16 @@ function generateFunctionForOperation(
629
629
  : combineAllParams(parameters, requestBodyParam)
630
630
 
631
631
  const responseType = generateResponseType(operation.responses)
632
+
633
+ // Determine if response is an array type
634
+ const isArrayResponse = responseType.endsWith('[]')
635
+
636
+ // For arrays: ApiResponse<T[]>
637
+ // For single objects: T & metadata (more permissive for assignment)
632
638
  const responseTypeStr = responseType
633
- ? `: Promise<AxiosResponse<${responseType}>>`
639
+ ? isArrayResponse
640
+ ? `: Promise<ApiResponse<${responseType}>>`
641
+ : `: Promise<${responseType} & { $raw?: any, $metadata?: any, totalCount?: number, page?: number, perPage?: number, totalPages?: number, rateLimit?: number, rateLimitReset?: number, getHeader?: (name: string) => string | undefined, hasPagination?: boolean, hasNextPage?: boolean, hasPrevPage?: boolean }>`
634
642
  : ''
635
643
 
636
644
  // Create JSDoc comment with OpenAPI documentation