quickbase-js 1.1.0-beta.3 → 1.1.0-beta.5

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 (69) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +115 -5
  3. package/build.js +175 -55
  4. package/dist/{quickbase.d.ts → esm/quickbase.d.ts} +1108 -349
  5. package/dist/{quickbase.js → esm/quickbase.js} +828 -263
  6. package/dist/esm/quickbase.js.map +1 -0
  7. package/dist/esm/quickbase.min.js +2 -0
  8. package/dist/esm/quickbase.min.js.map +1 -0
  9. package/dist/umd/quickbase.umd.d.ts +5341 -0
  10. package/dist/umd/quickbase.umd.js +7696 -0
  11. package/dist/umd/quickbase.umd.js.map +1 -0
  12. package/dist/umd/quickbase.umd.min.js +2 -0
  13. package/dist/umd/quickbase.umd.min.js.map +1 -0
  14. package/examples/react.js +12 -12
  15. package/examples/vanillajs.html +12 -12
  16. package/log-gen.yaml +536 -1915
  17. package/open-api/definitions/apps.ts +274 -0
  18. package/open-api/definitions/auth.ts +10 -0
  19. package/open-api/definitions/fields.ts +751 -0
  20. package/open-api/definitions/index.ts +18 -0
  21. package/open-api/definitions/records.ts +269 -0
  22. package/open-api/definitions/relationships.ts +90 -0
  23. package/open-api/definitions/reports.ts +10 -0
  24. package/open-api/definitions/tables.ts +112 -0
  25. package/{src/code-generation → open-api}/fix-spec-main.ts +3 -3
  26. package/{src/code-generation → open-api}/generate-unified-interface.ts +42 -17
  27. package/{src/code-generation → open-api}/output/quickbase-fixed.json +3244 -4586
  28. package/open-api/paths/apps.ts +100 -0
  29. package/open-api/paths/auth.ts +25 -0
  30. package/open-api/paths/fields.ts +207 -0
  31. package/open-api/paths/index.ts +17 -0
  32. package/open-api/paths/records.ts +68 -0
  33. package/open-api/paths/relationships.ts +32 -0
  34. package/open-api/paths/reports.ts +34 -0
  35. package/open-api/paths/tables.ts +162 -0
  36. package/{src/code-generation → open-api}/regenerate-client.ts +4 -4
  37. package/package.json +34 -25
  38. package/playwright-results.txt/.last-run.json +4 -0
  39. package/playwright.config.ts +1 -1
  40. package/rollup.config.mjs +114 -0
  41. package/src/generated-unified/QuickbaseClient.ts +7 -6
  42. package/test-artifacts/.last-run.json +4 -2
  43. package/test-esm.js +1 -0
  44. package/test-umd.js +1 -0
  45. package/test.ts +1 -0
  46. package/tests/playwright/qb/auth/umd.test.ts +10 -0
  47. package/tests/vitest/qb/fields/createField.test.ts +78 -0
  48. package/tests/vitest/qb/fields/deleteFields.test.ts +89 -0
  49. package/tests/vitest/qb/fields/getField.test.ts +85 -0
  50. package/tests/vitest/qb/fields/getFieldUsage.test.ts +174 -0
  51. package/tests/vitest/qb/fields/getFieldsUsage.test.ts +77 -0
  52. package/tests/vitest/qb/index.ts +25 -1
  53. package/tests/vitest/unit/fields/createField.test.ts +391 -0
  54. package/tests/vitest/unit/fields/deleteFields.test.ts +141 -0
  55. package/tests/vitest/unit/fields/getField.test.ts +189 -0
  56. package/tests/vitest/unit/fields/getFieldUsage.test.ts +147 -0
  57. package/tests/vitest/unit/fields/getFieldsUsage.test.ts +160 -0
  58. package/tests/vitest/unit/index.ts +30 -1
  59. package/tests/vitest/unit/umd.test.ts +8 -0
  60. package/{src → tools}/log-gen.ts +14 -10
  61. package/tools/openapi-jars/openapi-generator-cli-7.12.0.jar +0 -0
  62. package/tsconfig.build.json +17 -0
  63. package/tsconfig.json +5 -5
  64. package/dist/quickbase.js.map +0 -1
  65. package/rollup.config.js +0 -70
  66. package/src/code-generation/fix-spec-definitions.ts +0 -809
  67. package/src/code-generation/fix-spec-paths.ts +0 -439
  68. package/test-artifacts/test-results.json +0 -829
  69. /package/{src/specs → specs}/QuickBase_RESTful_API_2025-03-04T06_22_39.725Z.json +0 -0
@@ -0,0 +1,141 @@
1
+ // tests/vitest/unit/fields/deleteFields.test.ts
2
+ import { describe, it, expect, beforeEach } from "vitest";
3
+ import {
4
+ createClient,
5
+ mockFetch,
6
+ QB_REALM,
7
+ QB_USER_TOKEN,
8
+ QB_TABLE_ID_1,
9
+ } from "@tests/setup.ts";
10
+ import {
11
+ DeleteFieldsRequest,
12
+ DeleteFields200Response,
13
+ } from "@/generated/models";
14
+
15
+ describe("QuickbaseClient Unit - deleteFields", () => {
16
+ let client: ReturnType<typeof createClient>;
17
+
18
+ beforeEach(() => {
19
+ mockFetch.mockClear();
20
+ });
21
+
22
+ it("initializes without errors and has deleteFields method", () => {
23
+ client = createClient(mockFetch, { debug: true });
24
+ expect(client).toBeDefined();
25
+ expect(typeof client.deleteFields).toBe("function");
26
+ });
27
+
28
+ it("deletes fields successfully with user token", async () => {
29
+ client = createClient(mockFetch, { debug: true });
30
+
31
+ const request: DeleteFieldsRequest = {
32
+ fieldIds: [6, 7, 8],
33
+ };
34
+
35
+ const mockResponse: DeleteFields200Response = {
36
+ deletedFieldIds: [6, 7, 8],
37
+ errors: [],
38
+ };
39
+
40
+ mockFetch.mockResolvedValueOnce({
41
+ ok: true,
42
+ status: 200,
43
+ json: () => Promise.resolve(mockResponse),
44
+ });
45
+
46
+ const result = await client.deleteFields({
47
+ tableId: QB_TABLE_ID_1,
48
+ body: request,
49
+ });
50
+
51
+ expect(result).toEqual(mockResponse);
52
+ expect(mockFetch).toHaveBeenCalledWith(
53
+ `https://api.quickbase.com/v1/fields?tableId=${QB_TABLE_ID_1}`,
54
+ expect.objectContaining({
55
+ method: "DELETE",
56
+ headers: expect.objectContaining({
57
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
58
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
59
+ "Content-Type": "application/json",
60
+ }),
61
+ body: JSON.stringify(request),
62
+ credentials: "omit",
63
+ })
64
+ );
65
+ });
66
+
67
+ it("handles partial success with errors", async () => {
68
+ client = createClient(mockFetch, { debug: true });
69
+
70
+ const request: DeleteFieldsRequest = {
71
+ fieldIds: [6, 7, 8],
72
+ };
73
+
74
+ const mockResponse: DeleteFields200Response = {
75
+ deletedFieldIds: [6, 8],
76
+ errors: ["Error found with fid: 7"],
77
+ };
78
+
79
+ mockFetch.mockResolvedValueOnce({
80
+ ok: true,
81
+ status: 200,
82
+ json: () => Promise.resolve(mockResponse),
83
+ });
84
+
85
+ const result = await client.deleteFields({
86
+ tableId: QB_TABLE_ID_1,
87
+ body: request,
88
+ });
89
+
90
+ expect(result).toEqual(mockResponse);
91
+ expect(mockFetch).toHaveBeenCalledWith(
92
+ `https://api.quickbase.com/v1/fields?tableId=${QB_TABLE_ID_1}`,
93
+ expect.objectContaining({
94
+ method: "DELETE",
95
+ headers: expect.objectContaining({
96
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
97
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
98
+ "Content-Type": "application/json",
99
+ }),
100
+ body: JSON.stringify(request),
101
+ credentials: "omit",
102
+ })
103
+ );
104
+ });
105
+
106
+ it("handles 400 error for invalid request", async () => {
107
+ client = createClient(mockFetch, { debug: true });
108
+
109
+ const request: DeleteFieldsRequest = {
110
+ fieldIds: [], // Invalid: empty fieldIds array
111
+ };
112
+
113
+ mockFetch.mockResolvedValueOnce({
114
+ ok: false,
115
+ status: 400,
116
+ json: () =>
117
+ Promise.resolve({
118
+ message: "Invalid input",
119
+ description: "Field IDs list cannot be empty.",
120
+ }),
121
+ });
122
+
123
+ await expect(
124
+ client.deleteFields({ tableId: QB_TABLE_ID_1, body: request })
125
+ ).rejects.toThrow("API Error: Invalid input (Status: 400)");
126
+
127
+ expect(mockFetch).toHaveBeenCalledWith(
128
+ `https://api.quickbase.com/v1/fields?tableId=${QB_TABLE_ID_1}`,
129
+ expect.objectContaining({
130
+ method: "DELETE",
131
+ headers: expect.objectContaining({
132
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
133
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
134
+ "Content-Type": "application/json",
135
+ }),
136
+ body: JSON.stringify(request),
137
+ credentials: "omit",
138
+ })
139
+ );
140
+ });
141
+ });
@@ -0,0 +1,189 @@
1
+ // tests/vitest/unit/fields/getField.test.ts
2
+ import { describe, it, expect, beforeEach } from "vitest";
3
+ import {
4
+ createClient,
5
+ mockFetch,
6
+ QB_REALM,
7
+ QB_USER_TOKEN,
8
+ QB_TABLE_ID_1,
9
+ } from "@tests/setup.ts";
10
+ import { Field } from "@/generated/models";
11
+
12
+ describe("QuickbaseClient Unit - getField", () => {
13
+ let client: ReturnType<typeof createClient>;
14
+
15
+ beforeEach(() => {
16
+ mockFetch.mockClear();
17
+ client = createClient(mockFetch, { debug: true });
18
+ });
19
+
20
+ it("initializes without errors and has getField method", () => {
21
+ expect(client).toBeDefined();
22
+ expect(typeof client.getField).toBe("function");
23
+ });
24
+
25
+ it("calls getField successfully with user token", async () => {
26
+ const mockResponse: Field = {
27
+ id: 123,
28
+ label: "Field1",
29
+ fieldType: "text",
30
+ mode: "",
31
+ noWrap: false,
32
+ bold: false,
33
+ required: false,
34
+ appearsByDefault: false,
35
+ findEnabled: false,
36
+ unique: false,
37
+ doesDataCopy: false,
38
+ fieldHelp: "field help",
39
+ audited: false,
40
+ properties: {
41
+ primaryKey: false,
42
+ foreignKey: false,
43
+ numLines: 1,
44
+ maxLength: 0,
45
+ appendOnly: false,
46
+ allowHTML: false,
47
+ allowMentions: false,
48
+ sortAsGiven: false,
49
+ carryChoices: true,
50
+ allowNewChoices: false,
51
+ formula: "",
52
+ defaultValue: "",
53
+ },
54
+ permissions: [
55
+ { permissionType: "View", role: "Viewer", roleId: 10 },
56
+ { permissionType: "None", role: "Participant", roleId: 11 },
57
+ { permissionType: "Modify", role: "Administrator", roleId: 12 },
58
+ ],
59
+ };
60
+
61
+ mockFetch.mockResolvedValueOnce({
62
+ ok: true,
63
+ status: 200,
64
+ json: () => Promise.resolve(mockResponse),
65
+ });
66
+
67
+ const result = await client.getField({
68
+ fieldId: 123,
69
+ tableId: QB_TABLE_ID_1,
70
+ includeFieldPerms: true,
71
+ });
72
+
73
+ expect(result).toEqual(mockResponse);
74
+ expect(mockFetch).toHaveBeenCalledWith(
75
+ `https://api.quickbase.com/v1/fields/123?tableId=${QB_TABLE_ID_1}&includeFieldPerms=true`,
76
+ expect.objectContaining({
77
+ method: "GET",
78
+ headers: expect.objectContaining({
79
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
80
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
81
+ "Content-Type": "application/json",
82
+ }),
83
+ })
84
+ );
85
+ });
86
+
87
+ it("calls getField successfully with temp token", async () => {
88
+ client = createClient(mockFetch, { useTempTokens: true, debug: true });
89
+
90
+ const mockResponse: Field = {
91
+ id: 123,
92
+ label: "Field1",
93
+ fieldType: "text",
94
+ mode: "",
95
+ noWrap: false,
96
+ bold: false,
97
+ required: false,
98
+ appearsByDefault: false,
99
+ findEnabled: false,
100
+ unique: false,
101
+ doesDataCopy: false,
102
+ fieldHelp: "field help",
103
+ audited: false,
104
+ properties: {
105
+ primaryKey: false,
106
+ foreignKey: false,
107
+ numLines: 1,
108
+ maxLength: 0,
109
+ appendOnly: false,
110
+ allowHTML: false,
111
+ allowMentions: false,
112
+ sortAsGiven: false,
113
+ carryChoices: true,
114
+ allowNewChoices: false,
115
+ formula: "",
116
+ defaultValue: "",
117
+ },
118
+ permissions: [],
119
+ };
120
+
121
+ mockFetch
122
+ .mockResolvedValueOnce({
123
+ ok: true,
124
+ status: 200,
125
+ json: () => Promise.resolve({ temporaryAuthorization: "temp_token" }),
126
+ })
127
+ .mockResolvedValueOnce({
128
+ ok: true,
129
+ status: 200,
130
+ json: () => Promise.resolve(mockResponse),
131
+ });
132
+
133
+ const result = await client.getField({
134
+ fieldId: 123,
135
+ tableId: QB_TABLE_ID_1,
136
+ });
137
+
138
+ expect(result).toEqual(mockResponse);
139
+ expect(mockFetch).toHaveBeenCalledTimes(2);
140
+ expect(mockFetch).toHaveBeenNthCalledWith(
141
+ 1,
142
+ `https://api.quickbase.com/v1/auth/temporary/${QB_TABLE_ID_1}`,
143
+ expect.objectContaining({
144
+ method: "GET",
145
+ headers: expect.objectContaining({
146
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
147
+ "Content-Type": "application/json",
148
+ }),
149
+ credentials: "include",
150
+ })
151
+ );
152
+ expect(mockFetch).toHaveBeenNthCalledWith(
153
+ 2,
154
+ `https://api.quickbase.com/v1/fields/123?tableId=${QB_TABLE_ID_1}`,
155
+ expect.objectContaining({
156
+ method: "GET",
157
+ headers: expect.objectContaining({
158
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
159
+ Authorization: "QB-TEMP-TOKEN temp_token",
160
+ "Content-Type": "application/json",
161
+ }),
162
+ })
163
+ );
164
+ });
165
+
166
+ it("handles 404 error for non-existent field", async () => {
167
+ mockFetch.mockResolvedValueOnce({
168
+ ok: false,
169
+ status: 404,
170
+ json: () => Promise.resolve({ message: "Field not found" }),
171
+ });
172
+
173
+ await expect(
174
+ client.getField({ fieldId: 999, tableId: QB_TABLE_ID_1 })
175
+ ).rejects.toThrow("API Error: Field not found (Status: 404)");
176
+
177
+ expect(mockFetch).toHaveBeenCalledWith(
178
+ `https://api.quickbase.com/v1/fields/999?tableId=${QB_TABLE_ID_1}`,
179
+ expect.objectContaining({
180
+ method: "GET",
181
+ headers: expect.objectContaining({
182
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
183
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
184
+ "Content-Type": "application/json",
185
+ }),
186
+ })
187
+ );
188
+ });
189
+ });
@@ -0,0 +1,147 @@
1
+ // tests/vitest/unit/fields/getFieldUsage.test.ts
2
+ import { describe, it, expect, beforeEach } from "vitest";
3
+ import {
4
+ createClient,
5
+ mockFetch,
6
+ QB_REALM,
7
+ QB_USER_TOKEN,
8
+ QB_TABLE_ID_1,
9
+ } from "@tests/setup.ts";
10
+ import { FieldUsage } from "@/generated/models";
11
+
12
+ describe("QuickbaseClient Unit - getFieldUsage", () => {
13
+ let client: ReturnType<typeof createClient>;
14
+
15
+ beforeEach(() => {
16
+ mockFetch.mockClear();
17
+ client = createClient(mockFetch, { realm: QB_REALM, debug: true });
18
+ });
19
+
20
+ it("initializes without errors and has getFieldUsage method", () => {
21
+ expect(client).toBeDefined();
22
+ expect(typeof client.getFieldUsage).toBe("function");
23
+ });
24
+
25
+ it("calls getFieldUsage successfully with user token", async () => {
26
+ const mockResponse: FieldUsage = {
27
+ field: {
28
+ id: 6,
29
+ name: "name",
30
+ type: "text", // Match QuickBase's lowercase response
31
+ },
32
+ usage: {
33
+ actions: { count: 0 },
34
+ appHomePages: { count: 0 },
35
+ dashboards: { count: 2 },
36
+ defaultReports: { count: 1 },
37
+ exactForms: { count: 0 },
38
+ fields: { count: 0 },
39
+ forms: { count: 1 },
40
+ notifications: { count: 0 },
41
+ personalReports: { count: 0 },
42
+ pipelines: { count: 1 },
43
+ relationships: { count: 0 },
44
+ reminders: { count: 0 },
45
+ reports: { count: 2 },
46
+ roles: { count: 2 },
47
+ tableImports: { count: 2 },
48
+ tableRules: { count: 1 },
49
+ webhooks: { count: 0 },
50
+ },
51
+ };
52
+
53
+ // Mock the response as an array to match the updated API behavior
54
+ mockFetch.mockResolvedValueOnce(
55
+ new Response(JSON.stringify([mockResponse]), {
56
+ status: 200,
57
+ statusText: "OK",
58
+ headers: { "Content-Type": "application/json" },
59
+ })
60
+ );
61
+
62
+ const result = await client.getFieldUsage({
63
+ fieldId: 6,
64
+ tableId: QB_TABLE_ID_1,
65
+ });
66
+
67
+ // Expect an array and unwrap the first item
68
+ expect(result).toBeInstanceOf(Array);
69
+ expect(result).toHaveLength(1);
70
+ const fieldUsage = result[0];
71
+
72
+ expect(fieldUsage).toEqual(mockResponse);
73
+ expect(mockFetch).toHaveBeenCalledWith(
74
+ `https://api.quickbase.com/v1/fields/usage/6?tableId=${QB_TABLE_ID_1}`,
75
+ expect.objectContaining({
76
+ method: "GET",
77
+ headers: expect.objectContaining({
78
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
79
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
80
+ "Content-Type": "application/json",
81
+ }),
82
+ })
83
+ );
84
+ expect(fieldUsage.field.id).toBe(6);
85
+ expect(fieldUsage.field.name).toBe("name");
86
+ expect(fieldUsage.usage.dashboards.count).toBe(2);
87
+ });
88
+
89
+ it("handles 404 error for non-existent field", async () => {
90
+ mockFetch.mockResolvedValueOnce(
91
+ new Response(JSON.stringify({ message: "Field not found" }), {
92
+ status: 404,
93
+ statusText: "Not Found",
94
+ headers: { "Content-Type": "application/json" },
95
+ })
96
+ );
97
+
98
+ await expect(
99
+ client.getFieldUsage({
100
+ fieldId: 999,
101
+ tableId: QB_TABLE_ID_1,
102
+ })
103
+ ).rejects.toThrow("API Error: Field not found (Status: 404)");
104
+
105
+ expect(mockFetch).toHaveBeenCalledWith(
106
+ `https://api.quickbase.com/v1/fields/usage/999?tableId=${QB_TABLE_ID_1}`,
107
+ expect.objectContaining({
108
+ method: "GET",
109
+ headers: expect.objectContaining({
110
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
111
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
112
+ "Content-Type": "application/json",
113
+ }),
114
+ })
115
+ );
116
+ });
117
+
118
+ it("handles 401 error and does not retry with user token", async () => {
119
+ mockFetch.mockResolvedValueOnce(
120
+ new Response(JSON.stringify({ message: "Unauthorized" }), {
121
+ status: 401,
122
+ statusText: "Unauthorized",
123
+ headers: { "Content-Type": "application/json" },
124
+ })
125
+ );
126
+
127
+ await expect(
128
+ client.getFieldUsage({
129
+ fieldId: 6,
130
+ tableId: QB_TABLE_ID_1,
131
+ })
132
+ ).rejects.toThrow("API Error: Unauthorized (Status: 401)");
133
+
134
+ expect(mockFetch).toHaveBeenCalledTimes(1); // No retry with user token
135
+ expect(mockFetch).toHaveBeenCalledWith(
136
+ `https://api.quickbase.com/v1/fields/usage/6?tableId=${QB_TABLE_ID_1}`,
137
+ expect.objectContaining({
138
+ method: "GET",
139
+ headers: expect.objectContaining({
140
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
141
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
142
+ "Content-Type": "application/json",
143
+ }),
144
+ })
145
+ );
146
+ });
147
+ });
@@ -0,0 +1,160 @@
1
+ // tests/vitest/unit/fields/getFieldsUsage.test.ts
2
+ import { describe, it, expect, beforeEach } from "vitest";
3
+ import {
4
+ createClient,
5
+ mockFetch,
6
+ QB_REALM,
7
+ QB_TABLE_ID_1,
8
+ QB_USER_TOKEN,
9
+ } from "@tests/setup.ts";
10
+ import { FieldUsage } from "@/generated/models";
11
+
12
+ describe("QuickbaseClient Unit - getFieldsUsage", () => {
13
+ let client: ReturnType<typeof createClient>;
14
+
15
+ beforeEach(() => {
16
+ mockFetch.mockClear();
17
+ client = createClient(mockFetch, { debug: true });
18
+ });
19
+
20
+ it("initializes without errors and has getFieldsUsage method", () => {
21
+ expect(client).toBeDefined();
22
+ expect(typeof client.getFieldsUsage).toBe("function");
23
+ });
24
+
25
+ it("calls getFieldsUsage successfully with user token", async () => {
26
+ const mockResponse: FieldUsage[] = [
27
+ {
28
+ field: {
29
+ id: 6,
30
+ name: "name",
31
+ type: "Text",
32
+ },
33
+ usage: {
34
+ actions: { count: 0 },
35
+ appHomePages: { count: 0 },
36
+ dashboards: { count: 2 },
37
+ defaultReports: { count: 1 },
38
+ exactForms: { count: 0 },
39
+ fields: { count: 0 },
40
+ forms: { count: 1 },
41
+ notifications: { count: 0 },
42
+ personalReports: { count: 0 },
43
+ pipelines: { count: 1 },
44
+ relationships: { count: 0 },
45
+ reminders: { count: 0 },
46
+ reports: { count: 2 },
47
+ roles: { count: 2 },
48
+ tableImports: { count: 3 },
49
+ tableRules: { count: 1 },
50
+ webhooks: { count: 0 },
51
+ },
52
+ },
53
+ ];
54
+
55
+ mockFetch.mockResolvedValueOnce({
56
+ ok: true,
57
+ status: 200,
58
+ json: () => Promise.resolve(mockResponse),
59
+ });
60
+
61
+ const result = await client.getFieldsUsage({
62
+ tableId: QB_TABLE_ID_1,
63
+ });
64
+
65
+ expect(result).toEqual(mockResponse);
66
+ expect(mockFetch).toHaveBeenCalledWith(
67
+ `https://api.quickbase.com/v1/fields/usage?tableId=${QB_TABLE_ID_1}`,
68
+ expect.objectContaining({
69
+ method: "GET",
70
+ headers: expect.objectContaining({
71
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
72
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
73
+ "Content-Type": "application/json",
74
+ }),
75
+ })
76
+ );
77
+ });
78
+
79
+ it("calls getFieldsUsage with skip and top parameters", async () => {
80
+ const mockResponse: FieldUsage[] = [
81
+ {
82
+ field: {
83
+ id: 7,
84
+ name: "priority",
85
+ type: "Text",
86
+ },
87
+ usage: {
88
+ actions: { count: 1 },
89
+ appHomePages: { count: 0 },
90
+ dashboards: { count: 0 },
91
+ defaultReports: { count: 0 },
92
+ exactForms: { count: 0 },
93
+ fields: { count: 1 },
94
+ forms: { count: 0 },
95
+ notifications: { count: 0 },
96
+ personalReports: { count: 0 },
97
+ pipelines: { count: 0 },
98
+ relationships: { count: 0 },
99
+ reminders: { count: 0 },
100
+ reports: { count: 1 },
101
+ roles: { count: 1 },
102
+ tableImports: { count: 0 },
103
+ tableRules: { count: 0 },
104
+ webhooks: { count: 0 },
105
+ },
106
+ },
107
+ ];
108
+
109
+ mockFetch.mockResolvedValueOnce({
110
+ ok: true,
111
+ status: 200,
112
+ json: () => Promise.resolve(mockResponse),
113
+ });
114
+
115
+ const result = await client.getFieldsUsage({
116
+ tableId: QB_TABLE_ID_1,
117
+ skip: 1,
118
+ top: 1,
119
+ });
120
+
121
+ expect(result).toEqual(mockResponse);
122
+ expect(mockFetch).toHaveBeenCalledWith(
123
+ `https://api.quickbase.com/v1/fields/usage?tableId=${QB_TABLE_ID_1}&skip=1&top=1`,
124
+ expect.objectContaining({
125
+ method: "GET",
126
+ headers: expect.objectContaining({
127
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
128
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
129
+ "Content-Type": "application/json",
130
+ }),
131
+ })
132
+ );
133
+ });
134
+
135
+ it("handles 404 error for non-existent table", async () => {
136
+ const nonExistentTableId = "nonexistent_dbid";
137
+
138
+ mockFetch.mockResolvedValueOnce({
139
+ ok: false,
140
+ status: 404,
141
+ json: () => Promise.resolve({ message: "Table not found" }),
142
+ });
143
+
144
+ await expect(
145
+ client.getFieldsUsage({ tableId: nonExistentTableId })
146
+ ).rejects.toThrow("API Error: Table not found (Status: 404)");
147
+
148
+ expect(mockFetch).toHaveBeenCalledWith(
149
+ `https://api.quickbase.com/v1/fields/usage?tableId=${nonExistentTableId}`,
150
+ expect.objectContaining({
151
+ method: "GET",
152
+ headers: expect.objectContaining({
153
+ "QB-Realm-Hostname": `${QB_REALM}.quickbase.com`,
154
+ Authorization: `QB-USER-TOKEN ${QB_USER_TOKEN}`,
155
+ "Content-Type": "application/json",
156
+ }),
157
+ })
158
+ );
159
+ });
160
+ });
@@ -1,4 +1,33 @@
1
- // tests/unit/index.ts
1
+ // tests/vitest/unit/index.ts
2
+ // Apps
3
+ export * from "./apps/copyApp.test.ts";
4
+ export * from "./apps/createApp.test.ts";
5
+ export * from "./apps/deleteApp.test.ts";
2
6
  export * from "./apps/getApp.test.ts";
7
+
8
+ // Auth
9
+ export * from "./auth/fetchTempToken401.test.ts";
10
+ export * from "./auth/getTempToken.test.ts";
11
+ export * from "./auth/retryOn401.test.ts";
12
+ export * from "./auth/two401s.test.ts";
13
+
14
+ // Fields
3
15
  export * from "./fields/getFields.test.ts";
16
+ export * from "./fields/getField.test.ts";
17
+ export * from "./fields/createField.test.ts";
18
+ export * from "./fields/deleteFields.test.ts";
19
+ export * from "./fields/getFieldsUsage.test.ts";
20
+ export * from "./fields/getFieldUsage.test.ts";
21
+
22
+ // Records
23
+ export * from "./records/deleteRecords.test.ts";
24
+ export * from "./records/runQuery.test.ts";
25
+ export * from "./records/upsert.test.ts";
26
+
27
+ // Tables
28
+ export * from "./tables/createTable.test.ts";
29
+ export * from "./tables/deleteTable.test.ts";
4
30
  export * from "./tables/getAppTables.test.ts";
31
+ export * from "./tables/getRelationships.test.ts";
32
+ export * from "./tables/getTable.test.ts";
33
+ export * from "./tables/updateTable.test.ts";
@@ -0,0 +1,8 @@
1
+ // tests/vitest/unit/umd.test.ts
2
+ import { test, expect } from "vitest";
3
+ const quickbaseUMD = require("../../dist/umd/quickbase.umd.js");
4
+ const { quickbase: quickbaseESM } = await import("../../dist/esm/quickbase.js");
5
+ test("UMD and ESM builds work in Node.js", () => {
6
+ expect(quickbaseUMD).toBeDefined();
7
+ expect(quickbaseESM).toBeDefined();
8
+ });