quickbase-js 1.1.0-beta.5 → 1.1.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.
Files changed (110) hide show
  1. package/README.md +253 -135
  2. package/dist/esm/quickbase.d.ts +5614 -2861
  3. package/dist/esm/quickbase.js +3203 -2113
  4. package/dist/esm/quickbase.js.map +1 -1
  5. package/dist/esm/quickbase.min.js +1 -1
  6. package/dist/esm/quickbase.min.js.map +1 -1
  7. package/dist/umd/quickbase.umd.js +3532 -2322
  8. package/dist/umd/quickbase.umd.js.map +1 -1
  9. package/dist/umd/quickbase.umd.min.js +1 -1
  10. package/dist/umd/quickbase.umd.min.js.map +1 -1
  11. package/package.json +49 -32
  12. package/CHANGELOG.md +0 -86
  13. package/build.js +0 -186
  14. package/dist/umd/quickbase.umd.d.ts +0 -5341
  15. package/examples/react.js +0 -48
  16. package/examples/vanillajs.html +0 -47
  17. package/log-gen.yaml +0 -1301
  18. package/open-api/definitions/apps.ts +0 -274
  19. package/open-api/definitions/auth.ts +0 -10
  20. package/open-api/definitions/fields.ts +0 -751
  21. package/open-api/definitions/index.ts +0 -18
  22. package/open-api/definitions/records.ts +0 -269
  23. package/open-api/definitions/relationships.ts +0 -90
  24. package/open-api/definitions/reports.ts +0 -10
  25. package/open-api/definitions/tables.ts +0 -112
  26. package/open-api/fix-spec-main.ts +0 -176
  27. package/open-api/generate-unified-interface.ts +0 -170
  28. package/open-api/output/quickbase-fixed.json +0 -6760
  29. package/open-api/paths/apps.ts +0 -100
  30. package/open-api/paths/auth.ts +0 -25
  31. package/open-api/paths/fields.ts +0 -207
  32. package/open-api/paths/index.ts +0 -17
  33. package/open-api/paths/records.ts +0 -68
  34. package/open-api/paths/relationships.ts +0 -32
  35. package/open-api/paths/reports.ts +0 -34
  36. package/open-api/paths/tables.ts +0 -162
  37. package/open-api/regenerate-client.ts +0 -110
  38. package/playwright-results.txt/.last-run.json +0 -4
  39. package/playwright.config.ts +0 -37
  40. package/rollup.config.mjs +0 -114
  41. package/specs/QuickBase_RESTful_API_2025-03-04T06_22_39.725Z.json +0 -46878
  42. package/src/generated-unified/QuickbaseClient.ts +0 -62
  43. package/src/index.ts +0 -1
  44. package/src/quickbaseClient.ts +0 -311
  45. package/src/tokenCache.ts +0 -51
  46. package/test-artifacts/.last-run.json +0 -6
  47. package/test-esm.js +0 -1
  48. package/test-results.json +0 -2050
  49. package/test-umd.js +0 -1
  50. package/test.ts +0 -1
  51. package/tests/playwright/qb/auth/cacheSwitching.test.ts +0 -189
  52. package/tests/playwright/qb/auth/fetchTempToken401.test.ts +0 -217
  53. package/tests/playwright/qb/auth/getAppWithUserToken.test.ts +0 -151
  54. package/tests/playwright/qb/auth/getTempToken.test.ts +0 -180
  55. package/tests/playwright/qb/auth/tokenPrefetch.test.ts +0 -192
  56. package/tests/playwright/qb/auth/tokenRenewal.test.ts +0 -110
  57. package/tests/playwright/qb/auth/umd.test.ts +0 -10
  58. package/tests/setup.ts +0 -51
  59. package/tests/vitest/qb/apps/copyApp.test.ts +0 -76
  60. package/tests/vitest/qb/apps/createApp.test.ts +0 -64
  61. package/tests/vitest/qb/apps/deleteApp.test.ts +0 -76
  62. package/tests/vitest/qb/apps/getApp.test.ts +0 -40
  63. package/tests/vitest/qb/fields/createField.test.ts +0 -78
  64. package/tests/vitest/qb/fields/deleteFields.test.ts +0 -89
  65. package/tests/vitest/qb/fields/getField.test.ts +0 -85
  66. package/tests/vitest/qb/fields/getFieldUsage.test.ts +0 -174
  67. package/tests/vitest/qb/fields/getFields.test.ts +0 -232
  68. package/tests/vitest/qb/fields/getFieldsUsage.test.ts +0 -77
  69. package/tests/vitest/qb/index.ts +0 -28
  70. package/tests/vitest/qb/records/deleteRecords.test.ts +0 -110
  71. package/tests/vitest/qb/records/runQuery.test.ts +0 -146
  72. package/tests/vitest/qb/records/upsert.test.ts +0 -102
  73. package/tests/vitest/qb/tables/createTable.test.ts +0 -55
  74. package/tests/vitest/qb/tables/deleteTable.test.ts +0 -50
  75. package/tests/vitest/qb/tables/getAppTables.test.ts +0 -46
  76. package/tests/vitest/qb/tables/getRelationships.test.ts +0 -80
  77. package/tests/vitest/qb/tables/getTable.test.ts +0 -26
  78. package/tests/vitest/qb/tables/updateTable.test.ts +0 -48
  79. package/tests/vitest/unit/apps/copyApp.test.ts +0 -282
  80. package/tests/vitest/unit/apps/createApp.test.ts +0 -125
  81. package/tests/vitest/unit/apps/deleteApp.test.ts +0 -215
  82. package/tests/vitest/unit/apps/getApp.test.ts +0 -86
  83. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +0 -85
  84. package/tests/vitest/unit/auth/getTempToken.test.ts +0 -95
  85. package/tests/vitest/unit/auth/retryOn401.test.ts +0 -106
  86. package/tests/vitest/unit/auth/two401s.test.ts +0 -77
  87. package/tests/vitest/unit/fields/createField.test.ts +0 -391
  88. package/tests/vitest/unit/fields/deleteFields.test.ts +0 -141
  89. package/tests/vitest/unit/fields/getField.test.ts +0 -189
  90. package/tests/vitest/unit/fields/getFieldUsage.test.ts +0 -147
  91. package/tests/vitest/unit/fields/getFields.test.ts +0 -122
  92. package/tests/vitest/unit/fields/getFieldsUsage.test.ts +0 -160
  93. package/tests/vitest/unit/index.ts +0 -33
  94. package/tests/vitest/unit/records/deleteRecords.test.ts +0 -112
  95. package/tests/vitest/unit/records/runQuery.test.ts +0 -102
  96. package/tests/vitest/unit/records/upsert.test.ts +0 -218
  97. package/tests/vitest/unit/tables/createTable.test.ts +0 -70
  98. package/tests/vitest/unit/tables/deleteTable.test.ts +0 -77
  99. package/tests/vitest/unit/tables/getAppTables.test.ts +0 -85
  100. package/tests/vitest/unit/tables/getRelationships.test.ts +0 -259
  101. package/tests/vitest/unit/tables/getTable.test.ts +0 -233
  102. package/tests/vitest/unit/tables/updateTable.test.ts +0 -80
  103. package/tests/vitest/unit/umd.test.ts +0 -8
  104. package/text.txt +0 -104
  105. package/tools/log-gen.ts +0 -175
  106. package/tools/openapi-jars/openapi-generator-cli-7.12.0.jar +0 -0
  107. package/tsconfig.build.json +0 -17
  108. package/tsconfig.json +0 -29
  109. package/versionrc.json +0 -9
  110. package/vitest.config.ts +0 -27
package/log-gen.yaml DELETED
@@ -1,1301 +0,0 @@
1
- project: quickbase-js
2
- date: 3/12/2025
3
- root: /home/drew/Projects/quickbase-js
4
- goals:
5
- - A library for interacting with the QuickBase RESTful API.
6
- - Use OpenAPI to generate types and methods using a proxy. Validate with tests.
7
- - Provide robust and intuitive temporary token support for browser environments.
8
- - User Tokens support both Node.js and browser environments.
9
- - 'Use case: JS frameworks like React, Vue, and Angular hosted in QuickBase code pages.'
10
- - Enable a flexible or native fetch in the browser.
11
- - Enable a flexible fetch framework in Node.js.
12
- - '#'
13
- - No manual updating methods when the QuickBase API changes.
14
- - The proxy magic dynamically maps generated methods and types.
15
- - '#'
16
- - TokenCache is defined per quickbaseClient call, so each instance has its own isolated TokenCache.
17
- - Each quickbase client instance has an isolated and individual token cache.
18
- pipelineOverview:
19
- - 'fix-spec-main.ts: Input: Reads the latest QuickBase_RESTful*.json file from the specs/ folder and applies fixes to the parameters and paths.'
20
- - filters out the QB-Realm-Hostname, Authorization, and User-Agent parameters.
21
- - Converts parameter names to camelCase.
22
- - Fixes array schemas and applies custom paths.
23
- - Merges paths from fix-spec-paths.ts and definitions from fix-spec-definitions.ts.
24
- - 'Output: writes quickbase-fixed.json to src/code-generation/output/.'
25
- - 'Key Behavior: The merge (spec.paths = { ...spec.paths, ...paths }) preserves all origional endpoints, only overriding those defined in fix-spec-paths.ts.'
26
- - '#'
27
- - 'regenerate-client.ts: Uses quickbase-fixed.json to generate raw TypeScript-fetch files (src/generated/). including models and APIs.'
28
- - '#'
29
- - 'generate-unified-interface.ts: Uses quickbase-fixed.json to generate a unified QuickbaseClient.ts interface in src/generated-unified/.'
30
- - QuickbaseClient.ts includes all endpoints from src/code-generation/output/quickbase-fixed, and types from src/generated.
31
- - '#'
32
- - /specs/QuickBase_RESTful_API_*.json is over 46k lines of JSON, so it's not included in the snapshot, its too large to give to an AI.
33
- - which creates difficulties in understanding the structure of the API.
34
- - It makes it difficult to model the src/code-generation/fix-spec-*.ts files in the snapshot.
35
- - '#'
36
- - vitest unit and integration tests. Integration tests use the real QuickBase API with user token auth.
37
- - playwright is used to test the real QuickBase API in a browser enviornment with temporary token auth.
38
- - temp tokens can only be generated in a browser enviornment and can not be fetched with a user token.
39
- - '#'
40
- - getTempTokenDBID() method is wrapped to enhance temporary token generation reuse interacting with a token cache.
41
- - '#'
42
- - 'npm run fix-spec: Generates quickbase-fixed.json from the latest QuickBase_RESTful*.json file.'
43
- - npm run regenerate:openapi Generates raw TypeScript-fetch files in src/generated/.
44
- - 'npm run generate:unified: Generates a unified QuickbaseClient.ts interface in src/generated-unified/.'
45
- tree:
46
- name: .
47
- type: directory
48
- children:
49
- - name: .env
50
- type: file
51
- - name: .gitignore
52
- type: file
53
- - name: CHANGELOG.md
54
- type: file
55
- - name: LICENSE
56
- type: file
57
- - name: README.md
58
- type: file
59
- - name: build.js
60
- type: file
61
- contents: |-
62
- import { execSync } from 'child_process';
63
- import { rollup } from 'rollup';
64
- import terser from '@rollup/plugin-terser';
65
- import nodeResolve from '@rollup/plugin-node-resolve';
66
- import commonjs from '@rollup/plugin-commonjs';
67
- import dts from 'rollup-plugin-dts';
68
- import { rimrafSync } from 'rimraf';
69
- import { copyFileSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
70
- import { join } from 'path';
71
-
72
- // Clean the dist folder
73
- rimrafSync('dist');
74
- rimrafSync('dist/temp-src');
75
-
76
- // Step 1: Copy runtime-relevant files from src/ to dist/temp-src and remove .ts extensions
77
- const srcDir = join(process.cwd(), 'src');
78
- const tempSrcDir = join(process.cwd(), 'dist/temp-src');
79
- const runtimeDirs = ['generated', 'generated-unified'];
80
- const runtimeFiles = ['index.ts', 'quickbaseClient.ts', 'tokenCache.ts'];
81
-
82
- function copyAndRewriteTsExtensions(src, dest) {
83
- console.log(`Copying from ${src} to ${dest}`);
84
- mkdirSync(dest, { recursive: true });
85
- const files = readdirSync(src, { withFileTypes: true });
86
- for (const file of files) {
87
- const srcPath = join(src, file.name);
88
- const destPath = join(dest, file.name);
89
- if (file.isDirectory()) {
90
- if (runtimeDirs.includes(file.name) || runtimeDirs.some(dir => src.includes(dir))) {
91
- copyAndRewriteTsExtensions(srcPath, destPath);
92
- } else {
93
- console.log(`Skipping non-runtime directory ${srcPath}`);
94
- }
95
- } else if (file.name.endsWith('.ts')) {
96
- if (runtimeFiles.includes(file.name) || src.includes('generated') || src.includes('generated-unified')) {
97
- console.log(`Processing ${srcPath} -> ${destPath}`);
98
- let content = readFileSync(srcPath, 'utf8');
99
- content = content.replace(/(from\s+["']\.[\w\/-]+)\.ts(["'])/g, '$1$2');
100
- content = content.replace(/(export\s+\*\s+from\s+["']\.[\w\/-]+)\.ts(["'])/g, '$1$2');
101
- writeFileSync(destPath, content, 'utf8');
102
- } else {
103
- console.log(`Skipping non-runtime file ${srcPath}`);
104
- }
105
- } else {
106
- console.log(`Skipping non-.ts file ${srcPath}`);
107
- }
108
- }
109
- }
110
- copyAndRewriteTsExtensions(srcDir, tempSrcDir);
111
-
112
- // Step 2: Compile TypeScript to JavaScript with tsc
113
- console.log('Running tsc...');
114
- const tsFiles = readdirSync(tempSrcDir, { recursive: true })
115
- .filter(file => file.endsWith('.ts'))
116
- .map(file => join(tempSrcDir, file));
117
- const tscCommand = `npx tsc ${tsFiles.join(' ')} --outDir ${join(process.cwd(), 'dist/temp')} --module ESNext --target ESNext --sourceMap --moduleResolution bundler --baseUrl ${process.cwd()}`;
118
- console.log(`Command: ${tscCommand}`);
119
- execSync(tscCommand, { stdio: 'inherit' });
120
-
121
- // Step 3: Rollup configuration
122
- const isProd = process.env.NODE_ENV === 'production';
123
- const external = [
124
- 'node:http', 'node:https', 'node:zlib', 'node:stream', 'node:buffer',
125
- 'node:util', 'node:url', 'node:net', 'node:fs', 'node:path', 'node-fetch',
126
- ];
127
- const globals = { 'node-fetch': 'fetch' };
128
-
129
- // ESM Build
130
- console.log(`Building ESM bundle (${isProd ? 'minified' : 'unminified'})...`);
131
- const esmBundle = await rollup({
132
- input: 'dist/temp/quickbaseClient.js',
133
- external,
134
- plugins: [
135
- nodeResolve({ preferBuiltins: true }),
136
- commonjs(),
137
- isProd && terser(), // Only minify in prod
138
- ],
139
- });
140
- await esmBundle.write({
141
- dir: 'dist/esm',
142
- format: 'esm',
143
- sourcemap: true,
144
- entryFileNames: isProd ? 'quickbase.min.js' : 'quickbase.js',
145
- });
146
- await esmBundle.close();
147
-
148
- // UMD Build
149
- console.log(`Building UMD bundle (${isProd ? 'minified' : 'unminified'})...`);
150
- const umdBundle = await rollup({
151
- input: 'dist/temp/quickbaseClient.js',
152
- external,
153
- plugins: [
154
- nodeResolve({ preferBuiltins: true, browser: true }),
155
- commonjs(),
156
- isProd && terser(), // Only minify in prod
157
- ],
158
- });
159
- await umdBundle.write({
160
- file: join(process.cwd(), 'dist/umd', isProd ? 'quickbase.umd.min.js' : 'quickbase.umd.js'),
161
- format: 'umd',
162
- name: 'QuickbaseJS',
163
- sourcemap: true,
164
- globals,
165
- });
166
- await umdBundle.close();
167
-
168
- // Declarations
169
- console.log('Generating declarations...');
170
- const dtsBundle = await rollup({
171
- input: 'src/quickbaseClient.ts',
172
- plugins: [dts({ tsconfig: './tsconfig.json', respectExternal: true })],
173
- });
174
- await dtsBundle.write({ file: 'dist/esm/quickbase.d.ts', format: 'esm' });
175
- await dtsBundle.write({ file: 'dist/umd/quickbase.umd.d.ts', format: 'umd' });
176
- await dtsBundle.close();
177
-
178
- // Clean up
179
- rimrafSync('dist/temp');
180
- rimrafSync('dist/temp-src');
181
- console.log('Build completed successfully');
182
- - name: dist
183
- type: directory
184
- children:
185
- - name: esm
186
- type: directory
187
- children:
188
- - name: quickbase.d.ts
189
- type: file
190
- - name: quickbase.min.js
191
- type: file
192
- - name: quickbase.min.js.map
193
- type: file
194
- - name: umd
195
- type: directory
196
- children:
197
- - name: quickbase.umd.d.ts
198
- type: file
199
- - name: quickbase.umd.min.js
200
- type: file
201
- - name: quickbase.umd.min.js.map
202
- type: file
203
- - name: examples
204
- type: directory
205
- children:
206
- - name: react.js
207
- type: file
208
- - name: vanillajs.html
209
- type: file
210
- - name: log-gen.yaml
211
- type: file
212
- - name: open-api
213
- type: directory
214
- children:
215
- - name: definitions
216
- type: directory
217
- children:
218
- - name: apps.ts
219
- type: file
220
- - name: auth.ts
221
- type: file
222
- - name: fields.ts
223
- type: file
224
- - name: index.ts
225
- type: file
226
- - name: records.ts
227
- type: file
228
- - name: relationships.ts
229
- type: file
230
- - name: reports.ts
231
- type: file
232
- - name: tables.ts
233
- type: file
234
- - name: fix-spec-main.ts
235
- type: file
236
- - name: generate-unified-interface.ts
237
- type: file
238
- - name: output
239
- type: directory
240
- children:
241
- - name: quickbase-fixed.json
242
- type: file
243
- - name: paths
244
- type: directory
245
- children:
246
- - name: apps.ts
247
- type: file
248
- - name: auth.ts
249
- type: file
250
- - name: fields.ts
251
- type: file
252
- - name: index.ts
253
- type: file
254
- - name: records.ts
255
- type: file
256
- - name: relationships.ts
257
- type: file
258
- - name: reports.ts
259
- type: file
260
- - name: tables.ts
261
- type: file
262
- - name: regenerate-client.ts
263
- type: file
264
- - name: openapitools.json
265
- type: file
266
- - name: package-lock.json
267
- type: file
268
- - name: package.json
269
- type: file
270
- contents: |
271
- {
272
- "name": "quickbase-js",
273
- "version": "1.1.0-beta.4",
274
- "description": "QuickBase JavaScript client for frameworks and vanilla JS",
275
- "type": "module",
276
- "main": "dist/esm/quickbase.js",
277
- "module": "dist/esm/quickbase.js",
278
- "types": "dist/esm/quickbase.d.ts",
279
- "publishConfig": {
280
- "access": "public"
281
- },
282
- "exports": {
283
- ".": {
284
- "import": {
285
- "minified": "./dist/esm/quickbase.min.js",
286
- "default": "./dist/esm/quickbase.js"
287
- },
288
- "require": {
289
- "minified": "./dist/umd/quickbase.umd.min.js",
290
- "default": "./dist/umd/quickbase.umd.js"
291
- },
292
- "types": "./dist/esm/quickbase.d.ts",
293
- "umd:types": "./dist/umd/quickbase.umd.d.ts"
294
- }
295
- },
296
- "scripts": {
297
- "release": "standard-version",
298
- "release:beta": "standard-version --prerelease beta",
299
- "release:alpha": "standard-version --prerelease alpha",
300
- "release:push": "npm run release:beta && git push --follow-tags origin main",
301
- "release:publish": "npm run release:push && npm publish --tag beta",
302
-
303
-
304
- "fix-spec": "node --loader ts-node/esm open-api/fix-spec-main.ts",
305
- "regenerate:openapi": "rimraf src/generated && node --loader ts-node/esm open-api/regenerate-client.ts",
306
- "regenerate:unified": "node --loader ts-node/esm open-api/generate-unified-interface.ts",
307
- "regenerate:all": "npm run fix-spec && npm run regenerate:openapi && npm run regenerate:unified",
308
- "log-gen": "node --loader ts-node/esm tools/log-gen.ts",
309
- "build": "rimraf dist && node --loader ts-node/esm build.js",
310
- "build:prod": "rimraf dist && NODE_ENV=production node --loader ts-node/esm build.js",
311
-
312
-
313
- "build-old": "rimraf dist && rollup -c",
314
- "build:prod-old": "rimraf dist && NODE_ENV=production rollup -c",
315
- "test:all": "vitest run tests/vitest/**/**/*.test.ts --reporter=basic && playwright test tests/playwright/qb --config playwright.config.ts --reporter=dot --quiet",
316
- "test:pw:qb:all": "playwright test tests/playwright/qb --config playwright.config.ts",
317
- "test:vitest:all": "vitest run tests/vitest/**/**/*.test.ts",
318
- "test:vitest:qb": "vitest run tests/vitest/qb/**/*.test.ts",
319
- "test:vitest:unit": "vitest run tests/vitest/unit/**/*.test.ts",
320
- "test:vitest:qb:apps": "vitest run tests/vitest/qb/apps/**/*.test.ts",
321
- "test:vitest:qb:auth": "vitest run tests/vitest/qb/auth/**/*.test.ts",
322
- "test:vitest:qb:fields": "vitest run tests/vitest/qb/fields/**/*.test.ts",
323
- "test:vitest:qb:records": "vitest run tests/vitest/qb/records/**/*.test.ts",
324
- "test:vitest:qb:tables": "vitest run tests/vitest/qb/tables/**/*.test.ts",
325
- "test:vitest:unit:apps": "vitest run tests/vitest/unit/apps/**/*.test.ts",
326
- "test:vitest:unit:auth": "vitest run tests/vitest/unit/auth/**/*.test.ts",
327
- "test:vitest:unit:fields": "vitest run tests/vitest/unit/fields/**/*.test.ts",
328
- "test:vitest:unit:records": "vitest run tests/vitest/unit/records/**/*.test.ts",
329
- "test:vitest:unit:tables": "vitest run tests/vitest/unit/tables/**/*.test.ts",
330
- "test:pw:qb:auth": "playwright test tests/playwright/qb/auth"
331
- },
332
- "dependencies": {
333
- "typescript": "^5.8.2"
334
- },
335
- "devDependencies": {
336
- "@openapitools/openapi-generator-cli": "^2.17.0",
337
- "@playwright/test": "^1.51.0",
338
- "@rollup/plugin-commonjs": "^28.0.3",
339
- "@rollup/plugin-node-resolve": "^16.0.0",
340
- "@rollup/plugin-terser": "^0.4.4",
341
- "@rollup/plugin-typescript": "^12.1.2",
342
- "@types/js-yaml": "^4.0.9",
343
- "@types/node": "^22.13.10",
344
- "dotenv": "^16.4.7",
345
- "glob": "^11.0.1",
346
- "js-yaml": "^4.1.0",
347
- "jsdom": "^26.0.0",
348
- "node-fetch": "^3.3.2",
349
- "openapi-types": "^12.1.3",
350
- "rimraf": "^5.0.10",
351
- "rollup": "^4.35.0",
352
- "rollup-plugin-dts": "^6.1.1",
353
- "standard-version": "^9.5.0",
354
- "ts-morph": "^25.0.1",
355
- "ts-node": "^10.9.2",
356
- "tslib": "^2.8.1",
357
- "undici-types": "^7.5.0",
358
- "vitest": "^3.0.8"
359
- }
360
- }
361
- - name: playwright-results.txt
362
- type: directory
363
- children:
364
- - name: .last-run.json
365
- type: file
366
- - name: playwright.config.ts
367
- type: file
368
- - name: rollup.config.mjs
369
- type: file
370
- - name: src
371
- type: directory
372
- children:
373
- - name: generated
374
- type: directory
375
- children:
376
- - name: .openapi-generator
377
- type: directory
378
- children:
379
- - name: FILES
380
- type: file
381
- - name: VERSION
382
- type: file
383
- - name: .openapi-generator-ignore
384
- type: file
385
- - name: apis
386
- type: directory
387
- children:
388
- - name: AppsApi.ts
389
- type: file
390
- - name: AuditApi.ts
391
- type: file
392
- - name: AuthApi.ts
393
- type: file
394
- - name: DocumentTemplatesApi.ts
395
- type: file
396
- - name: FieldsApi.ts
397
- type: file
398
- - name: FilesApi.ts
399
- type: file
400
- - name: FormulasApi.ts
401
- type: file
402
- - name: PlatformAnalyticsApi.ts
403
- type: file
404
- - name: RecordsApi.ts
405
- type: file
406
- - name: RelationshipsApi.ts
407
- type: file
408
- - name: ReportsApi.ts
409
- type: file
410
- - name: SolutionsApi.ts
411
- type: file
412
- - name: TablesApi.ts
413
- type: file
414
- - name: UserTokenApi.ts
415
- type: file
416
- - name: UsersApi.ts
417
- type: file
418
- - name: index.ts
419
- type: file
420
- - name: index.ts
421
- type: file
422
- - name: models
423
- type: directory
424
- children:
425
- - name: AddMembersToGroup200Response.ts
426
- type: file
427
- - name: AddSubgroupsToGroup200Response.ts
428
- type: file
429
- - name: App.ts
430
- type: file
431
- - name: AppMemoryInfo.ts
432
- type: file
433
- - name: AppSecurityProperties.ts
434
- type: file
435
- - name: Audit200Response.ts
436
- type: file
437
- - name: Audit202Response.ts
438
- type: file
439
- - name: AuditRequest.ts
440
- type: file
441
- - name: CloneUserToken200Response.ts
442
- type: file
443
- - name: CloneUserTokenRequest.ts
444
- type: file
445
- - name: CopyApp200Response.ts
446
- type: file
447
- - name: CopyAppRequest.ts
448
- type: file
449
- - name: CopyAppRequestProperties.ts
450
- type: file
451
- - name: CreateApp200Response.ts
452
- type: file
453
- - name: CreateAppRequest.ts
454
- type: file
455
- - name: CreateAppRequestVariablesInner.ts
456
- type: file
457
- - name: CreateField200Response.ts
458
- type: file
459
- - name: CreateFieldRequest.ts
460
- type: file
461
- - name: CreateRelationship200Response.ts
462
- type: file
463
- - name: CreateRelationshipRequest.ts
464
- type: file
465
- - name: CreateTableRequest.ts
466
- type: file
467
- - name: DeactivateUserToken200Response.ts
468
- type: file
469
- - name: DeleteApp200Response.ts
470
- type: file
471
- - name: DeleteAppRequest.ts
472
- type: file
473
- - name: DeleteFields200Response.ts
474
- type: file
475
- - name: DeleteFieldsRequest.ts
476
- type: file
477
- - name: DeleteFile200Response.ts
478
- type: file
479
- - name: DeleteRecords200Response.ts
480
- type: file
481
- - name: DeleteRecordsRequest.ts
482
- type: file
483
- - name: DeleteRelationship200Response.ts
484
- type: file
485
- - name: DeleteTableResponse.ts
486
- type: file
487
- - name: DenyUsers200Response.ts
488
- type: file
489
- - name: ExchangeSsoToken200Response.ts
490
- type: file
491
- - name: ExchangeSsoTokenRequest.ts
492
- type: file
493
- - name: Field.ts
494
- type: file
495
- - name: FieldPermissionsInner.ts
496
- type: file
497
- - name: FieldProperties.ts
498
- type: file
499
- - name: FieldUsage.ts
500
- type: file
501
- - name: FieldUsageField.ts
502
- type: file
503
- - name: FieldUsageUsage.ts
504
- type: file
505
- - name: GenerateDocument200Response.ts
506
- type: file
507
- - name: GetRelationships200Response.ts
508
- type: file
509
- - name: GetRelationships200ResponseMetadata.ts
510
- type: file
511
- - name: GetReport200Response.ts
512
- type: file
513
- - name: GetTempTokenDBID200Response.ts
514
- type: file
515
- - name: GetUsers200Response.ts
516
- type: file
517
- - name: GetUsersRequest.ts
518
- type: file
519
- - name: PlatformAnalyticEventSummaries200Response.ts
520
- type: file
521
- - name: PlatformAnalyticEventSummaries200ResponseMetadata.ts
522
- type: file
523
- - name: PlatformAnalyticEventSummaries200ResponseResultsInner.ts
524
- type: file
525
- - name: PlatformAnalyticEventSummaries200ResponseResultsInnerEventTypesInner.ts
526
- type: file
527
- - name: PlatformAnalyticEventSummaries200ResponseResultsInnerTotals.ts
528
- type: file
529
- - name: PlatformAnalyticEventSummaries200ResponseTotals.ts
530
- type: file
531
- - name: PlatformAnalyticEventSummaries200ResponseWhereInner.ts
532
- type: file
533
- - name: PlatformAnalyticEventSummariesRequest.ts
534
- type: file
535
- - name: PlatformAnalyticEventSummariesRequestWhereInner.ts
536
- type: file
537
- - name: PlatformAnalyticReads200Response.ts
538
- type: file
539
- - name: Record.ts
540
- type: file
541
- - name: RecordValue.ts
542
- type: file
543
- - name: Relationship.ts
544
- type: file
545
- - name: RelationshipField.ts
546
- type: file
547
- - name: RemoveMembersFromGroup200Response.ts
548
- type: file
549
- - name: RemoveSubgroupsFromGroup200Response.ts
550
- type: file
551
- - name: ReportRunResponse.ts
552
- type: file
553
- - name: RunFormula200Response.ts
554
- type: file
555
- - name: RunFormulaRequest.ts
556
- type: file
557
- - name: RunQueryRequest.ts
558
- type: file
559
- - name: RunQueryRequestGroupByInner.ts
560
- type: file
561
- - name: RunQueryRequestOptions.ts
562
- type: file
563
- - name: RunQueryRequestSortByInner.ts
564
- type: file
565
- - name: RunQueryResponse.ts
566
- type: file
567
- - name: RunQueryResponseFieldsInner.ts
568
- type: file
569
- - name: RunQueryResponseMetadata.ts
570
- type: file
571
- - name: Table.ts
572
- type: file
573
- - name: TransferUserToken200Response.ts
574
- type: file
575
- - name: TransferUserTokenRequest.ts
576
- type: file
577
- - name: UndenyUsers200Response.ts
578
- type: file
579
- - name: UpdateRelationshipRequest.ts
580
- type: file
581
- - name: UpdateTableRequest.ts
582
- type: file
583
- - name: Upsert200Response.ts
584
- type: file
585
- - name: Upsert200ResponseDataInnerValue.ts
586
- type: file
587
- - name: Upsert200ResponseMetadata.ts
588
- type: file
589
- - name: Upsert207Response.ts
590
- type: file
591
- - name: Upsert207ResponseMetadata.ts
592
- type: file
593
- - name: UpsertRequest.ts
594
- type: file
595
- - name: UsageCount.ts
596
- type: file
597
- - name: index.ts
598
- type: file
599
- - name: runtime.ts
600
- type: file
601
- - name: generated-unified
602
- type: directory
603
- children:
604
- - name: QuickbaseClient.ts
605
- type: file
606
- contents: |
607
- // Generated on 2025-03-12T19:20:50.952Z
608
- import { App, CopyApp200Response, CopyAppRequest, CreateApp200Response, CreateAppRequest, CreateField200Response, CreateFieldRequest, DeleteApp200Response, DeleteAppRequest, DeleteFields200Response, DeleteFieldsRequest, DeleteRecords200Response, DeleteRecordsRequest, DeleteTableResponse, Field, FieldUsage, GetRelationships200Response, GetTempTokenDBID200Response, ReportRunResponse, RunQueryRequest, RunQueryResponse, Table, UpdateTableRequest, Upsert200Response, Upsert207Response, UpsertRequest } from "../generated/models";
609
-
610
- export interface QuickbaseClient {
611
- createApp: (params: { body: CreateAppRequest }) => Promise<CreateApp200Response>;
612
- getApp: (params: { appId: string }) => Promise<App>;
613
- deleteApp: (params: { appId: string; body: DeleteAppRequest }) => Promise<DeleteApp200Response>;
614
- getAppEvents: (params: { appId: string }) => Promise<any[]>;
615
- copyApp: (params: { appId: string; body: CopyAppRequest }) => Promise<CopyApp200Response>;
616
- getAppTables: (params: { appId: string }) => Promise<Table[]>;
617
- createTable: (params: { appId: string; body: any }) => Promise<Table>;
618
- getTable: (params: { tableId: string; appId: string }) => Promise<Table>;
619
- updateTable: (params: { tableId: string; appId: string; body: UpdateTableRequest }) => Promise<Table>;
620
- deleteTable: (params: { tableId: string; appId: string }) => Promise<DeleteTableResponse>;
621
- getRelationships: (params: { tableId: string; skip?: number }) => Promise<GetRelationships200Response>;
622
- createRelationship: (params: { tableId: string; generated?: any }) => Promise<{ [key: string]: any }>;
623
- updateRelationship: (params: { tableId: string; relationshipId: any; generated?: any }) => Promise<{ [key: string]: any }>;
624
- deleteRelationship: (params: { tableId: string; relationshipId: any }) => Promise<{ [key: string]: any }>;
625
- getTableReports: (params: { tableId: string }) => Promise<any[]>;
626
- getReport: (params: { tableId: string; reportId: string }) => Promise<{ [key: string]: any }>;
627
- runReport: (params: { reportId: string; generated: any }) => Promise<ReportRunResponse[]>;
628
- getFields: (params: { tableId: string; includeFieldPerms?: boolean }) => Promise<Field[]>;
629
- createField: (params: { tableId: string; body: CreateFieldRequest }) => Promise<CreateField200Response>;
630
- deleteFields: (params: { tableId: string; body: DeleteFieldsRequest }) => Promise<DeleteFields200Response>;
631
- getField: (params: { fieldId: number; tableId: string; includeFieldPerms?: boolean }) => Promise<Field>;
632
- getFieldsUsage: (params: { tableId: string; skip?: number; top?: number }) => Promise<FieldUsage[]>;
633
- getFieldUsage: (params: { fieldId: number; tableId: string }) => Promise<FieldUsage[]>;
634
- runFormula: (params: { generated?: any }) => Promise<{ [key: string]: any }>;
635
- upsert: (params: { body: UpsertRequest }) => Promise<Upsert200Response | Upsert207Response>;
636
- deleteRecords: (params: { body: DeleteRecordsRequest }) => Promise<DeleteRecords200Response>;
637
- runQuery: (params: { body: RunQueryRequest }) => Promise<RunQueryResponse>;
638
- getTempTokenDBID: (params: { dbid: string }) => Promise<GetTempTokenDBID200Response>;
639
- exchangeSsoToken: (params: { generated?: any }) => Promise<{ [key: string]: any }>;
640
- cloneUserToken: (params: { generated?: any }) => Promise<{ [key: string]: any }>;
641
- transferUserToken: (params: { generated?: any }) => Promise<{ [key: string]: any }>;
642
- deactivateUserToken: (params: { }) => Promise<{ [key: string]: any }>;
643
- deleteUserToken: (params: { }) => Promise<{ [key: string]: any }>;
644
- downloadFile: (params: { tableId: string; recordId: number; fieldId: number; versionNumber: number }) => Promise<any>;
645
- deleteFile: (params: { tableId: string; recordId: number; fieldId: number; versionNumber: number }) => Promise<{ [key: string]: any }>;
646
- getUsers: (params: { accountId?: any; generated?: { [key: string]: any } }) => Promise<{ [key: string]: any }>;
647
- denyUsers: (params: { accountId?: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
648
- denyUsersAndGroups: (params: { accountId?: any; shouldDeleteFromGroups: boolean; generated?: string[] }) => Promise<{ [key: string]: any }>;
649
- undenyUsers: (params: { accountId?: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
650
- addMembersToGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
651
- removeMembersFromGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
652
- addManagersToGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
653
- removeManagersFromGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
654
- addSubgroupsToGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
655
- removeSubgroupsFromGroup: (params: { gid: any; generated?: string[] }) => Promise<{ [key: string]: any }>;
656
- audit: (params: { generated?: any }) => Promise<{ [key: string]: any }>;
657
- platformAnalyticReads: (params: { day?: string }) => Promise<{ [key: string]: any }>;
658
- platformAnalyticEventSummaries: (params: { accountId?: any; generated?: any }) => Promise<any>;
659
- exportSolution: (params: { solutionId: string; qBLVersion?: string }) => Promise<any>;
660
- updateSolution: (params: { solutionId: string; generated?: any; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
661
- createSolution: (params: { generated?: any; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
662
- exportSolutionToRecord: (params: { solutionId: string; tableId: string; fieldId: number; xQBLErrorsAsSuccess?: boolean; qBLVersion?: string }) => Promise<any>;
663
- createSolutionFromRecord: (params: { tableId: string; fieldId: number; recordId: number; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
664
- updateSolutionToRecord: (params: { solutionId: string; tableId: string; fieldId: number; recordId: number; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
665
- changesetSolution: (params: { solutionId: string; generated?: any; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
666
- changesetSolutionFromRecord: (params: { solutionId: string; tableId: string; fieldId: number; recordId: number; xQBLErrorsAsSuccess?: boolean }) => Promise<any>;
667
- generateDocument: (params: { templateId: any; tableId: string; recordId?: any; filename: string; accept?: string; format?: string; margin?: string; unit?: string; pageSize?: string; orientation?: string; realm?: string }) => Promise<{ [key: string]: any }>;
668
- }
669
- - name: index.ts
670
- type: file
671
- - name: quickbaseClient.ts
672
- type: file
673
- contents: |
674
- // src/quickbaseClient.ts
675
- import { QuickbaseClient as IQuickbaseClient } from "./generated-unified/QuickbaseClient.ts";
676
- import {
677
- Configuration,
678
- HTTPHeaders,
679
- ResponseError,
680
- } from "./generated/runtime.ts";
681
- import * as apis from "./generated/apis/index.ts";
682
- import { TokenCache } from "./tokenCache.ts";
683
-
684
- // Re-export all model types from generated/models
685
- export * from "./generated/models";
686
-
687
- const simplifyName = (name: string): string =>
688
- name
689
- .replace(/ById$/, "")
690
- .replace(/Api$/, "")
691
- .replace(/^(\w)/, (_, c) => c.toLowerCase());
692
-
693
- export interface QuickbaseClient extends IQuickbaseClient {}
694
-
695
- export interface QuickbaseConfig {
696
- realm: string;
697
- userToken?: string;
698
- tempToken?: string;
699
- useTempTokens?: boolean;
700
- debug?: boolean;
701
- fetchApi?: typeof fetch;
702
- }
703
-
704
- export interface TempTokenParams {
705
- appId?: string;
706
- tableId?: string;
707
- dbid?: string;
708
- }
709
-
710
- type ApiMethod<K extends keyof QuickbaseClient> = (
711
- requestParameters: Parameters<QuickbaseClient[K]>[0],
712
- initOverrides?: RequestInit
713
- ) => Promise<ReturnType<QuickbaseClient[K]>>;
714
-
715
- interface MethodInfo<K extends keyof QuickbaseClient> {
716
- api: any;
717
- method: ApiMethod<K>;
718
- paramMap: string[];
719
- }
720
-
721
- type MethodMap = { [K in keyof QuickbaseClient]: MethodInfo<K> };
722
-
723
- const getParamNames = (fn: (...args: any[]) => any): string[] =>
724
- fn
725
- .toString()
726
- .slice(fn.toString().indexOf("(") + 1, fn.toString().indexOf(")"))
727
- .split(",")
728
- .map((p) => p.trim().split("=")[0].trim())
729
- .filter((p) => p && !p.match(/^\{/) && p !== "options");
730
-
731
- const extractDbid = (
732
- params: Partial<TempTokenParams>,
733
- errorMessage: string
734
- ): string => {
735
- const dbid = params.dbid || params.tableId || params.appId;
736
- if (!dbid) {
737
- throw new Error(errorMessage);
738
- }
739
- return dbid;
740
- };
741
-
742
- export function quickbase(config: QuickbaseConfig): QuickbaseClient {
743
- const {
744
- realm,
745
- userToken,
746
- tempToken: initialTempToken,
747
- useTempTokens,
748
- fetchApi,
749
- debug,
750
- } = config;
751
- const baseUrl = `https://api.quickbase.com/v1`;
752
-
753
- const tokenCache = new TokenCache();
754
-
755
- const baseHeaders: HTTPHeaders = {
756
- "QB-Realm-Hostname": `${realm}.quickbase.com`,
757
- "Content-Type": "application/json",
758
- };
759
-
760
- if (initialTempToken) {
761
- baseHeaders["Authorization"] = `QB-TEMP-TOKEN ${initialTempToken}`;
762
- } else if (userToken && !useTempTokens) {
763
- baseHeaders["Authorization"] = `QB-USER-TOKEN ${userToken}`;
764
- }
765
-
766
- const defaultFetch: typeof fetch | undefined =
767
- typeof globalThis.window !== "undefined"
768
- ? globalThis.window.fetch.bind(globalThis.window)
769
- : undefined;
770
- const configuration = new Configuration({
771
- basePath: baseUrl,
772
- headers: { ...baseHeaders },
773
- fetchApi: fetchApi || defaultFetch,
774
- credentials: useTempTokens ? "include" : "omit",
775
- });
776
-
777
- if (!configuration.fetchApi && typeof globalThis.window === "undefined") {
778
- throw new Error(
779
- "fetchApi must be provided in non-browser environments (e.g., Node.js)"
780
- );
781
- }
782
-
783
- const apiInstances = Object.fromEntries(
784
- Object.entries(apis)
785
- .filter(([name]) => name.endsWith("Api"))
786
- .map(([name, ApiClass]) => [
787
- name.replace("Api", "").toLowerCase(),
788
- new ApiClass(configuration),
789
- ])
790
- );
791
-
792
- const methodMap = buildMethodMap();
793
-
794
- function buildMethodMap(): MethodMap {
795
- const methodMap: Partial<MethodMap> = {};
796
- const isValidMethod = (name: string) =>
797
- !name.startsWith("_") &&
798
- name !== "constructor" &&
799
- !["Middleware", "Pre", "Post", "Raw"].some((s) => name.includes(s));
800
-
801
- for (const [apiName, api] of Object.entries(apiInstances)) {
802
- Object.getOwnPropertyNames(Object.getPrototypeOf(api))
803
- .filter(
804
- (name) =>
805
- isValidMethod(name) &&
806
- typeof api[name as keyof typeof api] === "function"
807
- )
808
- .forEach((rawMethodName) => {
809
- const simplifiedName = simplifyName(
810
- rawMethodName
811
- ) as keyof QuickbaseClient;
812
- const method = api[rawMethodName as keyof typeof api];
813
- const boundMethod = method.bind(api as any) as unknown;
814
- if (typeof boundMethod === "function" && boundMethod.length <= 2) {
815
- methodMap[simplifiedName] = {
816
- api,
817
- method: boundMethod as ApiMethod<typeof simplifiedName>,
818
- paramMap: getParamNames(method),
819
- };
820
- }
821
- });
822
- }
823
- return methodMap as MethodMap;
824
- }
825
-
826
- const fetchTempToken = async (dbid: string): Promise<string> => {
827
- const effectiveFetch = fetchApi || defaultFetch;
828
- if (!effectiveFetch) {
829
- throw new Error(
830
- "No fetch implementation available for fetching temp token"
831
- );
832
- }
833
-
834
- const response = await effectiveFetch(
835
- `https://api.quickbase.com/v1/auth/temporary/${dbid}`,
836
- {
837
- method: "GET",
838
- headers: { ...baseHeaders },
839
- credentials: "include",
840
- }
841
- );
842
-
843
- if (!response.ok) {
844
- const errorBody: { message?: string } = await response.json();
845
- throw new Error(
846
- `API Error: ${errorBody.message || "Unknown error"} (Status: ${
847
- response.status
848
- })`
849
- );
850
- }
851
-
852
- const tokenResult = await response.json();
853
- const token = tokenResult.temporaryAuthorization;
854
- if (!token) {
855
- throw new Error("No temporary token returned from API");
856
- }
857
- tokenCache.set(dbid, token);
858
- if (debug) {
859
- console.log(
860
- `Fetched and cached new token for dbid: ${dbid}`,
861
- token,
862
- `Expires at: ${new Date(
863
- Date.now() + (4 * 60 + 50) * 1000
864
- ).toISOString()}`
865
- );
866
- }
867
- return token;
868
- };
869
-
870
- async function invokeMethod<K extends keyof QuickbaseClient>(
871
- methodName: K,
872
- params: Parameters<QuickbaseClient[K]>[0] & Partial<TempTokenParams>,
873
- retryCount: number = 0
874
- ): Promise<ReturnType<QuickbaseClient[K]>> {
875
- const methodInfo = methodMap[methodName];
876
- if (!methodInfo) {
877
- throw new Error(`Method ${methodName} not found`);
878
- }
879
-
880
- const requestParameters =
881
- methodInfo.paramMap.length === 1 &&
882
- methodInfo.paramMap[0] === "requestParameters"
883
- ? { requestParameters: params }
884
- : params;
885
- let requestOptions: RequestInit = {};
886
-
887
- const selectedToken =
888
- initialTempToken || (userToken && !useTempTokens ? userToken : undefined);
889
-
890
- if (methodName === "getTempTokenDBID" && useTempTokens) {
891
- const dbid = extractDbid(params, "No dbid provided for getTempTokenDBID");
892
- const cachedToken = tokenCache.get(dbid);
893
- if (cachedToken) {
894
- return { temporaryAuthorization: cachedToken } as ReturnType<
895
- QuickbaseClient[K]
896
- >;
897
- }
898
- }
899
-
900
- let authorizationToken = selectedToken;
901
- if (useTempTokens && !authorizationToken) {
902
- const dbid = extractDbid(
903
- params,
904
- `No dbid found in params for ${methodName} to fetch temp token`
905
- );
906
- const cachedToken = tokenCache.get(dbid);
907
- authorizationToken = cachedToken || (await fetchTempToken(dbid));
908
- if (methodName === "getTempTokenDBID") {
909
- return { temporaryAuthorization: authorizationToken } as ReturnType<
910
- QuickbaseClient[K]
911
- >;
912
- }
913
- requestOptions.headers = {
914
- ...baseHeaders,
915
- Authorization: `QB-TEMP-TOKEN ${authorizationToken}`,
916
- };
917
- } else if (authorizationToken) {
918
- requestOptions.headers = {
919
- ...baseHeaders,
920
- Authorization: `QB-USER-TOKEN ${authorizationToken}`,
921
- };
922
- }
923
-
924
- try {
925
- return await methodInfo.method(requestParameters, requestOptions);
926
- } catch (error) {
927
- if (
928
- error instanceof ResponseError &&
929
- error.response.status === 401 &&
930
- retryCount < 1 &&
931
- useTempTokens
932
- ) {
933
- if (debug) {
934
- console.log(
935
- `Authorization error for ${methodName}, refreshing token:`,
936
- error.message
937
- );
938
- }
939
- const dbid = extractDbid(
940
- params,
941
- `No dbid to refresh token after authorization error`
942
- );
943
- authorizationToken = await fetchTempToken(dbid);
944
- requestOptions.headers = {
945
- ...baseHeaders,
946
- Authorization: `QB-TEMP-TOKEN ${authorizationToken}`,
947
- };
948
- if (debug) {
949
- console.log(`Retrying ${methodName} with new token`);
950
- }
951
- return invokeMethod(methodName, params, retryCount + 1);
952
- }
953
- if (error instanceof ResponseError) {
954
- let errorMessage = error.message;
955
- try {
956
- const errorBody: { message?: string } = await error.response.json();
957
- if (debug) {
958
- console.log(`Error response body for ${methodName}:`, errorBody);
959
- }
960
- errorMessage = errorBody.message || errorMessage;
961
- } catch (e) {
962
- // Silent fail on parse error
963
- }
964
- throw new Error(
965
- `API Error: ${errorMessage} (Status: ${error.response.status})`
966
- );
967
- }
968
- throw error;
969
- }
970
- }
971
-
972
- const proxy = new Proxy<QuickbaseClient>({} as QuickbaseClient, {
973
- get: (_, prop: string): ((params: any) => Promise<any>) | undefined => {
974
- if (prop in methodMap) {
975
- const methodName = prop as keyof QuickbaseClient;
976
- return (params: Parameters<QuickbaseClient[typeof methodName]>[0]) =>
977
- invokeMethod(methodName, params);
978
- }
979
- return undefined;
980
- },
981
- });
982
-
983
- return proxy;
984
- }
985
- - name: tokenCache.ts
986
- type: file
987
- contents: |
988
- interface CachedToken {
989
- token: string;
990
- expiresAt: number; // Timestamp in milliseconds
991
- }
992
-
993
- export class TokenCache {
994
- private cache: Map<string, CachedToken>;
995
- private readonly lifespan: number; // Token lifespan in milliseconds
996
-
997
- constructor(lifespan: number = 4 * 60 * 1000 + 50 * 1000) {
998
- // Default 4:50
999
- this.cache = new Map<string, CachedToken>();
1000
- this.lifespan = lifespan;
1001
- }
1002
-
1003
- get(dbid: string): string | undefined {
1004
- const entry = this.cache.get(dbid);
1005
- const now = Date.now();
1006
- if (entry && entry.expiresAt > now) {
1007
- return entry.token;
1008
- }
1009
- return undefined; // Expired or not found
1010
- }
1011
-
1012
- // New method to get full entry
1013
- getEntry(dbid: string): CachedToken | undefined {
1014
- const entry = this.cache.get(dbid);
1015
- const now = Date.now();
1016
- if (entry && entry.expiresAt > now) {
1017
- return entry;
1018
- }
1019
- return undefined; // Expired or not found
1020
- }
1021
-
1022
- set(dbid: string, token: string): void {
1023
- const now = Date.now();
1024
- this.cache.set(dbid, {
1025
- token,
1026
- expiresAt: now + this.lifespan,
1027
- });
1028
- }
1029
-
1030
- dump(): [string, CachedToken][] {
1031
- return Array.from(this.cache.entries());
1032
- }
1033
-
1034
- // New method to clear the cache
1035
- clear(): void {
1036
- this.cache.clear();
1037
- }
1038
- }
1039
- - name: test-artifacts
1040
- type: directory
1041
- children:
1042
- - name: .last-run.json
1043
- type: file
1044
- - name: test-esm.js
1045
- type: file
1046
- - name: test-results.json
1047
- type: file
1048
- - name: test-umd.js
1049
- type: file
1050
- - name: test.ts
1051
- type: file
1052
- - name: tests
1053
- type: directory
1054
- children:
1055
- - name: playwright
1056
- type: directory
1057
- children:
1058
- - name: qb
1059
- type: directory
1060
- children:
1061
- - name: auth
1062
- type: directory
1063
- children:
1064
- - name: cacheSwitching.test.ts
1065
- type: file
1066
- - name: fetchTempToken401.test.ts
1067
- type: file
1068
- - name: getAppWithUserToken.test.ts
1069
- type: file
1070
- - name: getTempToken.test.ts
1071
- type: file
1072
- - name: tokenPrefetch.test.ts
1073
- type: file
1074
- - name: tokenRenewal.test.ts
1075
- type: file
1076
- - name: umd.test.ts
1077
- type: file
1078
- - name: setup.ts
1079
- type: file
1080
- - name: vitest
1081
- type: directory
1082
- children:
1083
- - name: qb
1084
- type: directory
1085
- children:
1086
- - name: apps
1087
- type: directory
1088
- children:
1089
- - name: copyApp.test.ts
1090
- type: file
1091
- - name: createApp.test.ts
1092
- type: file
1093
- - name: deleteApp.test.ts
1094
- type: file
1095
- - name: getApp.test.ts
1096
- type: file
1097
- - name: fields
1098
- type: directory
1099
- children:
1100
- - name: createField.test.ts
1101
- type: file
1102
- - name: deleteFields.test.ts
1103
- type: file
1104
- - name: getField.test.ts
1105
- type: file
1106
- - name: getFieldUsage.test.ts
1107
- type: file
1108
- - name: getFields.test.ts
1109
- type: file
1110
- - name: getFieldsUsage.test.ts
1111
- type: file
1112
- - name: index.ts
1113
- type: file
1114
- - name: records
1115
- type: directory
1116
- children:
1117
- - name: deleteRecords.test.ts
1118
- type: file
1119
- - name: runQuery.test.ts
1120
- type: file
1121
- - name: upsert.test.ts
1122
- type: file
1123
- - name: tables
1124
- type: directory
1125
- children:
1126
- - name: createTable.test.ts
1127
- type: file
1128
- - name: deleteTable.test.ts
1129
- type: file
1130
- - name: getAppTables.test.ts
1131
- type: file
1132
- - name: getRelationships.test.ts
1133
- type: file
1134
- - name: getTable.test.ts
1135
- type: file
1136
- - name: updateTable.test.ts
1137
- type: file
1138
- - name: unit
1139
- type: directory
1140
- children:
1141
- - name: apps
1142
- type: directory
1143
- children:
1144
- - name: copyApp.test.ts
1145
- type: file
1146
- - name: createApp.test.ts
1147
- type: file
1148
- - name: deleteApp.test.ts
1149
- type: file
1150
- - name: getApp.test.ts
1151
- type: file
1152
- - name: auth
1153
- type: directory
1154
- children:
1155
- - name: fetchTempToken401.test.ts
1156
- type: file
1157
- - name: getTempToken.test.ts
1158
- type: file
1159
- - name: retryOn401.test.ts
1160
- type: file
1161
- - name: two401s.test.ts
1162
- type: file
1163
- - name: fields
1164
- type: directory
1165
- children:
1166
- - name: createField.test.ts
1167
- type: file
1168
- - name: deleteFields.test.ts
1169
- type: file
1170
- - name: getField.test.ts
1171
- type: file
1172
- - name: getFieldUsage.test.ts
1173
- type: file
1174
- - name: getFields.test.ts
1175
- type: file
1176
- - name: getFieldsUsage.test.ts
1177
- type: file
1178
- - name: index.ts
1179
- type: file
1180
- - name: records
1181
- type: directory
1182
- children:
1183
- - name: deleteRecords.test.ts
1184
- type: file
1185
- - name: runQuery.test.ts
1186
- type: file
1187
- - name: upsert.test.ts
1188
- type: file
1189
- - name: tables
1190
- type: directory
1191
- children:
1192
- - name: createTable.test.ts
1193
- type: file
1194
- - name: deleteTable.test.ts
1195
- type: file
1196
- - name: getAppTables.test.ts
1197
- type: file
1198
- - name: getRelationships.test.ts
1199
- type: file
1200
- - name: getTable.test.ts
1201
- type: file
1202
- - name: updateTable.test.ts
1203
- type: file
1204
- - name: umd.test.ts
1205
- type: file
1206
- - name: text.txt
1207
- type: file
1208
- - name: tools
1209
- type: directory
1210
- children:
1211
- - name: log-gen.ts
1212
- type: file
1213
- - name: openapi-jars
1214
- type: directory
1215
- children:
1216
- - name: openapi-generator-cli-7.12.0.jar
1217
- type: file
1218
- - name: tsconfig.build.json
1219
- type: file
1220
- contents: |-
1221
- {
1222
- "extends": "./tsconfig.json",
1223
- "compilerOptions": {
1224
- "outDir": "dist/temp",
1225
- "noEmit": false,
1226
- "allowImportingTsExtensions": false,
1227
- "declaration": false,
1228
- "sourceMap": true
1229
- },
1230
- "include": ["dist/temp-src/**/*"],
1231
- "exclude": [
1232
- "node_modules",
1233
- "dist",
1234
- "tests/**/*",
1235
- "src/**/*" // Exclude original src/ to avoid confusion
1236
- ]
1237
- }
1238
- - name: tsconfig.json
1239
- type: file
1240
- contents: |-
1241
- {
1242
- "compilerOptions": {
1243
- "target": "ESNext",
1244
- "module": "ESNext",
1245
- "moduleResolution": "bundler",
1246
- "strict": true,
1247
- "lib": ["ES2015", "ESNext", "DOM"],
1248
- "types": ["node", "playwright/test", "undici-types"],
1249
- "esModuleInterop": true,
1250
- "resolveJsonModule": true,
1251
- "allowImportingTsExtensions": true,
1252
- "noEmit": true,
1253
- "outDir": "dist",
1254
- "rootDir": ".",
1255
- "declaration": true,
1256
- "sourceMap": true,
1257
- "baseUrl": ".",
1258
- "paths": {
1259
- "@/*": ["src/*"],
1260
- "@tests/*": ["tests/*"]
1261
- }
1262
- },
1263
- "include": ["src/**/*", "tests/**/*", "open-api/**/*", "tools/**/*"],
1264
- "exclude": ["node_modules", "dist", "specs"],
1265
- "ts-node": {
1266
- "esm": true,
1267
- "transpileOnly": true
1268
- }
1269
- }
1270
- - name: versionrc.json
1271
- type: file
1272
- - name: vitest.config.ts
1273
- type: file
1274
- contents: |
1275
- // vitest.config.ts
1276
- import { defineConfig } from "vitest/config";
1277
- import path from "path";
1278
- import dotenv from "dotenv"; // Add this import
1279
-
1280
- // Load .env variables before tests run
1281
- dotenv.config({ path: path.resolve(__dirname, ".env") });
1282
-
1283
- export default defineConfig({
1284
- test: {
1285
- environment: "jsdom",
1286
- include: ["tests/vitest/**/**/*.test.ts"],
1287
- setupFiles: ["tests/setup.ts"], // Relative path from root
1288
- pool: "forks",
1289
- poolOptions: {
1290
- forks: {
1291
- singleFork: true, // Run tests sequentially
1292
- },
1293
- },
1294
- },
1295
- resolve: {
1296
- alias: {
1297
- "@": path.resolve(__dirname, "./src"), // For src/ imports
1298
- "@tests": path.resolve(__dirname, "./tests"), // For tests/ imports
1299
- },
1300
- },
1301
- });