quickbase-js 1.1.0-beta.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +253 -135
  2. package/dist/esm/quickbase.d.ts +5614 -2861
  3. package/dist/esm/quickbase.js +3207 -2116
  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 +3536 -2325
  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 -93
  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/examples/vanillatest.html +0 -49
  18. package/log-gen.yaml +0 -1372
  19. package/open-api/definitions/apps.ts +0 -274
  20. package/open-api/definitions/auth.ts +0 -10
  21. package/open-api/definitions/fields.ts +0 -751
  22. package/open-api/definitions/index.ts +0 -18
  23. package/open-api/definitions/records.ts +0 -269
  24. package/open-api/definitions/relationships.ts +0 -90
  25. package/open-api/definitions/reports.ts +0 -10
  26. package/open-api/definitions/tables.ts +0 -112
  27. package/open-api/fix-spec-main.ts +0 -176
  28. package/open-api/generate-unified-interface.ts +0 -170
  29. package/open-api/output/quickbase-fixed.json +0 -6760
  30. package/open-api/paths/apps.ts +0 -100
  31. package/open-api/paths/auth.ts +0 -25
  32. package/open-api/paths/fields.ts +0 -207
  33. package/open-api/paths/index.ts +0 -17
  34. package/open-api/paths/records.ts +0 -68
  35. package/open-api/paths/relationships.ts +0 -32
  36. package/open-api/paths/reports.ts +0 -34
  37. package/open-api/paths/tables.ts +0 -162
  38. package/open-api/regenerate-client.ts +0 -110
  39. package/playwright-results.txt/.last-run.json +0 -4
  40. package/playwright.config.ts +0 -37
  41. package/rollup.config.mjs +0 -114
  42. package/specs/QuickBase_RESTful_API_2025-03-04T06_22_39.725Z.json +0 -46878
  43. package/src/generated-unified/QuickbaseClient.ts +0 -62
  44. package/src/index.ts +0 -1
  45. package/src/quickbaseClient.ts +0 -313
  46. package/src/tokenCache.ts +0 -51
  47. package/test-artifacts/.last-run.json +0 -6
  48. package/test-esm.js +0 -1
  49. package/test-results.json +0 -2050
  50. package/test-umd.js +0 -1
  51. package/test.ts +0 -1
  52. package/tests/playwright/qb/auth/cacheSwitching.test.ts +0 -189
  53. package/tests/playwright/qb/auth/fetchTempToken401.test.ts +0 -217
  54. package/tests/playwright/qb/auth/getAppWithUserToken.test.ts +0 -151
  55. package/tests/playwright/qb/auth/getTempToken.test.ts +0 -180
  56. package/tests/playwright/qb/auth/tokenPrefetch.test.ts +0 -192
  57. package/tests/playwright/qb/auth/tokenRenewal.test.ts +0 -110
  58. package/tests/playwright/qb/auth/umd.test.ts +0 -10
  59. package/tests/setup.ts +0 -51
  60. package/tests/vitest/qb/apps/copyApp.test.ts +0 -76
  61. package/tests/vitest/qb/apps/createApp.test.ts +0 -64
  62. package/tests/vitest/qb/apps/deleteApp.test.ts +0 -76
  63. package/tests/vitest/qb/apps/getApp.test.ts +0 -40
  64. package/tests/vitest/qb/fields/createField.test.ts +0 -78
  65. package/tests/vitest/qb/fields/deleteFields.test.ts +0 -89
  66. package/tests/vitest/qb/fields/getField.test.ts +0 -85
  67. package/tests/vitest/qb/fields/getFieldUsage.test.ts +0 -174
  68. package/tests/vitest/qb/fields/getFields.test.ts +0 -232
  69. package/tests/vitest/qb/fields/getFieldsUsage.test.ts +0 -77
  70. package/tests/vitest/qb/index.ts +0 -28
  71. package/tests/vitest/qb/records/deleteRecords.test.ts +0 -110
  72. package/tests/vitest/qb/records/runQuery.test.ts +0 -146
  73. package/tests/vitest/qb/records/upsert.test.ts +0 -102
  74. package/tests/vitest/qb/tables/createTable.test.ts +0 -55
  75. package/tests/vitest/qb/tables/deleteTable.test.ts +0 -50
  76. package/tests/vitest/qb/tables/getAppTables.test.ts +0 -46
  77. package/tests/vitest/qb/tables/getRelationships.test.ts +0 -80
  78. package/tests/vitest/qb/tables/getTable.test.ts +0 -26
  79. package/tests/vitest/qb/tables/updateTable.test.ts +0 -48
  80. package/tests/vitest/unit/apps/copyApp.test.ts +0 -282
  81. package/tests/vitest/unit/apps/createApp.test.ts +0 -125
  82. package/tests/vitest/unit/apps/deleteApp.test.ts +0 -215
  83. package/tests/vitest/unit/apps/getApp.test.ts +0 -86
  84. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +0 -85
  85. package/tests/vitest/unit/auth/getTempToken.test.ts +0 -95
  86. package/tests/vitest/unit/auth/retryOn401.test.ts +0 -106
  87. package/tests/vitest/unit/auth/two401s.test.ts +0 -77
  88. package/tests/vitest/unit/fields/createField.test.ts +0 -391
  89. package/tests/vitest/unit/fields/deleteFields.test.ts +0 -141
  90. package/tests/vitest/unit/fields/getField.test.ts +0 -189
  91. package/tests/vitest/unit/fields/getFieldUsage.test.ts +0 -147
  92. package/tests/vitest/unit/fields/getFields.test.ts +0 -122
  93. package/tests/vitest/unit/fields/getFieldsUsage.test.ts +0 -160
  94. package/tests/vitest/unit/index.ts +0 -33
  95. package/tests/vitest/unit/records/deleteRecords.test.ts +0 -112
  96. package/tests/vitest/unit/records/runQuery.test.ts +0 -102
  97. package/tests/vitest/unit/records/upsert.test.ts +0 -218
  98. package/tests/vitest/unit/tables/createTable.test.ts +0 -70
  99. package/tests/vitest/unit/tables/deleteTable.test.ts +0 -77
  100. package/tests/vitest/unit/tables/getAppTables.test.ts +0 -85
  101. package/tests/vitest/unit/tables/getRelationships.test.ts +0 -259
  102. package/tests/vitest/unit/tables/getTable.test.ts +0 -233
  103. package/tests/vitest/unit/tables/updateTable.test.ts +0 -80
  104. package/tests/vitest/unit/umd.test.ts +0 -8
  105. package/text.txt +0 -104
  106. package/tools/log-gen.ts +0 -175
  107. package/tools/openapi-jars/openapi-generator-cli-7.12.0.jar +0 -0
  108. package/tsconfig.build.json +0 -17
  109. package/tsconfig.json +0 -29
  110. package/versionrc.json +0 -9
  111. package/vitest.config.ts +0 -27
@@ -1,180 +0,0 @@
1
- // tests/integration/auth/getTempToken.test.ts
2
- import { test, expect } from "@playwright/test";
3
- import { quickbase } from "../../../../src/quickbaseClient.ts";
4
- import fetch from "node-fetch";
5
- import dotenv from "dotenv";
6
-
7
- dotenv.config();
8
-
9
- const loginToQuickbase = async (
10
- page: import("@playwright/test").Page,
11
- quickbaseUrl: string,
12
- username: string,
13
- password: string
14
- ): Promise<boolean> => {
15
- console.log("Logging in to QuickBase");
16
- let loginSuccess = false;
17
- const maxLoginAttempts = 3;
18
- let loginAttempt = 0;
19
-
20
- while (!loginSuccess && loginAttempt < maxLoginAttempts) {
21
- try {
22
- loginAttempt++;
23
- if (loginAttempt > 1) console.log(`Login attempt ${loginAttempt}`);
24
-
25
- await page.goto(quickbaseUrl, { timeout: 60000 });
26
- await page.waitForSelector("input[name='loginid']", { timeout: 60000 });
27
- await page.fill("input[name='loginid']", username);
28
- await page.fill("input[name='password']", password);
29
- await page.click("#signin");
30
- await page.waitForURL(`https://*.quickbase.com/**`, {
31
- waitUntil: "networkidle",
32
- timeout: 60000,
33
- });
34
-
35
- const loginError = await page.$(".login-error");
36
- if (loginError) {
37
- throw new Error("Login failed. Please check your credentials.");
38
- }
39
-
40
- console.log("Signed In to QuickBase.");
41
- loginSuccess = true;
42
- } catch (error) {
43
- console.error(
44
- `Login attempt ${loginAttempt} failed: ${(error as Error).message}`
45
- );
46
- if (loginAttempt >= maxLoginAttempts) {
47
- console.error("Max login attempts reached. Exiting.");
48
- await page.context().browser()!.close();
49
- return false;
50
- }
51
- await new Promise((resolve) => setTimeout(resolve, 5000));
52
- }
53
- }
54
- return loginSuccess;
55
- };
56
-
57
- test.describe("QuickbaseClient Integration - getApp with Temp Tokens", () => {
58
- test("uses temp tokens automatically for getApp in browser", async ({
59
- page,
60
- }) => {
61
- const realm = process.env.QB_REALM;
62
- const appId = process.env.QB_APP_ID;
63
- const username = process.env.QB_USERNAME;
64
- const password = process.env.QB_PASSWORD;
65
-
66
- if (!realm) throw new Error("QB_REALM is not defined in .env");
67
- if (!appId) throw new Error("QB_APP_ID is not defined in .env");
68
- if (!username) throw new Error("QB_USERNAME is not defined in .env");
69
- if (!password) throw new Error("QB_PASSWORD is not defined in .env");
70
-
71
- // Login to QuickBase
72
- const quickbaseUrl = `https://${realm}.quickbase.com/db/main?a=SignIn`;
73
- const loginSuccess = await loginToQuickbase(
74
- page,
75
- quickbaseUrl,
76
- username,
77
- password
78
- );
79
- if (!loginSuccess) {
80
- throw new Error("Failed to log in to QuickBase after max attempts.");
81
- }
82
-
83
- // Navigate to the app page to ensure session context
84
- await page.goto(`https://${realm}.quickbase.com/db/${appId}`, {
85
- waitUntil: "networkidle",
86
- timeout: 60000,
87
- });
88
- console.log("Post-login URL after app navigation:", page.url());
89
-
90
- // Define browser fetch function
91
- const browserFetch = async (url: string, init?: RequestInit) => {
92
- const response = await page.evaluate(
93
- async ([fetchUrl, fetchInit]) => {
94
- const res = await fetch(fetchUrl, {
95
- ...fetchInit,
96
- credentials: "include",
97
- });
98
- const body = await res.text();
99
- return {
100
- ok: res.ok,
101
- status: res.status,
102
- statusText: res.statusText,
103
- headers: Object.fromEntries(res.headers.entries()),
104
- body,
105
- };
106
- },
107
- [url, init] as [string, RequestInit]
108
- );
109
-
110
- console.log(`Raw response from ${url}:`, {
111
- status: response.status,
112
- statusText: response.statusText,
113
- body: response.body,
114
- });
115
-
116
- const fetchResponse = new Response(response.body || null, {
117
- status: response.status,
118
- statusText: response.statusText,
119
- headers: response.headers,
120
- });
121
-
122
- fetchResponse.json = async () => {
123
- if (!response.body) throw new Error("Empty response body from API");
124
- try {
125
- return JSON.parse(response.body);
126
- } catch (e) {
127
- throw new SyntaxError(`Invalid JSON response: ${response.body}`);
128
- }
129
- };
130
-
131
- return fetchResponse;
132
- };
133
-
134
- // Single client with conditional fetch
135
- const client = quickbase({
136
- realm,
137
- useTempTokens: true,
138
- debug: true,
139
- fetchApi: async (url, init) => {
140
- if (url.includes("/auth/temporary/")) {
141
- return browserFetch(url, init); // Use browser context for temp token
142
- }
143
- console.log(`Fetching ${url} with init:`, init);
144
- const response = await fetch(url, init as RequestInit); // Node-fetch for API calls
145
- const body = await response.text();
146
-
147
- console.log(`Raw response from ${url}:`, {
148
- status: response.status,
149
- statusText: response.statusText,
150
- body,
151
- });
152
-
153
- const fetchResponse = new Response(body || null, {
154
- status: response.status,
155
- statusText: response.statusText,
156
- headers: Object.fromEntries(response.headers.entries()),
157
- });
158
-
159
- fetchResponse.json = async () => {
160
- if (!body) throw new Error("Empty response body from API");
161
- try {
162
- return JSON.parse(body);
163
- } catch (e) {
164
- throw new SyntaxError(`Invalid JSON response: ${body}`);
165
- }
166
- };
167
-
168
- return fetchResponse;
169
- },
170
- });
171
-
172
- // Call getApp directly, letting the library handle temp token logic
173
- const appResult = await client.getApp({ appId });
174
- console.log("App response using auto-fetched temp token:", appResult);
175
-
176
- // Validate the app response
177
- expect(appResult).toHaveProperty("id", appId);
178
- expect(appResult).toHaveProperty("name");
179
- });
180
- });
@@ -1,192 +0,0 @@
1
- // tests/playwright/qb/auth/tokenPrefetch.test.ts
2
- import { test, expect } from "@playwright/test";
3
- import { quickbase } from "../../../../src/quickbaseClient.ts";
4
- import fetch from "node-fetch";
5
- import dotenv from "dotenv";
6
-
7
- dotenv.config();
8
-
9
- const loginToQuickbase = async (
10
- page: import("@playwright/test").Page,
11
- quickbaseUrl: string,
12
- username: string,
13
- password: string
14
- ): Promise<boolean> => {
15
- console.log("Logging in to QuickBase");
16
- let loginSuccess = false;
17
- const maxLoginAttempts = 3;
18
- let loginAttempt = 0;
19
-
20
- while (!loginSuccess && loginAttempt < maxLoginAttempts) {
21
- try {
22
- loginAttempt++;
23
- if (loginAttempt > 1) console.log(`Login attempt ${loginAttempt}`);
24
-
25
- await page.goto(quickbaseUrl, { timeout: 60000 });
26
- await page.waitForSelector("input[name='loginid']", { timeout: 60000 });
27
- await page.fill("input[name='loginid']", username);
28
- await page.fill("input[name='password']", password);
29
- await page.click("#signin");
30
- await page.waitForURL(`https://*.quickbase.com/**`, {
31
- waitUntil: "networkidle",
32
- timeout: 60000,
33
- });
34
-
35
- const loginError = await page.$(".login-error");
36
- if (loginError) {
37
- throw new Error("Login failed. Please check your credentials.");
38
- }
39
-
40
- console.log("Signed In to QuickBase.");
41
- loginSuccess = true;
42
- } catch (error) {
43
- console.error(
44
- `Login attempt ${loginAttempt} failed: ${(error as Error).message}`
45
- );
46
- if (loginAttempt >= maxLoginAttempts) {
47
- console.error("Max login attempts reached. Exiting.");
48
- await page.context().browser()!.close();
49
- return false;
50
- }
51
- await new Promise((resolve) => setTimeout(resolve, 5000));
52
- }
53
- }
54
- return loginSuccess;
55
- };
56
-
57
- test.describe("QuickbaseClient Integration - Token Pre-Fetch and Cache Reuse", () => {
58
- test("pre-fetches token and reuses it for subsequent API calls", async ({
59
- page,
60
- }) => {
61
- const realm = process.env.QB_REALM;
62
- const appId = process.env.QB_APP_ID;
63
- const username = process.env.QB_USERNAME;
64
- const password = process.env.QB_PASSWORD;
65
-
66
- if (!realm) throw new Error("QB_REALM is not defined in .env");
67
- if (!appId) throw new Error("QB_APP_ID is not defined in .env");
68
- if (!username) throw new Error("QB_USERNAME is not defined in .env");
69
- if (!password) throw new Error("QB_PASSWORD is not defined in .env");
70
-
71
- // Login to QuickBase
72
- const quickbaseUrl = `https://${realm}.quickbase.com/db/main?a=SignIn`;
73
- const loginSuccess = await loginToQuickbase(
74
- page,
75
- quickbaseUrl,
76
- username,
77
- password
78
- );
79
- if (!loginSuccess) {
80
- throw new Error("Failed to log in to QuickBase after max attempts.");
81
- }
82
-
83
- // Navigate to the app page to ensure session context
84
- await page.goto(`https://${realm}.quickbase.com/db/${appId}`, {
85
- waitUntil: "networkidle",
86
- timeout: 60000,
87
- });
88
- console.log("Post-login URL after app navigation:", page.url());
89
-
90
- // Track tokens and call counts
91
- let callCount = 0;
92
- let cachedToken: string | null = null;
93
-
94
- const browserFetch = async (url: string, init?: RequestInit) => {
95
- console.log(`browserFetch called for ${url}, callCount: ${callCount}`);
96
- const response = await page.evaluate(
97
- async ([fetchUrl, fetchInit]) => {
98
- const res = await fetch(fetchUrl, {
99
- ...fetchInit,
100
- credentials: "include",
101
- });
102
- const body = await res.text();
103
- return {
104
- ok: res.ok,
105
- status: res.status,
106
- statusText: res.statusText,
107
- headers: Object.fromEntries(res.headers.entries()),
108
- body,
109
- };
110
- },
111
- [url, init] as [string, RequestInit]
112
- );
113
-
114
- console.log(`Raw response from ${url}:`, {
115
- status: response.status,
116
- statusText: response.statusText,
117
- body: response.body,
118
- });
119
-
120
- const fetchResponse = new Response(response.body || null, {
121
- status: response.status,
122
- statusText: response.statusText,
123
- headers: response.headers,
124
- });
125
-
126
- // Capture token from response
127
- if (url.includes("/auth/temporary/")) {
128
- const json = await fetchResponse.clone().json();
129
- const token = json.temporaryAuthorization;
130
- cachedToken = token; // Store the pre-fetched token
131
- console.log(`Captured pre-fetched token: ${cachedToken}`);
132
- }
133
-
134
- return fetchResponse;
135
- };
136
-
137
- const client = quickbase({
138
- realm,
139
- useTempTokens: true,
140
- debug: true,
141
- fetchApi: async (url, init) => {
142
- callCount++;
143
- console.log(`fetchApi called for ${url}, callCount: ${callCount}`);
144
-
145
- if (url.includes("/auth/temporary/")) {
146
- return browserFetch(url, init); // Use browser fetch for temp tokens
147
- }
148
-
149
- // Use node-fetch for app calls, ensuring we track reuse
150
- console.log(`Fetching ${url} with init:`, init);
151
- const response = await fetch(url, init as RequestInit);
152
- const body = await response.text();
153
-
154
- console.log(`Raw response from ${url}:`, {
155
- status: response.status,
156
- statusText: response.statusText,
157
- body,
158
- });
159
-
160
- return new Response(body || null, {
161
- status: response.status,
162
- statusText: response.statusText,
163
- headers: Object.fromEntries(response.headers.entries()),
164
- });
165
- },
166
- });
167
-
168
- // Step 1: Pre-fetch token
169
- console.log("Pre-fetching token...");
170
- const tokenResult = await client.getTempTokenDBID({ dbid: appId });
171
- console.log("Pre-fetched token result:", tokenResult);
172
- expect(tokenResult).toHaveProperty("temporaryAuthorization");
173
- expect(cachedToken).toBe(tokenResult.temporaryAuthorization);
174
-
175
- // Step 2: Call getApp, expecting it to reuse the cached token
176
- console.log("Calling getApp with pre-fetched token...");
177
- const appResult = await client.getApp({ appId });
178
- console.log("App response:", appResult);
179
-
180
- // Validate the app response
181
- expect(appResult).toHaveProperty("id", appId);
182
- expect(appResult).toHaveProperty("name");
183
-
184
- // Verify call count and token reuse
185
- console.log(`Final callCount: ${callCount}`);
186
- expect(callCount).toBe(2); // One for pre-fetch, one for getApp
187
- expect(cachedToken).toBeDefined();
188
-
189
- // Check that getApp reused the token by inspecting logs manually or adding a header check if needed
190
- console.log(`Pre-fetched token: ${cachedToken}`);
191
- });
192
- });
@@ -1,110 +0,0 @@
1
- // tests/playwright/qb/auth/tokenRenewal.test.ts
2
- import { test, expect } from "@playwright/test";
3
- import { quickbase } from "../../../../src/quickbaseClient.ts";
4
- import dotenv from "dotenv";
5
-
6
- dotenv.config();
7
-
8
- const loginToQuickbase = async (
9
- page,
10
- quickbaseUrl,
11
- username,
12
- password,
13
- appUrl
14
- ) => {
15
- console.log("Logging in to QuickBase");
16
- await page.goto(quickbaseUrl, { timeout: 60000 });
17
- await page.waitForSelector("input[name='loginid']", { timeout: 60000 });
18
- await page.fill("input[name='loginid']", username);
19
- await page.fill("input[name='password']", password);
20
- await page.click("#signin");
21
- await page.waitForURL(`https://*.quickbase.com/**`, {
22
- waitUntil: "networkidle",
23
- timeout: 60000,
24
- });
25
- console.log("Signed In to QuickBase.");
26
- await page.goto(appUrl, { waitUntil: "networkidle", timeout: 60000 });
27
- console.log("Navigated to app URL:", page.url());
28
- };
29
-
30
- test.describe("QuickbaseClient Integration - Temp Token Renewal", () => {
31
- test("renews temp token after 5 minutes with getApp → wait → getApp sequence", async ({
32
- page,
33
- }) => {
34
- const realm = process.env.QB_REALM!;
35
- const appId = process.env.QB_APP_ID!;
36
- const username = process.env.QB_USERNAME!;
37
- const password = process.env.QB_PASSWORD!;
38
- const quickbaseUrl = `https://${realm}.quickbase.com/db/main?a=SignIn`;
39
- const appUrl = `https://${realm}.quickbase.com/db/${appId}`;
40
-
41
- await loginToQuickbase(page, quickbaseUrl, username, password, appUrl);
42
-
43
- const browserFetch = async (
44
- url: string,
45
- init: RequestInit
46
- ): Promise<Response> => {
47
- const response = await page.request.fetch(url, {
48
- method: init.method || "GET",
49
- headers: {
50
- ...init.headers,
51
- Referer: `https://${realm}.quickbase.com/db/${appId}`,
52
- Origin: `https://${realm}.quickbase.com`,
53
- },
54
- data: init.body,
55
- credentials: "include",
56
- });
57
- const body = await response.text();
58
- console.log(
59
- "Response from:",
60
- url,
61
- "status:",
62
- response.status(),
63
- "body:",
64
- body
65
- );
66
- return new Response(body, {
67
- status: response.status(),
68
- statusText: response.statusText(),
69
- headers: response.headers(),
70
- });
71
- };
72
-
73
- const client = quickbase({
74
- realm,
75
- useTempTokens: true,
76
- debug: true,
77
- fetchApi: browserFetch,
78
- });
79
-
80
- console.log("Checking session state before getApp...");
81
- const cookies = await page.context().cookies();
82
- const sessionCookie = cookies.find(
83
- (c) => c.name === "TICKET" || c.name.startsWith("TICKET_")
84
- );
85
- console.log(
86
- "Session cookie present:",
87
- !!sessionCookie,
88
- "Cookies:",
89
- cookies
90
- );
91
- if (!sessionCookie) throw new Error("TICKET session cookie not found");
92
-
93
- await page.waitForTimeout(5000); // Debug delay
94
- console.log("Cookies after delay:", await page.context().cookies());
95
-
96
- const appResult1 = await client.getApp({ appId });
97
- console.log("First getApp response:", appResult1);
98
- expect(appResult1.id).toBe(appId);
99
-
100
- console.log("Waiting 5 minutes to test token expiration...");
101
- await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000));
102
-
103
- await page.reload({ waitUntil: "load", timeout: 60000 });
104
- console.log("Refreshed page after 5 minutes, URL:", page.url());
105
-
106
- const appResult2 = await client.getApp({ appId });
107
- console.log("Second getApp response:", appResult2);
108
- expect(appResult2.id).toBe(appId);
109
- });
110
- });
@@ -1,10 +0,0 @@
1
- // tests/playwright/qb/auth/umd.test.ts
2
- import { test, expect } from "@playwright/test";
3
- test("UMD build works in browser", async ({ page }) => {
4
- await page.goto("http://localhost:3000/test-umd.html");
5
- const result = await page.evaluate(() => {
6
- const qb = new QuickbaseJS({ realm: "example", useTempTokens: true });
7
- return qb.getTempTokenDBID({ dbid: "test-dbid" });
8
- });
9
- expect(result).toBeTruthy();
10
- });
package/tests/setup.ts DELETED
@@ -1,51 +0,0 @@
1
- // @tests/setup.ts
2
- import { vi } from "vitest";
3
- import { quickbase } from "../src/quickbaseClient.ts";
4
- import type { QuickbaseConfig } from "../src/quickbaseClient.ts";
5
- import dotenv from "dotenv";
6
-
7
- // Load environment variables from .env file
8
- dotenv.config({ path: "./.env" }); // Assumes .env is at project root
9
-
10
- export const mockFetch = vi.fn();
11
-
12
- export const QB_REALM = process.env.QB_REALM || "test-realm";
13
- export const QB_USER_TOKEN =
14
- process.env.QB_USER_TOKEN || "user-token-1234567890";
15
- export const QB_APP_ID = process.env.QB_APP_ID || "app-id-1234567890";
16
- export const QB_TABLE_ID_1 =
17
- process.env.QB_TABLE_ID_1 || "table-id-1-1234567890";
18
- export const QB_TABLE_ID_2 =
19
- process.env.QB_TABLE_ID_2 || "table-id-2-1234567890";
20
-
21
- // Mock env variables for consistency, using .env values if available
22
- vi.stubEnv("QB_REALM", QB_REALM);
23
- vi.stubEnv("QB_USER_TOKEN", QB_USER_TOKEN);
24
- vi.stubEnv("QB_APP_ID", QB_APP_ID);
25
- vi.stubEnv("QB_TABLE_ID_1", QB_TABLE_ID_1);
26
- vi.stubEnv("QB_TABLE_ID_2", QB_TABLE_ID_2);
27
-
28
- export const createClient = (
29
- fetchApi?: any,
30
- config: Partial<QuickbaseConfig> = {}
31
- ) => {
32
- // Use loaded env vars with fallbacks for safety
33
- const realm = QB_REALM;
34
- const userToken = QB_USER_TOKEN;
35
-
36
- const client = quickbase({
37
- realm,
38
- userToken,
39
- debug: true,
40
- fetchApi,
41
- ...config, // Allow overrides if provided
42
- });
43
- console.log("[createClient] Config:", {
44
- realm,
45
- userToken,
46
- debug: true,
47
- ...config,
48
- });
49
- console.log("[createClient] Returning:", client);
50
- return client;
51
- };
@@ -1,76 +0,0 @@
1
- // tests/vitest/qb/apps/copyApp.test.ts
2
- import { test, expect } from "vitest";
3
- import { quickbase } from "../../../../src/quickbaseClient";
4
-
5
- test(
6
- "QuickbaseClient Integration - copyApp > creates a new copied app in QuickBase",
7
- { timeout: 30000 }, // Increased to 30 seconds
8
- async () => {
9
- const config = {
10
- realm: process.env.QB_REALM || "",
11
- userToken: process.env.QB_USER_TOKEN || "",
12
- debug: true,
13
- };
14
- const client = quickbase(config);
15
- const appId = process.env.QB_APP_ID || ""; // The source app ID to copy from
16
-
17
- const copyAppName = `CopiedApp_${Date.now()}`; // Unique name to avoid conflicts
18
- const copyBody = {
19
- name: copyAppName,
20
- description: "Test copied app",
21
- properties: {
22
- keepData: false,
23
- excludeFiles: true,
24
- usersAndRoles: false,
25
- assignUserToken: true,
26
- },
27
- };
28
-
29
- console.log("Config used:", {
30
- ...config,
31
- userToken: config.userToken ? "[REDACTED]" : "", // Avoid logging sensitive token
32
- });
33
- console.log("Copying app with:", copyBody);
34
- const startTime = Date.now();
35
- let response;
36
- try {
37
- response = await client.copyApp({ appId, body: copyBody });
38
- const duration = Date.now() - startTime;
39
- console.log(`copyApp completed in ${duration}ms`);
40
- console.log("Real API response:", response);
41
-
42
- expect(response).toBeDefined();
43
- expect(response.id).toBeDefined();
44
- expect(response.name).toBe(copyAppName);
45
- expect(response.description).toBe(copyBody.description);
46
- expect(response.created).toBeInstanceOf(Date);
47
- expect(response.updated).toBeInstanceOf(Date);
48
- expect(response.dateFormat).toMatch(/^\w{2}-\w{2}-\w{4}$/); // e.g., "MM-DD-YYYY"
49
- expect(typeof response.timeZone).toBe("string"); // Simplified check
50
- expect(typeof response.hasEveryoneOnTheInternet).toBe("boolean");
51
- expect(response.ancestorId).toBe(appId); // Should match the source app ID
52
- expect(
53
- response.dataClassification === undefined ||
54
- typeof response.dataClassification === "string"
55
- ).toBe(true); // Allow undefined or string
56
- expect(
57
- response.variables === undefined || Array.isArray(response.variables)
58
- ).toBe(true); // Allow undefined or array
59
- } catch (error) {
60
- const duration = Date.now() - startTime;
61
- console.error(`copyApp failed after ${duration}ms:`, error);
62
- throw error; // Re-throw to fail the test
63
- }
64
-
65
- // Cleanup: Delete the copied app using deleteApp
66
- const deleteStartTime = Date.now();
67
- const deleteResponse = await client.deleteApp({
68
- appId: response.id,
69
- body: { name: copyAppName },
70
- });
71
- const deleteDuration = Date.now() - deleteStartTime;
72
- console.log(`deleteApp completed in ${deleteDuration}ms`);
73
- console.log("Cleanup - Deleted app:", deleteResponse);
74
- expect(deleteResponse.deletedAppId).toBe(response.id);
75
- }
76
- );
@@ -1,64 +0,0 @@
1
- // tests/vitest/qb/apps/createApp.test.ts
2
- import { test, expect } from "vitest";
3
- import { quickbase } from "../../../../src/quickbaseClient";
4
-
5
- test(
6
- "QuickbaseClient Integration - createApp > creates a new app in QuickBase",
7
- { timeout: 30000 },
8
- async () => {
9
- const config = {
10
- realm: process.env.QB_REALM || "",
11
- userToken: process.env.QB_USER_TOKEN || "",
12
- debug: true,
13
- useTempTokens: false,
14
- };
15
- const client = quickbase(config);
16
-
17
- const appName = `TestApp_${Date.now()}`;
18
- const createBody = {
19
- name: appName,
20
- description: "Test app creation",
21
- assignToken: true,
22
- };
23
-
24
- console.log("Config used:", {
25
- ...config,
26
- userToken: config.userToken ? "[REDACTED]" : "",
27
- });
28
- console.log("Creating app with:", createBody);
29
- const createStartTime = Date.now();
30
- let response;
31
- try {
32
- response = await client.createApp({ body: createBody });
33
- const createDuration = Date.now() - createStartTime;
34
- console.log(`createApp completed in ${createDuration}ms`);
35
- console.log("Real API response:", response);
36
-
37
- expect(response).toBeDefined();
38
- expect(response.id).toBeDefined();
39
- expect(response.name).toBe(appName);
40
- expect(response.description).toBe(createBody.description);
41
- expect(response.created).toBeInstanceOf(Date);
42
- expect(response.updated).toBeInstanceOf(Date);
43
- expect(response.dateFormat).toMatch(/^\w{2}-\w{2}-\w{4}$/);
44
- expect(typeof response.timeZone).toBe("string");
45
- expect(typeof response.hasEveryoneOnTheInternet).toBe("boolean");
46
- expect(
47
- response.dataClassification === undefined ||
48
- typeof response.dataClassification === "string"
49
- ).toBe(true);
50
- expect(
51
- response.variables === undefined || Array.isArray(response.variables)
52
- ).toBe(true);
53
-
54
- // Cleanup: Delete the app after assertions
55
- const deleteBody = { name: appName };
56
- await client.deleteApp({ appId: response.id, body: deleteBody });
57
- console.log("Cleanup: App deleted:", response.id);
58
- } catch (error) {
59
- const createDuration = Date.now() - createStartTime;
60
- console.error(`createApp failed after ${createDuration}ms:`, error);
61
- throw error;
62
- }
63
- }
64
- );