quickbase-js 0.1.0-beta.8 → 0.1.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +46 -130
  3. package/dist/esm/quickbase.d.ts +822 -119
  4. package/dist/esm/quickbase.js +373 -236
  5. package/dist/esm/quickbase.js.map +1 -1
  6. package/dist/esm/quickbase.min.js +1 -1
  7. package/dist/esm/quickbase.min.js.map +1 -1
  8. package/dist/umd/quickbase.umd.js +373 -236
  9. package/dist/umd/quickbase.umd.js.map +1 -1
  10. package/dist/umd/quickbase.umd.min.js +1 -1
  11. package/dist/umd/quickbase.umd.min.js.map +1 -1
  12. package/open-api/generate-unified-interface.ts +97 -17
  13. package/open-api/utils/generateJsDoc.ts +96 -0
  14. package/package.json +3 -1
  15. package/src/ThrottleBucket.ts +17 -12
  16. package/src/authorizationStrategy.ts +246 -0
  17. package/src/generated-unified/QuickbaseClient.ts +809 -119
  18. package/src/invokeMethod.ts +150 -265
  19. package/src/quickbaseClient.ts +85 -58
  20. package/src/rateLimiter.ts +25 -0
  21. package/src/tokenCache.ts +10 -26
  22. package/tests/vitest/qb/auth/mockQuickbaseServer.ts +60 -0
  23. package/tests/vitest/qb/auth/retryUserToken401.test.ts +59 -42
  24. package/tests/vitest/qb/auth/ssoTokenIntegrationWithServer.test.ts +65 -0
  25. package/tests/vitest/qb/fields/getFieldUsage.test.ts +58 -150
  26. package/tests/vitest/qb/formulas/runFormula.test.ts +96 -0
  27. package/tests/vitest/qb/tables/createRelationship.test.ts +102 -0
  28. package/tests/vitest/qb/tables/deleteRelationship.test.ts +143 -0
  29. package/tests/vitest/qb/tables/updateRelationship.test.ts +118 -145
  30. package/tests/vitest/unit/ThrottleBucket.test.ts +95 -0
  31. package/tests/vitest/unit/apps/copyApp.test.ts +133 -40
  32. package/tests/vitest/unit/apps/updateApp.test.ts +42 -11
  33. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +3 -2
  34. package/tests/vitest/unit/auth/getTempToken.test.ts +42 -18
  35. package/tests/vitest/unit/auth/retryTempToken401.test.ts +46 -64
  36. package/tests/vitest/unit/auth/retryTempTokenMaxRetries.test.ts +235 -0
  37. package/tests/vitest/unit/auth/retryUserToken401.test.ts +56 -43
  38. package/tests/vitest/unit/auth/ssoTokenRefresh.test.ts +325 -0
  39. package/tests/vitest/unit/fields/createField.test.ts +180 -116
  40. package/tests/vitest/unit/fields/getFieldUsage.test.ts +17 -3
  41. package/tests/vitest/unit/fields/updateField.test.ts +12 -7
  42. package/tests/vitest/unit/formulas/runFormula.test.ts +205 -0
  43. package/tests/vitest/unit/index.ts +2 -1
  44. package/tests/vitest/unit/inferHttpMethod.test.ts +131 -0
  45. package/tests/vitest/unit/rateLimit.test.ts +4 -2
  46. package/tests/vitest/unit/tables/createRelationship.test.ts +212 -0
  47. package/tests/vitest/unit/tables/deleteRelationship.test.ts +97 -0
  48. package/tests/vitest/unit/tables/updateRelationship.test.ts +12 -10
  49. package/tests/vitest/unit/tokenLifespan.test.ts +149 -83
  50. package/tools/log-gen.ts +14 -5
  51. package/tools/log-gen.yaml +710 -268
  52. package/tests/vitest/unit/auth/retryTempTokenTwo401.test.ts +0 -81
package/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [0.1.0-beta.9](https://github.com/DrewBradfordXYZ/quickbase-js/compare/v0.1.0-beta.8...v0.1.0-beta.9) (2025-03-20)
6
+
7
+
8
+ ### Features
9
+
10
+ * 429 and throttlebucket tests pass ([5591e19](https://github.com/DrewBradfordXYZ/quickbase-js/commit/5591e19357c3c3232337ec4ede020530a635aa76))
11
+ * add baseUrl with a default ([5c5829f](https://github.com/DrewBradfordXYZ/quickbase-js/commit/5c5829fcbe32e780efebea903db11a505bb9166c))
12
+ * add SSO strategy ([501034d](https://github.com/DrewBradfordXYZ/quickbase-js/commit/501034d363ffd7b4d5acdd9cf2932b5d97f249ee))
13
+ * all relationship tests are passing ([5cdd0e9](https://github.com/DrewBradfordXYZ/quickbase-js/commit/5cdd0e9aafe5d22e354f3915e45b3950eec98cdf))
14
+ * auth refactor, auth tests pass, other tests still have errors ([47f353f](https://github.com/DrewBradfordXYZ/quickbase-js/commit/47f353f0fdb38813b9c047ec06059c9ff6354225))
15
+ * createField unit test passes ([676b6ab](https://github.com/DrewBradfordXYZ/quickbase-js/commit/676b6ab98379300b2d16e01c58b180bf1277ed86))
16
+ * createRelationship unit and integration tests pass ([577e7bb](https://github.com/DrewBradfordXYZ/quickbase-js/commit/577e7bbce7f7fa3d6ffbe1f9f2b7cb00e1a5e486))
17
+ * inferHttpMethod test and updateRelationship test pass ([1c6b342](https://github.com/DrewBradfordXYZ/quickbase-js/commit/1c6b34203a2100f17e9f626f547d426252922c67))
18
+ * jsdoc documents type properties ([191d721](https://github.com/DrewBradfordXYZ/quickbase-js/commit/191d7211c5c1cecd55b2019237c132225cf2d461))
19
+ * retryTempTokenMaxRetires unit test pass and update copyApp unit test is now more self contained ([8f38b1b](https://github.com/DrewBradfordXYZ/quickbase-js/commit/8f38b1b81a525702c6a49db07c1ef5b70a686792))
20
+ * retryUserToken401 integration test passes ([d78b0c6](https://github.com/DrewBradfordXYZ/quickbase-js/commit/d78b0c62cea3c1a35b9beca3db30d9fa1596c4e7))
21
+ * runFormula integration test passes ([4e5927d](https://github.com/DrewBradfordXYZ/quickbase-js/commit/4e5927d51d10d44534430c58321580bc363a9496))
22
+ * runFormula unit test passes ([871d6e9](https://github.com/DrewBradfordXYZ/quickbase-js/commit/871d6e97c4aa93bc8a206337f20b8ba325e16a64))
23
+ * runFormula.test.ts unit test pass ([8fe27d8](https://github.com/DrewBradfordXYZ/quickbase-js/commit/8fe27d8401ac53f4da8e7a52ea4c8645c5a46508))
24
+ * sso integration test passes ([c09a02c](https://github.com/DrewBradfordXYZ/quickbase-js/commit/c09a02cd379efd935dd0c256d8cf6fb4a7402a7e))
25
+ * sso unit test passes ([5e5baeb](https://github.com/DrewBradfordXYZ/quickbase-js/commit/5e5baeb3fb0a00e7301183346ef49b6aee483a6a))
26
+ * tokenLifespan unit test passes ([09a72a9](https://github.com/DrewBradfordXYZ/quickbase-js/commit/09a72a965a99bb6bd712cb705354c1904c72aebb))
27
+ * updateField unit test passes ([9a2aae1](https://github.com/DrewBradfordXYZ/quickbase-js/commit/9a2aae1338c53eb92a82a6bff212c275705d027e))
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * updateRelationship integration test cleanup ([d27c030](https://github.com/DrewBradfordXYZ/quickbase-js/commit/d27c0303ec55162bea8d479064c5a93584cdef37))
33
+
5
34
  ## [0.1.0-beta.8](https://github.com/DrewBradfordXYZ/quickbase-js/compare/v0.1.0-beta.7...v0.1.0-beta.8) (2025-03-18)
6
35
 
7
36
 
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # quickbase-js
2
2
 
3
+ This is a Typescript library using the QuickBase OpenAPI spec and the typescipt-fetch generator. This library is designed for both browser and Node.js environments. Code pages have first class support.
4
+
5
+ Authentication methods: `Temporary Tokens`, `User Tokens`, `SSO`.
6
+
3
7
  # Installation
4
8
 
5
9
  ```bash
@@ -51,154 +55,66 @@ npm install --save quickbase-js
51
55
  </html>
52
56
  ```
53
57
 
54
- # Development workflow
55
-
56
- ```bash
57
- npm run gen:all
58
- npm run build
59
- npm run test:all
60
- ```
61
-
62
- ## Usage
63
-
64
- ### Node.js (ESM - Recommended)
65
-
66
- For modern Node.js applications, use ES modules:
67
-
68
- ```javascript
69
- // ESM (Node.js) - Recommended
70
- import { quickbase } from "quickbase-js";
71
- const qb = quickbase({ realm: "example", userToken: "your-token" });
72
-
73
- // Example: Fetching an app
74
- const app = await qb.getApp({ appId: "your-app-id" });
75
- console.log(app);
76
-
77
- // Example: Creating a record with temporary token
78
- const qbTemp = quickbase({ realm: "example", useTempTokens: true });
79
- const record = await qbTemp.upsert({
80
- body: {
81
- to: "your-table-id",
82
- data: [
83
- {
84
- /* record data */
85
- },
86
- ],
87
- },
88
- });
89
- console.log(record);
90
- ```
91
-
92
- ```javascript
93
- // Example: TypeScript ESM (Recommended)
94
- import { quickbase } from "quickbase-js";
95
- const qbTyped: QuickbaseClient = quickbase({
96
- realm: "example",
97
- userToken: "your-token",
98
- });
99
- const typedApp = await qbTyped.getApp({ appId: "your-app-id" });
100
- console.log(typedApp);
101
- ```
102
-
103
- ```javascript
104
- // Example: UMD via CDN (QuickBase Code Pages)
105
- // Note: This is HTML, not JavaScript, and should be used in a browser environment
106
-
107
- <script src="https://cdn.jsdelivr.net/npm/quickbase-js@1.1.0-beta.4/dist/umd/quickbase.umd.js"></script>
108
- <script>
109
- const qb = new QuickbaseJS({ realm: 'example', useTempTokens: true });
110
- // Example: Fetching an app
111
- qb.getApp({ appId: 'your-app-id' }).then(app => console.log(app));
112
- </script>
113
-
114
- ```
115
-
116
- ## In QuickBase Code Pages (Browser Environment)
117
-
118
- ### useTempTokens: true:
119
-
120
- Token Fetch: Auto-fetches temporary tokens using the provided fetchApi (or window.fetch by default) with cookies (withCredentials: true in the internal tokenClient).
121
-
122
- Subsequent Calls (e.g., getApp): Uses the same fetchApi (or window.fetch) with the QB-TEMP-TOKEN {TOKEN} header. No additional config needed beyond realm and useTempTokens.
123
-
124
- How It Works: Leverages the browser’s session cookies for the initial token fetch, then uses the token for all API calls. In a real code page, window.fetch handles both steps seamlessly.
58
+ ## Configuration
125
59
 
126
- Test Output: The test uses page.evaluate for token fetch and node-fetch for getApp to bypass Playwright’s browser fetch issue, but in a code page, it’s all window.fetch.
60
+ The `quickbase` function accepts a `QuickbaseConfig` object with the following options:
127
61
 
128
- ### userToken:
62
+ - **`realm`** (`string`): Your QuickBase realm (e.g., "company"). This is required and has no default value.
63
+ - **`userToken`** (`string`, optional): A QuickBase user token for authentication. No default is provided.
64
+ - **`useTempTokens`** (`boolean`, optional): Enables temporary token authentication. Defaults to `false`.
65
+ - **`useSso`** (`boolean`, optional): Enables SSO authentication. Defaults to `false`.
66
+ - **`samlToken`** (`string`, optional): A SAML token for SSO authentication. No default is provided.
129
67
 
130
- All Calls: Uses the provided fetchApi (or window.fetch by default) with the QB-USER-TOKEN {TOKEN} header. No session cookies needed (credentials: "omit").
68
+ ---
131
69
 
132
- How It Works: The user token authenticates directly, independent of the browser session, making it straightforward and reliable.
70
+ _Optional advanced options:_
133
71
 
134
- Test Output: Confirms this with page.evaluate sending QB-USER-TOKEN.
72
+ - **`tempTokenLifespan`** (`number`, optional): The lifespan (in milliseconds) of temporary tokens in the cache. Defaults to `290000` (290 seconds).
73
+ - **`throttle`** (`{ rate: number; burst: number }`, optional): Configures rate limiting, where `rate` is requests per second and `burst` is the maximum burst of requests. Defaults to `{ rate: 10, burst: 10 }`.
74
+ - **`maxRetries`** (`number`, optional): The maximum number of retries for failed requests. Defaults to `3`.
75
+ - **`retryDelay`** (`number`, optional): The base delay (in milliseconds) between retries, which increases exponentially. Defaults to `1000`.
76
+ - **`convertDates`** (`boolean`, optional): Converts ISO date strings to `Date` objects in responses. Defaults to `true`.
77
+ - **`baseUrl`** (`string`, optional): The base URL for the QuickBase API. Defaults to `"https://api.quickbase.com/v1"`.
78
+ - **`tempToken`** (`string`, optional): A temporary token for authentication. No default is provided.
79
+ - **`tokenCache`** (`TokenCache`, optional): A custom token cache instance. Defaults to a new `TokenCache` instance created with `tempTokenLifespan`.
80
+ - **`fetchApi`** (`typeof fetch`, optional): A custom fetch implementation (e.g., for Node.js). Defaults to the browser’s `fetch` if available, or the provided implementation.
81
+ - **`debug`** (`boolean`, optional): Enables debug logging to the console. Defaults to `false`.
135
82
 
136
- ## In Node.js (Non-Browser Environment)
83
+ ### Configuration Notes
137
84
 
138
- ### userToken:
85
+ - **Authentication**: Use `userToken` for standard auth, `tempToken` with `useTempTokens` for temporary tokens, or `samlToken` with `useSso` for SSO. Only one auth method is active at a time.
86
+ - **`throttle`**: Controls API request pacing to avoid hitting rate limits. For example, `{ rate: 5, burst: 20 }` allows 5 requests per second with a burst capacity of 20.
87
+ - **`tokenCache`**: If not provided, a new cache is initialized automatically, storing temporary tokens for the specified `tempTokenLifespan`.
88
+ - **`fetchApi`**: In Node.js, you must provide a fetch implementation (e.g., `node-fetch`), as there’s no built-in `fetch` like in browsers.
139
89
 
140
- All Calls: Works with a provided fetchApi (e.g., fetchApi: node-fetch). Sets QB-USER-TOKEN {TOKEN} header.
90
+ ### Development workflow
141
91
 
142
- How It Works: Fully functional as long as fetchApi is supplied (e.g., node-fetch), since user tokens don’t require a browser session.
143
-
144
- Requirement: Must provide fetchApi explicitly (no default in Node.js).
145
-
146
- ### useTempTokens: true:
147
-
148
- Behavior: Fails with a clear error unless a browser-like fetchApi is provided:
149
-
150
- "Temporary tokens require a browser environment or a custom fetchApi with browser-like session support"
151
-
152
- How It Works: Temp tokens need a browser session with cookies, which Node.js can’t provide natively. A custom fetchApi (e.g., via Puppeteer) could work but is impractical for typical Node.js use.
153
-
154
- Practicality: Effectively unusable in Node.js without external browser support, aligning with QuickBase’s temp token requirement.
155
-
156
- ## getTempTokenDBID
157
-
158
- Temporary Token Handling with getTempTokenDBID
159
- The QuickBase API provides the getTempTokenDBID method to fetch temporary tokens (QB-TEMP-TOKEN) for browser-based authentication, typically using session credentials (e.g., cookies). These tokens are short-lived (~5 minutes) and intended for secure, client-side API calls. In the generated OpenAPI client, getTempTokenDBID makes a straightforward GET request to /v1/auth/temporary/{dbid} and returns { temporaryAuthorization: string }. However, this raw implementation lacks caching and doesn’t optimize repeated calls, which can lead to unnecessary API requests.
160
- In quickbaseClient.ts, we enhance getTempTokenDBID when useTempTokens: true is enabled, wrapping it with intelligent token management:
161
- Caching: We introduce a TokenCache to store temporary tokens by dbid. Before fetching a new token, the client checks the cache. If a valid token exists, it’s returned immediately, avoiding redundant API calls.
162
-
163
- Custom Fetch Logic: Instead of relying solely on the generated method, we use a custom fetchTempToken function to fetch tokens. This ensures consistency with browser-based session authentication (credentials: "include") and allows us to cache the result.
164
-
165
- Early Returns: For getTempTokenDBID, we bypass the generated method’s execution by returning the cached or freshly fetched token directly. This prevents unnecessary calls to the underlying API when the token is already available or just retrieved.
166
-
167
- Why This Matters
168
- Efficiency: Caching reduces API requests, crucial for performance in browser environments where temp tokens are fetched frequently but don’t change within their lifespan.
169
-
170
- Seamless Integration: The wrapper supports both QB-USER-TOKEN (server-side) and QB-TEMP-TOKEN (client-side) workflows, controlled by the useTempTokens config. This makes the client versatile for different use cases.
171
-
172
- Testability: The enhancement fixes issues in unit tests (e.g., getTempToken.test.ts) by ensuring predictable behavior—fetching once and reusing cached tokens—avoiding unexpected errors from redundant calls.
173
-
174
- How It Works
175
- When you call client.getTempTokenDBID({ dbid: "someDbid" }) with useTempTokens: true:
176
- Cache Check: Looks for an existing token in tokenCache for the given dbid.
177
-
178
- Fetch if Needed: If no cached token exists, fetchTempToken requests a new one from /v1/auth/temporary/{dbid} and caches it.
92
+ ```bash
93
+ npm run gen:all
94
+ npm run build
95
+ npm run test:all
96
+ ```
179
97
 
180
- Return Early: Returns { temporaryAuthorization: token } immediately, skipping the generated method’s execution.
98
+ ### Prerequisites
181
99
 
182
- For other methods (e.g., getFields), the fetched temp token is applied to the Authorization header, ensuring authenticated API calls without re-fetching.
100
+ Node.js >= 18
183
101
 
184
- ## 401 Unauthorized Error Behavior
102
+ npm >= 8
185
103
 
186
- The quickbase-js library manages 401 Unauthorized errors from the QuickBase API when using temporary tokens (useTempTokens: true). Normally, it keeps tokens fresh via a time-managed cache intending to never have a 401 Unauthorized error, but there is added safety measures incase a 401 happens to occur.
104
+ A Quickbase app with a table and a user token. A free builder account works with must API calls.
187
105
 
188
- If a 401 happens, the library tries once more with a fresh temporary token.
106
+ ### Contributing
189
107
 
190
- It gets the new token using fetchTempToken and retries the call.
108
+ 1. Fork the repository.
191
109
 
192
- If the retry fails with another 401, it stops and throws an error like API Error: Unauthorized (Status: 401).
110
+ 2. Create a feature branch (git checkout -b feature/your-feature).
193
111
 
194
- Fetching a New Token:
195
- If fetchTempToken itself gets a 401 (e.g., no valid login session), it doesn’t retry.
112
+ 3. Commit changes (git commit -m "Add your feature").
196
113
 
197
- It throws an error right away: API Error: Unauthorized (Status: 401).
114
+ 4. Push to your branch (git push origin feature/your-feature).
198
115
 
199
- Why It’s Like This
200
- One Retry: Retries once to fix expired tokens, but stops to avoid endless tries.
116
+ 5. Open a pull request.
201
117
 
202
- Fast Fail: No retry on fetchTempToken 401s means you know quickly if login is broken.
118
+ ### License
203
119
 
204
- No Loops: Built to never get stuck retrying forever.
120
+ MIT License - see LICENSE for details.