From 3907d05678afba860d414aba7c3b1f4fed42c742 Mon Sep 17 00:00:00 2001
From: yyyyaaa
Date: Mon, 17 Aug 2026 12:39:03 +0700
Subject: [PATCH 1/2] test: remove low-value coverage
---
TEST_SUITE_AUDIT.md | 125 +
apps/blocks/e2e/docs.smoke.spec.ts | 150 +-
apps/blocks/e2e/mobile.interaction.spec.ts | 284 +-
apps/blocks/src/app/sitemap.test.ts | 42 -
.../constructive-console-kit.test.tsx | 28 -
.../store/console-kit-store.test.ts | 100 -
.../billing-showcase-preview.test.tsx | 150 +-
.../billing-showcase-resources.test.ts | 36 -
.../src/components/docs/ui-demos.test.tsx | 48 -
.../components/site/registry-shell.test.tsx | 75 -
.../src/components/site/site-topbar.test.tsx | 91 +-
apps/blocks/src/feature-packs/catalog.test.ts | 73 -
apps/blocks/src/lib/ai-docs.test.ts | 22 -
apps/blocks/src/lib/base-primitives.test.ts | 72 -
apps/blocks/src/lib/billing-blocks.test.ts | 35 -
apps/blocks/src/lib/feature-packs.test.ts | 47 -
.../src/__tests__/keybinding.test.ts | 304 +-
.../src/__tests__/multi-step-builder.test.ts | 136 +-
.../src/__tests__/registry.test.ts | 188 +-
.../data/src/__tests__/complex-fields.test.ts | 547 --
.../data/src/__tests__/data.types.test.ts | 60 +-
.../src/__tests__/mutation-input.node.test.ts | 25 -
.../__snapshots__/builder.test.ts.snap | 507 --
.../meta-object.node.test.ts.snap | 6568 -----------------
.../__snapshots__/meta-object.test.ts.snap | 6568 -----------------
.../__tests__/meta-object.node.test.ts | 4 -
.../src/__tests__/query-generator.test.ts | 8 -
.../schema-builder-layout-motion.test.tsx | 392 -
.../__tests__/schema-builder-render.test.tsx | 147 +-
.../schema-builder-selectors.test.tsx | 90 +-
.../tables/create-table-card.test.tsx | 257 -
.../__tests__/create-sheets-cell.test.ts | 46 +
.../__tests__/kind-parity.test-d.ts | 13 -
.../src/cell-model/create-sheets-cell.ts | 4 +-
.../src/cell-model/factories/boolean.ts | 10 +-
.../src/cell-model/factories/datetime.ts | 2 +-
.../src/cell-model/factories/geometry.ts | 5 +-
.../sheets/src/cell-model/factories/number.ts | 9 +-
.../src/cell-model/factories/relation.ts | 6 +-
.../sheets/src/cell-model/factories/text.ts | 5 +-
.../sheets/src/cell-model/factories/uri.ts | 5 +-
packages/sheets/src/cell-model/sheets-cell.ts | 9 +-
.../__tests__/draft-action-view.test.tsx | 31 -
.../views/__tests__/geometry-view.test.tsx | 126 -
.../views/__tests__/image-view.test.tsx | 151 -
.../views/__tests__/loading-view.test.tsx | 78 -
.../views/__tests__/relation-view.test.tsx | 107 -
.../__tests__/registry-sheetscell.test.ts | 69 -
.../__tests__/default-commands.test.ts | 200 -
.../src/commands/__tests__/keymap.test.ts | 18 +-
.../src/commands/__tests__/registry.test.ts | 12 +-
.../__tests__/sheets-dom.parity.test.tsx | 175 -
.../__tests__/sheets-dom.smoke.test.tsx | 139 -
.../editors/__tests__/edit-intent.test.ts | 221 +-
.../grid/__golden__/cell-display.golden.json | 496 --
.../cell-display.sheets.parity.test.ts | 31 -
.../src/grid/__golden__/coverage.meta.test.ts | 110 -
.../src/grid/__golden__/display-cases.ts | 13 +-
.../src/grid/__golden__/harness.self.test.ts | 119 -
.../src/grid/__golden__/parity.harness.ts | 298 -
.../__golden__/post-processing.golden.json | 293 -
.../__golden__/post-processing.golden.test.ts | 212 -
.../src/grid/__golden__/resolver.golden.json | 2243 ------
.../grid/__golden__/resolver.golden.test.ts | 227 -
.../src/grid/__golden__/selection.golden.json | 1054 ---
.../grid/__golden__/selection.golden.test.ts | 389 -
.../grid/__golden__/sheets-dom.golden.json | 3038 --------
.../grid/__tests__/cell-type-resolver.test.ts | 46 +
.../grid/__tests__/registry-fidelity.test.ts | 141 -
.../__tests__/range-set.golden.test.ts | 108 -
.../src/selection/__tests__/range-set.test.ts | 36 +
packages/sheets/src/selection/range-set.ts | 10 +-
.../stories/__tests__/stories-render.test.tsx | 192 +-
.../sheets/src/stories/_support/fixtures.ts | 8 +-
.../grid-viewport-active-cell.test.tsx | 7 +-
.../__tests__/grid-viewport-header.test.tsx | 18 -
.../grid-viewport-rowmarker.test.tsx | 40 -
.../__tests__/mock-execute-roundtrip.test.ts | 137 -
packages/ui/test/app-shell.test.tsx | 104 +-
packages/ui/test/button-as-child.test.tsx | 39 -
packages/ui/test/field-empty.test.tsx | 78 -
packages/ui/test/select-transition.test.tsx | 51 -
packages/ui/test/stack-animation.test.tsx | 153 -
83 files changed, 526 insertions(+), 27785 deletions(-)
create mode 100644 TEST_SUITE_AUDIT.md
delete mode 100644 apps/blocks/src/app/sitemap.test.ts
delete mode 100644 apps/blocks/src/components/docs/ui-demos.test.tsx
delete mode 100644 apps/blocks/src/components/site/registry-shell.test.tsx
delete mode 100644 apps/blocks/src/lib/ai-docs.test.ts
delete mode 100644 apps/blocks/src/lib/base-primitives.test.ts
delete mode 100644 apps/blocks/src/lib/billing-blocks.test.ts
delete mode 100644 apps/blocks/src/lib/feature-packs.test.ts
delete mode 100644 packages/data/src/__tests__/complex-fields.test.ts
delete mode 100644 packages/data/src/__tests__/query-builder/__tests__/__snapshots__/builder.test.ts.snap
delete mode 100644 packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.node.test.ts.snap
delete mode 100644 packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.test.ts.snap
delete mode 100644 packages/schema-builder/src/__tests__/schema-builder-layout-motion.test.tsx
delete mode 100644 packages/schema-builder/src/schema/schema-builder-policies/components/tables/create-table-card.test.tsx
create mode 100644 packages/sheets/src/cell-model/__tests__/create-sheets-cell.test.ts
delete mode 100644 packages/sheets/src/cell-model/__tests__/kind-parity.test-d.ts
delete mode 100644 packages/sheets/src/cell-model/views/__tests__/geometry-view.test.tsx
delete mode 100644 packages/sheets/src/cell-model/views/__tests__/image-view.test.tsx
delete mode 100644 packages/sheets/src/cell-model/views/__tests__/loading-view.test.tsx
delete mode 100644 packages/sheets/src/cell-model/views/__tests__/relation-view.test.tsx
delete mode 100644 packages/sheets/src/cell-types/__tests__/registry-sheetscell.test.ts
delete mode 100644 packages/sheets/src/commands/__tests__/default-commands.test.ts
delete mode 100644 packages/sheets/src/grid-dom/__tests__/sheets-dom.parity.test.tsx
delete mode 100644 packages/sheets/src/grid-dom/__tests__/sheets-dom.smoke.test.tsx
delete mode 100644 packages/sheets/src/grid/__golden__/cell-display.golden.json
delete mode 100644 packages/sheets/src/grid/__golden__/cell-display.sheets.parity.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/coverage.meta.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/harness.self.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/parity.harness.ts
delete mode 100644 packages/sheets/src/grid/__golden__/post-processing.golden.json
delete mode 100644 packages/sheets/src/grid/__golden__/post-processing.golden.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/resolver.golden.json
delete mode 100644 packages/sheets/src/grid/__golden__/resolver.golden.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/selection.golden.json
delete mode 100644 packages/sheets/src/grid/__golden__/selection.golden.test.ts
delete mode 100644 packages/sheets/src/grid/__golden__/sheets-dom.golden.json
create mode 100644 packages/sheets/src/grid/__tests__/cell-type-resolver.test.ts
delete mode 100644 packages/sheets/src/grid/__tests__/registry-fidelity.test.ts
delete mode 100644 packages/sheets/src/selection/__tests__/range-set.golden.test.ts
create mode 100644 packages/sheets/src/selection/__tests__/range-set.test.ts
delete mode 100644 packages/sheets/src/testing/__tests__/mock-execute-roundtrip.test.ts
delete mode 100644 packages/ui/test/field-empty.test.tsx
delete mode 100644 packages/ui/test/select-transition.test.tsx
delete mode 100644 packages/ui/test/stack-animation.test.tsx
diff --git a/TEST_SUITE_AUDIT.md b/TEST_SUITE_AUDIT.md
new file mode 100644
index 0000000..3498a39
--- /dev/null
+++ b/TEST_SUITE_AUDIT.md
@@ -0,0 +1,125 @@
+# Test suite audit
+
+This audit removes tests that restated static structure, catalog contents, mock behavior, or visual implementation. It keeps runtime validation, security and tenancy rules, state transitions, user workflows, serialization, persistence-facing adapters, and difficult failure behavior.
+
+## Result
+
+- The normal test suite moved from 185 to 157 test files and from 1,491 to 1,157 cases.
+- 31 test files were deleted, three focused contract files were added, and 27 existing files were rewritten or consolidated.
+- 334 Vitest/Node cases and six Playwright cases were removed, for 340 fewer cases in the audited files.
+- Nine obsolete snapshot, golden-data, and parity-harness artifacts were deleted.
+
+The counts include the unchanged registry and repository script tests. Playwright is counted separately because `pnpm test` does not run it.
+
+## Application and documentation tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `apps/blocks/e2e/docs.smoke.spec.ts` | Rewrite, 4 → 1 | Enumerated every catalog page, heading, and example count. That duplicated static catalogs and coupled the test to editorial inventory. | The pages build and generated-content checks protect valid pages. The retained browser test protects the runtime 404 contract for removed and unknown routes. |
+| `apps/blocks/e2e/mobile.interaction.spec.ts` | Consolidate, 5 → 2 | Checked breakpoints, CSS overflow, touch-target dimensions, and viewport geometry alongside real interactions. The geometry checks were visual-policy tests. | Retained tests complete mobile navigation and verify modal Escape dismissal plus focus restoration. Layout and target sizing remain visual-review concerns. |
+| `apps/blocks/src/app/sitemap.test.ts` | Delete | Compared the sitemap with exact catalog counts and URLs. The test changed whenever documentation inventory changed. | `build:pages`, sitemap compilation, and the browser route tests protect generation and routing. No separate runtime contract was lost. |
+| `apps/blocks/src/components/docs/ui-demos.test.tsx` | Delete | Matched the primitive catalog and mounted every demo without asserting a workflow. | Type checking resolves every component, `gen:check` resolves and extracts demo source, and the pages build mounts the documentation graph. |
+| `apps/blocks/src/components/site/registry-shell.test.tsx` | Delete | Mounted each shell variant and asserted landmarks and documentation chrome existed. | The application build catches composition failures; focused Console Kit and documentation interaction tests protect behavior. |
+| `apps/blocks/src/lib/ai-docs.test.ts` | Delete | Pinned aggregate registry metadata and import strings. | Registry generation and package builds validate these static references. |
+| `apps/blocks/src/lib/base-primitives.test.ts` | Delete | Froze the exact primitive catalog, exports, registry entries, and example import paths. | TypeScript, registry generation, and package/registry builds protect resolvability. Exact editorial inventory is intentionally not a runtime test. |
+| `apps/blocks/src/lib/billing-blocks.test.ts` | Delete | Froze eight block names, guidance fields, and lookup presence. | The typed catalog and pages/registry builds protect structure and resolution. Billing resource behavior remains tested below. |
+| `apps/blocks/src/lib/feature-packs.test.ts` | Delete | Froze seven documentation records, summaries, registry names, and editorial fields. | Typed catalogs, registry manifests, and page generation protect static consistency. Dependency semantics remain in `catalog.test.ts`. |
+| `apps/blocks/src/blocks/console-kit/constructive/constructive-console-kit.test.tsx` | Consolidate, 15 → 14 | Included a barrel/existence assertion for the selected feature pack. | Removed only that static assertion. Adapter normalization, policy enforcement, callbacks, errors, and runtime behavior remain covered. |
+| `apps/blocks/src/blocks/console-kit/store/console-kit-store.test.ts` | Consolidate, 9 → 7 | Inspected initial internal object shape and revision increments. | Store transition tests retain tenant isolation, resource state, invalidation, and observable update behavior. TypeScript protects the state shape. |
+| `apps/blocks/src/components/billing-showcase/billing-showcase-preview.test.tsx` | Consolidate, 8 → 4 | Mounted fixtures, checked labels/loading copy, and asserted scale/layout details in addition to actions. | Retained delegated actions, partial-failure behavior, iframe control state, and full-screen keyboard focus. |
+| `apps/blocks/src/components/billing-showcase/billing-showcase-resources.test.ts` | Consolidate, 4 → 2 | Rechecked fixture completeness and all-success aggregation. | Retained runtime value validation and partial-resource failure semantics, which TypeScript cannot protect. |
+| `apps/blocks/src/components/site/site-topbar.test.tsx` | Consolidate, 11 → 3 | Checked static buttons, labels, hrefs, and presentational variants. | Retained clipboard behavior, feature-pack install mapping, and suppression on unsupported paths. |
+| `apps/blocks/src/feature-packs/catalog.test.ts` | Consolidate, 9 → 5 | Froze exact catalog order, defaults, and sidecar fields. | Retained dependency ordering and malformed-pack rejection. Generated registry checks protect static manifest alignment. |
+
+## Command palette tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `packages/command-palette/src/__tests__/keybinding.test.ts` | Rewrite, 32 → 5 | Enumerated many equivalent key strings and exact formatting branches. | Five table-driven contracts retain platform modifiers, editable-target rejection, modifier matching, and user-visible formatting. |
+| `packages/command-palette/src/__tests__/multi-step-builder.test.ts` | Consolidate, 10 → 3 | Checked fluent-builder method presence and every intermediate property. | Retained ordered step output and runtime rejection of invalid step configurations. TypeScript protects the fluent API surface. |
+| `packages/command-palette/src/__tests__/registry.test.ts` | Consolidate, 17 → 3 | Proved CRUD methods delegated to the current Map/Set implementation and counted notifications. | Retained dynamic replacement/removal and subscriber-visible changes. Registration existence is covered by bootstrap and execution tests. |
+
+## Data tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `packages/data/src/__tests__/complex-fields.test.ts` | Delete | Mocked every `custom-ast` import, then asserted that the mocks returned their own fixtures. It tested the mock instead of the adapter. | Query-builder integration tests still protect owned GraphQL output. A direct, unmocked complex-field adapter contract is a genuine remaining gap. |
+| `packages/data/src/__tests__/data.types.test.ts` | Consolidate, 27 → 21 | Created typed filter objects only to assert their fields at runtime. | TypeScript and package declaration generation protect those assignments. Runtime data conversion and query behavior remain covered. |
+| `packages/data/src/__tests__/mutation-input.node.test.ts` | Consolidate, 49 → 47 | Turned `PartialBy` examples into runtime property checks. | The compiler owns this generic type contract; mutation-name, identifier, and input transformation cases remain. |
+| `packages/data/src/__tests__/query-builder/__tests__/meta-object.node.test.ts` | Consolidate, 2 → 1 | Snapshotted a very large complete query in addition to checking meaningful meta-type discovery. | Retained runtime meta-type discovery. Query serialization remains protected by the smaller builder snapshot suite. |
+| `packages/data/src/__tests__/query-generator.test.ts` | Consolidate, 42 → 41 | Asserted only that the builder object exposed methods. | TypeScript and module resolution protect method existence; generated operation behavior and errors remain covered. |
+
+## Schema Builder tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `packages/schema-builder/src/__tests__/schema-builder-layout-motion.test.tsx` | Delete | Inspected CSS classes, motion props, crossfade decomposition, and scroll affordances. | Visual review owns layout and motion. Keyboard, drag-and-drop, route selection, and state behavior remain tested. |
+| `packages/schema-builder/src/schema/schema-builder-policies/components/tables/create-table-card.test.tsx` | Delete | Mocked callback refs and counted scroll-listener allocation and cleanup for a shadow effect. | This was an internal implementation test for visual polish. Browser lifecycle and Strict Mode remain exercised by integration builds and higher-level component tests. |
+| `packages/schema-builder/src/__tests__/schema-builder-render.test.tsx` | Rewrite, 3 → 1 | Included mount-without-crashing and static copy checks. | Retained cross-database scope rejection, which is an observable tenancy boundary. |
+| `packages/schema-builder/src/__tests__/schema-builder-selectors.test.tsx` | Consolidate, 3 → 2 | Counted selector identities and rerenders caused by the current store decomposition. | Retained the host-data boundary and clearing an invalid user selection. |
+
+## Sheets tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `packages/sheets/src/cell-model/__tests__/kind-parity.test-d.ts` | Delete | Proved an internal migration type was assignable to its predecessor. | Package type checking and declaration generation protect the current type graph; the removed predecessor is not a public contract. |
+| `packages/sheets/src/cell-model/__tests__/create-sheets-cell.test.ts` | Add focused contract | Replaces broad parity and registry fixtures with owned transformation behavior. | Protects email normalization, relation label/overflow rules, and suppression of draft placeholder IDs. |
+| `packages/sheets/src/cell-model/views/__tests__/geometry-view.test.tsx` | Delete | Checked icons, abbreviated labels, and empty visual output. | Cell-type resolution remains covered; iconography and labels are visual presentation. |
+| `packages/sheets/src/cell-model/views/__tests__/image-view.test.tsx` | Delete | Checked wrappers, CSS classes, placeholders, and every thumbnail/file-chip presentation branch. | Image editor upload behavior remains covered. Presentational rendering moves to Storybook/visual review. |
+| `packages/sheets/src/cell-model/views/__tests__/loading-view.test.tsx` | Delete | Checked skeleton markup, animation class, and absence of text. | Loading-state functionality remains in the grid loading-skeleton test; shimmer styling is visual. |
+| `packages/sheets/src/cell-model/views/__tests__/relation-view.test.tsx` | Delete | Checked badge and chip markup for four display variants. | The new cell contract test protects relation data semantics; relation-editor tests protect user behavior. Badge layout remains visual. |
+| `packages/sheets/src/cell-model/views/__tests__/draft-action-view.test.tsx` | Consolidate, 7 → 4 | Included default label, static rendering, and no-handler checks. | Retained submit, saving, error/retry, and disabled-action behavior. |
+| `packages/sheets/src/cell-types/__tests__/registry-sheetscell.test.ts` | Delete | Proved registered functions/components were returned and missing keys returned `undefined`. | The dynamic customization seam, registry gating, cell routing, and real DOM host tests protect registry behavior without restating Map lookups. |
+| `packages/sheets/src/commands/__tests__/default-commands.test.ts` | Delete | Asserted exact mock calls for thin default-command delegates. | Pure selection/navigation helpers, command dispatch, keymaps, clipboard, fill, undo, and editor workflow tests protect the underlying behavior. |
+| `packages/sheets/src/commands/__tests__/keymap.test.ts` | Consolidate, 15 → 14 | Froze the full default keymap object. | Retained meaningful key matching and platform behavior; static keymap shape is visible in code and exercised through dispatch. |
+| `packages/sheets/src/commands/__tests__/registry.test.ts` | Consolidate, 4 → 3 | Included one test that only proved default command IDs were registered. | Retained dynamic override and isolation behavior; bootstrap/build protects static registration. |
+| `packages/sheets/src/grid-dom/__tests__/sheets-dom.parity.test.tsx` | Delete | Compared every rendered fixture cell with a frozen migration golden. | Focused DOM interaction and render-safety tests remain. The removed comparison described the retired implementation rather than the current public contract. |
+| `packages/sheets/src/grid-dom/__tests__/sheets-dom.smoke.test.tsx` | Delete | Asserted that a hand-fed grid rendered cells and no canvas. | Real editor, active-cell, virtualization, and render-safety tests already cross the same DOM boundary with meaningful behavior. |
+| `packages/sheets/src/grid-dom/editors/__tests__/edit-intent.test.ts` | Rewrite, 23 → 3 | Enumerated every cell type and mirrored the routing table. | Three contracts retain family routing, readonly rejection, and explicit registry override precedence. |
+| `packages/sheets/src/grid/__golden__/cell-display.sheets.parity.test.ts` | Delete | Compared all factory projections with frozen migration output. | Focused factory semantics and live editor tests protect owned behavior. Static family coverage is handled by TypeScript and the registry build. |
+| `packages/sheets/src/grid/__golden__/coverage.meta.test.ts` | Delete | Tested whether the test fixtures covered every union member and branch. | This was coverage of the harness, not product behavior. TypeScript checks the cell-type records. |
+| `packages/sheets/src/grid/__golden__/harness.self.test.ts` | Delete | Tested projection helpers and asserted the harness maps stayed aligned. | The deleted migration harness no longer has a product role. |
+| `packages/sheets/src/grid/__golden__/post-processing.golden.test.ts` | Delete | Froze relation and draft post-processing plus fixture constants. | Row-model tests protect non-enumerable draft metadata. Focused `createSheetsCell` tests now protect relation transformation. |
+| `packages/sheets/src/grid/__golden__/resolver.golden.test.ts` | Replace, 4 → 3 | Froze more than 80 table-driven mapping outputs and test-fixture size. | `cell-type-resolver.test.ts` retains metadata precedence, readonly identifiers/timestamps, and viewer-only search vectors. Static table inventory is intentionally not frozen. |
+| `packages/sheets/src/grid/__tests__/cell-type-resolver.test.ts` | Add focused contract | Replaces the resolver golden with representative semantic branches. | Protects precedence across aliases, arrays, backend metadata, GraphQL fallback, readonly rules, and viewer-only activation. |
+| `packages/sheets/src/grid/__golden__/selection.golden.test.ts` | Delete | Ran a large operation table and compared one aggregate JSON blob. | The focused `range-set.test.ts` cases make merge, split, offset, and large-range failures local and readable. |
+| `packages/sheets/src/grid/__tests__/registry-fidelity.test.ts` | Delete | Repeated factory output across 21 cases and asserted that the fixture touched every family. | Focused cell contracts, editor behavior, and routing tests protect owned semantics without testing fixture completeness. |
+| `packages/sheets/src/selection/__tests__/range-set.golden.test.ts` | Replace, 24 → 4 | Replayed the retired implementation's captured output across many sequences. | `range-set.test.ts` protects the interval invariants that matter: merging, splitting, offsets, and sparse large ranges. |
+| `packages/sheets/src/selection/__tests__/range-set.test.ts` | Add focused contract | Replaces captured parity with direct domain assertions. | The tests fail on observable selection results and no longer depend on the old implementation. |
+| `packages/sheets/src/stories/__tests__/stories-render.test.tsx` | Rewrite, 14 → 1 | Mounted every story, mostly proving it did not throw, then duplicated the 10k virtualization assertion. | Retained one 10,000-row DOM-window contract. Individual visual stories remain for manual review. |
+| `packages/sheets/src/table/__tests__/grid-viewport-active-cell.test.tsx` | Rewrite assertions, 3 → 3 | Mixed active-cell ARIA behavior with a selected CSS-class assertion. | Removed the styling assertion; retained active-descendant and active-cell accessibility behavior. |
+| `packages/sheets/src/table/__tests__/grid-viewport-header.test.tsx` | Consolidate, 4 → 3 | Included a static header-exists check. | Retained sort toggling, resize behavior, and keyboard interaction. |
+| `packages/sheets/src/table/__tests__/grid-viewport-rowmarker.test.tsx` | Consolidate, 4 → 2 | Included static marker existence and absent-marker rendering checks. | Retained row selection and select-all behavior. |
+| `packages/sheets/src/testing/__tests__/mock-execute-roundtrip.test.ts` | Delete | Validated that the repository's test mock recognized queries and echoed mutations. | Real query builders, the PostGraphile adapter, and `sheets-execute` tests protect production behavior. The mock does not receive its own contract suite. |
+
+## UI tests
+
+| File | Decision | Existing assertion and value | Protection and retained coverage |
+| --- | --- | --- | --- |
+| `packages/ui/test/app-shell.test.tsx` | Consolidate, 4 → 1 | Checked region presence, class names, and static layout composition. | Retained the sidebar's accessible collapsed/expanded state transition. |
+| `packages/ui/test/button-as-child.test.tsx` | Consolidate, 5 → 2 | Checked CSS, touch-target, and motion classes in addition to slot semantics. | Retained ref/event composition through `asChild` and native button behavior. |
+| `packages/ui/test/field-empty.test.tsx` | Delete | Checked legacy slots, upstream surface, CSS classes, and standard empty markup. | TypeScript and the package build protect exports and composition; visual examples own presentation. |
+| `packages/ui/test/select-transition.test.tsx` | Delete | Inspected entering/exiting data attributes for a visual transition. | Select interaction tests in consumers and visual review protect user behavior; the animation implementation is not a stable contract. |
+| `packages/ui/test/stack-animation.test.tsx` | Delete | Mocked motion internals and asserted exact tween/spring sequencing. | Stack context behavior remains covered. Timing and animation curves are visual implementation details. |
+
+## Removed support artifacts
+
+The audit deleted the unused Data snapshots `builder.test.ts.snap`, `meta-object.node.test.ts.snap`, and `meta-object.test.ts.snap`. It also deleted the Sheets migration harness, five golden JSON files, and their stale parity comments. The smaller `builder.node.test.ts.snap` remains because serialized GraphQL output is a public adapter contract.
+
+## High-value coverage retained
+
+- Console Kit still covers authorization, tenant isolation, capability policy, callback/error translation, provisioning cleanup, and fail-closed behavior.
+- Data still covers query serialization, mutation input semantics, schema compatibility, error classification, row identity, and policy provisioning.
+- Command Palette still covers execution, cancellation/background work, reducer transitions, key matching, runtime configuration validation, and dynamic registry changes.
+- Sheets still covers selection invariants, adapter behavior, uploads, batch commit, undo/redo, editors, draft rows, cache/state lifecycles, error gating, accessibility, and virtualization.
+- Schema Builder still covers keyboard and drag behavior, runtime providers, policy CRUD/masks, selection changes, and cross-database scope rejection.
+- UI still covers portals, modal dismissal, SSR, controlled state, accessibility state, and child ref/event composition.
+
+## Remaining coupling and gaps
+
+- `console-kit-effects.test.tsx`, `feature-pack-interactions.test.tsx`, `constructive-console-kit.test.tsx`, and `schemas-route-selection.test.tsx` still have large mock surfaces. Their assertions protect real policy and workflow behavior, but future work should move more setup into contract fixtures or browser-level flows.
+- Several Sheets editor and batch-commit tests mock host context heavily. They protect failure and side-effect behavior, but a small adapter integration harness would reduce coupling.
+- The Data complex-field adapter has no direct unmocked contract test against `@constructive-io/graphql-query/custom-ast`; this is the clearest runtime coverage gap found.
+- Public package types are validated by `tsc` and declaration builds, but there is no dedicated compatibility suite for intentional developer-facing type contracts.
+- Layout, motion, responsive overflow, and ordinary component appearance now rely on Storybook and visual review by design; they should use visual regression only if the repository adopts a stable visual baseline workflow.
+- Live provider behavior remains outside the normal suite and requires the existing explicit live-E2E environment. The local suite continues to test only repository-owned adapter behavior.
diff --git a/apps/blocks/e2e/docs.smoke.spec.ts b/apps/blocks/e2e/docs.smoke.spec.ts
index a020a81..5a424f2 100644
--- a/apps/blocks/e2e/docs.smoke.spec.ts
+++ b/apps/blocks/e2e/docs.smoke.spec.ts
@@ -1,156 +1,12 @@
import { expect, test } from '@playwright/test';
-const routes = [
- ['/blocks/', 'Build the product on Constructive.'],
- ['/blocks/blocks/', 'Install the foundation your way'],
- ['/blocks/blocks/ui/button/', 'Button'],
- ['/blocks/blocks/ui/dialog/', 'Dialog'],
-] as const;
-
-const billingBlocks = [
- 'billing-pricing-table',
- 'billing-subscription-card',
- 'billing-entitlements-list',
- 'billing-usage-overview',
- 'billing-credits-card',
- 'billing-usage-history',
- 'billing-activity-table',
- 'billing-settings-page',
-] as const;
-
-const featurePacks = [
- { id: 'data', previewHeading: 'Data', title: 'Data', variant: 'tables' },
- { id: 'auth', previewHeading: 'Account', title: 'Authentication', variant: 'account' },
- {
- id: 'users',
- previewHeading: 'App access',
- title: 'App access',
- variant: 'directory',
- },
- {
- id: 'organizations',
- previewHeading: 'Organizations',
- title: 'Organizations',
- variant: 'memberships',
- },
- { id: 'storage', previewHeading: 'Storage', title: 'Storage', variant: 'browser' },
- { id: 'billing', previewHeading: 'Billing', title: 'Billing', variant: 'organization' },
- {
- id: 'notifications',
- previewHeading: 'Notifications',
- title: 'Notifications',
- variant: 'inbox',
- },
-] as const;
-
-const billingRoute = (name: string) => `/blocks/blocks/billing/${name}/`;
-const featurePackRoute = (id: string) => `/blocks/blocks/features/${id}/`;
-
-for (const [route, heading] of routes) {
- test(`${route} renders its documentation surface`, async ({ page }) => {
- const response = await page.goto(route, { waitUntil: 'networkidle' });
- expect(response?.status()).toBe(200);
- await expect(page.getByRole('heading', { level: 1, name: heading })).toBeVisible();
- await expect(page.locator('main')).toBeVisible();
- });
-}
-
-test('the primitive catalogs remain complete and legacy block routes stay removed', async ({ page }) => {
- await page.goto('/blocks/', { waitUntil: 'networkidle' });
- await expect(page.locator('section[aria-labelledby="component-showcase"] a[href*="/ui/"]')).toHaveCount(29);
-
- await page.goto('/blocks/blocks/', { waitUntil: 'networkidle' });
- await expect(page.locator('section[aria-labelledby="primitive-catalog"] a[href*="/ui/"]')).toHaveCount(29);
-
- const legacyResponse = await page.goto('/blocks/blocks/auth/sign-in-card/', {
- waitUntil: 'networkidle',
- });
- expect(legacyResponse?.status()).toBe(404);
-});
-
-test('the billing catalog discovers all eight live pages', async ({ page }) => {
- const catalogResponse = await page.goto('/blocks/blocks/billing/', {
- waitUntil: 'networkidle',
- });
- expect(catalogResponse?.status()).toBe(200);
- await expect(page.getByRole('heading', { level: 1, name: 'Billing' })).toBeVisible();
-
- const previewLinks = page.locator('section[aria-labelledby="billing-catalog-heading"]').getByRole('link');
- await expect(previewLinks).toHaveCount(8);
-
- const discoveredPaths = await previewLinks.evaluateAll((links) =>
- links.map((link) => new URL((link as HTMLAnchorElement).href).pathname.replace(/\/?$/, '/')).sort(),
- );
- expect(discoveredPaths).toEqual(billingBlocks.map(billingRoute).sort());
-
- for (const name of billingBlocks) {
- await test.step(name, async () => {
- const response = await page.goto(billingRoute(name), {
- waitUntil: 'networkidle',
- });
- expect(response?.status()).toBe(200);
- await expect(page.locator('[data-slot="billing-showcase-preview"]')).toBeVisible();
- });
- }
-});
-
-test('the feature-pack catalog discovers all seven live pages', async ({ page }) => {
- const consoleErrors: string[] = [];
- const pageErrors: string[] = [];
- page.on('console', (message) => {
- if (message.type() === 'error') consoleErrors.push(message.text());
- });
- page.on('pageerror', (error) => pageErrors.push(error.message));
-
- const catalogResponse = await page.goto('/blocks/blocks/features/', {
- waitUntil: 'networkidle',
- });
- expect(catalogResponse?.status()).toBe(200);
- await expect(page.getByRole('heading', { level: 1, name: 'Feature packs' })).toBeVisible();
-
- const previewLinks = page.locator('section[aria-labelledby="feature-pack-catalog-heading"]').getByRole('link');
- await expect(previewLinks).toHaveCount(7);
-
- const discoveredPaths = await previewLinks.evaluateAll((links) =>
- links.map((link) => new URL((link as HTMLAnchorElement).href).pathname.replace(/\/?$/, '/')).sort(),
- );
- expect(discoveredPaths).toEqual(featurePacks.map(({ id }) => featurePackRoute(id)).sort());
-
- for (const { id, previewHeading, title, variant } of featurePacks) {
- await test.step(id, async () => {
- const response = await page.goto(featurePackRoute(id), {
- waitUntil: 'networkidle',
- });
- expect(response?.status()).toBe(200);
- const preview = page.locator('[data-slot="feature-pack-showcase-preview"]');
- await expect(preview).toBeVisible();
-
- const frameTitle = `${title} feature pack inline live preview`;
- const iframe = preview.getByTitle(frameTitle);
- await expect(iframe).toHaveAttribute(
- 'src',
- `/blocks/blocks/features/${id}/preview/?variant=${variant}&state=ready`,
- );
- await expect(
- page.frameLocator(`iframe[title="${frameTitle}"]`).getByRole('heading', {
- exact: true,
- level: 1,
- name: previewHeading,
- }),
- ).toBeVisible();
- });
- }
-
- expect(pageErrors).toEqual([]);
- expect(consoleErrors).toEqual([]);
-});
-
-test('unknown feature-pack detail and preview routes return 404', async ({ page }) => {
+test('removed and unknown documentation routes return 404', async ({ page }) => {
for (const route of [
+ '/blocks/blocks/auth/sign-in-card/',
'/blocks/blocks/features/not-a-pack/',
'/blocks/blocks/features/not-a-pack/preview/',
]) {
const response = await page.goto(route, { waitUntil: 'domcontentloaded' });
- expect(response?.status()).toBe(404);
+ expect(response?.status(), route).toBe(404);
}
});
diff --git a/apps/blocks/e2e/mobile.interaction.spec.ts b/apps/blocks/e2e/mobile.interaction.spec.ts
index 0fc9736..0d62a52 100644
--- a/apps/blocks/e2e/mobile.interaction.spec.ts
+++ b/apps/blocks/e2e/mobile.interaction.spec.ts
@@ -1,89 +1,23 @@
-import {
- expect,
- test,
- type FrameLocator,
- type Locator,
- type Page,
-} from '@playwright/test';
+import { expect, test } from '@playwright/test';
-const billingRoute = (name: string) => `/blocks/blocks/billing/${name}/`;
-const applicationRoute = (name: string) => `/blocks/blocks/${name}/`;
-
-function billingPreviewFrame(page: Page): FrameLocator {
- return page.frameLocator(
- '[data-slot="billing-showcase-preview"] iframe[title$="live preview"]',
- );
-}
-
-function applicationPreviewFrame(page: Page): FrameLocator {
- return page.frameLocator(
- '[data-slot="application-block-showcase-preview"] iframe[title$="live preview"]',
- );
-}
-
-async function expectTouchTargets(targets: Locator) {
- const targetCount = await targets.count();
- expect(targetCount).toBeGreaterThan(0);
-
- for (let index = 0; index < targetCount; index += 1) {
- const target = targets.nth(index);
- const targetName =
- (await target.getAttribute('aria-label')) ??
- (await target.textContent()) ??
- `target ${index + 1}`;
- const hitArea = await target.evaluate((element) => {
- const box = element.getBoundingClientRect();
- const coarsePointerTarget = getComputedStyle(element, '::after');
- const pseudoMinWidth = Number.parseFloat(coarsePointerTarget.minWidth) || 0;
- const pseudoMinHeight = Number.parseFloat(coarsePointerTarget.minHeight) || 0;
- return {
- width: Math.max(box.width, pseudoMinWidth),
- height: Math.max(box.height, pseudoMinHeight),
- };
- });
- expect(hitArea.width, `${targetName} width`).toBeGreaterThanOrEqual(44);
- expect(hitArea.height, `${targetName} height`).toBeGreaterThanOrEqual(44);
- }
-}
-
-async function chooseShowcaseOption(
- page: Page,
- label: 'Account' | 'Resource state',
- option: string,
-) {
- const preview = page.locator('[data-slot="billing-showcase-preview"]');
- const trigger = preview.getByRole('combobox', { name: label });
- await trigger.click();
- await page.getByRole('option', { name: option, exact: true }).click();
- await expect(trigger).toContainText(option);
-}
-
-test('navigation changes at the shared 860px breakpoint', async ({ page }) => {
- await page.setViewportSize({ width: 861, height: 900 });
+test('mobile navigation opens, follows a link, and closes', async ({ page }) => {
+ await page.setViewportSize({ width: 860, height: 900 });
await page.goto('/blocks/blocks/ui/button/', { waitUntil: 'networkidle' });
- const navigationMenu = page.getByRole('button', { name: 'Navigation menu', exact: true });
- await expect(navigationMenu).toBeHidden();
- await page.setViewportSize({ width: 860, height: 900 });
- await expect(navigationMenu).toBeVisible();
+ const navigationMenu = page.getByRole('button', { name: 'Navigation menu', exact: true });
await expect(navigationMenu).toHaveAttribute('aria-expanded', 'false');
await navigationMenu.click();
await expect(navigationMenu).toHaveAttribute('aria-expanded', 'true');
- const closeNavigation = page.getByRole('button', { name: 'Close navigation', exact: true });
- await expect(closeNavigation).toBeVisible();
- await expect(closeNavigation).toHaveCount(1);
- await expect(page.getByRole('button', { name: 'Dismiss navigation', exact: true })).toBeVisible();
+
await page.getByRole('link', { name: 'Tooltip' }).click();
await expect(page).toHaveURL(/\/blocks\/blocks\/ui\/tooltip\/$/);
- await expect(closeNavigation).toHaveCount(0);
await expect(navigationMenu).toHaveAttribute('aria-expanded', 'false');
});
-test('mobile modal examples open, dismiss, and restore focus without hydration errors', async ({ page }) => {
+test('mobile modal examples dismiss with Escape and restore focus', async ({ page }) => {
const pageErrors: string[] = [];
page.on('pageerror', (error) => pageErrors.push(error.message));
await page.goto('/blocks/blocks/ui/sheet/', { waitUntil: 'networkidle' });
- await expect(page.getByRole('button', { name: /Switch to (light|dark) theme/ })).toBeEnabled();
const trigger = page.getByRole('button', { name: 'Edit organization' });
await trigger.click();
@@ -94,209 +28,3 @@ test('mobile modal examples open, dismiss, and restore focus without hydration e
await expect(trigger).toBeFocused();
expect(pageErrors).toEqual([]);
});
-
-test('mobile billing tables keep horizontal overflow inside their containers', async ({
- page,
-}) => {
- const response = await page.goto(billingRoute('billing-settings-page'), {
- waitUntil: 'networkidle',
- });
- expect(response?.status()).toBe(200);
-
- const preview = page.locator('[data-slot="billing-showcase-preview"]');
- await preview
- .getByRole('button', { name: 'Mobile preview, 390 pixels' })
- .click();
- const frame = billingPreviewFrame(page);
- const settings = frame.locator('[data-slot="billing-settings-page"]');
- await settings.getByRole('tab', { name: 'Usage' }).click();
- const tables = settings.getByRole('table');
- await expect(tables).toHaveCount(2);
-
- let overflowingContainers = 0;
- for (let index = 0; index < 2; index += 1) {
- const table = tables.nth(index);
- const container = table.locator('xpath=..');
- await expect(container).toHaveAttribute('data-slot', 'table-container');
- expect(
- await container.evaluate((element) => getComputedStyle(element).overflowX),
- ).toBe('auto');
-
- expect(
- await container.evaluate(
- (element) => element.getBoundingClientRect().width <= window.innerWidth,
- ),
- ).toBe(true);
-
- if (
- await container.evaluate(
- (element) => element.scrollWidth > element.clientWidth,
- )
- ) {
- overflowingContainers += 1;
- }
- }
-
- expect(overflowingContainers).toBeGreaterThan(0);
- expect(
- await frame.locator('html').evaluate(
- (element) => element.scrollWidth <= element.clientWidth,
- ),
- ).toBe(true);
- expect(
- await page.evaluate(
- () =>
- document.documentElement.scrollWidth <=
- document.documentElement.clientWidth,
- ),
- ).toBe(true);
-});
-
-test('mobile billing controls expose 44px touch targets and switch account context', async ({
- page,
-}) => {
- await page.goto(billingRoute('billing-settings-page'), {
- waitUntil: 'networkidle',
- });
- const preview = page.locator('[data-slot="billing-showcase-preview"]');
- await preview
- .getByRole('button', { name: 'Mobile preview, 390 pixels' })
- .click();
- await chooseShowcaseOption(page, 'Account', 'Personal account');
-
- const frame = billingPreviewFrame(page);
- const settings = frame.locator('[data-slot="billing-settings-page"]');
- await expect(settings.getByText('Avery Chen', { exact: true }).first()).toBeVisible();
- await expect(settings.getByText('Personal account', { exact: true }).first()).toBeVisible();
-
- await expectTouchTargets(
- preview.locator(
- '[data-slot="select-trigger"]:visible, [data-slot="button"]:visible',
- ),
- );
- await expectTouchTargets(
- frame.locator(
- '[data-slot="tabs-trigger"]:visible, [data-slot="billing-settings-page"] [data-slot="button"]:visible',
- ),
- );
-});
-
-test('mobile application blocks keep their primary workflows inside the viewport', async ({
- page,
-}) => {
- await test.step('Org Chart fits every node and action target', async () => {
- await page.goto(applicationRoute('org-chart'), { waitUntil: 'networkidle' });
- expect(await page.evaluate(() => window.scrollY)).toBe(0);
- const frame = applicationPreviewFrame(page);
- const nodes = frame.locator('.react-flow__node');
- await expect(nodes).toHaveCount(5);
-
- await expect
- .poll(() =>
- nodes.evaluateAll((elements) =>
- elements.every((element) => {
- const bounds = element.getBoundingClientRect();
- return bounds.left >= 0 && bounds.right <= window.innerWidth;
- }),
- ),
- )
- .toBe(true);
-
- const actions = frame.getByRole('button', { name: /^Actions for / });
- await expect(actions).toHaveCount(5);
- expect(
- await actions.evaluateAll((elements) =>
- elements.every((element) => {
- const bounds = element.getBoundingClientRect();
- return bounds.left >= 0 && bounds.right <= window.innerWidth;
- }),
- ),
- ).toBe(true);
-
- for (const person of ['Maya Chen', 'Theo Brooks']) {
- await frame
- .getByRole('button', { name: new RegExp(`^Actions for ${person}`) })
- .click();
- const menu = frame.getByRole('menu');
- await expect(menu).toBeVisible();
- expect(
- await menu.evaluate((element) => {
- const bounds = element.getBoundingClientRect();
- return bounds.left >= 0 && bounds.right <= window.innerWidth;
- }),
- ).toBe(true);
- await page.keyboard.press('Escape');
- await expect(menu).toBeHidden();
- }
-
- const preview = page.locator(
- '[data-slot="application-block-showcase-preview"]',
- );
- await preview
- .getByRole('button', { name: 'Desktop preview, 1280 pixels' })
- .click();
- const fullscreenTrigger = preview.getByRole('button', {
- name: 'Open full-screen preview',
- });
- await fullscreenTrigger.click();
- const dialog = page.getByRole('dialog', { name: 'Org Chart preview' });
- const frameContainer = dialog.locator(
- '[data-slot="application-block-preview-frame"]',
- );
- const fullscreenFrame = dialog.locator('iframe');
- await expect
- .poll(async () => Number(await frameContainer.getAttribute('data-preview-scale')))
- .toBeLessThan(1);
- expect(
- await fullscreenFrame.evaluate((element) => {
- const frameBounds = element.getBoundingClientRect();
- const containerBounds = element.parentElement!.getBoundingClientRect();
- return frameBounds.width <= containerBounds.width + 1;
- }),
- ).toBe(true);
- await page.keyboard.press('Escape');
- await expect(dialog).toBeHidden();
- await expect(fullscreenTrigger).toBeFocused();
- });
-
- await test.step('Storage opens object details from the keyboard', async () => {
- await page.goto(applicationRoute('storage-browser'), {
- waitUntil: 'networkidle',
- });
- const frame = applicationPreviewFrame(page);
- const objectLink = frame.getByRole('button', {
- name: 'Open details for launch-cover.png',
- });
- await objectLink.focus();
- await objectLink.press('Enter');
- await expect(frame.getByRole('dialog')).toBeVisible();
- await page.keyboard.press('Escape');
- await expect(frame.getByRole('dialog')).toBeHidden();
- await expect(objectLink).toBeFocused();
- });
-
- await test.step('Schema Builder create cards do not overflow', async () => {
- await page.goto(applicationRoute('schema-builder'), {
- waitUntil: 'networkidle',
- });
- expect(await page.evaluate(() => window.scrollY)).toBe(0);
- const frame = applicationPreviewFrame(page);
- await frame.getByRole('button', { name: 'Create table' }).first().click();
- await expect(frame.getByTestId('table-name-input')).not.toBeFocused();
- const cards = frame.locator('[data-testid^="policy-card-"]');
- await expect(cards.first()).toBeVisible();
- expect(
- await cards.evaluateAll((elements) =>
- elements.every((element) => {
- const bounds = element.getBoundingClientRect();
- return bounds.left >= 0 && bounds.right <= window.innerWidth;
- }),
- ),
- ).toBe(true);
- expect(
- await frame.locator('html').evaluate(
- (element) => element.scrollWidth <= element.clientWidth,
- ),
- ).toBe(true);
- });
-});
diff --git a/apps/blocks/src/app/sitemap.test.ts b/apps/blocks/src/app/sitemap.test.ts
deleted file mode 100644
index a50f256..0000000
--- a/apps/blocks/src/app/sitemap.test.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { AI_COMPONENTS } from '@/lib/ai-components';
-import { APPLICATION_BLOCKS } from '@/lib/application-blocks';
-import { BASE_PRIMITIVES } from '@/lib/base-primitives';
-import { BILLING_BLOCKS } from '@/lib/billing-blocks';
-import { FEATURE_PACK_DOCS } from '@/lib/feature-packs';
-import { SOURCE_BLOCKS } from '@/lib/source-blocks';
-
-import sitemap from './sitemap';
-
-describe('sitemap', () => {
- it('contains foundations, application blocks, seven feature packs, 29 primitives, AI catalog, and the complete billing catalog', () => {
- const entries = sitemap();
- expect(BASE_PRIMITIVES).toHaveLength(29);
- expect(entries).toHaveLength(
- BASE_PRIMITIVES.length +
- FEATURE_PACK_DOCS.length +
- BILLING_BLOCKS.length +
- APPLICATION_BLOCKS.length +
- SOURCE_BLOCKS.length +
- AI_COMPONENTS.length +
- 8,
- );
- expect(entries.map(({ url }) => url)).toEqual([
- 'http://localhost:3005/',
- 'http://localhost:3005/blocks',
- 'http://localhost:3005/blocks/styling',
- 'http://localhost:3005/blocks/features',
- ...FEATURE_PACK_DOCS.map(({ id }) => `http://localhost:3005/blocks/features/${id}`),
- 'http://localhost:3005/blocks/command-palette',
- 'http://localhost:3005/blocks/ai',
- ...AI_COMPONENTS.map(({ name }) => `http://localhost:3005/blocks/ai/${name}`),
- ...SOURCE_BLOCKS.map(({ name }) => `http://localhost:3005/blocks/${name}`),
- ...APPLICATION_BLOCKS.map(({ name }) => `http://localhost:3005/blocks/${name}`),
- 'http://localhost:3005/blocks/console-kit',
- ...BASE_PRIMITIVES.map(({ name }) => `http://localhost:3005/blocks/ui/${name}`),
- 'http://localhost:3005/blocks/billing',
- ...BILLING_BLOCKS.map(({ name }) => `http://localhost:3005/blocks/billing/${name}`),
- ]);
- });
-});
diff --git a/apps/blocks/src/blocks/console-kit/constructive/constructive-console-kit.test.tsx b/apps/blocks/src/blocks/console-kit/constructive/constructive-console-kit.test.tsx
index 4035874..38b875d 100644
--- a/apps/blocks/src/blocks/console-kit/constructive/constructive-console-kit.test.tsx
+++ b/apps/blocks/src/blocks/console-kit/constructive/constructive-console-kit.test.tsx
@@ -174,34 +174,6 @@ describe('ConstructiveConsoleKit external ownership', () => {
}
});
- it('supports a first-party selected-pack composition from the core barrel', () => {
- const hostSession = embeddedSession('database-1');
- const hostTransport = transport('selected-packs');
-
- render(
-
- );
-
- const props = consoleKitCaptures.props.at(-1) as Readonly<{
- featureModules: readonly Readonly<{ id: string }>[];
- }>;
- expect(props.featureModules.map((module) => module.id)).toEqual([
- 'data',
- 'auth'
- ]);
- });
-
it('initializes its wrapper-owned store from a valid semantic default route', async () => {
const defaultRoute = {
feature: 'data',
diff --git a/apps/blocks/src/blocks/console-kit/store/console-kit-store.test.ts b/apps/blocks/src/blocks/console-kit/store/console-kit-store.test.ts
index a75457c..cbea4df 100644
--- a/apps/blocks/src/blocks/console-kit/store/console-kit-store.test.ts
+++ b/apps/blocks/src/blocks/console-kit/store/console-kit-store.test.ts
@@ -7,106 +7,6 @@ import {
import { createConsoleKitStore } from './console-kit-store';
describe('Console Kit store', () => {
- it('composes navigation, runtime, and adapter slices in one isolated store', () => {
- const first = createConsoleKitStore('data', {
- databaseId: 'database-1',
- organizationId: null
- }, [storageConsoleStoreSlice]);
- const second = createConsoleKitStore('auth');
- const adapter = {};
-
- first.getState().setSession({
- status: 'authenticated',
- identity: {
- kind: 'authenticated',
- cachePartition: 'login-1',
- subjectId: 'user-1',
- organizationId: 'org-1'
- }
- });
- first.getState().setAuthFlow({ status: 'entry', mode: 'sign-up' });
- first.getState().setRoute({
- feature: 'organizations',
- screen: 'organizations'
- });
- first.getState().setAdapterLoad('users', {
- status: 'ready',
- adapter,
- requestKey: 'database-1:user-1:users',
- props: { members: [] }
- });
- first.getState().setMetadata('database-1:user-1:data', {
- status: 'incompatible',
- message: 'The endpoint is missing the current _meta contract.',
- missing: ['Query._meta']
- });
- first.getState().setEndpoints({
- data: { id: 'database-1-data', kind: 'data', url: '/graphql' }
- });
- first.getState().setPackCapability('data', {
- status: 'ready',
- packId: 'data',
- supportedCapabilities: ['data.read'],
- evidence: []
- });
- getConsoleKitStorageSlice(first).selectStorageBucket(
- 'database-1:login-1',
- 'documents'
- );
-
- const revisionAfterAuth = first.getState().metadataRevision;
- expect(first.getState()).toMatchObject({
- route: { feature: 'organizations', screen: 'organizations' },
- authFlow: { status: 'entry', mode: 'sign-up' },
- context: { databaseId: 'database-1', organizationId: null },
- session: { status: 'authenticated' },
- metadataKey: 'database-1:user-1:data',
- endpoints: { data: { id: 'database-1-data' } },
- packCapabilities: { data: { status: 'ready' } },
- storageSelection: {
- scope: 'database-1:login-1',
- bucketKey: 'documents'
- },
- adapterLoads: {
- users: {
- status: 'ready',
- adapter,
- requestKey: 'database-1:user-1:users'
- }
- }
- });
- expect(revisionAfterAuth).toBeGreaterThanOrEqual(1);
-
- first.getState().retryMetadata();
- expect(first.getState()).toMatchObject({
- metadataRevision: revisionAfterAuth + 1,
- metadataKey: null,
- metadata: { status: 'checking' },
- metadataByEndpoint: {}
- });
- expect(second.getState()).toMatchObject({
- route: { feature: 'auth', screen: 'entry' },
- authFlow: { status: 'entry', mode: 'sign-in' },
- context: null,
- session: { status: 'loading' },
- endpoints: {},
- packCapabilities: {},
- adapterLoads: {}
- });
- expect(second.getState()).not.toHaveProperty('storageSelection');
- });
-
- it('keeps adapter subscription and retry revisions in their own slice', () => {
- const store = createConsoleKitStore('data');
-
- store.getState().notifyAdapterChange();
- store.getState().retryAdapter('storage');
- store.getState().retryAdapter('storage');
-
- expect(store.getState().adapterRevision).toBe(1);
- expect(store.getState().adapterAttempts.storage).toBe(2);
- });
-
it('clears organization selection whenever the session identity changes', () => {
const store = createConsoleKitStore('organizations', {
databaseId: 'database-1',
diff --git a/apps/blocks/src/components/billing-showcase/billing-showcase-preview.test.tsx b/apps/blocks/src/components/billing-showcase/billing-showcase-preview.test.tsx
index d4273db..480335f 100644
--- a/apps/blocks/src/components/billing-showcase/billing-showcase-preview.test.tsx
+++ b/apps/blocks/src/components/billing-showcase/billing-showcase-preview.test.tsx
@@ -1,6 +1,6 @@
-import { act, fireEvent, render, screen, within } from '@testing-library/react';
+import { fireEvent, render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { describe, expect, it, vi } from 'vitest';
+import { describe, expect, it } from 'vitest';
import { BillingShowcaseCanvas } from './billing-showcase-canvas';
import { BillingShowcasePreview } from './billing-showcase-preview';
@@ -13,92 +13,7 @@ function selectOption(triggerName: string, optionLabel: string) {
fireEvent.click(option as HTMLElement);
}
-function mockStageWidth(width: number) {
- const observers = new Set();
-
- class ResizeObserverStub {
- constructor(private readonly callback: ResizeObserverCallback) {
- observers.add(callback);
- }
-
- observe() {
- this.callback([], this as unknown as ResizeObserver);
- }
-
- unobserve() {}
-
- disconnect() {
- observers.delete(this.callback);
- }
- }
-
- vi.stubGlobal('ResizeObserver', ResizeObserverStub);
-
- return {
- apply(stage: HTMLElement) {
- Object.defineProperty(stage, 'clientWidth', {
- configurable: true,
- get: () => width
- });
- for (const callback of observers) {
- callback([], {} as ResizeObserver);
- }
- },
- cleanup() {
- vi.unstubAllGlobals();
- }
- };
-}
-
describe('BillingShowcasePreview', () => {
- it('switches the canonical subscription fixture with the account control', () => {
- const { rerender } = render(
-
- );
-
- expect(screen.getByText('Northstar Field Operations')).toBeInTheDocument();
- expect(screen.getByText('Scale')).toBeInTheDocument();
-
- rerender(
-
- );
-
- expect(screen.getByText('Avery Chen')).toBeInTheDocument();
- expect(screen.getByText('Developer')).toBeInTheDocument();
- });
-
- it('drives canonical loading resources from the shared state control', () => {
- const { rerender } = render(
-
- );
- expect(screen.getByRole('heading', { name: 'Plans and pricing' })).toBeInTheDocument();
-
- rerender(
-
- );
-
- expect(screen.getByLabelText('Loading plans and pricing…')).toHaveAttribute(
- 'aria-busy',
- 'true'
- );
- });
-
it('shows delegated actions without mutating the billing fixture', async () => {
const user = userEvent.setup();
render(
@@ -211,65 +126,4 @@ describe('BillingShowcasePreview', () => {
);
});
- it('scales the desktop frame to the stage width without changing the logical viewport', () => {
- const stageWidth = mockStageWidth(640);
-
- try {
- const { container } = render(
-
- );
- const stage = container.querySelector(
- '[data-slot="billing-preview-stage"]'
- );
- expect(stage).not.toBeNull();
- act(() => {
- stageWidth.apply(stage as HTMLElement);
- });
-
- const frame = screen.getByTitle('Pricing table inline live preview');
- const shell = container.querySelector(
- '[data-slot="billing-preview-frame"]'
- );
-
- expect(frame).toHaveAttribute('width', '1280');
- expect(frame).toHaveAttribute('data-preview-viewport', 'desktop');
- expect(shell).toHaveAttribute('data-preview-scale', '0.500');
- expect(shell).toHaveStyle({ width: '640px' });
- } finally {
- stageWidth.cleanup();
- }
- });
-
- it('does not upscale when the stage is wider than the device viewport', async () => {
- const user = userEvent.setup();
- const stageWidth = mockStageWidth(900);
-
- try {
- const { container } = render(
-
- );
- await user.click(
- screen.getByRole('button', { name: 'Mobile preview, 390 pixels' })
- );
-
- const stage = container.querySelector(
- '[data-slot="billing-preview-stage"]'
- );
- expect(stage).not.toBeNull();
- act(() => {
- stageWidth.apply(stage as HTMLElement);
- });
-
- const frame = screen.getByTitle('Pricing table inline live preview');
- const shell = container.querySelector(
- '[data-slot="billing-preview-frame"]'
- );
-
- expect(frame).toHaveAttribute('width', '390');
- expect(shell).toHaveAttribute('data-preview-scale', '1.000');
- expect(shell).toHaveStyle({ width: '390px' });
- } finally {
- stageWidth.cleanup();
- }
- });
});
diff --git a/apps/blocks/src/components/billing-showcase/billing-showcase-resources.test.ts b/apps/blocks/src/components/billing-showcase/billing-showcase-resources.test.ts
index c1b1b80..ea7e837 100644
--- a/apps/blocks/src/components/billing-showcase/billing-showcase-resources.test.ts
+++ b/apps/blocks/src/components/billing-showcase/billing-showcase-resources.test.ts
@@ -1,38 +1,13 @@
import { describe, expect, it } from 'vitest';
import {
- BILLING_SHOWCASE_ACCOUNT_OPTIONS,
- BILLING_SHOWCASE_RESOURCE_STATE_OPTIONS,
- BILLING_SHOWCASE_SETTINGS_STATE_OPTIONS,
- getBillingShowcaseAccount,
getBillingShowcaseSettingsResources,
- getBillingShowcaseSubscriptionResources,
isBillingShowcaseAccountKind,
isBillingShowcaseResourceState,
isBillingShowcaseSettingsState
} from './billing-showcase-resources';
describe('billing showcase resources', () => {
- it('keeps the two account variants and six shared resource states explicit', () => {
- expect(BILLING_SHOWCASE_ACCOUNT_OPTIONS.map(({ value }) => value)).toEqual([
- 'organization',
- 'personal'
- ]);
- expect(
- BILLING_SHOWCASE_RESOURCE_STATE_OPTIONS.map(({ value }) => value)
- ).toEqual([
- 'ready',
- 'loading',
- 'empty',
- 'error',
- 'stale',
- 'estimated'
- ]);
- expect(BILLING_SHOWCASE_SETTINGS_STATE_OPTIONS.at(-1)?.value).toBe(
- 'partial'
- );
- });
-
it('validates control values without accepting arbitrary strings', () => {
expect(isBillingShowcaseAccountKind('personal')).toBe(true);
expect(isBillingShowcaseAccountKind('workspace')).toBe(false);
@@ -42,17 +17,6 @@ describe('billing showcase resources', () => {
expect(isBillingShowcaseSettingsState('unknown')).toBe(false);
});
- it('switches account and subscription fixtures together', () => {
- expect(getBillingShowcaseAccount('personal').label).toBe('Avery Chen');
- expect(
- getBillingShowcaseSubscriptionResources('personal').ready.status
- ).toBe('ready');
- const personal = getBillingShowcaseSubscriptionResources('personal').ready;
- expect(personal.status === 'ready' ? personal.data.planName : undefined).toBe(
- 'Developer'
- );
- });
-
it('builds uniform settings states and preserves the partial-failure boundary', () => {
const loading = getBillingShowcaseSettingsResources(
'loading',
diff --git a/apps/blocks/src/components/docs/ui-demos.test.tsx b/apps/blocks/src/components/docs/ui-demos.test.tsx
deleted file mode 100644
index 8aaaa64..0000000
--- a/apps/blocks/src/components/docs/ui-demos.test.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { cleanup, render, waitFor } from '@testing-library/react';
-import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
-
-import { BASE_PRIMITIVES } from '@/lib/base-primitives';
-
-import { UI_DEMOS } from './showcase-ui';
-
-beforeAll(() => {
- if (!Element.prototype.scrollIntoView) Element.prototype.scrollIntoView = function scrollIntoView() {};
- if (!Element.prototype.getAnimations) Element.prototype.getAnimations = () => [];
- if (!window.matchMedia) {
- window.matchMedia = ((query: string) => ({
- matches: false,
- media: query,
- onchange: null,
- addListener: vi.fn(),
- removeListener: vi.fn(),
- addEventListener: vi.fn(),
- removeEventListener: vi.fn(),
- dispatchEvent: vi.fn(),
- })) as unknown as typeof window.matchMedia;
- }
- if (!('ResizeObserver' in globalThis)) {
- globalThis.ResizeObserver = class ResizeObserverStub {
- observe() {}
- unobserve() {}
- disconnect() {}
- takeRecords(): ResizeObserverEntry[] {
- return [];
- }
- };
- }
-});
-
-afterEach(cleanup);
-
-describe('base primitive previews', () => {
- it('matches the typed catalog exactly', () => {
- expect(Object.keys(UI_DEMOS)).toEqual(BASE_PRIMITIVES.map(({ name }) => name));
- });
-
- it.each(BASE_PRIMITIVES)('mounts the $name package preview', async ({ name }) => {
- const Demo = UI_DEMOS[name];
- const { container, unmount } = render();
- await waitFor(() => expect(container.firstChild).not.toBeNull());
- unmount();
- });
-});
diff --git a/apps/blocks/src/components/site/registry-shell.test.tsx b/apps/blocks/src/components/site/registry-shell.test.tsx
deleted file mode 100644
index c179e41..0000000
--- a/apps/blocks/src/components/site/registry-shell.test.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import { cleanup, render, screen } from '@testing-library/react';
-import { afterEach, describe, expect, it, vi } from 'vitest';
-
-vi.mock('next/navigation', () => ({
- usePathname: vi.fn(() => '/'),
-}));
-
-vi.mock('@/components/site/site-sidebar', () => ({
- SiteSidebar: () => ,
-}));
-
-vi.mock('@/components/site/site-topbar', () => ({
- SiteTopbar: () => ,
-}));
-
-import { usePathname } from 'next/navigation';
-
-import { RegistryShell } from './registry-shell';
-
-const mockUsePathname = vi.mocked(usePathname);
-
-afterEach(() => {
- cleanup();
- vi.clearAllMocks();
-});
-
-describe('RegistryShell standalone previews', () => {
- it.each([
- '/blocks/billing/billing-settings-page/preview',
- '/blocks/features/data/preview',
- '/blocks/features/notifications/preview/',
- '/blocks/org-chart/preview',
- '/blocks/storage-browser/preview/',
- '/blocks/sheets/preview',
- '/blocks/schema-builder/preview/',
- ])('omits recursive documentation chrome on %s', (pathname) => {
- mockUsePathname.mockReturnValue(pathname);
- render(
-
- Live preview
- ,
- );
-
- expect(screen.getByText('Live preview')).toBeVisible();
- expect(screen.queryByText('Docs sidebar')).not.toBeInTheDocument();
- expect(screen.queryByText('Docs topbar')).not.toBeInTheDocument();
- expect(screen.getByRole('main')).toHaveAttribute('id', 'main-content');
- });
-
- it('lets the Console Kit app shell own the integration main landmark', () => {
- mockUsePathname.mockReturnValue('/__integration/console-kit');
- render(
-
- Console Kit
-
- );
-
- expect(screen.getAllByRole('main')).toHaveLength(1);
- expect(screen.getByRole('main')).toHaveAttribute('id', 'main-content');
- });
-
- it('keeps the documentation chrome on a feature-pack detail route', () => {
- mockUsePathname.mockReturnValue('/blocks/features/data');
- render(
-
- Data docs
- ,
- );
-
- expect(screen.getByText('Docs sidebar')).toBeVisible();
- expect(screen.getByText('Docs topbar')).toBeVisible();
- expect(screen.getByText('Data docs')).toBeVisible();
- expect(screen.getAllByRole('main')).toHaveLength(1);
- });
-});
diff --git a/apps/blocks/src/components/site/site-topbar.test.tsx b/apps/blocks/src/components/site/site-topbar.test.tsx
index caf6443..36c972e 100644
--- a/apps/blocks/src/components/site/site-topbar.test.tsx
+++ b/apps/blocks/src/components/site/site-topbar.test.tsx
@@ -46,15 +46,6 @@ describe('SiteTopbar install command', () => {
});
});
- it('normalizes trailing slashes before resolving the registry item', () => {
- mockUsePathname.mockReturnValue('/blocks/ui/dialog/');
- render();
-
- expect(screen.getByRole('button', { name: 'Copy Dialog install command' })).toHaveTextContent(
- 'pnpm dlx shadcn@latest add @constructive/dialog',
- );
- });
-
it('copies the exact feature-pack registry root and exposes its breadcrumb', async () => {
mockUsePathname.mockReturnValue('/blocks/features/organizations/');
render();
@@ -71,75 +62,17 @@ describe('SiteTopbar install command', () => {
});
});
- it('offers install actions for documented source and application blocks', () => {
- mockUsePathname.mockReturnValue('/blocks/billing/billing-usage-overview');
- const { unmount } = render();
- expect(
- screen.getByRole('button', {
- name: 'Copy Usage overview install command',
- }),
- ).toHaveTextContent('pnpm dlx shadcn@latest add @constructive/billing-usage-overview');
-
- unmount();
- mockUsePathname.mockReturnValue('/blocks/org-chart');
- const orgChart = render();
- expect(
- screen.getByRole('button', {
- name: 'Copy Org Chart install command',
- }),
- ).toHaveTextContent('pnpm dlx shadcn@latest add @constructive/org-chart');
-
- orgChart.unmount();
- mockUsePathname.mockReturnValue('/blocks/storage-browser');
- const storageBrowser = render();
- expect(
- screen.getByRole('button', {
- name: 'Copy Storage Browser install command',
- }),
- ).toHaveTextContent('pnpm dlx shadcn@latest add @constructive/storage-browser');
-
- storageBrowser.unmount();
- mockUsePathname.mockReturnValue('/blocks/sheets');
- const sheets = render();
- expect(screen.getByRole('button', { name: 'Copy Sheets install command' })).toHaveTextContent(
- 'pnpm dlx shadcn@latest add @constructive/sheets',
- );
-
- sheets.unmount();
- mockUsePathname.mockReturnValue('/blocks/schema-builder');
- const schemaBuilder = render();
- expect(screen.getByRole('button', { name: 'Copy Schema Builder install command' })).toHaveTextContent(
- 'pnpm dlx shadcn@latest add @constructive/schema-builder',
- );
-
- schemaBuilder.unmount();
- mockUsePathname.mockReturnValue('/blocks/command-palette');
- const commandPalette = render();
- expect(screen.getByRole('button', { name: 'Copy Command Palette install command' })).toHaveTextContent(
- 'pnpm dlx shadcn@latest add @constructive/command-palette',
- );
-
- commandPalette.unmount();
- mockUsePathname.mockReturnValue('/blocks/console-kit');
- render();
- expect(screen.getByRole('button', { name: 'Copy Console Kit install command' })).toHaveTextContent(
- 'pnpm dlx shadcn@latest add @constructive/console-kit-nextjs',
- );
- });
-
- it.each([
- '/',
- '/blocks',
- '/blocks/styling',
- '/blocks/features',
- '/blocks/features/not-a-pack',
- '/blocks/features/data/preview',
- '/blocks/ui/not-a-registry-item',
- ])('hides the install command on %s', (pathname) => {
- mockUsePathname.mockReturnValue(pathname);
- render();
-
- expect(screen.queryByRole('button', { name: /install command/i })).not.toBeInTheDocument();
- expect(screen.queryByText(/pnpm dlx shadcn@latest add @constructive\//)).not.toBeInTheDocument();
+ it('hides install commands for catalogs, previews, and unknown items', () => {
+ for (const pathname of [
+ '/blocks',
+ '/blocks/features',
+ '/blocks/features/data/preview',
+ '/blocks/ui/not-a-registry-item',
+ ]) {
+ mockUsePathname.mockReturnValue(pathname);
+ const view = render();
+ expect(screen.queryByRole('button', { name: /install command/i }), pathname).not.toBeInTheDocument();
+ view.unmount();
+ }
});
});
diff --git a/apps/blocks/src/feature-packs/catalog.test.ts b/apps/blocks/src/feature-packs/catalog.test.ts
index 13b7b7c..69539e3 100644
--- a/apps/blocks/src/feature-packs/catalog.test.ts
+++ b/apps/blocks/src/feature-packs/catalog.test.ts
@@ -1,11 +1,7 @@
-import { readFileSync } from 'node:fs';
-
import { describe, expect, it } from 'vitest';
import {
- ATOMIC_CAPABILITY_IDS,
FEATURE_PACK_CATALOG,
- FEATURE_PACK_IDS,
FEATURE_PACK_MANIFESTS,
PRESET_PROFILES,
generateFeaturePackCatalog,
@@ -14,61 +10,7 @@ import {
type FeaturePackManifestV1
} from './index';
-function readSidecar(relativePath: string): unknown {
- return JSON.parse(
- readFileSync(new URL(relativePath, import.meta.url), 'utf8')
- );
-}
-
describe('first-release feature pack catalog', () => {
- it('contains exactly the approved first-release pack IDs', () => {
- expect(FEATURE_PACK_CATALOG.featurePacks.map((pack) => pack.id)).toEqual(
- FEATURE_PACK_IDS
- );
- expect(new Set(ATOMIC_CAPABILITY_IDS).size).toBe(
- ATOMIC_CAPABILITY_IDS.length
- );
- });
-
- it('maps backend presets to the approved pack profiles', () => {
- expect(
- Object.fromEntries(
- PRESET_PROFILES.map((profile) => [
- profile.presetSlug,
- profile.featurePacks
- ])
- )
- ).toEqual({
- 'auth:hardened': ['data', 'auth', 'users'],
- 'b2b:storage': [
- 'data',
- 'auth',
- 'users',
- 'organizations',
- 'storage'
- ],
- full: [
- 'data',
- 'auth',
- 'users',
- 'organizations',
- 'storage',
- 'billing',
- 'notifications'
- ]
- });
- expect(PRESET_PROFILES.every((profile) => profile.stability === 'stable')).toBe(true);
- });
-
- it('keeps search, i18n, and realtime optional', () => {
- const data = FEATURE_PACK_MANIFESTS.find((pack) => pack.id === 'data');
- expect(data?.capabilities.optional).toEqual([
- 'data.search',
- 'data.i18n',
- 'data.realtime'
- ]);
- });
-
it('generates dependency-ordered manifests for each preset', () => {
expect(
getPresetFeaturePacks(FEATURE_PACK_CATALOG, 'b2b-storage').map(
@@ -77,21 +19,6 @@ describe('first-release feature pack catalog', () => {
).toEqual(['data', 'auth', 'users', 'organizations', 'storage']);
});
- it('keeps installable JSON sidecars identical to the typed catalog', () => {
- for (const manifest of FEATURE_PACK_MANIFESTS) {
- expect(
- readSidecar(
- `../blocks/feature-packs/${manifest.id}/feature-pack.json`
- )
- ).toEqual(manifest);
- }
-
- for (const profile of PRESET_PROFILES) {
- expect(
- readSidecar(`../blocks/presets/${profile.id}.json`)
- ).toEqual(profile);
- }
- });
});
describe('feature pack catalog validation', () => {
diff --git a/apps/blocks/src/lib/ai-docs.test.ts b/apps/blocks/src/lib/ai-docs.test.ts
deleted file mode 100644
index 655551d..0000000
--- a/apps/blocks/src/lib/ai-docs.test.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { AI_COMPONENTS } from './ai-components';
-import { AI_DOC } from './ai-docs';
-
-describe('AI registry documentation', () => {
- it('documents one aggregate registry item with source-installed imports', () => {
- expect(AI_DOC.name).toBe('ai');
- expect(AI_DOC).not.toHaveProperty('kitName');
- expect(AI_DOC).not.toHaveProperty('npmImport');
- expect(AI_DOC.usage.example).toContain("from '@/components/ui/ai'");
- expect(AI_DOC.usage.example).toContain("from '@/components/ui/button'");
- expect(AI_DOC.usage.example).not.toContain('@constructive-io/ui');
- });
-
- it('uses the installed AI barrel in every component example', () => {
- for (const component of AI_COMPONENTS) {
- expect(component.importExample).toContain("from '@/components/ui/ai'");
- expect(component.importExample).not.toContain('@constructive-io/ui');
- }
- });
-});
diff --git a/apps/blocks/src/lib/base-primitives.test.ts b/apps/blocks/src/lib/base-primitives.test.ts
deleted file mode 100644
index 2003591..0000000
--- a/apps/blocks/src/lib/base-primitives.test.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import fs from 'node:fs';
-import path from 'node:path';
-import { fileURLToPath } from 'node:url';
-
-import { describe, expect, it } from 'vitest';
-
-import { BASE_PRIMITIVES, getBasePrimitive, packageImport, registryInstall } from './base-primitives';
-
-const expectedNames = [
- 'alert',
- 'alert-dialog',
- 'avatar',
- 'badge',
- 'breadcrumb',
- 'button',
- 'card',
- 'checkbox',
- 'collapsible',
- 'dialog',
- 'drawer',
- 'dropdown-menu',
- 'input',
- 'label',
- 'pagination',
- 'popover',
- 'progress',
- 'radio-group',
- 'resizable',
- 'scroll-area',
- 'select',
- 'separator',
- 'sheet',
- 'skeleton',
- 'switch',
- 'table',
- 'tabs',
- 'textarea',
- 'tooltip',
-] as const;
-
-const testDirectory = path.dirname(fileURLToPath(import.meta.url));
-const repositoryRoot = path.resolve(testDirectory, '..', '..', '..', '..');
-
-describe('base primitive catalog', () => {
- it('is the exact clean-slate route contract', () => {
- expect(BASE_PRIMITIVES.map(({ name }) => name)).toEqual(expectedNames);
- expect(new Set(expectedNames).size).toBe(expectedNames.length);
- });
-
- it('resolves every item to an npm export and registry item', () => {
- const packageJson = JSON.parse(fs.readFileSync(path.join(repositoryRoot, 'packages/ui/package.json'), 'utf8')) as {
- exports: Record;
- };
- const registry = JSON.parse(fs.readFileSync(path.join(repositoryRoot, 'packages/ui/registry.json'), 'utf8')) as {
- items: Array<{ name: string }>;
- };
- const registryNames = new Set(registry.items.map(({ name }) => name));
-
- for (const primitive of BASE_PRIMITIVES) {
- expect(packageJson.exports[`./${primitive.name}`], primitive.name).toBeDefined();
- expect(registryNames.has(primitive.name), primitive.name).toBe(true);
- expect(getBasePrimitive(primitive.name)).toBe(primitive);
- }
- });
-
- it('keeps package and registry examples on their respective distribution paths', () => {
- for (const primitive of BASE_PRIMITIVES) {
- expect(packageImport(primitive)).toContain(`@constructive-io/ui/${primitive.name}`);
- expect(registryInstall(primitive)).toBe(`pnpm dlx shadcn@latest add @constructive/${primitive.name}`);
- }
- });
-});
diff --git a/apps/blocks/src/lib/billing-blocks.test.ts b/apps/blocks/src/lib/billing-blocks.test.ts
deleted file mode 100644
index e9b21f4..0000000
--- a/apps/blocks/src/lib/billing-blocks.test.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import {
- BILLING_BLOCKS,
- getBillingBlock,
- isBillingBlockName
-} from './billing-blocks';
-
-describe('billing block catalog', () => {
- it('contains the eight unique customer-first visual blocks', () => {
- expect(BILLING_BLOCKS).toHaveLength(8);
- expect(new Set(BILLING_BLOCKS.map(({ name }) => name)).size).toBe(8);
- expect(BILLING_BLOCKS.at(-1)?.name).toBe('billing-settings-page');
- });
-
- it('keeps usage and accessibility guidance on every block', () => {
- for (const block of BILLING_BLOCKS) {
- expect(block.resource.length).toBeGreaterThan(0);
- expect(block.whenToUse.length).toBeGreaterThan(0);
- expect(block.usage.description.length).toBeGreaterThan(0);
- expect(block.usage.example).toContain(block.exportName);
- expect(block.state.description.length).toBeGreaterThan(0);
- expect(block.accessibility.length).toBeGreaterThan(0);
- }
- });
-
- it('resolves only catalogued billing block names', () => {
- expect(isBillingBlockName('billing-usage-overview')).toBe(true);
- expect(getBillingBlock('billing-usage-overview')?.title).toBe(
- 'Usage overview'
- );
- expect(isBillingBlockName('billing-invoice-history')).toBe(false);
- expect(getBillingBlock('billing-invoice-history')).toBeUndefined();
- });
-});
diff --git a/apps/blocks/src/lib/feature-packs.test.ts b/apps/blocks/src/lib/feature-packs.test.ts
deleted file mode 100644
index f7422bb..0000000
--- a/apps/blocks/src/lib/feature-packs.test.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { FEATURE_PACK_CATALOG, FEATURE_PACK_IDS, getFeaturePackManifest } from '@/feature-packs';
-
-import { FEATURE_PACK_DOCS, getFeaturePackDoc, isFeaturePackDocId } from './feature-packs';
-
-function endpointLabel(required: readonly string[], optional: readonly string[]) {
- return [...required, ...optional.map((endpoint) => `optional ${endpoint}`)].join(', ');
-}
-
-describe('feature-pack documentation catalog', () => {
- it('contains the seven unique feature packs in canonical dependency order', () => {
- expect(FEATURE_PACK_DOCS.map(({ id }) => id)).toEqual(FEATURE_PACK_IDS);
- expect(new Set(FEATURE_PACK_DOCS.map(({ id }) => id)).size).toBe(7);
- });
-
- it('keeps manifest summaries and registry names aligned', () => {
- for (const block of FEATURE_PACK_DOCS) {
- const manifest = getFeaturePackManifest(FEATURE_PACK_CATALOG, block.id)!;
- expect(block.registryName).toBe(`feature-pack-${block.id}`);
- expect(block.dependencies).toEqual(manifest.dependencies);
- expect(block.endpoints).toBe(endpointLabel(manifest.endpoints.required, manifest.endpoints.optional));
- }
- });
-
- it('provides complete billing-style editorial coverage for every root', () => {
- for (const block of FEATURE_PACK_DOCS) {
- expect(block.description.length).toBeGreaterThan(0);
- expect(block.resource.length).toBeGreaterThan(0);
- expect(block.whenToUse.length).toBeGreaterThanOrEqual(2);
- expect(block.usage.description.length).toBeGreaterThan(0);
- expect(block.usage.example).toContain(block.exportName);
- expect(block.usage.example).toContain(`@/blocks/feature-packs/${block.id}/${block.id}-feature-pack`);
- expect(block.state.description.length).toBeGreaterThan(0);
- expect(block.surfaces.length).toBeGreaterThan(0);
- expect(block.accessibility.length).toBeGreaterThan(0);
- expect(block.api.length).toBeGreaterThan(0);
- }
- });
-
- it('resolves only documented feature-pack ids', () => {
- expect(isFeaturePackDocId('organizations')).toBe(true);
- expect(getFeaturePackDoc('organizations')?.title).toBe('Organizations');
- expect(isFeaturePackDocId('analytics')).toBe(false);
- expect(getFeaturePackDoc('analytics')).toBeUndefined();
- });
-});
diff --git a/packages/command-palette/src/__tests__/keybinding.test.ts b/packages/command-palette/src/__tests__/keybinding.test.ts
index 5f4e843..9a2ee1c 100644
--- a/packages/command-palette/src/__tests__/keybinding.test.ts
+++ b/packages/command-palette/src/__tests__/keybinding.test.ts
@@ -1,277 +1,73 @@
-import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import {
- kbd,
- isMac,
- isEditableTarget,
- matchKeyBinding,
- formatKeyBinding,
-} from '../keybinding';
-import type { KeyBinding } from '../keybinding';
+import { afterEach, describe, expect, it } from 'vitest';
-// Helper to create a KeyboardEvent-like object
-function fakeKeyEvent(
- key: string,
- opts: {
- metaKey?: boolean;
- ctrlKey?: boolean;
- shiftKey?: boolean;
- altKey?: boolean;
- } = {}
-): KeyboardEvent {
+import { formatKeyBinding, isEditableTarget, isMac, kbd, matchKeyBinding } from '../keybinding';
+
+const originalNavigator = globalThis.navigator;
+
+function setPlatform(platform?: string) {
+ Object.defineProperty(globalThis, 'navigator', {
+ configurable: true,
+ value: platform === undefined ? undefined : { platform },
+ });
+}
+
+function keyEvent(key: string, modifiers: Partial = {}): KeyboardEvent {
return {
key,
- metaKey: opts.metaKey ?? false,
- ctrlKey: opts.ctrlKey ?? false,
- shiftKey: opts.shiftKey ?? false,
- altKey: opts.altKey ?? false,
+ metaKey: false,
+ ctrlKey: false,
+ shiftKey: false,
+ altKey: false,
+ ...modifiers,
} as KeyboardEvent;
}
-describe('kbd factory', () => {
- it('creates binding with key only', () => {
- expect(kbd('enter')).toEqual({ key: 'enter' });
- });
-
- it('creates binding with one modifier', () => {
- expect(kbd('h', 'mod')).toEqual({ key: 'h', modifiers: ['mod'] });
- });
-
- it('creates binding with multiple modifiers', () => {
- expect(kbd('p', 'mod', 'shift')).toEqual({
- key: 'p',
- modifiers: ['mod', 'shift'],
- });
+afterEach(() => {
+ Object.defineProperty(globalThis, 'navigator', {
+ configurable: true,
+ value: originalNavigator,
});
});
-describe('isMac', () => {
- const originalNavigator = globalThis.navigator;
-
- afterEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: originalNavigator,
- writable: true,
- });
- });
-
- it('returns false when navigator is undefined (SSR)', () => {
- Object.defineProperty(globalThis, 'navigator', {
- value: undefined,
- writable: true,
- });
+describe('keybinding', () => {
+ it('detects macOS without breaking server rendering', () => {
+ setPlatform();
expect(isMac()).toBe(false);
- });
-
- it('returns true for Mac platform', () => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'MacIntel' },
- writable: true,
- });
+ setPlatform('MacIntel');
expect(isMac()).toBe(true);
- });
-
- it('returns false for Windows platform', () => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'Win32' },
- writable: true,
- });
+ setPlatform('Win32');
expect(isMac()).toBe(false);
});
-});
-describe('isEditableTarget', () => {
- it('returns false for null', () => {
+ it('recognizes editable targets that must retain keyboard input', () => {
+ for (const tag of ['input', 'textarea', 'select'] as const) {
+ expect(isEditableTarget(document.createElement(tag)), tag).toBe(true);
+ }
+ const editable = document.createElement('div');
+ editable.contentEditable = 'true';
+ expect(isEditableTarget(editable)).toBe(true);
+ expect(isEditableTarget(document.createElement('div'))).toBe(false);
expect(isEditableTarget(null)).toBe(false);
});
- it('returns true for INPUT', () => {
- const el = document.createElement('input');
- expect(isEditableTarget(el)).toBe(true);
- });
-
- it('returns true for TEXTAREA', () => {
- const el = document.createElement('textarea');
- expect(isEditableTarget(el)).toBe(true);
- });
-
- it('returns true for SELECT', () => {
- const el = document.createElement('select');
- expect(isEditableTarget(el)).toBe(true);
- });
-
- it('returns true for contentEditable', () => {
- const el = document.createElement('div');
- el.contentEditable = 'true';
- expect(isEditableTarget(el)).toBe(true);
- });
-
- it('returns false for regular div', () => {
- const el = document.createElement('div');
- expect(isEditableTarget(el)).toBe(false);
- });
-
- it('returns false for non-HTMLElement', () => {
- expect(isEditableTarget({} as EventTarget)).toBe(false);
- });
-});
-
-describe('matchKeyBinding', () => {
- // Set platform to non-Mac for predictable tests
- const originalNavigator = globalThis.navigator;
-
- beforeEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'Win32' },
- writable: true,
- });
- });
-
- afterEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: originalNavigator,
- writable: true,
- });
- });
-
- it('matches simple key', () => {
- expect(matchKeyBinding(fakeKeyEvent('h'), kbd('h'))).toBe(true);
+ it('matches keys case-insensitively and rejects missing or extra modifiers', () => {
+ setPlatform('Win32');
+ expect(matchKeyBinding(keyEvent('H'), kbd('h'))).toBe(true);
+ expect(matchKeyBinding(keyEvent('k', { ctrlKey: true }), kbd('k', 'mod'))).toBe(true);
+ expect(matchKeyBinding(keyEvent('k'), kbd('k', 'mod'))).toBe(false);
+ expect(matchKeyBinding(keyEvent('h', { shiftKey: true }), kbd('h'))).toBe(false);
});
- it('case insensitive key match', () => {
- expect(matchKeyBinding(fakeKeyEvent('H'), kbd('h'))).toBe(true);
+ it('maps the mod key to Command on macOS instead of Control', () => {
+ setPlatform('MacIntel');
+ expect(matchKeyBinding(keyEvent('k', { metaKey: true }), kbd('k', 'mod'))).toBe(true);
+ expect(matchKeyBinding(keyEvent('k', { ctrlKey: true }), kbd('k', 'mod'))).toBe(false);
});
- it('rejects wrong key', () => {
- expect(matchKeyBinding(fakeKeyEvent('j'), kbd('h'))).toBe(false);
- });
-
- it('matches mod+key on Windows (ctrlKey)', () => {
- expect(
- matchKeyBinding(fakeKeyEvent('k', { ctrlKey: true }), kbd('k', 'mod'))
- ).toBe(true);
- });
-
- it('rejects mod+key when ctrl is not pressed', () => {
- expect(matchKeyBinding(fakeKeyEvent('k'), kbd('k', 'mod'))).toBe(false);
- });
-
- it('rejects extra modifiers (ctrl pressed but not required)', () => {
- expect(
- matchKeyBinding(fakeKeyEvent('h', { ctrlKey: true }), kbd('h'))
- ).toBe(false);
- });
-
- it('rejects extra shift modifier', () => {
- expect(
- matchKeyBinding(
- fakeKeyEvent('h', { ctrlKey: true, shiftKey: true }),
- kbd('h', 'mod')
- )
- ).toBe(false);
- });
-
- it('matches mod+shift+key', () => {
- expect(
- matchKeyBinding(
- fakeKeyEvent('p', { ctrlKey: true, shiftKey: true }),
- kbd('p', 'mod', 'shift')
- )
- ).toBe(true);
- });
-
- it('matches alt+key', () => {
- expect(
- matchKeyBinding(fakeKeyEvent('a', { altKey: true }), kbd('a', 'alt'))
- ).toBe(true);
- });
-
- describe('Mac platform', () => {
- beforeEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'MacIntel' },
- writable: true,
- });
- });
-
- it('matches mod+key on Mac (metaKey)', () => {
- expect(
- matchKeyBinding(fakeKeyEvent('k', { metaKey: true }), kbd('k', 'mod'))
- ).toBe(true);
- });
-
- it('rejects ctrlKey for mod on Mac', () => {
- expect(
- matchKeyBinding(fakeKeyEvent('k', { ctrlKey: true }), kbd('k', 'mod'))
- ).toBe(false);
- });
- });
-});
-
-describe('formatKeyBinding', () => {
- const originalNavigator = globalThis.navigator;
-
- afterEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: originalNavigator,
- writable: true,
- });
- });
-
- it('formats single key', () => {
- expect(formatKeyBinding(kbd('enter'))).toEqual(['enter']);
- });
-
- it('capitalizes single-char keys', () => {
- expect(formatKeyBinding(kbd('h'))).toEqual(['H']);
- });
-
- describe('Mac', () => {
- beforeEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'MacIntel' },
- writable: true,
- });
- });
-
- it('formats mod as ⌘', () => {
- expect(formatKeyBinding(kbd('h', 'mod'))).toEqual(['⌘', 'H']);
- });
-
- it('formats shift as ⇧', () => {
- expect(formatKeyBinding(kbd('p', 'mod', 'shift'))).toEqual([
- '⌘',
- '⇧',
- 'P',
- ]);
- });
-
- it('formats alt as ⌥', () => {
- expect(formatKeyBinding(kbd('a', 'alt'))).toEqual(['⌥', 'A']);
- });
- });
-
- describe('PC', () => {
- beforeEach(() => {
- Object.defineProperty(globalThis, 'navigator', {
- value: { platform: 'Win32' },
- writable: true,
- });
- });
-
- it('formats mod as Ctrl', () => {
- expect(formatKeyBinding(kbd('h', 'mod'))).toEqual(['Ctrl', 'H']);
- });
-
- it('formats shift as Shift', () => {
- expect(formatKeyBinding(kbd('p', 'mod', 'shift'))).toEqual([
- 'Ctrl',
- 'Shift',
- 'P',
- ]);
- });
-
- it('formats alt as Alt', () => {
- expect(formatKeyBinding(kbd('a', 'alt'))).toEqual(['Alt', 'A']);
- });
+ it('formats shortcuts for the active platform', () => {
+ setPlatform('MacIntel');
+ expect(formatKeyBinding(kbd('p', 'mod', 'shift'))).toEqual(['⌘', '⇧', 'P']);
+ setPlatform('Win32');
+ expect(formatKeyBinding(kbd('p', 'mod', 'shift'))).toEqual(['Ctrl', 'Shift', 'P']);
});
});
diff --git a/packages/command-palette/src/__tests__/multi-step-builder.test.ts b/packages/command-palette/src/__tests__/multi-step-builder.test.ts
index 935f82b..e1074a2 100644
--- a/packages/command-palette/src/__tests__/multi-step-builder.test.ts
+++ b/packages/command-palette/src/__tests__/multi-step-builder.test.ts
@@ -1,135 +1,41 @@
-import { describe, it, expect, vi } from 'vitest';
+import { describe, expect, it } from 'vitest';
+
import { multiStepCommand } from '../multi-step/builder';
-import { kbd } from '../keybinding';
import type { StepViewProps } from '../multi-step/types';
-// Minimal step component for testing
-function StubStep(_props: StepViewProps) {
+function StubStep(_props: StepViewProps) {
return null;
}
const base = { id: 'test', label: 'Test', group: 'g' };
describe('multiStepCommand builder', () => {
- it('builds a valid CommandDefinition with type multi-step', () => {
- const cmd = multiStepCommand(base)
- .step({ id: 's1', title: 'Step 1', Component: StubStep })
- .build();
-
- expect(cmd.id).toBe('test');
- expect(cmd.type).toBe('multi-step');
- expect(cmd.multiStep).toBeDefined();
- expect(cmd.multiStep!.steps).toHaveLength(1);
- expect(cmd.multiStep!.steps[0].id).toBe('s1');
- });
-
- it('preserves all base fields', () => {
- const cmd = multiStepCommand({
- ...base,
- description: 'desc',
- shortcut: kbd('n', 'mod'),
- keywords: ['a', 'b'],
- priority: 5,
- })
- .step({ id: 's1', title: 'S1', Component: StubStep })
- .build();
-
- expect(cmd.description).toBe('desc');
- expect(cmd.shortcut).toEqual(kbd('n', 'mod'));
- expect(cmd.keywords).toEqual(['a', 'b']);
- expect(cmd.priority).toBe(5);
- });
-
- it('supports multiple steps in order', () => {
- const cmd = multiStepCommand(base)
- .step({ id: 's1', title: 'First', Component: StubStep })
- .step({ id: 's2', title: 'Second', Component: StubStep })
- .step({ id: 's3', title: 'Third', Component: StubStep })
- .build();
-
- const steps = cmd.multiStep!.steps;
- expect(steps).toHaveLength(3);
- expect(steps[0].id).toBe('s1');
- expect(steps[1].id).toBe('s2');
- expect(steps[2].id).toBe('s3');
- });
-
- it('sets initialContext', () => {
- const cmd = multiStepCommand<{ name: string }>(base)
- .step({ id: 's1', title: 'S1', Component: StubStep })
+ it('preserves the ordered flow configuration', () => {
+ const onComplete = () => undefined;
+ const command = multiStepCommand<{ name: string }>(base)
+ .step({ id: 'first', title: 'First', Component: StubStep })
+ .step({ id: 'second', title: 'Second', Component: StubStep, skippable: true })
.initialContext({ name: 'default' })
+ .onComplete(onComplete)
.build();
- expect(cmd.multiStep!.initialContext).toEqual({ name: 'default' });
+ expect(command.multiStep).toMatchObject({
+ steps: [{ id: 'first' }, { id: 'second', skippable: true }],
+ initialContext: { name: 'default' },
+ onComplete,
+ });
});
- it('sets onComplete callback', () => {
- const fn = vi.fn();
- const cmd = multiStepCommand(base)
- .step({ id: 's1', title: 'S1', Component: StubStep })
- .onComplete(fn)
- .build();
-
- expect(cmd.multiStep!.onComplete).toBe(fn);
+ it('rejects a flow without steps', () => {
+ expect(() => multiStepCommand(base).build()).toThrow('at least one step is required');
});
- it('sets onCancel callback', () => {
- const fn = vi.fn();
- const cmd = multiStepCommand(base)
- .step({ id: 's1', title: 'S1', Component: StubStep })
- .onCancel(fn)
- .build();
-
- expect(cmd.multiStep!.onCancel).toBe(fn);
- });
-
- it('throws if no steps added', () => {
- expect(() => multiStepCommand(base).build()).toThrow(
- 'at least one step is required'
- );
- });
-
- it('throws on duplicate step ids', () => {
+ it('rejects duplicate step ids', () => {
expect(() =>
multiStepCommand(base)
- .step({ id: 'dup', title: 'A', Component: StubStep })
- .step({ id: 'dup', title: 'B', Component: StubStep })
- .build()
- ).toThrow('duplicate step id "dup"');
- });
-
- it('supports fluent chaining', () => {
- const builder = multiStepCommand<{ x: number }>(base);
- const same = builder
- .step({ id: 's1', title: 'S1', Component: StubStep })
- .initialContext({ x: 1 })
- .onComplete(() => {})
- .onCancel(() => {});
-
- // All methods return the same builder
- expect(same).toBe(builder);
- });
-
- it('includes step config fields (loader, validate, skippable)', () => {
- const loader = vi.fn();
- const validate = vi.fn();
-
- const cmd = multiStepCommand(base)
- .step({
- id: 's1',
- title: 'S1',
- Component: StubStep,
- loader,
- validate,
- skippable: true,
- description: 'step desc',
- })
- .build();
-
- const step = cmd.multiStep!.steps[0];
- expect(step.loader).toBe(loader);
- expect(step.validate).toBe(validate);
- expect(step.skippable).toBe(true);
- expect(step.description).toBe('step desc');
+ .step({ id: 'duplicate', title: 'A', Component: StubStep })
+ .step({ id: 'duplicate', title: 'B', Component: StubStep })
+ .build(),
+ ).toThrow('duplicate step id "duplicate"');
});
});
diff --git a/packages/command-palette/src/__tests__/registry.test.ts b/packages/command-palette/src/__tests__/registry.test.ts
index dbac64a..e9072d3 100644
--- a/packages/command-palette/src/__tests__/registry.test.ts
+++ b/packages/command-palette/src/__tests__/registry.test.ts
@@ -1,179 +1,49 @@
-import { describe, it, expect, vi } from 'vitest';
-import { CommandRegistryManager, createCommandRegistry } from '../registry';
+import { describe, expect, it, vi } from 'vitest';
+
+import { CommandRegistryManager } from '../registry';
import type { CommandDefinition, CommandGroupDef } from '../types';
-function makeCommand(overrides: Partial = {}): CommandDefinition {
- return {
- id: 'test-cmd',
- label: 'Test Command',
- type: 'action',
- group: 'test',
- onSelect: () => {},
- ...overrides,
- };
+function command(id: string, label = id): CommandDefinition {
+ return { id, label, type: 'action', group: 'test', onSelect: () => undefined };
}
-function makeGroup(overrides: Partial = {}): CommandGroupDef {
- return {
- id: 'test',
- label: 'Test Group',
- priority: 1,
- ...overrides,
- };
+function group(id: string): CommandGroupDef {
+ return { id, label: id, priority: 1 };
}
describe('CommandRegistryManager', () => {
- it('initializes empty', () => {
- const reg = new CommandRegistryManager();
- expect(reg.getCommands()).toEqual([]);
- expect(reg.getGroups()).toEqual([]);
- });
-
- it('initializes with seed data', () => {
- const reg = new CommandRegistryManager({
- groups: [makeGroup()],
- commands: [makeCommand()],
- });
- expect(reg.getCommands()).toHaveLength(1);
- expect(reg.getGroups()).toHaveLength(1);
- });
+ it('supports dynamic command replacement and removal by id', () => {
+ const registry = new CommandRegistryManager({ commands: [command('a', 'First')], groups: [] });
- it('registers and retrieves commands', () => {
- const reg = new CommandRegistryManager();
- reg.registerCommand(makeCommand({ id: 'a' }));
- reg.registerCommand(makeCommand({ id: 'b' }));
- expect(reg.getCommands()).toHaveLength(2);
- expect(reg.getCommands().map((c) => c.id)).toEqual(['a', 'b']);
- });
+ registry.registerCommand(command('a', 'Replacement'));
+ registry.registerCommand(command('b'));
+ registry.unregisterCommand('b');
- it('unregisters commands', () => {
- const reg = new CommandRegistryManager();
- reg.registerCommand(makeCommand({ id: 'a' }));
- reg.registerCommand(makeCommand({ id: 'b' }));
- reg.unregisterCommand('a');
- expect(reg.getCommands()).toHaveLength(1);
- expect(reg.getCommands()[0].id).toBe('b');
+ expect(registry.getCommands()).toEqual([expect.objectContaining({ id: 'a', label: 'Replacement' })]);
});
- it('overwrites commands with same id', () => {
- const reg = new CommandRegistryManager();
- reg.registerCommand(makeCommand({ id: 'a', label: 'First' }));
- reg.registerCommand(makeCommand({ id: 'a', label: 'Second' }));
- expect(reg.getCommands()).toHaveLength(1);
- expect(reg.getCommands()[0].label).toBe('Second');
- });
+ it('supports dynamic group registration and removal', () => {
+ const registry = new CommandRegistryManager({ groups: [group('a')], commands: [] });
- it('registers and retrieves groups', () => {
- const reg = new CommandRegistryManager();
- reg.registerGroup(makeGroup({ id: 'g1' }));
- reg.registerGroup(makeGroup({ id: 'g2' }));
- expect(reg.getGroups()).toHaveLength(2);
- });
+ registry.registerGroup(group('b'));
+ registry.unregisterGroup('a');
- it('unregisters groups', () => {
- const reg = new CommandRegistryManager();
- reg.registerGroup(makeGroup({ id: 'g1' }));
- reg.registerGroup(makeGroup({ id: 'g2' }));
- reg.unregisterGroup('g1');
- expect(reg.getGroups()).toHaveLength(1);
- expect(reg.getGroups()[0].id).toBe('g2');
+ expect(registry.getGroups()).toEqual([expect.objectContaining({ id: 'b' })]);
});
- it('notifies subscribers on registerCommand', () => {
- const reg = new CommandRegistryManager();
+ it('notifies active subscribers for registry changes and stops after unsubscribe', () => {
+ const registry = new CommandRegistryManager();
const listener = vi.fn();
- reg.subscribe(listener);
- reg.registerCommand(makeCommand());
- expect(listener).toHaveBeenCalledTimes(1);
- });
+ const unsubscribe = registry.subscribe(listener);
- it('notifies subscribers on unregisterCommand', () => {
- const reg = new CommandRegistryManager();
- reg.registerCommand(makeCommand({ id: 'a' }));
- const listener = vi.fn();
- reg.subscribe(listener);
- reg.unregisterCommand('a');
- expect(listener).toHaveBeenCalledTimes(1);
- });
-
- it('notifies subscribers on registerGroup', () => {
- const reg = new CommandRegistryManager();
- const listener = vi.fn();
- reg.subscribe(listener);
- reg.registerGroup(makeGroup());
- expect(listener).toHaveBeenCalledTimes(1);
- });
-
- it('notifies subscribers on unregisterGroup', () => {
- const reg = new CommandRegistryManager();
- reg.registerGroup(makeGroup({ id: 'g1' }));
- const listener = vi.fn();
- reg.subscribe(listener);
- reg.unregisterGroup('g1');
- expect(listener).toHaveBeenCalledTimes(1);
- });
-
- it('unsubscribes correctly', () => {
- const reg = new CommandRegistryManager();
- const listener = vi.fn();
- const unsub = reg.subscribe(listener);
- unsub();
- reg.registerCommand(makeCommand());
- expect(listener).not.toHaveBeenCalled();
- });
-
- it('supports multiple subscribers', () => {
- const reg = new CommandRegistryManager();
- const l1 = vi.fn();
- const l2 = vi.fn();
- reg.subscribe(l1);
- reg.subscribe(l2);
- reg.registerCommand(makeCommand());
- expect(l1).toHaveBeenCalledTimes(1);
- expect(l2).toHaveBeenCalledTimes(1);
- });
-});
-
-describe('createCommandRegistry', () => {
- it('returns a CommandRegistryManager', () => {
- const reg = createCommandRegistry();
- expect(reg).toBeInstanceOf(CommandRegistryManager);
- });
-
- it('passes initial data', () => {
- const reg = createCommandRegistry({
- groups: [makeGroup()],
- commands: [makeCommand()],
- });
- expect(reg.getCommands()).toHaveLength(1);
- expect(reg.getGroups()).toHaveLength(1);
- });
-});
-
-describe('Sorting behavior', () => {
- it('groups sort by priority', () => {
- const reg = createCommandRegistry({
- groups: [
- makeGroup({ id: 'c', priority: 10 }),
- makeGroup({ id: 'a', priority: 1 }),
- makeGroup({ id: 'b', priority: 5 }),
- ],
- commands: [],
- });
- const sorted = reg.getGroups().sort((a, b) => a.priority - b.priority);
- expect(sorted.map((g) => g.id)).toEqual(['a', 'b', 'c']);
- });
+ registry.registerCommand(command('a'));
+ registry.unregisterCommand('a');
+ registry.registerGroup(group('g'));
+ registry.unregisterGroup('g');
+ expect(listener).toHaveBeenCalledTimes(4);
- it('commands sort by priority within a group', () => {
- const commands = [
- makeCommand({ id: 'c', priority: 30, group: 'g1' }),
- makeCommand({ id: 'a', priority: 5, group: 'g1' }),
- makeCommand({ id: 'b', priority: 10, group: 'g1' }),
- makeCommand({ id: 'd', group: 'g1' }), // default 99
- ];
- const sorted = commands.sort(
- (a, b) => (a.priority ?? 99) - (b.priority ?? 99)
- );
- expect(sorted.map((c) => c.id)).toEqual(['a', 'b', 'c', 'd']);
+ unsubscribe();
+ registry.registerCommand(command('ignored'));
+ expect(listener).toHaveBeenCalledTimes(4);
});
});
diff --git a/packages/data/src/__tests__/complex-fields.test.ts b/packages/data/src/__tests__/complex-fields.test.ts
deleted file mode 100644
index b14a32e..0000000
--- a/packages/data/src/__tests__/complex-fields.test.ts
+++ /dev/null
@@ -1,547 +0,0 @@
-/**
- * Tests for complex field handling
- * Tests complex GraphQL types (GeometryPoint, Interval, etc.) and their AST generation with proper subfield selection
- */
-import { beforeEach, describe, expect, it, vi } from "vitest";
-import type { CleanField } from "../data.types";
-import {
- getCustomAstForCleanField,
- requiresSubfieldSelection,
-} from "@constructive-io/graphql-query/custom-ast";
-import { complexTable } from "./fixtures";
-
-// Mock the query builder AST functions
-vi.mock("@constructive-io/graphql-query/custom-ast", () => ({
- requiresSubfieldSelection: vi.fn(),
- getCustomAstForCleanField: vi.fn(),
- geometryPointAst: vi.fn(),
- intervalAst: vi.fn(),
- geometryGeometryCollectionAst: vi.fn(),
- geoJsonAst: vi.fn(),
-}));
-
-describe("complex-fields", () => {
- beforeEach(() => {
- vi.clearAllMocks();
- });
-
- describe("complex field detection", () => {
- it("should detect GeometryPoint as complex field", () => {
- const field: CleanField = {
- name: "location",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "Point",
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should detect Interval as complex field", () => {
- const field: CleanField = {
- name: "timeSpent",
- type: {
- gqlType: "Interval",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "interval",
- subtype: null,
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should detect GeometryGeometryCollection as complex field", () => {
- const field: CleanField = {
- name: "bounds",
- type: {
- gqlType: "GeometryGeometryCollection",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "GeometryCollection",
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should detect GeoJSON as complex field", () => {
- const field: CleanField = {
- name: "geoData",
- type: {
- gqlType: "GeoJSON",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: null,
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should not detect simple types as complex fields", () => {
- const simpleFields = [
- { gqlType: "String", expected: false },
- { gqlType: "Int", expected: false },
- { gqlType: "Boolean", expected: false },
- { gqlType: "UUID", expected: false },
- { gqlType: "JSON", expected: false },
- { gqlType: "Datetime", expected: false },
- ];
-
- simpleFields.forEach(({ gqlType, expected }) => {
- const field: CleanField = {
- name: "testField",
- type: {
- gqlType,
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: gqlType.toLowerCase(),
- subtype: null,
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(expected);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(expected);
- });
- });
-
- it("should handle array complex fields", () => {
- const field: CleanField = {
- name: "locations",
- type: {
- gqlType: "GeometryPoint",
- isArray: true,
- modifier: null,
- pgAlias: null,
- pgType: "geometry[]",
- subtype: "Point",
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
- });
-
- describe("AST generation for complex fields", () => {
- it("should generate AST for GeometryPoint", () => {
- const field: CleanField = {
- name: "location",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "Point",
- typmod: null,
- },
- };
-
- const mockAst = {
- kind: "Field",
- name: { kind: "Name", value: "location" },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- { kind: "Field", name: { kind: "Name", value: "x" } },
- { kind: "Field", name: { kind: "Name", value: "y" } },
- ],
- },
- } as any;
-
- vi.mocked(getCustomAstForCleanField).mockReturnValue(mockAst);
-
- const result = getCustomAstForCleanField(field);
- expect(result).toEqual(mockAst);
- expect(getCustomAstForCleanField).toHaveBeenCalledWith(field);
- });
-
- it("should generate AST for Interval", () => {
- const field: CleanField = {
- name: "timeSpent",
- type: {
- gqlType: "Interval",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "interval",
- subtype: null,
- typmod: null,
- },
- };
-
- const mockAst = {
- kind: "Field",
- name: { kind: "Name", value: "timeSpent" },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- { kind: "Field", name: { kind: "Name", value: "days" } },
- { kind: "Field", name: { kind: "Name", value: "hours" } },
- { kind: "Field", name: { kind: "Name", value: "minutes" } },
- { kind: "Field", name: { kind: "Name", value: "months" } },
- { kind: "Field", name: { kind: "Name", value: "seconds" } },
- { kind: "Field", name: { kind: "Name", value: "years" } },
- ],
- },
- } as any;
-
- vi.mocked(getCustomAstForCleanField).mockReturnValue(mockAst);
-
- const result = getCustomAstForCleanField(field);
- expect(result).toEqual(mockAst);
- });
-
- it("should generate AST for GeometryGeometryCollection", () => {
- const field: CleanField = {
- name: "bounds",
- type: {
- gqlType: "GeometryGeometryCollection",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "GeometryCollection",
- typmod: null,
- },
- };
-
- const mockAst = {
- kind: "Field",
- name: { kind: "Name", value: "bounds" },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- {
- kind: "Field",
- name: { kind: "Name", value: "geometries" },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- {
- kind: "InlineFragment",
- typeCondition: {
- kind: "NamedType",
- name: { kind: "Name", value: "GeometryPoint" },
- },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- { kind: "Field", name: { kind: "Name", value: "x" } },
- { kind: "Field", name: { kind: "Name", value: "y" } },
- ],
- },
- },
- ],
- },
- },
- ],
- },
- } as any;
-
- vi.mocked(getCustomAstForCleanField).mockReturnValue(mockAst);
-
- const result = getCustomAstForCleanField(field);
- expect(result).toEqual(mockAst);
- });
-
- it("should generate AST for GeoJSON", () => {
- const field: CleanField = {
- name: "geoData",
- type: {
- gqlType: "GeoJSON",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: null,
- typmod: null,
- },
- };
-
- const mockAst = {
- kind: "Field",
- name: { kind: "Name", value: "geoData" },
- selectionSet: {
- kind: "SelectionSet",
- selections: [
- { kind: "Field", name: { kind: "Name", value: "geojson" } },
- ],
- },
- } as any;
-
- vi.mocked(getCustomAstForCleanField).mockReturnValue(mockAst);
-
- const result = getCustomAstForCleanField(field);
- expect(result).toEqual(mockAst);
- });
- });
-
- describe("complex field integration", () => {
- it("should handle complex fields in table definition", () => {
- const complexFields = complexTable.fields.filter((field) => {
- vi.mocked(requiresSubfieldSelection).mockImplementation((f: CleanField) => {
- return [
- "GeometryPoint",
- "Interval",
- "GeometryGeometryCollection",
- "GeoJSON",
- ].includes(f.type.gqlType);
- });
- return requiresSubfieldSelection(field);
- });
-
- expect(complexFields.length).toBeGreaterThan(0);
-
- complexFields.forEach((field) => {
- expect([
- "GeometryPoint",
- "Interval",
- "GeometryGeometryCollection",
- "GeoJSON",
- ]).toContain(field.type.gqlType);
- });
- });
-
- it("should handle mixed simple and complex fields", () => {
- const allFields = complexTable.fields;
-
- vi.mocked(requiresSubfieldSelection).mockImplementation((field: CleanField) => {
- return [
- "GeometryPoint",
- "Interval",
- "GeometryGeometryCollection",
- "GeoJSON",
- ].includes(field.type.gqlType);
- });
-
- const complexFields = allFields.filter(requiresSubfieldSelection);
- const simpleFields = allFields.filter(
- (field) => !requiresSubfieldSelection(field),
- );
-
- expect(complexFields.length).toBeGreaterThan(0);
- expect(simpleFields.length).toBeGreaterThan(0);
- expect(complexFields.length + simpleFields.length).toBe(allFields.length);
- });
-
- it("should handle complex fields with different PostgreSQL subtypes", () => {
- const geometryFields = [
- {
- name: "point",
- type: { gqlType: "GeometryPoint", subtype: "Point" },
- },
- {
- name: "polygon",
- type: { gqlType: "GeometryPolygon", subtype: "Polygon" },
- },
- {
- name: "collection",
- type: {
- gqlType: "GeometryGeometryCollection",
- subtype: "GeometryCollection",
- },
- },
- ];
-
- geometryFields.forEach((field) => {
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
- expect(requiresSubfieldSelection(field as CleanField)).toBe(true);
- });
- });
- });
-
- describe("edge cases and error handling", () => {
- it("should handle fields with null subtype", () => {
- const field: CleanField = {
- name: "testField",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: null,
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should handle fields with undefined properties", () => {
- const field: CleanField = {
- name: "testField",
- type: {
- gqlType: "Interval",
- isArray: false,
- modifier: undefined,
- pgAlias: undefined,
- pgType: "interval",
- subtype: undefined,
- typmod: undefined,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
-
- it("should handle unknown complex types gracefully", () => {
- const field: CleanField = {
- name: "unknownField",
- type: {
- gqlType: "UnknownComplexType",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "unknown",
- subtype: null,
- typmod: null,
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(false);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(false);
- });
-
- it("should handle AST generation errors gracefully", () => {
- const field: CleanField = {
- name: "problematicField",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "Point",
- typmod: null,
- },
- };
-
- vi.mocked(getCustomAstForCleanField).mockImplementation(() => {
- throw new Error("AST generation failed");
- });
-
- expect(() => getCustomAstForCleanField(field)).toThrow(
- "AST generation failed",
- );
- });
-
- it("should handle complex fields with SRID information", () => {
- const field: CleanField = {
- name: "locationWithSRID",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: "NOT NULL",
- pgAlias: "point",
- pgType: "geometry",
- subtype: "Point",
- typmod: 4326, // SRID
- },
- };
-
- vi.mocked(requiresSubfieldSelection).mockReturnValue(true);
-
- const result = requiresSubfieldSelection(field);
- expect(result).toBe(true);
- });
- });
-
- describe("performance considerations", () => {
- it("should efficiently detect complex fields in large tables", () => {
- const largeFieldSet = Array.from({ length: 100 }, (_, i) => ({
- name: `field${i}`,
- type: {
- gqlType: i % 10 === 0 ? "GeometryPoint" : "String",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: i % 10 === 0 ? "geometry" : "text",
- subtype: i % 10 === 0 ? "Point" : null,
- typmod: null,
- },
- }));
-
- vi.mocked(requiresSubfieldSelection).mockImplementation((field: CleanField) => {
- return field.type.gqlType === "GeometryPoint";
- });
-
- const complexFields = largeFieldSet.filter(requiresSubfieldSelection);
- expect(complexFields).toHaveLength(10);
- });
-
- it("should cache AST generation results when possible", () => {
- const field: CleanField = {
- name: "location",
- type: {
- gqlType: "GeometryPoint",
- isArray: false,
- modifier: null,
- pgAlias: null,
- pgType: "geometry",
- subtype: "Point",
- typmod: null,
- },
- };
-
- const mockAst = {
- kind: "Field",
- name: { kind: "Name", value: "location" },
- } as any;
- vi.mocked(getCustomAstForCleanField).mockReturnValue(mockAst);
-
- // Call multiple times
- const result1 = getCustomAstForCleanField(field);
- const result2 = getCustomAstForCleanField(field);
-
- expect(result1).toEqual(mockAst);
- expect(result2).toEqual(mockAst);
- expect(getCustomAstForCleanField).toHaveBeenCalledTimes(2);
- });
- });
-});
diff --git a/packages/data/src/__tests__/data.types.test.ts b/packages/data/src/__tests__/data.types.test.ts
index df409cf..7e2bb4d 100644
--- a/packages/data/src/__tests__/data.types.test.ts
+++ b/packages/data/src/__tests__/data.types.test.ts
@@ -3,9 +3,9 @@
* Tests core type definitions, utilities, and type conversion functions
*/
import { beforeEach, describe, expect, it } from "vitest";
-import type { CleanTable, Filter, MetaTable } from "../data.types";
+import type { CleanTable, MetaTable } from "../data.types";
import { cleanTable, pgFieldToCamelCase } from "../data.types";
-import { complexTable, filterFixtures, simpleTable } from "./fixtures";
+import { complexTable, simpleTable } from "./fixtures";
import { createMockMetaResponse, createMockTable } from "./test-helpers";
describe("data.types", () => {
@@ -422,62 +422,6 @@ describe("data.types", () => {
});
});
- describe("Filter type validation", () => {
- it("should accept valid simple filters", () => {
- const filter: Filter = filterFixtures.simple;
-
- expect(filter).toEqual({
- isActive: { equalTo: true },
- });
- });
-
- it("should accept valid string operator filters", () => {
- const filter: Filter = filterFixtures.stringOperators;
-
- expect(filter).toEqual({
- name: { includes: "test" },
- email: { endsWith: "@example.com" },
- description: { startsWith: "Important" },
- });
- });
-
- it("should accept valid numeric operator filters", () => {
- const filter: Filter = filterFixtures.numericOperators;
-
- expect(filter).toEqual({
- age: { greaterThan: 18 },
- score: { lessThanOrEqualTo: 100 },
- rating: { in: [4, 5] },
- });
- });
-
- it("should accept valid logical operator filters", () => {
- const filter: Filter = filterFixtures.logicalOperators;
-
- expect(filter).toHaveProperty("and");
- expect(filter).toHaveProperty("or");
- expect(Array.isArray(filter.and)).toBe(true);
- expect(Array.isArray(filter.or)).toBe(true);
- });
-
- it("should accept valid nested filters", () => {
- const filter: Filter = filterFixtures.nested;
-
- expect(filter).toHaveProperty("and");
- expect(Array.isArray(filter.and)).toBe(true);
- expect(filter.and).toHaveLength(2);
- });
-
- it("should accept valid relational filters", () => {
- const filter: Filter = filterFixtures.relational;
-
- expect(filter).toHaveProperty("posts");
- expect(filter).toHaveProperty("profile");
- expect(filter.posts).toHaveProperty("some");
- expect(filter.profile).toHaveProperty("every");
- });
- });
-
describe("pgFieldToCamelCase", () => {
it("should convert snake_case to camelCase", () => {
expect(pgFieldToCamelCase("owner_id")).toBe("ownerId");
diff --git a/packages/data/src/__tests__/mutation-input.node.test.ts b/packages/data/src/__tests__/mutation-input.node.test.ts
index 7f6533f..f8495a8 100644
--- a/packages/data/src/__tests__/mutation-input.node.test.ts
+++ b/packages/data/src/__tests__/mutation-input.node.test.ts
@@ -5,7 +5,6 @@
import { describe, expect, it } from "vitest";
import {
- type PartialBy,
prepareCreateInput,
prepareMutationInput,
preparePatchInput,
@@ -363,30 +362,6 @@ describe("prepareMutationInput direct usage", () => {
});
});
-// =========================================================================
-// PartialBy Type Utility (compile-time checks)
-// =========================================================================
-describe("PartialBy type utility", () => {
- it("makes specified keys optional (compile-time check)", () => {
- type Input = { name: string; inheritsId: string; databaseId: string };
- type SafeInput = PartialBy;
-
- // This compiles — inheritsId is now optional
- const valid: SafeInput = { name: "test", databaseId: "db-1" };
- expect(valid.name).toBe("test");
- expect(valid.databaseId).toBe("db-1");
- expect(valid).not.toHaveProperty("inheritsId");
- });
-
- it("makes multiple keys optional", () => {
- type Input = { name: string; inheritsId: string; databaseId: string };
- type SafeInput = PartialBy;
-
- const valid: SafeInput = { name: "test" };
- expect(valid.name).toBe("test");
- });
-});
-
// =========================================================================
// stripEmpty
// =========================================================================
diff --git a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/builder.test.ts.snap b/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/builder.test.ts.snap
deleted file mode 100644
index 5c41d1b..0000000
--- a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/builder.test.ts.snap
+++ /dev/null
@@ -1,507 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`create with custom selection 1`] = `
-"mutation createActionMutation($id: UUID, $slug: String, $photo: JSON, $shareImage: JSON, $title: String, $titleObjectTemplate: String, $url: String, $description: String, $discoveryHeader: String, $discoveryDescription: String, $notificationText: String, $notificationObjectTemplate: String, $enableNotifications: Boolean, $enableNotificationsText: String, $search: FullText, $location: GeoJSON, $locationRadius: BigFloat, $timeRequired: IntervalInput, $startDate: Datetime, $endDate: Datetime, $approved: Boolean, $published: Boolean, $isPrivate: Boolean, $rewardAmount: BigFloat, $activityFeedText: String, $callToAction: String, $completedActionText: String, $alreadyCompletedActionText: String, $selfVerifiable: Boolean, $isRecurring: Boolean, $recurringInterval: IntervalInput, $oncePerObject: Boolean, $minimumGroupMembers: Int, $limitedToLocation: Boolean, $tags: [String], $groupId: UUID, $ownerId: UUID!, $objectTypeId: Int, $rewardId: UUID, $verifyRewardId: UUID, $photoUpload: Upload, $shareImageUpload: Upload) {
- createAction(
- input: {action: {id: $id, slug: $slug, photo: $photo, shareImage: $shareImage, title: $title, titleObjectTemplate: $titleObjectTemplate, url: $url, description: $description, discoveryHeader: $discoveryHeader, discoveryDescription: $discoveryDescription, notificationText: $notificationText, notificationObjectTemplate: $notificationObjectTemplate, enableNotifications: $enableNotifications, enableNotificationsText: $enableNotificationsText, search: $search, location: $location, locationRadius: $locationRadius, timeRequired: $timeRequired, startDate: $startDate, endDate: $endDate, approved: $approved, published: $published, isPrivate: $isPrivate, rewardAmount: $rewardAmount, activityFeedText: $activityFeedText, callToAction: $callToAction, completedActionText: $completedActionText, alreadyCompletedActionText: $alreadyCompletedActionText, selfVerifiable: $selfVerifiable, isRecurring: $isRecurring, recurringInterval: $recurringInterval, oncePerObject: $oncePerObject, minimumGroupMembers: $minimumGroupMembers, limitedToLocation: $limitedToLocation, tags: $tags, groupId: $groupId, ownerId: $ownerId, objectTypeId: $objectTypeId, rewardId: $rewardId, verifyRewardId: $verifyRewardId, photoUpload: $photoUpload, shareImageUpload: $shareImageUpload}}
- ) {
- action {
- id
- photo
- title
- }
- }
-}
-"
-`;
-
-exports[`create with custom selection 2`] = `"createActionMutation"`;
-
-exports[`create with default scalar selection 1`] = `
-"mutation createActionMutation($id: UUID, $slug: String, $photo: JSON, $shareImage: JSON, $title: String, $titleObjectTemplate: String, $url: String, $description: String, $discoveryHeader: String, $discoveryDescription: String, $notificationText: String, $notificationObjectTemplate: String, $enableNotifications: Boolean, $enableNotificationsText: String, $search: FullText, $location: GeoJSON, $locationRadius: BigFloat, $timeRequired: IntervalInput, $startDate: Datetime, $endDate: Datetime, $approved: Boolean, $published: Boolean, $isPrivate: Boolean, $rewardAmount: BigFloat, $activityFeedText: String, $callToAction: String, $completedActionText: String, $alreadyCompletedActionText: String, $selfVerifiable: Boolean, $isRecurring: Boolean, $recurringInterval: IntervalInput, $oncePerObject: Boolean, $minimumGroupMembers: Int, $limitedToLocation: Boolean, $tags: [String], $groupId: UUID, $ownerId: UUID!, $objectTypeId: Int, $rewardId: UUID, $verifyRewardId: UUID, $photoUpload: Upload, $shareImageUpload: Upload) {
- createAction(
- input: {action: {id: $id, slug: $slug, photo: $photo, shareImage: $shareImage, title: $title, titleObjectTemplate: $titleObjectTemplate, url: $url, description: $description, discoveryHeader: $discoveryHeader, discoveryDescription: $discoveryDescription, notificationText: $notificationText, notificationObjectTemplate: $notificationObjectTemplate, enableNotifications: $enableNotifications, enableNotificationsText: $enableNotificationsText, search: $search, location: $location, locationRadius: $locationRadius, timeRequired: $timeRequired, startDate: $startDate, endDate: $endDate, approved: $approved, published: $published, isPrivate: $isPrivate, rewardAmount: $rewardAmount, activityFeedText: $activityFeedText, callToAction: $callToAction, completedActionText: $completedActionText, alreadyCompletedActionText: $alreadyCompletedActionText, selfVerifiable: $selfVerifiable, isRecurring: $isRecurring, recurringInterval: $recurringInterval, oncePerObject: $oncePerObject, minimumGroupMembers: $minimumGroupMembers, limitedToLocation: $limitedToLocation, tags: $tags, groupId: $groupId, ownerId: $ownerId, objectTypeId: $objectTypeId, rewardId: $rewardId, verifyRewardId: $verifyRewardId, photoUpload: $photoUpload, shareImageUpload: $shareImageUpload}}
- ) {
- action {
- id
- slug
- photo
- shareImage
- title
- titleObjectTemplate
- url
- description
- discoveryHeader
- discoveryDescription
- notificationText
- notificationObjectTemplate
- enableNotifications
- enableNotificationsText
- search
- location {
- geojson
- }
- locationRadius
- timeRequired {
- days
- hours
- minutes
- months
- seconds
- years
- }
- startDate
- endDate
- approved
- published
- isPrivate
- rewardAmount
- activityFeedText
- callToAction
- completedActionText
- alreadyCompletedActionText
- selfVerifiable
- isRecurring
- recurringInterval {
- days
- hours
- minutes
- months
- seconds
- years
- }
- oncePerObject
- minimumGroupMembers
- limitedToLocation
- tags
- createdBy
- updatedBy
- createdAt
- updatedAt
- }
- }
-}
-"
-`;
-
-exports[`create with default scalar selection 2`] = `"createActionMutation"`;
-
-exports[`delete 1`] = `
-"mutation deleteActionMutation($id: UUID!) {
- deleteAction(input: {id: $id}) {
- clientMutationId
- }
-}
-"
-`;
-
-exports[`delete 2`] = `"deleteActionMutation"`;
-
-exports[`expands further selections of custom ast fields in nested selection 1`] = `
-"query getActionGoalsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionGoalCondition, $filter: ActionGoalFilter, $orderBy: [ActionGoalsOrderBy!]) {
- actionGoals(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- action {
- id
- location {
- geojson
- }
- timeRequired {
- days
- hours
- minutes
- months
- seconds
- years
- }
- }
- }}
-}
-"
-`;
-
-exports[`expands further selections of custom ast fields in nested selection 2`] = `"getActionGoalsQuery"`;
-
-exports[`getAll 1`] = `
-"query getActionsQueryAll {
- actions {totalCount, nodes {
- id
- photo
- title
- }}
-}
-"
-`;
-
-exports[`getAll 2`] = `"getActionsQueryAll"`;
-
-exports[`getMany edges 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, edges {
- cursor
- node {
- id
- photo
- title
- }
- }}
-}
-"
-`;
-
-exports[`getMany edges 2`] = `"getActionsQuery"`;
-
-exports[`getMany should select only scalar fields by default 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- id
- slug
- photo
- shareImage
- title
- titleObjectTemplate
- url
- description
- discoveryHeader
- discoveryDescription
- notificationText
- notificationObjectTemplate
- enableNotifications
- enableNotificationsText
- search
- location {
- geojson
- }
- locationRadius
- timeRequired {
- days
- hours
- minutes
- months
- seconds
- years
- }
- startDate
- endDate
- approved
- published
- isPrivate
- rewardAmount
- activityFeedText
- callToAction
- completedActionText
- alreadyCompletedActionText
- selfVerifiable
- isRecurring
- recurringInterval {
- days
- hours
- minutes
- months
- seconds
- years
- }
- oncePerObject
- minimumGroupMembers
- limitedToLocation
- tags
- createdBy
- updatedBy
- createdAt
- updatedAt
- }}
-}
-"
-`;
-
-exports[`getMany should select only scalar fields by default 2`] = `"getActionsQuery"`;
-
-exports[`getMany should whitelist selected fields 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- id
- photo
- title
- }}
-}
-"
-`;
-
-exports[`getMany should whitelist selected fields 2`] = `"getActionsQuery"`;
-
-exports[`getOne 1`] = `
-"query getActionQuery($id: UUID!) {
- action(id: $id) {
- id
- photo
- title
- }
-}
-"
-`;
-
-exports[`getOne 2`] = `"getActionQuery"`;
-
-exports[`selects all scalar fields of junction table by default 1`] = `
-"query getActionGoalsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionGoalCondition, $filter: ActionGoalFilter, $orderBy: [ActionGoalsOrderBy!]) {
- actionGoals(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- createdBy
- updatedBy
- createdAt
- updatedAt
- actionId
- goalId
- }}
-}
-"
-`;
-
-exports[`selects belongsTo relation field 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- owner {
- id
- }
- }}
-}
-"
-`;
-
-exports[`selects non-scalar custom types 1`] = `"getActionsQuery"`;
-
-exports[`selects relation field 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- id
- slug
- photo
- title
- url
- goals(first: 3) {totalCount, nodes {
- id
- name
- slug
- shortName
- icon
- subHead
- tags
- search
- createdBy
- updatedBy
- createdAt
- updatedAt
- }}
- }}
-}
-"
-`;
-
-exports[`should select totalCount in subfields by default 1`] = `
-"query getActionsQuery($first: Int, $last: Int, $after: Cursor, $before: Cursor, $offset: Int, $condition: ActionCondition, $filter: ActionFilter, $orderBy: [ActionsOrderBy!]) {
- actions(
- first: $first
- last: $last
- offset: $offset
- after: $after
- before: $before
- condition: $condition
- filter: $filter
- orderBy: $orderBy
- ) {totalCount, pageInfo {
- hasNextPage
- hasPreviousPage
- endCursor
- startCursor
- }, nodes {
- id
- photo
- title
- }}
-}
-"
-`;
-
-exports[`should select totalCount in subfields by default 2`] = `"getActionsQuery"`;
-
-exports[`update with custom selection 1`] = `
-"mutation updateActionMutation($id: UUID!, $slug: String, $photo: JSON, $shareImage: JSON, $title: String, $titleObjectTemplate: String, $url: String, $description: String, $discoveryHeader: String, $discoveryDescription: String, $notificationText: String, $notificationObjectTemplate: String, $enableNotifications: Boolean, $enableNotificationsText: String, $search: FullText, $location: GeoJSON, $locationRadius: BigFloat, $timeRequired: IntervalInput, $startDate: Datetime, $endDate: Datetime, $approved: Boolean, $published: Boolean, $isPrivate: Boolean, $rewardAmount: BigFloat, $activityFeedText: String, $callToAction: String, $completedActionText: String, $alreadyCompletedActionText: String, $selfVerifiable: Boolean, $isRecurring: Boolean, $recurringInterval: IntervalInput, $oncePerObject: Boolean, $minimumGroupMembers: Int, $limitedToLocation: Boolean, $tags: [String], $groupId: UUID, $ownerId: UUID, $objectTypeId: Int, $rewardId: UUID, $verifyRewardId: UUID, $photoUpload: Upload, $shareImageUpload: Upload) {
- updateAction(
- input: {id: $id, patch: {slug: $slug, photo: $photo, shareImage: $shareImage, title: $title, titleObjectTemplate: $titleObjectTemplate, url: $url, description: $description, discoveryHeader: $discoveryHeader, discoveryDescription: $discoveryDescription, notificationText: $notificationText, notificationObjectTemplate: $notificationObjectTemplate, enableNotifications: $enableNotifications, enableNotificationsText: $enableNotificationsText, search: $search, location: $location, locationRadius: $locationRadius, timeRequired: $timeRequired, startDate: $startDate, endDate: $endDate, approved: $approved, published: $published, isPrivate: $isPrivate, rewardAmount: $rewardAmount, activityFeedText: $activityFeedText, callToAction: $callToAction, completedActionText: $completedActionText, alreadyCompletedActionText: $alreadyCompletedActionText, selfVerifiable: $selfVerifiable, isRecurring: $isRecurring, recurringInterval: $recurringInterval, oncePerObject: $oncePerObject, minimumGroupMembers: $minimumGroupMembers, limitedToLocation: $limitedToLocation, tags: $tags, groupId: $groupId, ownerId: $ownerId, objectTypeId: $objectTypeId, rewardId: $rewardId, verifyRewardId: $verifyRewardId, photoUpload: $photoUpload, shareImageUpload: $shareImageUpload}}
- ) {
- action {
- id
- photo
- title
- }
- }
-}
-"
-`;
-
-exports[`update with custom selection 2`] = `"updateActionMutation"`;
-
-exports[`update with default scalar selection 1`] = `
-"mutation updateActionMutation($id: UUID!, $slug: String, $photo: JSON, $shareImage: JSON, $title: String, $titleObjectTemplate: String, $url: String, $description: String, $discoveryHeader: String, $discoveryDescription: String, $notificationText: String, $notificationObjectTemplate: String, $enableNotifications: Boolean, $enableNotificationsText: String, $search: FullText, $location: GeoJSON, $locationRadius: BigFloat, $timeRequired: IntervalInput, $startDate: Datetime, $endDate: Datetime, $approved: Boolean, $published: Boolean, $isPrivate: Boolean, $rewardAmount: BigFloat, $activityFeedText: String, $callToAction: String, $completedActionText: String, $alreadyCompletedActionText: String, $selfVerifiable: Boolean, $isRecurring: Boolean, $recurringInterval: IntervalInput, $oncePerObject: Boolean, $minimumGroupMembers: Int, $limitedToLocation: Boolean, $tags: [String], $groupId: UUID, $ownerId: UUID, $objectTypeId: Int, $rewardId: UUID, $verifyRewardId: UUID, $photoUpload: Upload, $shareImageUpload: Upload) {
- updateAction(
- input: {id: $id, patch: {slug: $slug, photo: $photo, shareImage: $shareImage, title: $title, titleObjectTemplate: $titleObjectTemplate, url: $url, description: $description, discoveryHeader: $discoveryHeader, discoveryDescription: $discoveryDescription, notificationText: $notificationText, notificationObjectTemplate: $notificationObjectTemplate, enableNotifications: $enableNotifications, enableNotificationsText: $enableNotificationsText, search: $search, location: $location, locationRadius: $locationRadius, timeRequired: $timeRequired, startDate: $startDate, endDate: $endDate, approved: $approved, published: $published, isPrivate: $isPrivate, rewardAmount: $rewardAmount, activityFeedText: $activityFeedText, callToAction: $callToAction, completedActionText: $completedActionText, alreadyCompletedActionText: $alreadyCompletedActionText, selfVerifiable: $selfVerifiable, isRecurring: $isRecurring, recurringInterval: $recurringInterval, oncePerObject: $oncePerObject, minimumGroupMembers: $minimumGroupMembers, limitedToLocation: $limitedToLocation, tags: $tags, groupId: $groupId, ownerId: $ownerId, objectTypeId: $objectTypeId, rewardId: $rewardId, verifyRewardId: $verifyRewardId, photoUpload: $photoUpload, shareImageUpload: $shareImageUpload}}
- ) {
- action {
- id
- slug
- photo
- shareImage
- title
- titleObjectTemplate
- url
- description
- discoveryHeader
- discoveryDescription
- notificationText
- notificationObjectTemplate
- enableNotifications
- enableNotificationsText
- search
- location {
- geojson
- }
- locationRadius
- timeRequired {
- days
- hours
- minutes
- months
- seconds
- years
- }
- startDate
- endDate
- approved
- published
- isPrivate
- rewardAmount
- activityFeedText
- callToAction
- completedActionText
- alreadyCompletedActionText
- selfVerifiable
- isRecurring
- recurringInterval {
- days
- hours
- minutes
- months
- seconds
- years
- }
- oncePerObject
- minimumGroupMembers
- limitedToLocation
- tags
- createdBy
- updatedBy
- createdAt
- updatedAt
- }
- }
-}
-"
-`;
-
-exports[`update with default scalar selection 2`] = `"updateActionMutation"`;
diff --git a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.node.test.ts.snap b/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.node.test.ts.snap
deleted file mode 100644
index c1bf9d7..0000000
--- a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.node.test.ts.snap
+++ /dev/null
@@ -1,6568 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`convertFromMetaSchema() > matches snapshot 1`] = `
-{
- "tables": [
- {
- "fields": [
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "goal",
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Goal",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionGoal",
- "primaryConstraints": [
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "itemOrder",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "timeRequired",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isRequired",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "notificationText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "embedCode",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "url",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "media",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionItem",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionResult",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "photo",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "title",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "url",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "discoveryHeader",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "discoveryDescription",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "enableNotifications",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "enableNotificationsText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "search",
- "type": {
- "gqlType": "FullText",
- "isArray": false,
- "modifier": null,
- "pgAlias": "tsvector",
- "pgType": "tsvector",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "locationRadius",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "timeRequired",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "startDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "endDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "approved",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rewardAmount",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "activityFeedText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "callToAction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "completedActionText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "alreadyCompletedActionText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Action",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "data",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "receiver",
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ClaimedInvite",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "details",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ConnectedAccount",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "address",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "CryptoAddress",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "address",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Email",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "audio",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "attachment",
- "pgType": "attachment",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "audioDuration",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "explanationTitle",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "explanation",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "goal",
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Goal",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "GoalExplanation",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "shortName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "icon",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "subHead",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "search",
- "type": {
- "gqlType": "FullText",
- "isArray": false,
- "modifier": null,
- "pgAlias": "tsvector",
- "pgType": "tsvector",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "Goal",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteToken",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteValid",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteLimit",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteCount",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "multiple",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "data",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "expiresAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Invite",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "level",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "requiredCount",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "priority",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "LevelRequirement",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "level",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "Level",
- "primaryConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "memberIds",
- "type": {
- "gqlType": "[UUID]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "MessageGroup",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "content",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "upload",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "groupId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "group",
- "name": "groupId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "MessageGroup",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Message",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "link",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "publishedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "photo",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "NewsUpdate",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "profilePicture",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "website",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reputation",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "organization",
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "OrganizationProfile",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "cc",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "number",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "PhoneNumber",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "number",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "count",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "UserAchievement",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "value",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "status",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "actionItem",
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "ActionItem",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionItem",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reacterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "reacter",
- "name": "reacterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionReaction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "value",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "actionResult",
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "ActionResult",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionResult",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionStarted",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "complete",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verifiedDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userRating",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rejected",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rejectedReason",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verifierId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "verifier",
- "name": "verifierId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "income",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "gender",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": 5,
- "pgAlias": "char",
- "pgType": "bpchar",
- "subtype": null,
- "typmod": {
- "modifier": 5,
- },
- },
- },
- {
- "name": "race",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "age",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "dob",
- "type": {
- "gqlType": "Date",
- "isArray": false,
- "modifier": null,
- "pgAlias": "date",
- "pgType": "date",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "education",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "homeOwnership",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "treeHuggerLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "diyLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "gardenerLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "freeTime",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "researchToDoer",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserCharacteristic",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "accepted",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "requester",
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "responder",
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserConnection",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "vcf",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "fullName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "emails",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "device",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserContact",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "content",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "upload",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "received",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverRead",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderReaction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverReaction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "receiver",
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserMessage",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserPassAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "profilePicture",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "bio",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reputation",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "displayName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "desired",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserProfile",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserSavedAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "firstName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "lastName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "searchRadius",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserSetting",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "count",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "UserStep",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserViewedAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "User",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "bbox",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107468,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPolygon",
- "typmod": {
- "gisType": "Polygon",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 3,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "ZipCode",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "details",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "AuthAccount",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- ],
-}
-`;
diff --git a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.test.ts.snap b/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.test.ts.snap
deleted file mode 100644
index 9458975..0000000
--- a/packages/data/src/__tests__/query-builder/__tests__/__snapshots__/meta-object.test.ts.snap
+++ /dev/null
@@ -1,6568 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`convertFromMetaSchema() matches snapshot 1`] = `
-{
- "tables": [
- {
- "fields": [
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "goal",
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Goal",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionGoal",
- "primaryConstraints": [
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "itemOrder",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "timeRequired",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isRequired",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "notificationText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "embedCode",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "url",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "media",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionItem",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ActionResult",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "photo",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "title",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "url",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "discoveryHeader",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "discoveryDescription",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "enableNotifications",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "enableNotificationsText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "search",
- "type": {
- "gqlType": "FullText",
- "isArray": false,
- "modifier": null,
- "pgAlias": "tsvector",
- "pgType": "tsvector",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "locationRadius",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "timeRequired",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "startDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "endDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "approved",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rewardAmount",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "activityFeedText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "callToAction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "completedActionText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "alreadyCompletedActionText",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Action",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "data",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "receiver",
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ClaimedInvite",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "details",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "ConnectedAccount",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "address",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "CryptoAddress",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "address",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Email",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "audio",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "attachment",
- "pgType": "attachment",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "audioDuration",
- "type": {
- "gqlType": "Interval",
- "isArray": false,
- "modifier": null,
- "pgAlias": "interval",
- "pgType": "interval",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "explanationTitle",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "explanation",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "goal",
- "name": "goalId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Goal",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "GoalExplanation",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "slug",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "shortName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "icon",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "subHead",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "search",
- "type": {
- "gqlType": "FullText",
- "isArray": false,
- "modifier": null,
- "pgAlias": "tsvector",
- "pgType": "tsvector",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "Goal",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteToken",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteValid",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteLimit",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "inviteCount",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "multiple",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "data",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "expiresAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Invite",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "email",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "level",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "requiredCount",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "priority",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "LevelRequirement",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "level",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "Level",
- "primaryConstraints": [
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "memberIds",
- "type": {
- "gqlType": "[UUID]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "MessageGroup",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "content",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "upload",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "groupId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "group",
- "name": "groupId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "MessageGroup",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "Message",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "link",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "publishedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "photo",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "NewsUpdate",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "profilePicture",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "description",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "website",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "url",
- "pgType": "url",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reputation",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "organization",
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "OrganizationProfile",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "organizationId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "cc",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "number",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isPrimary",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "PhoneNumber",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "number",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "count",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "UserAchievement",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "value",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "status",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "actionItem",
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "ActionItem",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionItem",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionItemId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reacterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "reacter",
- "name": "reacterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionReaction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "value",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "userAction",
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "UserAction",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "actionResult",
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "ActionResult",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserActionResult",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userActionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionResultId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionStarted",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "complete",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verifiedDate",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userRating",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rejected",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "rejectedReason",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "verifierId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "verifier",
- "name": "verifierId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "income",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "gender",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": 5,
- "pgAlias": "char",
- "pgType": "bpchar",
- "subtype": null,
- "typmod": {
- "modifier": 5,
- },
- },
- },
- {
- "name": "race",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "age",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "dob",
- "type": {
- "gqlType": "Date",
- "isArray": false,
- "modifier": null,
- "pgAlias": "date",
- "pgType": "date",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "education",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "homeOwnership",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "treeHuggerLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "diyLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "gardenerLevel",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "freeTime",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "researchToDoer",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "smallint",
- "pgType": "int2",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserCharacteristic",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "accepted",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "requester",
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "responder",
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserConnection",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "requesterId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "responderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "vcf",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "fullName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "emails",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "email",
- "pgType": "email",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "device",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserContact",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "content",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "upload",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "upload",
- "pgType": "upload",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "received",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverRead",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderReaction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverReaction",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "sender",
- "name": "senderId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "receiver",
- "name": "receiverId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserMessage",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserPassAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "profilePicture",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "image",
- "pgType": "image",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "bio",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "reputation",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "displayName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "tags",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "desired",
- "type": {
- "gqlType": "[String]",
- "isArray": true,
- "modifier": null,
- "pgAlias": "citext",
- "pgType": "citext",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserProfile",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserSavedAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "firstName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "lastName",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "searchRadius",
- "type": {
- "gqlType": "BigFloat",
- "isArray": false,
- "modifier": null,
- "pgAlias": "numeric",
- "pgType": "numeric",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserSetting",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "name",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "count",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "UserStep",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "user",
- "name": "userId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- {
- "fromKey": {
- "alias": "action",
- "name": "actionId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "Action",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "UserViewedAction",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "type",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "User",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "location",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107460,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPoint",
- "typmod": {
- "gisType": "Point",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 1,
- },
- },
- },
- {
- "name": "bbox",
- "type": {
- "gqlType": "GeoJSON",
- "isArray": false,
- "modifier": 1107468,
- "pgAlias": "geometry",
- "pgType": "geometry",
- "subtype": "GeometryPolygon",
- "typmod": {
- "gisType": "Polygon",
- "hasM": false,
- "hasZ": false,
- "srid": 4326,
- "subtype": 3,
- },
- },
- },
- {
- "name": "createdBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedBy",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "createdAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "updatedAt",
- "type": {
- "gqlType": "Datetime",
- "isArray": false,
- "modifier": null,
- "pgAlias": "timestamptz",
- "pgType": "timestamptz",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [],
- "name": "ZipCode",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "zip",
- "type": {
- "gqlType": "Int",
- "isArray": false,
- "modifier": null,
- "pgAlias": "int",
- "pgType": "int4",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- {
- "fields": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "details",
- "type": {
- "gqlType": "JSON",
- "isArray": false,
- "modifier": null,
- "pgAlias": "jsonb",
- "pgType": "jsonb",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "isVerified",
- "type": {
- "gqlType": "Boolean",
- "isArray": false,
- "modifier": null,
- "pgAlias": "boolean",
- "pgType": "bool",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "foreignConstraints": [
- {
- "fromKey": {
- "alias": "owner",
- "name": "ownerId",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- "refTable": "User",
- "toKey": {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- },
- ],
- "name": "AuthAccount",
- "primaryConstraints": [
- {
- "name": "id",
- "type": {
- "gqlType": "UUID",
- "isArray": false,
- "modifier": null,
- "pgAlias": "uuid",
- "pgType": "uuid",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- "uniqueConstraints": [
- {
- "name": "service",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- {
- "name": "identifier",
- "type": {
- "gqlType": "String",
- "isArray": false,
- "modifier": null,
- "pgAlias": "text",
- "pgType": "text",
- "subtype": null,
- "typmod": null,
- },
- },
- ],
- },
- ],
-}
-`;
diff --git a/packages/data/src/__tests__/query-builder/__tests__/meta-object.node.test.ts b/packages/data/src/__tests__/query-builder/__tests__/meta-object.node.test.ts
index 07a5fbe..4f4825f 100644
--- a/packages/data/src/__tests__/query-builder/__tests__/meta-object.node.test.ts
+++ b/packages/data/src/__tests__/query-builder/__tests__/meta-object.node.test.ts
@@ -9,8 +9,4 @@ describe('convertFromMetaSchema()', () => {
const validate = validateMetaObject(metaObj);
expect(validate).toBe(true);
});
-
- it('matches snapshot', () => {
- expect(convertFromMetaSchema(apiMetaSchema as any)).toMatchSnapshot();
- });
});
diff --git a/packages/data/src/__tests__/query-generator.test.ts b/packages/data/src/__tests__/query-generator.test.ts
index 9a387a0..1432fd6 100644
--- a/packages/data/src/__tests__/query-generator.test.ts
+++ b/packages/data/src/__tests__/query-generator.test.ts
@@ -12,7 +12,6 @@ import {
buildPostGraphileDelete,
buildPostGraphileUpdate,
buildSelect,
- createASTQueryBuilder,
toCamelCasePlural,
toCamelCaseSingular,
toPatchFieldName,
@@ -359,13 +358,6 @@ describe("query-generator", () => {
});
});
- describe("createASTQueryBuilder", () => {
- it("creates builder with tables", () => {
- expect(createASTQueryBuilder(allTables)).toBeDefined();
- expect(createASTQueryBuilder([testTable])).toBeDefined();
- });
- });
-
describe("edge cases", () => {
it("handles empty fields", () => {
const emptyTable = createCleanTable("empty");
diff --git a/packages/schema-builder/src/__tests__/schema-builder-layout-motion.test.tsx b/packages/schema-builder/src/__tests__/schema-builder-layout-motion.test.tsx
deleted file mode 100644
index cc86f0f..0000000
--- a/packages/schema-builder/src/__tests__/schema-builder-layout-motion.test.tsx
+++ /dev/null
@@ -1,392 +0,0 @@
-import { cleanup, fireEvent, render, screen, within } from '@testing-library/react';
-import { MotionConfig } from 'motion/react';
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-import type { ReactNode } from 'react';
-
-const schemaMocks = vi.hoisted(() => ({
- currentSchema: null as Record | null,
- currentTable: null as Record | null,
- draggedType: {
- configurable: {},
- defaultConstraints: { nullable: true },
- description: 'Plain text',
- label: 'Text',
- type: 'text'
- },
- panelExpanded: true,
- pushCard: vi.fn(),
- sections: { app: true, system: false },
- selectTable: vi.fn(),
- selectedTableId: 'app-table',
- togglePanel: vi.fn(),
- toggleSidebarSection: vi.fn()
-}));
-
-vi.mock('motion/react', async () => {
- const React = await vi.importActual('react');
- const ReducedMotionContext = React.createContext('never');
-
- type MotionDivProps = React.HTMLAttributes & {
- animate?: Record;
- exit?: Record;
- initial?: false | Record;
- transition?: Record;
- };
-
- const MotionDiv = React.forwardRef(
- ({ animate, exit, initial, style, transition, ...props }, ref) => {
- const reducedMotion = React.useContext(ReducedMotionContext);
-
- return React.createElement('div', {
- ...props,
- ref,
- style,
- 'data-motion-animate': JSON.stringify(animate),
- 'data-motion-exit': JSON.stringify(exit),
- 'data-motion-initial': JSON.stringify(initial),
- 'data-motion-reduced-motion': reducedMotion,
- 'data-motion-style': JSON.stringify(style),
- 'data-motion-transition': JSON.stringify(transition)
- });
- }
- );
-
- return {
- AnimatePresence: ({ children }: { children: ReactNode }) => children,
- MotionConfig: ({ children, reducedMotion = 'never' }: { children: ReactNode; reducedMotion?: string }) =>
- React.createElement(ReducedMotionContext.Provider, { value: reducedMotion }, children),
- motion: { div: MotionDiv }
- };
-});
-
-vi.mock('@constructive-io/ui/button', async () => {
- const React = await vi.importActual('react');
-
- return {
- Button: React.forwardRef<
- HTMLButtonElement,
- React.ButtonHTMLAttributes & { size?: string; variant?: string }
- >(({ children, size: _size, variant: _variant, ...props }, ref) => (
-
- ))
- };
-});
-
-vi.mock('@constructive-io/ui/tooltip', async () => {
- const React = await vi.importActual('react');
-
- return {
- Tooltip: ({ children }: { children: ReactNode }) => children,
- TooltipContent: ({ children }: { children: ReactNode }) => {children}
,
- TooltipProvider: ({ children }: { children: ReactNode }) => children,
- TooltipTrigger: ({ children }: { children: ReactNode }) =>
- React.isValidElement(children) ? children : <>{children}>
- };
-});
-
-vi.mock('@constructive-io/ui/dropdown-menu', async () => {
- const React = await vi.importActual('react');
-
- return {
- DropdownMenu: ({ children }: { children: ReactNode }) => children,
- DropdownMenuContent: ({ children }: { children: ReactNode }) => {children}
,
- DropdownMenuItem: ({ children, ...props }: React.ButtonHTMLAttributes) => (
-
- ),
- DropdownMenuTrigger: ({ children }: { children: ReactNode }) =>
- React.isValidElement(children) ? children : <>{children}>
- };
-});
-
-vi.mock('@constructive-io/ui/progressive-blur', () => ({
- ProgressiveBlur: ({ position }: { position: string }) =>
-}));
-
-vi.mock('@constructive-io/ui/stack', () => ({
- useCardStack: () => ({ push: schemaMocks.pushCard })
-}));
-
-vi.mock('@dnd-kit/core', () => ({
- DndContext: ({ children }: { children: ReactNode }) => {children}
,
- DragOverlay: ({ children }: { children: ReactNode }) => {children}
,
- useDraggable: ({ id }: { id: string }) => ({
- attributes: { 'aria-describedby': `${id}-instructions`, role: 'button', tabIndex: 0 },
- isDragging: false,
- listeners: {},
- setNodeRef: vi.fn(),
- transform: null
- })
-}));
-
-vi.mock('@/blocks/schema/schema-builder-core/lib/gql/hooks/schema-builder', () => ({
- useSchemaBuilderSelectors: () => ({
- currentSchema: schemaMocks.currentSchema,
- currentTable: schemaMocks.currentTable,
- selectTable: schemaMocks.selectTable,
- selectedTableId: schemaMocks.selectedTableId
- })
-}));
-
-vi.mock('@/blocks/schema/schema-builder-core/store/app-store', () => ({
- useSidebarSectionActions: () => ({ toggleSidebarSection: schemaMocks.toggleSidebarSection }),
- useSidebarSections: () => schemaMocks.sections,
- useToggleTypesLibraryExpanded: () => schemaMocks.togglePanel,
- useTypesLibraryExpanded: () => schemaMocks.panelExpanded
-}));
-
-vi.mock('../schema/schema-builder-fields/components/table-editor/use-field-dnd', () => ({
- DEFAULT_DROP_ANIMATION: {},
- useFieldDnD: () => ({
- activeId: 'field-type-text',
- customCollisionDetection: vi.fn(),
- dragSource: 'panel',
- draggedType: schemaMocks.draggedType,
- handleAddFieldRef: vi.fn(),
- handleDragCancel: vi.fn(),
- handleDragEnd: vi.fn(),
- handleDragStart: vi.fn(),
- sensors: []
- })
-}));
-
-vi.mock('../schema/schema-builder-fields/components/table-editor/fields-section', () => ({
- FieldsSection: () => Field editor dropzone
-}));
-
-vi.mock('@/blocks/schema/schema-builder-tables/components/table-editor/table-metadata-section', () => ({
- TableMetadataSection: () => Field metadata
-}));
-
-vi.mock('@/blocks/schema/schema-builder-tables/components/table-editor/no-table-selected-view', () => ({
- NoTableSelectedView: () => No table selected
-}));
-
-vi.mock('../schema/schema-builder-tables/components/tables', () => ({
- CreateTableCard: () => null,
- DeleteTableDialog: () => null
-}));
-
-import { TableEditor } from '../schema/schema-builder-fields/components/table-editor/table-editor';
-import { TypesLibrary } from '../schema/schema-builder-fields/components/table-editor/types-library';
-import {
- SchemaBuilderSidebar,
- getScrollAffordanceState
-} from '../schema/schema-builder-tables/components/schemas/schema-builder-sidebar';
-
-const APP_TABLE = {
- category: 'APP',
- fields: [],
- id: 'app-table',
- name: 'posts'
-};
-
-const SYSTEM_TABLE = {
- category: 'CORE',
- fields: [],
- id: 'system-table',
- name: 'internal_jobs'
-};
-
-const LAYOUT_PROPERTIES = ['bottom', 'height', 'left', 'margin', 'padding', 'paddingRight', 'right', 'top', 'width'];
-
-class ResizeObserverStub {
- observe() {}
- unobserve() {}
- disconnect() {}
-}
-
-function renderWithMotion(children: ReactNode) {
- return render({children});
-}
-
-function parseMotionValue(element: Element, attribute: string): unknown {
- const value = element.getAttribute(attribute);
- return value === null || value === undefined ? undefined : JSON.parse(value);
-}
-
-function activateButtonWithEnter(button: HTMLElement) {
- button.focus();
- fireEvent.keyDown(button, { code: 'Enter', key: 'Enter' });
- // jsdom does not synthesize the native button click generated by Enter.
- fireEvent.click(button, { detail: 0 });
- fireEvent.keyUp(button, { code: 'Enter', key: 'Enter' });
-}
-
-function expectTransformOnlyMotion(container: ParentNode) {
- const motionElements = [...container.querySelectorAll('[data-motion-animate]')];
- expect(motionElements.length).toBeGreaterThan(0);
-
- motionElements.forEach((element) => {
- ['data-motion-initial', 'data-motion-animate', 'data-motion-exit', 'data-motion-transition'].forEach(
- (attribute) => {
- const value = parseMotionValue(element, attribute);
- if (!value || typeof value !== 'object' || Array.isArray(value)) return;
- expect(Object.keys(value as Record)).not.toEqual(expect.arrayContaining(LAYOUT_PROPERTIES));
- }
- );
- expect(element.getAttribute('data-motion-reduced-motion')).toBe('user');
- });
-}
-
-beforeEach(() => {
- schemaMocks.currentTable = APP_TABLE;
- schemaMocks.currentSchema = {
- id: 'schema-1',
- name: 'public',
- relationships: [],
- tables: [APP_TABLE, SYSTEM_TABLE],
- version: '1'
- };
- schemaMocks.panelExpanded = true;
- schemaMocks.sections = { app: true, system: false };
- schemaMocks.selectedTableId = APP_TABLE.id;
- schemaMocks.pushCard.mockReset();
- schemaMocks.selectTable.mockReset();
- schemaMocks.togglePanel.mockReset();
- schemaMocks.toggleSidebarSection.mockReset();
-
- vi.stubGlobal('ResizeObserver', ResizeObserverStub);
- vi.stubGlobal('requestAnimationFrame', vi.fn(() => 1));
- vi.stubGlobal('cancelAnimationFrame', vi.fn());
-});
-
-afterEach(() => {
- cleanup();
- vi.restoreAllMocks();
- vi.unstubAllGlobals();
-});
-
-describe('schema builder layout-safe motion', () => {
- it('commits table editor panel geometry while preserving crossfades, toggles, and DnD content', () => {
- const view = renderWithMotion();
- const editor = view.container.querySelector("[data-chat-component='table-editor']")!;
- const [mainContent, panel] = [...editor.children] as HTMLElement[];
-
- expect(mainContent.style.paddingRight).toBe('380px');
- expect(mainContent.hasAttribute('data-motion-animate')).toBe(false);
- expect(panel.style.width).toBe('380px');
- expect(panel.dataset.state).toBe('expanded');
- expect(panel.hasAttribute('data-motion-animate')).toBe(false);
- expect(screen.getByText('Field metadata')).toBeTruthy();
- expect(screen.getByTestId('fields-section').textContent).toContain('Field editor dropzone');
- expect(within(screen.getByTestId('drag-overlay')).getByText('Text')).toBeTruthy();
-
- const crossfadeLayers = [...panel.querySelectorAll(':scope [data-motion-animate]')].slice(0, 2);
- expect(crossfadeLayers.map((layer) => parseMotionValue(layer, 'data-motion-animate'))).toEqual([
- { opacity: 0 },
- { opacity: 1 }
- ]);
- expect(crossfadeLayers.map((layer) => layer.style.pointerEvents)).toEqual(['none', 'auto']);
-
- fireEvent.click(screen.getByRole('button', { name: 'Collapse panel' }));
- expect(schemaMocks.togglePanel).toHaveBeenCalledTimes(1);
- schemaMocks.panelExpanded = false;
- view.rerender();
-
- const collapsedEditor = view.container.querySelector("[data-chat-component='table-editor']")!;
- const [collapsedMain, collapsedPanel] = [...collapsedEditor.children] as HTMLElement[];
- expect(collapsedMain.style.paddingRight).toBe('56px');
- expect(collapsedPanel.style.width).toBe('56px');
- expect(collapsedPanel.dataset.state).toBe('collapsed');
- expect(screen.getAllByRole('button', { name: 'Expand panel' })).toHaveLength(2);
- expectTransformOnlyMotion(view.container);
-
- schemaMocks.currentTable = null;
- view.rerender();
- const emptyEditor = view.container.querySelector("[data-chat-component='table-editor']")!;
- expect((emptyEditor.firstElementChild as HTMLElement).style.paddingRight).toBe('0px');
- expect(emptyEditor.querySelector('[data-state]')).toBeNull();
- expect(screen.getByText('No table selected')).toBeTruthy();
- });
-
- it('toggles type sections through the existing button semantics without layout animation', () => {
- const view = renderWithMotion();
- const basicTrigger = screen.getByRole('button', { name: /Basic/ });
- const advancedTrigger = screen.getByRole('button', { name: /Advanced/ });
-
- expect(basicTrigger.getAttribute('aria-expanded')).toBe('true');
- expect(advancedTrigger.getAttribute('aria-expanded')).toBe('false');
- expect(screen.getByText('Text', { selector: 'span' })).toBeTruthy();
- expect(view.container.querySelectorAll('[data-motion-animate][class*="overflow-hidden"]')).toHaveLength(1);
- expect(view.container.querySelector('.overflow-auto')).toBeTruthy();
-
- activateButtonWithEnter(advancedTrigger);
-
- expect(document.activeElement).toBe(advancedTrigger);
- expect(advancedTrigger.getAttribute('aria-expanded')).toBe('true');
- expect(view.container.querySelectorAll('[data-motion-animate][class*="overflow-hidden"]')).toHaveLength(2);
-
- fireEvent.click(basicTrigger);
- fireEvent.click(basicTrigger);
- expect(basicTrigger.getAttribute('aria-expanded')).toBe('true');
-
- const contentLayers = [...view.container.querySelectorAll('[data-motion-animate][class*="overflow-hidden"]')];
- contentLayers.forEach((layer) => {
- expect(parseMotionValue(layer, 'data-motion-initial')).toEqual({ opacity: 0, y: -4 });
- expect(parseMotionValue(layer, 'data-motion-animate')).toEqual({ opacity: 1, y: 0 });
- expect(parseMotionValue(layer, 'data-motion-exit')).toEqual({ opacity: 0, y: -4 });
- });
- expectTransformOnlyMotion(view.container);
- });
-
- it('preserves sidebar presence, selected indicators, rapid reversal, and scroll affordances', () => {
- const view = renderWithMotion();
- const appTrigger = screen.getByRole('button', { name: /Your Tables/ });
- const systemTrigger = screen.getByRole('button', { name: /System Tables/ });
-
- expect(appTrigger.getAttribute('aria-expanded')).toBe('true');
- expect(systemTrigger.getAttribute('aria-expanded')).toBe('false');
- expect(screen.getByTestId('collapsible-content-Your Tables')).toBeTruthy();
- expect(screen.queryByTestId('collapsible-content-System Tables')).toBeNull();
-
- activateButtonWithEnter(appTrigger);
- expect(schemaMocks.toggleSidebarSection).toHaveBeenCalledWith('app');
- expect(document.activeElement).toBe(appTrigger);
-
- schemaMocks.sections = { app: false, system: false };
- view.rerender();
- expect(screen.queryByTestId('collapsible-content-Your Tables')).toBeNull();
- expect(screen.getByLabelText('Contains selected item')).toBeTruthy();
-
- schemaMocks.sections = { app: true, system: false };
- view.rerender();
- schemaMocks.sections = { app: false, system: false };
- view.rerender();
- schemaMocks.sections = { app: true, system: true };
- view.rerender();
-
- expect(screen.getByTestId('collapsible-content-Your Tables')).toBeTruthy();
- expect(screen.getByTestId('collapsible-content-System Tables')).toBeTruthy();
- expect(screen.queryByLabelText('Contains selected item')).toBeNull();
-
- const viewport = screen
- .getByTestId('collapsible-content-Your Tables')
- .querySelector('.scrollbar-neutral-thin')!;
- Object.defineProperties(viewport, {
- clientHeight: { configurable: true, value: 100 },
- scrollHeight: { configurable: true, value: 400 },
- scrollTop: { configurable: true, value: 100, writable: true }
- });
- fireEvent.scroll(viewport);
- expect(screen.getByTestId('progressive-blur-top')).toBeTruthy();
- expect(screen.getByTestId('progressive-blur-bottom')).toBeTruthy();
-
- expect(getScrollAffordanceState({ clientHeight: 100, scrollHeight: 400, scrollTop: 300 })).toEqual({
- hasOverflow: true,
- showBottomBlur: false,
- showTopBlur: true
- });
-
- const contentLayers = [...view.container.querySelectorAll('[data-testid^="collapsible-content-"]')];
- contentLayers.forEach((layer) => {
- expect(parseMotionValue(layer, 'data-motion-initial')).toEqual({ opacity: 0, y: -4 });
- expect(parseMotionValue(layer, 'data-motion-animate')).toEqual({ opacity: 1, y: 0 });
- expect(parseMotionValue(layer, 'data-motion-exit')).toEqual({ opacity: 0, y: -4 });
- });
- expectTransformOnlyMotion(view.container);
- });
-});
diff --git a/packages/schema-builder/src/__tests__/schema-builder-render.test.tsx b/packages/schema-builder/src/__tests__/schema-builder-render.test.tsx
index 6379b05..6d9d615 100644
--- a/packages/schema-builder/src/__tests__/schema-builder-render.test.tsx
+++ b/packages/schema-builder/src/__tests__/schema-builder-render.test.tsx
@@ -1,135 +1,58 @@
-import { act, cleanup, render, screen } from '@testing-library/react';
+import { cleanup, render } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import type { ReactNode } from 'react';
import { createNoopSchemaBuilderAdapter } from '../testing';
-import { DEFAULT_SCHEMA_BUILDER_PREFERENCES, type SchemaBuilderProps } from '../types';
+import { DEFAULT_SCHEMA_BUILDER_PREFERENCES } from '../types';
vi.mock('@constructive-io/ui/stack', () => ({
CardStackProvider: ({ children }: { children: ReactNode }) => children,
- CardStackViewport: () => null
+ CardStackViewport: () => null,
}));
-
vi.mock('../schema/schema-builder/components/client-only', () => ({
- ClientOnly: ({ children }: { children: ReactNode }) => children
+ ClientOnly: ({ children }: { children: ReactNode }) => children,
}));
-
vi.mock('../schema/schema-builder-core/lib/gql/hooks/schema-builder', () => ({
- SchemaBuilderDataProvider: ({ children }: { children: ReactNode }) => children
+ SchemaBuilderDataProvider: ({ children }: { children: ReactNode }) => children,
+}));
+vi.mock('../schema/schema-builder/components/schemas/schemas-route', () => ({
+ SchemasRoute: () => null,
}));
-
-vi.mock('../schema/schema-builder/components/schemas/schemas-route', async () => {
- const { useReducedMotionConfig } = await vi.importActual('motion/react');
-
- return {
- SchemasRoute: ({ emptyState }: { emptyState?: ReactNode }) => {
- const shouldReduceMotion = useReducedMotionConfig();
-
- return (
-
- );
- }
- };
-});
import { SchemaBuilder } from '../components/schema-builder';
afterEach(cleanup);
-let prefersReducedMotion = false;
-const reducedMotionListeners = new Set();
-const reducedMotionQuery = {
- get matches() {
- return prefersReducedMotion;
- },
- media: '(prefers-reduced-motion)',
- onchange: null,
- addEventListener: (_type: string, listener: EventListenerOrEventListenerObject) => {
- reducedMotionListeners.add(listener);
- },
- removeEventListener: (_type: string, listener: EventListenerOrEventListenerObject) => {
- reducedMotionListeners.delete(listener);
- },
- addListener: vi.fn(),
- removeListener: vi.fn(),
- dispatchEvent: vi.fn(() => true)
-} as MediaQueryList;
-
-Object.defineProperty(window, 'matchMedia', {
- configurable: true,
- value: vi.fn(() => reducedMotionQuery)
-});
-
-function setReducedMotionPreference(matches: boolean) {
- prefersReducedMotion = matches;
- const event = { matches, media: reducedMotionQuery.media } as MediaQueryListEvent;
- reducedMotionListeners.forEach((listener) => {
- if (typeof listener === 'function') listener(event);
- else listener.handleEvent(event);
- });
-}
-
-function renderSchemaBuilder(overrides: Partial = {}) {
- return render(
- No database selected by this host
}
- {...overrides}
- />
- );
-}
-
describe('SchemaBuilder host boundary', () => {
- it('forwards the host empty state to the schemas route', () => {
- renderSchemaBuilder();
-
- expect(screen.getByTestId('schemas-route-boundary')).toBeTruthy();
- expect(screen.getByText('No database selected by this host')).toBeTruthy();
- });
-
- it('passes the user motion preference to package descendants', () => {
- setReducedMotionPreference(false);
- const firstRender = renderSchemaBuilder();
- expect(screen.getByTestId('schemas-route-boundary').getAttribute('data-reduced-motion')).toBe('false');
-
- firstRender.unmount();
- act(() => setReducedMotionPreference(true));
- renderSchemaBuilder();
-
- expect(screen.getByTestId('schemas-route-boundary').getAttribute('data-reduced-motion')).toBe('true');
- });
-
it('rejects host data from a different database scope', () => {
expect(() =>
- renderSchemaBuilder({
- dataState: {
- availableSchemas: [],
- routeOrgId: 'org-1',
- routeDatabaseId: 'db-other',
- selectedSchemaKey: '',
- currentSchemaInfo: null,
- currentSchema: null,
- currentTable: null,
- selectedTableId: null,
- hasResolvedDatabaseLookup: true,
- isLoading: false,
- isFetching: false,
- error: null,
- refetch: vi.fn(async () => undefined),
- selectTable: vi.fn()
- }
- })
+ render(
+ undefined),
+ selectTable: vi.fn(),
+ }}
+ />,
+ ),
).toThrow(/dataState must match/);
});
});
diff --git a/packages/schema-builder/src/__tests__/schema-builder-selectors.test.tsx b/packages/schema-builder/src/__tests__/schema-builder-selectors.test.tsx
index fc37ed0..2858563 100644
--- a/packages/schema-builder/src/__tests__/schema-builder-selectors.test.tsx
+++ b/packages/schema-builder/src/__tests__/schema-builder-selectors.test.tsx
@@ -1,4 +1,4 @@
-import { memo, type ReactNode } from 'react';
+import type { ReactNode } from 'react';
import { act, cleanup, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
@@ -71,7 +71,6 @@ const onPreferencesChange = vi.fn();
const onActiveTabChange = vi.fn();
let latestSelectors: UseSchemaBuilderSelectorsResult | null = null;
-let dataConsumerRenderCount = 0;
function SelectorProbe() {
const selectors = useSchemaBuilderSelectors();
@@ -85,41 +84,30 @@ function SelectorProbe() {
);
}
-const StableDataConsumer = memo(function StableDataConsumer() {
- dataConsumerRenderCount += 1;
- const availableSchemas = useSchemaBuilderDataSelector((state) => state.availableSchemas);
- return ;
-});
-
function TestTree({
- unrelatedValue,
onSelectedTableChange,
children
}: {
- unrelatedValue: number;
onSelectedTableChange: (selection: { tableId: string | null; tableName: string | null }) => void;
children?: ReactNode;
}) {
return (
-
-
-
-
-
- {children}
-
-
-
+
+
+
+ {children}
+
+
);
}
@@ -130,7 +118,6 @@ function currentSelectors() {
beforeEach(() => {
latestSelectors = null;
- dataConsumerRenderCount = 0;
dataMocks.accessibleDatabaseCalls = 0;
dataMocks.refetchDatabases.mockClear();
onPreferencesChange.mockClear();
@@ -174,49 +161,9 @@ describe('schema builder selector identities', () => {
expect(dataMocks.accessibleDatabaseCalls).toBe(0);
});
- it('keeps actions stable across unrelated rerenders and changes only real dependents', () => {
- const firstSelectionHandler = vi.fn();
- const view = render(
-
- );
- const first = currentSelectors();
-
- view.rerender(
-
- );
- const afterUnrelatedRender = currentSelectors();
-
- expect(afterUnrelatedRender.selectOrg).toBe(first.selectOrg);
- expect(afterUnrelatedRender.selectSchema).toBe(first.selectSchema);
- expect(afterUnrelatedRender.selectTable).toBe(first.selectTable);
- expect(afterUnrelatedRender.selectField).toBe(first.selectField);
- expect(afterUnrelatedRender.clearAllSelections).toBe(first.clearAllSelections);
- expect(afterUnrelatedRender.setActiveTab).toBe(first.setActiveTab);
- expect(afterUnrelatedRender.setCurrentDatabaseApi).toBe(first.setCurrentDatabaseApi);
- expect(afterUnrelatedRender.isCustomSchema).toBe(first.isCustomSchema);
- expect(afterUnrelatedRender.getSchemaByKey).toBe(first.getSchemaByKey);
- expect(afterUnrelatedRender.customSchemas).toBe(first.customSchemas);
- expect(dataConsumerRenderCount).toBe(1);
-
- const nextSelectionHandler = vi.fn();
- view.rerender(
-
- );
- const afterDependencyChange = currentSelectors();
-
- expect(afterDependencyChange.selectTable).not.toBe(first.selectTable);
- expect(afterDependencyChange.clearAllSelections).not.toBe(first.clearAllSelections);
- expect(afterDependencyChange.selectField).toBe(first.selectField);
- expect(afterDependencyChange.setCurrentDatabaseApi).toBe(first.setCurrentDatabaseApi);
- expect(afterDependencyChange.selectOrg).toBe(first.selectOrg);
- expect(afterDependencyChange.selectSchema).toBe(first.selectSchema);
- expect(afterDependencyChange.setActiveTab).toBe(first.setActiveTab);
- expect(dataConsumerRenderCount).toBe(1);
- });
-
it('preserves field clearing for table selection and clearing all selections', () => {
const onSelectedTableChange = vi.fn();
- render();
+ render();
act(() => currentSelectors().selectField('field-1'));
expect(screen.getByTestId('selected-field').textContent).toBe('field-1');
@@ -237,6 +184,5 @@ describe('schema builder selector identities', () => {
tableId: null,
tableName: null
});
- expect(dataConsumerRenderCount).toBe(1);
});
});
diff --git a/packages/schema-builder/src/schema/schema-builder-policies/components/tables/create-table-card.test.tsx b/packages/schema-builder/src/schema/schema-builder-policies/components/tables/create-table-card.test.tsx
deleted file mode 100644
index cfb79c3..0000000
--- a/packages/schema-builder/src/schema/schema-builder-policies/components/tables/create-table-card.test.tsx
+++ /dev/null
@@ -1,257 +0,0 @@
-import { StrictMode, type ComponentProps, type PropsWithChildren } from 'react';
-import { cleanup, fireEvent, render, screen } from '@testing-library/react';
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-
-const scrollHarness = vi.hoisted(() => ({
- key: 'first',
- withViewport: true,
- initialScrollTop: 0,
- add: vi.fn(),
- remove: vi.fn(),
-}));
-
-const dependencyMocks = vi.hoisted(() => ({
- close: vi.fn(),
- push: vi.fn(() => 'child-card'),
- stack: {
- has: vi.fn(() => false),
- dismiss: vi.fn(),
- updateProps: vi.fn(),
- },
- mutateAsync: vi.fn(),
- createTableWithPolicies: vi.fn(),
- updateDefaults: vi.fn(),
- getEnabledOperations: vi.fn(() => []),
-}));
-
-vi.mock('@constructive-io/ui/scroll-area', async () => {
- const React = await import('react');
- const patchedViewports = new WeakSet();
-
- const ScrollArea = React.forwardRef>(
- ({ children }, forwardedRef) => {
- const nodeKey = scrollHarness.key;
- const withViewport = scrollHarness.withViewport;
- const attach = React.useCallback(
- (node: HTMLDivElement | null) => {
- if (!node) return;
- const viewport = node.querySelector('[data-slot="scroll-area-viewport"]');
- if (viewport) {
- viewport.scrollTop = scrollHarness.initialScrollTop;
- if (!patchedViewports.has(viewport)) {
- patchedViewports.add(viewport);
- const addEventListener = viewport.addEventListener.bind(viewport);
- const removeEventListener = viewport.removeEventListener.bind(viewport);
- viewport.addEventListener = ((
- type: string,
- listener: EventListenerOrEventListenerObject,
- options?: boolean | AddEventListenerOptions,
- ) => {
- if (type === 'scroll') scrollHarness.add(viewport, type, listener, options);
- addEventListener(type, listener, options);
- }) as typeof viewport.addEventListener;
- viewport.removeEventListener = ((
- type: string,
- listener: EventListenerOrEventListenerObject,
- options?: boolean | EventListenerOptions,
- ) => {
- if (type === 'scroll') scrollHarness.remove(viewport, type, listener, options);
- removeEventListener(type, listener, options);
- }) as typeof viewport.removeEventListener;
- }
- }
-
- if (typeof forwardedRef === 'function') return forwardedRef(node);
- if (forwardedRef) forwardedRef.current = node;
- return () => {
- if (forwardedRef) forwardedRef.current = null;
- };
- },
- [forwardedRef, nodeKey, withViewport],
- );
-
- return (
-
- {withViewport ?
{children}
: children}
-
- );
- },
- );
-
- return { ScrollArea };
-});
-
-vi.mock('@constructive-io/ui/stack', () => ({
- useCardStack: () => dependencyMocks.stack,
-}));
-
-vi.mock('@constructive-io/ui/toast', () => ({
- showErrorToast: vi.fn(),
- showSuccessToast: vi.fn(),
-}));
-
-vi.mock('@/blocks/schema/schema-builder-core/lib/gql/hooks/schema-builder', () => ({
- useSchemaBuilderSelectors: () => ({
- currentDatabase: { databaseId: 'database-1', schemaId: 'schema-1' },
- currentSchema: { tables: [] },
- }),
-}));
-
-vi.mock('../../lib/gql/hooks/schema-builder/use-create-table', () => ({
- useCreateTable: () => ({ mutateAsync: dependencyMocks.mutateAsync, isPending: false }),
-}));
-
-vi.mock('../policies/policy-hooks', () => ({
- getDefaultFormValues: vi.fn(() => ({})),
- useCreateTableWithPolicies: () => ({
- createTableWithPolicies: dependencyMocks.createTableWithPolicies,
- isCreating: false,
- }),
- usePolicyTypes: () => ({ policyTypes: [], error: null }),
-}));
-
-vi.mock('../policies/use-crud-policy-state', () => ({
- useCrudPolicyState: () => ({
- defaults: { policyData: {} },
- operations: {},
- updateDefaults: dependencyMocks.updateDefaults,
- getEnabledOperations: dependencyMocks.getEnabledOperations,
- }),
-}));
-
-vi.mock('../policies/composite-policy-builder', () => ({
- createEmptyCompositePolicyData: vi.fn(() => ({})),
-}));
-
-vi.mock('../policies/policy-config-card', () => ({ PolicyConfigContent: () => null }));
-vi.mock('../policies/policy-diagram', () => ({ PolicyDiagramByKey: () => null }));
-vi.mock('../policies/policy-know-more-card', () => ({ PolicyKnowMoreCard: () => null }));
-
-import { CreateTableCard } from './create-table-card';
-
-const card = {
- id: 'create-table-card',
- push: dependencyMocks.push,
- close: dependencyMocks.close,
- setTitle: vi.fn(),
- setDescription: vi.fn(),
- setWidth: vi.fn(),
- setDismissable: vi.fn(),
- updateProps: vi.fn(),
-} as ComponentProps['card'];
-
-function cardElement(props: Partial> = {}) {
- return ;
-}
-
-function viewport(container: ParentNode = document) {
- const node = container.querySelector('[data-slot="scroll-area-viewport"]');
- if (!node) throw new Error('Missing scroll viewport');
- return node;
-}
-
-function stickyHeader() {
- const node = screen.getByTestId('table-name-input').closest('.bg-card');
- if (!node) throw new Error('Missing sticky table-name header');
- return node;
-}
-
-function expectListenerPair(addIndex: number, removeIndex: number) {
- const addCall = scrollHarness.add.mock.calls[addIndex];
- const removeCall = scrollHarness.remove.mock.calls[removeIndex];
- expect(removeCall[0]).toBe(addCall[0]);
- expect(removeCall[1]).toBe('scroll');
- expect(removeCall[2]).toBe(addCall[2]);
-}
-
-beforeEach(() => {
- scrollHarness.key = 'first';
- scrollHarness.withViewport = true;
- scrollHarness.initialScrollTop = 0;
- scrollHarness.add.mockClear();
- scrollHarness.remove.mockClear();
- vi.clearAllMocks();
-});
-
-afterEach(cleanup);
-
-describe('CreateTableCard scroll listener ownership', () => {
- it('samples the attached viewport and keeps the sticky shadow in sync with scroll', () => {
- scrollHarness.initialScrollTop = 8;
- const view = render(cardElement());
- const liveViewport = viewport(view.container);
-
- expect(scrollHarness.add).toHaveBeenCalledTimes(1);
- expect(scrollHarness.add.mock.calls[0].slice(1)).toEqual([
- 'scroll',
- expect.any(Function),
- { passive: true },
- ]);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(true);
-
- liveViewport.scrollTop = 0;
- fireEvent.scroll(liveViewport);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(false);
-
- liveViewport.scrollTop = 24;
- fireEvent.scroll(liveViewport);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(true);
-
- view.unmount();
- expect(scrollHarness.remove).toHaveBeenCalledTimes(1);
- expectListenerPair(0, 0);
- });
-
- it('releases a replaced viewport before attaching the next node', () => {
- const view = render(cardElement({ tableName: 'first_table' }));
- const firstViewport = viewport(view.container);
-
- scrollHarness.key = 'second';
- scrollHarness.initialScrollTop = 5;
- view.rerender(cardElement({ tableName: 'second_table' }));
- const secondViewport = viewport(view.container);
-
- expect(secondViewport).not.toBe(firstViewport);
- expect(scrollHarness.add).toHaveBeenCalledTimes(2);
- expect(scrollHarness.remove).toHaveBeenCalledTimes(1);
- expectListenerPair(0, 0);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(true);
-
- secondViewport.scrollTop = 0;
- fireEvent.scroll(secondViewport);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(false);
-
- firstViewport.scrollTop = 10;
- fireEvent.scroll(firstViewport);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(false);
-
- secondViewport.scrollTop = 10;
- fireEvent.scroll(secondViewport);
- expect(stickyHeader().classList.contains('shadow-md')).toBe(true);
-
- view.unmount();
- expect(scrollHarness.remove).toHaveBeenCalledTimes(2);
- expectListenerPair(1, 1);
- });
-
- it('pairs every Strict Mode callback-ref setup with cleanup', () => {
- const view = render({cardElement()});
-
- expect(scrollHarness.add).toHaveBeenCalledTimes(2);
- expect(scrollHarness.remove).toHaveBeenCalledTimes(1);
- expectListenerPair(0, 0);
-
- view.unmount();
- expect(scrollHarness.remove).toHaveBeenCalledTimes(2);
- expectListenerPair(1, 1);
- });
-
- it('does not allocate a listener when the attached node has no viewport', () => {
- scrollHarness.withViewport = false;
- const view = render(cardElement());
-
- expect(scrollHarness.add).not.toHaveBeenCalled();
- view.unmount();
- expect(scrollHarness.remove).not.toHaveBeenCalled();
- });
-});
diff --git a/packages/sheets/src/cell-model/__tests__/create-sheets-cell.test.ts b/packages/sheets/src/cell-model/__tests__/create-sheets-cell.test.ts
new file mode 100644
index 0000000..9f5f8fd
--- /dev/null
+++ b/packages/sheets/src/cell-model/__tests__/create-sheets-cell.test.ts
@@ -0,0 +1,46 @@
+import { describe, expect, it } from 'vitest';
+
+import type { CellCreationMetadata } from '../../grid/grid-cell-types';
+import { createSheetsCell } from '../create-sheets-cell';
+
+function metadata(cellType: string, overrides: Partial = {}): CellCreationMetadata {
+ return {
+ cellType,
+ fieldName: 'value',
+ canEdit: true,
+ isReadonly: false,
+ activationBehavior: 'double-click',
+ ...overrides,
+ };
+}
+
+describe('createSheetsCell', () => {
+ it('normalizes an email into navigable data without changing its display value', () => {
+ expect(createSheetsCell('ada@example.com', metadata('email'))).toMatchObject({
+ kind: 'uri',
+ data: 'mailto:ada@example.com',
+ displayData: 'ada@example.com',
+ });
+ });
+
+ it('derives relation labels, truncates them, and reports list overflow', () => {
+ const cell = createSheetsCell(
+ [{ displayName: 'Alexandria' }, { displayName: 'Bob' }, { displayName: 'Chen' }],
+ metadata('relation', {
+ relationInfo: { kind: 'hasMany', displayCandidates: ['displayName'] },
+ relationOptions: { relationChipLimit: 2, relationLabelMaxLength: 6 },
+ }),
+ );
+
+ expect(cell).toMatchObject({ kind: 'relation', data: ['Alexa…', 'Bob', '+1'], displayData: '' });
+ });
+
+ it('does not expose a draft placeholder as a relation label', () => {
+ expect(
+ createSheetsCell(
+ { id: 'draft:pending', displayName: 'Unsaved record' },
+ metadata('relation', { relationInfo: { kind: 'belongsTo', displayCandidates: ['displayName'] } }),
+ ),
+ ).toMatchObject({ kind: 'relation', data: '', displayData: '' });
+ });
+});
diff --git a/packages/sheets/src/cell-model/__tests__/kind-parity.test-d.ts b/packages/sheets/src/cell-model/__tests__/kind-parity.test-d.ts
deleted file mode 100644
index d523c5c..0000000
--- a/packages/sheets/src/cell-model/__tests__/kind-parity.test-d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// TYPE-LEVEL guard: SheetsCellKind must equal the frozen DisplayKind
-// member-for-member. Test file → may import the harness (vitest is fine here).
-// The real check is these two assignments COMPILING; there is no runtime body.
-
-import type { DisplayKind } from '../../grid/__golden__/parity.harness';
-import type { SheetsCellKind } from '../sheets-cell';
-
-// Mutual assignability ⇒ the two unions are identical sets of string literals.
-const _kindIntoDisplay: DisplayKind = '' as SheetsCellKind;
-const _displayIntoKind: SheetsCellKind = '' as DisplayKind;
-
-// Silence unused-locals without a runtime export.
-export type _KindParity = [typeof _kindIntoDisplay, typeof _displayIntoKind];
diff --git a/packages/sheets/src/cell-model/create-sheets-cell.ts b/packages/sheets/src/cell-model/create-sheets-cell.ts
index c1b3843..6842ce2 100644
--- a/packages/sheets/src/cell-model/create-sheets-cell.ts
+++ b/packages/sheets/src/cell-model/create-sheets-cell.ts
@@ -56,8 +56,8 @@ const SHEETS_CELL_FACTORIES: SheetsCellFactory[] = [
* its type (the host reads `SheetsCellResolution.typeKey`, but the cell carrying
* `meta.cellType` keeps it self-contained for the editor adapters that already
* read it — date/geometry). MERGE (not replace) so any factory-set meta key
- * (e.g. geometry's `geometryType`) survives. Parity-safe: `projectSheetsCell`
- * ignores `meta` entirely, so display/copy text is unchanged.
+ * (e.g. geometry's `geometryType`) survives. This does not change display or
+ * copy text because projection ignores `meta`.
*/
function withTypeKey(cell: SheetsCell, cellType: string): SheetsCell {
return { ...cell, meta: { ...cell.meta, cellType: cellType as CellType } };
diff --git a/packages/sheets/src/cell-model/factories/boolean.ts b/packages/sheets/src/cell-model/factories/boolean.ts
index 8ea89e9..efee7d9 100644
--- a/packages/sheets/src/cell-model/factories/boolean.ts
+++ b/packages/sheets/src/cell-model/factories/boolean.ts
@@ -1,14 +1,8 @@
// Boolean SheetsCell factory — native analogue of v1's BooleanCellFactory
// (grid/cell-content-factory.ts). Claims BOOLEAN_TYPES (boolean, bit, toggle).
//
-// Parity contract (projectSheetsCell ≡ projectGlideCell):
-// The glide BooleanCell carries `data: boolValue` and NO `displayData`, so
-// projectGlideCell yields { displayText: '', copyText: String(boolValue) }.
-// We mirror that: `data` holds EXACTLY the boolean glide put in `.data`, and
-// `displayData` is '' (glide Boolean had none). Since kind 'boolean' is not
-// geometry/custom, projectSheetsCell reads displayData -> '' and data ->
-// String(boolValue), matching glide branch-for-branch. The glide BooleanCell
-// sets no `readonly`, so readonly = false.
+// The BooleanCell keeps the boolean in `data` for copying and leaves
+// `displayData` empty because the view owns its visual representation.
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
import { BOOLEAN_TYPES } from '../../cell-types/cell-type-groups';
diff --git a/packages/sheets/src/cell-model/factories/datetime.ts b/packages/sheets/src/cell-model/factories/datetime.ts
index 5ceba50..60a2507 100644
--- a/packages/sheets/src/cell-model/factories/datetime.ts
+++ b/packages/sheets/src/cell-model/factories/datetime.ts
@@ -3,7 +3,7 @@
// (date, datetime, time, timestamptz) and emits a neutral `text` cell carrying
// the value's string form. v1 renders the raw value as formatted text: non-null
// -> data/displayData = String(value); null/undefined -> both ''. This factory
-// mirrors that exactly so projectSheetsCell deep-equals projectGlideCell.
+// preserves that display and copy behavior.
import type { CellType } from '../../cell-types/types';
import { DATE_TIME_TYPES } from '../../cell-types/cell-type-groups';
diff --git a/packages/sheets/src/cell-model/factories/geometry.ts b/packages/sheets/src/cell-model/factories/geometry.ts
index fbf8209..c275a21 100644
--- a/packages/sheets/src/cell-model/factories/geometry.ts
+++ b/packages/sheets/src/cell-model/factories/geometry.ts
@@ -7,9 +7,8 @@
// it falls back to a compact JSON preview as both the copy value and the display
// string — identical to v1's Text fallback.
//
-// Parity: `projectSheetsCell` special-cases kind `geometry` so copyText ===
-// displayText === displayData. The fallback therefore sets `data` and
-// `displayData` to the SAME `compactJsonPreview(value, 80)` string v1 emits.
+// Copy and display text intentionally use the same compact JSON preview when no
+// geometry-specific builder is available.
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
import { GEOMETRY_TYPES } from '../../cell-types/cell-type-groups';
diff --git a/packages/sheets/src/cell-model/factories/number.ts b/packages/sheets/src/cell-model/factories/number.ts
index fb6b936..2962a03 100644
--- a/packages/sheets/src/cell-model/factories/number.ts
+++ b/packages/sheets/src/cell-model/factories/number.ts
@@ -4,13 +4,8 @@
// the number family wins it before the text fallback; this is a deliberate v1
// quirk preserved for parity).
//
-// Parity contract (projectSheetsCell ≡ projectGlideCell):
-// - null/undefined OR NaN coercion -> data: undefined, displayData: ''
-// (projects copyText '' + displayText '')
-// - otherwise -> data: numValue (number), displayData: String(numValue)
-// Mirrors the glide NumberCell branch-for-branch; `data` holds EXACTLY what the
-// glide factory put in `.data`, and `displayData` is the string form of glide's
-// `.displayData`. The glide NumberCell sets no `readonly`, so readonly = false.
+// Null, undefined, and invalid values become an empty cell. Valid values keep
+// the numeric data and a string display value.
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
import { NUMBER_TYPES } from '../../cell-types/cell-type-groups';
diff --git a/packages/sheets/src/cell-model/factories/relation.ts b/packages/sheets/src/cell-model/factories/relation.ts
index 31627f8..a9467b4 100644
--- a/packages/sheets/src/cell-model/factories/relation.ts
+++ b/packages/sheets/src/cell-model/factories/relation.ts
@@ -6,10 +6,8 @@
// copied verbatim from v1 (no import from cell-content-factory.ts — that module
// stays glide-only and is deleted at cutover).
//
-// PARITY: projectSheetsCell(create(...)) deep-equals projectGlideCell(v1 create).
-// single — glide Text: data = label, displayData = label.
-// list — glide Bubble: data = finalData (chips + "+N"), displayData = '' (Bubble
-// carries no displayData, so it projects to '' on the display side).
+// Single relations use their label for data and display. List relations keep
+// their final chips in data while the relation view owns their visual display.
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
import { compactJsonPreview } from '../../grid/sheets.formatters';
diff --git a/packages/sheets/src/cell-model/factories/text.ts b/packages/sheets/src/cell-model/factories/text.ts
index 74f5309..f5b00b1 100644
--- a/packages/sheets/src/cell-model/factories/text.ts
+++ b/packages/sheets/src/cell-model/factories/text.ts
@@ -6,9 +6,8 @@
//
// v1 emits a Text glide cell: null/undefined -> data/displayData ''; string ->
// data/displayData = value; anything else -> compactJsonPreview(value, 80) for
-// both. This factory mirrors that exactly so projectSheetsCell deep-equals
-// projectGlideCell. `compactJsonPreview` is shared (sheets.formatters), so it is
-// imported rather than copied.
+// both. `compactJsonPreview` is shared (sheets.formatters), so it is imported
+// rather than copied.
import type { CellType } from '../../cell-types/types';
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
diff --git a/packages/sheets/src/cell-model/factories/uri.ts b/packages/sheets/src/cell-model/factories/uri.ts
index d4932f3..4ed2047 100644
--- a/packages/sheets/src/cell-model/factories/uri.ts
+++ b/packages/sheets/src/cell-model/factories/uri.ts
@@ -3,9 +3,8 @@
// render payload. All domain logic (email -> mailto, url passthrough, empty
// guard) is reproduced here verbatim so this file is glide-free at cutover.
//
-// PARITY: projectSheetsCell(create(...)) deep-equals projectGlideCell of v1's
-// UriCell — `data`/`displayData` are the SAME strings v1 emits. v1 drops only
-// the `onClickUri` side-effect (the DOM view owns clicks).
+// `data` holds the navigable URI while `displayData` keeps the user-facing
+// string; the DOM view owns click behavior.
import type { CellType } from '../../cell-types/types';
import type { CellCreationMetadata } from '../../grid/grid-cell-types';
diff --git a/packages/sheets/src/cell-model/sheets-cell.ts b/packages/sheets/src/cell-model/sheets-cell.ts
index 53a0a2c..e1610b5 100644
--- a/packages/sheets/src/cell-model/sheets-cell.ts
+++ b/packages/sheets/src/cell-model/sheets-cell.ts
@@ -1,16 +1,13 @@
// Native cell model — the DOM render payload that replaces glide `GridCell`.
//
// Pure types: no @tanstack/* or virtual import. `SheetsCellKind` is the neutral
-// 11-member render vocabulary, frozen by the Phase-0 parity harness
-// (`grid/__golden__/parity.harness.ts` DisplayKind). The type-level guard in
-// `__tests__/kind-parity.test-d.ts` asserts member-for-member equality without
-// importing the harness into production code (it pulls vitest).
+// render vocabulary consumed by the DOM cell host.
import type { CellType } from '../cell-types/types';
/**
- * Neutral RENDER kinds — equal to the frozen `DisplayKind` union. `loading` and
- * `draft-action` originate from grid-internal state, not the `CellType` system.
+ * Neutral render kinds. `loading` and `draft-action` originate from grid-internal
+ * state, not the `CellType` system.
*/
export type SheetsCellKind =
| 'text'
diff --git a/packages/sheets/src/cell-model/views/__tests__/draft-action-view.test.tsx b/packages/sheets/src/cell-model/views/__tests__/draft-action-view.test.tsx
index 2fe2b92..55c4eee 100644
--- a/packages/sheets/src/cell-model/views/__tests__/draft-action-view.test.tsx
+++ b/packages/sheets/src/cell-model/views/__tests__/draft-action-view.test.tsx
@@ -38,26 +38,6 @@ describe('DraftActionCellView (native DOM)', () => {
});
}
- it('idle renders an enabled "Save" button', async () => {
- await mount({ status: 'idle' });
-
- const btn = getButton(container);
- expect(btn.disabled).toBe(false);
- expect(btn.textContent).toContain('Save');
- expect(btn.textContent).not.toContain('Saving');
- // no spinner, no error indicator in the idle branch
- expect(container.querySelector('.animate-spin')).toBeNull();
- expect(container.querySelector('[data-slot="draft-action-error"]')).toBeNull();
- });
-
- it('defaults to idle when no status prop is given', async () => {
- await mount({});
-
- const btn = getButton(container);
- expect(btn.disabled).toBe(false);
- expect(btn.textContent).toContain('Save');
- });
-
it('click fires onSubmit exactly once', async () => {
const onSubmit = vi.fn();
await mount({ status: 'idle', onSubmit });
@@ -70,17 +50,6 @@ describe('DraftActionCellView (native DOM)', () => {
expect(onSubmit).toHaveBeenCalledTimes(1);
});
- it('does not throw when clicked without an onSubmit handler', async () => {
- await mount({ status: 'idle' });
-
- const btn = getButton(container);
- await act(async () => {
- btn.dispatchEvent(new MouseEvent('click', { bubbles: true }));
- });
-
- expect(btn.disabled).toBe(false);
- });
-
it('saving shows the spinner + "Saving..." and disables the button', async () => {
const onSubmit = vi.fn();
await mount({ status: 'saving', onSubmit });
diff --git a/packages/sheets/src/cell-model/views/__tests__/geometry-view.test.tsx b/packages/sheets/src/cell-model/views/__tests__/geometry-view.test.tsx
deleted file mode 100644
index 54e164d..0000000
--- a/packages/sheets/src/cell-model/views/__tests__/geometry-view.test.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-/* @vitest-environment jsdom */
-//
-// Unit test for the enriched GeometryCellView. Asserts the view paints a geo ICON
-// (tinted by geometry category) plus an ABBREVIATED type label — the DOM analogue
-// of the canvas painter (grid/custom-cells/geometry-cell.tsx), NOT a plain
-// monospace preview. Same component-test idiom as the editor tests: jsdom +
-// react-dom/client createRoot + act (no @testing-library — not a dep here).
-
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-
-import { GeometryCellView } from '../geometry-view';
-import type { CellProps } from '../../cell-props';
-import type { SheetsCell } from '../../sheets-cell';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-// Build CellProps around a hand-fed geometry SheetsCell. `data`/`displayData`
-// mirror the factory's compact-JSON fallback unless overridden.
-function makeProps(cell: Partial): CellProps {
- const merged: SheetsCell = {
- kind: 'geometry',
- data: '',
- displayData: '',
- readonly: false,
- ...cell,
- };
- return {
- cell: merged,
- value: merged.data,
- colKey: 'location',
- rowId: 'row-1',
- rowIndex: 0,
- column: { key: 'location', name: 'Location', cellType: 'geometry' },
- isEditing: false,
- onStartEdit: () => {},
- disabled: false,
- };
-}
-
-describe('GeometryCellView (enriched DOM view)', () => {
- let root: Root;
- let container: HTMLDivElement;
-
- beforeEach(() => {
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- });
-
- function render(props: CellProps) {
- act(() => {
- root.render();
- });
- }
-
- it('renders a point icon + "Point" label for a Point value (sniffed from preview)', () => {
- const json = JSON.stringify({ type: 'Point', coordinates: [1, 2] });
- render(makeProps({ data: json, displayData: json }));
-
- const cell = container.querySelector('[data-slot="geometry-cell"]');
- expect(cell).not.toBeNull();
- expect(cell?.getAttribute('data-geometry-category')).toBe('point');
-
- // An ICON is painted (inline SVG), not a monospace span.
- const icon = cell?.querySelector('svg[data-geometry-icon="point"]');
- expect(icon).not.toBeNull();
- // Tinted by the point category colour (mirrors canvas ICON_COLORS blue).
- expect(icon?.getAttribute('stroke')).toBe('#3b82f6');
-
- // Abbreviated type label, NOT the raw JSON.
- expect(cell?.textContent).toBe('Point');
- expect(cell?.textContent).not.toContain('coordinates');
- });
-
- it('renders a map icon + abbreviated "Poly" label for a Polygon value', () => {
- const json = JSON.stringify({ type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 0]]] });
- render(makeProps({ data: json, displayData: json }));
-
- const cell = container.querySelector('[data-slot="geometry-cell"]');
- expect(cell?.getAttribute('data-geometry-category')).toBe('polygon');
-
- const icon = cell?.querySelector('svg[data-geometry-icon="polygon"]');
- expect(icon).not.toBeNull();
- expect(icon?.getAttribute('stroke')).toBe('#10b981');
-
- expect(cell?.textContent).toBe('Poly');
- });
-
- it('prefers an explicit geometryType hint from cell.meta (deriveGeometry path)', () => {
- render(makeProps({ data: 'POINT(1 2)', displayData: 'POINT(1 2)', meta: { geometryType: 'LineString' } }));
-
- const cell = container.querySelector('[data-slot="geometry-cell"]');
- expect(cell?.getAttribute('data-geometry-category')).toBe('line');
- expect(cell?.querySelector('svg[data-geometry-icon="line"]')).not.toBeNull();
- expect(cell?.textContent).toBe('Line');
- });
-
- it('renders an invalid (warning) icon + "Invalid" label for an unparseable value', () => {
- render(makeProps({ data: 'not-geojson', displayData: 'not-geojson' }));
-
- const cell = container.querySelector('[data-slot="geometry-cell"]');
- expect(cell?.getAttribute('data-geometry-category')).toBe('invalid');
- const icon = cell?.querySelector('svg[data-geometry-icon="invalid"]');
- expect(icon).not.toBeNull();
- expect(icon?.getAttribute('stroke')).toBe('#ef4444');
- expect(cell?.textContent).toBe('Invalid');
- });
-
- it('paints nothing (no icon, no label) for an empty cell', () => {
- render(makeProps({ data: '', displayData: '' }));
-
- const cell = container.querySelector('[data-slot="geometry-cell"]');
- expect(cell).not.toBeNull();
- expect(cell?.querySelector('svg')).toBeNull();
- expect(cell?.textContent).toBe('');
- });
-});
diff --git a/packages/sheets/src/cell-model/views/__tests__/image-view.test.tsx b/packages/sheets/src/cell-model/views/__tests__/image-view.test.tsx
deleted file mode 100644
index 57f25cf..0000000
--- a/packages/sheets/src/cell-model/views/__tests__/image-view.test.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-/* @vitest-environment jsdom */
-
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-
-import type { CellProps } from '../../cell-props';
-import type { SheetsCell } from '../../sheets-cell';
-import { ImageCellView } from '../image-view';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-// The image factory puts the resolved url in a single-element array (`[url]`),
-// collapsing empty/null/'' to `['']`. The view reads data[0].
-function makeProps(url: string): CellProps {
- const cell: SheetsCell = {
- kind: 'image',
- data: [url],
- displayData: JSON.stringify([url]),
- readonly: false,
- };
- return {
- cell,
- value: url,
- colKey: 'avatar',
- rowId: 'row-1',
- rowIndex: 0,
- column: { key: 'avatar', name: 'Avatar', cellType: 'image' },
- isEditing: false,
- onStartEdit: () => {},
- disabled: false,
- };
-}
-
-// A media value with rich metadata ({ url, mime, filename }) on a given column type —
-// used to exercise the type-aware file-chip vs thumbnail branch.
-function makeFileProps(value: unknown, cellType: string): CellProps {
- const url =
- typeof value === 'string'
- ? value
- : value && typeof value === 'object' && 'url' in value
- ? String((value as { url?: unknown }).url ?? '')
- : '';
- const cell: SheetsCell = { kind: 'image', data: [url], displayData: JSON.stringify([url]), readonly: false };
- return {
- cell,
- value,
- colKey: 'attachment',
- rowId: 'row-1',
- rowIndex: 0,
- column: { key: 'attachment', name: 'Attachment', cellType: cellType as CellProps['column']['cellType'] },
- isEditing: false,
- onStartEdit: () => {},
- disabled: false,
- };
-}
-
-describe('ImageCellView', () => {
- let root: Root;
- let container: HTMLDivElement;
-
- beforeEach(() => {
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- });
-
- function render(props: CellProps) {
- act(() => {
- root.render();
- });
- }
-
- it('renders the slot wrapper', () => {
- render(makeProps('https://example.com/a.png'));
- expect(container.querySelector('[data-slot="image-cell"]')).not.toBeNull();
- });
-
- it('non-empty url -> eager async-decode
with cover + rounded classes', () => {
- render(makeProps('https://example.com/a.png'));
- const img = container.querySelector('img');
- expect(img).not.toBeNull();
- expect(img!.getAttribute('src')).toBe('https://example.com/a.png');
- // No loading="lazy": in a virtualized scroller it forces a fetch-after-mount on
- // every remount (pop-in). Eager + async decode keeps scroll-back paints warm.
- expect(img!.getAttribute('loading')).toBeNull();
- expect(img!.getAttribute('decoding')).toBe('async');
- expect(img!.className).toContain('object-cover');
- expect(img!.className).not.toContain('object-contain');
- expect(img!.className).toContain('rounded-sm');
- });
-
- it('empty url -> muted placeholder, no
', () => {
- render(makeProps(''));
- expect(container.querySelector('img')).toBeNull();
- const placeholder = container.querySelector('[data-slot="image-cell"] > div');
- expect(placeholder).not.toBeNull();
- expect(placeholder!.className).toContain('bg-muted');
- expect(placeholder!.className).toContain('aspect-square');
- });
-
- it('placeholder box backs the image (square + rounded) when a url is present', () => {
- render(makeProps('https://example.com/a.png'));
- const box = container.querySelector('[data-slot="image-cell"] > div');
- expect(box).not.toBeNull();
- expect(box!.className).toContain('aspect-square');
- expect(box!.className).toContain('bg-muted');
- expect(box!.className).toContain('rounded-sm');
- });
-
- it('non-image file value on a non-image column -> file chip, no
', () => {
- render(
- makeFileProps(
- { url: 'https://example.com/report.pdf', mime: 'application/pdf', filename: 'report.pdf' },
- 'upload',
- ),
- );
- expect(container.querySelector('[data-slot="file-cell"]')).not.toBeNull();
- expect(container.querySelector('img')).toBeNull();
- expect(container.textContent).toContain('report.pdf');
- });
-
- it('image-mime value on a non-image column -> thumbnail (image path preserved)', () => {
- render(
- makeFileProps({ url: 'https://example.com/photo.png', mime: 'image/png', filename: 'photo.png' }, 'upload'),
- );
- expect(container.querySelector('[data-slot="image-cell"]')).not.toBeNull();
- expect(container.querySelector('img')).not.toBeNull();
- });
-
- it('image column always renders a thumbnail regardless of mime', () => {
- render(makeFileProps({ url: 'https://example.com/x.bin', mime: 'application/pdf' }, 'image'));
- expect(container.querySelector('[data-slot="image-cell"]')).not.toBeNull();
- expect(container.querySelector('[data-slot="file-cell"]')).toBeNull();
- });
-
- it('bare-string url (no metadata) on a non-image column -> file chip with basename', () => {
- // Mirrors the editor: without a known image mime we chip rather than risk a broken
.
- render(makeFileProps('https://example.com/files/report.pdf', 'upload'));
- expect(container.querySelector('[data-slot="file-cell"]')).not.toBeNull();
- expect(container.querySelector('img')).toBeNull();
- expect(container.textContent).toContain('report.pdf');
- });
-});
diff --git a/packages/sheets/src/cell-model/views/__tests__/loading-view.test.tsx b/packages/sheets/src/cell-model/views/__tests__/loading-view.test.tsx
deleted file mode 100644
index 25f01fb..0000000
--- a/packages/sheets/src/cell-model/views/__tests__/loading-view.test.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-/* @vitest-environment jsdom */
-
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-
-import type { SheetsCell } from '../../sheets-cell';
-import type { CellProps } from '../../cell-props';
-import { LoadingCellView } from '../loading-view';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-// An unloaded infinite-scroll row resolves to a neutral `loading` cell with no
-// data/displayData — the view must render purely from the kind, ignoring value.
-function makeProps(over: Partial = {}): CellProps {
- const cell: SheetsCell = { kind: 'loading', data: null, displayData: '', readonly: true };
- return {
- cell,
- value: undefined,
- colKey: 'name',
- rowId: 'row-7',
- rowIndex: 7,
- column: { key: 'name', name: 'name', cellType: 'unknown' },
- isEditing: false,
- onStartEdit: () => {},
- disabled: false,
- ...over,
- };
-}
-
-describe('LoadingCellView', () => {
- let root: Root;
- let container: HTMLDivElement;
-
- beforeEach(() => {
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- });
-
- it('renders a skeleton placeholder gridcell with data-slot="loading-cell"', async () => {
- await act(async () => {
- root.render();
- });
-
- const slot = container.querySelector('[data-slot="loading-cell"]');
- expect(slot).toBeTruthy();
- expect(slot?.getAttribute('role')).toBe('gridcell');
- expect(slot?.getAttribute('aria-busy')).toBe('true');
- });
-
- it('paints a shimmer bar (animate-pulse) inside the cell', async () => {
- await act(async () => {
- root.render();
- });
-
- const slot = container.querySelector('[data-slot="loading-cell"]');
- const bar = slot?.querySelector('span');
- expect(bar).toBeTruthy();
- expect(bar?.className).toContain('animate-pulse');
- });
-
- it('renders no cell text regardless of value/displayData', async () => {
- await act(async () => {
- root.render();
- });
-
- const slot = container.querySelector('[data-slot="loading-cell"]');
- expect(slot?.textContent).toBe('');
- });
-});
diff --git a/packages/sheets/src/cell-model/views/__tests__/relation-view.test.tsx b/packages/sheets/src/cell-model/views/__tests__/relation-view.test.tsx
deleted file mode 100644
index be04f99..0000000
--- a/packages/sheets/src/cell-model/views/__tests__/relation-view.test.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-/* @vitest-environment jsdom */
-//
-// Phase-7 RelationCellView enrichment test. Mirrors the canvas count-badge
-// (grid/draw-relation-badge.ts): a LIST relation (cell.data is string[], possibly
-// with a trailing "+N" overflow chip) renders a leading count badge before the
-// chips; a SINGLE relation (string data) renders plain text with no badge.
-//
-// Uses the package's component-test idiom — jsdom + react-dom/client createRoot +
-// act (no @testing-library — not a dep of this package). The view is pure (no
-// virtualizer/layout), so it is rendered directly with hand-fed CellProps.
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-
-import { RelationCellView } from '../relation-view';
-import type { CellProps } from '../../cell-props';
-import type { SheetsCell } from '../../sheets-cell';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-function makeProps(cell: SheetsCell): CellProps {
- return {
- cell,
- value: cell.data,
- colKey: 'author',
- rowId: 'r1',
- rowIndex: 0,
- column: { key: 'author', name: 'Author', cellType: 'relation' },
- isEditing: false,
- onStartEdit: () => {},
- disabled: false,
- };
-}
-
-function listCell(data: string[]): SheetsCell {
- return { kind: 'relation', data, displayData: '', readonly: false };
-}
-
-function singleCell(label: string): SheetsCell {
- return { kind: 'relation', data: label, displayData: label, readonly: false };
-}
-
-describe('RelationCellView (count badge + chips)', () => {
- let root: Root;
- let container: HTMLDivElement;
-
- beforeEach(() => {
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- });
-
- async function render(cell: SheetsCell): Promise {
- await act(async () => {
- root.render();
- });
- const el = container.querySelector('[data-slot="relation-cell"]') as HTMLElement | null;
- expect(el).not.toBeNull();
- return el as HTMLElement;
- }
-
- it('renders a count badge before chips for a list relation', async () => {
- const el = await render(listCell(['Alice', 'Bob']));
-
- const badge = el.querySelector('[data-slot="relation-count-badge"]');
- expect(badge).not.toBeNull();
- expect(badge?.textContent).toBe('2');
-
- // Both chips render alongside the badge.
- expect(el.textContent).toContain('Alice');
- expect(el.textContent).toContain('Bob');
-
- // Badge is the leading (first) child of the cell — painted before the chips.
- expect(el.firstElementChild).toBe(badge);
- });
-
- it('counts a trailing "+N" overflow chip into the badge total (mirrors getRelationCount)', async () => {
- // 3 visible chips + "+5" overflow -> total = (4 - 1) + 5 = 8.
- const el = await render(listCell(['Alice', 'Bob', 'Carol', '+5']));
-
- const badge = el.querySelector('[data-slot="relation-count-badge"]');
- expect(badge?.textContent).toBe('8');
-
- // The "+5" overflow chip is still painted (canvas keeps it visible).
- expect(el.textContent).toContain('+5');
- });
-
- it('renders no badge for an empty list relation', async () => {
- const el = await render(listCell([]));
-
- expect(el.querySelector('[data-slot="relation-count-badge"]')).toBeNull();
- });
-
- it('renders a single relation as plain text with no badge', async () => {
- const el = await render(singleCell('Acme Corp'));
-
- expect(el.querySelector('[data-slot="relation-count-badge"]')).toBeNull();
- expect(el.textContent).toBe('Acme Corp');
- });
-});
diff --git a/packages/sheets/src/cell-types/__tests__/registry-sheetscell.test.ts b/packages/sheets/src/cell-types/__tests__/registry-sheetscell.test.ts
deleted file mode 100644
index a8ce82b..0000000
--- a/packages/sheets/src/cell-types/__tests__/registry-sheetscell.test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { defineCellType } from '../define-cell-type';
-import { createCellTypeRegistry, type CellTypeBuiltins } from '../cell-type-registry';
-import type { SheetsCell } from '../../cell-model/sheets-cell';
-import type { CellProps } from '../../cell-model/cell-props';
-import type { EditorProps } from '../../grid-dom/editors/editor-props';
-
-function sheetsCell(displayData: string): SheetsCell {
- return { kind: 'text', data: displayData, displayData, readonly: false };
-}
-
-function makeBuiltins(overrides?: Partial): CellTypeBuiltins {
- return {
- toSheetsCell: (value) => sheetsCell(`builtin:${String(value)}`),
- ...overrides,
- };
-}
-
-const ctx = {
- metadata: { cellType: 'x', fieldName: 'f', canEdit: true, isReadonly: false, activationBehavior: 'double-click' as const },
-};
-
-function TextComponent(_props: CellProps) {
- return null;
-}
-
-function TextEditorComponent(_props: EditorProps) {
- return null;
-}
-
-describe('createCellTypeRegistry — native SheetsCell + cell component', () => {
- const textDef = defineCellType({
- typeKey: 'text',
- toSheetsCell: (v) => sheetsCell(`def:${String(v)}`),
- cell: TextComponent,
- editorComponent: TextEditorComponent,
- });
-
- it('toSheetsCell uses the def for a matching typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.toSheetsCell('text', 'hi', ctx)).toMatchObject({ displayData: 'def:hi' });
- });
-
- it('toSheetsCell falls back to builtins for an unregistered typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.toSheetsCell('number', 7, ctx)).toMatchObject({ displayData: 'builtin:7' });
- });
-
- it('getCellComponent returns the def component for a matching typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.getCellComponent('text')).toBe(TextComponent);
- });
-
- it('getCellComponent returns undefined for an unregistered typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.getCellComponent('number')).toBeUndefined();
- });
-
- it('getEditorComponent returns the def editor for a matching typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.getEditorComponent('text')).toBe(TextEditorComponent);
- });
-
- it('getEditorComponent returns undefined for an unregistered typeKey', () => {
- const reg = createCellTypeRegistry([textDef], makeBuiltins());
- expect(reg.getEditorComponent('number')).toBeUndefined();
- });
-});
diff --git a/packages/sheets/src/commands/__tests__/default-commands.test.ts b/packages/sheets/src/commands/__tests__/default-commands.test.ts
deleted file mode 100644
index d4fac2c..0000000
--- a/packages/sheets/src/commands/__tests__/default-commands.test.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * PARITY spec — pins each DEFAULT_COMMANDS body to the VERBATIM sheets.tsx branch it was
- * lifted from, using a spy ctx (mock-context). Asserts the exact ctx dispatcher calls +
- * args + anchor resets + scroll order the original handler performed, BEFORE the Stage B
- * wiring. This is the regression gate for the lift: if a body drifts from the original
- * keydown/pointer handler, a call assertion here fails.
- */
-
-import { describe, expect, it } from 'vitest';
-
-import { createGridCommandRegistry } from '../registry';
-import type { GridCommand } from '../types';
-import { emptySheetsSelection, selectAllCells, computeKeyNavTarget } from '../../selection/selection-model';
-import { createMockCtx, type MockCtx } from './mock-context';
-
-const registry = createGridCommandRegistry();
-function cmd(id: string): GridCommand {
- const c = registry.get(id);
- if (!c) throw new Error(`missing command ${id}`);
- return c;
-}
-function run(id: string, ctx: MockCtx, payload?: unknown) {
- void cmd(id).run(ctx, payload);
-}
-function canRun(id: string, ctx: MockCtx, payload?: unknown): boolean {
- const c = cmd(id);
- return c.canRun ? c.canRun(ctx, payload) : true;
-}
-
-describe('edit.undo / edit.redo (lifted: undo/redo keydown branch)', () => {
- it('edit.undo calls ctx.undo', () => {
- const ctx = createMockCtx();
- run('edit.undo', ctx);
- expect(ctx.undo).toHaveBeenCalledTimes(1);
- expect(ctx.redo).not.toHaveBeenCalled();
- });
- it('edit.redo calls ctx.redo', () => {
- const ctx = createMockCtx();
- run('edit.redo', ctx);
- expect(ctx.redo).toHaveBeenCalledTimes(1);
- });
-});
-
-describe('selection.all (lifted: Ctrl/Cmd+A branch)', () => {
- it('canRun is false on an empty grid (original returned early)', () => {
- expect(canRun('selection.all', createMockCtx({ rowCount: 0 }))).toBe(false);
- expect(canRun('selection.all', createMockCtx({ colCount: 0 }))).toBe(false);
- expect(canRun('selection.all', createMockCtx())).toBe(true);
- });
- it('sets anchor [0,0] and selects the whole grid via selectAllCells', () => {
- const sel = emptySheetsSelection;
- const ctx = createMockCtx({ selection: sel, colCount: 4, rowCount: 7 });
- run('selection.all', ctx);
- expect(ctx.setAnchor).toHaveBeenCalledWith([0, 0]);
- expect(ctx.setSelection).toHaveBeenCalledWith(selectAllCells(sel, 4, 7));
- });
-});
-
-describe('cell.move* (lifted: plain-arrow branch)', () => {
- const cases: [string, number, number][] = [
- ['cell.moveUp', 0, -1],
- ['cell.moveDown', 0, 1],
- ['cell.moveLeft', -1, 0],
- ['cell.moveRight', 1, 0],
- ];
- for (const [id, dCol, dRow] of cases) {
- it(`${id}: setAnchor(clamped target) → moveActiveCell(delta) → scrollToCell(target)`, () => {
- const base: [number, number] = [1, 1];
- const ctx = createMockCtx({ selection: { current: { cell: base } } as never, colCount: 3, rowCount: 10 });
- run(id, ctx);
- const nextCol = Math.max(0, Math.min(base[0] + dCol, 3 - 1));
- const nextRow = Math.max(0, Math.min(base[1] + dRow, 10 - 1));
- expect(ctx.setAnchor).toHaveBeenCalledWith([nextCol, nextRow]);
- expect(ctx.moveActiveCell).toHaveBeenCalledWith(dCol, dRow, 3, 10);
- expect(ctx.scrollToCell).toHaveBeenCalledWith(nextCol, nextRow);
- // plain move never extends.
- expect(ctx.extendToCell).not.toHaveBeenCalled();
- });
- }
- it('clamps at the grid edge (no overflow past col/row bounds)', () => {
- const ctx = createMockCtx({ selection: { current: { cell: [0, 0] } } as never, colCount: 3, rowCount: 10 });
- run('cell.moveLeft', ctx);
- expect(ctx.setAnchor).toHaveBeenCalledWith([0, 0]);
- expect(ctx.scrollToCell).toHaveBeenCalledWith(0, 0);
- });
- it('canRun false on empty grid', () => {
- expect(canRun('cell.moveDown', createMockCtx({ rowCount: 0 }))).toBe(false);
- });
-});
-
-describe('cell.extend* (lifted: shift-arrow branch)', () => {
- const cases: [string, number, number][] = [
- ['cell.extendUp', 0, -1],
- ['cell.extendDown', 0, 1],
- ['cell.extendLeft', -1, 0],
- ['cell.extendRight', 1, 0],
- ];
- for (const [id, dCol, dRow] of cases) {
- it(`${id}: extendToCell(clamped target) → scrollToCell(target), never moveActiveCell`, () => {
- const base: [number, number] = [1, 1];
- const ctx = createMockCtx({ selection: { current: { cell: base } } as never, colCount: 3, rowCount: 10 });
- run(id, ctx);
- const nextCol = Math.max(0, Math.min(base[0] + dCol, 3 - 1));
- const nextRow = Math.max(0, Math.min(base[1] + dRow, 10 - 1));
- expect(ctx.extendToCell).toHaveBeenCalledWith(nextCol, nextRow);
- expect(ctx.scrollToCell).toHaveBeenCalledWith(nextCol, nextRow);
- expect(ctx.moveActiveCell).not.toHaveBeenCalled();
- // extend keeps the anchor put (never resets it).
- expect(ctx.setAnchor).not.toHaveBeenCalled();
- });
- }
-});
-
-describe('cell.navAbsolute (lifted: Tab/Home/End/PageUp/PageDown branch)', () => {
- it('computes the target via computeKeyNavTarget, resets anchor, activates, scrolls', () => {
- const base: [number, number] = [1, 2];
- const ctx = createMockCtx({ selection: { current: { cell: base } } as never, colCount: 3, rowCount: 10 });
- const payload = { key: 'End', ctrlOrMeta: true, shift: false, pageRows: 5 };
- run('cell.navAbsolute', ctx, payload);
- const target = computeKeyNavTarget('End', { ctrlOrMeta: true, shift: false }, base, 3, 10, 5)!;
- expect(ctx.setAnchor).toHaveBeenCalledWith([target[0], target[1]]);
- expect(ctx.setActiveCell).toHaveBeenCalledWith(target[0], target[1]);
- expect(ctx.scrollToCell).toHaveBeenCalledWith(target[0], target[1]);
- });
- it('no-ops when computeKeyNavTarget yields null (unhandled key)', () => {
- const ctx = createMockCtx();
- run('cell.navAbsolute', ctx, { key: 'Escape', ctrlOrMeta: false, shift: false, pageRows: 5 });
- expect(ctx.setActiveCell).not.toHaveBeenCalled();
- expect(ctx.scrollToCell).not.toHaveBeenCalled();
- });
- it('canRun false on empty grid', () => {
- expect(canRun('cell.navAbsolute', createMockCtx({ colCount: 0 }))).toBe(false);
- });
-});
-
-describe('editor.openActive (lifted: Enter/F2 branch)', () => {
- it('canRun opens the editor at the active cell and returns its boolean', () => {
- const opened = createMockCtx({ openEditorAtActiveResult: true });
- expect(canRun('editor.openActive', opened)).toBe(true);
- expect(opened.openEditorAtActive).toHaveBeenCalledWith();
-
- const notOpened = createMockCtx({ openEditorAtActiveResult: false });
- expect(canRun('editor.openActive', notOpened)).toBe(false);
- });
-});
-
-describe('editor.typeToEdit (lifted: type-to-edit sentinel)', () => {
- it('canRun opens the editor seeded with the typed char and returns its boolean', () => {
- const ctx = createMockCtx({ openEditorAtActiveResult: true });
- expect(canRun('editor.typeToEdit', ctx, { char: 'q' })).toBe(true);
- expect(ctx.openEditorAtActive).toHaveBeenCalledWith('q');
- });
- it('returns false (key falls through) when the cell is non-editable', () => {
- const ctx = createMockCtx({ openEditorAtActiveResult: false });
- expect(canRun('editor.typeToEdit', ctx, { char: 'q' })).toBe(false);
- });
-});
-
-describe('cell.activate / cell.extendToClicked (lifted: handleActivateCell)', () => {
- it('cell.activate resets the anchor and parks the active cell', () => {
- const ctx = createMockCtx();
- run('cell.activate', ctx, { col: 2, row: 4 });
- expect(ctx.setAnchor).toHaveBeenCalledWith([2, 4]);
- expect(ctx.setActiveCell).toHaveBeenCalledWith(2, 4);
- });
- it('cell.extendToClicked extends from the latched anchor (shift-click), no anchor reset', () => {
- const ctx = createMockCtx();
- run('cell.extendToClicked', ctx, { col: 2, row: 4 });
- expect(ctx.extendToCell).toHaveBeenCalledWith(2, 4);
- expect(ctx.setActiveCell).not.toHaveBeenCalled();
- expect(ctx.setAnchor).not.toHaveBeenCalled();
- });
-});
-
-describe('editor.open (lifted: dblclick openEditor)', () => {
- it('opens the overlay at the explicit cell + anchor rect', () => {
- const ctx = createMockCtx();
- const rect = { top: 1 } as DOMRect;
- run('editor.open', ctx, { rowIndex: 3, colKey: 'name', anchorRect: rect, initialText: 'x' });
- expect(ctx.openEditorAt).toHaveBeenCalledWith(3, 'name', rect, 'x');
- });
-});
-
-describe('structural pointer commands (routed for invariant completeness)', () => {
- it('header.sortToggle delegates to ctx.sortToggle(colKey)', () => {
- const ctx = createMockCtx();
- run('header.sortToggle', ctx, { colKey: 'name' });
- expect(ctx.sortToggle).toHaveBeenCalledWith('name');
- });
- it('rowmarker.toggleRow delegates to ctx.toggleRow(rowIndex, shift)', () => {
- const ctx = createMockCtx();
- run('rowmarker.toggleRow', ctx, { rowIndex: 5, shift: true });
- expect(ctx.toggleRow).toHaveBeenCalledWith(5, true);
- });
- it('rowmarker.toggleAll delegates to ctx.toggleAll', () => {
- const ctx = createMockCtx();
- run('rowmarker.toggleAll', ctx);
- expect(ctx.toggleAll).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/packages/sheets/src/commands/__tests__/keymap.test.ts b/packages/sheets/src/commands/__tests__/keymap.test.ts
index 8af1bda..3e6a410 100644
--- a/packages/sheets/src/commands/__tests__/keymap.test.ts
+++ b/packages/sheets/src/commands/__tests__/keymap.test.ts
@@ -7,7 +7,7 @@
import { afterEach, describe, expect, it } from 'vitest';
-import { DEFAULT_KEYMAP, resolveKeyCommand } from '../keymap';
+import { resolveKeyCommand } from '../keymap';
function ev(key: string, mods: Partial<{ ctrl: boolean; meta: boolean; shift: boolean; alt: boolean }> = {}): KeyboardEvent {
return {
@@ -124,19 +124,3 @@ describe('first-match-wins', () => {
expect(resolveKeyCommand(ev('x'), map)).toBe('k');
});
});
-
-describe('DEFAULT_KEYMAP shape', () => {
- it('declares pointer triggers for the structural gestures', () => {
- const pointers = DEFAULT_KEYMAP.filter((b) => b.trigger.kind === 'pointer').map((b) => b.command);
- expect(pointers).toEqual(
- expect.arrayContaining([
- 'cell.activate',
- 'cell.extendToClicked',
- 'editor.open',
- 'header.sortToggle',
- 'rowmarker.toggleRow',
- 'rowmarker.toggleAll',
- ]),
- );
- });
-});
diff --git a/packages/sheets/src/commands/__tests__/registry.test.ts b/packages/sheets/src/commands/__tests__/registry.test.ts
index a020537..2661e85 100644
--- a/packages/sheets/src/commands/__tests__/registry.test.ts
+++ b/packages/sheets/src/commands/__tests__/registry.test.ts
@@ -1,6 +1,6 @@
/**
- * Spec for createGridCommandRegistry (registry.ts). Covers default population, consumer
- * override REPLACING a default by id, and a new id ADDING a command (the Phase 2 seam).
+ * Dynamic command customization is runtime behavior; static default registration is
+ * covered by module construction and the package build.
*/
import { describe, expect, it, vi } from 'vitest';
@@ -8,14 +8,6 @@ import { describe, expect, it, vi } from 'vitest';
import { createGridCommandRegistry, DEFAULT_COMMANDS } from '../registry';
describe('createGridCommandRegistry', () => {
- it('populates every default command by id', () => {
- const registry = createGridCommandRegistry();
- for (const cmd of DEFAULT_COMMANDS) {
- expect(registry.get(cmd.id)).toBe(cmd);
- }
- expect(registry.size).toBe(DEFAULT_COMMANDS.length);
- });
-
it('a consumer override with a matching id REPLACES the default', () => {
const override = { id: 'edit.undo', run: vi.fn() };
const registry = createGridCommandRegistry([override]);
diff --git a/packages/sheets/src/grid-dom/__tests__/sheets-dom.parity.test.tsx b/packages/sheets/src/grid-dom/__tests__/sheets-dom.parity.test.tsx
deleted file mode 100644
index a2d814f..0000000
--- a/packages/sheets/src/grid-dom/__tests__/sheets-dom.parity.test.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-/* @vitest-environment jsdom */
-//
-// CAPSTONE test (post-cutover). The TanStack DOM grid is the ONLY render path; the
-// canvas glide grid is gone, so this proves two things over the all-cell-types
-// showcase fixture the Storybook showcase renders:
-//
-// • DOM mount — the real public is rendered through the
-// in-memory mock adapter (createMockAdapter + the showcase fixture) in jsdom,
-// exactly as the stories do, and we wait for it to populate (role="gridcell"
-// nodes appear once the mock query resolves). This is the genuine DOM render
-// path on the showcase data, drawing zero canvas.
-//
-// • Display golden — for every (row, column) the native pipeline
-// (createSheetsCell -> projectSheetsCell) projects to a stable
-// { displayText, copyText } pair, frozen in `sheets-dom.golden.json`. With the
-// glide reference removed, the native projection IS the source of truth; the
-// committed golden locks it so a future regression to the dispatcher/factories
-// over the showcase fixture is caught. Cell types are resolved through the
-// PRODUCTION channel `resolveCellType(name, fieldMeta)` (reads field.type.pgAlias)
-// — the same resolution useSheetsContent performs at runtime.
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-import { QueryClient } from '@tanstack/react-query';
-
-import { SheetsProvider } from '../../context/sheets-provider';
-import type { SheetsConfig } from '../../context/sheets-context';
-import { Sheets } from '../../grid/sheets';
-import { buildAllCellTypesTable, makeRows } from '../../stories/_support/fixtures';
-import { createMockAdapter } from '../../stories/_support/mock-adapter';
-import { resolveCellType, type FieldMetadata } from '../../cell-types/cell-type-resolver';
-import { createSheetsCell } from '../../cell-model/create-sheets-cell';
-import {
- makeMetadata,
- fakeGeometrySheetsCell,
- RELATION_INFO_BELONGS_TO,
-} from '../../grid/__golden__/display-cases';
-import { assertOrUpdateGolden, projectSheetsCell } from '../../grid/__golden__/parity.harness';
-import type { CellCreationMetadata } from '../../grid/grid-cell-types';
-import type { MetaField } from '../../forms/types';
-import type { SheetsRow } from '../../grid/row-model';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-// ─── Shared showcase fixture (the all-cell-types table the showcase renders) ─────────────────────
-const TABLE = buildAllCellTypesTable();
-const TABLE_NAME = TABLE.name; // 'demo'
-const ROWS: SheetsRow[] = makeRows(TABLE, 12, 7);
-const FIELDS = (TABLE.fields ?? []) as MetaField[];
-
-// Build the CellCreationMetadata the grid would build for a column: cellType resolved through the
-// PRODUCTION channel (resolveCellType reads field.type.pgAlias), relationInfo supplied for the
-// relation column exactly as useSheetsContent does (the relation factory keys canHandle on the
-// resolved 'relation' cellType, so display parity needs the same metadata).
-function metadataForField(field: MetaField): CellCreationMetadata {
- const fieldMeta = field as unknown as FieldMetadata;
- const { cellType } = resolveCellType(field.name, fieldMeta);
- const isRelation = cellType === 'relation';
- return makeMetadata(cellType, {
- fieldName: field.name,
- fieldMeta,
- ...(isRelation ? { relationInfo: RELATION_INFO_BELONGS_TO, relationOptions: {} } : {}),
- });
-}
-
-const proto = window.HTMLElement.prototype;
-
-describe('CAPSTONE — DOM grid renders + projects the showcase fixture (frozen golden)', () => {
- let root: Root;
- let container: HTMLDivElement;
- const origW = Object.getOwnPropertyDescriptor(proto, 'offsetWidth');
- const origH = Object.getOwnPropertyDescriptor(proto, 'offsetHeight');
- const origRect = proto.getBoundingClientRect;
-
- beforeEach(() => {
- // jsdom does no layout; shim element geometry so TanStack Virtual emits a realistic, bounded
- // window (sized scroll element + a real per-row height the row virtualizer measures).
- Object.defineProperty(proto, 'offsetWidth', { configurable: true, get: () => 1200 });
- Object.defineProperty(proto, 'offsetHeight', { configurable: true, get: () => 800 });
- proto.getBoundingClientRect = function () {
- return { width: 1200, height: 33, top: 0, left: 0, right: 1200, bottom: 33, x: 0, y: 0, toJSON() {} } as DOMRect;
- };
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- if (origW) Object.defineProperty(proto, 'offsetWidth', origW);
- else delete (proto as unknown as Record).offsetWidth;
- if (origH) Object.defineProperty(proto, 'offsetHeight', origH);
- else delete (proto as unknown as Record).offsetHeight;
- proto.getBoundingClientRect = origRect;
- });
-
- it('mounts the real DOM grid over the showcase fixture and it populates', async () => {
- const adapter = createMockAdapter({ table: TABLE, rows: ROWS });
- const config: SheetsConfig = {
- endpoint: 'mock://parity',
- auth: { mode: 'embedded', getToken: () => 't' },
- adapter,
- queryClient: new QueryClient({
- defaultOptions: { queries: { retry: false, gcTime: 0, staleTime: 0 }, mutations: { retry: false } },
- }),
- };
-
- await act(async () => {
- root.render(
-
-
-
-
-
,
- );
- });
-
- // Poll for the grid to populate after the async mock query resolves.
- await waitFor(() => {
- expect(container.querySelector('[data-part-id="sheets-viewport"]')).not.toBeNull();
- expect(container.querySelector('[data-impl="dom"]')).not.toBeNull();
- expect(container.querySelectorAll('[role="gridcell"]').length).toBeGreaterThan(0);
- });
-
- // Zero canvas on the DOM render path.
- expect(container.querySelectorAll('canvas').length).toBe(0);
- });
-
- it('projects each (row, column) of the showcase fixture to the frozen golden', () => {
- // The native DOM pipeline is the ONLY display path now, so its projection IS the
- // source of truth — frozen here so a dispatcher/factory regression over the showcase
- // fixture is caught. cell types are resolved through the production resolver.
- const rows = FIELDS.map((field) => {
- const meta = metadataForField(field);
- const cells = ROWS.map((row, r) => {
- const value = (row as Record)[field.name];
- const { displayText, copyText } = projectSheetsCell(createSheetsCell(value, meta, fakeGeometrySheetsCell));
- return { row: r, displayText, copyText };
- });
- return { field: field.name, cellType: meta.cellType, cells };
- });
-
- // Guard against a vacuous golden: the fixture must actually exercise every column × row.
- const assertions = rows.reduce((n, f) => n + f.cells.length, 0);
- expect(assertions).toBe(FIELDS.length * ROWS.length);
- expect(FIELDS.length).toBeGreaterThanOrEqual(46);
-
- assertOrUpdateGolden('sheets-dom.golden', rows);
- });
-});
-
-// ─── Minimal async poller (no @testing-library in this package; mirrors the smoke-test idiom) ─────
-async function waitFor(assert: () => void, { timeout = 4000, interval = 25 } = {}): Promise {
- const start = Date.now();
- let lastError: unknown;
- // eslint-disable-next-line no-constant-condition
- while (true) {
- try {
- await act(async () => {
- await Promise.resolve();
- });
- assert();
- return;
- } catch (error) {
- lastError = error;
- if (Date.now() - start > timeout) throw lastError;
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, interval));
- });
- }
- }
-}
diff --git a/packages/sheets/src/grid-dom/__tests__/sheets-dom.smoke.test.tsx b/packages/sheets/src/grid-dom/__tests__/sheets-dom.smoke.test.tsx
deleted file mode 100644
index c8c2f4e..0000000
--- a/packages/sheets/src/grid-dom/__tests__/sheets-dom.smoke.test.tsx
+++ /dev/null
@@ -1,139 +0,0 @@
-/* @vitest-environment jsdom */
-//
-// Phase-1 DOM-spine smoke test. Renders the S4 GridViewport over the S3 table
-// instance with the S5 SheetsCellHost, fed HAND-CRAFTED rows — NOT the full
-// GraphQL-backed Sheets (its data hooks pull @constructive-io/data, awkward
-// under vitest; full integration is Chrome-verified at Phase 8).
-//
-// Uses the package's existing component-test idiom: jsdom + react-dom/client
-// createRoot + act (no @testing-library — not a dep of this package).
-//
-// jsdom does NO layout, so TanStack Virtual's `getRect` (reads offsetWidth/
-// offsetHeight) sees 0 → outerSize 0 → range null → zero virtual items. We shim
-// offsetWidth/offsetHeight on HTMLElement so the scroll element reports a real
-// viewport and every fixture row/column virtualizes in.
-import { act } from 'react';
-import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-
-import { useSheetsTableInstance, type SheetsColumnDescriptor } from '../../table/use-sheets-table-instance';
-import { GridViewport, type RenderCell } from '../../table/grid-viewport';
-import { SheetsCellHost } from '../sheets-cell-host';
-import { createSheetsCell } from '../../cell-model/create-sheets-cell';
-import { makeMetadata } from '../../grid/__golden__/display-cases';
-import type { CellType } from '../../cell-types/types';
-import type { SheetsCellResolution } from '../use-sheets-content';
-import type { SheetsRow } from '../../grid/row-model';
-
-(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-
-const COLUMNS: SheetsColumnDescriptor[] = [
- { key: 'name', name: 'Name', size: 160 },
- { key: 'count', name: 'Count', size: 160 },
- { key: 'active', name: 'Active', size: 160 }
-];
-
-const ROWS: SheetsRow[] = [
- { id: 'r1', name: 'Alpha', count: 11, active: true },
- { id: 'r2', name: 'Bravo', count: 22, active: false },
- { id: 'r3', name: 'Charlie', count: 33, active: true }
-];
-
-// Map each fixture column to the CellType the resolver should build it as. The host
-// now requires an injected resolver (it no longer guesses kind from the JS value),
-// so the test stands in for the real `getSheetsCellContent`: read the hand-fed value
-// and dispatch through the same `createSheetsCell` family selection the shell uses.
-const COL_TYPE: Record = { name: 'text', count: 'number', active: 'boolean' };
-
-const getSheetsCellContent = (rowIndex: number, colKey: string): SheetsCellResolution => {
- const value = (ROWS[rowIndex] as Record)?.[colKey];
- const typeKey = COL_TYPE[colKey] ?? 'unknown';
- const cell = createSheetsCell(value, makeMetadata(typeKey));
- return { cell, component: undefined, colKey, typeKey };
-};
-
-const renderCell: RenderCell = (c, ctx) => (
-
-);
-
-const noop = () => {};
-const EMPTY = {} as never;
-
-function Harness() {
- const table = useSheetsTableInstance({
- columns: COLUMNS,
- data: ROWS,
- columnSizing: EMPTY,
- columnPinning: EMPTY,
- rowSelection: EMPTY,
- onColumnSizingChange: noop,
- onColumnPinningChange: noop,
- onRowSelectionChange: noop
- });
- return ;
-}
-
-describe('DOM spine smoke (GridViewport + SheetsCellHost, hand-fed)', () => {
- let root: Root;
- let container: HTMLDivElement;
- const proto = window.HTMLElement.prototype;
- const origW = Object.getOwnPropertyDescriptor(proto, 'offsetWidth');
- const origH = Object.getOwnPropertyDescriptor(proto, 'offsetHeight');
-
- beforeEach(() => {
- // Give the (layout-less) jsdom elements a non-zero size so TanStack
- // Virtual's getRect yields outerSize > 0 and emits virtual items.
- Object.defineProperty(proto, 'offsetWidth', { configurable: true, get: () => 1000 });
- Object.defineProperty(proto, 'offsetHeight', { configurable: true, get: () => 1000 });
- container = document.createElement('div');
- document.body.appendChild(container);
- root = createRoot(container);
- });
-
- afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
- container.remove();
- if (origW) Object.defineProperty(proto, 'offsetWidth', origW);
- else delete (proto as unknown as Record).offsetWidth;
- if (origH) Object.defineProperty(proto, 'offsetHeight', origH);
- else delete (proto as unknown as Record).offsetHeight;
- });
-
- it('renders real gridcell nodes, value text, the dom marker, and zero canvas', async () => {
- await act(async () => {
- root.render();
- });
-
- // (a) Real DOM nodes with role=gridcell. 3 rows × 3 cols (col0 sticky +
- // 2 virtualized) = 9. Asserts count > 0 AND the exact expected count.
- const gridcells = container.querySelectorAll('[role="gridcell"]');
- expect(gridcells.length).toBeGreaterThan(0);
- expect(gridcells.length).toBe(ROWS.length * COLUMNS.length);
-
- // (b) text / number values surface as DOM text. Booleans render via BooleanCellView
- // as a read-only design-system Checkbox (role=checkbox + aria-checked), NOT the
- // literal "true"/"false".
- const text = container.textContent ?? '';
- expect(text).toContain('Alpha'); // text
- expect(text).toContain('Charlie');
- expect(text).toContain('11'); // number
- expect(text).toContain('33');
- expect(text).not.toContain('true'); // booleans never surface as literal strings
- expect(text).not.toContain('false');
- // Boolean cells exist (one per row's `active` column), each a read-only Checkbox;
- // both polarities are present (some checked, some unchecked).
- const boolCells = Array.from(container.querySelectorAll('[data-slot="boolean-cell"]'));
- expect(boolCells.length).toBe(ROWS.length);
- expect(boolCells.every((c) => c.querySelector('[data-slot="checkbox"]'))).toBe(true); // each renders a Checkbox
- expect(boolCells.some((c) => c.querySelector('[data-slot="checkbox"][aria-checked="true"]'))).toBe(true); // some checked
- expect(boolCells.some((c) => c.querySelector('[data-slot="checkbox"][aria-checked="false"]'))).toBe(true); // some unchecked
-
- // (c) the DOM-path marker is present (GridViewport root).
- expect(container.querySelector('[data-impl="dom"]')).not.toBeNull();
-
- // (d) ZERO canvas elements — the canvas render path is not on the DOM spine.
- expect(container.querySelectorAll('canvas').length).toBe(0);
- });
-});
diff --git a/packages/sheets/src/grid-dom/editors/__tests__/edit-intent.test.ts b/packages/sheets/src/grid-dom/editors/__tests__/edit-intent.test.ts
index 7d422d5..e7f8a87 100644
--- a/packages/sheets/src/grid-dom/editors/__tests__/edit-intent.test.ts
+++ b/packages/sheets/src/grid-dom/editors/__tests__/edit-intent.test.ts
@@ -1,217 +1,40 @@
-/* @vitest-environment node */
-
-// EXHAUSTIVE routing contract for the edit-intent resolver — the regression guard
-// for the bug this fix closes: EVERY non-text cell used to mis-route to TextEditor
-// because the host read a `meta.cellType` the factories never set. Here we assert
-// every CellType lands in exactly the bucket the AUTHORITATIVE enumeration prescribes,
-// that readonly always wins, and that a consumer override wins for overlay types (but
-// never flips inline-toggle or readonly).
-//
-// EXHAUSTIVENESS is anchored to the SAME authoritative list every golden asserts
-// through — ALL_CELL_TYPES from grid/__golden__/parity.harness (the runtime mirror of
-// the CellType union, typed `Record` upstream so it can only lag in the
-// safe direction). Importing it here — rather than re-listing the union — means a new
-// CellType is forced into a bucket by THIS test the moment it joins the union: the
-// `for (const type of ALL_CELL_TYPES)` loop visits it, and its `default`-less
-// classification below makes an unclassified member fail loudly.
-
import { describe, expect, it } from 'vitest';
import type { CellType } from '../../../cell-types/types';
-import {
- BOOLEAN_TYPES,
- DATE_TIME_TYPES,
- GEOMETRY_TYPES,
- MEDIA_TYPES,
- NUMBER_TYPES,
- isArrayCellType,
-} from '../../../cell-types/cell-type-groups';
-import { ALL_CELL_TYPES } from '../../../grid/__golden__/parity.harness';
import { DOM_EDITOR_REGISTRY, type NativeEditor } from '../editor-registry-dom';
-import { resolveEditIntent, type EditIntent } from '../edit-intent';
-
-// ─── The authoritative per-type expectation, derived FROM the canonical groups ──
-//
-// `expectedIntentFor` is the spec's enumeration expressed as code, but — like the
-// resolver — it is DRIVEN OFF the same cell-type-groups Sets, so it stays exhaustive
-// by construction (never a hand-maintained per-type table that could drift). For each
-// CellType it returns the intent the resolver MUST produce, keyed to the DOM registry
-// editor for overlay types:
-// • boolean/toggle/bit -> { mode: 'inline-toggle' }
-// • NUMBER_TYPES -> { mode: 'inline-edit' } (simple text-representable, in-cell)
-// • DATE_TIME_TYPES -> overlay DateEditorDom (key === type)
-// • interval -> overlay IntervalEditorDom
-// • json | jsonb -> overlay JsonEditorDom (key === type)
-// • isArrayCellType (incl. tags) -> overlay ArrayEditorDom (key === type)
-// • GEOMETRY_TYPES -> overlay GeometryEditorDom (key === type)
-// • inet -> overlay InetEditorDom (validated editor — NOT inline)
-// • MEDIA_TYPES -> overlay ImageEditorDom (key 'image')
-// • relation -> overlay RelationEditorDom
-// • url -> overlay UrlEditorDom (the explicit text exception — NOT inline)
-// • tsvector -> overlay TsvectorEditorDom (viewer-only, still overlay)
-// • everything text-like (text/textarea/email/phone/citext/bpchar/uuid/color/
-// origin/unknown) -> { mode: 'inline-edit' } (simple text — edits in place;
-// color is just a text string, no dedicated editor)
-type ExpectedOverlay = { mode: 'overlay'; editor: NativeEditor };
-type ExpectedIntent = { mode: 'inline-toggle' } | { mode: 'inline-edit' } | ExpectedOverlay;
-
-function overlayWith(editor: NativeEditor): ExpectedOverlay {
- return { mode: 'overlay', editor };
-}
+import { resolveEditIntent } from '../edit-intent';
-function expectedIntentFor(type: CellType): ExpectedIntent {
- if (BOOLEAN_TYPES.has(type)) return { mode: 'inline-toggle' };
- if (NUMBER_TYPES.has(type)) return { mode: 'inline-edit' };
- if (DATE_TIME_TYPES.has(type)) return overlayWith(DOM_EDITOR_REGISTRY[type]);
- if (type === 'interval') return overlayWith(DOM_EDITOR_REGISTRY.interval);
- if (type === 'json' || type === 'jsonb') return overlayWith(DOM_EDITOR_REGISTRY[type]);
- if (isArrayCellType(type)) return overlayWith(DOM_EDITOR_REGISTRY[type]);
- if (GEOMETRY_TYPES.has(type)) return overlayWith(DOM_EDITOR_REGISTRY[type]);
- if (type === 'inet') return overlayWith(DOM_EDITOR_REGISTRY.inet);
- if (MEDIA_TYPES.has(type)) return overlayWith(DOM_EDITOR_REGISTRY.image);
- if (type === 'relation') return overlayWith(DOM_EDITOR_REGISTRY.relation);
- if (type === 'url') return overlayWith(DOM_EDITOR_REGISTRY.url);
- if (type === 'tsvector') return overlayWith(DOM_EDITOR_REGISTRY.tsvector);
- // Text-like floor — text/textarea/email/phone/citext/bpchar/uuid/color/origin/unknown — edits inline.
- return { mode: 'inline-edit' };
-}
+describe('resolveEditIntent', () => {
+ it('routes representative cell families to their observable editing modes', () => {
+ const cases: Array<[CellType, ReturnType]> = [
+ ['boolean', { mode: 'inline-toggle' }],
+ ['integer', { mode: 'inline-edit' }],
+ ['text', { mode: 'inline-edit' }],
+ ['date', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.date }],
+ ['text-array', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.array }],
+ ['geometry-point', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.geometry }],
+ ['upload', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.image }],
+ ['relation', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.relation }],
+ ['url', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.url }],
+ ['tsvector', { mode: 'overlay', editor: DOM_EDITOR_REGISTRY.tsvector }],
+ ];
-describe('resolveEditIntent — EXHAUSTIVE enumeration (every ALL_CELL_TYPES member)', () => {
- it(`covers all ${ALL_CELL_TYPES.length} CellTypes with exactly the prescribed intent`, () => {
- // The "all combinations" guard: visit EVERY authoritative CellType and assert the
- // resolver yields the group-derived expectation. A new union member (hence a new
- // ALL_CELL_TYPES entry) is checked here automatically — a missing classification
- // in either map fails this loop.
- for (const type of ALL_CELL_TYPES) {
- const actual = resolveEditIntent(type, {});
- const expected = expectedIntentFor(type);
- expect(actual, `${type} -> ${JSON.stringify(expected)}`).toEqual(expected);
-
- // Overlay editors must resolve to a real component (never an empty portal).
- if (expected.mode === 'overlay') {
- expect((actual as ExpectedOverlay).editor, `${type} editor is defined`).toBeTruthy();
- }
+ for (const [cellType, expected] of cases) {
+ expect(resolveEditIntent(cellType, {}), cellType).toEqual(expected);
}
});
- it('the enumeration spans the full 46-member CellType union', () => {
- // Belt-and-suspenders: the list is the authoritative one (no duplicates), so its
- // length is the CellType-union cardinality. Pin it so an accidental edit to the
- // harness list (or a union change without a list update) is visible here too.
- expect(new Set(ALL_CELL_TYPES).size).toBe(ALL_CELL_TYPES.length);
- expect(ALL_CELL_TYPES.length).toBe(46);
- });
-});
-
-describe('resolveEditIntent — per-family spot checks (spec language)', () => {
- it('booleans (boolean/toggle/bit) are inline-toggle, never an overlay', () => {
- for (const t of ['boolean', 'toggle', 'bit'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'inline-toggle' });
+ it('lets readonly state override every editing route', () => {
+ for (const cellType of ['boolean', 'text', 'relation'] as CellType[]) {
+ expect(resolveEditIntent(cellType, { readonly: true })).toEqual({ mode: 'none' });
}
});
- it('number family (incl. rating) edits inline (simple text-representable)', () => {
- for (const t of ['number', 'integer', 'smallint', 'decimal', 'currency', 'percentage', 'rating'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'inline-edit' });
- }
- });
-
- it('date/time family routes to DateEditorDom', () => {
- for (const t of ['date', 'datetime', 'time', 'timestamptz'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.date });
- }
- });
-
- it('interval routes to IntervalEditorDom', () => {
- expect(resolveEditIntent('interval', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.interval });
- });
-
- it('json/jsonb route to JsonEditorDom', () => {
- for (const t of ['json', 'jsonb'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.json });
- }
- });
-
- it('array family (incl. tags) routes to ArrayEditorDom', () => {
- for (const t of ['array', 'text-array', 'uuid-array', 'number-array', 'integer-array', 'date-array', 'tags'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY[t] });
- expect((resolveEditIntent(t, {}) as ExpectedOverlay).editor).toBe(DOM_EDITOR_REGISTRY.array);
- }
- });
-
- it('geometry family routes to GeometryEditorDom', () => {
- for (const t of ['geometry', 'geometry-point', 'geometry-collection'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.geometry });
- }
- });
-
- it('media family (image/file/video/audio/upload) reuses the image editor', () => {
- for (const t of ['image', 'file', 'video', 'audio', 'upload'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.image });
- }
- });
-
- it('inet routes to InetEditorDom', () => {
- expect(resolveEditIntent('inet', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.inet });
- });
-
- it('relation routes to RelationEditorDom', () => {
- expect(resolveEditIntent('relation', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.relation });
- });
-
- it('url routes to UrlEditorDom (was the text overlay before the fix)', () => {
- expect(resolveEditIntent('url', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.url });
- });
-
- it('tsvector is viewer-only but still opens an overlay (not none)', () => {
- expect(resolveEditIntent('tsvector', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.tsvector });
- });
-
- it('text-like family edits inline (the simple text floor)', () => {
- for (const t of ['text', 'textarea', 'email', 'phone', 'citext', 'bpchar', 'uuid', 'color', 'origin', 'unknown'] as CellType[]) {
- expect(resolveEditIntent(t, {})).toEqual({ mode: 'inline-edit' });
- }
- });
-
- it('url is the explicit text exception — it keeps its overlay editor, NOT inline', () => {
- expect(resolveEditIntent('url', {})).toEqual({ mode: 'overlay', editor: DOM_EDITOR_REGISTRY.url });
- });
-
- it('color is NOT a dedicated editor — it edits inline, and no color key leaks into the registry', () => {
- expect(resolveEditIntent('color', {})).toEqual({ mode: 'inline-edit' });
- expect(DOM_EDITOR_REGISTRY.color).toBeUndefined();
- });
-});
-
-describe('resolveEditIntent — readonly & override precedence', () => {
- it('readonly wins for EVERY CellType, regardless of bucket', () => {
- for (const type of ALL_CELL_TYPES) {
- expect(resolveEditIntent(type, { readonly: true }), `${type} readonly -> none`).toEqual({ mode: 'none' });
- }
- });
-
- it('a consumer override flips an inline text type to its overlay editor', () => {
- const Custom = (() => null) as unknown as NativeEditor;
- const intent: EditIntent = resolveEditIntent('text', {}, (k) => (k === 'text' ? Custom : undefined));
- expect(intent).toEqual({ mode: 'overlay', editor: Custom });
- });
-
- it('a consumer override flips an inline number type to its overlay editor', () => {
+ it('uses consumer editors only for editable inline cells', () => {
const Custom = (() => null) as unknown as NativeEditor;
- expect(resolveEditIntent('integer', {}, () => Custom)).toEqual({ mode: 'overlay', editor: Custom });
- });
-
- it('without an override, an inline type stays inline (override is opt-in)', () => {
- expect(resolveEditIntent('text', {}, () => undefined)).toEqual({ mode: 'inline-edit' });
- });
- it('a consumer override does NOT flip an inline-toggle', () => {
- const Custom = (() => null) as unknown as NativeEditor;
+ expect(resolveEditIntent('text', {}, () => Custom)).toEqual({ mode: 'overlay', editor: Custom });
expect(resolveEditIntent('boolean', {}, () => Custom)).toEqual({ mode: 'inline-toggle' });
- });
-
- it('a consumer override does NOT flip a readonly none', () => {
- const Custom = (() => null) as unknown as NativeEditor;
expect(resolveEditIntent('text', { readonly: true }, () => Custom)).toEqual({ mode: 'none' });
});
});
diff --git a/packages/sheets/src/grid/__golden__/cell-display.golden.json b/packages/sheets/src/grid/__golden__/cell-display.golden.json
deleted file mode 100644
index d2b69fb..0000000
--- a/packages/sheets/src/grid/__golden__/cell-display.golden.json
+++ /dev/null
@@ -1,496 +0,0 @@
-[
- {
- "copyText": "hello world",
- "displayText": "hello world",
- "intendedKind": "text",
- "label": "text — string",
- "typeKey": "text",
- "value": "hello world"
- },
- {
- "copyText": "line one\nline two",
- "displayText": "line one\nline two",
- "intendedKind": "text",
- "label": "textarea — multiline string",
- "typeKey": "textarea",
- "value": "line one\nline two"
- },
- {
- "copyText": "mailto:ada@example.com",
- "displayText": "ada@example.com",
- "intendedKind": "uri",
- "label": "email — address (mailto data)",
- "typeKey": "email",
- "value": "ada@example.com"
- },
- {
- "copyText": "https://example.com/path",
- "displayText": "https://example.com/path",
- "intendedKind": "uri",
- "label": "url — http link",
- "typeKey": "url",
- "value": "https://example.com/path"
- },
- {
- "copyText": "+1 555 0100",
- "displayText": "+1 555 0100",
- "intendedKind": "text",
- "label": "phone — digits string",
- "typeKey": "phone",
- "value": "+1 555 0100"
- },
- {
- "copyText": "MixedCase",
- "displayText": "MixedCase",
- "intendedKind": "text",
- "label": "citext — case-insensitive text",
- "typeKey": "citext",
- "value": "MixedCase"
- },
- {
- "copyText": "AB ",
- "displayText": "AB ",
- "intendedKind": "text",
- "label": "bpchar — padded char",
- "typeKey": "bpchar",
- "value": "AB "
- },
- {
- "copyText": "42.5",
- "displayText": "42.5",
- "intendedKind": "number",
- "label": "number — float",
- "typeKey": "number",
- "value": 42.5
- },
- {
- "copyText": "17",
- "displayText": "17",
- "intendedKind": "number",
- "label": "integer — int",
- "typeKey": "integer",
- "value": 17
- },
- {
- "copyText": "7",
- "displayText": "7",
- "intendedKind": "number",
- "label": "smallint — small int",
- "typeKey": "smallint",
- "value": 7
- },
- {
- "copyText": "123.45",
- "displayText": "123.45",
- "intendedKind": "number",
- "label": "decimal — string coerced",
- "typeKey": "decimal",
- "value": "123.45"
- },
- {
- "copyText": "1999.99",
- "displayText": "1999.99",
- "intendedKind": "number",
- "label": "currency — number",
- "typeKey": "currency",
- "value": 1999.99
- },
- {
- "copyText": "0.42",
- "displayText": "0.42",
- "intendedKind": "number",
- "label": "percentage — number",
- "typeKey": "percentage",
- "value": 0.42
- },
- {
- "copyText": "2026-06-11",
- "displayText": "2026-06-11",
- "intendedKind": "text",
- "label": "date — iso date",
- "typeKey": "date",
- "value": "2026-06-11"
- },
- {
- "copyText": "2026-06-11T10:00:00",
- "displayText": "2026-06-11T10:00:00",
- "intendedKind": "text",
- "label": "datetime — iso datetime",
- "typeKey": "datetime",
- "value": "2026-06-11T10:00:00"
- },
- {
- "copyText": "10:00:00",
- "displayText": "10:00:00",
- "intendedKind": "text",
- "label": "time — clock",
- "typeKey": "time",
- "value": "10:00:00"
- },
- {
- "copyText": "2026-06-11T10:00:00Z",
- "displayText": "2026-06-11T10:00:00Z",
- "intendedKind": "text",
- "label": "timestamptz — iso tz",
- "typeKey": "timestamptz",
- "value": "2026-06-11T10:00:00Z"
- },
- {
- "copyText": "{\"years\":1,\"months\":6}",
- "displayText": "1y 6mo",
- "intendedKind": "text",
- "label": "interval — object formatted",
- "typeKey": "interval",
- "value": {
- "months": 6,
- "years": 1
- }
- },
- {
- "copyText": "true",
- "displayText": "",
- "intendedKind": "boolean",
- "label": "boolean — true",
- "typeKey": "boolean",
- "value": true
- },
- {
- "copyText": "true",
- "displayText": "",
- "intendedKind": "boolean",
- "label": "toggle — truthy coercion",
- "typeKey": "toggle",
- "value": 1
- },
- {
- "copyText": "true",
- "displayText": "",
- "intendedKind": "boolean",
- "label": "bit — string coercion (truthy)",
- "typeKey": "bit",
- "value": "1"
- },
- {
- "copyText": "{\"a\":1,\"b\":\"two\"}",
- "displayText": "{\"a\":1,\"b\":\"two\"}",
- "intendedKind": "text",
- "label": "json — object preview",
- "typeKey": "json",
- "value": {
- "a": 1,
- "b": "two"
- }
- },
- {
- "copyText": "{\"nested\":{\"x\":[1,2]}}",
- "displayText": "{\"nested\":{\"x\":[1,2]}}",
- "intendedKind": "text",
- "label": "jsonb — nested object preview",
- "typeKey": "jsonb",
- "value": {
- "nested": {
- "x": [
- 1,
- 2
- ]
- }
- }
- },
- {
- "copyText": "[\"a\",\"b\",\"c\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "array — generic list",
- "typeKey": "array",
- "value": [
- "a",
- "b",
- "c"
- ]
- },
- {
- "copyText": "[\"x\",\"y\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "text-array — strings",
- "typeKey": "text-array",
- "value": [
- "x",
- "y"
- ]
- },
- {
- "copyText": "[\"11111111-1111\",\"22222222-2222\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "uuid-array — uuids",
- "typeKey": "uuid-array",
- "value": [
- "11111111-1111",
- "22222222-2222"
- ]
- },
- {
- "copyText": "[\"1\",\"2\",\"3\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "number-array — numbers",
- "typeKey": "number-array",
- "value": [
- 1,
- 2,
- 3
- ]
- },
- {
- "copyText": "[\"10\",\"20\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "integer-array — ints",
- "typeKey": "integer-array",
- "value": [
- 10,
- 20
- ]
- },
- {
- "copyText": "[\"2026-01-01\",\"2026-02-02\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "date-array — date strings",
- "typeKey": "date-array",
- "value": [
- "2026-01-01",
- "2026-02-02"
- ]
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[1,2]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[1,2]}",
- "intendedKind": "geometry",
- "label": "geometry — point geojson",
- "typeKey": "geometry",
- "value": {
- "coordinates": [
- 1,
- 2
- ],
- "type": "Point"
- }
- },
- {
- "copyText": "geo:{\"x\":1,\"y\":2}",
- "displayText": "geo:{\"x\":1,\"y\":2}",
- "intendedKind": "geometry",
- "label": "geometry-point — bare xy",
- "typeKey": "geometry-point",
- "value": {
- "x": 1,
- "y": 2
- }
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "intendedKind": "geometry",
- "label": "geometry-collection — collection",
- "typeKey": "geometry-collection",
- "value": {
- "geometries": [],
- "type": "GeometryCollection"
- }
- },
- {
- "copyText": "192.168.0.1",
- "displayText": "192.168.0.1",
- "intendedKind": "text",
- "label": "inet — ip address",
- "typeKey": "inet",
- "value": "192.168.0.1"
- },
- {
- "copyText": "[\"https://example.com/a.png\"]",
- "displayText": "[\"https://example.com/a.png\"]",
- "intendedKind": "image",
- "label": "image — url string",
- "typeKey": "image",
- "value": "https://example.com/a.png"
- },
- {
- "copyText": "[\"https://example.com/doc.pdf\"]",
- "displayText": "[\"https://example.com/doc.pdf\"]",
- "intendedKind": "image",
- "label": "file — object with url",
- "typeKey": "file",
- "value": {
- "url": "https://example.com/doc.pdf"
- }
- },
- {
- "copyText": "[\"https://example.com/v.mp4\"]",
- "displayText": "[\"https://example.com/v.mp4\"]",
- "intendedKind": "image",
- "label": "video — url string",
- "typeKey": "video",
- "value": "https://example.com/v.mp4"
- },
- {
- "copyText": "[\"https://example.com/a.mp3\"]",
- "displayText": "[\"https://example.com/a.mp3\"]",
- "intendedKind": "image",
- "label": "audio — url string",
- "typeKey": "audio",
- "value": "https://example.com/a.mp3"
- },
- {
- "copyText": "[\"/uploads/file.bin\"]",
- "displayText": "[\"/uploads/file.bin\"]",
- "intendedKind": "image",
- "label": "upload — object with path",
- "typeKey": "upload",
- "value": {
- "path": "/uploads/file.bin"
- }
- },
- {
- "copyText": "550e8400-e29b-41d4-a716-446655440000",
- "displayText": "550e8400-e29b-41d4-a716-446655440000",
- "intendedKind": "text",
- "label": "uuid — string",
- "typeKey": "uuid",
- "value": "550e8400-e29b-41d4-a716-446655440000"
- },
- {
- "copyText": "#3b82f6",
- "displayText": "#3b82f6",
- "intendedKind": "text",
- "label": "color — hex string",
- "typeKey": "color",
- "value": "#3b82f6"
- },
- {
- "copyText": "4",
- "displayText": "4",
- "intendedKind": "number",
- "label": "rating — number (NUMBER_TYPES quirk)",
- "typeKey": "rating",
- "value": 4
- },
- {
- "copyText": "[\"red\",\"green\",\"blue\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "tags — comma string split",
- "typeKey": "tags",
- "value": "red, green, blue"
- },
- {
- "copyText": "[\"cat A\",\"sat B\",\"mat\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "tsvector — lexeme preview",
- "typeKey": "tsvector",
- "value": "'cat':1A 'sat':2B,3 'mat':4"
- },
- {
- "copyText": "system",
- "displayText": "system",
- "intendedKind": "text",
- "label": "origin — string fallback",
- "typeKey": "origin",
- "value": "system"
- },
- {
- "copyText": "Ada Lovelace",
- "displayText": "Ada Lovelace",
- "intendedKind": "relation",
- "label": "relation — belongsTo object (displayName)",
- "typeKey": "relation",
- "value": {
- "displayName": "Ada Lovelace",
- "id": "u1"
- }
- },
- {
- "copyText": "mystery",
- "displayText": "mystery",
- "intendedKind": "text",
- "label": "unknown — string fallback",
- "typeKey": "unknown",
- "value": "mystery"
- },
- {
- "copyText": "",
- "displayText": "",
- "intendedKind": "number",
- "label": "number — NaN string -> empty",
- "typeKey": "number",
- "value": "not-a-number"
- },
- {
- "copyText": "{\"a\":1,\"b\":2}",
- "displayText": "{\"a\":1,\"b\":2}",
- "intendedKind": "text",
- "label": "text — object -> JSON preview",
- "typeKey": "text",
- "value": {
- "a": 1,
- "b": 2
- }
- },
- {
- "copyText": "[\"alpha\",\"beta\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "tags — array form",
- "typeKey": "tags",
- "value": [
- "alpha",
- "beta"
- ]
- },
- {
- "copyText": "[\"{\\\"k\\\":1}\",\"{\\\"k\\\":2}\"]",
- "displayText": "",
- "intendedKind": "badges",
- "label": "array — object items JSON-stringified",
- "typeKey": "array",
- "value": [
- {
- "k": 1
- },
- {
- "k": 2
- }
- ]
- },
- {
- "copyText": "[\"https://example.com/s.png\"]",
- "displayText": "[\"https://example.com/s.png\"]",
- "intendedKind": "image",
- "label": "image — object src key precedence",
- "typeKey": "image",
- "value": {
- "src": "https://example.com/s.png"
- }
- },
- {
- "copyText": "1 day",
- "displayText": "1 day",
- "intendedKind": "text",
- "label": "interval — string passthrough",
- "typeKey": "interval",
- "value": "1 day"
- },
- {
- "copyText": "{\"years\":0,\"months\":0}",
- "displayText": "0s",
- "intendedKind": "text",
- "label": "interval — zero object -> 0s",
- "typeKey": "interval",
- "value": {
- "months": 0,
- "years": 0
- }
- }
-]
diff --git a/packages/sheets/src/grid/__golden__/cell-display.sheets.parity.test.ts b/packages/sheets/src/grid/__golden__/cell-display.sheets.parity.test.ts
deleted file mode 100644
index ffe8b3d..0000000
--- a/packages/sheets/src/grid/__golden__/cell-display.sheets.parity.test.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// BREADTH gate — DISPATCHER-level display golden (native pipeline vs frozen v1).
-//
-// The `createSheetsCell` DISPATCHER must select the right family and project the
-// SAME { displayText, copyText } v1 froze, across EVERY CellType + edge case in
-// the shared fixture table. The committed `cell-display.golden.json` holds those
-// frozen v1 values; here we run each case through the live native pipeline
-// (createSheetsCell -> projectSheetsCell) and assert it reproduces the golden.
-//
-// If a dispatcher precedence drifts (e.g. text-fallback no longer last, or a family
-// claims the wrong types) the projected pair for that case diverges from the frozen
-// golden and this fails. `intendedKind` (from CELL_TYPE_TO_DISPLAY_KIND) is recorded
-// per row so the golden also pins the neutral render kind each type resolves to.
-
-import { describe, it } from 'vitest';
-
-import { createSheetsCell } from '../../cell-model/create-sheets-cell';
-
-import { ALL_CASES, fakeGeometrySheetsCell, makeMetadata } from './display-cases';
-import { CELL_TYPE_TO_DISPLAY_KIND, assertOrUpdateGolden, projectSheetsCell } from './parity.harness';
-
-describe('BREADTH — createSheetsCell dispatcher projects to the frozen cell-display golden', () => {
- it('matches the committed golden for every case', () => {
- const rows = ALL_CASES.map(({ label, typeKey, value, metaOverrides }) => {
- const meta = makeMetadata(typeKey, metaOverrides);
- const { displayText, copyText } = projectSheetsCell(createSheetsCell(value, meta, fakeGeometrySheetsCell));
- return { label, typeKey, value, intendedKind: CELL_TYPE_TO_DISPLAY_KIND[typeKey], displayText, copyText };
- });
-
- assertOrUpdateGolden('cell-display.golden', rows);
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/coverage.meta.test.ts b/packages/sheets/src/grid/__golden__/coverage.meta.test.ts
deleted file mode 100644
index e8546dc..0000000
--- a/packages/sheets/src/grid/__golden__/coverage.meta.test.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * PHASE-0 GATE — union-breadth + branch-reachability meta-test.
- *
- * This is the breadth gate over the committed goldens. It extends the spirit of
- * `__tests__/registry-fidelity.test.ts:152` ("covers every built-in factory
- * family at least once") from the ~7 representative families to the FULL
- * `CellType` union, and it pins that the resolver golden actually exercises the
- * editability branches (readonly / non-editable / viewer-only), not just the
- * happy path.
- *
- * Unlike the capture suites, this test reads the COMMITTED *.golden.json files
- * (not the live factories). It fails loudly if a future union member is added
- * without a display-golden case, or if the resolver golden is regenerated in a
- * way that drops a reachable branch — either of which would silently shrink
- * Phase-0 coverage and let the upcoming SheetsCell flip regress unobserved.
- *
- * Authoritative enumeration is `ALL_CELL_TYPES` (the runtime mirror of the
- * `CellType` union) and `CELL_TYPE_TO_DISPLAY_KIND` (the total type -> kind map),
- * both from `parity.harness`.
- */
-
-import { describe, expect, it } from 'vitest';
-
-import { ALL_CELL_TYPES, CELL_TYPE_TO_DISPLAY_KIND, loadGolden } from './parity.harness';
-
-// ─── Shapes of the committed goldens this gate reads ────────────────────────
-
-interface CellDisplayRow {
- typeKey: string;
-}
-
-interface ResolverRow {
- label: string;
- fieldName: string;
- resolution: {
- cellType: string;
- canEdit: boolean;
- canActivate: boolean;
- activationBehavior: 'single-click' | 'double-click';
- isReadonly: boolean;
- };
-}
-
-describe('PHASE-0 GATE — golden breadth + branch coverage', () => {
- // ── (1) cell-display golden covers EVERY CellType union member ──
- describe('cell-display golden covers the full CellType union', () => {
- const rows = loadGolden('cell-display.golden') as CellDisplayRow[];
- const coveredTypeKeys = new Set(rows.map((r) => r.typeKey));
-
- it('has at least one display-golden case per ALL_CELL_TYPES member', () => {
- const missing = ALL_CELL_TYPES.filter((t) => !coveredTypeKeys.has(t));
- expect(missing, `CellType members with no cell-display golden case: ${missing.join(', ')}`).toEqual([]);
- });
-
- it('introduces no display-golden typeKey outside the CellType union', () => {
- const known = new Set(ALL_CELL_TYPES);
- const extras = [...coveredTypeKeys].filter((t) => !known.has(t));
- expect(extras, `cell-display golden typeKeys not in ALL_CELL_TYPES: ${extras.join(', ')}`).toEqual([]);
- });
- });
-
- // ── (2) CELL_TYPE_TO_DISPLAY_KIND is total over the union ──
- describe('CELL_TYPE_TO_DISPLAY_KIND has a DisplayKind for every union member', () => {
- it('maps every ALL_CELL_TYPES member to a defined DisplayKind', () => {
- const unmapped = ALL_CELL_TYPES.filter((t) => CELL_TYPE_TO_DISPLAY_KIND[t] === undefined);
- expect(unmapped, `CellType members missing a DisplayKind: ${unmapped.join(', ')}`).toEqual([]);
- });
- });
-
- // ── (3) resolver golden exercises the editability branches ──
- describe('resolver golden exercises readonly / non-editable / viewer-only branches', () => {
- const rows = loadGolden('resolver.golden') as ResolverRow[];
-
- const readonlyRows = rows.filter((r) => r.resolution.isReadonly === true);
- // READONLY_CONDITIONS keys: id (only when gqlType === UUID), createdAt, updatedAt.
- const readonlyIdUuid = readonlyRows.filter((r) => r.fieldName === 'id' && r.resolution.cellType === 'uuid');
- const readonlyCreatedAt = readonlyRows.filter((r) => r.fieldName === 'createdAt');
- const readonlyUpdatedAt = readonlyRows.filter((r) => r.fieldName === 'updatedAt');
-
- // NON_EDITABLE outcome: canEdit === false (whatever the cause — readonly name
- // OR NON_EDITABLE_TYPES membership).
- const nonEditableRows = rows.filter((r) => r.resolution.canEdit === false);
- // VIEWER_ONLY outcome: the viewer-only lock — NOT editable but STILL activatable
- // (canEdit false && canActivate true). In v1 only tsvector is VIEWER_ONLY.
- const viewerOnlyRows = rows.filter((r) => r.resolution.canEdit === false && r.resolution.canActivate === true);
-
- it('covers the id+UUID readonly branch', () => {
- expect(readonlyIdUuid.length, 'no readonly id+UUID row in resolver.golden').toBeGreaterThan(0);
- });
-
- it('covers the createdAt readonly branch', () => {
- expect(readonlyCreatedAt.length, 'no readonly createdAt row in resolver.golden').toBeGreaterThan(0);
- });
-
- it('covers the updatedAt readonly branch', () => {
- expect(readonlyUpdatedAt.length, 'no readonly updatedAt row in resolver.golden').toBeGreaterThan(0);
- });
-
- it('covers at least one NON_EDITABLE outcome (canEdit === false)', () => {
- expect(nonEditableRows.length, 'no canEdit:false row in resolver.golden').toBeGreaterThan(0);
- });
-
- it('covers at least one VIEWER_ONLY outcome (canEdit false but canActivate true)', () => {
- expect(
- viewerOnlyRows.length,
- 'no viewer-only row (canEdit:false + canActivate:true) in resolver.golden',
- ).toBeGreaterThan(0);
- });
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/display-cases.ts b/packages/sheets/src/grid/__golden__/display-cases.ts
index 5145104..59c28ba 100644
--- a/packages/sheets/src/grid/__golden__/display-cases.ts
+++ b/packages/sheets/src/grid/__golden__/display-cases.ts
@@ -1,19 +1,12 @@
-/**
- * SHARED display fixtures — the native (glide-free) case tables + helpers that
- * drive the cell-display golden. The committed `cell-display.golden.json` freezes
- * the expected `{ displayText, copyText }` per case; the cell-display parity test
- * iterates these and asserts the native pipeline reproduces the frozen values.
- */
+/** Shared deterministic display fixtures used by focused editor tests. */
import type { CellType } from '../../cell-types/types';
import type { SheetsCell } from '../../cell-model/sheets-cell';
import type { CellCreationMetadata } from '../grid-cell-types';
import type { RelationInfo } from '../../store/relation-info-slice';
-// Deterministic geometry SheetsCell — the native render payload a geometry factory
-// emits. We do NOT import the real createGeometryCell (it pulls optional leaflet
-// peers); a stable `geo:` displayText keeps the golden reproducible while
-// exercising projectSheetsCell's geometry branch (display === copy) faithfully.
+// Deterministic geometry SheetsCell. We do not import the real
+// createGeometryCell because it pulls optional Leaflet peers.
export function fakeGeometrySheetsCell(value: unknown): SheetsCell {
return {
kind: 'geometry',
diff --git a/packages/sheets/src/grid/__golden__/harness.self.test.ts b/packages/sheets/src/grid/__golden__/harness.self.test.ts
deleted file mode 100644
index a8ec4b7..0000000
--- a/packages/sheets/src/grid/__golden__/harness.self.test.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import type { CellType } from '../../cell-types/types';
-import type { SheetsCell } from '../../cell-model/sheets-cell';
-
-import {
- ALL_CELL_TYPES,
- CELL_TYPE_TO_DISPLAY_KIND,
- projectSheetsCell,
- type DisplayKind,
-} from './parity.harness';
-
-// SELF-TEST for the shared parity contract. Validates the native projection is
-// total + deterministic for the kinds the factories emit, and that the
-// CellType -> DisplayKind map is total over the union. Geometry projection is
-// exercised here via a hand-built SheetsCell (display === copy) and downstream in
-// the golden suites.
-
-describe('projectSheetsCell — neutral projection over factory-emitted kinds', () => {
- it('text cell projects displayData/data verbatim', () => {
- const cell: SheetsCell = { kind: 'text', data: 'hello world', displayData: 'hello world', readonly: false };
- expect(projectSheetsCell(cell)).toEqual({ displayText: 'hello world', copyText: 'hello world' });
- });
-
- it('number cell projects string displayData and stringified numeric data', () => {
- const cell: SheetsCell = { kind: 'number', data: 42.5, displayData: '42.5', readonly: false };
- expect(projectSheetsCell(cell)).toEqual({ displayText: '42.5', copyText: '42.5' });
- });
-
- it('badges cell has no display text (-> empty) and JSON-stringifies its string[] data', () => {
- const cell: SheetsCell = { kind: 'badges', data: ['alpha', 'beta', 'gamma'], displayData: '', readonly: false };
- expect(projectSheetsCell(cell)).toEqual({
- displayText: '',
- copyText: '["alpha","beta","gamma"]',
- });
- });
-
- it('is total for null-ish fields (no throw, empty strings)', () => {
- // A number cell with data:undefined + empty displayData is what the factory
- // emits for null/NaN numeric input. Projection must stay total.
- const cell: SheetsCell = { kind: 'number', data: undefined, displayData: '', readonly: false };
- expect(projectSheetsCell(cell)).toEqual({ displayText: '', copyText: '' });
- });
-
- it('geometry-shaped cell projects display === copy from displayData', () => {
- const cell: SheetsCell = {
- kind: 'geometry',
- data: { type: 'Point', coordinates: [2, 1] },
- displayData: 'Point (1.0000, 2.0000)',
- readonly: false,
- };
- expect(projectSheetsCell(cell)).toEqual({
- displayText: 'Point (1.0000, 2.0000)',
- copyText: 'Point (1.0000, 2.0000)',
- });
- });
-});
-
-describe('CELL_TYPE_TO_DISPLAY_KIND — total over the CellType union', () => {
- const VALID_KINDS = new Set([
- 'text',
- 'number',
- 'boolean',
- 'badges',
- 'uri',
- 'image',
- 'geometry',
- 'relation',
- 'loading',
- 'draft-action',
- 'custom',
- ]);
-
- it('every ALL_CELL_TYPES entry has a valid DisplayKind', () => {
- for (const cellType of ALL_CELL_TYPES) {
- const kind = CELL_TYPE_TO_DISPLAY_KIND[cellType];
- expect(kind, `missing/invalid DisplayKind for "${cellType}"`).toBeDefined();
- expect(VALID_KINDS.has(kind), `unexpected DisplayKind "${kind}" for "${cellType}"`).toBe(true);
- }
- });
-
- it('the map has no keys beyond ALL_CELL_TYPES (no accidental extras)', () => {
- const known = new Set(ALL_CELL_TYPES);
- for (const key of Object.keys(CELL_TYPE_TO_DISPLAY_KIND)) {
- expect(known.has(key), `unexpected key "${key}" in CELL_TYPE_TO_DISPLAY_KIND`).toBe(true);
- }
- });
-
- it('ALL_CELL_TYPES has no duplicates and matches the map key count', () => {
- expect(new Set(ALL_CELL_TYPES).size).toBe(ALL_CELL_TYPES.length);
- expect(Object.keys(CELL_TYPE_TO_DISPLAY_KIND).length).toBe(ALL_CELL_TYPES.length);
- });
-
- it('pins the family-anchor mappings (image/uri/badges/number/boolean/geometry/relation/text)', () => {
- const expectations: Array<[CellType, DisplayKind]> = [
- ['image', 'image'],
- ['upload', 'image'],
- ['url', 'uri'],
- ['email', 'uri'],
- ['tags', 'badges'],
- ['tsvector', 'badges'],
- ['text-array', 'badges'],
- ['number', 'number'],
- ['rating', 'number'],
- ['boolean', 'boolean'],
- ['bit', 'boolean'],
- ['geometry', 'geometry'],
- ['relation', 'relation'],
- ['date', 'text'],
- ['interval', 'text'],
- ['json', 'text'],
- ['text', 'text'],
- ['unknown', 'text'],
- ];
- for (const [cellType, expected] of expectations) {
- expect(CELL_TYPE_TO_DISPLAY_KIND[cellType], cellType).toBe(expected);
- }
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/parity.harness.ts b/packages/sheets/src/grid/__golden__/parity.harness.ts
deleted file mode 100644
index 8ede63d..0000000
--- a/packages/sheets/src/grid/__golden__/parity.harness.ts
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- * SHARED PARITY CONTRACT — the native (glide-free) projection every golden
- * asserts through. With the glide cutover complete, the committed `*.golden.json`
- * snapshots ARE the frozen v1 truth, and the live native pipeline
- * (`createSheetsCell` -> {@link projectSheetsCell}) is asserted against them.
- *
- * Two concepts live here:
- *
- * 1. A neutral RENDER vocabulary — {@link DisplayKind} — the ~11 native kinds,
- * plus a total map from every {@link CellType} union member to its
- * `DisplayKind`.
- *
- * 2. A total, deterministic projection — {@link projectSheetsCell} — that
- * reduces any native `SheetsCell` the factories emit to a
- * `{ displayText, copyText }` pair (the frozen golden shape).
- *
- * 3. A golden assert/update helper — {@link assertOrUpdateGolden} — colocated
- * JSON snapshots with stable key order, switched by `UPDATE_GOLDEN`.
- *
- * Nothing here imports the real `createGeometryCell` (it pulls optional leaflet
- * peers); the geometry custom-cell is projected from its `displayData`.
- */
-
-import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
-import { dirname, join } from 'node:path';
-import { fileURLToPath } from 'node:url';
-
-import { expect } from 'vitest';
-
-import type { CellType } from '../../cell-types/types';
-import type { SheetsCell } from '../../cell-model/sheets-cell';
-
-// ─── (a) Neutral render vocabulary ──────────────────────────────────────────
-
-/**
- * The ~11 RENDER-LEVEL native kinds — the canonical neutral vocabulary every
- * phase projects into.
- *
- * `loading` and `draft-action` have no `CellType` source (they originate from
- * grid-internal state, not the data type system) but are part of the native
- * render surface, so they are reserved here for downstream phases.
- */
-export type DisplayKind =
- | 'text'
- | 'number'
- | 'boolean'
- | 'badges'
- | 'uri'
- | 'image'
- | 'geometry'
- | 'relation'
- | 'loading'
- | 'draft-action'
- | 'custom';
-
-// ─── (b) CellType -> DisplayKind (compiler-enforced exhaustive) ──────────────
-
-/**
- * Maps EVERY member of the {@link CellType} union to its {@link DisplayKind}.
- *
- * Typed as `Record` so a missing union member is a
- * COMPILE error (the spike's exhaustiveness guard). Each entry is assigned by
- * which `cell-content-factory` family handles that type:
- *
- * ImageCellFactory (MEDIA_TYPES) -> 'image'
- * UriCellFactory (url|email) -> 'uri'
- * ArrayCellFactory (array-like + tsvector) -> 'badges'
- * DateTimeCellFactory + IntervalCellFactory -> 'text' (formatted text in v1)
- * GeometryCellFactory(GEOMETRY_TYPES) -> 'geometry'
- * RelationCellFactory(relation) -> 'relation'
- * NumberCellFactory (NUMBER_TYPES) -> 'number'
- * BooleanCellFactory (BOOLEAN_TYPES) -> 'boolean'
- * TextCellFactory (everything else, fallback) -> 'text'
- *
- * NOTE on the two v1 quirks captured here (see `deviations`):
- * - `rating` is in NUMBER_TYPES (cell-type-groups.ts), so the NumberCellFactory
- * claims it before the text fallback -> 'number' (NOT 'text'), even though the
- * task's text-fallback list names 'rating'. Mapped to 'number' to match the
- * ACTUAL v1 factory selection.
- * - `relation` maps to 'relation' for BOTH single and list; the native
- * RelationCellView owns both, even though v1 glide emits Text (single) and
- * Bubble (list). The neutral kind intentionally collapses that glide split.
- */
-export const CELL_TYPE_TO_DISPLAY_KIND: Record = {
- // Text-based cells — TextCellFactory fallback display
- text: 'text',
- textarea: 'text',
- email: 'uri',
- url: 'uri',
- phone: 'text',
- citext: 'text',
- bpchar: 'text',
- // Numeric cells — NumberCellFactory
- number: 'number',
- integer: 'number',
- smallint: 'number',
- decimal: 'number',
- currency: 'number',
- percentage: 'number',
- // Date/time cells — DateTime + Interval factories (formatted text in v1)
- date: 'text',
- datetime: 'text',
- time: 'text',
- timestamptz: 'text',
- interval: 'text',
- // Boolean cells — BooleanCellFactory
- boolean: 'boolean',
- toggle: 'boolean',
- bit: 'boolean',
- // Structured data cells
- json: 'text',
- jsonb: 'text',
- array: 'badges',
- // Array cells (specific types) — ArrayCellFactory
- 'text-array': 'badges',
- 'uuid-array': 'badges',
- 'number-array': 'badges',
- 'integer-array': 'badges',
- 'date-array': 'badges',
- // Geometric cells — GeometryCellFactory
- geometry: 'geometry',
- 'geometry-point': 'geometry',
- 'geometry-collection': 'geometry',
- // Network cells — text fallback
- inet: 'text',
- // Media cells — ImageCellFactory
- image: 'image',
- file: 'image',
- video: 'image',
- audio: 'image',
- upload: 'image',
- // Special cells
- uuid: 'text',
- color: 'text',
- // `rating` is in NUMBER_TYPES -> NumberCellFactory claims it (v1 actual). quirk.
- rating: 'number',
- tags: 'badges',
- tsvector: 'badges',
- origin: 'text',
- // Relation cells — RelationCellFactory (single AND list -> one neutral kind)
- relation: 'relation',
- // Fallback
- unknown: 'text',
-};
-
-/**
- * Runtime mirror of the {@link CellType} union — the authoritative enumeration
- * for the Gate stage and for the harness self-test's totality check. Kept in the
- * SAME order as the union in `cell-types/types.ts`. If a member is added to the
- * union but not here, `CELL_TYPE_TO_DISPLAY_KIND` (typed `Record`)
- * still fails to compile, so this array can only ever lag in the safe direction.
- */
-export const ALL_CELL_TYPES: CellType[] = [
- 'text',
- 'textarea',
- 'email',
- 'url',
- 'phone',
- 'citext',
- 'bpchar',
- 'number',
- 'integer',
- 'smallint',
- 'decimal',
- 'currency',
- 'percentage',
- 'date',
- 'datetime',
- 'time',
- 'timestamptz',
- 'interval',
- 'boolean',
- 'toggle',
- 'bit',
- 'json',
- 'jsonb',
- 'array',
- 'text-array',
- 'uuid-array',
- 'number-array',
- 'integer-array',
- 'date-array',
- 'geometry',
- 'geometry-point',
- 'geometry-collection',
- 'inet',
- 'image',
- 'file',
- 'video',
- 'audio',
- 'upload',
- 'uuid',
- 'color',
- 'rating',
- 'tags',
- 'tsvector',
- 'origin',
- 'relation',
- 'unknown',
-];
-
-// ─── (c) Native neutral projection ──────────────────────────────────────────
-
-/**
- * Stringify one cell field deterministically:
- * - null / undefined -> ''
- * - Array (image/badges data) -> JSON.stringify(array)
- * - string -> as-is
- * - anything else -> String(value)
- */
-function stringifyField(value: unknown): string {
- if (value === null || value === undefined) return '';
- if (Array.isArray(value)) return JSON.stringify(value);
- if (typeof value === 'string') return value;
- return String(value);
-}
-
-/**
- * Reduce a native {@link SheetsCell} to the neutral `{ displayText, copyText }`
- * pair the committed goldens freeze. TOTAL + DETERMINISTIC over every kind the
- * factories emit.
- *
- * - geometry / custom — the SheetsCell carries the rendered text in
- * `displayData`, and (mirroring v1's Custom cell where copyData === displayText)
- * both display and copy come from `cell.displayData`, used verbatim.
- * - everything else — display from `displayData`, copy from `data`, both run
- * through the same `stringifyField` (arrays -> JSON; null/undefined -> '').
- * badges/boolean carry no display text, so they project to '' on the display
- * side — that is the frozen v1 truth.
- */
-export function projectSheetsCell(cell: SheetsCell): { displayText: string; copyText: string } {
- if (cell.kind === 'geometry' || cell.kind === 'custom') {
- return { displayText: cell.displayData, copyText: cell.displayData };
- }
- return {
- displayText: stringifyField(cell.displayData),
- copyText: stringifyField(cell.data),
- };
-}
-
-// ─── (d) + (e) Golden assert / update + load / write helpers ────────────────
-
-const GOLDEN_DIR = dirname(fileURLToPath(import.meta.url));
-
-function goldenPath(name: string): string {
- return join(GOLDEN_DIR, `${name}.json`);
-}
-
-/**
- * Recursively sort object keys so written goldens have a STABLE byte layout
- * regardless of insertion order. Arrays keep their order (order is meaningful);
- * primitives pass through.
- */
-function sortKeysDeep(value: unknown): unknown {
- if (Array.isArray(value)) return value.map(sortKeysDeep);
- if (value && typeof value === 'object') {
- const out: Record = {};
- for (const key of Object.keys(value as Record).sort()) {
- out[key] = sortKeysDeep((value as Record)[key]);
- }
- return out;
- }
- return value;
-}
-
-/** Read + parse the golden JSON for `name`. Throws if it is missing. */
-export function loadGolden(name: string): unknown {
- const path = goldenPath(name);
- if (!existsSync(path)) {
- throw new Error(
- `Golden "${name}" not found at ${path}. Generate it with UPDATE_GOLDEN=1 pnpm exec vitest run .`,
- );
- }
- return JSON.parse(readFileSync(path, 'utf8'));
-}
-
-/** Write `data` as a stable-key-order golden JSON (pretty, trailing newline). */
-export function writeGolden(name: string, data: unknown): void {
- if (!existsSync(GOLDEN_DIR)) mkdirSync(GOLDEN_DIR, { recursive: true });
- const stable = sortKeysDeep(data);
- writeFileSync(goldenPath(name), `${JSON.stringify(stable, null, 2)}\n`, 'utf8');
-}
-
-/**
- * Golden gate. With `UPDATE_GOLDEN` set, (re)writes `.json` and returns.
- * Otherwise reads the committed golden and asserts deep equality against
- * `actual`. `actual` is normalized through the same stable-key-order pass so
- * the comparison is order-insensitive on object keys — matching what was
- * written — while staying a strict `toEqual`.
- */
-export function assertOrUpdateGolden(name: string, actual: unknown): void {
- if (process.env.UPDATE_GOLDEN) {
- writeGolden(name, actual);
- return;
- }
- const expected = loadGolden(name);
- expect(sortKeysDeep(actual)).toEqual(expected);
-}
diff --git a/packages/sheets/src/grid/__golden__/post-processing.golden.json b/packages/sheets/src/grid/__golden__/post-processing.golden.json
deleted file mode 100644
index 4157da3..0000000
--- a/packages/sheets/src/grid/__golden__/post-processing.golden.json
+++ /dev/null
@@ -1,293 +0,0 @@
-{
- "draft": [
- {
- "after": {
- "copyText": "",
- "displayText": ""
- },
- "before": {
- "copyText": "draft:k-001",
- "displayText": "draft:k-001"
- },
- "cellType": "text",
- "colKey": "id",
- "isDraftRow": true,
- "label": "draft id column — draft: key blanked",
- "rawValue": "draft:k-001",
- "rowKeys": [
- "id"
- ],
- "suppressed": true
- },
- {
- "after": {
- "copyText": "",
- "displayText": ""
- },
- "before": {
- "copyText": "draft:k-001",
- "displayText": "draft:k-001"
- },
- "cellType": "text",
- "colKey": "parentId",
- "isDraftRow": true,
- "label": "draft non-id column equal to draft id — blanked",
- "rawValue": "draft:k-001",
- "rowKeys": [
- "id",
- "parentId"
- ],
- "suppressed": true
- },
- {
- "after": {
- "copyText": "Hello draft",
- "displayText": "Hello draft"
- },
- "before": {
- "copyText": "Hello draft",
- "displayText": "Hello draft"
- },
- "cellType": "text",
- "colKey": "name",
- "isDraftRow": true,
- "label": "draft normal column — untouched",
- "rawValue": "Hello draft",
- "rowKeys": [
- "id",
- "name"
- ],
- "suppressed": false
- },
- {
- "after": {
- "copyText": "Working title",
- "displayText": "Working title"
- },
- "before": {
- "copyText": "Working title",
- "displayText": "Working title"
- },
- "cellType": "text",
- "colKey": "title",
- "isDraftRow": true,
- "label": "draft error-status column — untouched",
- "rawValue": "Working title",
- "rowKeys": [
- "id",
- "title"
- ],
- "suppressed": false
- },
- {
- "after": {
- "copyText": "server-id-42",
- "displayText": "server-id-42"
- },
- "before": {
- "copyText": "server-id-42",
- "displayText": "server-id-42"
- },
- "cellType": "text",
- "colKey": "id",
- "isDraftRow": true,
- "label": "draft id column with server id — not blanked",
- "rawValue": "server-id-42",
- "rowKeys": [
- "id"
- ],
- "suppressed": false
- }
- ],
- "relation": [
- {
- "copyText": "Ada Lovelace",
- "displayText": "Ada Lovelace",
- "kind": "belongsTo",
- "label": "belongsTo — label from displayName",
- "relationOptions": {},
- "typeKey": "relation",
- "value": {
- "displayName": "Ada Lovelace",
- "id": "u1"
- }
- },
- {
- "copyText": "Grace Hopper",
- "displayText": "Grace Hopper",
- "kind": "belongsTo",
- "label": "belongsTo — fallback to name candidate",
- "relationOptions": {},
- "typeKey": "relation",
- "value": {
- "id": "u2",
- "name": "Grace Hopper"
- }
- },
- {
- "copyText": "u3",
- "displayText": "u3",
- "kind": "belongsTo",
- "label": "belongsTo — id last resort",
- "relationOptions": {},
- "typeKey": "relation",
- "value": {
- "id": "u3"
- }
- },
- {
- "copyText": "",
- "displayText": "",
- "kind": "belongsTo",
- "label": "belongsTo — null value",
- "relationOptions": {},
- "typeKey": "relation",
- "value": null
- },
- {
- "copyText": "plain-id",
- "displayText": "plain-id",
- "kind": "belongsTo",
- "label": "belongsTo — scalar string value",
- "relationOptions": {},
- "typeKey": "relation",
- "value": "plain-id"
- },
- {
- "copyText": "",
- "displayText": "",
- "kind": "belongsTo",
- "label": "belongsTo — draft: placeholder suppressed",
- "relationOptions": {},
- "typeKey": "relation",
- "value": "draft:abc123"
- },
- {
- "copyText": "",
- "displayText": "",
- "kind": "belongsTo",
- "label": "belongsTo — object id draft: suppressed",
- "relationOptions": {},
- "typeKey": "relation",
- "value": {
- "id": "draft:xyz"
- }
- },
- {
- "copyText": "A very long author disp…",
- "displayText": "A very long author disp…",
- "kind": "belongsTo",
- "label": "belongsTo — label truncated at default max",
- "relationOptions": {},
- "typeKey": "relation",
- "value": {
- "displayName": "A very long author display name that exceeds the limit"
- }
- },
- {
- "copyText": "A very …",
- "displayText": "A very …",
- "kind": "belongsTo",
- "label": "belongsTo — label truncated at explicit max 8",
- "relationOptions": {
- "relationLabelMaxLength": 8
- },
- "typeKey": "relation",
- "value": {
- "displayName": "A very long author display name that exceeds the limit"
- }
- },
- {
- "copyText": "[\"one\",\"two\"]",
- "displayText": "",
- "kind": "hasMany",
- "label": "hasMany — within chip limit",
- "relationOptions": {},
- "typeKey": "relation",
- "value": [
- {
- "title": "one"
- },
- {
- "title": "two"
- }
- ]
- },
- {
- "copyText": "[\"one\",\"two\",\"three\",\"+2\"]",
- "displayText": "",
- "kind": "hasMany",
- "label": "hasMany — overflow +N at default chip limit",
- "relationOptions": {},
- "typeKey": "relation",
- "value": [
- {
- "title": "one"
- },
- {
- "title": "two"
- },
- {
- "title": "three"
- },
- {
- "title": "four"
- },
- {
- "title": "five"
- }
- ]
- },
- {
- "copyText": "[\"one\",\"two\",\"+2\"]",
- "displayText": "",
- "kind": "hasMany",
- "label": "hasMany — overflow +N at explicit chip limit 2",
- "relationOptions": {
- "relationChipLimit": 2
- },
- "typeKey": "relation",
- "value": [
- {
- "title": "one"
- },
- {
- "title": "two"
- },
- {
- "title": "three"
- },
- {
- "title": "four"
- }
- ]
- },
- {
- "copyText": "[]",
- "displayText": "",
- "kind": "hasMany",
- "label": "hasMany — empty list",
- "relationOptions": {},
- "typeKey": "relation",
- "value": []
- },
- {
- "copyText": "[\"A ver…\",\"short\"]",
- "displayText": "",
- "kind": "hasMany",
- "label": "hasMany — per-chip truncation at explicit max 6",
- "relationOptions": {
- "relationLabelMaxLength": 6
- },
- "typeKey": "relation",
- "value": [
- {
- "title": "A very long author display name that exceeds the limit"
- },
- {
- "title": "short"
- }
- ]
- }
- ]
-}
diff --git a/packages/sheets/src/grid/__golden__/post-processing.golden.test.ts b/packages/sheets/src/grid/__golden__/post-processing.golden.test.ts
deleted file mode 100644
index 2c20364..0000000
--- a/packages/sheets/src/grid/__golden__/post-processing.golden.test.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { createSheetsCell } from '../../cell-model/create-sheets-cell';
-import type { CellCreationMetadata } from '../grid-cell-types';
-import { attachDraftMeta, getDraftMeta, type DraftMeta } from '../row-model';
-import { suppressDraftIdText } from '../../grid-dom/use-sheets-content';
-import type { RelationInfo } from '../../store/relation-info-slice';
-
-import { assertOrUpdateGolden, projectSheetsCell } from './parity.harness';
-
-// ─────────────────────────────────────────────────────────────────────────────
-// PARITY GOLDEN — relation derivation + draft POST-PROCESSING (native pipeline).
-//
-// Focused battery over the two behaviors that decorate the raw factory output. The
-// committed `post-processing.golden.json` froze the v1 values; here we run each
-// case through the live NATIVE pipeline and assert it reproduces that golden:
-//
-// 1. RELATION label derivation (relation SheetsCell factory): belongsTo single
-// label from displayCandidates; belongsTo null; hasMany list longer than the
-// chip limit -> '+N' overflow chip; a label longer than the max length ->
-// truncation with an ellipsis. Captured through createSheetsCell +
-// projectSheetsCell (single relations carry data === displayData === label;
-// list relations carry chips in `data` with no display text -> displayText '',
-// copyText the JSON-stringified chips — the frozen v1 truth).
-//
-// 2. DRAFT suppression (use-sheets-content.suppressDraftIdText): the draft slice
-// stores `id = 'draft:'`; the rendered id cell would leak that raw string,
-// so the native suppressor BLANKS its display/data while preserving kind. Run
-// against the real exported helper + the real attachDraftMeta.
-//
-// Native draft VISUAL styling (styleHint.draft/error) is a flag the host paints
-// from, not part of the projected pair, so it is intentionally NOT routed here.
-// ─────────────────────────────────────────────────────────────────────────────
-
-const RELATION_CHIP_LIMIT_DEFAULT = 3; // DEFAULT_MAX_RELATION_CHIPS in the relation factory
-const RELATION_LABEL_MAX_DEFAULT = 24; // DEFAULT_RELATION_LABEL_MAX_LEN in the relation factory
-
-function makeMetadata(cellType: string, overrides?: Partial): CellCreationMetadata {
- return {
- cellType,
- fieldName: overrides?.fieldName ?? cellType,
- canEdit: true,
- isReadonly: false,
- activationBehavior: 'double-click',
- ...overrides,
- };
-}
-
-const BELONGS_TO: RelationInfo = {
- kind: 'belongsTo',
- relatedTable: 'users',
- relationField: 'author',
- foreignKeyField: 'authorId',
- displayCandidates: ['displayName', 'name'],
-};
-
-const HAS_MANY: RelationInfo = {
- kind: 'hasMany',
- relatedTable: 'comments',
- relationField: 'comments',
- foreignKeyField: 'postId',
- displayCandidates: ['title'],
-};
-
-// ── Relation battery ────────────────────────────────────────────────────────
-
-function relationRow(label: string, value: unknown, info: RelationInfo, relationOptions: Record = {}) {
- const metadata = makeMetadata('relation', { relationInfo: info, relationOptions });
- const cell = createSheetsCell(value, metadata);
- const { displayText, copyText } = projectSheetsCell(cell);
- return {
- label,
- typeKey: 'relation',
- kind: info.kind,
- value,
- relationOptions,
- displayText,
- copyText,
- };
-}
-
-const LONG_LABEL = 'A very long author display name that exceeds the limit'; // 53 chars > 24
-
-function buildRelationRows() {
- return [
- // belongsTo single -> label derived from displayCandidates (displayName wins over id)
- relationRow('belongsTo — label from displayName', { id: 'u1', displayName: 'Ada Lovelace' }, BELONGS_TO),
- // belongsTo single -> falls through to second candidate (name) when displayName absent
- relationRow('belongsTo — fallback to name candidate', { id: 'u2', name: 'Grace Hopper' }, BELONGS_TO),
- // belongsTo single -> id is LAST resort when no name-like candidate present
- relationRow('belongsTo — id last resort', { id: 'u3' }, BELONGS_TO),
- // belongsTo null -> empty label
- relationRow('belongsTo — null value', null, BELONGS_TO),
- // belongsTo scalar string -> used directly as label
- relationRow('belongsTo — scalar string value', 'plain-id', BELONGS_TO),
- // belongsTo draft placeholder -> suppressed to empty by deriveRelationLabel
- relationRow('belongsTo — draft: placeholder suppressed', 'draft:abc123', BELONGS_TO),
- relationRow('belongsTo — object id draft: suppressed', { id: 'draft:xyz' }, BELONGS_TO),
- // belongsTo label longer than max length -> truncated with ellipsis (default max 24)
- relationRow('belongsTo — label truncated at default max', { displayName: LONG_LABEL }, BELONGS_TO),
- // belongsTo label truncated at a SMALLER explicit max
- relationRow('belongsTo — label truncated at explicit max 8', { displayName: LONG_LABEL }, BELONGS_TO, {
- relationLabelMaxLength: 8,
- }),
- // hasMany within limit -> all chips, no overflow
- relationRow('hasMany — within chip limit', [{ title: 'one' }, { title: 'two' }], HAS_MANY),
- // hasMany LONGER than default chip limit (3) -> '+N' overflow chip
- relationRow(
- 'hasMany — overflow +N at default chip limit',
- [{ title: 'one' }, { title: 'two' }, { title: 'three' }, { title: 'four' }, { title: 'five' }],
- HAS_MANY,
- ),
- // hasMany overflow at an explicit SMALLER chip limit
- relationRow(
- 'hasMany — overflow +N at explicit chip limit 2',
- [{ title: 'one' }, { title: 'two' }, { title: 'three' }, { title: 'four' }],
- HAS_MANY,
- { relationChipLimit: 2 },
- ),
- // hasMany empty list -> empty bubble (no chips)
- relationRow('hasMany — empty list', [], HAS_MANY),
- // hasMany with per-item truncation inside chips
- relationRow(
- 'hasMany — per-chip truncation at explicit max 6',
- [{ title: LONG_LABEL }, { title: 'short' }],
- HAS_MANY,
- { relationLabelMaxLength: 6 },
- ),
- ];
-}
-
-// ── Draft suppression battery ─────────────────────────────────────────────────
-
-const DRAFT_ID = 'draft:k-001';
-const DRAFT_META: DraftMeta = { isDraft: true, draftRowId: DRAFT_ID, status: 'idle', errors: null };
-
-function draftRow(label: string, colKey: string, rawValue: unknown, cellType: string, draftMeta: DraftMeta) {
- // Attach draft meta to the ROW via the real (non-enumerable) helper, then read
- // it back exactly as use-sheets-content does — proving DRAFT_META survives and is
- // invisible to enumeration.
- const row = attachDraftMeta({ id: DRAFT_ID, [colKey]: rawValue }, draftMeta);
- const meta = getDraftMeta(row);
- const isDraft = Boolean(meta?.isDraft);
-
- const metadata = makeMetadata(cellType, { fieldName: colKey });
- const baseCell = createSheetsCell(rawValue, metadata);
-
- const suppressed = suppressDraftIdText(baseCell, {
- isDraftRow: isDraft,
- colKey,
- rawValue,
- draftId: meta?.draftRowId,
- });
-
- const before = projectSheetsCell(baseCell);
- const after = projectSheetsCell(suppressed);
-
- return {
- label,
- colKey,
- cellType,
- rawValue,
- isDraftRow: isDraft,
- // non-enumerable Symbol must NOT leak into row keys
- rowKeys: Object.keys(row),
- before,
- after,
- suppressed: before.displayText !== after.displayText || before.copyText !== after.copyText,
- };
-}
-
-function buildDraftRows() {
- return [
- // id column holding the raw draft: key -> BLANKED (the headline suppression)
- draftRow('draft id column — draft: key blanked', 'id', DRAFT_ID, 'text', DRAFT_META),
- // a non-id column whose value EQUALS the draft id -> also blanked
- draftRow('draft non-id column equal to draft id — blanked', 'parentId', DRAFT_ID, 'text', DRAFT_META),
- // a normal draft-row data column -> untouched (suppression is narrow)
- draftRow('draft normal column — untouched', 'name', 'Hello draft', 'text', DRAFT_META),
- // a draft row in error status with a normal value -> suppression still narrow (no blanking)
- draftRow('draft error-status column — untouched', 'title', 'Working title', 'text', {
- isDraft: true,
- draftRowId: DRAFT_ID,
- status: 'error',
- errors: { title: 'Required' },
- }),
- // id column with a NON-draft id value (server-shaped) -> NOT blanked
- draftRow('draft id column with server id — not blanked', 'id', 'server-id-42', 'text', DRAFT_META),
- ];
-}
-
-describe('PARITY — post-processing golden (relation derivation + draft suppression)', () => {
- it('pins the relation/draft constants this battery assumes', () => {
- expect(RELATION_CHIP_LIMIT_DEFAULT).toBe(3);
- expect(RELATION_LABEL_MAX_DEFAULT).toBe(24);
- });
-
- it('draft meta is non-enumerable on every draft row', () => {
- for (const row of buildDraftRows()) {
- expect(row.rowKeys).not.toContain('isDraft');
- expect(row.isDraftRow).toBe(true);
- }
- });
-
- it('matches the committed golden', () => {
- const golden = {
- relation: buildRelationRows(),
- draft: buildDraftRows(),
- };
- assertOrUpdateGolden('post-processing.golden', golden);
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/resolver.golden.json b/packages/sheets/src/grid/__golden__/resolver.golden.json
deleted file mode 100644
index 0131c12..0000000
--- a/packages/sheets/src/grid/__golden__/resolver.golden.json
+++ /dev/null
@@ -1,2243 +0,0 @@
-[
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String"
- }
- },
- "fieldName": "name",
- "label": "gql String -> text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int"
- }
- },
- "fieldName": "count",
- "label": "gql Int -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float"
- }
- },
- "fieldName": "ratio",
- "label": "gql Float -> number",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Boolean"
- }
- },
- "fieldName": "active",
- "label": "gql Boolean -> boolean",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "boolean",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "ID"
- }
- },
- "fieldName": "ref",
- "label": "gql ID -> uuid",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "DateTime"
- }
- },
- "fieldName": "at",
- "label": "gql DateTime -> datetime",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "datetime",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Datetime"
- }
- },
- "fieldName": "at2",
- "label": "gql Datetime -> datetime",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "datetime",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Date"
- }
- },
- "fieldName": "day",
- "label": "gql Date -> date",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "date",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Time"
- }
- },
- "fieldName": "clock",
- "label": "gql Time -> time",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "time",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON"
- }
- },
- "fieldName": "blob",
- "label": "gql JSON -> json",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "json",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSONObject"
- }
- },
- "fieldName": "obj",
- "label": "gql JSONObject -> json",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "json",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Upload"
- }
- },
- "fieldName": "doc",
- "label": "gql Upload -> file",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "file",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "URL"
- }
- },
- "fieldName": "link",
- "label": "gql URL -> url",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "url",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "EmailAddress"
- }
- },
- "fieldName": "mail",
- "label": "gql EmailAddress -> email",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "email",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "PhoneNumber"
- }
- },
- "fieldName": "tel",
- "label": "gql PhoneNumber -> phone",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "phone",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "UUID"
- }
- },
- "fieldName": "guid",
- "label": "gql UUID -> uuid",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "BigFloat"
- }
- },
- "fieldName": "big",
- "label": "gql BigFloat -> number",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "BigInt"
- }
- },
- "fieldName": "bigi",
- "label": "gql BigInt -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Relation"
- }
- },
- "fieldName": "owner",
- "label": "gql Relation -> relation",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "relation",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Interval"
- }
- },
- "fieldName": "dur",
- "label": "gql Interval -> interval",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "interval",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeometryGeometryCollection"
- }
- },
- "fieldName": "shapes",
- "label": "gql GeometryGeometryCollection -> geometry-collection",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-collection",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Mystery"
- }
- },
- "fieldName": "weird",
- "label": "gql unknown -> text (default)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String!"
- }
- },
- "fieldName": "req",
- "label": "gql non-null String! -> text (modifier stripped)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": ""
- }
- },
- "fieldName": "empty",
- "label": "gql empty string -> text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "subtype": "GeometryPoint"
- }
- },
- "fieldName": "pt",
- "label": "GeoJSON GeometryPoint -> geometry-point",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-point",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "subtype": "GeometryPolygon"
- }
- },
- "fieldName": "poly",
- "label": "GeoJSON GeometryPolygon -> geometry-collection",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-collection",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON"
- }
- },
- "fieldName": "geo",
- "label": "GeoJSON default -> geometry",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "subtype": "GeometryLine"
- }
- },
- "fieldName": "geo2",
- "label": "GeoJSON unrecognized subtype -> geometry",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "image"
- }
- },
- "fieldName": "pic",
- "label": "alias image -> image",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "image",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "file"
- }
- },
- "fieldName": "att",
- "label": "alias file -> file",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "file",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "video"
- }
- },
- "fieldName": "clip",
- "label": "alias video -> video",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "video",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "audio"
- }
- },
- "fieldName": "snd",
- "label": "alias audio -> audio",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "audio",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "upload"
- }
- },
- "fieldName": "up",
- "label": "alias upload -> upload",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "upload",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "relation"
- }
- },
- "fieldName": "rel",
- "label": "alias relation -> relation",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "relation",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "email"
- }
- },
- "fieldName": "em",
- "label": "alias email -> email",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "email",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "url"
- }
- },
- "fieldName": "u",
- "label": "alias url -> url",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "url",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "phone"
- }
- },
- "fieldName": "ph",
- "label": "alias phone -> phone",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "phone",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "citext"
- }
- },
- "fieldName": "ci",
- "label": "alias citext -> citext",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "citext",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "textarea"
- }
- },
- "fieldName": "ta",
- "label": "alias textarea -> textarea",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "textarea",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgAlias": "number"
- }
- },
- "fieldName": "n",
- "label": "alias number -> number",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgAlias": "currency"
- }
- },
- "fieldName": "price",
- "label": "alias currency -> currency",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "currency",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgAlias": "percentage"
- }
- },
- "fieldName": "pct",
- "label": "alias percentage -> percentage",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "percentage",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgAlias": "numeric"
- }
- },
- "fieldName": "num",
- "label": "alias numeric -> decimal",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "decimal",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgAlias": "decimal"
- }
- },
- "fieldName": "dec",
- "label": "alias decimal -> decimal",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "decimal",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgAlias": "int"
- }
- },
- "fieldName": "i",
- "label": "alias int -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgAlias": "integer"
- }
- },
- "fieldName": "i2",
- "label": "alias integer -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgAlias": "smallint"
- }
- },
- "fieldName": "si",
- "label": "alias smallint -> smallint",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "smallint",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Boolean",
- "pgAlias": "boolean"
- }
- },
- "fieldName": "b",
- "label": "alias boolean -> boolean",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "boolean",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Boolean",
- "pgAlias": "toggle"
- }
- },
- "fieldName": "tg",
- "label": "alias toggle -> toggle",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "toggle",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Date",
- "pgAlias": "date"
- }
- },
- "fieldName": "d",
- "label": "alias date -> date",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "date",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "DateTime",
- "pgAlias": "datetime"
- }
- },
- "fieldName": "dt",
- "label": "alias datetime -> datetime",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "datetime",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Time",
- "pgAlias": "time"
- }
- },
- "fieldName": "t",
- "label": "alias time -> time",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "time",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "DateTime",
- "pgAlias": "timestamptz"
- }
- },
- "fieldName": "tstz",
- "label": "alias timestamptz -> timestamptz",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "timestamptz",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Interval",
- "pgAlias": "interval"
- }
- },
- "fieldName": "iv",
- "label": "alias interval -> interval",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "interval",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "json"
- }
- },
- "fieldName": "j",
- "label": "alias json -> json",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "json",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "jsonb"
- }
- },
- "fieldName": "jb",
- "label": "alias jsonb -> jsonb",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "jsonb",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "inet"
- }
- },
- "fieldName": "ip",
- "label": "alias inet -> inet",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "inet",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "pgAlias": "geometry"
- }
- },
- "fieldName": "g",
- "label": "alias geometry -> geometry",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "pgAlias": "geometry-point"
- }
- },
- "fieldName": "gp",
- "label": "alias geometry-point -> geometry-point",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-point",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "GeoJSON",
- "pgAlias": "geometry-collection"
- }
- },
- "fieldName": "gc",
- "label": "alias geometry-collection -> geometry-collection",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-collection",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "color"
- }
- },
- "fieldName": "c",
- "label": "alias color -> color",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "color",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgAlias": "rating"
- }
- },
- "fieldName": "r",
- "label": "alias rating -> rating",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "rating",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "tags"
- }
- },
- "fieldName": "tg2",
- "label": "alias tags -> tags",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "tags",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "UUID",
- "pgAlias": "uuid"
- }
- },
- "fieldName": "uu",
- "label": "alias uuid -> uuid",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "tsvector"
- }
- },
- "fieldName": "search",
- "label": "alias tsvector -> tsvector (NON_EDITABLE + VIEWER_ONLY)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": false,
- "cellType": "tsvector",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "origin"
- }
- },
- "fieldName": "og",
- "label": "alias origin -> origin",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "origin",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "char"
- }
- },
- "fieldName": "ch",
- "label": "alias char -> bpchar",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "bpchar",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "bpchar"
- }
- },
- "fieldName": "bp",
- "label": "alias bpchar -> bpchar",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "bpchar",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "text"
- }
- },
- "fieldName": "tx",
- "label": "alias text -> text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "bit"
- }
- },
- "fieldName": "bt",
- "label": "alias bit -> bit",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "bit",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgAlias": "IMAGE"
- }
- },
- "fieldName": "pic2",
- "label": "alias UPPERCASE IMAGE -> image (case-insensitive)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "image",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgAlias": "zzz-not-real"
- }
- },
- "fieldName": "fall",
- "label": "alias unknown -> falls through to gqlType",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgAlias": "zzz",
- "pgType": "uuid"
- }
- },
- "fieldName": "fall2",
- "label": "alias unknown -> falls through to pgType",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "isArray": true,
- "pgAlias": "array"
- }
- },
- "fieldName": "arr",
- "label": "alias array -> array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "isArray": true,
- "pgAlias": "text-array"
- }
- },
- "fieldName": "ta_arr",
- "label": "alias text-array -> text-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "isArray": true,
- "pgAlias": "integer-array"
- }
- },
- "fieldName": "i_arr",
- "label": "alias integer-array -> integer-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "BigFloat",
- "isArray": true,
- "pgAlias": "number-array"
- }
- },
- "fieldName": "n_arr",
- "label": "alias number-array -> number-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "UUID",
- "isArray": true,
- "pgAlias": "uuid-array"
- }
- },
- "fieldName": "u_arr",
- "label": "alias uuid-array -> uuid-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Date",
- "isArray": true,
- "pgAlias": "date-array"
- }
- },
- "fieldName": "d_arr",
- "label": "alias date-array -> date-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "date-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "isArray": true,
- "pgAlias": "image"
- }
- },
- "fieldName": "pics",
- "label": "alias image WINS over isArray -> image",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "image",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "isArray": true
- }
- },
- "fieldName": "sarr",
- "label": "array String -> text-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "UUID",
- "isArray": true
- }
- },
- "fieldName": "uarr",
- "label": "array UUID -> uuid-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "BigFloat",
- "isArray": true
- }
- },
- "fieldName": "narr",
- "label": "array BigFloat -> number-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "isArray": true
- }
- },
- "fieldName": "iarr",
- "label": "array Int -> integer-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Date",
- "isArray": true
- }
- },
- "fieldName": "darr",
- "label": "array Date -> date-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "date-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Foo",
- "isArray": true
- }
- },
- "fieldName": "garr",
- "label": "array unknown base -> array (generic)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "[String]",
- "isArray": true
- }
- },
- "fieldName": "barr",
- "label": "array bracket notation [String] -> text-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "[Int!]!",
- "isArray": true
- }
- },
- "fieldName": "barr2",
- "label": "array bracket non-null [Int!]! -> integer-array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer-array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "varchar"
- }
- },
- "fieldName": "vc",
- "label": "pgType varchar -> text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "citext"
- }
- },
- "fieldName": "pgci",
- "label": "pgType citext -> citext",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "citext",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "bpchar"
- }
- },
- "fieldName": "pgbp",
- "label": "pgType bpchar -> bpchar",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "bpchar",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgType": "int4"
- }
- },
- "fieldName": "i4",
- "label": "pgType int4 -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int",
- "pgType": "int2"
- }
- },
- "fieldName": "i2pg",
- "label": "pgType int2 -> smallint",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "smallint",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "bigint"
- }
- },
- "fieldName": "bi",
- "label": "pgType bigint -> integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "numeric"
- }
- },
- "fieldName": "pgnum",
- "label": "pgType numeric -> decimal",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "decimal",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgType": "real"
- }
- },
- "fieldName": "rl",
- "label": "pgType real -> number",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Float",
- "pgType": "double precision"
- }
- },
- "fieldName": "dp",
- "label": "pgType double precision -> number",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "number",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "money"
- }
- },
- "fieldName": "mny",
- "label": "pgType money -> currency",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "currency",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Boolean",
- "pgType": "bool"
- }
- },
- "fieldName": "bl",
- "label": "pgType bool -> boolean",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "boolean",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "bit varying"
- }
- },
- "fieldName": "bv",
- "label": "pgType bit varying -> bit",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "bit",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "timestamp"
- }
- },
- "fieldName": "ts",
- "label": "pgType timestamp -> datetime",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "datetime",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "timestamptz"
- }
- },
- "fieldName": "tstz2",
- "label": "pgType timestamptz -> timestamptz",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "timestamptz",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "timetz"
- }
- },
- "fieldName": "ttz",
- "label": "pgType timetz -> time",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "time",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "interval"
- }
- },
- "fieldName": "ivpg",
- "label": "pgType interval -> interval",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "interval",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "JSON",
- "pgType": "jsonb"
- }
- },
- "fieldName": "jbpg",
- "label": "pgType jsonb -> jsonb",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "jsonb",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "uuid"
- }
- },
- "fieldName": "uupg",
- "label": "pgType uuid -> uuid",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "uuid",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "tsvector"
- }
- },
- "fieldName": "tsv",
- "label": "pgType tsvector -> tsvector (NON_EDITABLE)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": false,
- "cellType": "tsvector",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "cidr"
- }
- },
- "fieldName": "cidr",
- "label": "pgType cidr -> inet",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "inet",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "macaddr"
- }
- },
- "fieldName": "mac",
- "label": "pgType macaddr -> text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "point"
- }
- },
- "fieldName": "ptpg",
- "label": "pgType point -> geometry-point",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry-point",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "polygon"
- }
- },
- "fieldName": "polypg",
- "label": "pgType polygon -> geometry",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "geography"
- }
- },
- "fieldName": "geog",
- "label": "pgType geography -> geometry",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "geometry",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "email"
- }
- },
- "fieldName": "empg",
- "label": "pgType email -> email",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "email",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "origin"
- }
- },
- "fieldName": "ogpg",
- "label": "pgType origin -> origin",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "origin",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "_text"
- }
- },
- "fieldName": "txtarr",
- "label": "pgType _text -> array",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "array",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Boolean",
- "pgType": "zzz-not-real"
- }
- },
- "fieldName": "pgfall",
- "label": "pgType unknown -> falls through to gqlType",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "boolean",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "UUID"
- }
- },
- "fieldName": "id",
- "label": "readonly: id WITH gqlType UUID -> readonly uuid",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": false,
- "canEdit": false,
- "cellType": "uuid",
- "isReadonly": true
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "Int"
- }
- },
- "fieldName": "id",
- "label": "readonly: id WITHOUT UUID (Int) -> NOT readonly integer",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "integer",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String"
- }
- },
- "fieldName": "id",
- "label": "readonly: id String -> NOT readonly text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": null,
- "fieldName": "id",
- "label": "readonly: id with NO fieldMeta -> NOT readonly, text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "DateTime"
- }
- },
- "fieldName": "createdAt",
- "label": "readonly: createdAt -> readonly (always)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": false,
- "canEdit": false,
- "cellType": "datetime",
- "isReadonly": true
- }
- },
- {
- "fieldMeta": null,
- "fieldName": "createdAt",
- "label": "readonly: createdAt with NO fieldMeta -> readonly text",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": false,
- "canEdit": false,
- "cellType": "text",
- "isReadonly": true
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "DateTime"
- }
- },
- "fieldName": "updatedAt",
- "label": "readonly: updatedAt -> readonly (always)",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": false,
- "canEdit": false,
- "cellType": "datetime",
- "isReadonly": true
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String"
- }
- },
- "fieldName": "title",
- "label": "editable: normal field -> NOT readonly",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "col",
- "type": {
- "gqlType": "String",
- "pgType": "tsvector"
- }
- },
- "fieldName": "updatedAt",
- "label": "tsvector readonly-name interplay: updatedAt+tsvector",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": false,
- "cellType": "tsvector",
- "isReadonly": true
- }
- },
- {
- "fieldMeta": null,
- "fieldName": "whatever",
- "label": "undefined fieldMeta -> text default",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- },
- {
- "fieldMeta": {
- "name": "whatever2"
- },
- "fieldName": "whatever2",
- "label": "fieldMeta present but no .type -> text default",
- "resolution": {
- "activationBehavior": "double-click",
- "canActivate": true,
- "canEdit": true,
- "cellType": "text",
- "isReadonly": false
- }
- }
-]
diff --git a/packages/sheets/src/grid/__golden__/resolver.golden.test.ts b/packages/sheets/src/grid/__golden__/resolver.golden.test.ts
deleted file mode 100644
index 3be6e53..0000000
--- a/packages/sheets/src/grid/__golden__/resolver.golden.test.ts
+++ /dev/null
@@ -1,227 +0,0 @@
-/**
- * PHASE-0 GOLDEN — resolveCellType() schema-metadata -> cell-type pipeline.
- *
- * Pure data, no glide. Snapshots the CURRENT v1 behavior of
- * `resolveCellType(fieldName, fieldMeta)` for ~80 cases that exercise every
- * reachable branch of the resolution pipeline:
- *
- * resolveCellType
- * -> READONLY_CONDITIONS (id+UUID / createdAt / updatedAt)
- * -> CellRegistry.findByMatch (the runtime singleton is EMPTY at module
- * load — nothing registers entries — so this ALWAYS returns undefined and
- * the resolver ALWAYS falls through to mapToFrontendCellType. Captured
- * as-is; see `deviations`.)
- * -> mapToFrontendCellType (pgAlias > isArray > pgType > gqlType)
- * -> canEdit / canActivate / activationBehavior (NON_EDITABLE_TYPES +
- * VIEWER_ONLY_TYPES = {tsvector}; SINGLE_CLICK_CELL_TYPES is EMPTY so
- * activationBehavior is ALWAYS 'double-click').
- *
- * The golden is generated by the REAL resolver (UPDATE_GOLDEN=1), not by any
- * hand-predicted table, so it freezes actual behavior including bugs.
- */
-
-import { describe, expect, it } from 'vitest';
-
-import type { FieldMetadata } from '../../cell-types/cell-type-resolver';
-import { resolveCellType } from '../../cell-types/cell-type-resolver';
-
-import { assertOrUpdateGolden } from './parity.harness';
-
-type FieldType = FieldMetadata['type'];
-
-interface ResolverCase {
- label: string;
- fieldName: string;
- fieldMeta?: FieldMetadata;
-}
-
-/** Build a nested FieldMetadata for an ordinary (non-readonly) column name. */
-function meta(type: FieldType): FieldMetadata {
- return { name: 'col', type };
-}
-
-// ─── Case table — ~80 cases, grouped by which branch they exercise ──────────
-
-const CASES: ResolverCase[] = [
- // ── (A) gqlType fallback — every scalar branch of mapGraphQLTypeToCellType
- { label: 'gql String -> text', fieldName: 'name', fieldMeta: meta({ gqlType: 'String' }) },
- { label: 'gql Int -> integer', fieldName: 'count', fieldMeta: meta({ gqlType: 'Int' }) },
- { label: 'gql Float -> number', fieldName: 'ratio', fieldMeta: meta({ gqlType: 'Float' }) },
- { label: 'gql Boolean -> boolean', fieldName: 'active', fieldMeta: meta({ gqlType: 'Boolean' }) },
- { label: 'gql ID -> uuid', fieldName: 'ref', fieldMeta: meta({ gqlType: 'ID' }) },
- { label: 'gql DateTime -> datetime', fieldName: 'at', fieldMeta: meta({ gqlType: 'DateTime' }) },
- { label: 'gql Datetime -> datetime', fieldName: 'at2', fieldMeta: meta({ gqlType: 'Datetime' }) },
- { label: 'gql Date -> date', fieldName: 'day', fieldMeta: meta({ gqlType: 'Date' }) },
- { label: 'gql Time -> time', fieldName: 'clock', fieldMeta: meta({ gqlType: 'Time' }) },
- { label: 'gql JSON -> json', fieldName: 'blob', fieldMeta: meta({ gqlType: 'JSON' }) },
- { label: 'gql JSONObject -> json', fieldName: 'obj', fieldMeta: meta({ gqlType: 'JSONObject' }) },
- { label: 'gql Upload -> file', fieldName: 'doc', fieldMeta: meta({ gqlType: 'Upload' }) },
- { label: 'gql URL -> url', fieldName: 'link', fieldMeta: meta({ gqlType: 'URL' }) },
- { label: 'gql EmailAddress -> email', fieldName: 'mail', fieldMeta: meta({ gqlType: 'EmailAddress' }) },
- { label: 'gql PhoneNumber -> phone', fieldName: 'tel', fieldMeta: meta({ gqlType: 'PhoneNumber' }) },
- { label: 'gql UUID -> uuid', fieldName: 'guid', fieldMeta: meta({ gqlType: 'UUID' }) },
- { label: 'gql BigFloat -> number', fieldName: 'big', fieldMeta: meta({ gqlType: 'BigFloat' }) },
- { label: 'gql BigInt -> integer', fieldName: 'bigi', fieldMeta: meta({ gqlType: 'BigInt' }) },
- { label: 'gql Relation -> relation', fieldName: 'owner', fieldMeta: meta({ gqlType: 'Relation' }) },
- { label: 'gql Interval -> interval', fieldName: 'dur', fieldMeta: meta({ gqlType: 'Interval' }) },
- {
- label: 'gql GeometryGeometryCollection -> geometry-collection',
- fieldName: 'shapes',
- fieldMeta: meta({ gqlType: 'GeometryGeometryCollection' }),
- },
- { label: 'gql unknown -> text (default)', fieldName: 'weird', fieldMeta: meta({ gqlType: 'Mystery' }) },
- { label: 'gql non-null String! -> text (modifier stripped)', fieldName: 'req', fieldMeta: meta({ gqlType: 'String!' }) },
- { label: 'gql empty string -> text', fieldName: 'empty', fieldMeta: meta({ gqlType: '' }) },
-
- // ── (B) GeoJSON subtype branches
- { label: 'GeoJSON GeometryPoint -> geometry-point', fieldName: 'pt', fieldMeta: meta({ gqlType: 'GeoJSON', subtype: 'GeometryPoint' }) },
- { label: 'GeoJSON GeometryPolygon -> geometry-collection', fieldName: 'poly', fieldMeta: meta({ gqlType: 'GeoJSON', subtype: 'GeometryPolygon' }) },
- { label: 'GeoJSON default -> geometry', fieldName: 'geo', fieldMeta: meta({ gqlType: 'GeoJSON' }) },
- { label: 'GeoJSON unrecognized subtype -> geometry', fieldName: 'geo2', fieldMeta: meta({ gqlType: 'GeoJSON', subtype: 'GeometryLine' }) },
-
- // ── (C) pgAlias branch — every alias key (priority 1, even over arrays)
- { label: 'alias image -> image', fieldName: 'pic', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'image' }) },
- { label: 'alias file -> file', fieldName: 'att', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'file' }) },
- { label: 'alias video -> video', fieldName: 'clip', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'video' }) },
- { label: 'alias audio -> audio', fieldName: 'snd', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'audio' }) },
- { label: 'alias upload -> upload', fieldName: 'up', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'upload' }) },
- { label: 'alias relation -> relation', fieldName: 'rel', fieldMeta: meta({ gqlType: 'String', pgAlias: 'relation' }) },
- { label: 'alias email -> email', fieldName: 'em', fieldMeta: meta({ gqlType: 'String', pgAlias: 'email' }) },
- { label: 'alias url -> url', fieldName: 'u', fieldMeta: meta({ gqlType: 'String', pgAlias: 'url' }) },
- { label: 'alias phone -> phone', fieldName: 'ph', fieldMeta: meta({ gqlType: 'String', pgAlias: 'phone' }) },
- { label: 'alias citext -> citext', fieldName: 'ci', fieldMeta: meta({ gqlType: 'String', pgAlias: 'citext' }) },
- { label: 'alias textarea -> textarea', fieldName: 'ta', fieldMeta: meta({ gqlType: 'String', pgAlias: 'textarea' }) },
- { label: 'alias number -> number', fieldName: 'n', fieldMeta: meta({ gqlType: 'Float', pgAlias: 'number' }) },
- { label: 'alias currency -> currency', fieldName: 'price', fieldMeta: meta({ gqlType: 'Float', pgAlias: 'currency' }) },
- { label: 'alias percentage -> percentage', fieldName: 'pct', fieldMeta: meta({ gqlType: 'Float', pgAlias: 'percentage' }) },
- { label: 'alias numeric -> decimal', fieldName: 'num', fieldMeta: meta({ gqlType: 'Float', pgAlias: 'numeric' }) },
- { label: 'alias decimal -> decimal', fieldName: 'dec', fieldMeta: meta({ gqlType: 'Float', pgAlias: 'decimal' }) },
- { label: 'alias int -> integer', fieldName: 'i', fieldMeta: meta({ gqlType: 'Int', pgAlias: 'int' }) },
- { label: 'alias integer -> integer', fieldName: 'i2', fieldMeta: meta({ gqlType: 'Int', pgAlias: 'integer' }) },
- { label: 'alias smallint -> smallint', fieldName: 'si', fieldMeta: meta({ gqlType: 'Int', pgAlias: 'smallint' }) },
- { label: 'alias boolean -> boolean', fieldName: 'b', fieldMeta: meta({ gqlType: 'Boolean', pgAlias: 'boolean' }) },
- { label: 'alias toggle -> toggle', fieldName: 'tg', fieldMeta: meta({ gqlType: 'Boolean', pgAlias: 'toggle' }) },
- { label: 'alias date -> date', fieldName: 'd', fieldMeta: meta({ gqlType: 'Date', pgAlias: 'date' }) },
- { label: 'alias datetime -> datetime', fieldName: 'dt', fieldMeta: meta({ gqlType: 'DateTime', pgAlias: 'datetime' }) },
- { label: 'alias time -> time', fieldName: 't', fieldMeta: meta({ gqlType: 'Time', pgAlias: 'time' }) },
- { label: 'alias timestamptz -> timestamptz', fieldName: 'tstz', fieldMeta: meta({ gqlType: 'DateTime', pgAlias: 'timestamptz' }) },
- { label: 'alias interval -> interval', fieldName: 'iv', fieldMeta: meta({ gqlType: 'Interval', pgAlias: 'interval' }) },
- { label: 'alias json -> json', fieldName: 'j', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'json' }) },
- { label: 'alias jsonb -> jsonb', fieldName: 'jb', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'jsonb' }) },
- { label: 'alias inet -> inet', fieldName: 'ip', fieldMeta: meta({ gqlType: 'String', pgAlias: 'inet' }) },
- { label: 'alias geometry -> geometry', fieldName: 'g', fieldMeta: meta({ gqlType: 'GeoJSON', pgAlias: 'geometry' }) },
- { label: 'alias geometry-point -> geometry-point', fieldName: 'gp', fieldMeta: meta({ gqlType: 'GeoJSON', pgAlias: 'geometry-point' }) },
- { label: 'alias geometry-collection -> geometry-collection', fieldName: 'gc', fieldMeta: meta({ gqlType: 'GeoJSON', pgAlias: 'geometry-collection' }) },
- { label: 'alias color -> color', fieldName: 'c', fieldMeta: meta({ gqlType: 'String', pgAlias: 'color' }) },
- { label: 'alias rating -> rating', fieldName: 'r', fieldMeta: meta({ gqlType: 'Int', pgAlias: 'rating' }) },
- { label: 'alias tags -> tags', fieldName: 'tg2', fieldMeta: meta({ gqlType: 'String', pgAlias: 'tags' }) },
- { label: 'alias uuid -> uuid', fieldName: 'uu', fieldMeta: meta({ gqlType: 'UUID', pgAlias: 'uuid' }) },
- { label: 'alias tsvector -> tsvector (NON_EDITABLE + VIEWER_ONLY)', fieldName: 'search', fieldMeta: meta({ gqlType: 'String', pgAlias: 'tsvector' }) },
- { label: 'alias origin -> origin', fieldName: 'og', fieldMeta: meta({ gqlType: 'String', pgAlias: 'origin' }) },
- { label: 'alias char -> bpchar', fieldName: 'ch', fieldMeta: meta({ gqlType: 'String', pgAlias: 'char' }) },
- { label: 'alias bpchar -> bpchar', fieldName: 'bp', fieldMeta: meta({ gqlType: 'String', pgAlias: 'bpchar' }) },
- { label: 'alias text -> text', fieldName: 'tx', fieldMeta: meta({ gqlType: 'String', pgAlias: 'text' }) },
- { label: 'alias bit -> bit', fieldName: 'bt', fieldMeta: meta({ gqlType: 'String', pgAlias: 'bit' }) },
- { label: 'alias UPPERCASE IMAGE -> image (case-insensitive)', fieldName: 'pic2', fieldMeta: meta({ gqlType: 'JSON', pgAlias: 'IMAGE' }) },
- { label: 'alias unknown -> falls through to gqlType', fieldName: 'fall', fieldMeta: meta({ gqlType: 'Int', pgAlias: 'zzz-not-real' }) },
- { label: 'alias unknown -> falls through to pgType', fieldName: 'fall2', fieldMeta: meta({ gqlType: 'String', pgAlias: 'zzz', pgType: 'uuid' }) },
-
- // ── (D) pgAlias array keys (priority 1 beats the isArray branch)
- { label: 'alias array -> array', fieldName: 'arr', fieldMeta: meta({ gqlType: 'String', isArray: true, pgAlias: 'array' }) },
- { label: 'alias text-array -> text-array', fieldName: 'ta_arr', fieldMeta: meta({ gqlType: 'String', isArray: true, pgAlias: 'text-array' }) },
- { label: 'alias integer-array -> integer-array', fieldName: 'i_arr', fieldMeta: meta({ gqlType: 'Int', isArray: true, pgAlias: 'integer-array' }) },
- { label: 'alias number-array -> number-array', fieldName: 'n_arr', fieldMeta: meta({ gqlType: 'BigFloat', isArray: true, pgAlias: 'number-array' }) },
- { label: 'alias uuid-array -> uuid-array', fieldName: 'u_arr', fieldMeta: meta({ gqlType: 'UUID', isArray: true, pgAlias: 'uuid-array' }) },
- { label: 'alias date-array -> date-array', fieldName: 'd_arr', fieldMeta: meta({ gqlType: 'Date', isArray: true, pgAlias: 'date-array' }) },
- { label: 'alias image WINS over isArray -> image', fieldName: 'pics', fieldMeta: meta({ gqlType: 'String', isArray: true, pgAlias: 'image' }) },
-
- // ── (E) isArray branch (no pgAlias) — arrayTypeMap + generic fallback
- { label: 'array String -> text-array', fieldName: 'sarr', fieldMeta: meta({ gqlType: 'String', isArray: true }) },
- { label: 'array UUID -> uuid-array', fieldName: 'uarr', fieldMeta: meta({ gqlType: 'UUID', isArray: true }) },
- { label: 'array BigFloat -> number-array', fieldName: 'narr', fieldMeta: meta({ gqlType: 'BigFloat', isArray: true }) },
- { label: 'array Int -> integer-array', fieldName: 'iarr', fieldMeta: meta({ gqlType: 'Int', isArray: true }) },
- { label: 'array Date -> date-array', fieldName: 'darr', fieldMeta: meta({ gqlType: 'Date', isArray: true }) },
- { label: 'array unknown base -> array (generic)', fieldName: 'garr', fieldMeta: meta({ gqlType: 'Foo', isArray: true }) },
- { label: 'array bracket notation [String] -> text-array', fieldName: 'barr', fieldMeta: meta({ gqlType: '[String]', isArray: true }) },
- { label: 'array bracket non-null [Int!]! -> integer-array', fieldName: 'barr2', fieldMeta: meta({ gqlType: '[Int!]!', isArray: true }) },
-
- // ── (F) pgType branch (no pgAlias, not array) — mapBackendTypeToCellType
- { label: 'pgType varchar -> text', fieldName: 'vc', fieldMeta: meta({ gqlType: 'String', pgType: 'varchar' }) },
- { label: 'pgType citext -> citext', fieldName: 'pgci', fieldMeta: meta({ gqlType: 'String', pgType: 'citext' }) },
- { label: 'pgType bpchar -> bpchar', fieldName: 'pgbp', fieldMeta: meta({ gqlType: 'String', pgType: 'bpchar' }) },
- { label: 'pgType int4 -> integer', fieldName: 'i4', fieldMeta: meta({ gqlType: 'Int', pgType: 'int4' }) },
- { label: 'pgType int2 -> smallint', fieldName: 'i2pg', fieldMeta: meta({ gqlType: 'Int', pgType: 'int2' }) },
- { label: 'pgType bigint -> integer', fieldName: 'bi', fieldMeta: meta({ gqlType: 'String', pgType: 'bigint' }) },
- { label: 'pgType numeric -> decimal', fieldName: 'pgnum', fieldMeta: meta({ gqlType: 'String', pgType: 'numeric' }) },
- { label: 'pgType real -> number', fieldName: 'rl', fieldMeta: meta({ gqlType: 'Float', pgType: 'real' }) },
- { label: 'pgType double precision -> number', fieldName: 'dp', fieldMeta: meta({ gqlType: 'Float', pgType: 'double precision' }) },
- { label: 'pgType money -> currency', fieldName: 'mny', fieldMeta: meta({ gqlType: 'String', pgType: 'money' }) },
- { label: 'pgType bool -> boolean', fieldName: 'bl', fieldMeta: meta({ gqlType: 'Boolean', pgType: 'bool' }) },
- { label: 'pgType bit varying -> bit', fieldName: 'bv', fieldMeta: meta({ gqlType: 'String', pgType: 'bit varying' }) },
- { label: 'pgType timestamp -> datetime', fieldName: 'ts', fieldMeta: meta({ gqlType: 'String', pgType: 'timestamp' }) },
- { label: 'pgType timestamptz -> timestamptz', fieldName: 'tstz2', fieldMeta: meta({ gqlType: 'String', pgType: 'timestamptz' }) },
- { label: 'pgType timetz -> time', fieldName: 'ttz', fieldMeta: meta({ gqlType: 'String', pgType: 'timetz' }) },
- { label: 'pgType interval -> interval', fieldName: 'ivpg', fieldMeta: meta({ gqlType: 'String', pgType: 'interval' }) },
- { label: 'pgType jsonb -> jsonb', fieldName: 'jbpg', fieldMeta: meta({ gqlType: 'JSON', pgType: 'jsonb' }) },
- { label: 'pgType uuid -> uuid', fieldName: 'uupg', fieldMeta: meta({ gqlType: 'String', pgType: 'uuid' }) },
- { label: 'pgType tsvector -> tsvector (NON_EDITABLE)', fieldName: 'tsv', fieldMeta: meta({ gqlType: 'String', pgType: 'tsvector' }) },
- { label: 'pgType cidr -> inet', fieldName: 'cidr', fieldMeta: meta({ gqlType: 'String', pgType: 'cidr' }) },
- { label: 'pgType macaddr -> text', fieldName: 'mac', fieldMeta: meta({ gqlType: 'String', pgType: 'macaddr' }) },
- { label: 'pgType point -> geometry-point', fieldName: 'ptpg', fieldMeta: meta({ gqlType: 'String', pgType: 'point' }) },
- { label: 'pgType polygon -> geometry', fieldName: 'polypg', fieldMeta: meta({ gqlType: 'String', pgType: 'polygon' }) },
- { label: 'pgType geography -> geometry', fieldName: 'geog', fieldMeta: meta({ gqlType: 'String', pgType: 'geography' }) },
- { label: 'pgType email -> email', fieldName: 'empg', fieldMeta: meta({ gqlType: 'String', pgType: 'email' }) },
- { label: 'pgType origin -> origin', fieldName: 'ogpg', fieldMeta: meta({ gqlType: 'String', pgType: 'origin' }) },
- { label: 'pgType _text -> array', fieldName: 'txtarr', fieldMeta: meta({ gqlType: 'String', pgType: '_text' }) },
- { label: 'pgType unknown -> falls through to gqlType', fieldName: 'pgfall', fieldMeta: meta({ gqlType: 'Boolean', pgType: 'zzz-not-real' }) },
-
- // ── (G) READONLY matrix
- { label: 'readonly: id WITH gqlType UUID -> readonly uuid', fieldName: 'id', fieldMeta: meta({ gqlType: 'UUID' }) },
- { label: 'readonly: id WITHOUT UUID (Int) -> NOT readonly integer', fieldName: 'id', fieldMeta: meta({ gqlType: 'Int' }) },
- { label: 'readonly: id String -> NOT readonly text', fieldName: 'id', fieldMeta: meta({ gqlType: 'String' }) },
- { label: 'readonly: id with NO fieldMeta -> NOT readonly, text', fieldName: 'id', fieldMeta: undefined },
- { label: 'readonly: createdAt -> readonly (always)', fieldName: 'createdAt', fieldMeta: meta({ gqlType: 'DateTime' }) },
- { label: 'readonly: createdAt with NO fieldMeta -> readonly text', fieldName: 'createdAt', fieldMeta: undefined },
- { label: 'readonly: updatedAt -> readonly (always)', fieldName: 'updatedAt', fieldMeta: meta({ gqlType: 'DateTime' }) },
- { label: 'editable: normal field -> NOT readonly', fieldName: 'title', fieldMeta: meta({ gqlType: 'String' }) },
-
- // ── (H) tsvector locks (NON_EDITABLE_TYPES + VIEWER_ONLY_TYPES) — canActivate true, canEdit false
- { label: 'tsvector readonly-name interplay: updatedAt+tsvector', fieldName: 'updatedAt', fieldMeta: meta({ gqlType: 'String', pgType: 'tsvector' }) },
-
- // ── (I) undefined fieldMeta (and fieldMeta with no .type) -> default text
- { label: 'undefined fieldMeta -> text default', fieldName: 'whatever', fieldMeta: undefined },
- { label: 'fieldMeta present but no .type -> text default', fieldName: 'whatever2', fieldMeta: { name: 'whatever2' } },
-];
-
-describe('resolveCellType golden — schema-metadata -> cell-type pipeline', () => {
- const results = CASES.map((c) => ({
- label: c.label,
- fieldName: c.fieldName,
- fieldMeta: c.fieldMeta ?? null,
- resolution: resolveCellType(c.fieldName, c.fieldMeta),
- }));
-
- it('matches the committed golden', () => {
- assertOrUpdateGolden('resolver.golden', results);
- });
-
- it('every case has activationBehavior === double-click (locks the EMPTY single-click set)', () => {
- for (const r of results) {
- expect(r.resolution.activationBehavior, r.label).toBe('double-click');
- }
- });
-
- it('has at least ~80 cases', () => {
- expect(results.length).toBeGreaterThanOrEqual(80);
- });
-
- it('tsvector is non-editable but still activatable (viewer-only lock)', () => {
- // Reachable via alias and via pgType; both must lock the same way.
- for (const r of results.filter((x) => x.resolution.cellType === 'tsvector')) {
- expect(r.resolution.canEdit, `${r.label} canEdit`).toBe(false);
- // canActivate is canEdit || VIEWER_ONLY.has -> true, UNLESS a readonly
- // field-name ALSO forced canEdit false via isReadonly (still viewer-only).
- expect(r.resolution.canActivate, `${r.label} canActivate`).toBe(true);
- }
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/selection.golden.json b/packages/sheets/src/grid/__golden__/selection.golden.json
deleted file mode 100644
index ead4fb3..0000000
--- a/packages/sheets/src/grid/__golden__/selection.golden.json
+++ /dev/null
@@ -1,1054 +0,0 @@
-[
- {
- "name": "empty",
- "ops": [],
- "result": {
- "first": null,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": false
- },
- {
- "index": 1,
- "present": false
- },
- {
- "index": -1,
- "present": false
- }
- ],
- "items": [],
- "last": null,
- "length": 0
- }
- },
- {
- "name": "add-single-index",
- "ops": [
- {
- "index": 5,
- "op": "add"
- }
- ],
- "result": {
- "first": 5,
- "hasIndexProbes": [
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 6,
- "present": false
- }
- ],
- "items": [
- 5
- ],
- "last": 5,
- "length": 1
- }
- },
- {
- "name": "add-three-single-indices-out-of-order-stay-separate",
- "ops": [
- {
- "index": 5,
- "op": "add"
- },
- {
- "index": 1,
- "op": "add"
- },
- {
- "index": 3,
- "op": "add"
- }
- ],
- "result": {
- "first": 1,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": false
- },
- {
- "index": 1,
- "present": true
- },
- {
- "index": 2,
- "present": false
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 6,
- "present": false
- }
- ],
- "items": [
- 1,
- 3,
- 5
- ],
- "last": 5,
- "length": 3
- }
- },
- {
- "name": "add-range",
- "ops": [
- {
- "end": 5,
- "op": "addRange",
- "start": 2
- }
- ],
- "result": {
- "first": 2,
- "hasIndexProbes": [
- {
- "index": 1,
- "present": false
- },
- {
- "index": 2,
- "present": true
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 5,
- "present": false
- }
- ],
- "items": [
- 2,
- 3,
- 4
- ],
- "last": 4,
- "length": 3
- }
- },
- {
- "name": "add-adjacent-ranges-merge",
- "ops": [
- {
- "end": 3,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 5,
- "op": "addRange",
- "start": 3
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 2,
- "present": true
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 5,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 3,
- 4
- ],
- "last": 4,
- "length": 5
- }
- },
- {
- "name": "add-index-adjacent-to-range-merges",
- "ops": [
- {
- "end": 3,
- "op": "addRange",
- "start": 0
- },
- {
- "index": 3,
- "op": "add"
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 3
- ],
- "last": 3,
- "length": 4
- }
- },
- {
- "name": "add-overlapping-ranges-merge",
- "ops": [
- {
- "end": 4,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 6,
- "op": "addRange",
- "start": 2
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 6,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5
- ],
- "last": 5,
- "length": 6
- }
- },
- {
- "name": "add-contained-range-is-noop",
- "ops": [
- {
- "end": 10,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 5,
- "op": "addRange",
- "start": 3
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 9,
- "present": true
- },
- {
- "index": 10,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "last": 9,
- "length": 10
- }
- },
- {
- "name": "add-ranges-with-gap-stay-separate",
- "ops": [
- {
- "end": 2,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 7,
- "op": "addRange",
- "start": 5
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 1,
- "present": true
- },
- {
- "index": 2,
- "present": false
- },
- {
- "index": 3,
- "present": false
- },
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 6,
- "present": true
- },
- {
- "index": 7,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 5,
- 6
- ],
- "last": 6,
- "length": 4
- }
- },
- {
- "name": "remove-index-splits-range",
- "ops": [
- {
- "end": 10,
- "op": "addRange",
- "start": 0
- },
- {
- "index": 4,
- "op": "remove"
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 9,
- "present": true
- },
- {
- "index": 10,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 3,
- 5,
- 6,
- 7,
- 8,
- 9
- ],
- "last": 9,
- "length": 9
- }
- },
- {
- "name": "remove-range-splits-range",
- "ops": [
- {
- "end": 10,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 6,
- "op": "removeRange",
- "start": 3
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 2,
- "present": true
- },
- {
- "index": 3,
- "present": false
- },
- {
- "index": 5,
- "present": false
- },
- {
- "index": 6,
- "present": true
- },
- {
- "index": 9,
- "present": true
- }
- ],
- "items": [
- 0,
- 1,
- 2,
- 6,
- 7,
- 8,
- 9
- ],
- "last": 9,
- "length": 7
- }
- },
- {
- "name": "toggle-index-add-then-remove-empties",
- "ops": [
- {
- "index": 7,
- "op": "add"
- },
- {
- "index": 7,
- "op": "remove"
- }
- ],
- "result": {
- "first": null,
- "hasIndexProbes": [
- {
- "index": 6,
- "present": false
- },
- {
- "index": 7,
- "present": false
- },
- {
- "index": 8,
- "present": false
- }
- ],
- "items": [],
- "last": null,
- "length": 0
- }
- },
- {
- "name": "remove-entire-range-empties",
- "ops": [
- {
- "end": 3,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 3,
- "op": "removeRange",
- "start": 0
- }
- ],
- "result": {
- "first": null,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": false
- },
- {
- "index": 1,
- "present": false
- },
- {
- "index": 2,
- "present": false
- }
- ],
- "items": [],
- "last": null,
- "length": 0
- }
- },
- {
- "name": "remove-absent-index-is-noop",
- "ops": [
- {
- "end": 3,
- "op": "addRange",
- "start": 0
- },
- {
- "index": 5,
- "op": "remove"
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 2,
- "present": true
- },
- {
- "index": 5,
- "present": false
- }
- ],
- "items": [
- 0,
- 1,
- 2
- ],
- "last": 2,
- "length": 3
- }
- },
- {
- "name": "remove-trims-two-adjacent-ranges",
- "ops": [
- {
- "end": 3,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 7,
- "op": "addRange",
- "start": 4
- },
- {
- "end": 5,
- "op": "removeRange",
- "start": 2
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 1,
- "present": true
- },
- {
- "index": 2,
- "present": false
- },
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": true
- },
- {
- "index": 6,
- "present": true
- }
- ],
- "items": [
- 0,
- 1,
- 5,
- 6
- ],
- "last": 6,
- "length": 4
- }
- },
- {
- "name": "remove-spanning-three-ranges",
- "ops": [
- {
- "end": 2,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 6,
- "op": "addRange",
- "start": 4
- },
- {
- "end": 10,
- "op": "addRange",
- "start": 8
- },
- {
- "end": 9,
- "op": "removeRange",
- "start": 1
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 1,
- "present": false
- },
- {
- "index": 4,
- "present": false
- },
- {
- "index": 5,
- "present": false
- },
- {
- "index": 8,
- "present": true
- },
- {
- "index": 9,
- "present": true
- }
- ],
- "items": [
- 0,
- 8,
- 9
- ],
- "last": 9,
- "length": 3
- }
- },
- {
- "name": "offset-shifts-all-ranges",
- "ops": [
- {
- "end": 5,
- "op": "addRange",
- "start": 2
- },
- {
- "amount": 10,
- "op": "offset"
- }
- ],
- "result": {
- "first": 12,
- "hasIndexProbes": [
- {
- "index": 11,
- "present": false
- },
- {
- "index": 12,
- "present": true
- },
- {
- "index": 14,
- "present": true
- },
- {
- "index": 15,
- "present": false
- }
- ],
- "items": [
- 12,
- 13,
- 14
- ],
- "last": 14,
- "length": 3
- }
- },
- {
- "name": "offset-zero-is-identity",
- "ops": [
- {
- "index": 3,
- "op": "add"
- },
- {
- "amount": 0,
- "op": "offset"
- }
- ],
- "result": {
- "first": 3,
- "hasIndexProbes": [
- {
- "index": 2,
- "present": false
- },
- {
- "index": 3,
- "present": true
- },
- {
- "index": 4,
- "present": false
- }
- ],
- "items": [
- 3
- ],
- "last": 3,
- "length": 1
- }
- },
- {
- "name": "offset-negative-shift",
- "ops": [
- {
- "end": 15,
- "op": "addRange",
- "start": 12
- },
- {
- "amount": -10,
- "op": "offset"
- }
- ],
- "result": {
- "first": 2,
- "hasIndexProbes": [
- {
- "index": 1,
- "present": false
- },
- {
- "index": 2,
- "present": true
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 5,
- "present": false
- }
- ],
- "items": [
- 2,
- 3,
- 4
- ],
- "last": 4,
- "length": 3
- }
- },
- {
- "name": "from-single-index",
- "ops": [
- {
- "index": 7,
- "op": "fromSingleIndex"
- }
- ],
- "result": {
- "first": 7,
- "hasIndexProbes": [
- {
- "index": 6,
- "present": false
- },
- {
- "index": 7,
- "present": true
- },
- {
- "index": 8,
- "present": false
- }
- ],
- "items": [
- 7
- ],
- "last": 7,
- "length": 1
- }
- },
- {
- "name": "from-single-range",
- "ops": [
- {
- "end": 5,
- "op": "fromSingleRange",
- "start": 2
- }
- ],
- "result": {
- "first": 2,
- "hasIndexProbes": [
- {
- "index": 1,
- "present": false
- },
- {
- "index": 2,
- "present": true
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 5,
- "present": false
- }
- ],
- "items": [
- 2,
- 3,
- 4
- ],
- "last": 4,
- "length": 3
- }
- },
- {
- "name": "from-single-index-then-add-resets-baseline",
- "ops": [
- {
- "index": 99,
- "op": "add"
- },
- {
- "index": 2,
- "op": "fromSingleIndex"
- },
- {
- "index": 4,
- "op": "add"
- }
- ],
- "result": {
- "first": 2,
- "hasIndexProbes": [
- {
- "index": 2,
- "present": true
- },
- {
- "index": 3,
- "present": false
- },
- {
- "index": 4,
- "present": true
- },
- {
- "index": 99,
- "present": false
- }
- ],
- "items": [
- 2,
- 4
- ],
- "last": 4,
- "length": 2
- }
- },
- {
- "name": "large-range-0-to-10000",
- "ops": [
- {
- "end": 10000,
- "op": "addRange",
- "start": 0
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": -1,
- "present": false
- },
- {
- "index": 0,
- "present": true
- },
- {
- "index": 1,
- "present": true
- },
- {
- "index": 5000,
- "present": true
- },
- {
- "index": 9998,
- "present": true
- },
- {
- "index": 9999,
- "present": true
- },
- {
- "index": 10000,
- "present": false
- }
- ],
- "last": 9999,
- "length": 10000
- }
- },
- {
- "name": "large-range-split-by-remove",
- "ops": [
- {
- "end": 10000,
- "op": "addRange",
- "start": 0
- },
- {
- "end": 6000,
- "op": "removeRange",
- "start": 4000
- }
- ],
- "result": {
- "first": 0,
- "hasIndexProbes": [
- {
- "index": 0,
- "present": true
- },
- {
- "index": 3999,
- "present": true
- },
- {
- "index": 4000,
- "present": false
- },
- {
- "index": 5000,
- "present": false
- },
- {
- "index": 5999,
- "present": false
- },
- {
- "index": 6000,
- "present": true
- },
- {
- "index": 9999,
- "present": true
- }
- ],
- "last": 9999,
- "length": 8000
- }
- }
-]
diff --git a/packages/sheets/src/grid/__golden__/selection.golden.test.ts b/packages/sheets/src/grid/__golden__/selection.golden.test.ts
deleted file mode 100644
index df2d4b2..0000000
--- a/packages/sheets/src/grid/__golden__/selection.golden.test.ts
+++ /dev/null
@@ -1,389 +0,0 @@
-/**
- * Canonical behavioral spec for selection/range-set.ts (Phase 6). The native
- * RangeSet MUST reproduce every (ops -> result) here. RangeSet is canonical;
- * TanStack rowSelection is only a one-way derived mirror.
- *
- * ──────────────────────────────────────────────────────────────────────────
- * WHAT THIS GOLDEN FREEZES
- *
- * The committed `selection.golden.json` was captured from glide's
- * `CompactSelection` — the reference the grid relied on pre-cutover. The native
- * {@link RangeSet} REPLACES it, and exposes the same small surface the grid reads:
- *
- * - `selection.rows.toArray()` -> selected row indices, ascending
- * - `selection.rows.toArray().length` / `selection.rows.length` -> selected count
- * - `hasIndex`, `first`, `last`, `offset`, `add`, `remove`, `fromSingleSelection`
- * -> the construction/mutation ops used to build the value the grid reads.
- *
- * Each named case is an `ops` PROGRAM (a serializable op list) starting from
- * `RangeSet.empty()`. The SAME op list is both (a) the committed spec and (b) the
- * executable input here, so the recorded `result` provably derives from those ops
- * — there is no hand-transcribed expectation to drift.
- *
- * RangeSet re-runs these exact op programs through its own interpreter and MUST
- * produce the byte-identical `result` objects the frozen golden holds. This file
- * IS the RangeSet contract.
- *
- * NOTE — the frozen golden captures glide's quirks AS-IS, which RangeSet faithfully
- * reproduces (see `deviations`):
- * - ADJACENCY MERGES. `add([0,3])` then `add([3,5])` -> a single `[0,5)` range
- * (mergeRanges treats touching ranges as joinable). Likewise `add([0,3])`
- * then `add(3)` -> `[0,4)`. The RangeSet must merge on touch, not only on
- * overlap.
- * - remove() SPLICES DURING ITERATION. `remove` mutates `items` in place while
- * looping `items.entries()`. For the multi-range removals captured here the
- * observable result is still the set-theoretic difference; the contract is the
- * RESULT, and the result is what RangeSet must match. (Case
- * "remove-spanning-three-ranges" exercises the path that fully drops a middle
- * range mid-iteration.)
- * - `first()`/`last()` on empty -> `undefined` (NOT -1, NOT 0). Recorded as the
- * JSON value `null` after serialization.
- */
-
-import { describe, it } from 'vitest';
-
-import { RangeSet } from '../../selection/range-set';
-
-import { assertOrUpdateGolden } from './parity.harness';
-
-// ─── Serializable op vocabulary ─────────────────────────────────────────────
-//
-// Every op is a plain JSON object: this is exactly what gets written into the
-// golden, AND what the interpreter below executes over the native RangeSet.
-
-type Op =
- | { op: 'add'; index: number } // add(number) -> covers [index, index+1)
- | { op: 'addRange'; start: number; end: number } // add([start, end))
- | { op: 'remove'; index: number } // remove(number)
- | { op: 'removeRange'; start: number; end: number } // remove([start, end))
- | { op: 'offset'; amount: number } // offset(amount)
- | { op: 'fromSingleIndex'; index: number } // RESET to fromSingleSelection(index)
- | { op: 'fromSingleRange'; start: number; end: number }; // RESET to fromSingleSelection([start,end))
-
-/**
- * Run an op PROGRAM against the native {@link RangeSet}, starting from `empty()`.
- * `fromSingle*` ops RESET the accumulator to a fresh single-selection (mirroring
- * how a selection is built from one click), every other op threads the immutable
- * result forward. RangeSet must reproduce the frozen golden these ops generate.
- */
-function runOps(ops: Op[]): RangeSet {
- let sel = RangeSet.empty();
- for (const o of ops) {
- switch (o.op) {
- case 'add':
- sel = sel.add(o.index);
- break;
- case 'addRange':
- sel = sel.add([o.start, o.end]);
- break;
- case 'remove':
- sel = sel.remove(o.index);
- break;
- case 'removeRange':
- sel = sel.remove([o.start, o.end]);
- break;
- case 'offset':
- sel = sel.offset(o.amount);
- break;
- case 'fromSingleIndex':
- sel = RangeSet.fromSingleSelection(o.index);
- break;
- case 'fromSingleRange':
- sel = RangeSet.fromSingleSelection([o.start, o.end]);
- break;
- }
- }
- return sel;
-}
-
-interface HasIndexProbe {
- index: number;
- present: boolean;
-}
-
-interface SequenceResult {
- /** Materialized selected indices (ascending). OMITTED for the huge case. */
- items?: number[];
- /** Selected count (== items.length for finite cases; the value the controls show). */
- length: number;
- /** first() — start of the lowest range, or null when empty. */
- first: number | null;
- /** last() — last selected index, or null when empty. */
- last: number | null;
- /** Membership probes at chosen boundary/inside/outside indices. */
- hasIndexProbes: HasIndexProbe[];
-}
-
-interface GoldenSequence {
- name: string;
- ops: Op[];
- result: SequenceResult;
-}
-
-/**
- * Build a recorded result from a selection. `probeIndices` chooses which
- * `hasIndex` boundaries to pin. `sampleItems=false` omits the materialized array
- * (used ONLY for the 10k case, where `length`+`first`+`last`+probes fully pin
- * behavior without dumping ten thousand entries).
- */
-function record(sel: RangeSet, probeIndices: number[], sampleItems = true): SequenceResult {
- const first = sel.first();
- const last = sel.last();
- const result: SequenceResult = {
- length: sel.length,
- first: first === undefined ? null : first,
- last: last === undefined ? null : last,
- hasIndexProbes: probeIndices.map((index) => ({ index, present: sel.hasIndex(index) })),
- };
- if (sampleItems) result.items = sel.toArray();
- return result;
-}
-
-// ─── The op-sequence battery ────────────────────────────────────────────────
-
-interface CaseSpec {
- name: string;
- ops: Op[];
- probes: number[];
- sampleItems?: boolean;
-}
-
-const CASES: CaseSpec[] = [
- // — empties / single index —
- {
- name: 'empty',
- ops: [],
- probes: [0, 1, -1],
- },
- {
- name: 'add-single-index',
- ops: [{ op: 'add', index: 5 }],
- probes: [4, 5, 6],
- },
- {
- name: 'add-three-single-indices-out-of-order-stay-separate',
- // 5,1,3 -> ascending, three width-1 ranges (no merge: they are not adjacent)
- ops: [
- { op: 'add', index: 5 },
- { op: 'add', index: 1 },
- { op: 'add', index: 3 },
- ],
- probes: [0, 1, 2, 3, 4, 5, 6],
- },
-
- // — range add —
- {
- name: 'add-range',
- // add([2,5)) -> indices 2,3,4 (end-exclusive)
- ops: [{ op: 'addRange', start: 2, end: 5 }],
- probes: [1, 2, 3, 4, 5],
- },
-
- // — adjacency merge (QUIRK: touching ranges merge) —
- {
- name: 'add-adjacent-ranges-merge',
- // [0,3) then [3,5) -> single [0,5)
- ops: [
- { op: 'addRange', start: 0, end: 3 },
- { op: 'addRange', start: 3, end: 5 },
- ],
- probes: [0, 2, 3, 4, 5],
- },
- {
- name: 'add-index-adjacent-to-range-merges',
- // [0,3) then add(3) -> single [0,4)
- ops: [
- { op: 'addRange', start: 0, end: 3 },
- { op: 'add', index: 3 },
- ],
- probes: [0, 3, 4],
- },
-
- // — overlap merge —
- {
- name: 'add-overlapping-ranges-merge',
- // [0,4) then [2,6) -> single [0,6)
- ops: [
- { op: 'addRange', start: 0, end: 4 },
- { op: 'addRange', start: 2, end: 6 },
- ],
- probes: [0, 3, 5, 6],
- },
- {
- name: 'add-contained-range-is-noop',
- // [0,10) then [3,5) (fully inside) -> still [0,10)
- ops: [
- { op: 'addRange', start: 0, end: 10 },
- { op: 'addRange', start: 3, end: 5 },
- ],
- probes: [0, 4, 9, 10],
- },
-
- // — gap (NO merge) —
- {
- name: 'add-ranges-with-gap-stay-separate',
- // [0,2) then [5,7) -> two ranges
- ops: [
- { op: 'addRange', start: 0, end: 2 },
- { op: 'addRange', start: 5, end: 7 },
- ],
- probes: [0, 1, 2, 3, 4, 5, 6, 7],
- },
-
- // — remove that splits a range —
- {
- name: 'remove-index-splits-range',
- // [0,10) remove(4) -> [0,4) + [5,10)
- ops: [
- { op: 'addRange', start: 0, end: 10 },
- { op: 'remove', index: 4 },
- ],
- probes: [3, 4, 5, 9, 10],
- },
- {
- name: 'remove-range-splits-range',
- // [0,10) remove([3,6)) -> [0,3) + [6,10)
- ops: [
- { op: 'addRange', start: 0, end: 10 },
- { op: 'removeRange', start: 3, end: 6 },
- ],
- probes: [2, 3, 5, 6, 9],
- },
-
- // — toggle (add then remove the same index) —
- {
- name: 'toggle-index-add-then-remove-empties',
- // add(7) then remove(7) -> empty
- ops: [
- { op: 'add', index: 7 },
- { op: 'remove', index: 7 },
- ],
- probes: [6, 7, 8],
- },
- {
- name: 'remove-entire-range-empties',
- // [0,3) remove([0,3)) -> empty
- ops: [
- { op: 'addRange', start: 0, end: 3 },
- { op: 'removeRange', start: 0, end: 3 },
- ],
- probes: [0, 1, 2],
- },
- {
- name: 'remove-absent-index-is-noop',
- // [0,3) remove(5) -> still [0,3)
- ops: [
- { op: 'addRange', start: 0, end: 3 },
- { op: 'remove', index: 5 },
- ],
- probes: [0, 2, 5],
- },
-
- // — remove across multiple ranges (splice-during-iteration path) —
- {
- name: 'remove-trims-two-adjacent-ranges',
- // [0,3) + [4,7) remove([2,5)) -> [0,2) + [5,7)
- ops: [
- { op: 'addRange', start: 0, end: 3 },
- { op: 'addRange', start: 4, end: 7 },
- { op: 'removeRange', start: 2, end: 5 },
- ],
- probes: [0, 1, 2, 4, 5, 6],
- },
- {
- name: 'remove-spanning-three-ranges',
- // [0,2) + [4,6) + [8,10) remove([1,9)) -> [0,1) + [8,10)
- // (middle range [4,6) fully dropped mid-iteration — the splice-while-looping path)
- ops: [
- { op: 'addRange', start: 0, end: 2 },
- { op: 'addRange', start: 4, end: 6 },
- { op: 'addRange', start: 8, end: 10 },
- { op: 'removeRange', start: 1, end: 9 },
- ],
- probes: [0, 1, 4, 5, 8, 9],
- },
-
- // — offset —
- {
- name: 'offset-shifts-all-ranges',
- // [2,5) offset(+10) -> [12,15)
- ops: [
- { op: 'addRange', start: 2, end: 5 },
- { op: 'offset', amount: 10 },
- ],
- probes: [11, 12, 14, 15],
- },
- {
- name: 'offset-zero-is-identity',
- // add(3) offset(0) -> still [3,4)
- ops: [
- { op: 'add', index: 3 },
- { op: 'offset', amount: 0 },
- ],
- probes: [2, 3, 4],
- },
- {
- name: 'offset-negative-shift',
- // [12,15) offset(-10) -> [2,5)
- ops: [
- { op: 'addRange', start: 12, end: 15 },
- { op: 'offset', amount: -10 },
- ],
- probes: [1, 2, 4, 5],
- },
-
- // — fromSingleSelection constructors (RESET semantics) —
- {
- name: 'from-single-index',
- // fromSingleSelection(7) -> [7,8)
- ops: [{ op: 'fromSingleIndex', index: 7 }],
- probes: [6, 7, 8],
- },
- {
- name: 'from-single-range',
- // fromSingleSelection([2,5)) -> [2,5)
- ops: [{ op: 'fromSingleRange', start: 2, end: 5 }],
- probes: [1, 2, 4, 5],
- },
- {
- name: 'from-single-index-then-add-resets-baseline',
- // fromSingleSelection(2) RESETS, then add(4) -> [2,3) + [4,5)
- ops: [
- { op: 'add', index: 99 }, // discarded by the reset below
- { op: 'fromSingleIndex', index: 2 },
- { op: 'add', index: 4 },
- ],
- probes: [2, 3, 4, 99],
- },
-
- // — large range: record length/first/last + sampled probes only (NO 10k dump) —
- {
- name: 'large-range-0-to-10000',
- // add([0,10000)) -> length 10000, first 0, last 9999; probe the boundaries.
- ops: [{ op: 'addRange', start: 0, end: 10000 }],
- probes: [-1, 0, 1, 5000, 9998, 9999, 10000],
- sampleItems: false,
- },
- {
- name: 'large-range-split-by-remove',
- // add([0,10000)) remove([4000,6000)) -> [0,4000) + [6000,10000); length 8000.
- ops: [
- { op: 'addRange', start: 0, end: 10000 },
- { op: 'removeRange', start: 4000, end: 6000 },
- ],
- probes: [0, 3999, 4000, 5000, 5999, 6000, 9999],
- sampleItems: false,
- },
-];
-
-describe('selection golden — native RangeSet behavioral spec', () => {
- it('reproduces every (ops -> result) the frozen golden froze', () => {
- const sequences: GoldenSequence[] = CASES.map(({ name, ops, probes, sampleItems }) => ({
- name,
- ops,
- result: record(runOps(ops), probes, sampleItems !== false),
- }));
-
- assertOrUpdateGolden('selection.golden', sequences);
- });
-});
diff --git a/packages/sheets/src/grid/__golden__/sheets-dom.golden.json b/packages/sheets/src/grid/__golden__/sheets-dom.golden.json
deleted file mode 100644
index 4882794..0000000
--- a/packages/sheets/src/grid/__golden__/sheets-dom.golden.json
+++ /dev/null
@@ -1,3038 +0,0 @@
-[
- {
- "cellType": "uuid",
- "cells": [
- {
- "copyText": "00fb8673-8b42-4c83-5484-f3e32248c1e8",
- "displayText": "00fb8673-8b42-4c83-5484-f3e32248c1e8",
- "row": 0
- },
- {
- "copyText": "e47eac5e-fd02-4c11-e494-cb07f116cb47",
- "displayText": "e47eac5e-fd02-4c11-e494-cb07f116cb47",
- "row": 1
- },
- {
- "copyText": "6407cd8b-ff5d-4dce-bb54-c5c09937ae40",
- "displayText": "6407cd8b-ff5d-4dce-bb54-c5c09937ae40",
- "row": 2
- },
- {
- "copyText": "61a22780-4f9c-4ea6-d7c6-1d2233c08581",
- "displayText": "61a22780-4f9c-4ea6-d7c6-1d2233c08581",
- "row": 3
- },
- {
- "copyText": "6de45a09-e593-4c42-25a8-83bc7358b18f",
- "displayText": "6de45a09-e593-4c42-25a8-83bc7358b18f",
- "row": 4
- },
- {
- "copyText": "6ba704b7-7bb2-49b3-a28e-b2a4ba7a1653",
- "displayText": "6ba704b7-7bb2-49b3-a28e-b2a4ba7a1653",
- "row": 5
- },
- {
- "copyText": "8608258a-b3a6-447e-2420-a4d3df2491fe",
- "displayText": "8608258a-b3a6-447e-2420-a4d3df2491fe",
- "row": 6
- },
- {
- "copyText": "37760c69-c30f-491c-fd6f-2fdf61f7c21e",
- "displayText": "37760c69-c30f-491c-fd6f-2fdf61f7c21e",
- "row": 7
- },
- {
- "copyText": "1d2c49c3-ee8a-4918-f938-82c42193f22c",
- "displayText": "1d2c49c3-ee8a-4918-f938-82c42193f22c",
- "row": 8
- },
- {
- "copyText": "11fcefca-f13a-4adf-c5ca-15d01efebcce",
- "displayText": "11fcefca-f13a-4adf-c5ca-15d01efebcce",
- "row": 9
- },
- {
- "copyText": "5cb8ebab-30bf-4072-0dad-da811b0a9104",
- "displayText": "5cb8ebab-30bf-4072-0dad-da811b0a9104",
- "row": 10
- },
- {
- "copyText": "b92351a8-e942-418b-d42d-19ea3c46bdc3",
- "displayText": "b92351a8-e942-418b-d42d-19ea3c46bdc3",
- "row": 11
- }
- ],
- "field": "id"
- },
- {
- "cellType": "text",
- "cells": [
- {
- "copyText": "golf golf",
- "displayText": "golf golf",
- "row": 0
- },
- {
- "copyText": "bravo echo",
- "displayText": "bravo echo",
- "row": 1
- },
- {
- "copyText": "foxtrot echo",
- "displayText": "foxtrot echo",
- "row": 2
- },
- {
- "copyText": "alpha alpha",
- "displayText": "alpha alpha",
- "row": 3
- },
- {
- "copyText": "foxtrot foxtrot",
- "displayText": "foxtrot foxtrot",
- "row": 4
- },
- {
- "copyText": "foxtrot bravo",
- "displayText": "foxtrot bravo",
- "row": 5
- },
- {
- "copyText": "bravo golf",
- "displayText": "bravo golf",
- "row": 6
- },
- {
- "copyText": "alpha india",
- "displayText": "alpha india",
- "row": 7
- },
- {
- "copyText": "golf bravo",
- "displayText": "golf bravo",
- "row": 8
- },
- {
- "copyText": "golf alpha",
- "displayText": "golf alpha",
- "row": 9
- },
- {
- "copyText": "juliet echo",
- "displayText": "juliet echo",
- "row": 10
- },
- {
- "copyText": "foxtrot hotel",
- "displayText": "foxtrot hotel",
- "row": 11
- }
- ],
- "field": "text"
- },
- {
- "cellType": "textarea",
- "cells": [
- {
- "copyText": "juliet\ngolf juliet",
- "displayText": "juliet\ngolf juliet",
- "row": 0
- },
- {
- "copyText": "echo\nfoxtrot bravo",
- "displayText": "echo\nfoxtrot bravo",
- "row": 1
- },
- {
- "copyText": "alpha\nalpha echo",
- "displayText": "alpha\nalpha echo",
- "row": 2
- },
- {
- "copyText": "hotel\ncharlie charlie",
- "displayText": "hotel\ncharlie charlie",
- "row": 3
- },
- {
- "copyText": "juliet\ngolf india",
- "displayText": "juliet\ngolf india",
- "row": 4
- },
- {
- "copyText": "alpha\njuliet india",
- "displayText": "alpha\njuliet india",
- "row": 5
- },
- {
- "copyText": "echo\nhotel golf",
- "displayText": "echo\nhotel golf",
- "row": 6
- },
- {
- "copyText": "foxtrot\nalpha hotel",
- "displayText": "foxtrot\nalpha hotel",
- "row": 7
- },
- {
- "copyText": "india\ngolf echo",
- "displayText": "india\ngolf echo",
- "row": 8
- },
- {
- "copyText": "bravo\necho delta",
- "displayText": "bravo\necho delta",
- "row": 9
- },
- {
- "copyText": "golf\ngolf bravo",
- "displayText": "golf\ngolf bravo",
- "row": 10
- },
- {
- "copyText": "india\ndelta hotel",
- "displayText": "india\ndelta hotel",
- "row": 11
- }
- ],
- "field": "textarea"
- },
- {
- "cellType": "email",
- "cells": [
- {
- "copyText": "mailto:edsger.lovelace@example.com",
- "displayText": "edsger.lovelace@example.com",
- "row": 0
- },
- {
- "copyText": "mailto:ken.torvalds@example.com",
- "displayText": "ken.torvalds@example.com",
- "row": 1
- },
- {
- "copyText": "mailto:alan.liskov@example.com",
- "displayText": "alan.liskov@example.com",
- "row": 2
- },
- {
- "copyText": "mailto:barbara.ritchie@example.com",
- "displayText": "barbara.ritchie@example.com",
- "row": 3
- },
- {
- "copyText": "mailto:ken.turing@example.com",
- "displayText": "ken.turing@example.com",
- "row": 4
- },
- {
- "copyText": "mailto:alan.thompson@example.com",
- "displayText": "alan.thompson@example.com",
- "row": 5
- },
- {
- "copyText": "mailto:margaret.ritchie@example.com",
- "displayText": "margaret.ritchie@example.com",
- "row": 6
- },
- {
- "copyText": "mailto:margaret.knuth@example.com",
- "displayText": "margaret.knuth@example.com",
- "row": 7
- },
- {
- "copyText": "mailto:grace.hopper@example.com",
- "displayText": "grace.hopper@example.com",
- "row": 8
- },
- {
- "copyText": "mailto:edsger.turing@example.com",
- "displayText": "edsger.turing@example.com",
- "row": 9
- },
- {
- "copyText": "mailto:grace.thompson@example.com",
- "displayText": "grace.thompson@example.com",
- "row": 10
- },
- {
- "copyText": "mailto:edsger.lovelace@example.com",
- "displayText": "edsger.lovelace@example.com",
- "row": 11
- }
- ],
- "field": "email"
- },
- {
- "cellType": "url",
- "cells": [
- {
- "copyText": "https://example.com/bravo/0.html",
- "displayText": "https://example.com/bravo/0.html",
- "row": 0
- },
- {
- "copyText": "https://example.com/golf/1.html",
- "displayText": "https://example.com/golf/1.html",
- "row": 1
- },
- {
- "copyText": "https://example.com/hotel/2.html",
- "displayText": "https://example.com/hotel/2.html",
- "row": 2
- },
- {
- "copyText": "https://example.com/charlie/3.html",
- "displayText": "https://example.com/charlie/3.html",
- "row": 3
- },
- {
- "copyText": "https://example.com/alpha/4.html",
- "displayText": "https://example.com/alpha/4.html",
- "row": 4
- },
- {
- "copyText": "https://example.com/hotel/5.html",
- "displayText": "https://example.com/hotel/5.html",
- "row": 5
- },
- {
- "copyText": "https://example.com/delta/6.html",
- "displayText": "https://example.com/delta/6.html",
- "row": 6
- },
- {
- "copyText": "https://example.com/india/7.html",
- "displayText": "https://example.com/india/7.html",
- "row": 7
- },
- {
- "copyText": "https://example.com/delta/8.html",
- "displayText": "https://example.com/delta/8.html",
- "row": 8
- },
- {
- "copyText": "https://example.com/foxtrot/9.html",
- "displayText": "https://example.com/foxtrot/9.html",
- "row": 9
- },
- {
- "copyText": "https://example.com/hotel/10.html",
- "displayText": "https://example.com/hotel/10.html",
- "row": 10
- },
- {
- "copyText": "https://example.com/india/11.html",
- "displayText": "https://example.com/india/11.html",
- "row": 11
- }
- ],
- "field": "url"
- },
- {
- "cellType": "phone",
- "cells": [
- {
- "copyText": "+1 555 4212",
- "displayText": "+1 555 4212",
- "row": 0
- },
- {
- "copyText": "+1 555 8491",
- "displayText": "+1 555 8491",
- "row": 1
- },
- {
- "copyText": "+1 555 8182",
- "displayText": "+1 555 8182",
- "row": 2
- },
- {
- "copyText": "+1 555 5211",
- "displayText": "+1 555 5211",
- "row": 3
- },
- {
- "copyText": "+1 555 9286",
- "displayText": "+1 555 9286",
- "row": 4
- },
- {
- "copyText": "+1 555 2346",
- "displayText": "+1 555 2346",
- "row": 5
- },
- {
- "copyText": "+1 555 7684",
- "displayText": "+1 555 7684",
- "row": 6
- },
- {
- "copyText": "+1 555 2555",
- "displayText": "+1 555 2555",
- "row": 7
- },
- {
- "copyText": "+1 555 2754",
- "displayText": "+1 555 2754",
- "row": 8
- },
- {
- "copyText": "+1 555 1775",
- "displayText": "+1 555 1775",
- "row": 9
- },
- {
- "copyText": "+1 555 5037",
- "displayText": "+1 555 5037",
- "row": 10
- },
- {
- "copyText": "+1 555 6107",
- "displayText": "+1 555 6107",
- "row": 11
- }
- ],
- "field": "phone"
- },
- {
- "cellType": "citext",
- "cells": [
- {
- "copyText": "EchoCase",
- "displayText": "EchoCase",
- "row": 0
- },
- {
- "copyText": "AlphaCase",
- "displayText": "AlphaCase",
- "row": 1
- },
- {
- "copyText": "HotelCase",
- "displayText": "HotelCase",
- "row": 2
- },
- {
- "copyText": "DeltaCase",
- "displayText": "DeltaCase",
- "row": 3
- },
- {
- "copyText": "GolfCase",
- "displayText": "GolfCase",
- "row": 4
- },
- {
- "copyText": "CharlieCase",
- "displayText": "CharlieCase",
- "row": 5
- },
- {
- "copyText": "FoxtrotCase",
- "displayText": "FoxtrotCase",
- "row": 6
- },
- {
- "copyText": "IndiaCase",
- "displayText": "IndiaCase",
- "row": 7
- },
- {
- "copyText": "GolfCase",
- "displayText": "GolfCase",
- "row": 8
- },
- {
- "copyText": "CharlieCase",
- "displayText": "CharlieCase",
- "row": 9
- },
- {
- "copyText": "JulietCase",
- "displayText": "JulietCase",
- "row": 10
- },
- {
- "copyText": "AlphaCase",
- "displayText": "AlphaCase",
- "row": 11
- }
- ],
- "field": "citext"
- },
- {
- "cellType": "bpchar",
- "cells": [
- {
- "copyText": "AL ",
- "displayText": "AL ",
- "row": 0
- },
- {
- "copyText": "BR ",
- "displayText": "BR ",
- "row": 1
- },
- {
- "copyText": "HO ",
- "displayText": "HO ",
- "row": 2
- },
- {
- "copyText": "BR ",
- "displayText": "BR ",
- "row": 3
- },
- {
- "copyText": "CH ",
- "displayText": "CH ",
- "row": 4
- },
- {
- "copyText": "FO ",
- "displayText": "FO ",
- "row": 5
- },
- {
- "copyText": "DE ",
- "displayText": "DE ",
- "row": 6
- },
- {
- "copyText": "EC ",
- "displayText": "EC ",
- "row": 7
- },
- {
- "copyText": "FO ",
- "displayText": "FO ",
- "row": 8
- },
- {
- "copyText": "GO ",
- "displayText": "GO ",
- "row": 9
- },
- {
- "copyText": "EC ",
- "displayText": "EC ",
- "row": 10
- },
- {
- "copyText": "AL ",
- "displayText": "AL ",
- "row": 11
- }
- ],
- "field": "bpchar"
- },
- {
- "cellType": "number",
- "cells": [
- {
- "copyText": "88.11",
- "displayText": "88.11",
- "row": 0
- },
- {
- "copyText": "717.18",
- "displayText": "717.18",
- "row": 1
- },
- {
- "copyText": "503.44",
- "displayText": "503.44",
- "row": 2
- },
- {
- "copyText": "917.09",
- "displayText": "917.09",
- "row": 3
- },
- {
- "copyText": "980.47",
- "displayText": "980.47",
- "row": 4
- },
- {
- "copyText": "310.26",
- "displayText": "310.26",
- "row": 5
- },
- {
- "copyText": "605.09",
- "displayText": "605.09",
- "row": 6
- },
- {
- "copyText": "676.45",
- "displayText": "676.45",
- "row": 7
- },
- {
- "copyText": "585.37",
- "displayText": "585.37",
- "row": 8
- },
- {
- "copyText": "27.82",
- "displayText": "27.82",
- "row": 9
- },
- {
- "copyText": "33.68",
- "displayText": "33.68",
- "row": 10
- },
- {
- "copyText": "169.86",
- "displayText": "169.86",
- "row": 11
- }
- ],
- "field": "number"
- },
- {
- "cellType": "integer",
- "cells": [
- {
- "copyText": "768",
- "displayText": "768",
- "row": 0
- },
- {
- "copyText": "892",
- "displayText": "892",
- "row": 1
- },
- {
- "copyText": "929",
- "displayText": "929",
- "row": 2
- },
- {
- "copyText": "301",
- "displayText": "301",
- "row": 3
- },
- {
- "copyText": "143",
- "displayText": "143",
- "row": 4
- },
- {
- "copyText": "902",
- "displayText": "902",
- "row": 5
- },
- {
- "copyText": "961",
- "displayText": "961",
- "row": 6
- },
- {
- "copyText": "842",
- "displayText": "842",
- "row": 7
- },
- {
- "copyText": "997",
- "displayText": "997",
- "row": 8
- },
- {
- "copyText": "955",
- "displayText": "955",
- "row": 9
- },
- {
- "copyText": "334",
- "displayText": "334",
- "row": 10
- },
- {
- "copyText": "289",
- "displayText": "289",
- "row": 11
- }
- ],
- "field": "integer"
- },
- {
- "cellType": "smallint",
- "cells": [
- {
- "copyText": "36",
- "displayText": "36",
- "row": 0
- },
- {
- "copyText": "28",
- "displayText": "28",
- "row": 1
- },
- {
- "copyText": "91",
- "displayText": "91",
- "row": 2
- },
- {
- "copyText": "76",
- "displayText": "76",
- "row": 3
- },
- {
- "copyText": "96",
- "displayText": "96",
- "row": 4
- },
- {
- "copyText": "93",
- "displayText": "93",
- "row": 5
- },
- {
- "copyText": "42",
- "displayText": "42",
- "row": 6
- },
- {
- "copyText": "64",
- "displayText": "64",
- "row": 7
- },
- {
- "copyText": "47",
- "displayText": "47",
- "row": 8
- },
- {
- "copyText": "26",
- "displayText": "26",
- "row": 9
- },
- {
- "copyText": "15",
- "displayText": "15",
- "row": 10
- },
- {
- "copyText": "82",
- "displayText": "82",
- "row": 11
- }
- ],
- "field": "smallint"
- },
- {
- "cellType": "decimal",
- "cells": [
- {
- "copyText": "426.72",
- "displayText": "426.72",
- "row": 0
- },
- {
- "copyText": "839.85",
- "displayText": "839.85",
- "row": 1
- },
- {
- "copyText": "528.14",
- "displayText": "528.14",
- "row": 2
- },
- {
- "copyText": "470.18",
- "displayText": "470.18",
- "row": 3
- },
- {
- "copyText": "914.34",
- "displayText": "914.34",
- "row": 4
- },
- {
- "copyText": "45.43",
- "displayText": "45.43",
- "row": 5
- },
- {
- "copyText": "236.91",
- "displayText": "236.91",
- "row": 6
- },
- {
- "copyText": "528.14",
- "displayText": "528.14",
- "row": 7
- },
- {
- "copyText": "497.74",
- "displayText": "497.74",
- "row": 8
- },
- {
- "copyText": "641.31",
- "displayText": "641.31",
- "row": 9
- },
- {
- "copyText": "989.95",
- "displayText": "989.95",
- "row": 10
- },
- {
- "copyText": "605.21",
- "displayText": "605.21",
- "row": 11
- }
- ],
- "field": "decimal"
- },
- {
- "cellType": "currency",
- "cells": [
- {
- "copyText": "2343.31",
- "displayText": "2343.31",
- "row": 0
- },
- {
- "copyText": "3221.78",
- "displayText": "3221.78",
- "row": 1
- },
- {
- "copyText": "4727.95",
- "displayText": "4727.95",
- "row": 2
- },
- {
- "copyText": "3307.75",
- "displayText": "3307.75",
- "row": 3
- },
- {
- "copyText": "4767.22",
- "displayText": "4767.22",
- "row": 4
- },
- {
- "copyText": "2158.85",
- "displayText": "2158.85",
- "row": 5
- },
- {
- "copyText": "3688.13",
- "displayText": "3688.13",
- "row": 6
- },
- {
- "copyText": "2968.25",
- "displayText": "2968.25",
- "row": 7
- },
- {
- "copyText": "2800.51",
- "displayText": "2800.51",
- "row": 8
- },
- {
- "copyText": "4767.2",
- "displayText": "4767.2",
- "row": 9
- },
- {
- "copyText": "3671.15",
- "displayText": "3671.15",
- "row": 10
- },
- {
- "copyText": "4742.3",
- "displayText": "4742.3",
- "row": 11
- }
- ],
- "field": "currency"
- },
- {
- "cellType": "percentage",
- "cells": [
- {
- "copyText": "0.95",
- "displayText": "0.95",
- "row": 0
- },
- {
- "copyText": "0.32",
- "displayText": "0.32",
- "row": 1
- },
- {
- "copyText": "0.92",
- "displayText": "0.92",
- "row": 2
- },
- {
- "copyText": "0.87",
- "displayText": "0.87",
- "row": 3
- },
- {
- "copyText": "0.15",
- "displayText": "0.15",
- "row": 4
- },
- {
- "copyText": "0.36",
- "displayText": "0.36",
- "row": 5
- },
- {
- "copyText": "0.53",
- "displayText": "0.53",
- "row": 6
- },
- {
- "copyText": "0.98",
- "displayText": "0.98",
- "row": 7
- },
- {
- "copyText": "0.8",
- "displayText": "0.8",
- "row": 8
- },
- {
- "copyText": "0.2",
- "displayText": "0.2",
- "row": 9
- },
- {
- "copyText": "0.12",
- "displayText": "0.12",
- "row": 10
- },
- {
- "copyText": "0.32",
- "displayText": "0.32",
- "row": 11
- }
- ],
- "field": "percentage"
- },
- {
- "cellType": "date",
- "cells": [
- {
- "copyText": "2024-09-10",
- "displayText": "2024-09-10",
- "row": 0
- },
- {
- "copyText": "2020-02-28",
- "displayText": "2020-02-28",
- "row": 1
- },
- {
- "copyText": "2022-11-23",
- "displayText": "2022-11-23",
- "row": 2
- },
- {
- "copyText": "2025-04-22",
- "displayText": "2025-04-22",
- "row": 3
- },
- {
- "copyText": "2020-06-22",
- "displayText": "2020-06-22",
- "row": 4
- },
- {
- "copyText": "2021-09-04",
- "displayText": "2021-09-04",
- "row": 5
- },
- {
- "copyText": "2021-09-19",
- "displayText": "2021-09-19",
- "row": 6
- },
- {
- "copyText": "2022-05-20",
- "displayText": "2022-05-20",
- "row": 7
- },
- {
- "copyText": "2021-03-17",
- "displayText": "2021-03-17",
- "row": 8
- },
- {
- "copyText": "2020-10-02",
- "displayText": "2020-10-02",
- "row": 9
- },
- {
- "copyText": "2021-08-19",
- "displayText": "2021-08-19",
- "row": 10
- },
- {
- "copyText": "2023-12-06",
- "displayText": "2023-12-06",
- "row": 11
- }
- ],
- "field": "date"
- },
- {
- "cellType": "datetime",
- "cells": [
- {
- "copyText": "2020-11-10T08:08:00Z",
- "displayText": "2020-11-10T08:08:00Z",
- "row": 0
- },
- {
- "copyText": "2023-01-15T16:15:00Z",
- "displayText": "2023-01-15T16:15:00Z",
- "row": 1
- },
- {
- "copyText": "2021-06-27T11:23:00Z",
- "displayText": "2021-06-27T11:23:00Z",
- "row": 2
- },
- {
- "copyText": "2025-10-18T13:39:00Z",
- "displayText": "2025-10-18T13:39:00Z",
- "row": 3
- },
- {
- "copyText": "2022-07-19T12:33:00Z",
- "displayText": "2022-07-19T12:33:00Z",
- "row": 4
- },
- {
- "copyText": "2020-02-16T11:56:00Z",
- "displayText": "2020-02-16T11:56:00Z",
- "row": 5
- },
- {
- "copyText": "2023-02-14T12:21:00Z",
- "displayText": "2023-02-14T12:21:00Z",
- "row": 6
- },
- {
- "copyText": "2020-01-02T10:34:00Z",
- "displayText": "2020-01-02T10:34:00Z",
- "row": 7
- },
- {
- "copyText": "2023-11-20T00:24:00Z",
- "displayText": "2023-11-20T00:24:00Z",
- "row": 8
- },
- {
- "copyText": "2020-10-03T03:34:00Z",
- "displayText": "2020-10-03T03:34:00Z",
- "row": 9
- },
- {
- "copyText": "2022-11-11T13:25:00Z",
- "displayText": "2022-11-11T13:25:00Z",
- "row": 10
- },
- {
- "copyText": "2025-05-20T00:14:00Z",
- "displayText": "2025-05-20T00:14:00Z",
- "row": 11
- }
- ],
- "field": "datetime"
- },
- {
- "cellType": "time",
- "cells": [
- {
- "copyText": "04:37:00",
- "displayText": "04:37:00",
- "row": 0
- },
- {
- "copyText": "10:46:00",
- "displayText": "10:46:00",
- "row": 1
- },
- {
- "copyText": "17:20:00",
- "displayText": "17:20:00",
- "row": 2
- },
- {
- "copyText": "08:00:00",
- "displayText": "08:00:00",
- "row": 3
- },
- {
- "copyText": "17:44:00",
- "displayText": "17:44:00",
- "row": 4
- },
- {
- "copyText": "09:17:00",
- "displayText": "09:17:00",
- "row": 5
- },
- {
- "copyText": "19:41:00",
- "displayText": "19:41:00",
- "row": 6
- },
- {
- "copyText": "17:25:00",
- "displayText": "17:25:00",
- "row": 7
- },
- {
- "copyText": "09:57:00",
- "displayText": "09:57:00",
- "row": 8
- },
- {
- "copyText": "02:51:00",
- "displayText": "02:51:00",
- "row": 9
- },
- {
- "copyText": "18:37:00",
- "displayText": "18:37:00",
- "row": 10
- },
- {
- "copyText": "09:52:00",
- "displayText": "09:52:00",
- "row": 11
- }
- ],
- "field": "time"
- },
- {
- "cellType": "timestamptz",
- "cells": [
- {
- "copyText": "2024-12-16T08:02:00Z",
- "displayText": "2024-12-16T08:02:00Z",
- "row": 0
- },
- {
- "copyText": "2021-03-06T03:44:00Z",
- "displayText": "2021-03-06T03:44:00Z",
- "row": 1
- },
- {
- "copyText": "2023-09-18T18:44:00Z",
- "displayText": "2023-09-18T18:44:00Z",
- "row": 2
- },
- {
- "copyText": "2024-04-17T19:53:00Z",
- "displayText": "2024-04-17T19:53:00Z",
- "row": 3
- },
- {
- "copyText": "2022-04-28T17:32:00Z",
- "displayText": "2022-04-28T17:32:00Z",
- "row": 4
- },
- {
- "copyText": "2021-11-05T18:28:00Z",
- "displayText": "2021-11-05T18:28:00Z",
- "row": 5
- },
- {
- "copyText": "2024-05-24T15:12:00Z",
- "displayText": "2024-05-24T15:12:00Z",
- "row": 6
- },
- {
- "copyText": "2020-08-03T04:12:00Z",
- "displayText": "2020-08-03T04:12:00Z",
- "row": 7
- },
- {
- "copyText": "2021-12-07T20:49:00Z",
- "displayText": "2021-12-07T20:49:00Z",
- "row": 8
- },
- {
- "copyText": "2024-11-24T08:03:00Z",
- "displayText": "2024-11-24T08:03:00Z",
- "row": 9
- },
- {
- "copyText": "2020-01-08T12:59:00Z",
- "displayText": "2020-01-08T12:59:00Z",
- "row": 10
- },
- {
- "copyText": "2021-03-16T17:53:00Z",
- "displayText": "2021-03-16T17:53:00Z",
- "row": 11
- }
- ],
- "field": "timestamptz"
- },
- {
- "cellType": "interval",
- "cells": [
- {
- "copyText": "{\"years\":2,\"months\":7,\"days\":25}",
- "displayText": "2y 7mo 25d",
- "row": 0
- },
- {
- "copyText": "{\"years\":2,\"months\":0,\"days\":0}",
- "displayText": "2y",
- "row": 1
- },
- {
- "copyText": "{\"years\":2,\"months\":1,\"days\":22}",
- "displayText": "2y 1mo 22d",
- "row": 2
- },
- {
- "copyText": "{\"years\":1,\"months\":3,\"days\":10}",
- "displayText": "1y 3mo 10d",
- "row": 3
- },
- {
- "copyText": "{\"years\":1,\"months\":1,\"days\":23}",
- "displayText": "1y 1mo 23d",
- "row": 4
- },
- {
- "copyText": "{\"years\":1,\"months\":2,\"days\":6}",
- "displayText": "1y 2mo 6d",
- "row": 5
- },
- {
- "copyText": "{\"years\":1,\"months\":4,\"days\":21}",
- "displayText": "1y 4mo 21d",
- "row": 6
- },
- {
- "copyText": "{\"years\":2,\"months\":0,\"days\":16}",
- "displayText": "2y 16d",
- "row": 7
- },
- {
- "copyText": "{\"years\":1,\"months\":3,\"days\":23}",
- "displayText": "1y 3mo 23d",
- "row": 8
- },
- {
- "copyText": "{\"years\":1,\"months\":3,\"days\":9}",
- "displayText": "1y 3mo 9d",
- "row": 9
- },
- {
- "copyText": "{\"years\":1,\"months\":6,\"days\":18}",
- "displayText": "1y 6mo 18d",
- "row": 10
- },
- {
- "copyText": "{\"years\":1,\"months\":4,\"days\":17}",
- "displayText": "1y 4mo 17d",
- "row": 11
- }
- ],
- "field": "interval"
- },
- {
- "cellType": "boolean",
- "cells": [
- {
- "copyText": "false",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "boolean"
- },
- {
- "cellType": "toggle",
- "cells": [
- {
- "copyText": "true",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "false",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "toggle"
- },
- {
- "cellType": "bit",
- "cells": [
- {
- "copyText": "true",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "true",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "bit"
- },
- {
- "cellType": "json",
- "cells": [
- {
- "copyText": "{\"key\":\"india\",\"n\":96,\"ok\":true}",
- "displayText": "{\"key\":\"india\",\"n\":96,\"ok\":true}",
- "row": 0
- },
- {
- "copyText": "{\"key\":\"foxtrot\",\"n\":70,\"ok\":false}",
- "displayText": "{\"key\":\"foxtrot\",\"n\":70,\"ok\":false}",
- "row": 1
- },
- {
- "copyText": "{\"key\":\"hotel\",\"n\":77,\"ok\":true}",
- "displayText": "{\"key\":\"hotel\",\"n\":77,\"ok\":true}",
- "row": 2
- },
- {
- "copyText": "{\"key\":\"foxtrot\",\"n\":74,\"ok\":false}",
- "displayText": "{\"key\":\"foxtrot\",\"n\":74,\"ok\":false}",
- "row": 3
- },
- {
- "copyText": "{\"key\":\"alpha\",\"n\":50,\"ok\":false}",
- "displayText": "{\"key\":\"alpha\",\"n\":50,\"ok\":false}",
- "row": 4
- },
- {
- "copyText": "{\"key\":\"juliet\",\"n\":90,\"ok\":false}",
- "displayText": "{\"key\":\"juliet\",\"n\":90,\"ok\":false}",
- "row": 5
- },
- {
- "copyText": "{\"key\":\"india\",\"n\":35,\"ok\":false}",
- "displayText": "{\"key\":\"india\",\"n\":35,\"ok\":false}",
- "row": 6
- },
- {
- "copyText": "{\"key\":\"india\",\"n\":15,\"ok\":true}",
- "displayText": "{\"key\":\"india\",\"n\":15,\"ok\":true}",
- "row": 7
- },
- {
- "copyText": "{\"key\":\"india\",\"n\":84,\"ok\":false}",
- "displayText": "{\"key\":\"india\",\"n\":84,\"ok\":false}",
- "row": 8
- },
- {
- "copyText": "{\"key\":\"juliet\",\"n\":51,\"ok\":true}",
- "displayText": "{\"key\":\"juliet\",\"n\":51,\"ok\":true}",
- "row": 9
- },
- {
- "copyText": "{\"key\":\"golf\",\"n\":58,\"ok\":false}",
- "displayText": "{\"key\":\"golf\",\"n\":58,\"ok\":false}",
- "row": 10
- },
- {
- "copyText": "{\"key\":\"foxtrot\",\"n\":15,\"ok\":false}",
- "displayText": "{\"key\":\"foxtrot\",\"n\":15,\"ok\":false}",
- "row": 11
- }
- ],
- "field": "json"
- },
- {
- "cellType": "jsonb",
- "cells": [
- {
- "copyText": "{\"nested\":{\"items\":[5,9]},\"tag\":\"juliet\"}",
- "displayText": "{\"nested\":{\"items\":[5,9]},\"tag\":\"juliet\"}",
- "row": 0
- },
- {
- "copyText": "{\"nested\":{\"items\":[5,0]},\"tag\":\"foxtrot\"}",
- "displayText": "{\"nested\":{\"items\":[5,0]},\"tag\":\"foxtrot\"}",
- "row": 1
- },
- {
- "copyText": "{\"nested\":{\"items\":[4,9]},\"tag\":\"juliet\"}",
- "displayText": "{\"nested\":{\"items\":[4,9]},\"tag\":\"juliet\"}",
- "row": 2
- },
- {
- "copyText": "{\"nested\":{\"items\":[5,0]},\"tag\":\"bravo\"}",
- "displayText": "{\"nested\":{\"items\":[5,0]},\"tag\":\"bravo\"}",
- "row": 3
- },
- {
- "copyText": "{\"nested\":{\"items\":[2,6]},\"tag\":\"echo\"}",
- "displayText": "{\"nested\":{\"items\":[2,6]},\"tag\":\"echo\"}",
- "row": 4
- },
- {
- "copyText": "{\"nested\":{\"items\":[2,6]},\"tag\":\"delta\"}",
- "displayText": "{\"nested\":{\"items\":[2,6]},\"tag\":\"delta\"}",
- "row": 5
- },
- {
- "copyText": "{\"nested\":{\"items\":[0,9]},\"tag\":\"echo\"}",
- "displayText": "{\"nested\":{\"items\":[0,9]},\"tag\":\"echo\"}",
- "row": 6
- },
- {
- "copyText": "{\"nested\":{\"items\":[7,8]},\"tag\":\"golf\"}",
- "displayText": "{\"nested\":{\"items\":[7,8]},\"tag\":\"golf\"}",
- "row": 7
- },
- {
- "copyText": "{\"nested\":{\"items\":[2,7]},\"tag\":\"india\"}",
- "displayText": "{\"nested\":{\"items\":[2,7]},\"tag\":\"india\"}",
- "row": 8
- },
- {
- "copyText": "{\"nested\":{\"items\":[6,0]},\"tag\":\"alpha\"}",
- "displayText": "{\"nested\":{\"items\":[6,0]},\"tag\":\"alpha\"}",
- "row": 9
- },
- {
- "copyText": "{\"nested\":{\"items\":[3,5]},\"tag\":\"delta\"}",
- "displayText": "{\"nested\":{\"items\":[3,5]},\"tag\":\"delta\"}",
- "row": 10
- },
- {
- "copyText": "{\"nested\":{\"items\":[3,4]},\"tag\":\"india\"}",
- "displayText": "{\"nested\":{\"items\":[3,4]},\"tag\":\"india\"}",
- "row": 11
- }
- ],
- "field": "jsonb"
- },
- {
- "cellType": "array",
- "cells": [
- {
- "copyText": "[\"foxtrot\",\"india\",\"alpha\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"hotel\",\"india\",\"alpha\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"bravo\",\"golf\",\"charlie\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"golf\",\"delta\",\"foxtrot\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"juliet\",\"echo\",\"golf\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"foxtrot\",\"juliet\",\"bravo\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"bravo\",\"delta\",\"delta\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"golf\",\"charlie\",\"hotel\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"alpha\",\"foxtrot\",\"alpha\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"juliet\",\"charlie\",\"golf\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"hotel\",\"hotel\",\"charlie\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"echo\",\"alpha\",\"echo\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "array"
- },
- {
- "cellType": "text-array",
- "cells": [
- {
- "copyText": "[\"foxtrot\",\"delta\",\"hotel\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"foxtrot\",\"delta\",\"alpha\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"foxtrot\",\"echo\",\"foxtrot\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"hotel\",\"bravo\",\"hotel\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"juliet\",\"alpha\",\"foxtrot\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"foxtrot\",\"india\",\"alpha\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"delta\",\"bravo\",\"foxtrot\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"hotel\",\"charlie\",\"india\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"charlie\",\"foxtrot\",\"alpha\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"alpha\",\"alpha\",\"alpha\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"hotel\",\"golf\",\"bravo\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"juliet\",\"india\",\"foxtrot\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "textArray"
- },
- {
- "cellType": "uuid-array",
- "cells": [
- {
- "copyText": "[\"8cf8d6ab-8430-40fd-a099-bf4fac9d2f89\",\"263ddbaf-9bf7-439c-d387-8247720201ef\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"e4245cdd-cbda-4bb4-6a53-79a6b3b876d1\",\"88aa16fb-8b5f-41c7-373d-f8f2720bc307\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"6a9d13d1-d5a5-4c32-791f-1a82cea02934\",\"6217bfaa-7515-499e-1417-be1cf7ed703c\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"0f869b6a-7357-4139-b51c-f292c2d6f795\",\"7a8e2252-1609-4f9f-0a4e-b02fcbc6ea69\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"40e1b290-f634-4933-01cd-5deb3a018434\",\"c3c395b8-d367-43da-b80f-c4ac5427ee38\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"8429d6af-71b7-4df4-e9bf-50ac5f3002b5\",\"92cd12b7-92ed-41cc-0eb6-03438689589e\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"92776b4c-b63f-40d2-9615-86c94b5ceabf\",\"d45544b6-a5c2-47fa-ae04-f8d316fa13a8\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"e58a9277-0577-4669-0012-ee33e5643985\",\"df0d0384-7118-44a0-574f-fb4d5a706b6c\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"3d2ab556-a735-4dea-3b03-7da8e2ecbbf6\",\"6cc45c4d-fd08-4765-37aa-004f8cf9ae53\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"e77b8a34-7f3a-4b55-0f9e-4541a412c058\",\"1b8b6403-739d-4829-ba65-d38852820d25\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"ef743ad8-b025-48a9-6a70-a03871708893\",\"9d3da72c-1958-4864-ae39-a9279a14dc5a\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"f0e6788b-6b3b-49aa-0df0-51af59b4dd96\",\"262069ab-7e06-458e-d31b-a9535557509c\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "uuidArray"
- },
- {
- "cellType": "number-array",
- "cells": [
- {
- "copyText": "[\"6.01\",\"17.45\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"66.49\",\"31.2\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"14.45\",\"36.74\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"74.01\",\"64.25\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"61.64\",\"45.1\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"26.11\",\"73.03\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"3.03\",\"83.86\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"13.13\",\"40.83\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"64.28\",\"80.22\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"75.38\",\"29.19\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"88.56\",\"19.46\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"47.93\",\"82.13\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "numberArray"
- },
- {
- "cellType": "integer-array",
- "cells": [
- {
- "copyText": "[\"40\",\"49\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"53\",\"94\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"79\",\"67\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"11\",\"94\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"35\",\"31\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"88\",\"16\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"41\",\"8\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"74\",\"14\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"84\",\"9\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"7\",\"35\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"58\",\"86\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"79\",\"59\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "integerArray"
- },
- {
- "cellType": "date-array",
- "cells": [
- {
- "copyText": "[\"2024-05-11\",\"2024-09-23\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"2021-07-20\",\"2021-02-18\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"2022-07-22\",\"2024-08-09\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"2025-11-08\",\"2024-11-13\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"2025-07-26\",\"2024-07-18\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"2023-01-25\",\"2022-01-10\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"2020-03-13\",\"2025-01-24\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"2025-10-04\",\"2021-07-24\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"2023-08-23\",\"2023-11-22\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"2023-04-01\",\"2025-10-05\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"2022-10-18\",\"2022-08-10\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"2022-05-21\",\"2021-10-21\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "dateArray"
- },
- {
- "cellType": "geometry",
- "cells": [
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[5.3982,53.6979]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[5.3982,53.6979]}",
- "row": 0
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-68.5712,8.4246]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-68.5712,8.4246]}",
- "row": 1
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-56.593,80.7422]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-56.593,80.7422]}",
- "row": 2
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-6.2532,-12.5181]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-6.2532,-12.5181]}",
- "row": 3
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-66.8936,41.4211]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-66.8936,41.4211]}",
- "row": 4
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[42.8503,18.2985]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[42.8503,18.2985]}",
- "row": 5
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-24.915,-82.7899]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-24.915,-82.7899]}",
- "row": 6
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-61.5576,70.8895]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-61.5576,70.8895]}",
- "row": 7
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-4.9481,-59.1728]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-4.9481,-59.1728]}",
- "row": 8
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[78.5617,80.0919]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[78.5617,80.0919]}",
- "row": 9
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[-8.2256,37.3817]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[-8.2256,37.3817]}",
- "row": 10
- },
- {
- "copyText": "geo:{\"type\":\"Point\",\"coordinates\":[46.0122,35.4564]}",
- "displayText": "geo:{\"type\":\"Point\",\"coordinates\":[46.0122,35.4564]}",
- "row": 11
- }
- ],
- "field": "geometry"
- },
- {
- "cellType": "geometry-point",
- "cells": [
- {
- "copyText": "geo:{\"x\":41.22,\"y\":56.26}",
- "displayText": "geo:{\"x\":41.22,\"y\":56.26}",
- "row": 0
- },
- {
- "copyText": "geo:{\"x\":45.34,\"y\":67.2}",
- "displayText": "geo:{\"x\":45.34,\"y\":67.2}",
- "row": 1
- },
- {
- "copyText": "geo:{\"x\":82.74,\"y\":37}",
- "displayText": "geo:{\"x\":82.74,\"y\":37}",
- "row": 2
- },
- {
- "copyText": "geo:{\"x\":48.54,\"y\":60.32}",
- "displayText": "geo:{\"x\":48.54,\"y\":60.32}",
- "row": 3
- },
- {
- "copyText": "geo:{\"x\":79.91,\"y\":96.21}",
- "displayText": "geo:{\"x\":79.91,\"y\":96.21}",
- "row": 4
- },
- {
- "copyText": "geo:{\"x\":88.25,\"y\":16.58}",
- "displayText": "geo:{\"x\":88.25,\"y\":16.58}",
- "row": 5
- },
- {
- "copyText": "geo:{\"x\":74.55,\"y\":87.82}",
- "displayText": "geo:{\"x\":74.55,\"y\":87.82}",
- "row": 6
- },
- {
- "copyText": "geo:{\"x\":85.07,\"y\":11.99}",
- "displayText": "geo:{\"x\":85.07,\"y\":11.99}",
- "row": 7
- },
- {
- "copyText": "geo:{\"x\":61.9,\"y\":19.2}",
- "displayText": "geo:{\"x\":61.9,\"y\":19.2}",
- "row": 8
- },
- {
- "copyText": "geo:{\"x\":50.76,\"y\":37.84}",
- "displayText": "geo:{\"x\":50.76,\"y\":37.84}",
- "row": 9
- },
- {
- "copyText": "geo:{\"x\":2.47,\"y\":48.58}",
- "displayText": "geo:{\"x\":2.47,\"y\":48.58}",
- "row": 10
- },
- {
- "copyText": "geo:{\"x\":72.83,\"y\":83.55}",
- "displayText": "geo:{\"x\":72.83,\"y\":83.55}",
- "row": 11
- }
- ],
- "field": "geometryPoint"
- },
- {
- "cellType": "geometry-collection",
- "cells": [
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 0
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 1
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 2
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 3
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 4
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 5
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 6
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 7
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 8
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 9
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 10
- },
- {
- "copyText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "displayText": "geo:{\"type\":\"GeometryCollection\",\"geometries\":[]}",
- "row": 11
- }
- ],
- "field": "geometryCollection"
- },
- {
- "cellType": "inet",
- "cells": [
- {
- "copyText": "74.134.198.20",
- "displayText": "74.134.198.20",
- "row": 0
- },
- {
- "copyText": "209.189.147.198",
- "displayText": "209.189.147.198",
- "row": 1
- },
- {
- "copyText": "126.158.213.24",
- "displayText": "126.158.213.24",
- "row": 2
- },
- {
- "copyText": "89.132.237.41",
- "displayText": "89.132.237.41",
- "row": 3
- },
- {
- "copyText": "202.191.150.41",
- "displayText": "202.191.150.41",
- "row": 4
- },
- {
- "copyText": "34.84.183.225",
- "displayText": "34.84.183.225",
- "row": 5
- },
- {
- "copyText": "87.10.168.238",
- "displayText": "87.10.168.238",
- "row": 6
- },
- {
- "copyText": "246.38.101.16",
- "displayText": "246.38.101.16",
- "row": 7
- },
- {
- "copyText": "70.138.98.57",
- "displayText": "70.138.98.57",
- "row": 8
- },
- {
- "copyText": "53.95.218.245",
- "displayText": "53.95.218.245",
- "row": 9
- },
- {
- "copyText": "31.79.93.58",
- "displayText": "31.79.93.58",
- "row": 10
- },
- {
- "copyText": "73.245.172.54",
- "displayText": "73.245.172.54",
- "row": 11
- }
- ],
- "field": "inet"
- },
- {
- "cellType": "image",
- "cells": [
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 0
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 1
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 2
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 3
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 4
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 5
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 6
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 7
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 8
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 9
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 10
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EIMG%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 11
- }
- ],
- "field": "image"
- },
- {
- "cellType": "file",
- "cells": [
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 0
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 1
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 2
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 3
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 4
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 5
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 6
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 7
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 8
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 9
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 10
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EFILE%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 11
- }
- ],
- "field": "file"
- },
- {
- "cellType": "video",
- "cells": [
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 0
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 1
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 2
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 3
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 4
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 5
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 6
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 7
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 8
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 9
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 10
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EVIDEO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 11
- }
- ],
- "field": "video"
- },
- {
- "cellType": "audio",
- "cells": [
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 0
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 1
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 2
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 3
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 4
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 5
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 6
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 7
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 8
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 9
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 10
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EAUDIO%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 11
- }
- ],
- "field": "audio"
- },
- {
- "cellType": "upload",
- "cells": [
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 0
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 1
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 2
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 3
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 4
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 5
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%233b82f6'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 6
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23ef4444'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 7
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2322c55e'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 8
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23f59e0b'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 9
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%23a855f7'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 10
- },
- {
- "copyText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "displayText": "[\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'96'%20height%3D'96'%3E%3Crect%20width%3D'96'%20height%3D'96'%20fill%3D'%2306b6d4'%2F%3E%3Ctext%20x%3D'48'%20y%3D'54'%20font-family%3D'system-ui%2Csans-serif'%20font-size%3D'13'%20font-weight%3D'700'%20fill%3D'white'%20text-anchor%3D'middle'%3EUPLOAD%3C%2Ftext%3E%3C%2Fsvg%3E\"]",
- "row": 11
- }
- ],
- "field": "upload"
- },
- {
- "cellType": "uuid",
- "cells": [
- {
- "copyText": "5e457d6f-8658-44e9-fd76-be8a2b69d641",
- "displayText": "5e457d6f-8658-44e9-fd76-be8a2b69d641",
- "row": 0
- },
- {
- "copyText": "acbedaa2-4f3e-40b8-d425-ba514f124b0b",
- "displayText": "acbedaa2-4f3e-40b8-d425-ba514f124b0b",
- "row": 1
- },
- {
- "copyText": "c7551731-584a-4ff1-edbd-7ced52600c13",
- "displayText": "c7551731-584a-4ff1-edbd-7ced52600c13",
- "row": 2
- },
- {
- "copyText": "fccb7ce7-24e9-4cf7-5790-79249188229b",
- "displayText": "fccb7ce7-24e9-4cf7-5790-79249188229b",
- "row": 3
- },
- {
- "copyText": "2539baa7-7032-4028-3189-8442c55066de",
- "displayText": "2539baa7-7032-4028-3189-8442c55066de",
- "row": 4
- },
- {
- "copyText": "688958ec-40f7-419d-35b0-f13270a12259",
- "displayText": "688958ec-40f7-419d-35b0-f13270a12259",
- "row": 5
- },
- {
- "copyText": "231b1faa-098b-460a-468a-4b3014b33189",
- "displayText": "231b1faa-098b-460a-468a-4b3014b33189",
- "row": 6
- },
- {
- "copyText": "f6b115fa-16a0-4f26-63bb-9e4ba5720209",
- "displayText": "f6b115fa-16a0-4f26-63bb-9e4ba5720209",
- "row": 7
- },
- {
- "copyText": "d9514829-15df-4345-e15e-514598069f8b",
- "displayText": "d9514829-15df-4345-e15e-514598069f8b",
- "row": 8
- },
- {
- "copyText": "4a64b778-697a-4205-c9a2-8a00a86646e1",
- "displayText": "4a64b778-697a-4205-c9a2-8a00a86646e1",
- "row": 9
- },
- {
- "copyText": "300b6a83-3fd7-45c8-960e-dda76485cdf7",
- "displayText": "300b6a83-3fd7-45c8-960e-dda76485cdf7",
- "row": 10
- },
- {
- "copyText": "b7768432-6ed3-433e-ed67-1366434ee157",
- "displayText": "b7768432-6ed3-433e-ed67-1366434ee157",
- "row": 11
- }
- ],
- "field": "uuid"
- },
- {
- "cellType": "color",
- "cells": [
- {
- "copyText": "#a855f7",
- "displayText": "#a855f7",
- "row": 0
- },
- {
- "copyText": "#3b82f6",
- "displayText": "#3b82f6",
- "row": 1
- },
- {
- "copyText": "#22c55e",
- "displayText": "#22c55e",
- "row": 2
- },
- {
- "copyText": "#ef4444",
- "displayText": "#ef4444",
- "row": 3
- },
- {
- "copyText": "#06b6d4",
- "displayText": "#06b6d4",
- "row": 4
- },
- {
- "copyText": "#f59e0b",
- "displayText": "#f59e0b",
- "row": 5
- },
- {
- "copyText": "#ef4444",
- "displayText": "#ef4444",
- "row": 6
- },
- {
- "copyText": "#06b6d4",
- "displayText": "#06b6d4",
- "row": 7
- },
- {
- "copyText": "#06b6d4",
- "displayText": "#06b6d4",
- "row": 8
- },
- {
- "copyText": "#f59e0b",
- "displayText": "#f59e0b",
- "row": 9
- },
- {
- "copyText": "#ef4444",
- "displayText": "#ef4444",
- "row": 10
- },
- {
- "copyText": "#06b6d4",
- "displayText": "#06b6d4",
- "row": 11
- }
- ],
- "field": "color"
- },
- {
- "cellType": "rating",
- "cells": [
- {
- "copyText": "4",
- "displayText": "4",
- "row": 0
- },
- {
- "copyText": "5",
- "displayText": "5",
- "row": 1
- },
- {
- "copyText": "2",
- "displayText": "2",
- "row": 2
- },
- {
- "copyText": "3",
- "displayText": "3",
- "row": 3
- },
- {
- "copyText": "3",
- "displayText": "3",
- "row": 4
- },
- {
- "copyText": "5",
- "displayText": "5",
- "row": 5
- },
- {
- "copyText": "4",
- "displayText": "4",
- "row": 6
- },
- {
- "copyText": "1",
- "displayText": "1",
- "row": 7
- },
- {
- "copyText": "5",
- "displayText": "5",
- "row": 8
- },
- {
- "copyText": "5",
- "displayText": "5",
- "row": 9
- },
- {
- "copyText": "4",
- "displayText": "4",
- "row": 10
- },
- {
- "copyText": "5",
- "displayText": "5",
- "row": 11
- }
- ],
- "field": "rating"
- },
- {
- "cellType": "tags",
- "cells": [
- {
- "copyText": "[\"juliet\",\"delta\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"foxtrot\",\"juliet\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"juliet\",\"hotel\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"hotel\",\"alpha\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"foxtrot\",\"delta\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"charlie\",\"alpha\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"hotel\",\"india\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"foxtrot\",\"bravo\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"echo\",\"echo\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"alpha\",\"charlie\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"delta\",\"alpha\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"echo\",\"delta\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "tags"
- },
- {
- "cellType": "tsvector",
- "cells": [
- {
- "copyText": "[\"charlie A\",\"alpha B\"]",
- "displayText": "",
- "row": 0
- },
- {
- "copyText": "[\"golf A\",\"delta B\"]",
- "displayText": "",
- "row": 1
- },
- {
- "copyText": "[\"delta A\",\"juliet B\"]",
- "displayText": "",
- "row": 2
- },
- {
- "copyText": "[\"delta A\",\"charlie B\"]",
- "displayText": "",
- "row": 3
- },
- {
- "copyText": "[\"hotel A\",\"charlie B\"]",
- "displayText": "",
- "row": 4
- },
- {
- "copyText": "[\"india A\",\"alpha B\"]",
- "displayText": "",
- "row": 5
- },
- {
- "copyText": "[\"bravo A\",\"alpha B\"]",
- "displayText": "",
- "row": 6
- },
- {
- "copyText": "[\"india A\",\"charlie B\"]",
- "displayText": "",
- "row": 7
- },
- {
- "copyText": "[\"golf A\",\"foxtrot B\"]",
- "displayText": "",
- "row": 8
- },
- {
- "copyText": "[\"alpha A\",\"india B\"]",
- "displayText": "",
- "row": 9
- },
- {
- "copyText": "[\"golf A\",\"echo B\"]",
- "displayText": "",
- "row": 10
- },
- {
- "copyText": "[\"charlie A\",\"alpha B\"]",
- "displayText": "",
- "row": 11
- }
- ],
- "field": "tsvector"
- },
- {
- "cellType": "origin",
- "cells": [
- {
- "copyText": "manual",
- "displayText": "manual",
- "row": 0
- },
- {
- "copyText": "api",
- "displayText": "api",
- "row": 1
- },
- {
- "copyText": "import",
- "displayText": "import",
- "row": 2
- },
- {
- "copyText": "manual",
- "displayText": "manual",
- "row": 3
- },
- {
- "copyText": "import",
- "displayText": "import",
- "row": 4
- },
- {
- "copyText": "system",
- "displayText": "system",
- "row": 5
- },
- {
- "copyText": "import",
- "displayText": "import",
- "row": 6
- },
- {
- "copyText": "system",
- "displayText": "system",
- "row": 7
- },
- {
- "copyText": "manual",
- "displayText": "manual",
- "row": 8
- },
- {
- "copyText": "api",
- "displayText": "api",
- "row": 9
- },
- {
- "copyText": "manual",
- "displayText": "manual",
- "row": 10
- },
- {
- "copyText": "manual",
- "displayText": "manual",
- "row": 11
- }
- ],
- "field": "origin"
- },
- {
- "cellType": "relation",
- "cells": [
- {
- "copyText": "Edsger Ritchie",
- "displayText": "Edsger Ritchie",
- "row": 0
- },
- {
- "copyText": "Ada Liskov",
- "displayText": "Ada Liskov",
- "row": 1
- },
- {
- "copyText": "Ken Thompson",
- "displayText": "Ken Thompson",
- "row": 2
- },
- {
- "copyText": "Ken Hopper",
- "displayText": "Ken Hopper",
- "row": 3
- },
- {
- "copyText": "Grace Thompson",
- "displayText": "Grace Thompson",
- "row": 4
- },
- {
- "copyText": "Margaret Ritchie",
- "displayText": "Margaret Ritchie",
- "row": 5
- },
- {
- "copyText": "Ken Liskov",
- "displayText": "Ken Liskov",
- "row": 6
- },
- {
- "copyText": "Dennis Ritchie",
- "displayText": "Dennis Ritchie",
- "row": 7
- },
- {
- "copyText": "Grace Dijkstra",
- "displayText": "Grace Dijkstra",
- "row": 8
- },
- {
- "copyText": "Ada Ritchie",
- "displayText": "Ada Ritchie",
- "row": 9
- },
- {
- "copyText": "Grace Hamilton",
- "displayText": "Grace Hamilton",
- "row": 10
- },
- {
- "copyText": "Linus Torvalds",
- "displayText": "Linus Torvalds",
- "row": 11
- }
- ],
- "field": "relation"
- }
-]
diff --git a/packages/sheets/src/grid/__tests__/cell-type-resolver.test.ts b/packages/sheets/src/grid/__tests__/cell-type-resolver.test.ts
new file mode 100644
index 0000000..72e6a47
--- /dev/null
+++ b/packages/sheets/src/grid/__tests__/cell-type-resolver.test.ts
@@ -0,0 +1,46 @@
+import { describe, expect, it } from 'vitest';
+
+import { resolveCellType, type FieldMetadata } from '../../cell-types/cell-type-resolver';
+
+function field(type: FieldMetadata['type']): FieldMetadata {
+ return { name: 'value', type };
+}
+
+describe('resolveCellType', () => {
+ it('applies schema metadata precedence before the GraphQL fallback', () => {
+ const cases: Array<[FieldMetadata, string]> = [
+ [field({ gqlType: 'String', isArray: true, pgType: 'uuid', pgAlias: 'image' }), 'image'],
+ [field({ gqlType: 'String', isArray: true, pgType: 'uuid' }), 'text-array'],
+ [field({ gqlType: 'String', pgType: 'uuid' }), 'uuid'],
+ [field({ gqlType: 'GeoJSON', subtype: 'GeometryPoint' }), 'geometry-point'],
+ [field({ gqlType: 'Mystery' }), 'text'],
+ ];
+
+ for (const [metadata, expected] of cases) {
+ expect(resolveCellType('value', metadata).cellType).toBe(expected);
+ }
+ });
+
+ it('makes only schema-owned identifiers and timestamps readonly', () => {
+ expect(resolveCellType('id', field({ gqlType: 'UUID' }))).toMatchObject({
+ cellType: 'uuid',
+ canEdit: false,
+ canActivate: false,
+ isReadonly: true,
+ });
+ expect(resolveCellType('id', field({ gqlType: 'Int' }))).toMatchObject({
+ cellType: 'integer',
+ canEdit: true,
+ isReadonly: false,
+ });
+ expect(resolveCellType('createdAt')).toMatchObject({ canEdit: false, isReadonly: true });
+ });
+
+ it('keeps viewer-only search vectors activatable without making them editable', () => {
+ expect(resolveCellType('search', field({ gqlType: 'String', pgType: 'tsvector' }))).toMatchObject({
+ cellType: 'tsvector',
+ canEdit: false,
+ canActivate: true,
+ });
+ });
+});
diff --git a/packages/sheets/src/grid/__tests__/registry-fidelity.test.ts b/packages/sheets/src/grid/__tests__/registry-fidelity.test.ts
deleted file mode 100644
index cba297f..0000000
--- a/packages/sheets/src/grid/__tests__/registry-fidelity.test.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import { describe, expect, it } from 'vitest';
-
-import { createCellTypeRegistry, type CellTypeBuiltins } from '../../cell-types/cell-type-registry';
-import type { SheetsCellRenderContext } from '../../cell-types/define-cell-type';
-import type { RelationInfo } from '../../store/relation-info-slice';
-
-import { createSheetsCell } from '../../cell-model/create-sheets-cell';
-import type { CellCreationMetadata } from '../grid-cell-types';
-
-// LOCK 1 — Built-in fidelity (roadmap §1.3).
-//
-// With NO consumer cell types registered, the per-instance CellTypeRegistry must
-// be a TRANSPARENT FALLBACK over the built-in NATIVE rendering engine. This pins
-// that `registry.toSheetsCell(typeKey, value, ctx)` produces output deep-equal to a
-// direct `createSheetsCell(value, metadata)` call for identical inputs — exactly how
-// useSheetsContent wires the builtins. If these ever diverge, the registry has
-// stopped being a pure override layer.
-
-// The exact builtins wiring — toSheetsCell delegates to createSheetsCell. (The glide
-// engines are gone; the native dispatcher is the only built-in display path.)
-const builtins: CellTypeBuiltins = {
- toSheetsCell: (value, ctx) => createSheetsCell(value, ctx.metadata),
-};
-
-// Build metadata the way useSheetsContent does (cellType === resolved typeKey,
-// canEdit/isReadonly/activationBehavior come from the structural route). For
-// fidelity we only need cellType to drive factory selection; the other fields are
-// passed identically through both paths so they cannot cause a divergence.
-function makeMetadata(cellType: string, overrides?: Partial): CellCreationMetadata {
- return {
- cellType,
- fieldName: overrides?.fieldName ?? cellType,
- canEdit: true,
- isReadonly: false,
- activationBehavior: 'double-click',
- ...overrides,
- };
-}
-
-function makeCtx(metadata: CellCreationMetadata): SheetsCellRenderContext {
- return { metadata };
-}
-
-interface FidelityCase {
- label: string;
- typeKey: string;
- value: unknown;
- metaOverrides?: Partial;
-}
-
-const RELATION_INFO_BELONGS_TO: RelationInfo = {
- kind: 'belongsTo',
- relatedTable: 'users',
- relationField: 'author',
- foreignKeyField: 'authorId',
- displayCandidates: ['displayName', 'name'],
-};
-
-const RELATION_INFO_HAS_MANY: RelationInfo = {
- kind: 'hasMany',
- relatedTable: 'comments',
- relationField: 'comments',
- foreignKeyField: 'postId',
- displayCandidates: ['title'],
-};
-
-// Representative coverage across the built-in factory families. Each case is a
-// (typeKey, value) the corresponding SheetsCell factory's canHandle accepts.
-const CASES: FidelityCase[] = [
- // text / string
- { label: 'text — string value', typeKey: 'text', value: 'hello world' },
- { label: 'text — null (empty cell)', typeKey: 'text', value: null },
- { label: 'text — object falls back to JSON preview', typeKey: 'text', value: { a: 1, b: 2 } },
- // number / Int
- { label: 'number — numeric value', typeKey: 'number', value: 42.5 },
- { label: 'integer — string coerced', typeKey: 'integer', value: '17' },
- { label: 'number — null', typeKey: 'number', value: null },
- { label: 'number — NaN string', typeKey: 'number', value: 'not-a-number' },
- // boolean
- { label: 'boolean — true', typeKey: 'boolean', value: true },
- { label: 'boolean — null coerces false', typeKey: 'boolean', value: null },
- { label: 'toggle — truthy coercion', typeKey: 'toggle', value: 1 },
- // date / timestamp
- { label: 'date — iso string', typeKey: 'date', value: '2026-06-11' },
- { label: 'timestamptz — value', typeKey: 'timestamptz', value: '2026-06-11T10:00:00Z' },
- { label: 'datetime — null', typeKey: 'datetime', value: null },
- // image
- { label: 'image — url string', typeKey: 'image', value: 'https://example.com/a.png' },
- { label: 'image — object with url key', typeKey: 'image', value: { url: 'https://example.com/b.png' } },
- { label: 'image — null', typeKey: 'image', value: null },
- // geometry (the native dispatcher's built-in geometry fallback owns this)
- { label: 'geometry — object value', typeKey: 'geometry', value: { type: 'Point', coordinates: [1, 2] } },
- { label: 'geometry — null', typeKey: 'geometry', value: null },
- // relation — single (belongsTo)
- {
- label: 'relation — belongsTo object',
- typeKey: 'relation',
- value: { id: 'u1', displayName: 'Ada Lovelace' },
- metaOverrides: { relationInfo: RELATION_INFO_BELONGS_TO, relationOptions: {} },
- },
- {
- label: 'relation — belongsTo null',
- typeKey: 'relation',
- value: null,
- metaOverrides: { relationInfo: RELATION_INFO_BELONGS_TO, relationOptions: {} },
- },
- // relation — list (hasMany) exercises the chip-limit branch
- {
- label: 'relation — hasMany list with chip overflow',
- typeKey: 'relation',
- value: [{ title: 'one' }, { title: 'two' }, { title: 'three' }, { title: 'four' }],
- metaOverrides: {
- relationInfo: RELATION_INFO_HAS_MANY,
- relationOptions: { relationChipLimit: 2, relationLabelMaxLength: 24 },
- },
- },
-];
-
-describe('LOCK 1 — registry.toSheetsCell is a transparent fallback to createSheetsCell', () => {
- const registry = createCellTypeRegistry([], builtins);
-
- it.each(CASES)('$label', ({ typeKey, value, metaOverrides }) => {
- const metadata = makeMetadata(typeKey, metaOverrides);
-
- // Direct built-in path (what the registry must mirror).
- const direct = createSheetsCell(value, metadata);
-
- // Registry path with zero consumer defs — should be 1:1.
- const viaRegistry = registry.toSheetsCell(typeKey, value, makeCtx(metadata));
-
- expect(viaRegistry).toEqual(direct);
- });
-
- it('covers every built-in factory family at least once', () => {
- // Guard against silent shrinkage of the representative set.
- const families = new Set(CASES.map((c) => c.typeKey));
- for (const required of ['text', 'number', 'boolean', 'date', 'image', 'relation', 'geometry']) {
- expect(families.has(required)).toBe(true);
- }
- });
-});
diff --git a/packages/sheets/src/selection/__tests__/range-set.golden.test.ts b/packages/sheets/src/selection/__tests__/range-set.golden.test.ts
deleted file mode 100644
index f88e5e6..0000000
--- a/packages/sheets/src/selection/__tests__/range-set.golden.test.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * RangeSet ⇄ golden parity (Phase 6).
- *
- * Drives the NATIVE {@link RangeSet} through the SAME op programs frozen in
- * `src/grid/__golden__/selection.golden.json` (recorded from glide's
- * `CompactSelection` by `selection.golden.test.ts`). For every committed case it
- * rebuilds the SequenceResult shape and asserts it DEEP-EQUALS the recorded
- * `result` — i.e. RangeSet reproduces CompactSelection byte-for-byte. This file
- * is the executable RangeSet contract.
- */
-
-import { describe, expect, it } from 'vitest';
-
-import { loadGolden } from '../../grid/__golden__/parity.harness';
-import { RangeSet } from '../range-set';
-
-// ─── Op vocabulary — mirrors selection.golden.test.ts ───────────────────────
-
-type Op =
- | { op: 'add'; index: number }
- | { op: 'addRange'; start: number; end: number }
- | { op: 'remove'; index: number }
- | { op: 'removeRange'; start: number; end: number }
- | { op: 'offset'; amount: number }
- | { op: 'fromSingleIndex'; index: number }
- | { op: 'fromSingleRange'; start: number; end: number };
-
-interface HasIndexProbe {
- index: number;
- present: boolean;
-}
-
-interface SequenceResult {
- items?: number[];
- length: number;
- first: number | null;
- last: number | null;
- hasIndexProbes: HasIndexProbe[];
-}
-
-interface GoldenSequence {
- name: string;
- ops: Op[];
- result: SequenceResult;
-}
-
-/**
- * Reference executor's native twin: maps each op onto RangeSet. `fromSingle*`
- * RESETS the accumulator; every other op threads the immutable result forward.
- */
-function runOps(ops: Op[]): RangeSet {
- let sel = RangeSet.empty();
- for (const o of ops) {
- switch (o.op) {
- case 'add':
- sel = sel.add(o.index);
- break;
- case 'addRange':
- sel = sel.add([o.start, o.end]);
- break;
- case 'remove':
- sel = sel.remove(o.index);
- break;
- case 'removeRange':
- sel = sel.remove([o.start, o.end]);
- break;
- case 'offset':
- sel = sel.offset(o.amount);
- break;
- case 'fromSingleIndex':
- sel = RangeSet.fromSingleSelection(o.index);
- break;
- case 'fromSingleRange':
- sel = RangeSet.fromSingleSelection([o.start, o.end]);
- break;
- }
- }
- return sel;
-}
-
-/**
- * Rebuild the recorded shape from a RangeSet. `items` is OMITTED when the golden
- * omits it (the `sampleItems: false` 10k cases — detected by the absence of an
- * `items` key on the committed result), matching `record()` in the spec file.
- */
-function record(sel: RangeSet, probeIndices: number[], sampleItems: boolean): SequenceResult {
- const first = sel.first();
- const last = sel.last();
- const result: SequenceResult = {
- length: sel.length,
- first: first === undefined ? null : first,
- last: last === undefined ? null : last,
- hasIndexProbes: probeIndices.map((index) => ({ index, present: sel.hasIndex(index) })),
- };
- if (sampleItems) result.items = sel.toArray();
- return result;
-}
-
-const GOLDEN = loadGolden('selection.golden') as GoldenSequence[];
-
-describe('RangeSet golden parity — reproduces CompactSelection (Phase 6)', () => {
- it.each(GOLDEN.map((seq) => [seq.name, seq] as const))('%s', (_name, seq) => {
- const probes = seq.result.hasIndexProbes.map((probe) => probe.index);
- const sampleItems = seq.result.items !== undefined;
- const actual = record(runOps(seq.ops), probes, sampleItems);
- expect(actual).toEqual(seq.result);
- });
-});
diff --git a/packages/sheets/src/selection/__tests__/range-set.test.ts b/packages/sheets/src/selection/__tests__/range-set.test.ts
new file mode 100644
index 0000000..2faa9f1
--- /dev/null
+++ b/packages/sheets/src/selection/__tests__/range-set.test.ts
@@ -0,0 +1,36 @@
+import { describe, expect, it } from 'vitest';
+
+import { RangeSet } from '../range-set';
+
+describe('RangeSet', () => {
+ it('merges touching and overlapping ranges without mutating prior selections', () => {
+ const first = RangeSet.empty().add([2, 5]);
+ const merged = first.add([5, 8]).add([0, 3]);
+
+ expect(first.toArray()).toEqual([2, 3, 4]);
+ expect(merged.toArray()).toEqual([0, 1, 2, 3, 4, 5, 6, 7]);
+ });
+
+ it('splits a range when removing an interior selection', () => {
+ const selection = RangeSet.fromSingleSelection([0, 10]).remove([3, 6]);
+
+ expect(selection.toArray()).toEqual([0, 1, 2, 6, 7, 8, 9]);
+ expect(selection.hasIndex(3)).toBe(false);
+ expect(selection.first()).toBe(0);
+ expect(selection.last()).toBe(9);
+ });
+
+ it('offsets sparse ranges while preserving their selected count', () => {
+ const selection = RangeSet.empty().add([0, 2]).add([5, 7]).offset(3);
+
+ expect(selection.toArray()).toEqual([3, 4, 8, 9]);
+ expect(selection.length).toBe(4);
+ });
+
+ it('treats empty and inverted ranges as no-ops', () => {
+ const selection = RangeSet.empty().add([1, 4]);
+
+ expect(selection.add([3, 3])).toBe(selection);
+ expect(selection.remove([5, 2])).toBe(selection);
+ });
+});
diff --git a/packages/sheets/src/selection/range-set.ts b/packages/sheets/src/selection/range-set.ts
index df1157c..4b424cd 100644
--- a/packages/sheets/src/selection/range-set.ts
+++ b/packages/sheets/src/selection/range-set.ts
@@ -8,9 +8,8 @@
* O(#ranges) instead of O(#rows). Every mutator returns a NEW RangeSet; the
* receiver is never mutated.
*
- * Behavior is frozen by `src/grid/__golden__/selection.golden.json` (the
- * `CompactSelection` reference) — this class MUST reproduce all 26 cases
- * byte-identically. See `src/selection/__tests__/range-set.golden.test.ts`.
+ * Focused tests protect merging, splitting, offsets, and immutability without
+ * freezing the obsolete grid implementation this class replaced.
*/
type Range = readonly [start: number, end: number];
@@ -61,9 +60,8 @@ function insertRange(ranges: readonly Range[], [s, e]: Range): Range[] {
* Subtract `[selMin, selMax)` from a sorted, disjoint range list, SPLITTING any
* covering range (removing the middle of one yields two).
*
- * This is a FAITHFUL port of glide `CompactSelection.remove` — INCLUDING its two
- * documented quirks (frozen by selection.golden.json), not a clean set
- * difference:
+ * This is a faithful port of glide `CompactSelection.remove`, including its two
+ * documented quirks rather than a clean set difference:
*
* 1. Overlap test is `start <= selMax && selMin <= end` — both bounds `<=`, so
* a range touching the cut is "intersected" (usually a harmless in-place
diff --git a/packages/sheets/src/stories/__tests__/stories-render.test.tsx b/packages/sheets/src/stories/__tests__/stories-render.test.tsx
index 72c12e1..2524299 100644
--- a/packages/sheets/src/stories/__tests__/stories-render.test.tsx
+++ b/packages/sheets/src/stories/__tests__/stories-render.test.tsx
@@ -1,199 +1,73 @@
/* @vitest-environment jsdom */
-//
-// Portable-stories render gate (Stage 3). Imports EVERY showcase/stress story via Storybook's
-// `composeStories` (the portable-stories API, re-exported by @storybook/react-vite) and renders
-// each one in jsdom with react-dom/client + act — the same mount idiom as the package's other
-// component tests (no @testing-library; not a dep here).
-//
-// Per story the gate asserts:
-// • it MOUNTS without throwing and renders SOMETHING (container gains children);
-// • for the grid-bearing stories, after the async mock query resolves the ported DOM grid
-// POPULATES — a [data-part-id="sheets-viewport"] with [role="gridcell"] nodes appears (we
-// poll for it). Edge-state stories (Loading / Empty / Error) and the custom-table Selection
-// harness legitimately render NO viewport, so the viewport assertion is applied only when a
-// viewport is present — never forced — and every story must still mount + render content.
-// • VIRTUALIZATION: any populated grid keeps a BOUNDED number of gridcell nodes in the DOM
-// (never one-per-row), and the 10k stress story specifically renders far fewer than 10000.
-//
-// composeStories applies each story's args/decorators/render but does NOT run its play(); we only
-// mount, so the (browser-only) interaction steps never execute under vitest.
import { act } from 'react';
import { createRoot, type Root } from 'react-dom/client';
-import { afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { composeStories } from '@storybook/react-vite';
+import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-import * as AllCellTypesStories from '../all-cell-types.stories';
-import * as EditingStories from '../editing.stories';
import * as StressStories from '../stress.stories';
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
-// A composed story is a render-able component; `storyName` is attached by composeStories.
-type ComposedStory = React.ComponentType & { storyName?: string };
-
-// composeStories(module) -> { [exportName]: ComposedStory }. Flatten every module into a flat list
-// of { title, name, Story } so one parametrized describe-block drives them all.
-interface NamedStory {
- title: string;
- name: string;
- Story: ComposedStory;
-}
-
-function collect(title: string, mod: Parameters[0]): NamedStory[] {
- const composed = composeStories(mod) as Record;
- return Object.entries(composed).map(([exportName, Story]) => ({
- title,
- name: Story.storyName ?? exportName,
- Story,
- }));
-}
-
-const ALL_STORIES: NamedStory[] = [
- ...collect('Showcase/All Cell Types', AllCellTypesStories),
- ...collect('Showcase/Editing', EditingStories),
- ...collect('Stress/10k Rows', StressStories),
-];
-
-// Every kept story (All Cell Types / Editing / Stress) renders the real DOM grid, so all are
-// expected to populate a viewport — no exemptions. (The former full-screen edge-state and
-// custom-table-harness stories were removed in the 3-story consolidation.)
-const NON_POPULATING = new Set();
-// Upper bound for "virtualized" — a populated grid must keep far fewer gridcell nodes than rows.
-const MAX_GRIDCELLS = 2000;
-// Per-test budget: the 100k / wide stress stories take a few seconds to build their dataset.
-const STORY_TEST_TIMEOUT = 30000;
-// Poll budget for a grid to populate — comfortably under STORY_TEST_TIMEOUT so the catch runs.
-const POPULATE_TIMEOUT = 8000;
-
const proto = window.HTMLElement.prototype;
-describe('Storybook stories render in jsdom (portable composeStories)', () => {
+describe('Sheets virtualization', () => {
let root: Root;
let container: HTMLDivElement;
- const origW = Object.getOwnPropertyDescriptor(proto, 'offsetWidth');
- const origH = Object.getOwnPropertyDescriptor(proto, 'offsetHeight');
- const origRect = proto.getBoundingClientRect;
-
- beforeAll(() => {
- expect(ALL_STORIES.length).toBeGreaterThan(0);
- });
+ const originalWidth = Object.getOwnPropertyDescriptor(proto, 'offsetWidth');
+ const originalHeight = Object.getOwnPropertyDescriptor(proto, 'offsetHeight');
+ const originalRect = proto.getBoundingClientRect;
beforeEach(() => {
- // jsdom does NO layout. Shim element geometry so TanStack Virtual works the way it does in a
- // real browser: a sized scroll element (offsetWidth/Height) AND a real per-row height
- // (getBoundingClientRect, read by the row virtualizer's measureElement). Without the row
- // height, 0-height rows make the virtual range unbounded — in infinite-scroll mode that
- // requests every page and loops (a jsdom measurement artifact, not a grid bug); a realistic
- // height bounds the window to a few dozen rows, exactly as in the browser.
Object.defineProperty(proto, 'offsetWidth', { configurable: true, get: () => 1200 });
Object.defineProperty(proto, 'offsetHeight', { configurable: true, get: () => 800 });
- proto.getBoundingClientRect = function () {
- return { width: 1200, height: 33, top: 0, left: 0, right: 1200, bottom: 33, x: 0, y: 0, toJSON() {} } as DOMRect;
- };
+ proto.getBoundingClientRect = () => ({
+ width: 1200,
+ height: 33,
+ top: 0,
+ left: 0,
+ right: 1200,
+ bottom: 33,
+ x: 0,
+ y: 0,
+ toJSON() {},
+ }) as DOMRect;
container = document.createElement('div');
document.body.appendChild(container);
root = createRoot(container);
});
afterEach(async () => {
- await act(async () => {
- root.unmount();
- });
+ await act(async () => root.unmount());
container.remove();
- // Overlay editors / portals mount onto document.body — clear any leftovers between stories.
- document.body.querySelectorAll('[data-slot="overlay-manager"], #portal').forEach((node) => node.remove());
- if (origW) Object.defineProperty(proto, 'offsetWidth', origW);
- else delete (proto as unknown as Record).offsetWidth;
- if (origH) Object.defineProperty(proto, 'offsetHeight', origH);
- else delete (proto as unknown as Record).offsetHeight;
- proto.getBoundingClientRect = origRect;
+ if (originalWidth) Object.defineProperty(proto, 'offsetWidth', originalWidth);
+ if (originalHeight) Object.defineProperty(proto, 'offsetHeight', originalHeight);
+ proto.getBoundingClientRect = originalRect;
});
- for (const { title, name, Story } of ALL_STORIES) {
- it(`${title} › ${name} mounts + renders`, { timeout: STORY_TEST_TIMEOUT }, async () => {
- await act(async () => {
- root.render();
- });
-
- // Let the async mock query resolve. Grid-bearing stories POPULATE — poll until
- // [role="gridcell"] nodes appear (the viewport div mounts before data loads, so we must
- // wait on the cells, not the viewport). Edge-state (Loading/Empty/Error) + the custom
- // Selection harness render no gridcells; for those, settle the async path and rely on the
- // universal mount+content assertions below.
- const populates = !NON_POPULATING.has(`${title} › ${name}`);
- if (populates) {
- try {
- await waitFor(
- () => {
- expect(container.querySelectorAll('[role="gridcell"]').length).toBeGreaterThan(0);
- },
- { timeout: POPULATE_TIMEOUT },
- );
- } catch {
- // Falls through: a story without a populating grid is still validated by (1).
- }
- } else {
- // Settle the (never-resolving / empty) async path so the state UI commits.
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, 50));
- });
- }
+ it('keeps the 10,000-row story to a bounded DOM window', { timeout: 30_000 }, async () => {
+ const { TenThousandRows } = composeStories(StressStories);
+ await act(async () => root.render());
- // (1) Universal: the story mounted and rendered real DOM content (no crash, non-empty).
- expect(container.childElementCount).toBeGreaterThan(0);
- expect(container.querySelectorAll('*').length).toBeGreaterThan(0);
-
- // (2) If a grid viewport rendered, it must have populated AND stay virtualized (bounded
- // gridcell node count — never one node per data row) with zero canvas on the DOM path.
- const viewport = container.querySelector('[data-part-id="sheets-viewport"]');
- if (viewport && populates) {
- const gridcells = container.querySelectorAll('[role="gridcell"]');
- expect(gridcells.length).toBeGreaterThan(0);
- expect(gridcells.length).toBeLessThan(MAX_GRIDCELLS);
- expect(container.querySelectorAll('canvas').length).toBe(0);
- }
+ await waitFor(() => {
+ expect(container.querySelectorAll('[role="gridcell"]').length).toBeGreaterThan(0);
});
- }
- // The headline stress story: 10k rows, infinite scroll. Assert it mounts, the virtualizer
- // renders a BOUNDED window (NOT 10000 DOM nodes), and the data really is 10k-scale.
- it('Stress/10k Rows › TenThousandRows virtualizes (bounded DOM nodes, not 10000)', { timeout: STORY_TEST_TIMEOUT }, async () => {
- const { TenThousandRows } = composeStories(StressStories) as Record;
- await act(async () => {
- root.render();
- });
- await waitFor(
- () => {
- expect(container.querySelector('[data-part-id="sheets-viewport"]')).not.toBeNull();
- expect(container.querySelectorAll('[role="gridcell"]').length).toBeGreaterThan(0);
- },
- { timeout: POPULATE_TIMEOUT },
- );
- const gridcells = container.querySelectorAll('[role="gridcell"]');
- // Bounded window: far fewer DOM gridcells than the 10000-row dataset (virtualization holds).
- expect(gridcells.length).toBeLessThan(MAX_GRIDCELLS);
- expect(container.querySelectorAll('canvas').length).toBe(0);
+ expect(container.querySelectorAll('[role="gridcell"]').length).toBeLessThan(2_000);
});
});
-// ─── Minimal async poller (mirrors the smoke-test idiom; no @testing-library in this package) ─────
-async function waitFor(assert: () => void, { timeout = 5000, interval = 30 } = {}): Promise {
- const start = Date.now();
+async function waitFor(assertion: () => void): Promise {
+ const deadline = Date.now() + 8_000;
let lastError: unknown;
- // eslint-disable-next-line no-constant-condition
- while (true) {
+ while (Date.now() < deadline) {
try {
- await act(async () => {
- await Promise.resolve();
- });
- assert();
+ await act(async () => Promise.resolve());
+ assertion();
return;
} catch (error) {
lastError = error;
- if (Date.now() - start > timeout) throw lastError;
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, interval));
- });
+ await act(async () => new Promise((resolve) => setTimeout(resolve, 30)));
}
}
+ throw lastError;
}
diff --git a/packages/sheets/src/stories/_support/fixtures.ts b/packages/sheets/src/stories/_support/fixtures.ts
index c577401..919e018 100644
--- a/packages/sheets/src/stories/_support/fixtures.ts
+++ b/packages/sheets/src/stories/_support/fixtures.ts
@@ -5,10 +5,8 @@
// that CellType regardless of gqlType (see cell-types/type-mapping.ts mapAliasToCellType).
// buildAllCellTypesTable emits ONE field per (forceable) CellType so the grid paints every view.
//
-// Row values mirror grid/__golden__/display-cases.ts patterns (strings, numbers, booleans, ISO
-// dates, arrays, {id,displayName} relations, image urls, geojson, …) but are generated by a
-// seeded PRNG (mulberry32) so makeRows(n) is fully reproducible — required for a stable 10k
-// stress test and visual regression.
+// Row values cover strings, numbers, booleans, ISO dates, relations, images,
+// and GeoJSON. A seeded PRNG keeps the 10k stress fixture reproducible.
import type { MetaTable, MetaField } from '../../forms/types';
import type { SheetsRow } from '../../grid/row-model';
import type { CellType } from '../../cell-types/types';
@@ -288,7 +286,7 @@ function valueForField(spec: FieldSpec, rng: () => number, rowIndex: number): un
case 'url':
return `https://example.com/${pick(rng, WORDS)}/${rowIndex}.html`;
// `pick(rng, COLORS)` consumes one rng() — same as the old url's `pick(rng, WORDS)` —
- // so non-media columns keep identical seeded values (golden stays minimal).
+ // so non-media columns keep identical seeded values.
case 'image':
return placeholderMedia(pick(rng, COLORS), 'IMG');
case 'video':
diff --git a/packages/sheets/src/table/__tests__/grid-viewport-active-cell.test.tsx b/packages/sheets/src/table/__tests__/grid-viewport-active-cell.test.tsx
index 8f5bd42..48ffbf2 100644
--- a/packages/sheets/src/table/__tests__/grid-viewport-active-cell.test.tsx
+++ b/packages/sheets/src/table/__tests__/grid-viewport-active-cell.test.tsx
@@ -146,19 +146,16 @@ describe('GridViewport active cell (focus ring + click-to-activate + arrow nav)'
return container.querySelector('[data-active="true"]');
}
- it('renders the active cell with aria-selected, the ring id, and the focus-ring class', async () => {
+ it('connects the active cell to the grid accessibility state', async () => {
await act(async () => {
root.render();
});
- // The active cell is [0,0] → id sheets-cell-0-0, aria-selected, ring class.
+ // The active cell is [0,0] and the grid points assistive technology to it.
const active = activeCellNode();
expect(active).toBeTruthy();
expect(active!.id).toBe('sheets-cell-0-0');
expect(active!.getAttribute('aria-selected')).toBe('true');
- expect(active!.className).toContain('ring-2');
-
- // The grid root mirrors it via aria-activedescendant.
expect(gridRoot().getAttribute('aria-activedescendant')).toBe('sheets-cell-0-0');
// Exactly ONE active cell.
diff --git a/packages/sheets/src/table/__tests__/grid-viewport-header.test.tsx b/packages/sheets/src/table/__tests__/grid-viewport-header.test.tsx
index 9b30812..6a76396 100644
--- a/packages/sheets/src/table/__tests__/grid-viewport-header.test.tsx
+++ b/packages/sheets/src/table/__tests__/grid-viewport-header.test.tsx
@@ -85,24 +85,6 @@ describe('GridViewport header row (sort caret + resize handle + sticky pin)', ()
return Array.from(container.querySelectorAll('[role="columnheader"]'));
}
- it('renders a columnheader per column, each carrying its title', async () => {
- await act(async () => {
- root.render();
- });
-
- const headers = headerCells();
- // 3 columns: sticky col0 + 2 virtualized.
- expect(headers.length).toBe(COLUMNS.length);
-
- const titles = headers.map((h) => h.textContent ?? '');
- expect(titles.some((t) => t.includes('Name'))).toBe(true);
- expect(titles.some((t) => t.includes('Count'))).toBe(true);
- expect(titles.some((t) => t.includes('Active'))).toBe(true);
-
- // Each header is keyed to its column id for the shell to target.
- expect(headers.map((h) => h.getAttribute('data-col-key')).sort()).toEqual(['active', 'count', 'name']);
- });
-
it('toggles sort via onHeaderClick(colKey) when a header is clicked', async () => {
const clicks: string[] = [];
await act(async () => {
diff --git a/packages/sheets/src/table/__tests__/grid-viewport-rowmarker.test.tsx b/packages/sheets/src/table/__tests__/grid-viewport-rowmarker.test.tsx
index 3313719..111bc66 100644
--- a/packages/sheets/src/table/__tests__/grid-viewport-rowmarker.test.tsx
+++ b/packages/sheets/src/table/__tests__/grid-viewport-rowmarker.test.tsx
@@ -147,32 +147,12 @@ describe('GridViewport row-marker column (leading checkbox + select-all → Rang
function markerHeader(): HTMLElement | null {
return container.querySelector('[data-slot="row-marker-header"]');
}
- function gridCells(): HTMLElement[] {
- return Array.from(container.querySelectorAll('[role="gridcell"]'));
- }
// The base-ui Checkbox renders a