quickbase-js 0.1.0-beta.7

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 (123) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/LICENSE +21 -0
  3. package/README.md +204 -0
  4. package/build-common.js +131 -0
  5. package/build-esm.js +71 -0
  6. package/build-umd.js +69 -0
  7. package/dist/esm/quickbase.d.ts +7594 -0
  8. package/dist/esm/quickbase.js +9752 -0
  9. package/dist/esm/quickbase.js.map +1 -0
  10. package/dist/esm/quickbase.min.js +2 -0
  11. package/dist/esm/quickbase.min.js.map +1 -0
  12. package/dist/umd/quickbase.umd.js +10502 -0
  13. package/dist/umd/quickbase.umd.js.map +1 -0
  14. package/dist/umd/quickbase.umd.min.js +2 -0
  15. package/dist/umd/quickbase.umd.min.js.map +1 -0
  16. package/examples/quicbase-jsCDN.html +36 -0
  17. package/examples/react.js +48 -0
  18. package/examples/vanillajs.html +47 -0
  19. package/notes.txt +158 -0
  20. package/open-api/fix-spec-main.ts +96 -0
  21. package/open-api/generate-unified-interface.ts +277 -0
  22. package/open-api/output/override-report.json +58 -0
  23. package/open-api/output/quickbase-fixed.json +10610 -0
  24. package/open-api/regenerate-client.ts +116 -0
  25. package/open-api/schema/enhance-general.ts +100 -0
  26. package/open-api/schema/fix-arrays.ts +69 -0
  27. package/open-api/schema/tags/apps.ts +90 -0
  28. package/open-api/schema/tags/fields.ts +156 -0
  29. package/open-api/schema/tags/groups.ts +51 -0
  30. package/open-api/schema/tags/index.ts +68 -0
  31. package/open-api/schema/tags/records.ts +115 -0
  32. package/open-api/schema/tags/tables.ts +211 -0
  33. package/open-api/schema/tags/users.ts +47 -0
  34. package/open-api/types/spec.ts +41 -0
  35. package/open-api/utils/infer-schema.ts +40 -0
  36. package/open-api/utils/naming.ts +10 -0
  37. package/package.json +91 -0
  38. package/playwright.config.ts +37 -0
  39. package/rollup.config.js +114 -0
  40. package/specs/QuickBase_RESTful_API_2025-03-04T06_22_39.725Z.json +46878 -0
  41. package/specs/split/apps.json +1315 -0
  42. package/specs/split/auth.json +191 -0
  43. package/specs/split/fields.json +3869 -0
  44. package/specs/split/records.json +754 -0
  45. package/specs/split/reports.json +619 -0
  46. package/specs/split/tables.json +1605 -0
  47. package/src/generated-unified/QuickbaseClient.ts +359 -0
  48. package/src/generated-unified/missing-types-report.json +3 -0
  49. package/src/index.ts +1 -0
  50. package/src/quickbaseClient.ts +402 -0
  51. package/src/tokenCache.ts +51 -0
  52. package/src/utils.ts +7 -0
  53. package/test-esm.js +1 -0
  54. package/test-results.json +2050 -0
  55. package/test-umd.js +1 -0
  56. package/test.ts +1 -0
  57. package/tests/playwright/qb/auth/cacheSwitching.test.ts +159 -0
  58. package/tests/playwright/qb/auth/fetchTempToken401.test.ts +219 -0
  59. package/tests/playwright/qb/auth/getAppWithTempToken.test.ts +162 -0
  60. package/tests/playwright/qb/auth/getAppWithUserToken.test.ts +153 -0
  61. package/tests/playwright/qb/auth/getTempToken.test.ts +152 -0
  62. package/tests/playwright/qb/auth/tokenPrefetch.test.ts +179 -0
  63. package/tests/playwright/qb/auth/tokenRenewal.test.ts +133 -0
  64. package/tests/setup.ts +51 -0
  65. package/tests/vitest/qb/apps/copyApp.test.ts +76 -0
  66. package/tests/vitest/qb/apps/createApp.test.ts +64 -0
  67. package/tests/vitest/qb/apps/deleteApp.test.ts +76 -0
  68. package/tests/vitest/qb/apps/getApp.test.ts +40 -0
  69. package/tests/vitest/qb/fields/createField.test.ts +78 -0
  70. package/tests/vitest/qb/fields/deleteFields.test.ts +89 -0
  71. package/tests/vitest/qb/fields/getField.test.ts +85 -0
  72. package/tests/vitest/qb/fields/getFieldUsage.test.ts +174 -0
  73. package/tests/vitest/qb/fields/getFields.test.ts +232 -0
  74. package/tests/vitest/qb/fields/getFieldsUsage.test.ts +77 -0
  75. package/tests/vitest/qb/index.ts +28 -0
  76. package/tests/vitest/qb/records/deleteRecords.test.ts +110 -0
  77. package/tests/vitest/qb/records/runQuery.test.ts +146 -0
  78. package/tests/vitest/qb/records/upsert.test.ts +102 -0
  79. package/tests/vitest/qb/tables/createTable.test.ts +55 -0
  80. package/tests/vitest/qb/tables/deleteTable.test.ts +50 -0
  81. package/tests/vitest/qb/tables/getAppTables.test.ts +46 -0
  82. package/tests/vitest/qb/tables/getRelationships.test.ts +80 -0
  83. package/tests/vitest/qb/tables/getTable.test.ts +26 -0
  84. package/tests/vitest/qb/tables/updateTable.test.ts +48 -0
  85. package/tests/vitest/unit/apps/copyApp.test.ts +488 -0
  86. package/tests/vitest/unit/apps/createApp.test.ts +186 -0
  87. package/tests/vitest/unit/apps/deleteApp.test.ts +216 -0
  88. package/tests/vitest/unit/apps/getApp.test.ts +128 -0
  89. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +82 -0
  90. package/tests/vitest/unit/auth/getTempToken.test.ts +95 -0
  91. package/tests/vitest/unit/auth/retryOn401.test.ts +116 -0
  92. package/tests/vitest/unit/auth/two401s.test.ts +86 -0
  93. package/tests/vitest/unit/fields/createField.test.ts +391 -0
  94. package/tests/vitest/unit/fields/deleteFields.test.ts +141 -0
  95. package/tests/vitest/unit/fields/getField.test.ts +189 -0
  96. package/tests/vitest/unit/fields/getFieldUsage.test.ts +147 -0
  97. package/tests/vitest/unit/fields/getFields.test.ts +122 -0
  98. package/tests/vitest/unit/fields/getFieldsUsage.test.ts +160 -0
  99. package/tests/vitest/unit/index.ts +33 -0
  100. package/tests/vitest/unit/records/deleteRecords.test.ts +112 -0
  101. package/tests/vitest/unit/records/runQuery.test.ts +102 -0
  102. package/tests/vitest/unit/records/upsert.test.ts +234 -0
  103. package/tests/vitest/unit/tables/createTable.test.ts +70 -0
  104. package/tests/vitest/unit/tables/deleteTable.test.ts +77 -0
  105. package/tests/vitest/unit/tables/getAppTables.test.ts +85 -0
  106. package/tests/vitest/unit/tables/getRelationships.test.ts +259 -0
  107. package/tests/vitest/unit/tables/getTable.test.ts +233 -0
  108. package/tests/vitest/unit/tables/updateTable.test.ts +80 -0
  109. package/tests/vitest/unit/umd.test.ts +8 -0
  110. package/text.txt +104 -0
  111. package/tools/generate-types.ts +29 -0
  112. package/tools/log-gen.ts +231 -0
  113. package/tools/log-gen.yaml +3826 -0
  114. package/tools/openapi-jars/openapi-generator-cli-7.12.0.jar +0 -0
  115. package/tools/openapi-schema-validator.ts +38 -0
  116. package/tools/spec-analyzer.ts +163 -0
  117. package/tools/split-spec.ts +148 -0
  118. package/tools/test-import.ts +3 -0
  119. package/tools/validate-spec.ts +40 -0
  120. package/tsconfig.build.json +17 -0
  121. package/tsconfig.json +29 -0
  122. package/versionrc.json +9 -0
  123. package/vitest.config.ts +27 -0
@@ -0,0 +1,3826 @@
1
+ project: >-
2
+ quickbase-js
3
+ date: >-
4
+ 3/16/2025
5
+ root: >-
6
+ /home/drew/Projects/quickbase-js
7
+ goals:
8
+ - >-
9
+ A
10
+ library
11
+ for
12
+ interacting
13
+ with
14
+ the
15
+ QuickBase
16
+ RESTful
17
+ API.
18
+ - >-
19
+ Use
20
+ OpenAPI
21
+ to
22
+ generate
23
+ types
24
+ and
25
+ methods
26
+ using
27
+ a
28
+ proxy.
29
+ Validate
30
+ with
31
+ tests.
32
+ - >-
33
+ Provide
34
+ robust
35
+ and
36
+ intuitive
37
+ temporary
38
+ token
39
+ support
40
+ for
41
+ browser
42
+ environments.
43
+ - >-
44
+ User
45
+ Tokens
46
+ support
47
+ both
48
+ Node.js
49
+ and
50
+ browser
51
+ environments.
52
+ - >-
53
+ Use
54
+ case:
55
+ JS
56
+ frameworks
57
+ like
58
+ React,
59
+ Vue,
60
+ and
61
+ Angular
62
+ hosted
63
+ in
64
+ QuickBase
65
+ code
66
+ pages.
67
+ - >-
68
+ Enable
69
+ a
70
+ flexible
71
+ or
72
+ native
73
+ fetch
74
+ in
75
+ the
76
+ browser.
77
+ - >-
78
+ Enable
79
+ a
80
+ flexible
81
+ fetch
82
+ framework
83
+ in
84
+ Node.js.
85
+ - >-
86
+ #
87
+ - >-
88
+ No
89
+ manual
90
+ updating
91
+ methods
92
+ when
93
+ the
94
+ QuickBase
95
+ API
96
+ changes.
97
+ - >-
98
+ The
99
+ proxy
100
+ magic
101
+ dynamically
102
+ maps
103
+ generated
104
+ methods
105
+ and
106
+ types.
107
+ - >-
108
+ #
109
+ - >-
110
+ TokenCache
111
+ is
112
+ defined
113
+ per
114
+ quickbaseClient
115
+ call,
116
+ so
117
+ each
118
+ instance
119
+ has
120
+ its
121
+ own
122
+ isolated
123
+ TokenCache.
124
+ - >-
125
+ Each
126
+ quickbase
127
+ client
128
+ instance
129
+ has
130
+ an
131
+ isolated
132
+ and
133
+ individual
134
+ token
135
+ cache.
136
+ pipelineOverview:
137
+ - >-
138
+ What
139
+ I’m
140
+ Trying
141
+ to
142
+ Do
143
+ - >-
144
+ My
145
+ approach
146
+ is
147
+ to
148
+ ensure
149
+ AppsApi.ts
150
+ is
151
+ generated
152
+ with
153
+ getAppById
154
+ so
155
+ QuickbaseClient.ts
156
+ can
157
+ map
158
+ it
159
+ to
160
+ client.getApp.
161
+ Steps
162
+ include:
163
+ - >-
164
+ Fix
165
+ fix-spec.ts:
166
+ - >-
167
+ Add
168
+ tags:
169
+ ["Apps"]
170
+ to
171
+ /apps/*
172
+ endpoints
173
+ to
174
+ group
175
+ them
176
+ into
177
+ AppsApi.ts.
178
+ - >-
179
+ Ensure
180
+ all
181
+ endpoints
182
+ and
183
+ models
184
+ are
185
+ correctly
186
+ defined
187
+ and
188
+ typed.
189
+ - >-
190
+ Debug
191
+ regenerate-client.ts:
192
+ - >-
193
+ Enhance
194
+ logging
195
+ to
196
+ catch
197
+ why
198
+ AppsApi.ts
199
+ isn’t
200
+ generated.
201
+ - >-
202
+ Test
203
+ if
204
+ getAppById
205
+ appears
206
+ in
207
+ another
208
+ file
209
+ (e.g.,
210
+ DefaultApi.ts).
211
+ - >-
212
+ Update
213
+ QuickbaseClient.ts:
214
+ - >-
215
+ Adjust
216
+ imports
217
+ to
218
+ use
219
+ the
220
+ correct
221
+ API
222
+ class
223
+ once
224
+ generated.
225
+ - >-
226
+ Test
227
+ and
228
+ Iterate:
229
+ - >-
230
+ Run
231
+ npm
232
+ run
233
+ fix-spec,
234
+ npm
235
+ run
236
+ regenerate,
237
+ and
238
+ npm
239
+ run
240
+ test
241
+ to
242
+ verify
243
+ AppsApi.ts
244
+ exists
245
+ and
246
+ test.ts
247
+ works.
248
+ - >-
249
+ The
250
+ latest
251
+ fix-spec.ts
252
+ with
253
+ tags
254
+ aims
255
+ to
256
+ force
257
+ the
258
+ generator
259
+ to
260
+ create
261
+ AppsApi.ts,
262
+ addressing
263
+ the
264
+ missing
265
+ file
266
+ issue.
267
+ - >-
268
+ Relevant
269
+ Project
270
+ Files
271
+ - >-
272
+ Here’s
273
+ a
274
+ list
275
+ of
276
+ files
277
+ that
278
+ would
279
+ help
280
+ understand
281
+ and
282
+ resolve
283
+ this
284
+ problem,
285
+ along
286
+ with
287
+ their
288
+ roles:
289
+ - >-
290
+ src/code-generation/fix-spec.ts:
291
+ - >-
292
+ Role:
293
+ Modifies
294
+ the
295
+ original
296
+ QuickBase
297
+ spec
298
+ (e.g.,
299
+ QuickBase_RESTful_*.json)
300
+ to
301
+ create
302
+ quickbase-fixed.json
303
+ with
304
+ required
305
+ endpoints
306
+ (e.g.,
307
+ /apps/{appId}).
308
+ - >-
309
+ Relevance:
310
+ Defines
311
+ the
312
+ spec
313
+ fed
314
+ to
315
+ the
316
+ generator;
317
+ errors
318
+ here
319
+ affect
320
+ generation.
321
+ - >-
322
+ src/code-generation/quickbase-fixed.json:
323
+ - >-
324
+ Role:
325
+ The
326
+ processed
327
+ OpenAPI
328
+ spec
329
+ used
330
+ by
331
+ regenerate-client.ts
332
+ to
333
+ generate
334
+ code.
335
+ - >-
336
+ Relevance:
337
+ Confirms
338
+ if
339
+ /apps/{appId}
340
+ is
341
+ correctly
342
+ structured
343
+ with
344
+ operationId:
345
+ "getAppById".
346
+ - >-
347
+ src/code-generation/regenerate-client.ts:
348
+ - >-
349
+ Role:
350
+ Runs
351
+ OpenAPI
352
+ Generator
353
+ to
354
+ produce
355
+ src/generated/
356
+ files
357
+ (APIs
358
+ and
359
+ models)
360
+ and
361
+ fixes
362
+ .ts
363
+ extensions
364
+ with
365
+ ts-morph.
366
+ - >-
367
+ Relevance:
368
+ Controls
369
+ the
370
+ generation
371
+ process;
372
+ logs
373
+ reveal
374
+ why
375
+ AppsApi.ts
376
+ is
377
+ missing.
378
+ - >-
379
+ src/generated/apis/AppsApi.ts
380
+ (if
381
+ exists):
382
+ - >-
383
+ Role:
384
+ Should
385
+ contain
386
+ getAppById
387
+ method
388
+ for
389
+ /apps/{appId}
390
+ GET.
391
+ - >-
392
+ Relevance:
393
+ Missing
394
+ file
395
+ is
396
+ the
397
+ core
398
+ issue;
399
+ its
400
+ absence
401
+ breaks
402
+ QuickbaseClient.ts.
403
+ - >-
404
+ src/generated/apis/DefaultApi.ts:
405
+ - >-
406
+ Role:
407
+ Default
408
+ API
409
+ class
410
+ for
411
+ untagged
412
+ operations.
413
+ - >-
414
+ Relevance:
415
+ Might
416
+ contain
417
+ getAppById
418
+ if
419
+ tags
420
+ are
421
+ misconfigured.
422
+ - >-
423
+ src/QuickbaseClient.ts:
424
+ - >-
425
+ Role:
426
+ Wraps
427
+ generated
428
+ API
429
+ classes
430
+ (e.g.,
431
+ AppsApi)
432
+ in
433
+ a
434
+ Proxy
435
+ for
436
+ ergonomic
437
+ calls
438
+ (e.g.,
439
+ client.getApp).
440
+ - >-
441
+ Relevance:
442
+ Fails
443
+ to
444
+ import
445
+ AppsApi.ts,
446
+ causing
447
+ the
448
+ runtime
449
+ error.
450
+ - >-
451
+ src/test.ts:
452
+ - >-
453
+ Role:
454
+ Test
455
+ script
456
+ calling
457
+ client.getApp({
458
+ appId
459
+ }).
460
+ - >-
461
+ Relevance:
462
+ Final
463
+ validation
464
+ point;
465
+ shows
466
+ if
467
+ the
468
+ fix
469
+ works.
470
+ - >-
471
+ .env.development:
472
+ - >-
473
+ Role:
474
+ Stores
475
+ QB_REALM,
476
+ QB_USER_TOKEN,
477
+ QB_APP_ID
478
+ for
479
+ API
480
+ authentication.
481
+ - >-
482
+ Relevance:
483
+ Ensures
484
+ the
485
+ API
486
+ call
487
+ has
488
+ valid
489
+ credentials
490
+ (not
491
+ the
492
+ current
493
+ issue,
494
+ but
495
+ critical
496
+ for
497
+ success).
498
+ - >-
499
+ src/specs/QuickBase_RESTful_API_2025-03-04T06_22_39.725Z.json
500
+ (or
501
+ similar):
502
+ - >-
503
+ Role:
504
+ Original
505
+ QuickBase
506
+ API
507
+ spec
508
+ before
509
+ fix-spec.ts
510
+ processing.
511
+ - >-
512
+ Relevance:
513
+ Shows
514
+ how
515
+ /apps/{appId}
516
+ was
517
+ originally
518
+ defined,
519
+ helping
520
+ identify
521
+ conflicts.
522
+ - >-
523
+ package.json:
524
+ - >-
525
+ Role:
526
+ Defines
527
+ scripts
528
+ (fix-spec,
529
+ regenerate,
530
+ test)
531
+ and
532
+ dependencies
533
+ (e.g.,
534
+ ts-node,
535
+ openapi-generator-cli).
536
+ - >-
537
+ Relevance:
538
+ Confirms
539
+ script
540
+ commands
541
+ and
542
+ versions
543
+ align
544
+ with
545
+ our
546
+ process.
547
+ - >-
548
+ What
549
+ We
550
+ Achieved
551
+ - >-
552
+ Goal
553
+ Met:
554
+ You
555
+ can
556
+ now
557
+ call
558
+ client.getApp({
559
+ appId:
560
+ "buwai2zpe"
561
+ })
562
+ and
563
+ get
564
+ the
565
+ app
566
+ details
567
+ {
568
+ id:
569
+ 'buwai2zpe',
570
+ name:
571
+ 'qb-copy'
572
+ }.
573
+ - >-
574
+ Fixes
575
+ Applied:
576
+ - >-
577
+ Added
578
+ tags:
579
+ ["Apps"]
580
+ in
581
+ fix-spec.ts
582
+ to
583
+ ensure
584
+ AppsApi.ts
585
+ is
586
+ generated
587
+ with
588
+ getAppById.
589
+ - >-
590
+ Updated
591
+ QuickbaseClient.ts
592
+ to:
593
+ - >-
594
+ Use
595
+ prototype
596
+ methods
597
+ via
598
+ Object.getOwnPropertyNames.
599
+ - >-
600
+ Bind
601
+ methods
602
+ to
603
+ preserve
604
+ context
605
+ with
606
+ .bind(api).
607
+ - >-
608
+ Handle
609
+ getAppById’s
610
+ direct
611
+ JSON
612
+ return
613
+ instead
614
+ of
615
+ a
616
+ Response
617
+ object.
618
+ - >-
619
+ Result:
620
+ The
621
+ ergonomic
622
+ API
623
+ you
624
+ wanted
625
+ (client.getApp)
626
+ works
627
+ seamlessly
628
+ with
629
+ the
630
+ generated
631
+ AppsApi.ts.
632
+ - >-
633
+ Why
634
+ It
635
+ Works
636
+ Now
637
+ - >-
638
+ fix-spec.ts:
639
+ - >-
640
+ Correctly
641
+ defined
642
+ /apps/{appId}
643
+ with
644
+ operationId:
645
+ "getAppById"
646
+ and
647
+ tags:
648
+ ["Apps"],
649
+ ensuring
650
+ AppsApi.ts
651
+ generation.
652
+ - >-
653
+ regenerate-client.ts:
654
+ - >-
655
+ Successfully
656
+ ran
657
+ OpenAPI
658
+ Generator
659
+ to
660
+ produce
661
+ AppsApi.ts
662
+ with
663
+ getAppById.
664
+ - >-
665
+ QuickbaseClient.ts:
666
+ - >-
667
+ buildMethodMap
668
+ now
669
+ captures
670
+ getAppById
671
+ and
672
+ maps
673
+ it
674
+ to
675
+ getApp.
676
+ - >-
677
+ invokeMethod
678
+ passes
679
+ {
680
+ appId:
681
+ 'buwai2zpe'
682
+ }
683
+ as
684
+ requestParameters
685
+ and
686
+ handles
687
+ the
688
+ JSON
689
+ response
690
+ directly.
691
+ - >-
692
+ test.ts:
693
+ - >-
694
+ Calls
695
+ client.getApp
696
+ and
697
+ logs
698
+ the
699
+ result,
700
+ proving
701
+ the
702
+ end-to-end
703
+ flow.
704
+ tree:
705
+ name: >-
706
+ .
707
+ type: >-
708
+ directory
709
+ children:
710
+ - name: >-
711
+ .env
712
+ type: >-
713
+ file
714
+ - name: >-
715
+ .gitignore
716
+ type: >-
717
+ file
718
+ - name: >-
719
+ CHANGELOG.md
720
+ type: >-
721
+ file
722
+ - name: >-
723
+ LICENSE
724
+ type: >-
725
+ file
726
+ - name: >-
727
+ README.md
728
+ type: >-
729
+ file
730
+ - name: >-
731
+ build-common.js
732
+ type: >-
733
+ file
734
+ - name: >-
735
+ build-esm.js
736
+ type: >-
737
+ file
738
+ - name: >-
739
+ build-umd.js
740
+ type: >-
741
+ file
742
+ - name: >-
743
+ debug.log
744
+ type: >-
745
+ file
746
+ - name: >-
747
+ dist
748
+ type: >-
749
+ directory
750
+ children:
751
+ - name: >-
752
+ esm
753
+ type: >-
754
+ directory
755
+ children:
756
+ - name: >-
757
+ quickbase.d.ts
758
+ type: >-
759
+ file
760
+ - name: >-
761
+ quickbase.js
762
+ type: >-
763
+ file
764
+ - name: >-
765
+ quickbase.js.map
766
+ type: >-
767
+ file
768
+ - name: >-
769
+ quickbase.min.js
770
+ type: >-
771
+ file
772
+ - name: >-
773
+ quickbase.min.js.map
774
+ type: >-
775
+ file
776
+ - name: >-
777
+ umd
778
+ type: >-
779
+ directory
780
+ children:
781
+ - name: >-
782
+ quickbase.umd.js
783
+ type: >-
784
+ file
785
+ - name: >-
786
+ quickbase.umd.js.map
787
+ type: >-
788
+ file
789
+ - name: >-
790
+ quickbase.umd.min.js
791
+ type: >-
792
+ file
793
+ - name: >-
794
+ quickbase.umd.min.js.map
795
+ type: >-
796
+ file
797
+ - name: >-
798
+ examples
799
+ type: >-
800
+ directory
801
+ children:
802
+ - name: >-
803
+ quicbase-jsCDN.html
804
+ type: >-
805
+ file
806
+ - name: >-
807
+ react.js
808
+ type: >-
809
+ file
810
+ - name: >-
811
+ vanillajs.html
812
+ type: >-
813
+ file
814
+ - name: >-
815
+ gen-no-overrides.log
816
+ type: >-
817
+ file
818
+ - name: >-
819
+ notes.txt
820
+ type: >-
821
+ file
822
+ - name: >-
823
+ open-api
824
+ type: >-
825
+ directory
826
+ children:
827
+ - name: >-
828
+ fix-spec-main.ts
829
+ type: >-
830
+ file
831
+ contents: >
832
+ #!/usr/bin/env
833
+ node
834
+
835
+
836
+ import
837
+ {
838
+ promises
839
+ as
840
+ fs
841
+ }
842
+ from
843
+ "fs";
844
+
845
+ import
846
+ path
847
+ from
848
+ "path";
849
+
850
+ import
851
+ {
852
+ fileURLToPath
853
+ }
854
+ from
855
+ "url";
856
+
857
+ import
858
+ *
859
+ as
860
+ glob
861
+ from
862
+ "glob";
863
+
864
+ import
865
+ {
866
+ enhanceTags
867
+ }
868
+ from
869
+ "./schema/tags/index.ts";
870
+
871
+ import
872
+ {
873
+ enhanceGeneral
874
+ }
875
+ from
876
+ "./schema/enhance-general.ts";
877
+
878
+ import
879
+ {
880
+ fixArrays
881
+ }
882
+ from
883
+ "./schema/fix-arrays.ts";
884
+
885
+ import
886
+ {
887
+ Spec
888
+ }
889
+ from
890
+ "./types/spec.ts";
891
+
892
+ import
893
+ {
894
+ toCamelCase
895
+ }
896
+ from
897
+ "./utils/naming.ts";
898
+
899
+
900
+ //
901
+ Removed
902
+ FixSpecConfig
903
+ since
904
+ applyOverrides
905
+ is
906
+ no
907
+ longer
908
+ needed
909
+
910
+ async
911
+ function
912
+ fixQuickBaseSpec():
913
+ Promise<void>
914
+ {
915
+ try {
916
+ const CODEGEN_DIR = path.dirname(fileURLToPath(import.meta.url));
917
+ const SPECS_DIR = path.join(CODEGEN_DIR, "..", "specs");
918
+ const OUTPUT_DIR = path.join(CODEGEN_DIR, "output");
919
+ console.log("Finding latest QuickBase RESTful API spec...");
920
+ const specFiles = glob.sync(
921
+ path.join(SPECS_DIR, "QuickBase_RESTful_*.json")
922
+ );
923
+ if (specFiles.length === 0) {
924
+ throw new Error(
925
+ "No QuickBase_RESTful_*.json files found in specs/ folder."
926
+ );
927
+ }
928
+ const inputFile = specFiles.sort().pop() as string;
929
+ const outputFile = path.join(OUTPUT_DIR, "quickbase-fixed.json");
930
+
931
+ console.log(`Reading ${path.basename(inputFile)} from specs/...`);
932
+ const specContent = await fs.readFile(inputFile, "utf8");
933
+ const spec: Spec = JSON.parse(specContent);
934
+
935
+ console.log("Fixing parameters...");
936
+ for (const pathKey in spec.paths) {
937
+ for (const method in spec.paths[pathKey]) {
938
+ const operation = spec.paths[pathKey][method];
939
+ if (operation.parameters) {
940
+ operation.parameters = operation.parameters
941
+ .filter(
942
+ (param) =>
943
+ !["QB-Realm-Hostname", "Authorization", "User-Agent"].includes(
944
+ param.name
945
+ )
946
+ )
947
+ .map((param) => {
948
+ param.name = toCamelCase(param.name);
949
+ if ("example" in param) delete param.example;
950
+ if ("schema" in param && param.in !== "body") delete param.schema;
951
+ if (!param.type && param.in !== "body") {
952
+ param.type = param.name.includes("Id") ? "string" : "string";
953
+ console.log(
954
+ `Set default type 'string' for ${pathKey}(${method}).${param.name} in initial pass`
955
+ );
956
+ }
957
+ return param;
958
+ });
959
+ }
960
+ }
961
+ }
962
+
963
+ // Removed applyOverrides conditional logic
964
+ console.log("Enhancing raw spec with tags...");
965
+ enhanceTags(spec);
966
+ console.log("Enhancing raw spec with general enhancements...");
967
+ enhanceGeneral(spec);
968
+
969
+ console.log("Fixing array schemas...");
970
+ fixArrays(spec);
971
+
972
+ console.log("Removing unexpected top-level attributes...");
973
+ delete spec.operations;
974
+ delete spec.groups;
975
+ delete spec.components;
976
+
977
+ console.log(`Writing fixed spec to ${path.basename(outputFile)}...`);
978
+ await fs.mkdir(OUTPUT_DIR, { recursive: true });
979
+ await fs.writeFile(outputFile, JSON.stringify(spec, null, 2), "utf8");
980
+ console.log("Spec fixed successfully! Output written to:", outputFile);
981
+ } catch (error) {
982
+ console.error("Failed to fix spec:", error);
983
+ process.exit(1);
984
+ }
985
+ }
986
+
987
+
988
+ async
989
+ function
990
+ main()
991
+ {
992
+ try {
993
+ await fixQuickBaseSpec();
994
+ } catch (error) {
995
+ console.error("Fatal error in script execution:", error);
996
+ process.exit(1);
997
+ }
998
+ }
999
+
1000
+
1001
+ main();
1002
+ - name: >-
1003
+ generate-unified-interface.ts
1004
+ type: >-
1005
+ file
1006
+ contents: >
1007
+ //
1008
+ open-api/generate-unified-interface.ts
1009
+
1010
+
1011
+ import
1012
+ {
1013
+ readFileSync,
1014
+ writeFileSync,
1015
+ mkdirSync,
1016
+ existsSync,
1017
+ readdirSync,
1018
+ }
1019
+ from
1020
+ "fs";
1021
+
1022
+ import
1023
+ {
1024
+ join,
1025
+ dirname
1026
+ }
1027
+ from
1028
+ "path";
1029
+
1030
+ import
1031
+ {
1032
+ fileURLToPath
1033
+ }
1034
+ from
1035
+ "url";
1036
+
1037
+ import
1038
+ {
1039
+ OpenAPIV2
1040
+ }
1041
+ from
1042
+ "openapi-types";
1043
+
1044
+ import
1045
+ {
1046
+ simplifyName
1047
+ }
1048
+ from
1049
+ "../src/utils.ts";
1050
+
1051
+
1052
+ const
1053
+ __dirname
1054
+ =
1055
+ dirname(fileURLToPath(import.meta.url));
1056
+
1057
+ const
1058
+ SPEC_FILE
1059
+ =
1060
+ join(__dirname,
1061
+ "output",
1062
+ "quickbase-fixed.json");
1063
+
1064
+ const
1065
+ OUTPUT_DIR
1066
+ =
1067
+ join(__dirname,
1068
+ "..",
1069
+ "src",
1070
+ "generated-unified");
1071
+
1072
+ const
1073
+ OUTPUT_FILE
1074
+ =
1075
+ join(OUTPUT_DIR,
1076
+ "QuickbaseClient.ts");
1077
+
1078
+ const
1079
+ MODELS_DIR
1080
+ =
1081
+ join(__dirname,
1082
+ "..",
1083
+ "src",
1084
+ "generated",
1085
+ "models");
1086
+
1087
+
1088
+ function
1089
+ mapOpenApiTypeToTs(
1090
+ openApiType: string | string[] | undefined
1091
+ ):
1092
+ string
1093
+ {
1094
+ const type = Array.isArray(openApiType)
1095
+ ? openApiType[0]
1096
+ : openApiType || "any";
1097
+ switch (type.toLowerCase()) {
1098
+ case "integer":
1099
+ case "int":
1100
+ case "number":
1101
+ return "number";
1102
+ case "string":
1103
+ return "string";
1104
+ case "boolean":
1105
+ return "boolean";
1106
+ default:
1107
+ return "any";
1108
+ }
1109
+ }
1110
+
1111
+
1112
+ function
1113
+ mapRefToType(
1114
+ schema: OpenAPIV2.SchemaObject | OpenAPIV2.ReferenceObject | undefined,
1115
+ modelImports: Set<string>,
1116
+ spec: OpenAPIV2.Document,
1117
+ depth: number = 0,
1118
+ availableModels: string[],
1119
+ missingTypes: Set<string>
1120
+ ):
1121
+ string
1122
+ {
1123
+ if (!schema) return "any";
1124
+
1125
+ if ("$ref" in schema && schema.$ref) {
1126
+ const refParts = schema.$ref.split("/");
1127
+ const model = refParts[refParts.length - 1];
1128
+ const pascalModel = model.charAt(0).toUpperCase() + model.slice(1);
1129
+ const camelModel = model.charAt(0).toLowerCase() + model.slice(1);
1130
+ if (availableModels.includes(pascalModel)) {
1131
+ modelImports.add(pascalModel);
1132
+ return pascalModel;
1133
+ } else if (availableModels.includes(camelModel)) {
1134
+ modelImports.add(camelModel);
1135
+ return camelModel;
1136
+ }
1137
+ missingTypes.add(pascalModel);
1138
+ console.warn(
1139
+ `Type ${pascalModel} not found in /generated/models, defaulting to 'any'`
1140
+ );
1141
+ return "any";
1142
+ }
1143
+
1144
+ if ("type" in schema) {
1145
+ if (schema.type === "object" && schema.properties) {
1146
+ const props = schema.properties;
1147
+ if (props.data && props.data.format === "binary") {
1148
+ return "ArrayBuffer"; // Map binary object to ArrayBuffer
1149
+ }
1150
+ if (props.content && props.content.format === "yaml") {
1151
+ return "string"; // Map YAML object to string
1152
+ }
1153
+ const propTypes = Object.entries(props).map(([key, prop]) => {
1154
+ const propSchema = prop as OpenAPIV2.SchemaObject;
1155
+ const propType = mapRefToType(
1156
+ propSchema,
1157
+ modelImports,
1158
+ spec,
1159
+ depth + 1,
1160
+ availableModels,
1161
+ missingTypes
1162
+ );
1163
+ return `${key}${propSchema.required ? "" : "?"}: ${propType}`;
1164
+ });
1165
+ return `{ ${propTypes.join("; ")} }`;
1166
+ }
1167
+ if (schema.type === "array" && schema.items) {
1168
+ const items = schema.items as
1169
+ | OpenAPIV2.SchemaObject
1170
+ | OpenAPIV2.ReferenceObject;
1171
+ const itemType = mapRefToType(
1172
+ items,
1173
+ modelImports,
1174
+ spec,
1175
+ depth + 1,
1176
+ availableModels,
1177
+ missingTypes
1178
+ );
1179
+ return `${itemType}[]`;
1180
+ }
1181
+ if (schema.type === "object" && schema.additionalProperties) {
1182
+ const additionalProps = schema.additionalProperties as
1183
+ | OpenAPIV2.SchemaObject
1184
+ | OpenAPIV2.ReferenceObject
1185
+ | boolean;
1186
+ if (typeof additionalProps === "boolean") {
1187
+ return "{ [key: string]: any }";
1188
+ }
1189
+ const valueType = mapRefToType(
1190
+ additionalProps,
1191
+ modelImports,
1192
+ spec,
1193
+ depth + 1,
1194
+ availableModels,
1195
+ missingTypes
1196
+ );
1197
+ return `{ [key: string]: ${valueType} }`;
1198
+ }
1199
+ return mapOpenApiTypeToTs(schema.type);
1200
+ }
1201
+
1202
+ return "any";
1203
+ }
1204
+
1205
+
1206
+ function
1207
+ generateInterface()
1208
+ {
1209
+ if (!existsSync(SPEC_FILE)) {
1210
+ console.error(
1211
+ `Spec file ${SPEC_FILE} not found. Run 'npm run fix-spec' first.`
1212
+ );
1213
+ process.exit(1);
1214
+ }
1215
+
1216
+ console.log("Generating unified QuickbaseClient interface...");
1217
+ const spec = JSON.parse(
1218
+ readFileSync(SPEC_FILE, "utf8")
1219
+ ) as OpenAPIV2.Document;
1220
+ const { paths } = spec;
1221
+
1222
+ const availableModels = readdirSync(MODELS_DIR)
1223
+ .filter((file) => file.endsWith(".ts") && !file.startsWith("index"))
1224
+ .map((file) => file.replace(".ts", ""));
1225
+ console.log("Available models:", availableModels);
1226
+
1227
+ const modelImports = new Set<string>();
1228
+ const missingTypes = new Set<string>();
1229
+ const methods: string[] = [];
1230
+
1231
+ for (const [path, methodsObj] of Object.entries(
1232
+ paths as OpenAPIV2.PathsObject
1233
+ )) {
1234
+ if (!methodsObj) continue;
1235
+
1236
+ for (const [method, operation] of Object.entries(
1237
+ methodsObj as OpenAPIV2.PathItemObject
1238
+ )) {
1239
+ const op = operation as OpenAPIV2.OperationObject | undefined;
1240
+ if (!op || !op.operationId) continue;
1241
+
1242
+ const opId = simplifyName(op.operationId);
1243
+ const summary = op.summary || "No description available.";
1244
+ const params = (op.parameters || [])
1245
+ .filter((p) => {
1246
+ const param = p as OpenAPIV2.Parameter;
1247
+ return !["QB-Realm-Hostname", "Authorization", "User-Agent"].includes(
1248
+ "name" in param ? param.name : ""
1249
+ );
1250
+ })
1251
+ .map((param: OpenAPIV2.Parameter) => {
1252
+ if (!("name" in param)) return "";
1253
+ let type: string;
1254
+ if ("schema" in param && param.schema) {
1255
+ type = mapRefToType(
1256
+ param.schema,
1257
+ modelImports,
1258
+ spec,
1259
+ 1,
1260
+ availableModels,
1261
+ missingTypes
1262
+ );
1263
+ } else if ("type" in param && param.type) {
1264
+ type = mapOpenApiTypeToTs(param.type);
1265
+ } else {
1266
+ console.warn(
1267
+ `Parameter ${param.name} in ${opId} has no type or schema, defaulting to 'any'`
1268
+ );
1269
+ type = "any";
1270
+ }
1271
+ const paramName = param.in === "body" ? "body" : param.name;
1272
+ return `${paramName}${param.required ? "" : "?"}: ${type}`;
1273
+ })
1274
+ .filter((param) => param !== "")
1275
+ .join("; ");
1276
+
1277
+ const successResponses = ["200", "207"]
1278
+ .map((code) => ({
1279
+ code,
1280
+ response: op.responses?.[code] as
1281
+ | OpenAPIV2.ResponseObject
1282
+ | undefined,
1283
+ }))
1284
+ .filter(({ response }) => response?.schema);
1285
+ const returnTypes = successResponses.map(({ response }) =>
1286
+ mapRefToType(
1287
+ response!.schema,
1288
+ modelImports,
1289
+ spec,
1290
+ 1,
1291
+ availableModels,
1292
+ missingTypes
1293
+ )
1294
+ );
1295
+ const uniqueReturnTypes = [...new Set(returnTypes)];
1296
+ const returnType =
1297
+ uniqueReturnTypes.length > 1
1298
+ ? uniqueReturnTypes.join(" | ")
1299
+ : uniqueReturnTypes[0] || "void";
1300
+
1301
+ const jsDoc = [
1302
+ ` /**`,
1303
+ ` * ${summary}`,
1304
+ ` * @param params - Parameters for the ${opId} operation`,
1305
+ ` * @returns A promise resolving to the ${opId} response`,
1306
+ ` */`,
1307
+ ].join("\n");
1308
+
1309
+ methods.push(
1310
+ `${jsDoc}\n ${opId}: (params: { ${params} }) => Promise<${returnType}>;`
1311
+ );
1312
+ }
1313
+ }
1314
+
1315
+ // Always write the missing-types-report.json to reflect the current state
1316
+ if (missingTypes.size > 0) {
1317
+ console.log(
1318
+ "Missing types detected (defaulted to 'any'):",
1319
+ Array.from(missingTypes)
1320
+ );
1321
+ } else {
1322
+ console.log("No missing types detected.");
1323
+ }
1324
+ writeFileSync(
1325
+ join(OUTPUT_DIR, "missing-types-report.json"),
1326
+ JSON.stringify({ missingTypes: Array.from(missingTypes) }, null, 2)
1327
+ );
1328
+ console.log("Missing types report saved to missing-types-report.json");
1329
+
1330
+ const importStatement =
1331
+ modelImports.size > 0
1332
+ ? `import { ${Array.from(modelImports)
1333
+ .sort()
1334
+ .join(", ")} } from "../generated/models";`
1335
+ : "";
1336
+ console.log(`Imports: ${Array.from(modelImports).join(", ")}`);
1337
+
1338
+ const interfaceContent = `// Generated on ${new Date().toISOString()}\n${importStatement}\n\nexport interface QuickbaseClient {\n${methods.join(
1339
+ "\n"
1340
+ )}\n}\n`;
1341
+
1342
+ if (!existsSync(OUTPUT_DIR)) {
1343
+ mkdirSync(OUTPUT_DIR, { recursive: true });
1344
+ }
1345
+ writeFileSync(OUTPUT_FILE, interfaceContent, "utf8");
1346
+ console.log(`Generated ${OUTPUT_FILE}`);
1347
+ }
1348
+
1349
+
1350
+ try
1351
+ {
1352
+ generateInterface();
1353
+ }
1354
+ catch
1355
+ (error)
1356
+ {
1357
+ console.error("Generation failed:", error);
1358
+ process.exit(1);
1359
+ }
1360
+ - name: >-
1361
+ regenerate-client.ts
1362
+ type: >-
1363
+ file
1364
+ contents: >
1365
+ #!/usr/bin/env
1366
+ node
1367
+
1368
+ import
1369
+ {
1370
+ execSync
1371
+ }
1372
+ from
1373
+ "child_process";
1374
+
1375
+ import
1376
+ {
1377
+ existsSync
1378
+ }
1379
+ from
1380
+ "fs";
1381
+
1382
+ import
1383
+ {
1384
+ join
1385
+ }
1386
+ from
1387
+ "path";
1388
+
1389
+ import
1390
+ {
1391
+ fileURLToPath
1392
+ }
1393
+ from
1394
+ "url";
1395
+
1396
+ import
1397
+ fetch
1398
+ from
1399
+ "node-fetch";
1400
+
1401
+ import
1402
+ readline
1403
+ from
1404
+ "readline";
1405
+
1406
+
1407
+ const
1408
+ CURRENT_JAR_VERSION
1409
+ =
1410
+ "7.12.0";
1411
+
1412
+ const
1413
+ MAVEN_METADATA_URL
1414
+ =
1415
+ "https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/maven-metadata.xml";
1416
+ const
1417
+ CODEGEN_DIR
1418
+ =
1419
+ join(fileURLToPath(import.meta.url),
1420
+ "..");
1421
+ //
1422
+ open-api/
1423
+
1424
+ const
1425
+ JARS_DIR
1426
+ =
1427
+ join(CODEGEN_DIR,
1428
+ "..",
1429
+ "tools",
1430
+ "openapi-jars");
1431
+ //
1432
+ Updated
1433
+ to
1434
+ tools/openapi-jars/
1435
+
1436
+ const
1437
+ SPEC_INPUT
1438
+ =
1439
+ join(CODEGEN_DIR,
1440
+ "output",
1441
+ "quickbase-fixed.json");
1442
+ //
1443
+ Relative
1444
+ to
1445
+ open-api/
1446
+
1447
+ const
1448
+ OUTPUT_DIR
1449
+ =
1450
+ join(CODEGEN_DIR,
1451
+ "..",
1452
+ "src",
1453
+ "generated");
1454
+ //
1455
+ Up
1456
+ to
1457
+ root,
1458
+ then
1459
+ into
1460
+ src/generated/
1461
+
1462
+
1463
+ async
1464
+ function
1465
+ getLatestVersion():
1466
+ Promise<string>
1467
+ {
1468
+ const response = await fetch(MAVEN_METADATA_URL);
1469
+ if (!response.ok)
1470
+ throw new Error(`Failed to fetch Maven metadata: ${response.statusText}`);
1471
+ const text = await response.text();
1472
+ const match = text.match(/<latest>(.*?)<\/latest>/);
1473
+ if (!match)
1474
+ throw new Error("Couldn’t parse latest version from Maven metadata");
1475
+ return match[1];
1476
+ }
1477
+
1478
+
1479
+ async
1480
+ function
1481
+ checkAndPromptForUpdate(messages:
1482
+ string[]):
1483
+ Promise<string>
1484
+ {
1485
+ const latestVersion = await getLatestVersion();
1486
+ if (latestVersion === CURRENT_JAR_VERSION) {
1487
+ messages.push(`Current version (${CURRENT_JAR_VERSION}) is the latest.`);
1488
+ return CURRENT_JAR_VERSION;
1489
+ }
1490
+
1491
+ messages.push(
1492
+ `Newer version available: ${latestVersion} (current: ${CURRENT_JAR_VERSION})`
1493
+ );
1494
+ const rl = readline.createInterface({
1495
+ input: process.stdin,
1496
+ output: process.stdout,
1497
+ });
1498
+
1499
+ return new Promise((resolve) => {
1500
+ const prompt = "Do you want to update to the latest version? (y/n): ";
1501
+ messages.push(prompt);
1502
+ rl.question(prompt, (answer) => {
1503
+ rl.close();
1504
+ if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
1505
+ messages.push(`Switching to version ${latestVersion}...`);
1506
+ resolve(latestVersion);
1507
+ } else {
1508
+ messages.push(`Sticking with version ${CURRENT_JAR_VERSION}.`);
1509
+ resolve(CURRENT_JAR_VERSION);
1510
+ }
1511
+ });
1512
+ });
1513
+ }
1514
+
1515
+
1516
+ async
1517
+ function
1518
+ ensureJarExists(
1519
+ version: string,
1520
+ messages: string[]
1521
+ ):
1522
+ Promise<string>
1523
+ {
1524
+ const jarPath = join(JARS_DIR, `openapi-generator-cli-${version}.jar`);
1525
+ const jarUrl = `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/${version}/openapi-generator-cli-${version}.jar`;
1526
+
1527
+ if (!existsSync(jarPath)) {
1528
+ messages.push(`Downloading OpenAPI Generator CLI v${version}...`);
1529
+ try {
1530
+ execSync(`curl -L -o ${jarPath} ${jarUrl}`, { stdio: "inherit" });
1531
+ messages.push(`Downloaded ${jarPath}`);
1532
+ } catch (error) {
1533
+ messages.push("Failed to download JAR.");
1534
+ throw error;
1535
+ }
1536
+ } else {
1537
+ messages.push(`Using existing ${jarPath}`);
1538
+ }
1539
+ return jarPath;
1540
+ }
1541
+
1542
+
1543
+ function
1544
+ regenerateClient(jarPath:
1545
+ string,
1546
+ messages:
1547
+ string[])
1548
+ {
1549
+ messages.push("Regenerating client from spec...");
1550
+ const command = `java -jar ${jarPath} generate -i ${SPEC_INPUT} -g typescript-fetch -o ${OUTPUT_DIR} --additional-properties=generateAliasAsModel=true`;
1551
+ try {
1552
+ execSync(command, { stdio: "inherit" });
1553
+ messages.push("Client regeneration complete.");
1554
+ } catch (error) {
1555
+ messages.push("Regeneration failed.");
1556
+ throw error;
1557
+ }
1558
+ }
1559
+
1560
+
1561
+ async
1562
+ function
1563
+ main()
1564
+ {
1565
+ const messages: string[] = [];
1566
+ try {
1567
+ if (!existsSync(SPEC_INPUT)) {
1568
+ console.error(
1569
+ `Spec file ${SPEC_INPUT} does not exist. Run 'npm run fix-spec' first.`
1570
+ );
1571
+ process.exit(1);
1572
+ }
1573
+ const versionToUse = await checkAndPromptForUpdate(messages);
1574
+ const jarPath = await ensureJarExists(versionToUse, messages);
1575
+ regenerateClient(jarPath, messages);
1576
+ } catch (error) {
1577
+ console.error("Error occurred during process:", error);
1578
+ } finally {
1579
+ console.log("\n--- Key Messages ---");
1580
+ messages.forEach((msg) => console.log(msg));
1581
+ }
1582
+ }
1583
+
1584
+
1585
+ main().catch((error)
1586
+ =>
1587
+ {
1588
+ console.error("Error in regeneration process:", error);
1589
+ process.exit(1);
1590
+ });
1591
+ - name: >-
1592
+ schema
1593
+ type: >-
1594
+ directory
1595
+ children:
1596
+ - name: >-
1597
+ enhance-general.ts
1598
+ type: >-
1599
+ file
1600
+ contents: >
1601
+ //
1602
+ schema/enhance-general.ts
1603
+
1604
+ import
1605
+ {
1606
+ Operation,
1607
+ Parameter,
1608
+ Spec
1609
+ }
1610
+ from
1611
+ "../types/spec.ts";
1612
+
1613
+ import
1614
+ {
1615
+ inferSchema
1616
+ }
1617
+ from
1618
+ "../utils/infer-schema.ts";
1619
+
1620
+
1621
+ export
1622
+ function
1623
+ enhanceGeneral(spec:
1624
+ Spec):
1625
+ void
1626
+ {
1627
+ spec.definitions = spec.definitions || {};
1628
+
1629
+ if (!spec.definitions["Record"]) {
1630
+ spec.definitions["Record"] = {
1631
+ type: "object",
1632
+ additionalProperties: {
1633
+ type: "object",
1634
+ properties: { value: { type: "string" } },
1635
+ required: ["value"],
1636
+ },
1637
+ description: "A generic QuickBase record with field ID-value pairs",
1638
+ };
1639
+ console.log("Added Record to definitions");
1640
+ }
1641
+
1642
+ if (!spec.definitions["Permission"]) {
1643
+ spec.definitions["Permission"] = {
1644
+ type: "object",
1645
+ properties: {
1646
+ role: { type: "string", description: "The role name" },
1647
+ permissionType: {
1648
+ type: "string",
1649
+ description: "Permission type (e.g., View, Modify)",
1650
+ },
1651
+ roleId: { type: "integer", description: "The role identifier" },
1652
+ },
1653
+ required: ["role", "permissionType", "roleId"],
1654
+ description: "A single permission entry for a field",
1655
+ };
1656
+ console.log("Added Permission to definitions");
1657
+ }
1658
+
1659
+ for (const pathKey in spec.paths) {
1660
+ for (const method in spec.paths[pathKey]) {
1661
+ const operation: Operation = spec.paths[pathKey][method];
1662
+ const opId =
1663
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
1664
+
1665
+ if (operation.parameters) {
1666
+ operation.parameters.forEach((param: Parameter) => {
1667
+ if (param.in !== "body" && !param.type && !param.schema) {
1668
+ param.type = param.name.includes("Id") ? "string" : "string";
1669
+ console.log(
1670
+ `Set default type 'string' for ${pathKey}(${method}).${param.name}`
1671
+ );
1672
+ }
1673
+ });
1674
+ }
1675
+
1676
+ if (operation.responses) {
1677
+ for (const status in operation.responses) {
1678
+ const response = operation.responses[status];
1679
+ if (response.schema) {
1680
+ const cleanStatus = status.replace("/", "_");
1681
+ const responseName = `${opId}${cleanStatus}Response`;
1682
+ if (!spec.definitions[responseName]) {
1683
+ console.log(
1684
+ `Adding ${responseName} to definitions for ${pathKey}(${method})`
1685
+ );
1686
+ if (!response.schema.type && response["x-amf-mediaType"]) {
1687
+ const mediaType = response["x-amf-mediaType"];
1688
+ if (mediaType === "application/octet-stream") {
1689
+ response.schema = {
1690
+ type: "object",
1691
+ properties: { data: { type: "string", format: "binary" } },
1692
+ description:
1693
+ response.schema?.description || "Binary file content",
1694
+ };
1695
+ } else if (mediaType === "application/x-yaml") {
1696
+ response.schema = {
1697
+ type: "object",
1698
+ properties: { content: { type: "string", format: "yaml" } },
1699
+ description: "YAML-formatted data",
1700
+ };
1701
+ } else if (
1702
+ mediaType === "application/json" &&
1703
+ response.schema.example
1704
+ ) {
1705
+ response.schema = inferSchema(
1706
+ response.schema.example,
1707
+ responseName
1708
+ );
1709
+ response.schema.description =
1710
+ response.description || `Response for ${opId}`;
1711
+ }
1712
+ }
1713
+ spec.definitions[responseName] = response.schema;
1714
+ }
1715
+ response.schema = { $ref: `#/definitions/${responseName}` };
1716
+ }
1717
+ }
1718
+ }
1719
+ }
1720
+ }
1721
+ }
1722
+ - name: >-
1723
+ fix-arrays.ts
1724
+ type: >-
1725
+ file
1726
+ contents: >
1727
+ //
1728
+ schema/fix-arrays.ts
1729
+
1730
+ import
1731
+ {
1732
+ Parameter,
1733
+ Spec
1734
+ }
1735
+ from
1736
+ "../types/spec.ts";
1737
+
1738
+
1739
+ export
1740
+ function
1741
+ fixArrays(spec:
1742
+ Spec):
1743
+ void
1744
+ {
1745
+ for (const pathKey in spec.paths) {
1746
+ for (const method in spec.paths[pathKey]) {
1747
+ const operation = spec.paths[pathKey][method];
1748
+ if (operation.parameters) {
1749
+ operation.parameters.forEach((param: Parameter) => {
1750
+ if (param.schema?.type === "array" && !param.schema.items) {
1751
+ console.log(
1752
+ `Fixing array schema for ${pathKey}(${method}).${param.name}`
1753
+ );
1754
+ param.schema.items = { type: "string" };
1755
+ }
1756
+ if (param.schema?.properties) {
1757
+ for (const propKey in param.schema.properties) {
1758
+ const prop = param.schema.properties[propKey];
1759
+ if (prop.type === "array" && !prop.items) {
1760
+ console.log(
1761
+ `Fixing nested array for ${pathKey}(${method}).${param.name}.${propKey}`
1762
+ );
1763
+ prop.items = { type: "string" };
1764
+ }
1765
+ }
1766
+ }
1767
+ });
1768
+ }
1769
+ if (operation.responses) {
1770
+ for (const status in operation.responses) {
1771
+ const response = operation.responses[status];
1772
+ if (response.schema?.type === "array" && !response.schema.items) {
1773
+ console.log(
1774
+ `Fixing array schema for ${pathKey}(${method}).responses.${status}`
1775
+ );
1776
+ response.schema.items = { type: "string" };
1777
+ }
1778
+ if (response.schema?.properties) {
1779
+ for (const propKey in response.schema.properties) {
1780
+ // Fixed: Changed param to response
1781
+ const prop = response.schema.properties[propKey];
1782
+ if (prop.type === "array" && !prop.items) {
1783
+ console.log(
1784
+ `Fixing nested array for ${pathKey}(${method}).responses.${status}.${propKey}`
1785
+ );
1786
+ prop.items = { type: "string" };
1787
+ }
1788
+ }
1789
+ }
1790
+ }
1791
+ }
1792
+ }
1793
+ }
1794
+
1795
+ console.log("Fixing array schemas in definitions...");
1796
+ const definitions = spec.definitions || {};
1797
+ for (const defKey in definitions) {
1798
+ const def = definitions[defKey];
1799
+ if (def.properties) {
1800
+ for (const propKey in def.properties) {
1801
+ const prop = def.properties[propKey];
1802
+ if (prop.type === "array" && !prop.items) {
1803
+ console.log(`Fixing missing items in ${defKey}.${propKey}`);
1804
+ prop.items = { type: "string" };
1805
+ }
1806
+ }
1807
+ }
1808
+ }
1809
+ }
1810
+ - name: >-
1811
+ tags
1812
+ type: >-
1813
+ directory
1814
+ children:
1815
+ - name: >-
1816
+ apps.ts
1817
+ type: >-
1818
+ file
1819
+ contents: >
1820
+ //
1821
+ schema/tags/apps.ts
1822
+
1823
+ import
1824
+ {
1825
+ Operation,
1826
+ Parameter,
1827
+ Spec
1828
+ }
1829
+ from
1830
+ "../../types/spec.ts";
1831
+
1832
+ import
1833
+ {
1834
+ normalizeDefinitionName
1835
+ }
1836
+ from
1837
+ "../../utils/naming.ts";
1838
+
1839
+
1840
+ export
1841
+ function
1842
+ enhanceApps(
1843
+ spec: Spec,
1844
+ pathKey: string,
1845
+ method: string,
1846
+ operation: Operation
1847
+ ):
1848
+ void
1849
+ {
1850
+ const opId =
1851
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
1852
+ if (operation.parameters && operation.tags?.includes("Apps")) {
1853
+ operation.parameters.forEach((param: Parameter) => {
1854
+ if (param.in === "body") {
1855
+ if (!param.schema) param.schema = {};
1856
+ let requestName =
1857
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
1858
+ requestName = normalizeDefinitionName(requestName);
1859
+
1860
+ if (
1861
+ !spec.definitions[requestName] ||
1862
+ !spec.definitions[requestName].type ||
1863
+ Object.keys(spec.definitions[requestName]?.properties || {})
1864
+ .length === 0
1865
+ ) {
1866
+ console.log(
1867
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
1868
+ );
1869
+ let properties;
1870
+ if (pathKey.includes("/copy") && method === "post") {
1871
+ properties = {
1872
+ name: { type: "string", description: "The name of the new app." },
1873
+ description: {
1874
+ type: "string",
1875
+ description: "A description for the new app.",
1876
+ },
1877
+ properties: {
1878
+ type: "object",
1879
+ properties: {
1880
+ keepData: {
1881
+ type: "boolean",
1882
+ description: "Whether to copy data.",
1883
+ },
1884
+ excludeFiles: {
1885
+ type: "boolean",
1886
+ description: "Whether to exclude files.",
1887
+ },
1888
+ usersAndRoles: {
1889
+ type: "boolean",
1890
+ description: "Whether to copy users and roles.",
1891
+ },
1892
+ assignUserToken: {
1893
+ type: "boolean",
1894
+ description: "Whether to assign the user token.",
1895
+ },
1896
+ },
1897
+ description: "Options for customizing the app copy process.",
1898
+ },
1899
+ };
1900
+ } else {
1901
+ properties = {
1902
+ name: { type: "string", description: "The name of the app." },
1903
+ description: {
1904
+ type: "string",
1905
+ description: "A description for the app.",
1906
+ },
1907
+ assignToken: {
1908
+ type: "boolean",
1909
+ description: "Whether to assign the user token.",
1910
+ },
1911
+ };
1912
+ }
1913
+ spec.definitions[requestName] = {
1914
+ type: "object",
1915
+ properties,
1916
+ required: Object.keys(properties).filter(
1917
+ (key) => key !== "description" && key !== "properties"
1918
+ ),
1919
+ description: operation.summary || `Request body for ${opId}`,
1920
+ };
1921
+ }
1922
+ param.schema = { $ref: `#/definitions/${requestName}` };
1923
+ console.log(
1924
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
1925
+ );
1926
+ }
1927
+ });
1928
+ }
1929
+ }
1930
+ - name: >-
1931
+ fields.ts
1932
+ type: >-
1933
+ file
1934
+ contents: >
1935
+ //
1936
+ schema/tags/fields.ts
1937
+
1938
+ import
1939
+ {
1940
+ Operation,
1941
+ Parameter,
1942
+ Spec
1943
+ }
1944
+ from
1945
+ "../../types/spec.ts";
1946
+
1947
+ import
1948
+ {
1949
+ normalizeDefinitionName
1950
+ }
1951
+ from
1952
+ "../../utils/naming.ts";
1953
+
1954
+
1955
+ export
1956
+ function
1957
+ enhanceFields(
1958
+ spec: Spec,
1959
+ pathKey: string,
1960
+ method: string,
1961
+ operation: Operation
1962
+ ):
1963
+ void
1964
+ {
1965
+ const opId =
1966
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
1967
+ if (operation.parameters && operation.tags?.includes("Fields")) {
1968
+ operation.parameters.forEach((param: Parameter) => {
1969
+ if (param.in === "body") {
1970
+ if (!param.schema) param.schema = {};
1971
+ let requestName =
1972
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
1973
+ requestName = normalizeDefinitionName(requestName);
1974
+
1975
+ if (
1976
+ !spec.definitions[requestName] ||
1977
+ !spec.definitions[requestName].type ||
1978
+ Object.keys(spec.definitions[requestName]?.properties || {})
1979
+ .length === 0
1980
+ ) {
1981
+ console.log(
1982
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
1983
+ );
1984
+ let properties;
1985
+ if (method === "delete") {
1986
+ properties = {
1987
+ fieldIds: { type: "array", items: { type: "integer" } },
1988
+ };
1989
+ } else {
1990
+ properties = {
1991
+ label: { type: "string", description: "The label of the field" },
1992
+ fieldType: {
1993
+ type: "string",
1994
+ description: "The type of the field",
1995
+ enum: [
1996
+ "text",
1997
+ "text-multiple-choice",
1998
+ "text-multi-line",
1999
+ "rich-text",
2000
+ "numeric",
2001
+ "currency",
2002
+ "percent",
2003
+ "rating",
2004
+ "date",
2005
+ "date-time",
2006
+ "time-of-day",
2007
+ "duration",
2008
+ "checkbox",
2009
+ "user",
2010
+ "multi-user",
2011
+ "address",
2012
+ "email",
2013
+ "phone",
2014
+ "url",
2015
+ "file",
2016
+ "record-id",
2017
+ ],
2018
+ },
2019
+ fieldHelp: {
2020
+ type: "string",
2021
+ description: "Help text for the field",
2022
+ nullable: true,
2023
+ },
2024
+ addToForms: {
2025
+ type: "boolean",
2026
+ description: "Whether to add the field to forms",
2027
+ nullable: true,
2028
+ },
2029
+ permissions: {
2030
+ anyOf: [
2031
+ {
2032
+ type: "array",
2033
+ items: { $ref: "#/definitions/Permission" },
2034
+ },
2035
+ { type: "null" },
2036
+ ],
2037
+ description: "Custom permissions for the field",
2038
+ },
2039
+ required: {
2040
+ type: "boolean",
2041
+ description: "Whether the field is required",
2042
+ nullable: true,
2043
+ },
2044
+ unique: {
2045
+ type: "boolean",
2046
+ description: "Whether the field must have unique values",
2047
+ nullable: true,
2048
+ },
2049
+ noWrap: {
2050
+ type: "boolean",
2051
+ description: "Whether text wrapping is disabled",
2052
+ nullable: true,
2053
+ },
2054
+ bold: {
2055
+ type: "boolean",
2056
+ description: "Whether the field is bolded",
2057
+ nullable: true,
2058
+ },
2059
+ appearsByDefault: {
2060
+ type: "boolean",
2061
+ description: "Whether the field appears by default in reports",
2062
+ nullable: true,
2063
+ },
2064
+ findEnabled: {
2065
+ type: "boolean",
2066
+ description: "Whether the field is searchable",
2067
+ nullable: true,
2068
+ },
2069
+ doesDataCopy: {
2070
+ type: "boolean",
2071
+ description: "Whether the field copies data",
2072
+ nullable: true,
2073
+ },
2074
+ audited: {
2075
+ type: "boolean",
2076
+ description: "Whether changes to the field are audited",
2077
+ nullable: true,
2078
+ },
2079
+ };
2080
+ }
2081
+ spec.definitions[requestName] = {
2082
+ type: "object",
2083
+ properties,
2084
+ required: Object.keys(properties).filter(
2085
+ (key) =>
2086
+ ![
2087
+ "fieldHelp",
2088
+ "addToForms",
2089
+ "permissions",
2090
+ "required",
2091
+ "unique",
2092
+ "noWrap",
2093
+ "bold",
2094
+ "appearsByDefault",
2095
+ "findEnabled",
2096
+ "doesDataCopy",
2097
+ "audited",
2098
+ ].includes(key)
2099
+ ),
2100
+ description: operation.summary || `Request body for ${opId}`,
2101
+ };
2102
+ }
2103
+ param.schema = { $ref: `#/definitions/${requestName}` };
2104
+ console.log(
2105
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2106
+ );
2107
+ }
2108
+ });
2109
+ }
2110
+ }
2111
+ - name: >-
2112
+ groups.ts
2113
+ type: >-
2114
+ file
2115
+ contents: >
2116
+ //
2117
+ schema/tags/groups.ts
2118
+
2119
+ import
2120
+ {
2121
+ Operation,
2122
+ Parameter,
2123
+ Spec
2124
+ }
2125
+ from
2126
+ "../../types/spec.ts";
2127
+
2128
+ import
2129
+ {
2130
+ normalizeDefinitionName
2131
+ }
2132
+ from
2133
+ "../../utils/naming.ts";
2134
+
2135
+
2136
+ export
2137
+ function
2138
+ enhanceGroups(
2139
+ spec: Spec,
2140
+ pathKey: string,
2141
+ method: string,
2142
+ operation: Operation
2143
+ ):
2144
+ void
2145
+ {
2146
+ const opId =
2147
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
2148
+ if (
2149
+ operation.parameters &&
2150
+ operation.tags?.includes("Groups") &&
2151
+ operation.summary?.toLowerCase().includes("subgroup")
2152
+ ) {
2153
+ operation.parameters.forEach((param: Parameter) => {
2154
+ if (param.in === "body") {
2155
+ if (!param.schema) param.schema = {};
2156
+ let requestName =
2157
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
2158
+ requestName = normalizeDefinitionName(requestName);
2159
+
2160
+ if (
2161
+ !spec.definitions[requestName] ||
2162
+ !spec.definitions[requestName].type ||
2163
+ Object.keys(spec.definitions[requestName]?.properties || {})
2164
+ .length === 0
2165
+ ) {
2166
+ console.log(
2167
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
2168
+ );
2169
+ const properties = {
2170
+ groupIds: { type: "array", items: { type: "string" } },
2171
+ };
2172
+ spec.definitions[requestName] = {
2173
+ type: "object",
2174
+ properties,
2175
+ required: Object.keys(properties),
2176
+ description: operation.summary || `Request body for ${opId}`,
2177
+ };
2178
+ }
2179
+ param.schema = { $ref: `#/definitions/${requestName}` };
2180
+ console.log(
2181
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2182
+ );
2183
+ }
2184
+ });
2185
+ }
2186
+ }
2187
+ - name: >-
2188
+ index.ts
2189
+ type: >-
2190
+ file
2191
+ contents: >
2192
+ //
2193
+ schema/tags/index.ts
2194
+
2195
+ import
2196
+ {
2197
+ Operation,
2198
+ Parameter,
2199
+ Spec
2200
+ }
2201
+ from
2202
+ "../../types/spec.ts";
2203
+
2204
+ import
2205
+ {
2206
+ normalizeDefinitionName
2207
+ }
2208
+ from
2209
+ "../../utils/naming.ts";
2210
+
2211
+ import
2212
+ {
2213
+ enhanceUsers
2214
+ }
2215
+ from
2216
+ "./users.ts";
2217
+
2218
+ import
2219
+ {
2220
+ enhanceGroups
2221
+ }
2222
+ from
2223
+ "./groups.ts";
2224
+
2225
+ import
2226
+ {
2227
+ enhanceRecords
2228
+ }
2229
+ from
2230
+ "./records.ts";
2231
+
2232
+ import
2233
+ {
2234
+ enhanceApps
2235
+ }
2236
+ from
2237
+ "./apps.ts";
2238
+
2239
+ import
2240
+ {
2241
+ enhanceFields
2242
+ }
2243
+ from
2244
+ "./fields.ts";
2245
+
2246
+ import
2247
+ {
2248
+ enhanceTables
2249
+ }
2250
+ from
2251
+ "./tables.ts";
2252
+
2253
+
2254
+ export
2255
+ function
2256
+ enhanceTags(spec:
2257
+ Spec):
2258
+ void
2259
+ {
2260
+ spec.definitions = spec.definitions || {};
2261
+
2262
+ for (const pathKey in spec.paths) {
2263
+ for (const method in spec.paths[pathKey]) {
2264
+ const operation: Operation = spec.paths[pathKey][method];
2265
+ const opId =
2266
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
2267
+
2268
+ // Handle array schemas
2269
+ if (operation.parameters) {
2270
+ operation.parameters.forEach((param: Parameter) => {
2271
+ if (param.in === "body") {
2272
+ if (!param.schema) param.schema = {};
2273
+ let requestName =
2274
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
2275
+ requestName = normalizeDefinitionName(requestName);
2276
+
2277
+ if (spec.definitions[requestName]?.type === "array") {
2278
+ console.log(
2279
+ `Wrapping array schema for ${requestName} in ${pathKey}(${method})`
2280
+ );
2281
+ const arraySchema = spec.definitions[requestName];
2282
+ let wrapperPropName = operation.tags?.includes("Users")
2283
+ ? "userIds"
2284
+ : "items";
2285
+ if (
2286
+ operation.tags?.includes("Groups") &&
2287
+ operation.summary?.toLowerCase().includes("subgroup")
2288
+ ) {
2289
+ wrapperPropName = "groupIds";
2290
+ }
2291
+ spec.definitions[requestName] = {
2292
+ type: "object",
2293
+ properties: { [wrapperPropName]: arraySchema },
2294
+ required: arraySchema.minItems > 0 ? [wrapperPropName] : [],
2295
+ description:
2296
+ arraySchema.description || `Request body for ${opId}`,
2297
+ };
2298
+ param.schema = { $ref: `#/definitions/${requestName}` };
2299
+ console.log(
2300
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2301
+ );
2302
+ }
2303
+ }
2304
+ });
2305
+ }
2306
+
2307
+ // Apply tag-specific enhancements
2308
+ enhanceUsers(spec, pathKey, method, operation);
2309
+ enhanceGroups(spec, pathKey, method, operation);
2310
+ enhanceRecords(spec, pathKey, method, operation);
2311
+ enhanceApps(spec, pathKey, method, operation);
2312
+ enhanceFields(spec, pathKey, method, operation);
2313
+ enhanceTables(spec, pathKey, method, operation);
2314
+ }
2315
+ }
2316
+ }
2317
+ - name: >-
2318
+ records.ts
2319
+ type: >-
2320
+ file
2321
+ contents: >
2322
+ //
2323
+ schema/tags/records.ts
2324
+
2325
+ import
2326
+ {
2327
+ Operation,
2328
+ Parameter,
2329
+ Spec
2330
+ }
2331
+ from
2332
+ "../../types/spec.ts";
2333
+
2334
+ import
2335
+ {
2336
+ normalizeDefinitionName
2337
+ }
2338
+ from
2339
+ "../../utils/naming.ts";
2340
+
2341
+
2342
+ export
2343
+ function
2344
+ enhanceRecords(
2345
+ spec: Spec,
2346
+ pathKey: string,
2347
+ method: string,
2348
+ operation: Operation
2349
+ ):
2350
+ void
2351
+ {
2352
+ const opId =
2353
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
2354
+ if (operation.parameters && operation.tags?.includes("Records")) {
2355
+ operation.parameters.forEach((param: Parameter) => {
2356
+ if (param.in === "body") {
2357
+ if (!param.schema) param.schema = {};
2358
+ let requestName =
2359
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
2360
+ requestName = normalizeDefinitionName(requestName);
2361
+
2362
+ if (
2363
+ !spec.definitions[requestName] ||
2364
+ !spec.definitions[requestName].type ||
2365
+ Object.keys(spec.definitions[requestName]?.properties || {})
2366
+ .length === 0
2367
+ ) {
2368
+ console.log(
2369
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
2370
+ );
2371
+ let properties;
2372
+ if (method === "post") {
2373
+ properties = {
2374
+ data: { type: "array", items: { $ref: "#/definitions/Record" } },
2375
+ to: { type: "string" },
2376
+ fieldsToReturn: { type: "array", items: { type: "integer" } },
2377
+ };
2378
+ } else if (method === "delete") {
2379
+ properties = {
2380
+ from: { type: "string" },
2381
+ where: { type: "string" },
2382
+ };
2383
+ } else if (operation.summary?.toLowerCase().includes("query")) {
2384
+ properties = {
2385
+ from: { type: "string" },
2386
+ select: { type: "array", items: { type: "integer" } },
2387
+ where: { type: "string" },
2388
+ };
2389
+ }
2390
+ if (properties) {
2391
+ spec.definitions[requestName] = {
2392
+ type: "object",
2393
+ properties,
2394
+ required: Object.keys(properties).filter(
2395
+ (key) => key !== "fieldsToReturn"
2396
+ ),
2397
+ description: operation.summary || `Request body for ${opId}`,
2398
+ };
2399
+ }
2400
+ }
2401
+ param.schema = { $ref: `#/definitions/${requestName}` };
2402
+ console.log(
2403
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2404
+ );
2405
+ }
2406
+ });
2407
+ }
2408
+ }
2409
+ - name: >-
2410
+ tables.ts
2411
+ type: >-
2412
+ file
2413
+ contents: >
2414
+ //
2415
+ schema/tags/tables.ts
2416
+
2417
+ import
2418
+ {
2419
+ Operation,
2420
+ Parameter,
2421
+ Spec
2422
+ }
2423
+ from
2424
+ "../../types/spec.ts";
2425
+
2426
+ import
2427
+ {
2428
+ normalizeDefinitionName
2429
+ }
2430
+ from
2431
+ "../../utils/naming.ts";
2432
+
2433
+
2434
+ export
2435
+ function
2436
+ enhanceTables(
2437
+ spec: Spec,
2438
+ pathKey: string,
2439
+ method: string,
2440
+ operation: Operation
2441
+ ):
2442
+ void
2443
+ {
2444
+ const opId =
2445
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
2446
+ if (operation.parameters && operation.tags?.includes("Tables")) {
2447
+ operation.parameters.forEach((param: Parameter) => {
2448
+ if (param.in === "body") {
2449
+ if (!param.schema) param.schema = {};
2450
+ let requestName =
2451
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
2452
+ requestName = normalizeDefinitionName(requestName);
2453
+
2454
+ if (
2455
+ !spec.definitions[requestName] ||
2456
+ !spec.definitions[requestName].type ||
2457
+ Object.keys(spec.definitions[requestName]?.properties || {})
2458
+ .length === 0
2459
+ ) {
2460
+ console.log(
2461
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
2462
+ );
2463
+ const properties = {
2464
+ name: { type: "string" },
2465
+ };
2466
+ spec.definitions[requestName] = {
2467
+ type: "object",
2468
+ properties,
2469
+ required: Object.keys(properties),
2470
+ description: operation.summary || `Request body for ${opId}`,
2471
+ };
2472
+ }
2473
+ param.schema = { $ref: `#/definitions/${requestName}` };
2474
+ console.log(
2475
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2476
+ );
2477
+ }
2478
+ });
2479
+ }
2480
+ }
2481
+ - name: >-
2482
+ users.ts
2483
+ type: >-
2484
+ file
2485
+ contents: >
2486
+ //
2487
+ schema/tags/users.ts
2488
+
2489
+ import
2490
+ {
2491
+ Operation,
2492
+ Parameter,
2493
+ Spec
2494
+ }
2495
+ from
2496
+ "../../types/spec.ts";
2497
+
2498
+ import
2499
+ {
2500
+ normalizeDefinitionName
2501
+ }
2502
+ from
2503
+ "../../utils/naming.ts";
2504
+
2505
+
2506
+ export
2507
+ function
2508
+ enhanceUsers(
2509
+ spec: Spec,
2510
+ pathKey: string,
2511
+ method: string,
2512
+ operation: Operation
2513
+ ):
2514
+ void
2515
+ {
2516
+ const opId =
2517
+ operation.operationId || `${method}${pathKey.replace(/\W/g, "")}`;
2518
+ if (operation.parameters && operation.tags?.includes("Users")) {
2519
+ operation.parameters.forEach((param: Parameter) => {
2520
+ if (param.in === "body") {
2521
+ if (!param.schema) param.schema = {};
2522
+ let requestName =
2523
+ param.schema.$ref?.split("/").pop() || `${opId}Request`;
2524
+ requestName = normalizeDefinitionName(requestName);
2525
+
2526
+ if (
2527
+ !spec.definitions[requestName] ||
2528
+ !spec.definitions[requestName].type ||
2529
+ Object.keys(spec.definitions[requestName]?.properties || {})
2530
+ .length === 0
2531
+ ) {
2532
+ console.log(
2533
+ `Defining schema for ${requestName} in ${pathKey}(${method})`
2534
+ );
2535
+ const properties = {
2536
+ userIds: { type: "array", items: { type: "string" } },
2537
+ };
2538
+ spec.definitions[requestName] = {
2539
+ type: "object",
2540
+ properties,
2541
+ required: Object.keys(properties),
2542
+ description: operation.summary || `Request body for ${opId}`,
2543
+ };
2544
+ }
2545
+ param.schema = { $ref: `#/definitions/${requestName}` };
2546
+ console.log(
2547
+ `Ensured ${requestName} in definitions for ${pathKey}(${method})`
2548
+ );
2549
+ }
2550
+ });
2551
+ }
2552
+ }
2553
+ - name: >-
2554
+ types
2555
+ type: >-
2556
+ directory
2557
+ children:
2558
+ - name: >-
2559
+ spec.ts
2560
+ type: >-
2561
+ file
2562
+ contents: >
2563
+ export
2564
+ interface
2565
+ Parameter
2566
+ {
2567
+ name: string;
2568
+ in: string;
2569
+ required?: boolean;
2570
+ type?: string;
2571
+ schema?: {
2572
+ type?: string;
2573
+ items?: any;
2574
+ $ref?: string;
2575
+ properties?: any;
2576
+ example?: any;
2577
+ };
2578
+ example?: any;
2579
+ }
2580
+
2581
+
2582
+ export
2583
+ interface
2584
+ Operation
2585
+ {
2586
+ parameters?: Parameter[];
2587
+ responses?: Record<
2588
+ string,
2589
+ { description: string; schema?: any; "x-amf-mediaType"?: string }
2590
+ >;
2591
+ operationId?: string;
2592
+ summary?: string;
2593
+ tags?: string[];
2594
+ }
2595
+
2596
+
2597
+ export
2598
+ interface
2599
+ Spec
2600
+ {
2601
+ paths: Record<string, Record<string, Operation>>;
2602
+ definitions?: Record<string, any>;
2603
+ swagger: string;
2604
+ info: any;
2605
+ operations?: any;
2606
+ groups?: any;
2607
+ components?: any;
2608
+ }
2609
+
2610
+
2611
+ export
2612
+ interface
2613
+ FixSpecConfig
2614
+ {
2615
+ applyOverrides?: boolean;
2616
+ overridePaths?: string[];
2617
+ overrideDefinitions?: string[];
2618
+ }
2619
+ - name: >-
2620
+ utils
2621
+ type: >-
2622
+ directory
2623
+ children:
2624
+ - name: >-
2625
+ infer-schema.ts
2626
+ type: >-
2627
+ file
2628
+ contents: >
2629
+ //
2630
+ utils/infer-schema.ts
2631
+
2632
+ export
2633
+ function
2634
+ inferSchema(example:
2635
+ any,
2636
+ operationId?:
2637
+ string):
2638
+ any
2639
+ {
2640
+ if (!example || typeof example !== "object") {
2641
+ return { type: "string" };
2642
+ }
2643
+ if (Array.isArray(example)) {
2644
+ return {
2645
+ type: "array",
2646
+ items:
2647
+ example.length > 0
2648
+ ? inferSchema(example[0], operationId)
2649
+ : { type: "string" },
2650
+ };
2651
+ }
2652
+ const properties: Record<string, any> = {};
2653
+ for (const [key, value] of Object.entries(example)) {
2654
+ if (Array.isArray(value)) {
2655
+ properties[key] = {
2656
+ type: "array",
2657
+ items:
2658
+ value.length > 0
2659
+ ? inferSchema(value[0], operationId)
2660
+ : { type: "string" },
2661
+ };
2662
+ } else if (typeof value === "object" && value !== null) {
2663
+ properties[key] = inferSchema(value, operationId);
2664
+ } else {
2665
+ properties[key] = {
2666
+ type:
2667
+ typeof value === "object" && value === null
2668
+ ? "object"
2669
+ : typeof value || "string",
2670
+ };
2671
+ }
2672
+ }
2673
+ if (operationId && operationId.endsWith("200Response")) {
2674
+ return { type: "array", items: { type: "object", properties } };
2675
+ }
2676
+ return { type: "object", properties };
2677
+ }
2678
+ - name: >-
2679
+ naming.ts
2680
+ type: >-
2681
+ file
2682
+ contents: >
2683
+ //
2684
+ utils/naming.ts
2685
+
2686
+ export
2687
+ function
2688
+ toCamelCase(str:
2689
+ string):
2690
+ string
2691
+ {
2692
+ return str
2693
+ .replace(/[-_](.)/g, (_, char) => char.toUpperCase())
2694
+ .replace(/^./, (str) => str.toLowerCase());
2695
+ }
2696
+
2697
+
2698
+ export
2699
+ function
2700
+ normalizeDefinitionName(name:
2701
+ string):
2702
+ string
2703
+ {
2704
+ return name.charAt(0).toUpperCase() + name.slice(1);
2705
+ }
2706
+ - name: >-
2707
+ openapitools.json
2708
+ type: >-
2709
+ file
2710
+ - name: >-
2711
+ output.log
2712
+ type: >-
2713
+ file
2714
+ - name: >-
2715
+ package-lock.json
2716
+ type: >-
2717
+ file
2718
+ - name: >-
2719
+ package.json
2720
+ type: >-
2721
+ file
2722
+ - name: >-
2723
+ playwright.config.ts
2724
+ type: >-
2725
+ file
2726
+ - name: >-
2727
+ regenerate_output.log
2728
+ type: >-
2729
+ file
2730
+ - name: >-
2731
+ rollup.config.js
2732
+ type: >-
2733
+ file
2734
+ - name: >-
2735
+ src
2736
+ type: >-
2737
+ directory
2738
+ children:
2739
+ - name: >-
2740
+ generated
2741
+ type: >-
2742
+ directory
2743
+ children:
2744
+ - name: >-
2745
+ .openapi-generator
2746
+ type: >-
2747
+ directory
2748
+ children:
2749
+ - name: >-
2750
+ FILES
2751
+ type: >-
2752
+ file
2753
+ - name: >-
2754
+ VERSION
2755
+ type: >-
2756
+ file
2757
+ - name: >-
2758
+ .openapi-generator-ignore
2759
+ type: >-
2760
+ file
2761
+ - name: >-
2762
+ apis
2763
+ type: >-
2764
+ directory
2765
+ children:
2766
+ - name: >-
2767
+ AppsApi.ts
2768
+ type: >-
2769
+ file
2770
+ - name: >-
2771
+ AuditApi.ts
2772
+ type: >-
2773
+ file
2774
+ - name: >-
2775
+ AuthApi.ts
2776
+ type: >-
2777
+ file
2778
+ - name: >-
2779
+ DocumentTemplatesApi.ts
2780
+ type: >-
2781
+ file
2782
+ - name: >-
2783
+ FieldsApi.ts
2784
+ type: >-
2785
+ file
2786
+ - name: >-
2787
+ FilesApi.ts
2788
+ type: >-
2789
+ file
2790
+ - name: >-
2791
+ FormulasApi.ts
2792
+ type: >-
2793
+ file
2794
+ - name: >-
2795
+ PlatformAnalyticsApi.ts
2796
+ type: >-
2797
+ file
2798
+ - name: >-
2799
+ RecordsApi.ts
2800
+ type: >-
2801
+ file
2802
+ - name: >-
2803
+ ReportsApi.ts
2804
+ type: >-
2805
+ file
2806
+ - name: >-
2807
+ SolutionsApi.ts
2808
+ type: >-
2809
+ file
2810
+ - name: >-
2811
+ TablesApi.ts
2812
+ type: >-
2813
+ file
2814
+ - name: >-
2815
+ UserTokenApi.ts
2816
+ type: >-
2817
+ file
2818
+ - name: >-
2819
+ UsersApi.ts
2820
+ type: >-
2821
+ file
2822
+ - name: >-
2823
+ index.ts
2824
+ type: >-
2825
+ file
2826
+ - name: >-
2827
+ index.ts
2828
+ type: >-
2829
+ file
2830
+ - name: >-
2831
+ models
2832
+ type: >-
2833
+ directory
2834
+ children:
2835
+ - name: >-
2836
+ AddManagersToGroup200Response.ts
2837
+ type: >-
2838
+ file
2839
+ - name: >-
2840
+ AddManagersToGroupRequest.ts
2841
+ type: >-
2842
+ file
2843
+ - name: >-
2844
+ AddMembersToGroup200Response.ts
2845
+ type: >-
2846
+ file
2847
+ - name: >-
2848
+ AddMembersToGroupRequest.ts
2849
+ type: >-
2850
+ file
2851
+ - name: >-
2852
+ AddSubgroupsToGroup200Response.ts
2853
+ type: >-
2854
+ file
2855
+ - name: >-
2856
+ AddSubgroupsToGroupRequest.ts
2857
+ type: >-
2858
+ file
2859
+ - name: >-
2860
+ Audit200Response.ts
2861
+ type: >-
2862
+ file
2863
+ - name: >-
2864
+ Audit202Response.ts
2865
+ type: >-
2866
+ file
2867
+ - name: >-
2868
+ AuditRequest.ts
2869
+ type: >-
2870
+ file
2871
+ - name: >-
2872
+ ChangesetSolution200Response.ts
2873
+ type: >-
2874
+ file
2875
+ - name: >-
2876
+ ChangesetSolution200ResponseInner.ts
2877
+ type: >-
2878
+ file
2879
+ - name: >-
2880
+ ChangesetSolution200ResponseInnerChangesInnerInner.ts
2881
+ type: >-
2882
+ file
2883
+ - name: >-
2884
+ ChangesetSolution400Response.ts
2885
+ type: >-
2886
+ file
2887
+ - name: >-
2888
+ ChangesetSolution401403Response.ts
2889
+ type: >-
2890
+ file
2891
+ - name: >-
2892
+ ChangesetSolution404Response.ts
2893
+ type: >-
2894
+ file
2895
+ - name: >-
2896
+ ChangesetSolution4xx5xxResponse.ts
2897
+ type: >-
2898
+ file
2899
+ - name: >-
2900
+ ChangesetSolutionFromRecord200Response.ts
2901
+ type: >-
2902
+ file
2903
+ - name: >-
2904
+ ChangesetSolutionFromRecord400Response.ts
2905
+ type: >-
2906
+ file
2907
+ - name: >-
2908
+ ChangesetSolutionFromRecord401403Response.ts
2909
+ type: >-
2910
+ file
2911
+ - name: >-
2912
+ ChangesetSolutionFromRecord404Response.ts
2913
+ type: >-
2914
+ file
2915
+ - name: >-
2916
+ ChangesetSolutionFromRecord4xx5xxResponse.ts
2917
+ type: >-
2918
+ file
2919
+ - name: >-
2920
+ CloneUserToken200Response.ts
2921
+ type: >-
2922
+ file
2923
+ - name: >-
2924
+ CloneUserTokenRequest.ts
2925
+ type: >-
2926
+ file
2927
+ - name: >-
2928
+ CopyApp200Response.ts
2929
+ type: >-
2930
+ file
2931
+ - name: >-
2932
+ CopyAppRequest.ts
2933
+ type: >-
2934
+ file
2935
+ - name: >-
2936
+ CopyAppRequestProperties.ts
2937
+ type: >-
2938
+ file
2939
+ - name: >-
2940
+ CreateApp200Response.ts
2941
+ type: >-
2942
+ file
2943
+ - name: >-
2944
+ CreateAppRequest.ts
2945
+ type: >-
2946
+ file
2947
+ - name: >-
2948
+ CreateField200Response.ts
2949
+ type: >-
2950
+ file
2951
+ - name: >-
2952
+ CreateFieldRequest.ts
2953
+ type: >-
2954
+ file
2955
+ - name: >-
2956
+ CreateRelationship200Response.ts
2957
+ type: >-
2958
+ file
2959
+ - name: >-
2960
+ CreateRelationshipRequest.ts
2961
+ type: >-
2962
+ file
2963
+ - name: >-
2964
+ CreateSolution200Response.ts
2965
+ type: >-
2966
+ file
2967
+ - name: >-
2968
+ CreateSolution400Response.ts
2969
+ type: >-
2970
+ file
2971
+ - name: >-
2972
+ CreateSolution401403Response.ts
2973
+ type: >-
2974
+ file
2975
+ - name: >-
2976
+ CreateSolution4xx5xxResponse.ts
2977
+ type: >-
2978
+ file
2979
+ - name: >-
2980
+ CreateSolutionFromRecord200Response.ts
2981
+ type: >-
2982
+ file
2983
+ - name: >-
2984
+ CreateSolutionFromRecord200ResponseInner.ts
2985
+ type: >-
2986
+ file
2987
+ - name: >-
2988
+ CreateSolutionFromRecord200ResponseInnerCreatedResourcesInner.ts
2989
+ type: >-
2990
+ file
2991
+ - name: >-
2992
+ CreateSolutionFromRecord200ResponseInnerCreatedResourcesInnerAppsInner.ts
2993
+ type: >-
2994
+ file
2995
+ - name: >-
2996
+ CreateSolutionFromRecord400Response.ts
2997
+ type: >-
2998
+ file
2999
+ - name: >-
3000
+ CreateSolutionFromRecord401403Response.ts
3001
+ type: >-
3002
+ file
3003
+ - name: >-
3004
+ CreateSolutionFromRecord404Response.ts
3005
+ type: >-
3006
+ file
3007
+ - name: >-
3008
+ CreateSolutionFromRecord4xx5xxResponse.ts
3009
+ type: >-
3010
+ file
3011
+ - name: >-
3012
+ CreateTable200Response.ts
3013
+ type: >-
3014
+ file
3015
+ - name: >-
3016
+ CreateTableRequest.ts
3017
+ type: >-
3018
+ file
3019
+ - name: >-
3020
+ DeactivateUserToken200Response.ts
3021
+ type: >-
3022
+ file
3023
+ - name: >-
3024
+ DeleteApp200Response.ts
3025
+ type: >-
3026
+ file
3027
+ - name: >-
3028
+ DeleteAppRequest.ts
3029
+ type: >-
3030
+ file
3031
+ - name: >-
3032
+ DeleteFields200Response.ts
3033
+ type: >-
3034
+ file
3035
+ - name: >-
3036
+ DeleteFieldsRequest.ts
3037
+ type: >-
3038
+ file
3039
+ - name: >-
3040
+ DeleteFile200Response.ts
3041
+ type: >-
3042
+ file
3043
+ - name: >-
3044
+ DeleteRecords200Response.ts
3045
+ type: >-
3046
+ file
3047
+ - name: >-
3048
+ DeleteRecordsRequest.ts
3049
+ type: >-
3050
+ file
3051
+ - name: >-
3052
+ DeleteRelationship200Response.ts
3053
+ type: >-
3054
+ file
3055
+ - name: >-
3056
+ DeleteTable200Response.ts
3057
+ type: >-
3058
+ file
3059
+ - name: >-
3060
+ DeleteUserToken200Response.ts
3061
+ type: >-
3062
+ file
3063
+ - name: >-
3064
+ DenyUsers200Response.ts
3065
+ type: >-
3066
+ file
3067
+ - name: >-
3068
+ DenyUsersAndGroups200Response.ts
3069
+ type: >-
3070
+ file
3071
+ - name: >-
3072
+ DenyUsersAndGroupsRequest.ts
3073
+ type: >-
3074
+ file
3075
+ - name: >-
3076
+ DenyUsersRequest.ts
3077
+ type: >-
3078
+ file
3079
+ - name: >-
3080
+ DownloadFile200Response.ts
3081
+ type: >-
3082
+ file
3083
+ - name: >-
3084
+ ExchangeSsoToken200Response.ts
3085
+ type: >-
3086
+ file
3087
+ - name: >-
3088
+ ExchangeSsoTokenRequest.ts
3089
+ type: >-
3090
+ file
3091
+ - name: >-
3092
+ ExportSolution200Response.ts
3093
+ type: >-
3094
+ file
3095
+ - name: >-
3096
+ ExportSolution400Response.ts
3097
+ type: >-
3098
+ file
3099
+ - name: >-
3100
+ ExportSolution401403Response.ts
3101
+ type: >-
3102
+ file
3103
+ - name: >-
3104
+ ExportSolution404Response.ts
3105
+ type: >-
3106
+ file
3107
+ - name: >-
3108
+ ExportSolution4xx5xxResponse.ts
3109
+ type: >-
3110
+ file
3111
+ - name: >-
3112
+ ExportSolutionToRecord200Response.ts
3113
+ type: >-
3114
+ file
3115
+ - name: >-
3116
+ ExportSolutionToRecord200ResponseInner.ts
3117
+ type: >-
3118
+ file
3119
+ - name: >-
3120
+ ExportSolutionToRecord400Response.ts
3121
+ type: >-
3122
+ file
3123
+ - name: >-
3124
+ ExportSolutionToRecord401403Response.ts
3125
+ type: >-
3126
+ file
3127
+ - name: >-
3128
+ ExportSolutionToRecord404Response.ts
3129
+ type: >-
3130
+ file
3131
+ - name: >-
3132
+ ExportSolutionToRecord4xx5xxResponse.ts
3133
+ type: >-
3134
+ file
3135
+ - name: >-
3136
+ GenerateDocument200Response.ts
3137
+ type: >-
3138
+ file
3139
+ - name: >-
3140
+ GetApp200Response.ts
3141
+ type: >-
3142
+ file
3143
+ - name: >-
3144
+ GetAppEvents200Response.ts
3145
+ type: >-
3146
+ file
3147
+ - name: >-
3148
+ GetAppTables200Response.ts
3149
+ type: >-
3150
+ file
3151
+ - name: >-
3152
+ GetField200Response.ts
3153
+ type: >-
3154
+ file
3155
+ - name: >-
3156
+ GetFieldUsage200Response.ts
3157
+ type: >-
3158
+ file
3159
+ - name: >-
3160
+ GetFields200Response.ts
3161
+ type: >-
3162
+ file
3163
+ - name: >-
3164
+ GetFieldsUsage200Response.ts
3165
+ type: >-
3166
+ file
3167
+ - name: >-
3168
+ GetRelationships200Response.ts
3169
+ type: >-
3170
+ file
3171
+ - name: >-
3172
+ GetReport200Response.ts
3173
+ type: >-
3174
+ file
3175
+ - name: >-
3176
+ GetTable200Response.ts
3177
+ type: >-
3178
+ file
3179
+ - name: >-
3180
+ GetTableReports200Response.ts
3181
+ type: >-
3182
+ file
3183
+ - name: >-
3184
+ GetTempTokenDBID200Response.ts
3185
+ type: >-
3186
+ file
3187
+ - name: >-
3188
+ GetUsers200Response.ts
3189
+ type: >-
3190
+ file
3191
+ - name: >-
3192
+ GetUsersRequest.ts
3193
+ type: >-
3194
+ file
3195
+ - name: >-
3196
+ Permission.ts
3197
+ type: >-
3198
+ file
3199
+ - name: >-
3200
+ PlatformAnalyticEventSummaries200Response.ts
3201
+ type: >-
3202
+ file
3203
+ - name: >-
3204
+ PlatformAnalyticEventSummaries200ResponseMetadata.ts
3205
+ type: >-
3206
+ file
3207
+ - name: >-
3208
+ PlatformAnalyticEventSummaries200ResponseResultsInner.ts
3209
+ type: >-
3210
+ file
3211
+ - name: >-
3212
+ PlatformAnalyticEventSummaries200ResponseResultsInnerEventTypesInner.ts
3213
+ type: >-
3214
+ file
3215
+ - name: >-
3216
+ PlatformAnalyticEventSummaries200ResponseResultsInnerTotals.ts
3217
+ type: >-
3218
+ file
3219
+ - name: >-
3220
+ PlatformAnalyticEventSummaries200ResponseTotals.ts
3221
+ type: >-
3222
+ file
3223
+ - name: >-
3224
+ PlatformAnalyticEventSummaries200ResponseWhereInner.ts
3225
+ type: >-
3226
+ file
3227
+ - name: >-
3228
+ PlatformAnalyticEventSummariesRequest.ts
3229
+ type: >-
3230
+ file
3231
+ - name: >-
3232
+ PlatformAnalyticEventSummariesRequestWhereInner.ts
3233
+ type: >-
3234
+ file
3235
+ - name: >-
3236
+ PlatformAnalyticReads200Response.ts
3237
+ type: >-
3238
+ file
3239
+ - name: >-
3240
+ Record.ts
3241
+ type: >-
3242
+ file
3243
+ - name: >-
3244
+ RecordValue.ts
3245
+ type: >-
3246
+ file
3247
+ - name: >-
3248
+ RemoveManagersFromGroup200Response.ts
3249
+ type: >-
3250
+ file
3251
+ - name: >-
3252
+ RemoveManagersFromGroupRequest.ts
3253
+ type: >-
3254
+ file
3255
+ - name: >-
3256
+ RemoveMembersFromGroup200Response.ts
3257
+ type: >-
3258
+ file
3259
+ - name: >-
3260
+ RemoveMembersFromGroupRequest.ts
3261
+ type: >-
3262
+ file
3263
+ - name: >-
3264
+ RemoveSubgroupsFromGroup200Response.ts
3265
+ type: >-
3266
+ file
3267
+ - name: >-
3268
+ RemoveSubgroupsFromGroupRequest.ts
3269
+ type: >-
3270
+ file
3271
+ - name: >-
3272
+ RunFormula200Response.ts
3273
+ type: >-
3274
+ file
3275
+ - name: >-
3276
+ RunFormulaRequest.ts
3277
+ type: >-
3278
+ file
3279
+ - name: >-
3280
+ RunQuery200Response.ts
3281
+ type: >-
3282
+ file
3283
+ - name: >-
3284
+ RunQueryRequest.ts
3285
+ type: >-
3286
+ file
3287
+ - name: >-
3288
+ RunReport200Response.ts
3289
+ type: >-
3290
+ file
3291
+ - name: >-
3292
+ TransferUserToken200Response.ts
3293
+ type: >-
3294
+ file
3295
+ - name: >-
3296
+ TransferUserTokenRequest.ts
3297
+ type: >-
3298
+ file
3299
+ - name: >-
3300
+ UndenyUsers200Response.ts
3301
+ type: >-
3302
+ file
3303
+ - name: >-
3304
+ UndenyUsersRequest.ts
3305
+ type: >-
3306
+ file
3307
+ - name: >-
3308
+ UpdateApp200Response.ts
3309
+ type: >-
3310
+ file
3311
+ - name: >-
3312
+ UpdateAppRequest.ts
3313
+ type: >-
3314
+ file
3315
+ - name: >-
3316
+ UpdateField200Response.ts
3317
+ type: >-
3318
+ file
3319
+ - name: >-
3320
+ UpdateFieldRequest.ts
3321
+ type: >-
3322
+ file
3323
+ - name: >-
3324
+ UpdateRelationship200Response.ts
3325
+ type: >-
3326
+ file
3327
+ - name: >-
3328
+ UpdateRelationshipRequest.ts
3329
+ type: >-
3330
+ file
3331
+ - name: >-
3332
+ UpdateSolution200Response.ts
3333
+ type: >-
3334
+ file
3335
+ - name: >-
3336
+ UpdateSolution200ResponseInner.ts
3337
+ type: >-
3338
+ file
3339
+ - name: >-
3340
+ UpdateSolution200ResponseInnerCreatedResourcesInner.ts
3341
+ type: >-
3342
+ file
3343
+ - name: >-
3344
+ UpdateSolution400Response.ts
3345
+ type: >-
3346
+ file
3347
+ - name: >-
3348
+ UpdateSolution401403Response.ts
3349
+ type: >-
3350
+ file
3351
+ - name: >-
3352
+ UpdateSolution4xx5xxResponse.ts
3353
+ type: >-
3354
+ file
3355
+ - name: >-
3356
+ UpdateSolutionToRecord200Response.ts
3357
+ type: >-
3358
+ file
3359
+ - name: >-
3360
+ UpdateSolutionToRecord200ResponseInner.ts
3361
+ type: >-
3362
+ file
3363
+ - name: >-
3364
+ UpdateSolutionToRecord400Response.ts
3365
+ type: >-
3366
+ file
3367
+ - name: >-
3368
+ UpdateSolutionToRecord401403Response.ts
3369
+ type: >-
3370
+ file
3371
+ - name: >-
3372
+ UpdateSolutionToRecord404Response.ts
3373
+ type: >-
3374
+ file
3375
+ - name: >-
3376
+ UpdateSolutionToRecord4xx5xxResponse.ts
3377
+ type: >-
3378
+ file
3379
+ - name: >-
3380
+ UpdateTable200Response.ts
3381
+ type: >-
3382
+ file
3383
+ - name: >-
3384
+ UpdateTableRequest.ts
3385
+ type: >-
3386
+ file
3387
+ - name: >-
3388
+ Upsert200Response.ts
3389
+ type: >-
3390
+ file
3391
+ - name: >-
3392
+ Upsert207Response.ts
3393
+ type: >-
3394
+ file
3395
+ - name: >-
3396
+ Upsert400Response.ts
3397
+ type: >-
3398
+ file
3399
+ - name: >-
3400
+ UpsertRequest.ts
3401
+ type: >-
3402
+ file
3403
+ - name: >-
3404
+ index.ts
3405
+ type: >-
3406
+ file
3407
+ - name: >-
3408
+ runtime.ts
3409
+ type: >-
3410
+ file
3411
+ - name: >-
3412
+ generated-unified
3413
+ type: >-
3414
+ directory
3415
+ children:
3416
+ - name: >-
3417
+ QuickbaseClient.ts
3418
+ type: >-
3419
+ file
3420
+ - name: >-
3421
+ missing-types-report.json
3422
+ type: >-
3423
+ file
3424
+ - name: >-
3425
+ index.ts
3426
+ type: >-
3427
+ file
3428
+ - name: >-
3429
+ quickbaseClient.ts
3430
+ type: >-
3431
+ file
3432
+ - name: >-
3433
+ tokenCache.ts
3434
+ type: >-
3435
+ file
3436
+ - name: >-
3437
+ utils.ts
3438
+ type: >-
3439
+ file
3440
+ - name: >-
3441
+ test-artifacts
3442
+ type: >-
3443
+ directory
3444
+ children:
3445
+ - name: >-
3446
+ .last-run.json
3447
+ type: >-
3448
+ file
3449
+ - name: >-
3450
+ test-results.json
3451
+ type: >-
3452
+ file
3453
+ - name: >-
3454
+ test-esm.js
3455
+ type: >-
3456
+ file
3457
+ - name: >-
3458
+ test-results.json
3459
+ type: >-
3460
+ file
3461
+ - name: >-
3462
+ test-umd.js
3463
+ type: >-
3464
+ file
3465
+ - name: >-
3466
+ test.ts
3467
+ type: >-
3468
+ file
3469
+ - name: >-
3470
+ tests
3471
+ type: >-
3472
+ directory
3473
+ children:
3474
+ - name: >-
3475
+ playwright
3476
+ type: >-
3477
+ directory
3478
+ children:
3479
+ - name: >-
3480
+ qb
3481
+ type: >-
3482
+ directory
3483
+ children:
3484
+ - name: >-
3485
+ auth
3486
+ type: >-
3487
+ directory
3488
+ children:
3489
+ - name: >-
3490
+ cacheSwitching.test.ts
3491
+ type: >-
3492
+ file
3493
+ - name: >-
3494
+ fetchTempToken401.test.ts
3495
+ type: >-
3496
+ file
3497
+ - name: >-
3498
+ getAppWithTempToken.test.ts
3499
+ type: >-
3500
+ file
3501
+ - name: >-
3502
+ getAppWithUserToken.test.ts
3503
+ type: >-
3504
+ file
3505
+ - name: >-
3506
+ getTempToken.test.ts
3507
+ type: >-
3508
+ file
3509
+ - name: >-
3510
+ tokenPrefetch.test.ts
3511
+ type: >-
3512
+ file
3513
+ - name: >-
3514
+ tokenRenewal.test.ts
3515
+ type: >-
3516
+ file
3517
+ - name: >-
3518
+ setup.ts
3519
+ type: >-
3520
+ file
3521
+ - name: >-
3522
+ vitest
3523
+ type: >-
3524
+ directory
3525
+ children:
3526
+ - name: >-
3527
+ qb
3528
+ type: >-
3529
+ directory
3530
+ children:
3531
+ - name: >-
3532
+ apps
3533
+ type: >-
3534
+ directory
3535
+ children:
3536
+ - name: >-
3537
+ copyApp.test.ts
3538
+ type: >-
3539
+ file
3540
+ - name: >-
3541
+ createApp.test.ts
3542
+ type: >-
3543
+ file
3544
+ - name: >-
3545
+ deleteApp.test.ts
3546
+ type: >-
3547
+ file
3548
+ - name: >-
3549
+ getApp.test.ts
3550
+ type: >-
3551
+ file
3552
+ - name: >-
3553
+ fields
3554
+ type: >-
3555
+ directory
3556
+ children:
3557
+ - name: >-
3558
+ createField.test.ts
3559
+ type: >-
3560
+ file
3561
+ - name: >-
3562
+ deleteFields.test.ts
3563
+ type: >-
3564
+ file
3565
+ - name: >-
3566
+ getField.test.ts
3567
+ type: >-
3568
+ file
3569
+ - name: >-
3570
+ getFieldUsage.test.ts
3571
+ type: >-
3572
+ file
3573
+ - name: >-
3574
+ getFields.test.ts
3575
+ type: >-
3576
+ file
3577
+ - name: >-
3578
+ getFieldsUsage.test.ts
3579
+ type: >-
3580
+ file
3581
+ - name: >-
3582
+ index.ts
3583
+ type: >-
3584
+ file
3585
+ - name: >-
3586
+ records
3587
+ type: >-
3588
+ directory
3589
+ children:
3590
+ - name: >-
3591
+ deleteRecords.test.ts
3592
+ type: >-
3593
+ file
3594
+ - name: >-
3595
+ runQuery.test.ts
3596
+ type: >-
3597
+ file
3598
+ - name: >-
3599
+ upsert.test.ts
3600
+ type: >-
3601
+ file
3602
+ - name: >-
3603
+ tables
3604
+ type: >-
3605
+ directory
3606
+ children:
3607
+ - name: >-
3608
+ createTable.test.ts
3609
+ type: >-
3610
+ file
3611
+ - name: >-
3612
+ deleteTable.test.ts
3613
+ type: >-
3614
+ file
3615
+ - name: >-
3616
+ getAppTables.test.ts
3617
+ type: >-
3618
+ file
3619
+ - name: >-
3620
+ getRelationships.test.ts
3621
+ type: >-
3622
+ file
3623
+ - name: >-
3624
+ getTable.test.ts
3625
+ type: >-
3626
+ file
3627
+ - name: >-
3628
+ updateTable.test.ts
3629
+ type: >-
3630
+ file
3631
+ - name: >-
3632
+ unit
3633
+ type: >-
3634
+ directory
3635
+ children:
3636
+ - name: >-
3637
+ apps
3638
+ type: >-
3639
+ directory
3640
+ children:
3641
+ - name: >-
3642
+ copyApp.test.ts
3643
+ type: >-
3644
+ file
3645
+ - name: >-
3646
+ createApp.test.ts
3647
+ type: >-
3648
+ file
3649
+ - name: >-
3650
+ deleteApp.test.ts
3651
+ type: >-
3652
+ file
3653
+ - name: >-
3654
+ getApp.test.ts
3655
+ type: >-
3656
+ file
3657
+ - name: >-
3658
+ auth
3659
+ type: >-
3660
+ directory
3661
+ children:
3662
+ - name: >-
3663
+ fetchTempToken401.test.ts
3664
+ type: >-
3665
+ file
3666
+ - name: >-
3667
+ getTempToken.test.ts
3668
+ type: >-
3669
+ file
3670
+ - name: >-
3671
+ retryOn401.test.ts
3672
+ type: >-
3673
+ file
3674
+ - name: >-
3675
+ two401s.test.ts
3676
+ type: >-
3677
+ file
3678
+ - name: >-
3679
+ fields
3680
+ type: >-
3681
+ directory
3682
+ children:
3683
+ - name: >-
3684
+ createField.test.ts
3685
+ type: >-
3686
+ file
3687
+ - name: >-
3688
+ deleteFields.test.ts
3689
+ type: >-
3690
+ file
3691
+ - name: >-
3692
+ getField.test.ts
3693
+ type: >-
3694
+ file
3695
+ - name: >-
3696
+ getFieldUsage.test.ts
3697
+ type: >-
3698
+ file
3699
+ - name: >-
3700
+ getFields.test.ts
3701
+ type: >-
3702
+ file
3703
+ - name: >-
3704
+ getFieldsUsage.test.ts
3705
+ type: >-
3706
+ file
3707
+ - name: >-
3708
+ index.ts
3709
+ type: >-
3710
+ file
3711
+ - name: >-
3712
+ records
3713
+ type: >-
3714
+ directory
3715
+ children:
3716
+ - name: >-
3717
+ deleteRecords.test.ts
3718
+ type: >-
3719
+ file
3720
+ - name: >-
3721
+ runQuery.test.ts
3722
+ type: >-
3723
+ file
3724
+ - name: >-
3725
+ upsert.test.ts
3726
+ type: >-
3727
+ file
3728
+ - name: >-
3729
+ tables
3730
+ type: >-
3731
+ directory
3732
+ children:
3733
+ - name: >-
3734
+ createTable.test.ts
3735
+ type: >-
3736
+ file
3737
+ - name: >-
3738
+ deleteTable.test.ts
3739
+ type: >-
3740
+ file
3741
+ - name: >-
3742
+ getAppTables.test.ts
3743
+ type: >-
3744
+ file
3745
+ - name: >-
3746
+ getRelationships.test.ts
3747
+ type: >-
3748
+ file
3749
+ - name: >-
3750
+ getTable.test.ts
3751
+ type: >-
3752
+ file
3753
+ - name: >-
3754
+ updateTable.test.ts
3755
+ type: >-
3756
+ file
3757
+ - name: >-
3758
+ umd.test.ts
3759
+ type: >-
3760
+ file
3761
+ - name: >-
3762
+ text.txt
3763
+ type: >-
3764
+ file
3765
+ - name: >-
3766
+ tools
3767
+ type: >-
3768
+ directory
3769
+ children:
3770
+ - name: >-
3771
+ generate-types.ts
3772
+ type: >-
3773
+ file
3774
+ - name: >-
3775
+ log-gen.ts
3776
+ type: >-
3777
+ file
3778
+ - name: >-
3779
+ log-gen.yaml
3780
+ type: >-
3781
+ file
3782
+ - name: >-
3783
+ openapi-jars
3784
+ type: >-
3785
+ directory
3786
+ children:
3787
+ - name: >-
3788
+ openapi-generator-cli-7.12.0.jar
3789
+ type: >-
3790
+ file
3791
+ - name: >-
3792
+ openapi-schema-validator.ts
3793
+ type: >-
3794
+ file
3795
+ - name: >-
3796
+ spec-analyzer.ts
3797
+ type: >-
3798
+ file
3799
+ - name: >-
3800
+ split-spec.ts
3801
+ type: >-
3802
+ file
3803
+ - name: >-
3804
+ test-import.ts
3805
+ type: >-
3806
+ file
3807
+ - name: >-
3808
+ validate-spec.ts
3809
+ type: >-
3810
+ file
3811
+ - name: >-
3812
+ tsconfig.build.json
3813
+ type: >-
3814
+ file
3815
+ - name: >-
3816
+ tsconfig.json
3817
+ type: >-
3818
+ file
3819
+ - name: >-
3820
+ versionrc.json
3821
+ type: >-
3822
+ file
3823
+ - name: >-
3824
+ vitest.config.ts
3825
+ type: >-
3826
+ file