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
@@ -1,18 +0,0 @@
1
- // src/code-generation/definitions/index.ts
2
- import { appsDefinitions } from "./apps.ts";
3
- import { authDefinitions } from "./auth.ts";
4
- import { fieldsDefinitions } from "./fields.ts";
5
- import { recordsDefinitions } from "./records.ts";
6
- import { relationshipsDefinitions } from "./relationships.ts";
7
- import { reportsDefinitions } from "./reports.ts";
8
- import { tablesDefinitions } from "./tables.ts";
9
-
10
- export const definitions = {
11
- ...appsDefinitions,
12
- ...authDefinitions,
13
- ...fieldsDefinitions,
14
- ...recordsDefinitions,
15
- ...relationshipsDefinitions,
16
- ...reportsDefinitions,
17
- ...tablesDefinitions,
18
- };
@@ -1,269 +0,0 @@
1
- // src/code-generation/definitions/records.ts
2
- export const recordsDefinitions = {
3
- Record: {
4
- type: "object",
5
- properties: {
6
- _dummy: {
7
- type: "string",
8
- description: "Unused dummy property to force model generation.",
9
- nullable: true,
10
- },
11
- },
12
- additionalProperties: {
13
- type: "object",
14
- properties: {
15
- value: {
16
- anyOf: [
17
- { type: "string" },
18
- { type: "number" },
19
- { type: "boolean" },
20
- { type: "object" },
21
- { type: "array" },
22
- { type: "null" },
23
- ],
24
- description: "The value of the field.",
25
- },
26
- },
27
- required: ["value"],
28
- description: "The value object for a field ID key.",
29
- },
30
- description:
31
- "A record with field ID keys (e.g., '6') and value objects (e.g., { value: 'data' }).",
32
- },
33
- UpsertRequest: {
34
- type: "object",
35
- required: ["to"],
36
- properties: {
37
- to: { type: "string", description: "The table identifier (dbid)." },
38
- data: {
39
- type: "array",
40
- items: { $ref: "#/definitions/Record" },
41
- description: "Array of records to upsert.",
42
- },
43
- mergeFieldId: {
44
- type: "integer",
45
- description: "The field ID to merge on (optional).",
46
- },
47
- fieldsToReturn: {
48
- type: "array",
49
- items: { type: "integer" },
50
- description: "Field IDs to return in the response (optional).",
51
- },
52
- },
53
- },
54
- Upsert200Response: {
55
- type: "object",
56
- properties: {
57
- data: {
58
- type: "array",
59
- items: {
60
- type: "object",
61
- additionalProperties: {
62
- type: "object",
63
- properties: {
64
- value: {
65
- anyOf: [
66
- { type: "string" },
67
- { type: "number" },
68
- { type: "boolean" },
69
- { type: "object" },
70
- { type: "array" },
71
- { type: "null" },
72
- ],
73
- description: "The value of the field.",
74
- },
75
- },
76
- required: ["value"],
77
- },
78
- },
79
- description: "Array of upserted records with field IDs and values.",
80
- },
81
- metadata: {
82
- type: "object",
83
- properties: {
84
- createdRecordIds: {
85
- type: "array",
86
- items: { type: "integer" },
87
- description: "IDs of newly created records.",
88
- },
89
- updatedRecordIds: {
90
- type: "array",
91
- items: { type: "integer" },
92
- description: "IDs of updated records.",
93
- },
94
- unchangedRecordIds: {
95
- type: "array",
96
- items: { type: "integer" },
97
- description: "IDs of unchanged records.",
98
- },
99
- totalNumberOfRecordsProcessed: {
100
- type: "integer",
101
- description: "Total records processed.",
102
- },
103
- },
104
- required: ["totalNumberOfRecordsProcessed"],
105
- },
106
- },
107
- },
108
- Upsert207Response: {
109
- type: "object",
110
- properties: {
111
- data: {
112
- type: "array",
113
- items: {
114
- type: "object",
115
- additionalProperties: {
116
- type: "object",
117
- properties: {
118
- value: {
119
- anyOf: [
120
- { type: "string" },
121
- { type: "number" },
122
- { type: "boolean" },
123
- { type: "object" },
124
- { type: "array" },
125
- { type: "null" },
126
- ],
127
- description: "The value of the field.",
128
- },
129
- },
130
- required: ["value"],
131
- },
132
- },
133
- description: "Array of successfully upserted records (may be empty).",
134
- },
135
- metadata: {
136
- type: "object",
137
- properties: {
138
- createdRecordIds: { type: "array", items: { type: "integer" } },
139
- updatedRecordIds: { type: "array", items: { type: "integer" } },
140
- unchangedRecordIds: { type: "array", items: { type: "integer" } },
141
- lineErrors: {
142
- type: "object",
143
- additionalProperties: { type: "array", items: { type: "string" } },
144
- description: "Errors by line number (1-based index).",
145
- },
146
- totalNumberOfRecordsProcessed: { type: "integer" },
147
- },
148
- required: ["totalNumberOfRecordsProcessed"],
149
- },
150
- },
151
- },
152
- DeleteRecordsRequest: {
153
- type: "object",
154
- required: ["from", "where"],
155
- properties: {
156
- from: {
157
- type: "string",
158
- description:
159
- "The table identifier (dbid) from which to delete records.",
160
- },
161
- where: {
162
- type: "string",
163
- description:
164
- "A QuickBase query string specifying which records to delete.",
165
- },
166
- },
167
- description:
168
- "Request body for deleting records from a table using a query.",
169
- },
170
- DeleteRecords200Response: {
171
- type: "object",
172
- properties: {
173
- numberDeleted: {
174
- type: "integer",
175
- description: "The number of records successfully deleted.",
176
- },
177
- },
178
- required: ["numberDeleted"],
179
- description: "Response body for successful deletion of records.",
180
- },
181
- RunQueryRequest: {
182
- type: "object",
183
- required: ["from"],
184
- properties: {
185
- from: { type: "string", description: "Table ID (dbid)" },
186
- select: {
187
- type: "array",
188
- items: { type: "integer" },
189
- description: "Field IDs to return",
190
- },
191
- where: { type: "string", description: "Query string" },
192
- sortBy: {
193
- type: "array",
194
- items: {
195
- type: "object",
196
- properties: {
197
- fieldId: { type: "integer" },
198
- order: { type: "string", enum: ["ASC", "DESC"] },
199
- },
200
- },
201
- description: "Sort criteria",
202
- },
203
- groupBy: {
204
- type: "array",
205
- items: {
206
- type: "object",
207
- properties: {
208
- fieldId: { type: "integer" },
209
- grouping: { type: "string", enum: ["equal-values"] },
210
- },
211
- },
212
- description: "Grouping criteria",
213
- },
214
- options: {
215
- type: "object",
216
- properties: {
217
- skip: { type: "integer", description: "Number of records to skip" },
218
- top: {
219
- type: "integer",
220
- description: "Max number of records to return",
221
- },
222
- compareWithAppLocalTime: {
223
- type: "boolean",
224
- description: "Compare times with app local time",
225
- },
226
- },
227
- },
228
- },
229
- },
230
- RunQueryResponse: {
231
- type: "object",
232
- properties: {
233
- data: {
234
- type: "array",
235
- items: {
236
- type: "object",
237
- additionalProperties: {
238
- type: "object",
239
- properties: { value: { type: "any" } },
240
- },
241
- },
242
- description: "Array of record data with field IDs as keys",
243
- },
244
- fields: {
245
- type: "array",
246
- items: {
247
- type: "object",
248
- properties: {
249
- id: { type: "integer" },
250
- label: { type: "string" },
251
- type: { type: "string" },
252
- },
253
- },
254
- description: "Field metadata",
255
- },
256
- metadata: {
257
- type: "object",
258
- properties: {
259
- numFields: { type: "integer" },
260
- numRecords: { type: "integer" },
261
- skip: { type: "integer" },
262
- top: { type: "integer" },
263
- totalRecords: { type: "integer" },
264
- },
265
- description: "Query metadata",
266
- },
267
- },
268
- },
269
- };
@@ -1,90 +0,0 @@
1
- // src/code-generation/definitions/relationships.ts
2
- export const relationshipsDefinitions = {
3
- GetRelationships200Response: {
4
- type: "object",
5
- properties: {
6
- metadata: {
7
- type: "object",
8
- properties: {
9
- numRelationships: {
10
- type: "integer",
11
- description:
12
- "The number of relationships in the current response object.",
13
- },
14
- skip: {
15
- type: "integer",
16
- description: "The number of relationships skipped.",
17
- },
18
- totalRelationships: {
19
- type: "integer",
20
- description: "The total number of relationships.",
21
- },
22
- },
23
- required: ["numRelationships", "skip", "totalRelationships"],
24
- description:
25
- "Additional information about the results that may be helpful.",
26
- },
27
- relationships: {
28
- type: "array",
29
- items: { $ref: "#/definitions/Relationship" },
30
- description: "The relationships in a table.",
31
- },
32
- },
33
- required: ["metadata", "relationships"],
34
- description: "Response containing relationships for a table.",
35
- },
36
- Relationship: {
37
- type: "object",
38
- properties: {
39
- id: {
40
- type: "integer",
41
- description: "The relationship id (foreign key field id).",
42
- },
43
- parentTableId: {
44
- type: "string",
45
- description: "The parent table id of the relationship.",
46
- },
47
- childTableId: {
48
- type: "string",
49
- description: "The child table id of the relationship.",
50
- },
51
- foreignKeyField: {
52
- $ref: "#/definitions/RelationshipField",
53
- description: "The foreign key field information.",
54
- },
55
- isCrossApp: {
56
- type: "boolean",
57
- description: "Whether this is a cross-app relationship.",
58
- },
59
- lookupFields: {
60
- type: "array",
61
- items: { $ref: "#/definitions/RelationshipField" },
62
- description: "The lookup fields array.",
63
- },
64
- summaryFields: {
65
- type: "array",
66
- items: { $ref: "#/definitions/RelationshipField" },
67
- description: "The summary fields array.",
68
- },
69
- },
70
- required: [
71
- "id",
72
- "parentTableId",
73
- "childTableId",
74
- "foreignKeyField",
75
- "isCrossApp",
76
- ],
77
- description: "A relationship between tables.",
78
- },
79
- RelationshipField: {
80
- type: "object",
81
- properties: {
82
- id: { type: "integer", description: "Field id." },
83
- label: { type: "string", description: "Field label." },
84
- type: { type: "string", description: "Field type." },
85
- },
86
- required: ["id", "label", "type"],
87
- description:
88
- "A field involved in a relationship (foreign key, lookup, or summary).",
89
- },
90
- };
@@ -1,10 +0,0 @@
1
- // src/code-generation/definitions/reports.ts
2
- export const reportsDefinitions = {
3
- ReportRunResponse: {
4
- type: "object",
5
- properties: {
6
- id: { type: "string" },
7
- data: { type: "object" },
8
- },
9
- },
10
- };
@@ -1,112 +0,0 @@
1
- // src/code-generation/definitions/tables.ts
2
- export const tablesDefinitions = {
3
- Table: {
4
- type: "object",
5
- required: ["id", "name"],
6
- properties: {
7
- id: {
8
- type: "string",
9
- description: "The unique identifier (dbid) of the table.",
10
- },
11
- name: { type: "string", description: "The name of the table." },
12
- alias: {
13
- type: "string",
14
- description: "The automatically-created table alias for the table.",
15
- },
16
- description: {
17
- type: "string",
18
- description:
19
- "The description of the table, as configured by an application administrator.",
20
- },
21
- created: {
22
- type: "string",
23
- format: "date-time",
24
- description:
25
- "The time and date when the table was created, in ISO 8601 format (UTC).",
26
- },
27
- updated: {
28
- type: "string",
29
- format: "date-time",
30
- description:
31
- "The time and date when the table schema or data was last updated, in ISO 8601 format (UTC).",
32
- },
33
- nextRecordId: {
34
- type: "integer",
35
- description:
36
- "The incremental Record ID that will be used when the next record is created.",
37
- },
38
- nextFieldId: {
39
- type: "integer",
40
- description:
41
- "The incremental Field ID that will be used when the next field is created.",
42
- },
43
- defaultSortFieldId: {
44
- type: "integer",
45
- description:
46
- "The id of the field that is configured for default sorting.",
47
- },
48
- defaultSortOrder: {
49
- type: "string",
50
- enum: ["ASC", "DESC"],
51
- description:
52
- "The default sort order for the table, either ascending (ASC) or descending (DESC).",
53
- },
54
- keyFieldId: {
55
- type: "integer",
56
- description:
57
- "The id of the field that is configured to be the key on this table, usually the Quickbase Record ID.",
58
- },
59
- singleRecordName: {
60
- type: "string",
61
- description: "The builder-configured singular noun of the table.",
62
- },
63
- pluralRecordName: {
64
- type: "string",
65
- description: "The builder-configured plural noun of the table.",
66
- },
67
- sizeLimit: {
68
- type: "string",
69
- description: "The size limit for the table (e.g., '150 MB').",
70
- },
71
- spaceUsed: {
72
- type: "string",
73
- description:
74
- "The amount of space currently being used by the table (e.g., '17 MB').",
75
- },
76
- spaceRemaining: {
77
- type: "string",
78
- description:
79
- "The amount of space remaining for use by the table (e.g., '133 MB').",
80
- },
81
- },
82
- },
83
- UpdateTableRequest: {
84
- type: "object",
85
- properties: {
86
- name: { type: "string", description: "The new name for the table." },
87
- singleRecordName: {
88
- type: "string",
89
- description:
90
- "The new singular noun for records in the table. Defaults to 'Record' if not provided.",
91
- },
92
- pluralRecordName: {
93
- type: "string",
94
- description:
95
- "The new plural noun for records in the table. Defaults to 'Records' if not provided.",
96
- },
97
- description: {
98
- type: "string",
99
- description:
100
- "The new description for the table. Defaults to blank if not provided.",
101
- },
102
- },
103
- description:
104
- "Request body for updating table properties. At least one property must be provided.",
105
- },
106
- DeleteTableResponse: {
107
- type: "object",
108
- properties: {
109
- deletedTableId: { type: "string", description: "The deleted table id." },
110
- },
111
- },
112
- };
@@ -1,176 +0,0 @@
1
- #!/usr/bin/env node
2
- import { promises as fs } from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
- import * as glob from "glob";
6
- import { paths } from "./paths/index.ts";
7
- import { definitions } from "./definitions/index.ts";
8
-
9
- interface Parameter {
10
- name: string;
11
- in: string;
12
- required?: boolean;
13
- type?: string;
14
- schema?: { type?: string; items?: any; $ref?: string; properties?: any };
15
- example?: any;
16
- }
17
-
18
- interface Operation {
19
- parameters?: Parameter[];
20
- responses?: Record<string, { description: string; schema?: any }>;
21
- operationId?: string;
22
- summary?: string;
23
- tags?: string[];
24
- }
25
-
26
- interface Spec {
27
- paths: Record<string, Record<string, Operation>>;
28
- definitions?: Record<string, any>;
29
- operations?: any;
30
- groups?: any;
31
- components?: any;
32
- }
33
-
34
- function toCamelCase(str: string): string {
35
- return str
36
- .replace(/[-_](.)/g, (_, char) => char.toUpperCase())
37
- .replace(/^./, (str) => str.toLowerCase());
38
- }
39
-
40
- function fixArraySchemas(spec: Spec) {
41
- for (const pathKey in spec.paths) {
42
- for (const method in spec.paths[pathKey]) {
43
- const operation = spec.paths[pathKey][method];
44
- if (operation.parameters) {
45
- operation.parameters.forEach((param: Parameter) => {
46
- if (param.schema) {
47
- if (param.schema.type === "array" && !param.schema.items) {
48
- console.log(
49
- `Fixing missing items in ${pathKey}(${method}).${param.name}`
50
- );
51
- param.schema.items =
52
- pathKey === "/records" && param.name === "generated"
53
- ? { $ref: "#/definitions/Record" }
54
- : { type: "string" };
55
- }
56
- if (param.schema.properties) {
57
- for (const propKey in param.schema.properties) {
58
- const prop = param.schema.properties[propKey];
59
- if (prop.type === "array" && !prop.items) {
60
- console.log(
61
- `Fixing nested array in ${pathKey}(${method}).${param.name}.${propKey}`
62
- );
63
- prop.items =
64
- propKey === "data" && pathKey === "/records"
65
- ? { $ref: "#/definitions/Record" }
66
- : { type: "string" };
67
- }
68
- }
69
- }
70
- }
71
- });
72
- }
73
- if (operation.responses) {
74
- for (const status in operation.responses) {
75
- const response = operation.responses[status];
76
- if (response.schema) {
77
- if (response.schema.type === "array" && !response.schema.items) {
78
- console.log(
79
- `Fixing missing items in ${pathKey}(${method}).responses.${status}`
80
- );
81
- response.schema.items =
82
- pathKey === "/records"
83
- ? { $ref: "#/definitions/Upsert200Response" }
84
- : { type: "string" };
85
- }
86
- if (response.schema.properties) {
87
- for (const propKey in response.schema.properties) {
88
- const prop = response.schema.properties[propKey];
89
- if (prop.type === "array" && !prop.items) {
90
- console.log(
91
- `Fixing nested array in ${pathKey}(${method}).responses.${status}.${propKey}`
92
- );
93
- prop.items =
94
- propKey === "data" && pathKey === "/records"
95
- ? { $ref: "#/definitions/Upsert200Response" }
96
- : { type: "string" };
97
- }
98
- }
99
- }
100
- }
101
- }
102
- }
103
- }
104
- }
105
- }
106
-
107
- async function fixQuickBaseSpec(): Promise<void> {
108
- try {
109
- const CODEGEN_DIR = path.dirname(fileURLToPath(import.meta.url));
110
- const SPECS_DIR = path.join(CODEGEN_DIR, "..", "specs");
111
- const OUTPUT_DIR = path.join(CODEGEN_DIR, "output");
112
- console.log("Finding latest QuickBase RESTful API spec...");
113
- const specFiles = glob.sync(
114
- path.join(SPECS_DIR, "QuickBase_RESTful_*.json")
115
- );
116
- if (specFiles.length === 0) {
117
- console.error(
118
- "No QuickBase_RESTful_*.json files found in specs/ folder."
119
- );
120
- process.exit(1);
121
- }
122
- const inputFile = specFiles.sort().pop() as string;
123
- const outputFile = path.join(OUTPUT_DIR, "quickbase-fixed.json");
124
-
125
- console.log(`Reading ${path.basename(inputFile)} from specs/...`);
126
- const specContent = await fs.readFile(inputFile, "utf8");
127
- const spec: Spec = JSON.parse(specContent);
128
-
129
- console.log("Fixing parameters...");
130
- for (const pathKey in spec.paths) {
131
- for (const method in spec.paths[pathKey]) {
132
- const operation = spec.paths[pathKey][method];
133
- if (operation.parameters) {
134
- operation.parameters = operation.parameters
135
- .filter(
136
- (param) =>
137
- !["QB-Realm-Hostname", "Authorization", "User-Agent"].includes(
138
- param.name
139
- )
140
- )
141
- .map((param: Parameter) => {
142
- param.name = toCamelCase(param.name);
143
- if ("example" in param) delete param.example;
144
- if ("schema" in param && param.in !== "body") delete param.schema;
145
- if (!param.type && param.in !== "body") param.type = "string";
146
- return param;
147
- });
148
- }
149
- }
150
- }
151
-
152
- console.log("Applying endpoint fixes...");
153
- spec.paths = { ...spec.paths, ...paths }; // Merge original and custom paths
154
-
155
- console.log("Fixing array schemas...");
156
- fixArraySchemas(spec);
157
-
158
- console.log("Applying definitions...");
159
- spec.definitions = { ...spec.definitions, ...definitions }; // Merge definitions
160
-
161
- console.log("Removing unexpected top-level attributes...");
162
- delete spec.operations;
163
- delete spec.groups;
164
- delete spec.components;
165
-
166
- console.log(`Writing fixed spec to ${path.basename(outputFile)}...`);
167
- await fs.mkdir(OUTPUT_DIR, { recursive: true });
168
- await fs.writeFile(outputFile, JSON.stringify(spec, null, 2), "utf8");
169
- console.log("Spec fixed successfully! Output written to:", outputFile);
170
- } catch (error) {
171
- console.error("Failed to fix spec:", error);
172
- process.exit(1);
173
- }
174
- }
175
-
176
- fixQuickBaseSpec();