quickbase-js 1.2.0 → 2.0.0-alpha.3

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.
Files changed (95) hide show
  1. package/README.md +351 -227
  2. package/dist/auth/index.d.ts +15 -0
  3. package/dist/auth/index.d.ts.map +1 -0
  4. package/dist/auth/index.js +29 -0
  5. package/dist/auth/index.js.map +1 -0
  6. package/dist/auth/sso-token.d.ts +28 -0
  7. package/dist/auth/sso-token.d.ts.map +1 -0
  8. package/dist/auth/sso-token.js +108 -0
  9. package/dist/auth/sso-token.js.map +1 -0
  10. package/dist/auth/temp-token.d.ts +31 -0
  11. package/dist/auth/temp-token.d.ts.map +1 -0
  12. package/dist/auth/temp-token.js +121 -0
  13. package/dist/auth/temp-token.js.map +1 -0
  14. package/dist/auth/token-cache.d.ts +44 -0
  15. package/dist/auth/token-cache.d.ts.map +1 -0
  16. package/dist/auth/token-cache.js +84 -0
  17. package/dist/auth/token-cache.js.map +1 -0
  18. package/dist/auth/types.d.ts +44 -0
  19. package/dist/auth/types.d.ts.map +1 -0
  20. package/dist/auth/types.js +5 -0
  21. package/dist/auth/types.js.map +1 -0
  22. package/dist/auth/user-token.d.ts +17 -0
  23. package/dist/auth/user-token.d.ts.map +1 -0
  24. package/dist/auth/user-token.js +30 -0
  25. package/dist/auth/user-token.js.map +1 -0
  26. package/dist/client/index.d.ts +12 -0
  27. package/dist/client/index.d.ts.map +1 -0
  28. package/dist/client/index.js +8 -0
  29. package/dist/client/index.js.map +1 -0
  30. package/dist/client/pagination.d.ts +131 -0
  31. package/dist/client/pagination.d.ts.map +1 -0
  32. package/dist/client/pagination.js +232 -0
  33. package/dist/client/pagination.js.map +1 -0
  34. package/dist/client/request.d.ts +45 -0
  35. package/dist/client/request.d.ts.map +1 -0
  36. package/dist/client/request.js +232 -0
  37. package/dist/client/request.js.map +1 -0
  38. package/dist/client/retry.d.ts +41 -0
  39. package/dist/client/retry.d.ts.map +1 -0
  40. package/dist/client/retry.js +122 -0
  41. package/dist/client/retry.js.map +1 -0
  42. package/dist/client/throttle.d.ts +46 -0
  43. package/dist/client/throttle.d.ts.map +1 -0
  44. package/dist/client/throttle.js +85 -0
  45. package/dist/client/throttle.js.map +1 -0
  46. package/dist/core/config.d.ts +13 -0
  47. package/dist/core/config.d.ts.map +1 -0
  48. package/dist/core/config.js +120 -0
  49. package/dist/core/config.js.map +1 -0
  50. package/dist/core/dates.d.ts +18 -0
  51. package/dist/core/dates.d.ts.map +1 -0
  52. package/dist/core/dates.js +58 -0
  53. package/dist/core/dates.js.map +1 -0
  54. package/dist/core/errors.d.ts +134 -0
  55. package/dist/core/errors.d.ts.map +1 -0
  56. package/dist/core/errors.js +185 -0
  57. package/dist/core/errors.js.map +1 -0
  58. package/dist/core/index.d.ts +10 -0
  59. package/dist/core/index.d.ts.map +1 -0
  60. package/dist/core/index.js +9 -0
  61. package/dist/core/index.js.map +1 -0
  62. package/dist/core/logger.d.ts +41 -0
  63. package/dist/core/logger.d.ts.map +1 -0
  64. package/dist/core/logger.js +96 -0
  65. package/dist/core/logger.js.map +1 -0
  66. package/dist/core/types.d.ts +154 -0
  67. package/dist/core/types.d.ts.map +1 -0
  68. package/dist/core/types.js +23 -0
  69. package/dist/core/types.js.map +1 -0
  70. package/dist/generated/client.d.ts +18 -0
  71. package/dist/generated/client.d.ts.map +1 -0
  72. package/dist/generated/client.js +1390 -0
  73. package/dist/generated/client.js.map +1 -0
  74. package/dist/generated/types.d.ts +3827 -0
  75. package/dist/generated/types.d.ts.map +1 -0
  76. package/dist/generated/types.js +8 -0
  77. package/dist/generated/types.js.map +1 -0
  78. package/dist/index.d.ts +89 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +99 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/quickbase.esm.js +7 -0
  83. package/dist/quickbase.esm.js.map +7 -0
  84. package/dist/quickbase.min.js +7 -0
  85. package/dist/quickbase.min.js.map +7 -0
  86. package/package.json +60 -86
  87. package/dist/esm/quickbase.d.ts +0 -8094
  88. package/dist/esm/quickbase.js +0 -8333
  89. package/dist/esm/quickbase.js.map +0 -1
  90. package/dist/esm/quickbase.min.js +0 -2
  91. package/dist/esm/quickbase.min.js.map +0 -1
  92. package/dist/umd/quickbase.umd.js +0 -8909
  93. package/dist/umd/quickbase.umd.js.map +0 -1
  94. package/dist/umd/quickbase.umd.min.js +0 -2
  95. package/dist/umd/quickbase.umd.min.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpF,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAUpB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Pagination support with fluent API
3
+ *
4
+ * Provides automatic pagination for QuickBase API endpoints that return
5
+ * paginated results. Supports both skip-based and token-based pagination.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Fetch single page (default)
10
+ * const page = await client.runQuery({ ... });
11
+ *
12
+ * // Fetch all pages automatically
13
+ * const all = await client.runQuery({ ... }).all();
14
+ *
15
+ * // Fetch with record limit
16
+ * const limited = await client.runQuery({ ... }).paginate({ limit: 500 });
17
+ *
18
+ * // Explicitly single page (if autoPaginate is enabled globally)
19
+ * const single = await client.runQuery({ ... }).noPaginate();
20
+ * ```
21
+ */
22
+ /**
23
+ * Pagination options for controlling automatic pagination behavior
24
+ */
25
+ export interface PaginationOptions {
26
+ /** Maximum number of records to fetch across all pages */
27
+ limit?: number;
28
+ /** Starting offset for skip-based pagination */
29
+ skip?: number;
30
+ }
31
+ /**
32
+ * Metadata returned with paginated responses
33
+ */
34
+ export interface PaginationMetadata {
35
+ totalRecords?: number;
36
+ numRecords?: number;
37
+ numFields?: number;
38
+ skip?: number;
39
+ top?: number;
40
+ nextPageToken?: string;
41
+ nextToken?: string;
42
+ }
43
+ /**
44
+ * A paginated response from the QuickBase API
45
+ */
46
+ export interface PaginatedResponse<T = unknown> {
47
+ data?: T[];
48
+ fields?: Array<{
49
+ id: number;
50
+ label: string;
51
+ type: string;
52
+ }>;
53
+ metadata: PaginationMetadata;
54
+ [key: string]: unknown;
55
+ }
56
+ /**
57
+ * Determines the type of pagination from a response
58
+ */
59
+ export type PaginationType = 'skip' | 'token' | 'none';
60
+ /**
61
+ * Detect pagination type from response metadata
62
+ */
63
+ export declare function detectPaginationType(metadata: PaginationMetadata): PaginationType;
64
+ /**
65
+ * Check if a response has more pages available
66
+ */
67
+ export declare function hasMorePages(response: PaginatedResponse, paginationType: PaginationType, currentCount: number): boolean;
68
+ /**
69
+ * Find the data array key in a response object
70
+ */
71
+ export declare function findDataKey(response: PaginatedResponse): string;
72
+ /**
73
+ * Check if a response looks like a paginated response
74
+ */
75
+ export declare function isPaginatedResponse(response: unknown): response is PaginatedResponse;
76
+ /**
77
+ * Request executor function type
78
+ */
79
+ export type RequestExecutor<T> = () => Promise<T>;
80
+ /**
81
+ * Request executor with pagination parameters
82
+ */
83
+ export type PaginatedRequestExecutor<T> = (params: {
84
+ skip?: number;
85
+ nextPageToken?: string;
86
+ nextToken?: string;
87
+ }) => Promise<T>;
88
+ /**
89
+ * A thenable request that supports fluent pagination methods
90
+ *
91
+ * This class wraps an API request and allows chaining pagination methods
92
+ * while still being directly awaitable.
93
+ */
94
+ export declare class PaginatedRequest<T> implements PromiseLike<T> {
95
+ private readonly executor;
96
+ private readonly paginatedExecutor?;
97
+ private readonly defaultAutoPaginate;
98
+ constructor(executor: RequestExecutor<T>, options?: {
99
+ paginatedExecutor?: PaginatedRequestExecutor<T>;
100
+ autoPaginate?: boolean;
101
+ });
102
+ /**
103
+ * Implement PromiseLike to allow direct awaiting
104
+ * Default behavior respects the global autoPaginate setting
105
+ */
106
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
107
+ /**
108
+ * Fetch all pages and combine results
109
+ */
110
+ all(): Promise<T>;
111
+ /**
112
+ * Fetch pages with optional limit
113
+ */
114
+ paginate(options?: PaginationOptions): Promise<T>;
115
+ /**
116
+ * Explicitly fetch only a single page (no pagination)
117
+ */
118
+ noPaginate(): Promise<T>;
119
+ /**
120
+ * Get the underlying promise (for compatibility)
121
+ */
122
+ toPromise(): Promise<T>;
123
+ }
124
+ /**
125
+ * Create a paginated request wrapper
126
+ */
127
+ export declare function createPaginatedRequest<T>(executor: RequestExecutor<T>, options?: {
128
+ paginatedExecutor?: PaginatedRequestExecutor<T>;
129
+ autoPaginate?: boolean;
130
+ }): PaginatedRequest<T>;
131
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/client/pagination.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Pagination support with fluent API
3
+ *
4
+ * Provides automatic pagination for QuickBase API endpoints that return
5
+ * paginated results. Supports both skip-based and token-based pagination.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Fetch single page (default)
10
+ * const page = await client.runQuery({ ... });
11
+ *
12
+ * // Fetch all pages automatically
13
+ * const all = await client.runQuery({ ... }).all();
14
+ *
15
+ * // Fetch with record limit
16
+ * const limited = await client.runQuery({ ... }).paginate({ limit: 500 });
17
+ *
18
+ * // Explicitly single page (if autoPaginate is enabled globally)
19
+ * const single = await client.runQuery({ ... }).noPaginate();
20
+ * ```
21
+ */
22
+ /**
23
+ * Detect pagination type from response metadata
24
+ */
25
+ export function detectPaginationType(metadata) {
26
+ if (metadata.totalRecords !== undefined && metadata.skip !== undefined) {
27
+ return 'skip';
28
+ }
29
+ if (metadata.nextPageToken !== undefined || metadata.nextToken !== undefined) {
30
+ return 'token';
31
+ }
32
+ return 'none';
33
+ }
34
+ /**
35
+ * Check if a response has more pages available
36
+ */
37
+ export function hasMorePages(response, paginationType, currentCount) {
38
+ const { metadata } = response;
39
+ if (paginationType === 'skip') {
40
+ return (metadata.totalRecords !== undefined &&
41
+ currentCount < metadata.totalRecords);
42
+ }
43
+ if (paginationType === 'token') {
44
+ const nextToken = metadata.nextPageToken ?? metadata.nextToken;
45
+ return nextToken !== undefined && nextToken !== '';
46
+ }
47
+ return false;
48
+ }
49
+ /**
50
+ * Find the data array key in a response object
51
+ */
52
+ export function findDataKey(response) {
53
+ for (const key of Object.keys(response)) {
54
+ if (Array.isArray(response[key])) {
55
+ return key;
56
+ }
57
+ }
58
+ return 'data';
59
+ }
60
+ /**
61
+ * Check if a response looks like a paginated response
62
+ */
63
+ export function isPaginatedResponse(response) {
64
+ if (!response || typeof response !== 'object') {
65
+ return false;
66
+ }
67
+ const obj = response;
68
+ // Must have metadata object
69
+ if (!obj.metadata || typeof obj.metadata !== 'object') {
70
+ return false;
71
+ }
72
+ // Must have an array field
73
+ const hasArrayField = Object.values(obj).some(Array.isArray);
74
+ if (!hasArrayField) {
75
+ return false;
76
+ }
77
+ const metadata = obj.metadata;
78
+ // Check for pagination indicators
79
+ return (metadata.totalRecords !== undefined ||
80
+ metadata.numRecords !== undefined ||
81
+ metadata.nextPageToken !== undefined ||
82
+ metadata.nextToken !== undefined);
83
+ }
84
+ /**
85
+ * A thenable request that supports fluent pagination methods
86
+ *
87
+ * This class wraps an API request and allows chaining pagination methods
88
+ * while still being directly awaitable.
89
+ */
90
+ export class PaginatedRequest {
91
+ executor;
92
+ paginatedExecutor;
93
+ defaultAutoPaginate;
94
+ constructor(executor, options) {
95
+ this.executor = executor;
96
+ this.paginatedExecutor = options?.paginatedExecutor;
97
+ this.defaultAutoPaginate = options?.autoPaginate ?? false;
98
+ }
99
+ /**
100
+ * Implement PromiseLike to allow direct awaiting
101
+ * Default behavior respects the global autoPaginate setting
102
+ */
103
+ then(onfulfilled, onrejected) {
104
+ const promise = this.defaultAutoPaginate ? this.all() : this.executor();
105
+ return promise.then(onfulfilled, onrejected);
106
+ }
107
+ /**
108
+ * Fetch all pages and combine results
109
+ */
110
+ async all() {
111
+ return this.paginate({});
112
+ }
113
+ /**
114
+ * Fetch pages with optional limit
115
+ */
116
+ async paginate(options = {}) {
117
+ if (!this.paginatedExecutor) {
118
+ // Not a paginated endpoint, just execute normally
119
+ return this.executor();
120
+ }
121
+ const { limit, skip: initialSkip = 0 } = options;
122
+ let allRecords = [];
123
+ let lastResponse = null;
124
+ let paginationType = 'none';
125
+ let currentSkip = initialSkip;
126
+ let nextToken;
127
+ // Fetch first page
128
+ const firstResponse = await this.paginatedExecutor({ skip: initialSkip });
129
+ if (!isPaginatedResponse(firstResponse)) {
130
+ // Not a paginated response, return as-is
131
+ return firstResponse;
132
+ }
133
+ lastResponse = firstResponse;
134
+ paginationType = detectPaginationType(firstResponse.metadata);
135
+ const dataKey = findDataKey(firstResponse);
136
+ const firstPageData = firstResponse[dataKey] || [];
137
+ // Apply limit to first page if needed
138
+ if (limit !== undefined && firstPageData.length > limit) {
139
+ allRecords = firstPageData.slice(0, limit);
140
+ }
141
+ else {
142
+ allRecords = [...firstPageData];
143
+ }
144
+ // Initialize continuation state
145
+ if (paginationType === 'skip') {
146
+ currentSkip = initialSkip + firstPageData.length;
147
+ }
148
+ else if (paginationType === 'token') {
149
+ nextToken = firstResponse.metadata.nextPageToken ?? firstResponse.metadata.nextToken;
150
+ }
151
+ // Fetch remaining pages
152
+ while (hasMorePages(lastResponse, paginationType, allRecords.length)) {
153
+ // Check limit
154
+ if (limit !== undefined && allRecords.length >= limit) {
155
+ break;
156
+ }
157
+ // Fetch next page
158
+ let nextResponse;
159
+ if (paginationType === 'skip') {
160
+ nextResponse = await this.paginatedExecutor({ skip: currentSkip });
161
+ }
162
+ else if (paginationType === 'token' && nextToken) {
163
+ const tokenKey = lastResponse.metadata.nextPageToken !== undefined
164
+ ? 'nextPageToken'
165
+ : 'nextToken';
166
+ nextResponse = await this.paginatedExecutor({ [tokenKey]: nextToken });
167
+ }
168
+ else {
169
+ break;
170
+ }
171
+ lastResponse = nextResponse;
172
+ const pageData = nextResponse[dataKey] || [];
173
+ // Check for empty response
174
+ if (pageData.length === 0) {
175
+ break;
176
+ }
177
+ // Apply limit if needed
178
+ if (limit !== undefined) {
179
+ const remainingCapacity = limit - allRecords.length;
180
+ allRecords = allRecords.concat(pageData.slice(0, remainingCapacity));
181
+ }
182
+ else {
183
+ allRecords = allRecords.concat(pageData);
184
+ }
185
+ // Update continuation state
186
+ if (paginationType === 'skip') {
187
+ currentSkip += pageData.length;
188
+ }
189
+ else if (paginationType === 'token') {
190
+ nextToken = nextResponse.metadata.nextPageToken ?? nextResponse.metadata.nextToken;
191
+ if (!nextToken) {
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ // Build final response
197
+ const finalResponse = {
198
+ ...lastResponse,
199
+ [dataKey]: allRecords,
200
+ metadata: {
201
+ ...lastResponse.metadata,
202
+ numRecords: allRecords.length,
203
+ skip: initialSkip,
204
+ },
205
+ };
206
+ // Clear pagination tokens in final response
207
+ if (paginationType === 'token') {
208
+ delete finalResponse.metadata.nextPageToken;
209
+ delete finalResponse.metadata.nextToken;
210
+ }
211
+ return finalResponse;
212
+ }
213
+ /**
214
+ * Explicitly fetch only a single page (no pagination)
215
+ */
216
+ async noPaginate() {
217
+ return this.executor();
218
+ }
219
+ /**
220
+ * Get the underlying promise (for compatibility)
221
+ */
222
+ toPromise() {
223
+ return this.then();
224
+ }
225
+ }
226
+ /**
227
+ * Create a paginated request wrapper
228
+ */
229
+ export function createPaginatedRequest(executor, options) {
230
+ return new PaginatedRequest(executor, options);
231
+ }
232
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/client/pagination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAwCH;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAA4B;IAC/D,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACvE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,QAAQ,CAAC,aAAa,KAAK,SAAS,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA2B,EAC3B,cAA8B,EAC9B,YAAoB;IAEpB,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAE9B,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO,CACL,QAAQ,CAAC,YAAY,KAAK,SAAS;YACnC,YAAY,GAAG,QAAQ,CAAC,YAAY,CACrC,CAAC;IACJ,CAAC;IAED,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,SAAS,CAAC;QAC/D,OAAO,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAA2B;IACrD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,GAAG,QAAmC,CAAC;IAEhD,4BAA4B;IAC5B,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2BAA2B;IAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAA8B,CAAC;IAEpD,kCAAkC;IAClC,OAAO,CACL,QAAQ,CAAC,YAAY,KAAK,SAAS;QACnC,QAAQ,CAAC,UAAU,KAAK,SAAS;QACjC,QAAQ,CAAC,aAAa,KAAK,SAAS;QACpC,QAAQ,CAAC,SAAS,KAAK,SAAS,CACjC,CAAC;AACJ,CAAC;AAgBD;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACV,QAAQ,CAAqB;IAC7B,iBAAiB,CAA+B;IAChD,mBAAmB,CAAU;IAE9C,YACE,QAA4B,EAC5B,OAGC;QAED,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,CAAC;QACpD,IAAI,CAAC,mBAAmB,GAAG,OAAO,EAAE,YAAY,IAAI,KAAK,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACH,IAAI,CACF,WAAqE,EACrE,UAA2E;QAE3E,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxE,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,UAA6B,EAAE;QAC5C,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,kDAAkD;YAClD,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;QACjD,IAAI,UAAU,GAAc,EAAE,CAAC;QAC/B,IAAI,YAAY,GAA6B,IAAI,CAAC;QAClD,IAAI,cAAc,GAAmB,MAAM,CAAC;QAC5C,IAAI,WAAW,GAAG,WAAW,CAAC;QAC9B,IAAI,SAA6B,CAAC;QAElC,mBAAmB;QACnB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAsB,CAAC;QAE/F,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,EAAE,CAAC;YACxC,yCAAyC;YACzC,OAAO,aAAkB,CAAC;QAC5B,CAAC;QAED,YAAY,GAAG,aAAa,CAAC;QAC7B,cAAc,GAAG,oBAAoB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAE9D,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAI,aAAa,CAAC,OAAO,CAAe,IAAI,EAAE,CAAC;QAElE,sCAAsC;QACtC,IAAI,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;YACxD,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;QAClC,CAAC;QAED,gCAAgC;QAChC,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;YAC9B,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;QACnD,CAAC;aAAM,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;YACtC,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,IAAI,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC;QACvF,CAAC;QAED,wBAAwB;QACxB,OAAO,YAAY,CAAC,YAAY,EAAE,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACrE,cAAc;YACd,IAAI,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;gBACtD,MAAM;YACR,CAAC;YAED,kBAAkB;YAClB,IAAI,YAA+B,CAAC;YAEpC,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;gBAC9B,YAAY,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAsB,CAAC;YAC1F,CAAC;iBAAM,IAAI,cAAc,KAAK,OAAO,IAAI,SAAS,EAAE,CAAC;gBACnD,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,KAAK,SAAS;oBAChE,CAAC,CAAC,eAAe;oBACjB,CAAC,CAAC,WAAW,CAAC;gBAChB,YAAY,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAsB,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;YAED,YAAY,GAAG,YAAY,CAAC;YAC5B,MAAM,QAAQ,GAAI,YAAY,CAAC,OAAO,CAAe,IAAI,EAAE,CAAC;YAE5D,2BAA2B;YAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM;YACR,CAAC;YAED,wBAAwB;YACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,iBAAiB,GAAG,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC;gBACpD,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3C,CAAC;YAED,4BAA4B;YAC5B,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;gBAC9B,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC;YACjC,CAAC;iBAAM,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;gBACtC,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACnF,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,aAAa,GAAsB;YACvC,GAAG,YAAY;YACf,CAAC,OAAO,CAAC,EAAE,UAAU;YACrB,QAAQ,EAAE;gBACR,GAAG,YAAY,CAAC,QAAQ;gBACxB,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,IAAI,EAAE,WAAW;aAClB;SACF,CAAC;QAEF,4CAA4C;QAC5C,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;YAC/B,OAAO,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC5C,OAAO,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC1C,CAAC;QAED,OAAO,aAAkB,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAA4B,EAC5B,OAGC;IAED,OAAO,IAAI,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Request execution module
3
+ *
4
+ * Handles the full request lifecycle:
5
+ * 1. Authentication
6
+ * 2. Throttling (if enabled)
7
+ * 3. Request execution
8
+ * 4. Error handling with retry
9
+ */
10
+ import type { ResolvedConfig } from '../core/types.js';
11
+ import type { AuthStrategy } from '../auth/types.js';
12
+ import type { Logger } from '../core/logger.js';
13
+ import type { Throttle } from './throttle.js';
14
+ export interface RequestOptions {
15
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
16
+ path: string;
17
+ body?: unknown;
18
+ query?: Record<string, string | number | boolean | undefined>;
19
+ /** Database ID for temp token auth */
20
+ dbid?: string;
21
+ /** Custom headers */
22
+ headers?: Record<string, string>;
23
+ }
24
+ export interface RequestExecutorOptions {
25
+ config: ResolvedConfig;
26
+ auth: AuthStrategy;
27
+ throttle: Throttle;
28
+ logger: Logger;
29
+ }
30
+ /**
31
+ * Extract dbid from request options for temp-token auth.
32
+ * Checks multiple locations where table/app ID may appear.
33
+ */
34
+ export declare function extractDbid(options: RequestOptions): string | undefined;
35
+ /**
36
+ * Execute a request with full retry logic
37
+ */
38
+ export declare function executeRequest<T = unknown>(options: RequestOptions, executor: RequestExecutorOptions): Promise<T>;
39
+ /**
40
+ * Create a request executor
41
+ */
42
+ export declare function createRequestExecutor(options: RequestExecutorOptions): {
43
+ execute: <T = unknown>(requestOptions: RequestOptions) => Promise<T>;
44
+ };
45
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/client/request.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAY9C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CA8BvE;AA2ID;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,OAAO,EAC9C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,sBAAsB,GAC/B,OAAO,CAAC,CAAC,CAAC,CA8EZ;AAcD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB;cAEvD,CAAC,4BAA4B,cAAc;EAGxD"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Request execution module
3
+ *
4
+ * Handles the full request lifecycle:
5
+ * 1. Authentication
6
+ * 2. Throttling (if enabled)
7
+ * 3. Request execution
8
+ * 4. Error handling with retry
9
+ */
10
+ import { QuickbaseError, RateLimitError, TimeoutError, parseErrorResponse, isRetryableError, } from '../core/errors.js';
11
+ import { extractRateLimitInfo, sleep } from './retry.js';
12
+ import { getRealmHostname } from '../core/config.js';
13
+ import { transformDates } from '../core/dates.js';
14
+ /**
15
+ * Extract dbid from request options for temp-token auth.
16
+ * Checks multiple locations where table/app ID may appear.
17
+ */
18
+ export function extractDbid(options) {
19
+ // 1. Explicit dbid takes priority
20
+ if (options.dbid) {
21
+ return options.dbid;
22
+ }
23
+ // 2. Check query params for tableId
24
+ if (options.query?.tableId) {
25
+ return String(options.query.tableId);
26
+ }
27
+ // 3. Check path for tableId (e.g., /v1/tables/{tableId}/...)
28
+ const tableIdMatch = options.path.match(/\/tables\/([^/?]+)/);
29
+ if (tableIdMatch) {
30
+ return tableIdMatch[1];
31
+ }
32
+ // 4. Check request body for 'from' field (runQuery, deleteRecords)
33
+ if (options.body && typeof options.body === 'object') {
34
+ const body = options.body;
35
+ if (typeof body.from === 'string') {
36
+ return body.from;
37
+ }
38
+ // 5. Check request body for 'to' field (upsert)
39
+ if (typeof body.to === 'string') {
40
+ return body.to;
41
+ }
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Build URL with query parameters
47
+ */
48
+ function buildUrl(baseUrl, path, query) {
49
+ // Ensure baseUrl ends with / and path doesn't start with / to properly join them
50
+ // new URL('/apps/x', 'https://api.quickbase.com/v1') would give https://api.quickbase.com/apps/x (wrong)
51
+ // new URL('apps/x', 'https://api.quickbase.com/v1/') gives https://api.quickbase.com/v1/apps/x (correct)
52
+ const normalizedBase = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
53
+ const normalizedPath = path.startsWith('/') ? path.slice(1) : path;
54
+ const url = new URL(normalizedPath, normalizedBase);
55
+ if (query) {
56
+ for (const [key, value] of Object.entries(query)) {
57
+ if (value !== undefined) {
58
+ url.searchParams.set(key, String(value));
59
+ }
60
+ }
61
+ }
62
+ return url.toString();
63
+ }
64
+ /**
65
+ * Create request headers
66
+ */
67
+ async function buildHeaders(auth, realmHostname, dbid, customHeaders) {
68
+ const token = await auth.getToken(dbid);
69
+ const authHeader = auth.getAuthorizationHeader(token);
70
+ return {
71
+ 'Content-Type': 'application/json',
72
+ 'QB-Realm-Hostname': realmHostname,
73
+ 'Authorization': authHeader,
74
+ ...customHeaders,
75
+ };
76
+ }
77
+ /**
78
+ * Execute a single request (no retry logic)
79
+ */
80
+ async function executeSingleRequest(options, executor, context) {
81
+ const { config, auth, throttle, logger } = executor;
82
+ const url = buildUrl(config.baseUrl, options.path, options.query);
83
+ const realmHostname = getRealmHostname(config.realm);
84
+ // Get auth headers (use extracted dbid from context)
85
+ const headers = await buildHeaders(auth, realmHostname, context.dbid, options.headers);
86
+ // Apply throttling if enabled
87
+ await throttle.acquire();
88
+ // Build fetch options
89
+ const fetchOptions = {
90
+ method: options.method,
91
+ headers,
92
+ };
93
+ if (options.body !== undefined) {
94
+ fetchOptions.body = JSON.stringify(options.body);
95
+ }
96
+ // Create abort controller for timeout
97
+ const controller = new AbortController();
98
+ const timeoutId = setTimeout(() => controller.abort(), config.timeout);
99
+ fetchOptions.signal = controller.signal;
100
+ const startTime = Date.now();
101
+ try {
102
+ const response = await config.fetchApi(url, fetchOptions);
103
+ const duration = Date.now() - startTime;
104
+ logger.timing(options.method, options.path, duration);
105
+ return response;
106
+ }
107
+ catch (error) {
108
+ if (error instanceof Error && error.name === 'AbortError') {
109
+ throw new TimeoutError(config.timeout);
110
+ }
111
+ throw error;
112
+ }
113
+ finally {
114
+ clearTimeout(timeoutId);
115
+ }
116
+ }
117
+ /**
118
+ * Handle response and throw appropriate errors
119
+ */
120
+ async function handleResponse(response, requestUrl, context, executor) {
121
+ const { config, logger } = executor;
122
+ if (response.ok) {
123
+ return response;
124
+ }
125
+ // Extract rate limit info for 429s
126
+ if (response.status === 429) {
127
+ const rateLimitInfo = extractRateLimitInfo(response, requestUrl, context.attempt);
128
+ logger.rateLimit({
129
+ url: requestUrl,
130
+ status: 429,
131
+ retryAfter: rateLimitInfo.retryAfter,
132
+ attempt: context.attempt,
133
+ rayId: rateLimitInfo.qbApiRay || rateLimitInfo.cfRay,
134
+ });
135
+ // Notify callback
136
+ if (config.onRateLimit) {
137
+ config.onRateLimit(rateLimitInfo);
138
+ }
139
+ throw new RateLimitError(rateLimitInfo);
140
+ }
141
+ // Parse and throw appropriate error
142
+ throw await parseErrorResponse(response, requestUrl);
143
+ }
144
+ /**
145
+ * Execute a request with full retry logic
146
+ */
147
+ export async function executeRequest(options, executor) {
148
+ const { config, auth, logger } = executor;
149
+ const maxAttempts = config.retry.maxAttempts;
150
+ // Extract dbid for temp-token auth
151
+ const dbid = extractDbid(options);
152
+ const context = {
153
+ methodName: `${options.method} ${options.path}`,
154
+ attempt: 1,
155
+ maxAttempts,
156
+ dbid,
157
+ startTime: Date.now(),
158
+ };
159
+ let lastError = null;
160
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
161
+ context.attempt = attempt;
162
+ try {
163
+ const response = await executeSingleRequest(options, executor, context);
164
+ const url = buildUrl(config.baseUrl, options.path, options.query);
165
+ await handleResponse(response, url, context, executor);
166
+ // Parse JSON response and optionally transform dates
167
+ const data = await response.json();
168
+ return transformDates(data, config.convertDates);
169
+ }
170
+ catch (error) {
171
+ lastError = error;
172
+ // Check if error is retryable
173
+ if (!isRetryableError(error)) {
174
+ throw error;
175
+ }
176
+ // Don't retry if we've exhausted attempts
177
+ if (attempt >= maxAttempts) {
178
+ throw error;
179
+ }
180
+ // Handle auth errors specially - try to refresh token
181
+ if (error instanceof QuickbaseError && error.statusCode === 401) {
182
+ const refreshed = await auth.handleAuthError(dbid);
183
+ if (!refreshed) {
184
+ throw error;
185
+ }
186
+ logger.debug('Token refreshed, retrying request');
187
+ continue;
188
+ }
189
+ // Calculate retry delay
190
+ let delayMs;
191
+ let reason;
192
+ if (error instanceof RateLimitError) {
193
+ delayMs = error.retryAfter
194
+ ? error.retryAfter * 1000
195
+ : calculateBackoff(attempt, config.retry);
196
+ reason = 'Rate limited (429)';
197
+ }
198
+ else if (error instanceof TimeoutError) {
199
+ delayMs = calculateBackoff(attempt, config.retry);
200
+ reason = 'Timeout';
201
+ }
202
+ else if (error instanceof QuickbaseError && error.statusCode >= 500) {
203
+ delayMs = calculateBackoff(attempt, config.retry);
204
+ reason = `Server error (${error.statusCode})`;
205
+ }
206
+ else {
207
+ delayMs = calculateBackoff(attempt, config.retry);
208
+ reason = 'Retryable error';
209
+ }
210
+ logger.retry(attempt, maxAttempts, delayMs, reason);
211
+ await sleep(delayMs);
212
+ }
213
+ }
214
+ throw lastError || new Error('Request failed');
215
+ }
216
+ /**
217
+ * Calculate exponential backoff delay with jitter
218
+ */
219
+ function calculateBackoff(attempt, config) {
220
+ const delay = config.initialDelayMs * Math.pow(config.multiplier, attempt - 1);
221
+ const jitter = delay * 0.1 * (Math.random() * 2 - 1);
222
+ return Math.min(delay + jitter, config.maxDelayMs);
223
+ }
224
+ /**
225
+ * Create a request executor
226
+ */
227
+ export function createRequestExecutor(options) {
228
+ return {
229
+ execute: (requestOptions) => executeRequest(requestOptions, options),
230
+ };
231
+ }
232
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/client/request.ts"],"names":[],"mappings":"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"}