quickbase-js 0.1.0-beta.7 → 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 (82) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +46 -130
  3. package/dist/esm/quickbase.d.ts +1292 -125
  4. package/dist/esm/quickbase.js +666 -190
  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 +674 -189
  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/fix-spec-main.ts +69 -68
  13. package/open-api/generate-override-report.ts +214 -0
  14. package/open-api/generate-unified-interface.ts +162 -103
  15. package/open-api/output/override-report.html +11 -0
  16. package/open-api/output/override-report.json +14395 -58
  17. package/open-api/output/quickbase-fixed.json +583 -2
  18. package/open-api/schema/tags/fields.ts +331 -16
  19. package/open-api/schema/tags/index.ts +2 -4
  20. package/open-api/types/spec.ts +2 -1
  21. package/open-api/utils/generateJsDoc.ts +96 -0
  22. package/package.json +33 -33
  23. package/src/RateLimitError.ts +12 -0
  24. package/src/ThrottleBucket.ts +41 -0
  25. package/src/authorizationStrategy.ts +246 -0
  26. package/src/generated-unified/QuickbaseClient.ts +809 -119
  27. package/src/invokeMethod.ts +242 -0
  28. package/src/quickbaseClient.ts +117 -248
  29. package/src/rateLimiter.ts +25 -0
  30. package/src/tokenCache.ts +10 -26
  31. package/tests/setup.ts +2 -0
  32. package/tests/vitest/qb/apps/getApp.test.ts +6 -2
  33. package/tests/vitest/qb/apps/getAppEvents.test.ts +67 -0
  34. package/tests/vitest/qb/apps/updateApp.test.ts +58 -0
  35. package/tests/vitest/qb/auth/mockQuickbaseServer.ts +60 -0
  36. package/tests/vitest/qb/auth/retryUserToken401.test.ts +73 -0
  37. package/tests/vitest/qb/auth/ssoTokenIntegrationWithServer.test.ts +65 -0
  38. package/tests/vitest/qb/fields/createField.test.ts +1 -2
  39. package/tests/vitest/qb/fields/deleteFields.test.ts +10 -16
  40. package/tests/vitest/qb/fields/getFieldUsage.test.ts +58 -150
  41. package/tests/vitest/qb/fields/updateField.test.ts +93 -0
  42. package/tests/vitest/qb/formulas/runFormula.test.ts +96 -0
  43. package/tests/vitest/qb/index.ts +1 -0
  44. package/tests/vitest/qb/tables/createRelationship.test.ts +102 -0
  45. package/tests/vitest/qb/tables/deleteRelationship.test.ts +143 -0
  46. package/tests/vitest/qb/tables/updateRelationship.test.ts +250 -0
  47. package/tests/vitest/unit/ThrottleBucket.test.ts +95 -0
  48. package/tests/vitest/unit/apps/copyApp.test.ts +133 -40
  49. package/tests/vitest/unit/apps/getAppEvents.test.ts +193 -0
  50. package/tests/vitest/unit/apps/updateApp.test.ts +412 -0
  51. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +7 -26
  52. package/tests/vitest/unit/auth/getTempToken.test.ts +42 -18
  53. package/tests/vitest/unit/auth/retryTempToken401.test.ts +95 -0
  54. package/tests/vitest/unit/auth/retryTempTokenMaxRetries.test.ts +235 -0
  55. package/tests/vitest/unit/auth/retryUserToken401.test.ts +69 -0
  56. package/tests/vitest/unit/auth/ssoTokenRefresh.test.ts +325 -0
  57. package/tests/vitest/unit/fields/createField.test.ts +180 -120
  58. package/tests/vitest/unit/fields/getFieldUsage.test.ts +47 -14
  59. package/tests/vitest/unit/fields/updateField.test.ts +285 -0
  60. package/tests/vitest/unit/formulas/runFormula.test.ts +205 -0
  61. package/tests/vitest/unit/index.ts +2 -1
  62. package/tests/vitest/unit/inferHttpMethod.test.ts +131 -0
  63. package/tests/vitest/unit/rateLimit.test.ts +191 -0
  64. package/tests/vitest/unit/tables/createRelationship.test.ts +212 -0
  65. package/tests/vitest/unit/tables/deleteRelationship.test.ts +97 -0
  66. package/tests/vitest/unit/tables/updateRelationship.test.ts +307 -0
  67. package/tests/vitest/unit/tokenLifespan.test.ts +204 -0
  68. package/tools/log-gen.ts +20 -7
  69. package/tools/log-gen.yaml +3446 -1848
  70. package/tsconfig.json +5 -2
  71. package/vitest.config.ts +2 -2
  72. package/notes.txt +0 -158
  73. package/tests/vitest/unit/auth/retryOn401.test.ts +0 -116
  74. package/tests/vitest/unit/auth/two401s.test.ts +0 -86
  75. package/tools/generate-types.ts +0 -29
  76. package/tools/openapi-schema-validator.ts +0 -38
  77. package/tools/spec-analyzer.ts +0 -163
  78. package/tools/split-spec.ts +0 -148
  79. package/tools/test-import.ts +0 -3
  80. package/tools/validate-spec.ts +0 -40
  81. /package/tests/playwright/qb/auth/{tokenPrefetch.test.ts → tempTokenPrefetch.test.ts} +0 -0
  82. /package/tests/playwright/qb/auth/{tokenRenewal.test.ts → tempTokenRenewal.test.ts} +0 -0
@@ -1,148 +0,0 @@
1
- // tools/split-spec.ts
2
- import { promises as fs } from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
- import * as glob from "glob";
6
-
7
- interface Parameter {
8
- name: string;
9
- in: string;
10
- required?: boolean;
11
- type?: string;
12
- schema?: any;
13
- example?: any;
14
- description?: string;
15
- }
16
-
17
- interface Operation {
18
- parameters?: Parameter[];
19
- }
20
-
21
- interface Spec {
22
- swagger?: string;
23
- openapi?: string;
24
- info: any;
25
- paths: Record<string, Record<string, Operation>>;
26
- definitions?: Record<string, any>;
27
- }
28
-
29
- function normalizeParameters(parameters: Parameter[] = []): Parameter[] {
30
- return parameters.map((param) => {
31
- const normalized: Parameter = {
32
- name: param.name,
33
- in: param.in,
34
- required: param.required,
35
- description: param.description,
36
- };
37
-
38
- // OpenAPI v2: 'body' parameters use 'schema', others use 'type'
39
- if (param.in === "body") {
40
- if (param.schema) {
41
- normalized.schema = param.schema;
42
- }
43
- } else {
44
- normalized.type = param.type || "string";
45
- if (param.example !== undefined) {
46
- delete param.example; // Remove 'example' as it’s not allowed in v2
47
- }
48
- }
49
-
50
- // Ensure 'in' is valid
51
- if (
52
- !["query", "header", "path", "formData", "body"].includes(normalized.in)
53
- ) {
54
- console.warn(
55
- `Invalid 'in' value '${normalized.in}' for parameter '${normalized.name}', defaulting to 'query'`
56
- );
57
- normalized.in = "query";
58
- }
59
-
60
- return normalized;
61
- });
62
- }
63
-
64
- async function splitSpec(): Promise<void> {
65
- const CODEGEN_DIR = path.dirname(fileURLToPath(import.meta.url));
66
- const SPECS_DIR = path.join(CODEGEN_DIR, "..", "specs");
67
- const OUTPUT_DIR = path.join(SPECS_DIR, "split");
68
-
69
- // Find the latest spec file
70
- const specFiles = glob.sync(path.join(SPECS_DIR, "QuickBase_RESTful_*.json"));
71
- if (specFiles.length === 0) {
72
- console.error("No QuickBase_RESTful_*.json files found in specs/ folder.");
73
- process.exit(1);
74
- }
75
- const inputFile = specFiles.sort().pop() as string;
76
- const specContent = await fs.readFile(inputFile, "utf8");
77
- const spec: Spec = JSON.parse(specContent);
78
-
79
- // Define categories based on endpoint paths
80
- const categories: Record<string, string[]> = {
81
- apps: Object.keys(spec.paths).filter((p) => p.startsWith("/apps")),
82
- auth: Object.keys(spec.paths).filter((p) => p.startsWith("/auth")),
83
- fields: Object.keys(spec.paths).filter((p) => p.startsWith("/fields")),
84
- records: Object.keys(spec.paths).filter((p) => p.startsWith("/records")),
85
- tables: Object.keys(spec.paths).filter((p) => p.startsWith("/tables")),
86
- reports: Object.keys(spec.paths).filter((p) => p.startsWith("/reports")),
87
- relationships: Object.keys(spec.paths).filter((p) =>
88
- p.startsWith("/relationships")
89
- ),
90
- events: Object.keys(spec.paths).filter((p) => p.startsWith("/events")),
91
- };
92
-
93
- await fs.mkdir(OUTPUT_DIR, { recursive: true });
94
-
95
- // Split spec by category
96
- for (const [category, paths] of Object.entries(categories)) {
97
- if (paths.length === 0) continue;
98
-
99
- const categorySpec: Spec = {
100
- swagger: "2.0", // OpenAPI v2
101
- info: spec.info || { title: `${category} API`, version: "1.0.0" },
102
- paths: {},
103
- definitions: {},
104
- };
105
-
106
- // Add relevant paths and normalize parameters
107
- for (const p of paths) {
108
- const pathObj = { ...spec.paths[p] };
109
- for (const method in pathObj) {
110
- if (pathObj[method].parameters) {
111
- pathObj[method].parameters = normalizeParameters(
112
- pathObj[method].parameters
113
- );
114
- }
115
- }
116
- categorySpec.paths[p] = pathObj;
117
- }
118
-
119
- // Add relevant definitions
120
- const refs = new Set<string>();
121
- const refRegex = /#\/definitions\/([^"]+)/g;
122
- const categorySpecString = JSON.stringify(categorySpec);
123
- let match;
124
- while ((match = refRegex.exec(categorySpecString))) {
125
- refs.add(match[1]);
126
- }
127
- if (spec.definitions) {
128
- for (const ref of refs) {
129
- if (spec.definitions[ref]) {
130
- categorySpec.definitions![ref] = spec.definitions[ref];
131
- }
132
- }
133
- }
134
-
135
- const outputFile = path.join(OUTPUT_DIR, `${category}.json`);
136
- await fs.writeFile(
137
- outputFile,
138
- JSON.stringify(categorySpec, null, 2),
139
- "utf8"
140
- );
141
- console.log(`Wrote ${outputFile}`);
142
- }
143
- }
144
-
145
- splitSpec().catch((error) => {
146
- console.error("Failed to split spec:", error);
147
- process.exit(1);
148
- });
@@ -1,3 +0,0 @@
1
- // tools/test-import.ts
2
- import OpenAPISchemaValidator from "openapi-schema-validator";
3
- console.log(OpenAPISchemaValidator);
@@ -1,40 +0,0 @@
1
- // tools/validate-spec.ts
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 OpenAPISchemaValidatorModule from "openapi-schema-validator";
7
-
8
- const OpenAPISchemaValidator = OpenAPISchemaValidatorModule.default;
9
-
10
- async function validateSpecs(): Promise<void> {
11
- const CODEGEN_DIR = path.dirname(fileURLToPath(import.meta.url));
12
- const SPLIT_DIR = path.join(CODEGEN_DIR, "..", "specs", "split");
13
-
14
- const specFiles = glob.sync(path.join(SPLIT_DIR, "*.json"));
15
- if (specFiles.length === 0) {
16
- console.error("No split spec files found in specs/split/ folder.");
17
- process.exit(1);
18
- }
19
-
20
- const validator = new OpenAPISchemaValidator({ version: 2 });
21
-
22
- for (const specFile of specFiles) {
23
- console.log(`Validating ${path.basename(specFile)}...`);
24
- const specContent = await fs.readFile(specFile, "utf8");
25
- const spec = JSON.parse(specContent);
26
-
27
- const result = validator.validate(spec);
28
- if (result.errors.length > 0) {
29
- console.error(`Validation errors in ${specFile}:`, result.errors);
30
- process.exit(1);
31
- } else {
32
- console.log(`${specFile} is valid.`);
33
- }
34
- }
35
- }
36
-
37
- validateSpecs().catch((error) => {
38
- console.error("Failed to validate specs:", error);
39
- process.exit(1);
40
- });