@ggts-sh/spec 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/artifact.d.ts +11 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +71 -0
- package/dist/artifact.js.map +1 -0
- package/dist/builder-core.d.ts +100 -0
- package/dist/builder-core.d.ts.map +1 -0
- package/dist/builder-core.js +176 -0
- package/dist/builder-core.js.map +1 -0
- package/dist/builder-data.d.ts +36 -0
- package/dist/builder-data.d.ts.map +1 -0
- package/dist/builder-data.js +123 -0
- package/dist/builder-data.js.map +1 -0
- package/dist/builder-geoms.d.ts +128 -0
- package/dist/builder-geoms.d.ts.map +1 -0
- package/dist/builder-geoms.js +221 -0
- package/dist/builder-geoms.js.map +1 -0
- package/dist/builder-options.d.ts +323 -0
- package/dist/builder-options.d.ts.map +1 -0
- package/dist/builder-options.js +2 -0
- package/dist/builder-options.js.map +1 -0
- package/dist/builder-scales.d.ts +160 -0
- package/dist/builder-scales.d.ts.map +1 -0
- package/dist/builder-scales.js +322 -0
- package/dist/builder-scales.js.map +1 -0
- package/dist/builder.d.ts +242 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +42 -0
- package/dist/builder.js.map +1 -0
- package/dist/capabilities-data.d.ts +72 -0
- package/dist/capabilities-data.d.ts.map +1 -0
- package/dist/capabilities-data.js +337 -0
- package/dist/capabilities-data.js.map +1 -0
- package/dist/capabilities-helpers.d.ts +31 -0
- package/dist/capabilities-helpers.d.ts.map +1 -0
- package/dist/capabilities-helpers.js +41 -0
- package/dist/capabilities-helpers.js.map +1 -0
- package/dist/capabilities.d.ts +22 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +154 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/coord-helpers.d.ts +102 -0
- package/dist/coord-helpers.d.ts.map +1 -0
- package/dist/coord-helpers.js +90 -0
- package/dist/coord-helpers.js.map +1 -0
- package/dist/coord-reference-build.d.ts +50 -0
- package/dist/coord-reference-build.d.ts.map +1 -0
- package/dist/coord-reference-build.js +211 -0
- package/dist/coord-reference-build.js.map +1 -0
- package/dist/coord-reference.d.ts +52 -0
- package/dist/coord-reference.d.ts.map +1 -0
- package/dist/coord-reference.js +27 -0
- package/dist/coord-reference.js.map +1 -0
- package/dist/error-catalog.d.ts +258 -0
- package/dist/error-catalog.d.ts.map +1 -0
- package/dist/error-catalog.js +235 -0
- package/dist/error-catalog.js.map +1 -0
- package/dist/error-prose-shared.d.ts +100 -0
- package/dist/error-prose-shared.d.ts.map +1 -0
- package/dist/error-prose-shared.js +95 -0
- package/dist/error-prose-shared.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +52 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/coord-reference-data.d.ts +189 -0
- package/dist/generated/coord-reference-data.d.ts.map +1 -0
- package/dist/generated/coord-reference-data.js +212 -0
- package/dist/generated/coord-reference-data.js.map +1 -0
- package/dist/generated/geom-param-keys.d.ts +58 -0
- package/dist/generated/geom-param-keys.d.ts.map +1 -0
- package/dist/generated/geom-param-keys.js +223 -0
- package/dist/generated/geom-param-keys.js.map +1 -0
- package/dist/generated/geom-reference-data.d.ts +2377 -0
- package/dist/generated/geom-reference-data.d.ts.map +1 -0
- package/dist/generated/geom-reference-data.js +2790 -0
- package/dist/generated/geom-reference-data.js.map +1 -0
- package/dist/generated/guide-reference-data.d.ts +219 -0
- package/dist/generated/guide-reference-data.d.ts.map +1 -0
- package/dist/generated/guide-reference-data.js +253 -0
- package/dist/generated/guide-reference-data.js.map +1 -0
- package/dist/generated/plot-spec-validator.d.ts +2 -0
- package/dist/generated/plot-spec-validator.d.ts.map +1 -0
- package/dist/generated/plot-spec-validator.js +6274 -0
- package/dist/generated/plot-spec-validator.js.map +1 -0
- package/dist/generated/position-reference-data.d.ts +82 -0
- package/dist/generated/position-reference-data.d.ts.map +1 -0
- package/dist/generated/position-reference-data.js +181 -0
- package/dist/generated/position-reference-data.js.map +1 -0
- package/dist/generated/scale-reference-data.d.ts +8366 -0
- package/dist/generated/scale-reference-data.d.ts.map +1 -0
- package/dist/generated/scale-reference-data.js +9821 -0
- package/dist/generated/scale-reference-data.js.map +1 -0
- package/dist/generated/stat-reference-data.d.ts +241 -0
- package/dist/generated/stat-reference-data.d.ts.map +1 -0
- package/dist/generated/stat-reference-data.js +311 -0
- package/dist/generated/stat-reference-data.js.map +1 -0
- package/dist/geom-params-build.d.ts +3 -0
- package/dist/geom-params-build.d.ts.map +1 -0
- package/dist/geom-params-build.js +80 -0
- package/dist/geom-params-build.js.map +1 -0
- package/dist/geom-params.d.ts +13 -0
- package/dist/geom-params.d.ts.map +1 -0
- package/dist/geom-params.js +7 -0
- package/dist/geom-params.js.map +1 -0
- package/dist/geom-reference-build.d.ts +29 -0
- package/dist/geom-reference-build.d.ts.map +1 -0
- package/dist/geom-reference-build.js +221 -0
- package/dist/geom-reference-build.js.map +1 -0
- package/dist/geom-reference.d.ts +52 -0
- package/dist/geom-reference.d.ts.map +1 -0
- package/dist/geom-reference.js +72 -0
- package/dist/geom-reference.js.map +1 -0
- package/dist/guide-helpers.d.ts +20 -0
- package/dist/guide-helpers.d.ts.map +1 -0
- package/dist/guide-helpers.js +25 -0
- package/dist/guide-helpers.js.map +1 -0
- package/dist/guide-reference-build.d.ts +42 -0
- package/dist/guide-reference-build.d.ts.map +1 -0
- package/dist/guide-reference-build.js +180 -0
- package/dist/guide-reference-build.js.map +1 -0
- package/dist/guide-reference.d.ts +48 -0
- package/dist/guide-reference.d.ts.map +1 -0
- package/dist/guide-reference.js +32 -0
- package/dist/guide-reference.js.map +1 -0
- package/dist/hue-grey-palettes.d.ts +15 -0
- package/dist/hue-grey-palettes.d.ts.map +1 -0
- package/dist/hue-grey-palettes.js +77 -0
- package/dist/hue-grey-palettes.js.map +1 -0
- package/dist/index.d.ts +364 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +225 -0
- package/dist/index.js.map +1 -0
- package/dist/lint-catalog.d.ts +47 -0
- package/dist/lint-catalog.d.ts.map +1 -0
- package/dist/lint-catalog.js +39 -0
- package/dist/lint-catalog.js.map +1 -0
- package/dist/lint-layer-rules.d.ts +18 -0
- package/dist/lint-layer-rules.d.ts.map +1 -0
- package/dist/lint-layer-rules.js +145 -0
- package/dist/lint-layer-rules.js.map +1 -0
- package/dist/lint-scale-rules.d.ts +8 -0
- package/dist/lint-scale-rules.d.ts.map +1 -0
- package/dist/lint-scale-rules.js +254 -0
- package/dist/lint-scale-rules.js.map +1 -0
- package/dist/lint.d.ts +62 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +57 -0
- package/dist/lint.js.map +1 -0
- package/dist/normalize-coord.d.ts +8 -0
- package/dist/normalize-coord.d.ts.map +1 -0
- package/dist/normalize-coord.js +123 -0
- package/dist/normalize-coord.js.map +1 -0
- package/dist/normalize-input-layers-marks.d.ts +208 -0
- package/dist/normalize-input-layers-marks.d.ts.map +1 -0
- package/dist/normalize-input-layers-marks.js +2 -0
- package/dist/normalize-input-layers-marks.js.map +1 -0
- package/dist/normalize-input-layers-special.d.ts +131 -0
- package/dist/normalize-input-layers-special.d.ts.map +1 -0
- package/dist/normalize-input-layers-special.js +2 -0
- package/dist/normalize-input-layers-special.js.map +1 -0
- package/dist/normalize-input.d.ts +81 -0
- package/dist/normalize-input.d.ts.map +1 -0
- package/dist/normalize-input.js +2 -0
- package/dist/normalize-input.js.map +1 -0
- package/dist/normalize-paint.d.ts +8 -0
- package/dist/normalize-paint.d.ts.map +1 -0
- package/dist/normalize-paint.js +83 -0
- package/dist/normalize-paint.js.map +1 -0
- package/dist/normalize-scales.d.ts +7 -0
- package/dist/normalize-scales.d.ts.map +1 -0
- package/dist/normalize-scales.js +90 -0
- package/dist/normalize-scales.js.map +1 -0
- package/dist/normalize.d.ts +46 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +279 -0
- package/dist/normalize.js.map +1 -0
- package/dist/paint-helpers.d.ts +45 -0
- package/dist/paint-helpers.d.ts.map +1 -0
- package/dist/paint-helpers.js +48 -0
- package/dist/paint-helpers.js.map +1 -0
- package/dist/pipeline-error-catalog.d.ts +319 -0
- package/dist/pipeline-error-catalog.d.ts.map +1 -0
- package/dist/pipeline-error-catalog.js +260 -0
- package/dist/pipeline-error-catalog.js.map +1 -0
- package/dist/portability-check.d.ts +35 -0
- package/dist/portability-check.d.ts.map +1 -0
- package/dist/portability-check.js +121 -0
- package/dist/portability-check.js.map +1 -0
- package/dist/portability-lossy.d.ts +19 -0
- package/dist/portability-lossy.d.ts.map +1 -0
- package/dist/portability-lossy.js +65 -0
- package/dist/portability-lossy.js.map +1 -0
- package/dist/portability.d.ts +23 -0
- package/dist/portability.d.ts.map +1 -0
- package/dist/portability.js +23 -0
- package/dist/portability.js.map +1 -0
- package/dist/portable-builder.d.ts +215 -0
- package/dist/portable-builder.d.ts.map +1 -0
- package/dist/portable-builder.js +27 -0
- package/dist/portable-builder.js.map +1 -0
- package/dist/portable-entry.d.ts +16 -0
- package/dist/portable-entry.d.ts.map +1 -0
- package/dist/portable-entry.js +14 -0
- package/dist/portable-entry.js.map +1 -0
- package/dist/position-reference-build.d.ts +29 -0
- package/dist/position-reference-build.d.ts.map +1 -0
- package/dist/position-reference-build.js +115 -0
- package/dist/position-reference-build.js.map +1 -0
- package/dist/position-reference.d.ts +34 -0
- package/dist/position-reference.d.ts.map +1 -0
- package/dist/position-reference.js +19 -0
- package/dist/position-reference.js.map +1 -0
- package/dist/runtime.d.ts +139 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scale-color-helpers.d.ts +121 -0
- package/dist/scale-color-helpers.d.ts.map +1 -0
- package/dist/scale-color-helpers.js +188 -0
- package/dist/scale-color-helpers.js.map +1 -0
- package/dist/scale-color-hue-grey.d.ts +52 -0
- package/dist/scale-color-hue-grey.d.ts.map +1 -0
- package/dist/scale-color-hue-grey.js +60 -0
- package/dist/scale-color-hue-grey.js.map +1 -0
- package/dist/scale-color-stops.d.ts +85 -0
- package/dist/scale-color-stops.d.ts.map +1 -0
- package/dist/scale-color-stops.js +87 -0
- package/dist/scale-color-stops.js.map +1 -0
- package/dist/scale-color-viridis.d.ts +52 -0
- package/dist/scale-color-viridis.d.ts.map +1 -0
- package/dist/scale-color-viridis.js +68 -0
- package/dist/scale-color-viridis.js.map +1 -0
- package/dist/scale-helpers.d.ts +20 -0
- package/dist/scale-helpers.d.ts.map +1 -0
- package/dist/scale-helpers.js +20 -0
- package/dist/scale-helpers.js.map +1 -0
- package/dist/scale-multi-helpers.d.ts +61 -0
- package/dist/scale-multi-helpers.d.ts.map +1 -0
- package/dist/scale-multi-helpers.js +147 -0
- package/dist/scale-multi-helpers.js.map +1 -0
- package/dist/scale-position-helpers.d.ts +81 -0
- package/dist/scale-position-helpers.d.ts.map +1 -0
- package/dist/scale-position-helpers.js +133 -0
- package/dist/scale-position-helpers.js.map +1 -0
- package/dist/scale-reference-build.d.ts +50 -0
- package/dist/scale-reference-build.d.ts.map +1 -0
- package/dist/scale-reference-build.js +147 -0
- package/dist/scale-reference-build.js.map +1 -0
- package/dist/scale-reference-classify-color.d.ts +11 -0
- package/dist/scale-reference-classify-color.d.ts.map +1 -0
- package/dist/scale-reference-classify-color.js +292 -0
- package/dist/scale-reference-classify-color.js.map +1 -0
- package/dist/scale-reference-classify-position.d.ts +10 -0
- package/dist/scale-reference-classify-position.d.ts.map +1 -0
- package/dist/scale-reference-classify-position.js +137 -0
- package/dist/scale-reference-classify-position.js.map +1 -0
- package/dist/scale-reference-classify-style.d.ts +10 -0
- package/dist/scale-reference-classify-style.d.ts.map +1 -0
- package/dist/scale-reference-classify-style.js +194 -0
- package/dist/scale-reference-classify-style.js.map +1 -0
- package/dist/scale-reference-classify-support.d.ts +37 -0
- package/dist/scale-reference-classify-support.d.ts.map +1 -0
- package/dist/scale-reference-classify-support.js +206 -0
- package/dist/scale-reference-classify-support.js.map +1 -0
- package/dist/scale-reference.d.ts +80 -0
- package/dist/scale-reference.d.ts.map +1 -0
- package/dist/scale-reference.js +85 -0
- package/dist/scale-reference.js.map +1 -0
- package/dist/scale-style-helpers.d.ts +158 -0
- package/dist/scale-style-helpers.d.ts.map +1 -0
- package/dist/scale-style-helpers.js +197 -0
- package/dist/scale-style-helpers.js.map +1 -0
- package/dist/schema-catalog.d.ts +62 -0
- package/dist/schema-catalog.d.ts.map +1 -0
- package/dist/schema-catalog.js +208 -0
- package/dist/schema-catalog.js.map +1 -0
- package/dist/schema-declarations.d.ts +1585 -0
- package/dist/schema-declarations.d.ts.map +1 -0
- package/dist/schema-declarations.js +51 -0
- package/dist/schema-declarations.js.map +1 -0
- package/dist/schema-decls-data.d.ts +58 -0
- package/dist/schema-decls-data.d.ts.map +1 -0
- package/dist/schema-decls-data.js +151 -0
- package/dist/schema-decls-data.js.map +1 -0
- package/dist/schema-decls-guides-theme.d.ts +166 -0
- package/dist/schema-decls-guides-theme.d.ts.map +1 -0
- package/dist/schema-decls-guides-theme.js +251 -0
- package/dist/schema-decls-guides-theme.js.map +1 -0
- package/dist/schema-decls-layers-col-boxplot.d.ts +118 -0
- package/dist/schema-decls-layers-col-boxplot.d.ts.map +1 -0
- package/dist/schema-decls-layers-col-boxplot.js +239 -0
- package/dist/schema-decls-layers-col-boxplot.js.map +1 -0
- package/dist/schema-decls-layers-count-pointrange.d.ts +89 -0
- package/dist/schema-decls-layers-count-pointrange.d.ts.map +1 -0
- package/dist/schema-decls-layers-count-pointrange.js +190 -0
- package/dist/schema-decls-layers-count-pointrange.js.map +1 -0
- package/dist/schema-decls-layers-crossbar-jitter.d.ts +129 -0
- package/dist/schema-decls-layers-crossbar-jitter.d.ts.map +1 -0
- package/dist/schema-decls-layers-crossbar-jitter.js +255 -0
- package/dist/schema-decls-layers-crossbar-jitter.js.map +1 -0
- package/dist/schema-decls-layers-point-path.d.ts +49 -0
- package/dist/schema-decls-layers-point-path.d.ts.map +1 -0
- package/dist/schema-decls-layers-point-path.js +156 -0
- package/dist/schema-decls-layers-point-path.js.map +1 -0
- package/dist/schema-decls-layers-sf-blank.d.ts +89 -0
- package/dist/schema-decls-layers-sf-blank.d.ts.map +1 -0
- package/dist/schema-decls-layers-sf-blank.js +254 -0
- package/dist/schema-decls-layers-sf-blank.js.map +1 -0
- package/dist/schema-decls-layers-text-map.d.ts +80 -0
- package/dist/schema-decls-layers-text-map.d.ts.map +1 -0
- package/dist/schema-decls-layers-text-map.js +151 -0
- package/dist/schema-decls-layers-text-map.js.map +1 -0
- package/dist/schema-decls-paint.d.ts +39 -0
- package/dist/schema-decls-paint.d.ts.map +1 -0
- package/dist/schema-decls-paint.js +95 -0
- package/dist/schema-decls-paint.js.map +1 -0
- package/dist/schema-decls-params-area-abline.d.ts +85 -0
- package/dist/schema-decls-params-area-abline.d.ts.map +1 -0
- package/dist/schema-decls-params-area-abline.js +259 -0
- package/dist/schema-decls-params-area-abline.js.map +1 -0
- package/dist/schema-decls-params-col-contour.d.ts +61 -0
- package/dist/schema-decls-params-col-contour.d.ts.map +1 -0
- package/dist/schema-decls-params-col-contour.js +202 -0
- package/dist/schema-decls-params-col-contour.js.map +1 -0
- package/dist/schema-decls-params-curve-label.d.ts +64 -0
- package/dist/schema-decls-params-curve-label.d.ts.map +1 -0
- package/dist/schema-decls-params-curve-label.js +204 -0
- package/dist/schema-decls-params-curve-label.js.map +1 -0
- package/dist/schema-decls-params-errorbar-position.d.ts +83 -0
- package/dist/schema-decls-params-errorbar-position.d.ts.map +1 -0
- package/dist/schema-decls-params-errorbar-position.js +264 -0
- package/dist/schema-decls-params-errorbar-position.js.map +1 -0
- package/dist/schema-decls-params-point-path.d.ts +61 -0
- package/dist/schema-decls-params-point-path.d.ts.map +1 -0
- package/dist/schema-decls-params-point-path.js +240 -0
- package/dist/schema-decls-params-point-path.js.map +1 -0
- package/dist/schema-decls-params-violin-summary.d.ts +78 -0
- package/dist/schema-decls-params-violin-summary.d.ts.map +1 -0
- package/dist/schema-decls-params-violin-summary.js +272 -0
- package/dist/schema-decls-params-violin-summary.js.map +1 -0
- package/dist/schema-decls-plot.d.ts +80 -0
- package/dist/schema-decls-plot.d.ts.map +1 -0
- package/dist/schema-decls-plot.js +222 -0
- package/dist/schema-decls-plot.js.map +1 -0
- package/dist/schema-decls-scales-guides.d.ts +291 -0
- package/dist/schema-decls-scales-guides.d.ts.map +1 -0
- package/dist/schema-decls-scales-guides.js +189 -0
- package/dist/schema-decls-scales-guides.js.map +1 -0
- package/dist/schema-decls-scales.d.ts +124 -0
- package/dist/schema-decls-scales.d.ts.map +1 -0
- package/dist/schema-decls-scales.js +279 -0
- package/dist/schema-decls-scales.js.map +1 -0
- package/dist/schema-imports.d.ts +1679 -0
- package/dist/schema-imports.d.ts.map +1 -0
- package/dist/schema-imports.js +104 -0
- package/dist/schema-imports.js.map +1 -0
- package/dist/schema-name-schemas.d.ts +18 -0
- package/dist/schema-name-schemas.d.ts.map +1 -0
- package/dist/schema-name-schemas.js +13 -0
- package/dist/schema-name-schemas.js.map +1 -0
- package/dist/schema-names.d.ts +53 -0
- package/dist/schema-names.d.ts.map +1 -0
- package/dist/schema-names.js +229 -0
- package/dist/schema-names.js.map +1 -0
- package/dist/schema-types.d.ts +336 -0
- package/dist/schema-types.d.ts.map +1 -0
- package/dist/schema-types.js +10 -0
- package/dist/schema-types.js.map +1 -0
- package/dist/schema.d.ts +38 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +34 -0
- package/dist/schema.js.map +1 -0
- package/dist/stat-reference-build.d.ts +24 -0
- package/dist/stat-reference-build.d.ts.map +1 -0
- package/dist/stat-reference-build.js +86 -0
- package/dist/stat-reference-build.js.map +1 -0
- package/dist/stat-reference.d.ts +33 -0
- package/dist/stat-reference.d.ts.map +1 -0
- package/dist/stat-reference.js +19 -0
- package/dist/stat-reference.js.map +1 -0
- package/dist/structural-gate.d.ts +15 -0
- package/dist/structural-gate.d.ts.map +1 -0
- package/dist/structural-gate.js +34 -0
- package/dist/structural-gate.js.map +1 -0
- package/dist/temporal-column.d.ts +33 -0
- package/dist/temporal-column.d.ts.map +1 -0
- package/dist/temporal-column.js +247 -0
- package/dist/temporal-column.js.map +1 -0
- package/dist/temporal-guides.d.ts +11 -0
- package/dist/temporal-guides.d.ts.map +1 -0
- package/dist/temporal-guides.js +11 -0
- package/dist/temporal-guides.js.map +1 -0
- package/dist/temporal-interval-schema.d.ts +9 -0
- package/dist/temporal-interval-schema.d.ts.map +1 -0
- package/dist/temporal-interval-schema.js +25 -0
- package/dist/temporal-interval-schema.js.map +1 -0
- package/dist/temporal-interval.d.ts +29 -0
- package/dist/temporal-interval.d.ts.map +1 -0
- package/dist/temporal-interval.js +122 -0
- package/dist/temporal-interval.js.map +1 -0
- package/dist/temporal-parse-core.d.ts +96 -0
- package/dist/temporal-parse-core.d.ts.map +1 -0
- package/dist/temporal-parse-core.js +235 -0
- package/dist/temporal-parse-core.js.map +1 -0
- package/dist/temporal-parse-format.d.ts +13 -0
- package/dist/temporal-parse-format.d.ts.map +1 -0
- package/dist/temporal-parse-format.js +180 -0
- package/dist/temporal-parse-format.js.map +1 -0
- package/dist/temporal-parse-schema.d.ts +11 -0
- package/dist/temporal-parse-schema.d.ts.map +1 -0
- package/dist/temporal-parse-schema.js +23 -0
- package/dist/temporal-parse-schema.js.map +1 -0
- package/dist/temporal-parse.d.ts +18 -0
- package/dist/temporal-parse.d.ts.map +1 -0
- package/dist/temporal-parse.js +183 -0
- package/dist/temporal-parse.js.map +1 -0
- package/dist/temporal-polyfill.d.ts +3 -0
- package/dist/temporal-polyfill.d.ts.map +1 -0
- package/dist/temporal-polyfill.js +25 -0
- package/dist/temporal-polyfill.js.map +1 -0
- package/dist/temporal-ticks.d.ts +20 -0
- package/dist/temporal-ticks.d.ts.map +1 -0
- package/dist/temporal-ticks.js +246 -0
- package/dist/temporal-ticks.js.map +1 -0
- package/dist/temporal.d.ts +109 -0
- package/dist/temporal.d.ts.map +1 -0
- package/dist/temporal.js +73 -0
- package/dist/temporal.js.map +1 -0
- package/dist/validate-data-checks-color-temporal.d.ts +58 -0
- package/dist/validate-data-checks-color-temporal.d.ts.map +1 -0
- package/dist/validate-data-checks-color-temporal.js +168 -0
- package/dist/validate-data-checks-color-temporal.js.map +1 -0
- package/dist/validate-data-checks-color.d.ts +28 -0
- package/dist/validate-data-checks-color.d.ts.map +1 -0
- package/dist/validate-data-checks-color.js +296 -0
- package/dist/validate-data-checks-color.js.map +1 -0
- package/dist/validate-data-checks-layer.d.ts +37 -0
- package/dist/validate-data-checks-layer.d.ts.map +1 -0
- package/dist/validate-data-checks-layer.js +343 -0
- package/dist/validate-data-checks-layer.js.map +1 -0
- package/dist/validate-data-checks-position.d.ts +45 -0
- package/dist/validate-data-checks-position.d.ts.map +1 -0
- package/dist/validate-data-checks-position.js +204 -0
- package/dist/validate-data-checks-position.js.map +1 -0
- package/dist/validate-data-checks-style-finite.d.ts +24 -0
- package/dist/validate-data-checks-style-finite.d.ts.map +1 -0
- package/dist/validate-data-checks-style-finite.js +40 -0
- package/dist/validate-data-checks-style-finite.js.map +1 -0
- package/dist/validate-data-checks-style-numeric.d.ts +26 -0
- package/dist/validate-data-checks-style-numeric.d.ts.map +1 -0
- package/dist/validate-data-checks-style-numeric.js +327 -0
- package/dist/validate-data-checks-style-numeric.js.map +1 -0
- package/dist/validate-data-checks-style.d.ts +14 -0
- package/dist/validate-data-checks-style.d.ts.map +1 -0
- package/dist/validate-data-checks-style.js +14 -0
- package/dist/validate-data-checks-style.js.map +1 -0
- package/dist/validate-data-checks-temporal.d.ts +57 -0
- package/dist/validate-data-checks-temporal.d.ts.map +1 -0
- package/dist/validate-data-checks-temporal.js +83 -0
- package/dist/validate-data-checks-temporal.js.map +1 -0
- package/dist/validate-data-checks.d.ts +31 -0
- package/dist/validate-data-checks.d.ts.map +1 -0
- package/dist/validate-data-checks.js +110 -0
- package/dist/validate-data-checks.js.map +1 -0
- package/dist/validate-data-evidence.d.ts +69 -0
- package/dist/validate-data-evidence.d.ts.map +1 -0
- package/dist/validate-data-evidence.js +329 -0
- package/dist/validate-data-evidence.js.map +1 -0
- package/dist/validate-data.d.ts +73 -0
- package/dist/validate-data.d.ts.map +1 -0
- package/dist/validate-data.js +30 -0
- package/dist/validate-data.js.map +1 -0
- package/dist/validate-map-errors.d.ts +32 -0
- package/dist/validate-map-errors.d.ts.map +1 -0
- package/dist/validate-map-errors.js +76 -0
- package/dist/validate-map-errors.js.map +1 -0
- package/dist/validate-map-forms.d.ts +43 -0
- package/dist/validate-map-forms.d.ts.map +1 -0
- package/dist/validate-map-forms.js +125 -0
- package/dist/validate-map-forms.js.map +1 -0
- package/dist/validate-map-path-keywords.d.ts +11 -0
- package/dist/validate-map-path-keywords.d.ts.map +1 -0
- package/dist/validate-map-path-keywords.js +95 -0
- package/dist/validate-map-path-keywords.js.map +1 -0
- package/dist/validate-map-path-unions.d.ts +27 -0
- package/dist/validate-map-path-unions.d.ts.map +1 -0
- package/dist/validate-map-path-unions.js +200 -0
- package/dist/validate-map-path-unions.js.map +1 -0
- package/dist/validate-schema-shape.d.ts +69 -0
- package/dist/validate-schema-shape.d.ts.map +1 -0
- package/dist/validate-schema-shape.js +156 -0
- package/dist/validate-schema-shape.js.map +1 -0
- package/dist/validate-schema-walk.d.ts +34 -0
- package/dist/validate-schema-walk.d.ts.map +1 -0
- package/dist/validate-schema-walk.js +216 -0
- package/dist/validate-schema-walk.js.map +1 -0
- package/dist/validate-structure-facet.d.ts +8 -0
- package/dist/validate-structure-facet.d.ts.map +1 -0
- package/dist/validate-structure-facet.js +67 -0
- package/dist/validate-structure-facet.js.map +1 -0
- package/dist/validate-structure-layer-computed-y.d.ts +14 -0
- package/dist/validate-structure-layer-computed-y.d.ts.map +1 -0
- package/dist/validate-structure-layer-computed-y.js +70 -0
- package/dist/validate-structure-layer-computed-y.js.map +1 -0
- package/dist/validate-structure-layer-ribbon.d.ts +8 -0
- package/dist/validate-structure-layer-ribbon.d.ts.map +1 -0
- package/dist/validate-structure-layer-ribbon.js +36 -0
- package/dist/validate-structure-layer-ribbon.js.map +1 -0
- package/dist/validate-structure-layer-rule.d.ts +14 -0
- package/dist/validate-structure-layer-rule.d.ts.map +1 -0
- package/dist/validate-structure-layer-rule.js +90 -0
- package/dist/validate-structure-layer-rule.js.map +1 -0
- package/dist/validate-structure-layer-shared.d.ts +12 -0
- package/dist/validate-structure-layer-shared.d.ts.map +1 -0
- package/dist/validate-structure-layer-shared.js +17 -0
- package/dist/validate-structure-layer-shared.js.map +1 -0
- package/dist/validate-structure-layers.d.ts +12 -0
- package/dist/validate-structure-layers.d.ts.map +1 -0
- package/dist/validate-structure-layers.js +292 -0
- package/dist/validate-structure-layers.js.map +1 -0
- package/dist/validate-structure-paint.d.ts +12 -0
- package/dist/validate-structure-paint.d.ts.map +1 -0
- package/dist/validate-structure-paint.js +87 -0
- package/dist/validate-structure-paint.js.map +1 -0
- package/dist/validate-structure-scales.d.ts +10 -0
- package/dist/validate-structure-scales.d.ts.map +1 -0
- package/dist/validate-structure-scales.js +242 -0
- package/dist/validate-structure-scales.js.map +1 -0
- package/dist/validate-structure-style-bins.d.ts +17 -0
- package/dist/validate-structure-style-bins.d.ts.map +1 -0
- package/dist/validate-structure-style-bins.js +150 -0
- package/dist/validate-structure-style-bins.js.map +1 -0
- package/dist/validate-structure.d.ts +16 -0
- package/dist/validate-structure.d.ts.map +1 -0
- package/dist/validate-structure.js +16 -0
- package/dist/validate-structure.js.map +1 -0
- package/dist/validate.d.ts +24 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +178 -0
- package/dist/validate.js.map +1 -0
- package/package.json +59 -0
- package/schema/v0.json +9618 -0
- package/src/artifact.ts +81 -0
- package/src/builder-core.ts +276 -0
- package/src/builder-data.ts +156 -0
- package/src/builder-geoms.ts +290 -0
- package/src/builder-options.ts +428 -0
- package/src/builder-scales.ts +443 -0
- package/src/builder.ts +125 -0
- package/src/capabilities-data.ts +336 -0
- package/src/capabilities-helpers.ts +54 -0
- package/src/capabilities.ts +159 -0
- package/src/coord-helpers.ts +177 -0
- package/src/coord-reference-build.ts +283 -0
- package/src/coord-reference.ts +75 -0
- package/src/error-catalog.ts +253 -0
- package/src/error-prose-shared.ts +106 -0
- package/src/errors.ts +87 -0
- package/src/generated/coord-reference-data.ts +235 -0
- package/src/generated/geom-param-keys.ts +222 -0
- package/src/generated/geom-reference-data.ts +3024 -0
- package/src/generated/guide-reference-data.ts +284 -0
- package/src/generated/plot-spec-validator.ts +7335 -0
- package/src/generated/position-reference-data.ts +191 -0
- package/src/generated/scale-reference-data.ts +10665 -0
- package/src/generated/stat-reference-data.ts +339 -0
- package/src/geom-params-build.ts +92 -0
- package/src/geom-params.ts +14 -0
- package/src/geom-reference-build.ts +292 -0
- package/src/geom-reference.ts +127 -0
- package/src/guide-helpers.ts +44 -0
- package/src/guide-reference-build.ts +249 -0
- package/src/guide-reference.ts +76 -0
- package/src/hue-grey-palettes.ts +82 -0
- package/src/index.ts +400 -0
- package/src/lint-catalog.ts +57 -0
- package/src/lint-layer-rules.ts +175 -0
- package/src/lint-scale-rules.ts +285 -0
- package/src/lint.ts +126 -0
- package/src/normalize-coord.ts +126 -0
- package/src/normalize-input-layers-marks.ts +276 -0
- package/src/normalize-input-layers-special.ts +252 -0
- package/src/normalize-input.ts +154 -0
- package/src/normalize-paint.ts +98 -0
- package/src/normalize-scales.ts +108 -0
- package/src/normalize.ts +403 -0
- package/src/paint-helpers.ts +98 -0
- package/src/pipeline-error-catalog.ts +278 -0
- package/src/portability-check.ts +155 -0
- package/src/portability-lossy.ts +81 -0
- package/src/portability.ts +31 -0
- package/src/portable-builder.ts +35 -0
- package/src/portable-entry.ts +37 -0
- package/src/position-reference-build.ts +164 -0
- package/src/position-reference.ts +41 -0
- package/src/runtime.ts +198 -0
- package/src/scale-color-helpers.ts +263 -0
- package/src/scale-color-hue-grey.ts +95 -0
- package/src/scale-color-stops.ts +177 -0
- package/src/scale-color-viridis.ts +99 -0
- package/src/scale-helpers.ts +264 -0
- package/src/scale-multi-helpers.ts +220 -0
- package/src/scale-position-helpers.ts +231 -0
- package/src/scale-reference-build.ts +222 -0
- package/src/scale-reference-classify-color.ts +334 -0
- package/src/scale-reference-classify-position.ts +164 -0
- package/src/scale-reference-classify-style.ts +229 -0
- package/src/scale-reference-classify-support.ts +298 -0
- package/src/scale-reference.ts +165 -0
- package/src/scale-style-helpers.ts +316 -0
- package/src/schema-catalog.ts +222 -0
- package/src/schema-declarations.ts +51 -0
- package/src/schema-decls-data.ts +272 -0
- package/src/schema-decls-guides-theme.ts +395 -0
- package/src/schema-decls-layers-col-boxplot.ts +410 -0
- package/src/schema-decls-layers-count-pointrange.ts +321 -0
- package/src/schema-decls-layers-crossbar-jitter.ts +443 -0
- package/src/schema-decls-layers-point-path.ts +246 -0
- package/src/schema-decls-layers-sf-blank.ts +408 -0
- package/src/schema-decls-layers-text-map.ts +259 -0
- package/src/schema-decls-paint.ts +124 -0
- package/src/schema-decls-params-area-abline.ts +440 -0
- package/src/schema-decls-params-col-contour.ts +333 -0
- package/src/schema-decls-params-curve-label.ts +343 -0
- package/src/schema-decls-params-errorbar-position.ts +446 -0
- package/src/schema-decls-params-point-path.ts +394 -0
- package/src/schema-decls-params-violin-summary.ts +447 -0
- package/src/schema-decls-plot.ts +385 -0
- package/src/schema-decls-scales-guides.ts +233 -0
- package/src/schema-decls-scales.ts +432 -0
- package/src/schema-imports.ts +116 -0
- package/src/schema-name-schemas.ts +37 -0
- package/src/schema-names.ts +243 -0
- package/src/schema-types.ts +400 -0
- package/src/schema.ts +287 -0
- package/src/stat-reference-build.ts +145 -0
- package/src/stat-reference.ts +38 -0
- package/src/structural-gate.ts +42 -0
- package/src/temporal-column.ts +323 -0
- package/src/temporal-guides.ts +32 -0
- package/src/temporal-interval-schema.ts +40 -0
- package/src/temporal-interval.ts +151 -0
- package/src/temporal-parse-core.ts +331 -0
- package/src/temporal-parse-format.ts +222 -0
- package/src/temporal-parse-schema.ts +38 -0
- package/src/temporal-parse.ts +259 -0
- package/src/temporal-polyfill.ts +27 -0
- package/src/temporal-ticks.ts +312 -0
- package/src/temporal.ts +112 -0
- package/src/validate-data-checks-color-temporal.ts +261 -0
- package/src/validate-data-checks-color.ts +395 -0
- package/src/validate-data-checks-layer.ts +492 -0
- package/src/validate-data-checks-position.ts +275 -0
- package/src/validate-data-checks-style-finite.ts +55 -0
- package/src/validate-data-checks-style-numeric.ts +455 -0
- package/src/validate-data-checks-style.ts +13 -0
- package/src/validate-data-checks-temporal.ts +129 -0
- package/src/validate-data-checks.ts +157 -0
- package/src/validate-data-evidence.ts +419 -0
- package/src/validate-data.ts +114 -0
- package/src/validate-map-errors.ts +126 -0
- package/src/validate-map-forms.ts +148 -0
- package/src/validate-map-path-keywords.ts +129 -0
- package/src/validate-map-path-unions.ts +281 -0
- package/src/validate-schema-shape.ts +232 -0
- package/src/validate-schema-walk.ts +219 -0
- package/src/validate-structure-facet.ts +76 -0
- package/src/validate-structure-layer-computed-y.ts +94 -0
- package/src/validate-structure-layer-ribbon.ts +61 -0
- package/src/validate-structure-layer-rule.ts +98 -0
- package/src/validate-structure-layer-shared.ts +29 -0
- package/src/validate-structure-layers.ts +395 -0
- package/src/validate-structure-paint.ts +101 -0
- package/src/validate-structure-scales.ts +278 -0
- package/src/validate-structure-style-bins.ts +167 -0
- package/src/validate-structure.ts +16 -0
- package/src/validate.ts +212 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size/linewidth/alpha sequential/binned data-aware scale checks (incl. temporal).
|
|
3
|
+
* Barrel: validate-data-checks-style.ts. Orchestrator: validate-data-checks.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { SpecError } from "./errors.js";
|
|
6
|
+
import { parseTemporalColumn, type TemporalDecision } from "./temporal-column.js";
|
|
7
|
+
import { parseTemporal } from "./temporal-parse.js";
|
|
8
|
+
import type { FieldEvidenceEntry, FieldEvidenceMap } from "./validate-data-evidence.js";
|
|
9
|
+
import {
|
|
10
|
+
temporalDecisionForField,
|
|
11
|
+
temporalParserUsable,
|
|
12
|
+
type ChannelFieldUse,
|
|
13
|
+
type TemporalDecisionCache,
|
|
14
|
+
} from "./validate-data-checks-temporal.js";
|
|
15
|
+
|
|
16
|
+
type NumericStyleConfig = {
|
|
17
|
+
type?: string;
|
|
18
|
+
temporalKind?: unknown;
|
|
19
|
+
parse?: unknown;
|
|
20
|
+
timezone?: unknown;
|
|
21
|
+
disambiguation?: unknown;
|
|
22
|
+
domain?: unknown;
|
|
23
|
+
parseFailure?: unknown;
|
|
24
|
+
breaks?: unknown;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type NumericStyleFacts = {
|
|
28
|
+
requestsTemporal: boolean;
|
|
29
|
+
temporalInputsUsable: boolean;
|
|
30
|
+
parser: Parameters<typeof parseTemporalColumn>[1];
|
|
31
|
+
temporalOptions: Parameters<typeof parseTemporalColumn>[2];
|
|
32
|
+
hasEpochParser: boolean;
|
|
33
|
+
hasExplicitDomain: boolean;
|
|
34
|
+
hasBinnedBreaks: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** True when a scaled constant is what the core `cellToNumber()` coerces to a
|
|
38
|
+
* finite number, mirroring the non-temporal numeric-style path
|
|
39
|
+
* (scale-style-values.ts). Booleans, numeric strings and ISO date strings all
|
|
40
|
+
* train and render at runtime, so validation must accept them too. Core's
|
|
41
|
+
* cellToNumber cannot be imported here (core depends on spec, not vice versa),
|
|
42
|
+
* so the predicate is replicated. */
|
|
43
|
+
function scaledConstantCoercesToFinite(value: unknown): boolean {
|
|
44
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
45
|
+
if (value instanceof Date) return Number.isFinite(value.getTime());
|
|
46
|
+
if (typeof value === "boolean") return true;
|
|
47
|
+
if (typeof value === "string") {
|
|
48
|
+
if (parseTemporal(value, "iso").ok) return true;
|
|
49
|
+
return value.trim() !== "" && Number.isFinite(Number(value));
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Format an arbitrary value for a diagnostic message without ever throwing.
|
|
55
|
+
* Tier-2 runs after schema errors, so a schema-invalid JS constant (BigInt,
|
|
56
|
+
* Symbol, circular object) can reach a message; JSON.stringify throws on BigInt
|
|
57
|
+
* and String() throws on Symbol, so fall back through both to the type name. */
|
|
58
|
+
function safeFormatConstant(value: unknown): string {
|
|
59
|
+
try {
|
|
60
|
+
const json = JSON.stringify(value);
|
|
61
|
+
if (json !== undefined) return json;
|
|
62
|
+
} catch {
|
|
63
|
+
/* BigInt / circular — fall through */
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
return String(value);
|
|
67
|
+
} catch {
|
|
68
|
+
return typeof value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** A quantitative field carrying temporal options resolves at runtime only when a
|
|
73
|
+
* working parser (or censor recovery) yields temporal values. Returns a mismatch
|
|
74
|
+
* error or null. Extracted to keep the field loop within the max-depth limit. */
|
|
75
|
+
function quantitativeTemporalFieldError(input: {
|
|
76
|
+
decision: TemporalDecision | null | undefined;
|
|
77
|
+
aesthetic: "size" | "linewidth" | "alpha";
|
|
78
|
+
field: string;
|
|
79
|
+
temporalKind: unknown;
|
|
80
|
+
parse: unknown;
|
|
81
|
+
parseFailure: unknown;
|
|
82
|
+
hasEpochParser: boolean;
|
|
83
|
+
hasExplicitDomain: boolean;
|
|
84
|
+
hasBinnedBreaks: boolean;
|
|
85
|
+
/** Channel-wide training (sibling fields / scaled constants) for parseFailure: "censor". */
|
|
86
|
+
channelTrains: boolean;
|
|
87
|
+
}): SpecError | null {
|
|
88
|
+
const {
|
|
89
|
+
decision,
|
|
90
|
+
aesthetic,
|
|
91
|
+
field,
|
|
92
|
+
temporalKind,
|
|
93
|
+
parse,
|
|
94
|
+
parseFailure,
|
|
95
|
+
hasEpochParser,
|
|
96
|
+
hasExplicitDomain,
|
|
97
|
+
hasBinnedBreaks,
|
|
98
|
+
channelTrains,
|
|
99
|
+
} = input;
|
|
100
|
+
const mismatch: SpecError = {
|
|
101
|
+
code: "scale-type-mismatch",
|
|
102
|
+
path: `/scales/${aesthetic}`,
|
|
103
|
+
message: `scales.${aesthetic} requests temporal values but field "${field}" is quantitative (numbers are not treated as temporal without a successful epoch parse).`,
|
|
104
|
+
fix: {
|
|
105
|
+
description: `Map a temporal field, use a working parse: { epoch: "ms" | "s" }, or remove temporal ${aesthetic} options.`,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
const censorRecovers =
|
|
109
|
+
parseFailure === "censor" && (hasExplicitDomain || hasBinnedBreaks || channelTrains);
|
|
110
|
+
if (decision === null || decision === undefined) {
|
|
111
|
+
return profileQuantitativeTemporalError({
|
|
112
|
+
aesthetic,
|
|
113
|
+
temporalKind,
|
|
114
|
+
hasEpochParser,
|
|
115
|
+
censorRecovers,
|
|
116
|
+
mismatch,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const censoredInvalid =
|
|
120
|
+
parse !== undefined &&
|
|
121
|
+
parseFailure === "censor" &&
|
|
122
|
+
decision.status === "invalid" &&
|
|
123
|
+
((decision.validatedCount ?? 0) > 0 || hasExplicitDomain || hasBinnedBreaks || channelTrains);
|
|
124
|
+
if (decision.status !== "temporal" && !censoredInvalid) return mismatch;
|
|
125
|
+
// temporalKind may be a schema-invalid non-string (e.g. a Symbol) reaching tier-2;
|
|
126
|
+
// only compare/stringify when it is a valid string, else defer to the schema diagnostic.
|
|
127
|
+
if (
|
|
128
|
+
typeof temporalKind === "string" &&
|
|
129
|
+
decision.kind !== null &&
|
|
130
|
+
decision.kind !== undefined &&
|
|
131
|
+
decision.kind !== temporalKind
|
|
132
|
+
) {
|
|
133
|
+
return {
|
|
134
|
+
code: "scale-type-mismatch",
|
|
135
|
+
path: `/scales/${aesthetic}`,
|
|
136
|
+
message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but field "${field}" parses as "${decision.kind}".`,
|
|
137
|
+
fix: {
|
|
138
|
+
description: `Use the ${decision.kind ?? "matching"} ${aesthetic} helper or correct the source precision.`,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function profileQuantitativeTemporalError(input: {
|
|
146
|
+
aesthetic: "size" | "linewidth" | "alpha";
|
|
147
|
+
temporalKind: unknown;
|
|
148
|
+
hasEpochParser: boolean;
|
|
149
|
+
censorRecovers: boolean;
|
|
150
|
+
mismatch: SpecError;
|
|
151
|
+
}): SpecError | null {
|
|
152
|
+
const { aesthetic, temporalKind, hasEpochParser, censorRecovers, mismatch } = input;
|
|
153
|
+
if (hasEpochParser && typeof temporalKind === "string" && temporalKind !== "datetime") {
|
|
154
|
+
return {
|
|
155
|
+
code: "scale-type-mismatch",
|
|
156
|
+
path: `/scales/${aesthetic}`,
|
|
157
|
+
message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but an epoch parser yields "datetime".`,
|
|
158
|
+
fix: {
|
|
159
|
+
description: `Set scales.${aesthetic}.temporalKind to "datetime", or use a parser that yields ${temporalKind} values.`,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return hasEpochParser || censorRecovers ? null : mismatch;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** A scaled numeric-style constant is checked against the same resolution path the
|
|
167
|
+
* runtime uses (resolveNumericStyleValueView). Returns a mismatch error, or null when
|
|
168
|
+
* the constant resolves. Extracted so the per-constant branching does not nest under
|
|
169
|
+
* the aesthetic/constant loops (max-depth). */
|
|
170
|
+
function numericStyleConstantError(input: {
|
|
171
|
+
value: unknown;
|
|
172
|
+
aesthetic: "size" | "linewidth" | "alpha";
|
|
173
|
+
configType: string;
|
|
174
|
+
requestsTemporal: boolean;
|
|
175
|
+
temporalKind: unknown;
|
|
176
|
+
parseUsable: boolean;
|
|
177
|
+
parser: Parameters<typeof parseTemporalColumn>[1];
|
|
178
|
+
options: Parameters<typeof parseTemporalColumn>[2];
|
|
179
|
+
censorRecovers: boolean;
|
|
180
|
+
}): SpecError | null {
|
|
181
|
+
const {
|
|
182
|
+
value,
|
|
183
|
+
aesthetic,
|
|
184
|
+
configType,
|
|
185
|
+
requestsTemporal,
|
|
186
|
+
temporalKind,
|
|
187
|
+
parseUsable,
|
|
188
|
+
parser,
|
|
189
|
+
options,
|
|
190
|
+
censorRecovers,
|
|
191
|
+
} = input;
|
|
192
|
+
if (!requestsTemporal) {
|
|
193
|
+
// Non-temporal: accept exactly what cellToNumber() coerces to a finite number
|
|
194
|
+
// (numbers, Dates, booleans, numeric strings, ISO strings); reject "large", "", null.
|
|
195
|
+
if (scaledConstantCoercesToFinite(value)) return null;
|
|
196
|
+
return {
|
|
197
|
+
code: "scale-type-mismatch",
|
|
198
|
+
path: `/scales/${aesthetic}`,
|
|
199
|
+
message: `scales.${aesthetic}.type is "${configType}" but the scaled constant ${safeFormatConstant(value)} is not numeric; ${configType} ${aesthetic} scales need quantitative or temporal values.`,
|
|
200
|
+
fix: {
|
|
201
|
+
description: `Use a numeric scaled constant, or set scales.${aesthetic}.type to "ordinal".`,
|
|
202
|
+
example: { type: "ordinal" },
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// Temporal: a schema-invalid parser defers to the schema error; otherwise the constant
|
|
207
|
+
// must resolve temporal (a Date is datetime), or be covered by censor recovery.
|
|
208
|
+
if (!parseUsable) return null;
|
|
209
|
+
let constantKind: string | null | undefined;
|
|
210
|
+
if (value instanceof Date) {
|
|
211
|
+
constantKind = "datetime";
|
|
212
|
+
} else if (typeof value === "string" || typeof value === "number") {
|
|
213
|
+
const decision = parseTemporalColumn(
|
|
214
|
+
[value] as Parameters<typeof parseTemporalColumn>[0],
|
|
215
|
+
parser,
|
|
216
|
+
options,
|
|
217
|
+
).decision;
|
|
218
|
+
constantKind = decision.status === "temporal" ? (decision.kind ?? null) : undefined;
|
|
219
|
+
} else {
|
|
220
|
+
// boolean, bigint, symbol, object, null: not a temporal constant, and must not be
|
|
221
|
+
// handed to parseTemporalColumn — its evidence formatting (JSON.stringify) throws on
|
|
222
|
+
// BigInt / unserializable objects. safeFormatConstant handles the message safely.
|
|
223
|
+
constantKind = undefined;
|
|
224
|
+
}
|
|
225
|
+
if (constantKind === undefined) {
|
|
226
|
+
if (censorRecovers) return null;
|
|
227
|
+
return {
|
|
228
|
+
code: "scale-type-mismatch",
|
|
229
|
+
path: `/scales/${aesthetic}`,
|
|
230
|
+
message: `scales.${aesthetic} requests temporal values but the scaled constant ${safeFormatConstant(value)} is not temporal; use a temporal constant or a working parse.`,
|
|
231
|
+
fix: {
|
|
232
|
+
description: `Use a temporal scaled constant, add a working parse: { epoch: "ms" | "s" }, or remove temporal ${aesthetic} options.`,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// The constant parses temporal; enforce the requested kind — the runtime throws
|
|
237
|
+
// style-temporal-kind when a datetime constant is fed to a `date` scale (or vice versa).
|
|
238
|
+
if (typeof temporalKind === "string" && constantKind !== null && constantKind !== temporalKind) {
|
|
239
|
+
return {
|
|
240
|
+
code: "scale-type-mismatch",
|
|
241
|
+
path: `/scales/${aesthetic}`,
|
|
242
|
+
message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but the scaled constant ${safeFormatConstant(value)} parses as "${constantKind}".`,
|
|
243
|
+
fix: {
|
|
244
|
+
description: `Use a ${temporalKind} constant, or set scales.${aesthetic}.temporalKind to "${constantKind}".`,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Size/linewidth/alpha sequential/binned scale vs field/constant types (incl. temporal).
|
|
253
|
+
* Prefers per-use evidenceForUse over the last-wins union so multi-table same-name
|
|
254
|
+
* fields keep independent types (#609 / #844).
|
|
255
|
+
*/
|
|
256
|
+
export function checkNumericStyleScaleDataCompatibility(input: {
|
|
257
|
+
scales: Record<string, unknown> | undefined;
|
|
258
|
+
fields: FieldEvidenceMap;
|
|
259
|
+
/**
|
|
260
|
+
* Optional per-use evidence lookup. When provided, prefer it over the
|
|
261
|
+
* last-wins `fields` union so multi-table layers with the same field name
|
|
262
|
+
* keep their own type evidence (#609 / #844).
|
|
263
|
+
*/
|
|
264
|
+
evidenceForUse?: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined;
|
|
265
|
+
numericStyleFields: Record<"size" | "linewidth" | "alpha", ChannelFieldUse[]>;
|
|
266
|
+
numericStyleScaledConstants: Record<"size" | "linewidth" | "alpha", unknown[]>;
|
|
267
|
+
temporalDecisionCache: TemporalDecisionCache;
|
|
268
|
+
}): SpecError[] {
|
|
269
|
+
const { scales, fields, numericStyleFields, numericStyleScaledConstants, temporalDecisionCache } =
|
|
270
|
+
input;
|
|
271
|
+
const errors: SpecError[] = [];
|
|
272
|
+
const evidenceOf = (use: ChannelFieldUse) => input.evidenceForUse?.(use) ?? fields.get(use.field);
|
|
273
|
+
const typeOf = (use: ChannelFieldUse) => evidenceOf(use)?.type ?? null;
|
|
274
|
+
// color check: a continuous ramp needs quantitative or temporal values, so a
|
|
275
|
+
// nominal/ordinal field trains no finite domain and the runtime throws
|
|
276
|
+
// `style-domain-empty` (scale-style.ts). Reject it at validation time with the
|
|
277
|
+
// same "use ordinal" guidance color scales give. Fields without an explicit
|
|
278
|
+
// sequential/binned type default to an ordinal numeric style and are fine.
|
|
279
|
+
for (const aesthetic of ["size", "linewidth", "alpha"] as const) {
|
|
280
|
+
const config = scales?.[aesthetic] as NumericStyleConfig | undefined;
|
|
281
|
+
if (config?.type !== "sequential" && config?.type !== "binned") continue;
|
|
282
|
+
const facts = numericStyleFacts(config);
|
|
283
|
+
// Pass 1: channel-wide training sources (sibling fields + scaled constants).
|
|
284
|
+
// Runtime trains sequential/binned style scales from the full channel value
|
|
285
|
+
// list, so an all-invalid field/constant is censored when any sibling trains.
|
|
286
|
+
const channelTrains = numericStyleChannelTrains({
|
|
287
|
+
uses: numericStyleFields[aesthetic],
|
|
288
|
+
constants: numericStyleScaledConstants[aesthetic],
|
|
289
|
+
evidenceOf,
|
|
290
|
+
typeOf,
|
|
291
|
+
cache: temporalDecisionCache,
|
|
292
|
+
facts,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Pass 2: field diagnostics (use channel-wide censor recovery).
|
|
296
|
+
for (const use of numericStyleFields[aesthetic]) {
|
|
297
|
+
const type = typeOf(use);
|
|
298
|
+
// A quantitative field carrying temporal options fails at resolve time
|
|
299
|
+
// unless a working parser (or censor recovery) yields temporal values —
|
|
300
|
+
// mirror the color checker rather than deferring unconditionally.
|
|
301
|
+
if (type === "quantitative" && facts.requestsTemporal) {
|
|
302
|
+
// Defer to the schema diagnostic when the parser/options are schema-invalid.
|
|
303
|
+
if (!facts.temporalInputsUsable) continue;
|
|
304
|
+
const decision = temporalDecisionForField(
|
|
305
|
+
temporalDecisionCache,
|
|
306
|
+
use.field,
|
|
307
|
+
evidenceOf(use),
|
|
308
|
+
facts.parser as Parameters<typeof temporalDecisionForField>[3],
|
|
309
|
+
facts.temporalOptions as Parameters<typeof temporalDecisionForField>[4],
|
|
310
|
+
);
|
|
311
|
+
const error = quantitativeTemporalFieldError({
|
|
312
|
+
decision,
|
|
313
|
+
aesthetic,
|
|
314
|
+
field: use.field,
|
|
315
|
+
temporalKind: config.temporalKind,
|
|
316
|
+
parse: config.parse,
|
|
317
|
+
parseFailure: config.parseFailure,
|
|
318
|
+
hasEpochParser: facts.hasEpochParser,
|
|
319
|
+
hasExplicitDomain: facts.hasExplicitDomain,
|
|
320
|
+
hasBinnedBreaks: facts.hasBinnedBreaks,
|
|
321
|
+
channelTrains,
|
|
322
|
+
});
|
|
323
|
+
if (error !== null) errors.push(error);
|
|
324
|
+
}
|
|
325
|
+
// A nominal/ordinal field trains no finite domain and the runtime throws
|
|
326
|
+
// `style-domain-empty`; reject it with the same "use ordinal" guidance color
|
|
327
|
+
// scales give. A nominal field carrying temporal options may still resolve
|
|
328
|
+
// to temporal at runtime, so defer (mirror the color checker).
|
|
329
|
+
if (type !== "nominal" && type !== "ordinal") continue;
|
|
330
|
+
if (facts.requestsTemporal) continue;
|
|
331
|
+
errors.push({
|
|
332
|
+
code: "scale-type-mismatch",
|
|
333
|
+
path: `/scales/${aesthetic}`,
|
|
334
|
+
message: `scales.${aesthetic}.type is "${config.type}" but field "${use.field}" is ${type}; ${config.type} ${aesthetic} scales need quantitative or temporal values.`,
|
|
335
|
+
fix: {
|
|
336
|
+
description: `Set scales.${aesthetic}.type to "ordinal", or map a quantitative field.`,
|
|
337
|
+
example: { type: "ordinal" },
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
// Scaled constants train the same numeric scale, so a constant the scale can't
|
|
342
|
+
// resolve throws at runtime (style-domain-empty / style-temporal-parse). Reject
|
|
343
|
+
// it here too, mirroring the field checks above for both resolution paths.
|
|
344
|
+
const censorRecovers =
|
|
345
|
+
config.parseFailure === "censor" &&
|
|
346
|
+
(facts.hasExplicitDomain || facts.hasBinnedBreaks || channelTrains);
|
|
347
|
+
for (const value of numericStyleScaledConstants[aesthetic]) {
|
|
348
|
+
const error = numericStyleConstantError({
|
|
349
|
+
value,
|
|
350
|
+
aesthetic,
|
|
351
|
+
configType: config.type,
|
|
352
|
+
requestsTemporal: facts.requestsTemporal,
|
|
353
|
+
temporalKind: config.temporalKind,
|
|
354
|
+
parseUsable: facts.temporalInputsUsable,
|
|
355
|
+
parser: facts.parser,
|
|
356
|
+
options: facts.temporalOptions,
|
|
357
|
+
censorRecovers,
|
|
358
|
+
});
|
|
359
|
+
if (error !== null) errors.push(error);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return errors;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function numericStyleFacts(config: NumericStyleConfig): NumericStyleFacts {
|
|
366
|
+
const requestsTemporal = [
|
|
367
|
+
config.temporalKind,
|
|
368
|
+
config.parse,
|
|
369
|
+
config.timezone,
|
|
370
|
+
config.disambiguation,
|
|
371
|
+
].some((value) => value !== undefined);
|
|
372
|
+
const temporalInputsUsable =
|
|
373
|
+
temporalParserUsable(config.parse) &&
|
|
374
|
+
(config.timezone === undefined || typeof config.timezone === "string") &&
|
|
375
|
+
(config.disambiguation === undefined || typeof config.disambiguation === "string");
|
|
376
|
+
const parser = (config.parse ?? "auto") as Parameters<typeof parseTemporalColumn>[1];
|
|
377
|
+
const temporalOptions = {
|
|
378
|
+
...(config.timezone !== undefined && { timezone: config.timezone }),
|
|
379
|
+
...(config.disambiguation !== undefined && { disambiguation: config.disambiguation }),
|
|
380
|
+
} as Parameters<typeof parseTemporalColumn>[2];
|
|
381
|
+
const parseableBound = (value: unknown): boolean =>
|
|
382
|
+
temporalInputsUsable &&
|
|
383
|
+
config.parse !== undefined &&
|
|
384
|
+
parseTemporal(value, config.parse as Parameters<typeof parseTemporal>[1], temporalOptions).ok;
|
|
385
|
+
const domainValues = Array.isArray(config.domain) ? config.domain.filter(nonNull) : [];
|
|
386
|
+
const binnedBreaks =
|
|
387
|
+
config.type === "binned" && Array.isArray(config.breaks) ? config.breaks.filter(nonNull) : [];
|
|
388
|
+
return {
|
|
389
|
+
requestsTemporal,
|
|
390
|
+
temporalInputsUsable,
|
|
391
|
+
parser,
|
|
392
|
+
temporalOptions,
|
|
393
|
+
hasEpochParser:
|
|
394
|
+
typeof config.parse === "object" && config.parse !== null && "epoch" in config.parse,
|
|
395
|
+
hasExplicitDomain:
|
|
396
|
+
domainValues.length === 2 && domainValues.every((value) => parseableBound(value)),
|
|
397
|
+
hasBinnedBreaks:
|
|
398
|
+
binnedBreaks.length >= 2 && binnedBreaks.every((value) => parseableBound(value)),
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function nonNull(value: unknown): boolean {
|
|
403
|
+
return value !== null;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function numericStyleChannelTrains(input: {
|
|
407
|
+
uses: ChannelFieldUse[];
|
|
408
|
+
constants: unknown[];
|
|
409
|
+
evidenceOf: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined;
|
|
410
|
+
typeOf: (use: ChannelFieldUse) => FieldEvidenceEntry["type"] | null;
|
|
411
|
+
cache: TemporalDecisionCache;
|
|
412
|
+
facts: NumericStyleFacts;
|
|
413
|
+
}): boolean {
|
|
414
|
+
const { uses, constants, evidenceOf, typeOf, cache, facts } = input;
|
|
415
|
+
if (uses.some((use) => fieldTrainsNumericStyle(use, evidenceOf, typeOf, cache, facts)))
|
|
416
|
+
return true;
|
|
417
|
+
if (!facts.requestsTemporal || !facts.temporalInputsUsable) return false;
|
|
418
|
+
return constants.some((value) => constantTrainsNumericStyle(value, facts));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function fieldTrainsNumericStyle(
|
|
422
|
+
use: ChannelFieldUse,
|
|
423
|
+
evidenceOf: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined,
|
|
424
|
+
typeOf: (use: ChannelFieldUse) => FieldEvidenceEntry["type"] | null,
|
|
425
|
+
cache: TemporalDecisionCache,
|
|
426
|
+
facts: NumericStyleFacts,
|
|
427
|
+
): boolean {
|
|
428
|
+
const type = typeOf(use);
|
|
429
|
+
if (type === "temporal") return true;
|
|
430
|
+
if (type !== "quantitative" || !facts.requestsTemporal || !facts.temporalInputsUsable)
|
|
431
|
+
return false;
|
|
432
|
+
const decision = temporalDecisionForField(
|
|
433
|
+
cache,
|
|
434
|
+
use.field,
|
|
435
|
+
evidenceOf(use),
|
|
436
|
+
facts.parser as Parameters<typeof temporalDecisionForField>[3],
|
|
437
|
+
facts.temporalOptions as Parameters<typeof temporalDecisionForField>[4],
|
|
438
|
+
);
|
|
439
|
+
return (
|
|
440
|
+
decision !== null &&
|
|
441
|
+
decision !== undefined &&
|
|
442
|
+
(decision.status === "temporal" || (decision.validatedCount ?? 0) > 0)
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
function constantTrainsNumericStyle(value: unknown, facts: NumericStyleFacts): boolean {
|
|
447
|
+
if (value instanceof Date) return true;
|
|
448
|
+
if (typeof value !== "string" && typeof value !== "number") return false;
|
|
449
|
+
const decision = parseTemporalColumn(
|
|
450
|
+
[value] as Parameters<typeof parseTemporalColumn>[0],
|
|
451
|
+
facts.parser,
|
|
452
|
+
facts.temporalOptions,
|
|
453
|
+
).decision;
|
|
454
|
+
return decision.status === "temporal" || (decision.validatedCount ?? 0) > 0;
|
|
455
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Style aesthetic data-aware scale checks (shape/linetype finite symbols;
|
|
3
|
+
* size/linewidth/alpha sequential/binned + temporal).
|
|
4
|
+
*
|
|
5
|
+
* - validate-data-checks-style-finite.ts — shape / linetype
|
|
6
|
+
* - validate-data-checks-style-numeric.ts — size / linewidth / alpha
|
|
7
|
+
*
|
|
8
|
+
* Shared temporal memoization: validate-data-checks-temporal.ts.
|
|
9
|
+
* Position: validate-data-checks-position.ts. Color: validate-data-checks-color.ts.
|
|
10
|
+
* Orchestrator: validate-data-checks.ts.
|
|
11
|
+
*/
|
|
12
|
+
export { checkFiniteStyleScaleDataCompatibility } from "./validate-data-checks-style-finite.js";
|
|
13
|
+
export { checkNumericStyleScaleDataCompatibility } from "./validate-data-checks-style-numeric.js";
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared temporal decision memoization for data-aware scale checks.
|
|
3
|
+
* Used by position (x/y), color/fill, and numeric style scale compatibility.
|
|
4
|
+
* Orchestrator: validate-data-checks.ts.
|
|
5
|
+
*/
|
|
6
|
+
import type { SpecError } from "./errors.js";
|
|
7
|
+
import { parseTemporalColumn, type TemporalDecision } from "./temporal-column.js";
|
|
8
|
+
import {
|
|
9
|
+
canonicalTemporalParserKey,
|
|
10
|
+
type TemporalParseOptions,
|
|
11
|
+
type TemporalParserSpec,
|
|
12
|
+
type TemporalScaleKind,
|
|
13
|
+
} from "./temporal-parse.js";
|
|
14
|
+
import type { FieldEvidenceEntry } from "./validate-data-evidence.js";
|
|
15
|
+
|
|
16
|
+
/** Channel field use collected during the layer walk (position or color). */
|
|
17
|
+
export interface ChannelFieldUse {
|
|
18
|
+
field: string;
|
|
19
|
+
path: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* True when a scale's `parse` value is safe to hand to temporalDecisionForField.
|
|
24
|
+
*
|
|
25
|
+
* A schema-invalid parser (e.g. `123`, `true`, `{}`, `[]`) is collected as a
|
|
26
|
+
* schema error, but tier-2 data checks still run, so a malformed value can reach
|
|
27
|
+
* this helper's `canonicalTemporalParserKey` — which does `"epoch" in parser`
|
|
28
|
+
* (throws on a non-object) and reads `parser.format` (throws inside fnv1a on an
|
|
29
|
+
* empty object). Only `undefined`, a string, or a well-formed `{ epoch }` /
|
|
30
|
+
* `{ format }` object is usable; anything else must defer to the schema
|
|
31
|
+
* diagnostic instead of crashing validation.
|
|
32
|
+
*/
|
|
33
|
+
export function temporalParserUsable(parse: unknown): boolean {
|
|
34
|
+
if (parse === undefined || typeof parse === "string") return true;
|
|
35
|
+
if (typeof parse !== "object" || parse === null || Array.isArray(parse)) return false;
|
|
36
|
+
return (
|
|
37
|
+
typeof (parse as { epoch?: unknown }).epoch === "string" ||
|
|
38
|
+
typeof (parse as { format?: unknown }).format === "string"
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* One cache per dataChecks() call — shared by position, color, and style checkers.
|
|
44
|
+
*
|
|
45
|
+
* Outer key: field + parser + timezone + disambiguation.
|
|
46
|
+
* Inner key: the FieldEvidenceEntry object (null when info is missing). Layers
|
|
47
|
+
* that share a named dataset reuse the same entry object, so multi-consumer
|
|
48
|
+
* memoization still hits. Layers with different datasets get different entries
|
|
49
|
+
* and must not share a decision under the same field name (#1339).
|
|
50
|
+
*/
|
|
51
|
+
export type TemporalDecisionCache = Map<
|
|
52
|
+
string,
|
|
53
|
+
Map<FieldEvidenceEntry | null, TemporalDecision | null | undefined>
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolve one field's temporal decision for scale compatibility checks.
|
|
58
|
+
*
|
|
59
|
+
* Memoized per dataChecks() call so multi-layer / multi-channel consumers of
|
|
60
|
+
* the same field evidence under the same parser+options pay O(n) once, not O(U·n).
|
|
61
|
+
* When parser is auto and options match the evidence pass (no timezone /
|
|
62
|
+
* disambiguation), reuse FieldEvidenceEntry.temporal instead of re-scanning.
|
|
63
|
+
*
|
|
64
|
+
* Cache key omits parseFailure and temporalKind — those only affect how the
|
|
65
|
+
* decision is interpreted, not the decision itself. Dataset identity is the
|
|
66
|
+
* FieldEvidenceEntry object identity (inner map key).
|
|
67
|
+
*/
|
|
68
|
+
export function temporalDecisionForField(
|
|
69
|
+
cache: TemporalDecisionCache,
|
|
70
|
+
field: string,
|
|
71
|
+
info: FieldEvidenceEntry | undefined,
|
|
72
|
+
parser: TemporalParserSpec | "auto",
|
|
73
|
+
options: TemporalParseOptions,
|
|
74
|
+
): TemporalDecision | null | undefined {
|
|
75
|
+
const parserKey = parser === "auto" ? "auto" : canonicalTemporalParserKey(parser);
|
|
76
|
+
const key = `${field}\0${parserKey}\0${options.timezone ?? ""}\0${options.disambiguation ?? ""}`;
|
|
77
|
+
let byInfo = cache.get(key);
|
|
78
|
+
if (byInfo === undefined) {
|
|
79
|
+
byInfo = new Map();
|
|
80
|
+
cache.set(key, byInfo);
|
|
81
|
+
}
|
|
82
|
+
const infoKey = info ?? null;
|
|
83
|
+
if (byInfo.has(infoKey)) return byInfo.get(infoKey);
|
|
84
|
+
|
|
85
|
+
let decision: TemporalDecision | null | undefined;
|
|
86
|
+
if (info?.values === null || info?.values === undefined) {
|
|
87
|
+
// Profile-backed fields: no inline values. temporal is always null today.
|
|
88
|
+
decision = info?.temporal ?? null;
|
|
89
|
+
} else if (
|
|
90
|
+
parser === "auto" &&
|
|
91
|
+
options.timezone === undefined &&
|
|
92
|
+
options.disambiguation === undefined &&
|
|
93
|
+
info.temporal !== null
|
|
94
|
+
) {
|
|
95
|
+
// Evidence was built with inferTemporalColumn(column) — same auto defaults.
|
|
96
|
+
decision = info.temporal;
|
|
97
|
+
} else {
|
|
98
|
+
decision = parseTemporalColumn(info.values, parser, options).decision;
|
|
99
|
+
}
|
|
100
|
+
byInfo.set(infoKey, decision);
|
|
101
|
+
return decision;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function appendTemporalKindMismatch(
|
|
105
|
+
errors: SpecError[],
|
|
106
|
+
input: {
|
|
107
|
+
axis: "x" | "y";
|
|
108
|
+
path: string;
|
|
109
|
+
field: string;
|
|
110
|
+
expected: TemporalScaleKind | undefined;
|
|
111
|
+
actual: "date" | "datetime" | "time" | null;
|
|
112
|
+
},
|
|
113
|
+
): void {
|
|
114
|
+
const { axis, path, field, expected, actual } = input;
|
|
115
|
+
if (expected === undefined || actual === null || actual === expected) return;
|
|
116
|
+
// scale_*_time reduces date/datetime to UTC clock portion (#831); not a mismatch.
|
|
117
|
+
if (expected === "time" && (actual === "date" || actual === "datetime")) return;
|
|
118
|
+
// monthDay takes the month-day off a full date and drops the rest, so a field
|
|
119
|
+
// parsing as date or datetime is exactly what it expects to be given.
|
|
120
|
+
if (expected === "monthDay" && (actual === "date" || actual === "datetime")) return;
|
|
121
|
+
errors.push({
|
|
122
|
+
code: "scale-type-mismatch",
|
|
123
|
+
path,
|
|
124
|
+
message: `scales.${axis}.temporalKind is "${expected}" but field "${field}" parses as ${actual}.`,
|
|
125
|
+
fix: {
|
|
126
|
+
description: `Use temporalKind "${actual}" or choose a parser that produces ${expected} values.`,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|