@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,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier-1 schema shape walk: discriminator-aware layer branches + plot shell.
|
|
3
|
+
*
|
|
4
|
+
* Shared geom branch lookup (`GEOM_BRANCHES`) is also used by validate() to
|
|
5
|
+
* recognise known geoms for the tier-2 structural gate. Branch validity for
|
|
6
|
+
* that gate comes from the compiled plot check (valid path) or from this
|
|
7
|
+
* walk's per-layer `Value.Errors` result (invalid path) — not a second
|
|
8
|
+
* interpreted `Value.Check` per layer (#1279).
|
|
9
|
+
*
|
|
10
|
+
* Orchestrator: validate.ts. Error mapping: validate-map-errors.ts.
|
|
11
|
+
*/
|
|
12
|
+
import { Value } from "typebox/value";
|
|
13
|
+
|
|
14
|
+
import type { SpecError } from "./errors.js";
|
|
15
|
+
import {
|
|
16
|
+
AreaLayerSchema,
|
|
17
|
+
BarLayerSchema,
|
|
18
|
+
BoxplotLayerSchema,
|
|
19
|
+
ColLayerSchema,
|
|
20
|
+
DensityLayerSchema,
|
|
21
|
+
Density2dLayerSchema,
|
|
22
|
+
Density2dFilledLayerSchema,
|
|
23
|
+
DotplotLayerSchema,
|
|
24
|
+
ErrorbarLayerSchema,
|
|
25
|
+
LinerangeLayerSchema,
|
|
26
|
+
PointrangeLayerSchema,
|
|
27
|
+
CrossbarLayerSchema,
|
|
28
|
+
HistogramLayerSchema,
|
|
29
|
+
FreqpolyLayerSchema,
|
|
30
|
+
HlineLayerSchema,
|
|
31
|
+
JitterLayerSchema,
|
|
32
|
+
LineLayerSchema,
|
|
33
|
+
PathLayerSchema,
|
|
34
|
+
PlotSpecSchema,
|
|
35
|
+
PointLayerSchema,
|
|
36
|
+
RasterLayerSchema,
|
|
37
|
+
HexLayerSchema,
|
|
38
|
+
RectLayerSchema,
|
|
39
|
+
RibbonLayerSchema,
|
|
40
|
+
SegmentLayerSchema,
|
|
41
|
+
CountLayerSchema,
|
|
42
|
+
ViolinLayerSchema,
|
|
43
|
+
FunctionLayerSchema,
|
|
44
|
+
PolygonLayerSchema,
|
|
45
|
+
AblineLayerSchema,
|
|
46
|
+
CurveLayerSchema,
|
|
47
|
+
MapLayerSchema,
|
|
48
|
+
BlankLayerSchema,
|
|
49
|
+
SfLayerSchema,
|
|
50
|
+
SfTextLayerSchema,
|
|
51
|
+
SfLabelLayerSchema,
|
|
52
|
+
SpokeLayerSchema,
|
|
53
|
+
RugLayerSchema,
|
|
54
|
+
StepLayerSchema,
|
|
55
|
+
QqLayerSchema,
|
|
56
|
+
QqLineLayerSchema,
|
|
57
|
+
RuleLayerSchema,
|
|
58
|
+
QuantileLayerSchema,
|
|
59
|
+
ContourLayerSchema,
|
|
60
|
+
SmoothLayerSchema,
|
|
61
|
+
TextLayerSchema,
|
|
62
|
+
LabelLayerSchema,
|
|
63
|
+
TileLayerSchema,
|
|
64
|
+
Bin2dLayerSchema,
|
|
65
|
+
VlineLayerSchema,
|
|
66
|
+
} from "./schema.js";
|
|
67
|
+
import { mapValueErrors, unknownGeomError } from "./validate-map-errors.js";
|
|
68
|
+
|
|
69
|
+
/** Known geom → layer schema for branch-selected tier-1 walks and tier-2 eligibility. */
|
|
70
|
+
export const GEOM_BRANCHES = {
|
|
71
|
+
point: PointLayerSchema,
|
|
72
|
+
line: LineLayerSchema,
|
|
73
|
+
path: PathLayerSchema,
|
|
74
|
+
col: ColLayerSchema,
|
|
75
|
+
bar: BarLayerSchema,
|
|
76
|
+
histogram: HistogramLayerSchema,
|
|
77
|
+
freqpoly: FreqpolyLayerSchema,
|
|
78
|
+
area: AreaLayerSchema,
|
|
79
|
+
ribbon: RibbonLayerSchema,
|
|
80
|
+
segment: SegmentLayerSchema,
|
|
81
|
+
count: CountLayerSchema,
|
|
82
|
+
violin: ViolinLayerSchema,
|
|
83
|
+
function: FunctionLayerSchema,
|
|
84
|
+
polygon: PolygonLayerSchema,
|
|
85
|
+
abline: AblineLayerSchema,
|
|
86
|
+
curve: CurveLayerSchema,
|
|
87
|
+
map: MapLayerSchema,
|
|
88
|
+
blank: BlankLayerSchema,
|
|
89
|
+
sf: SfLayerSchema,
|
|
90
|
+
sf_text: SfTextLayerSchema,
|
|
91
|
+
sf_label: SfLabelLayerSchema,
|
|
92
|
+
|
|
93
|
+
spoke: SpokeLayerSchema,
|
|
94
|
+
rug: RugLayerSchema,
|
|
95
|
+
step: StepLayerSchema,
|
|
96
|
+
qq: QqLayerSchema,
|
|
97
|
+
qq_line: QqLineLayerSchema,
|
|
98
|
+
rule: RuleLayerSchema,
|
|
99
|
+
hline: HlineLayerSchema,
|
|
100
|
+
vline: VlineLayerSchema,
|
|
101
|
+
jitter: JitterLayerSchema,
|
|
102
|
+
text: TextLayerSchema,
|
|
103
|
+
label: LabelLayerSchema,
|
|
104
|
+
smooth: SmoothLayerSchema,
|
|
105
|
+
quantile: QuantileLayerSchema,
|
|
106
|
+
contour: ContourLayerSchema,
|
|
107
|
+
boxplot: BoxplotLayerSchema,
|
|
108
|
+
density: DensityLayerSchema,
|
|
109
|
+
density_2d: Density2dLayerSchema,
|
|
110
|
+
density_2d_filled: Density2dFilledLayerSchema,
|
|
111
|
+
dotplot: DotplotLayerSchema,
|
|
112
|
+
errorbar: ErrorbarLayerSchema,
|
|
113
|
+
linerange: LinerangeLayerSchema,
|
|
114
|
+
pointrange: PointrangeLayerSchema,
|
|
115
|
+
crossbar: CrossbarLayerSchema,
|
|
116
|
+
rect: RectLayerSchema,
|
|
117
|
+
tile: TileLayerSchema,
|
|
118
|
+
bin_2d: Bin2dLayerSchema,
|
|
119
|
+
raster: RasterLayerSchema,
|
|
120
|
+
hex: HexLayerSchema,
|
|
121
|
+
} as const;
|
|
122
|
+
|
|
123
|
+
function isRecord(v: unknown): v is Record<string, unknown> {
|
|
124
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** One layer's tier-1 shape errors plus whether its geom branch was clean. */
|
|
128
|
+
type LayerShapeResult = {
|
|
129
|
+
errors: SpecError[];
|
|
130
|
+
/** True when `Value.Errors(branch, layer)` was empty (branch-valid). */
|
|
131
|
+
branchOk: boolean;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/** Discriminator-aware layer walk — one layer's tier-1 shape errors. */
|
|
135
|
+
function mapLayerShapeErrors(layer: unknown, layerPath: string): LayerShapeResult {
|
|
136
|
+
if (!isRecord(layer)) {
|
|
137
|
+
return {
|
|
138
|
+
branchOk: false,
|
|
139
|
+
errors: [
|
|
140
|
+
{
|
|
141
|
+
code: "invalid-layer",
|
|
142
|
+
path: layerPath,
|
|
143
|
+
message: `Each layer must be an object with a "geom" (got ${typeof layer}).`,
|
|
144
|
+
fix: { description: "Replace with a layer object.", example: { geom: "point" } },
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const geom = layer["geom"];
|
|
150
|
+
// Own-key check: `in` walks the prototype chain, so a geom named
|
|
151
|
+
// "constructor" would pass this guard and hand Value.Errors a function
|
|
152
|
+
// instead of a schema — reporting invalid-type rather than the did-you-mean.
|
|
153
|
+
if (typeof geom !== "string" || !Object.hasOwn(GEOM_BRANCHES, geom)) {
|
|
154
|
+
return { branchOk: false, errors: [unknownGeomError(geom, layerPath)] };
|
|
155
|
+
}
|
|
156
|
+
const branch = GEOM_BRANCHES[geom as keyof typeof GEOM_BRANCHES];
|
|
157
|
+
const raw = Value.Errors(branch, layer);
|
|
158
|
+
return {
|
|
159
|
+
branchOk: raw.length === 0,
|
|
160
|
+
errors: mapValueErrors(raw, {
|
|
161
|
+
schema: branch,
|
|
162
|
+
value: layer,
|
|
163
|
+
pathPrefix: layerPath,
|
|
164
|
+
}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Result of the tier-1 shape walk for one invalid plot. */
|
|
169
|
+
export type SchemaShapeResult = {
|
|
170
|
+
errors: SpecError[];
|
|
171
|
+
/**
|
|
172
|
+
* Layer indices whose geom-branch `Value.Errors` walk was empty. Used by
|
|
173
|
+
* validate() so the tier-2 structural gate does not re-run interpreted
|
|
174
|
+
* `Value.Check` on the same layers.
|
|
175
|
+
*/
|
|
176
|
+
branchOkLayerIndices: ReadonlySet<number>;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Tier-1 schema walk (caller must set TypeBox Settings for the process).
|
|
181
|
+
* Layer branch walk + plot-level shell so layer noise is not double-reported.
|
|
182
|
+
*/
|
|
183
|
+
export function collectSchemaShapeErrors(input: Record<string, unknown>): SchemaShapeResult {
|
|
184
|
+
const errors: SpecError[] = [];
|
|
185
|
+
const branchOkLayerIndices = new Set<number>();
|
|
186
|
+
const layers = input["layers"];
|
|
187
|
+
if (!Array.isArray(layers)) {
|
|
188
|
+
errors.push({
|
|
189
|
+
code: "missing-layers",
|
|
190
|
+
path: "/layers",
|
|
191
|
+
message: `"layers" must be an array of layer objects (got ${layers === undefined ? "nothing" : typeof layers}).`,
|
|
192
|
+
fix: {
|
|
193
|
+
description: "Add a layers array with at least one layer.",
|
|
194
|
+
example: [{ geom: "point" }],
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
} else if (layers.length === 0) {
|
|
198
|
+
errors.push({
|
|
199
|
+
code: "empty-layers",
|
|
200
|
+
path: "/layers",
|
|
201
|
+
message: '"layers" must contain at least one layer.',
|
|
202
|
+
fix: { description: "Add a layer.", example: [{ geom: "point" }] },
|
|
203
|
+
});
|
|
204
|
+
} else {
|
|
205
|
+
for (let i = 0; i < layers.length; i++) {
|
|
206
|
+
const layerResult = mapLayerShapeErrors(layers[i], `/layers/${i}`);
|
|
207
|
+
if (layerResult.branchOk) branchOkLayerIndices.add(i);
|
|
208
|
+
errors.push(...layerResult.errors);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Plot-level walk with a known-valid layer shell so layer noise is not
|
|
213
|
+
// re-reported alongside the branch-selected layer walk above.
|
|
214
|
+
const shell = { ...input, layers: [{ geom: "point" }] };
|
|
215
|
+
errors.push(
|
|
216
|
+
...mapValueErrors(Value.Errors(PlotSpecSchema, shell), {
|
|
217
|
+
schema: PlotSpecSchema,
|
|
218
|
+
value: shell,
|
|
219
|
+
pathPrefix: "",
|
|
220
|
+
}),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
if (errors.length === 0) {
|
|
224
|
+
// Compiled plot Check failed but neither walk produced a mapped error.
|
|
225
|
+
errors.push({
|
|
226
|
+
code: "invalid-type",
|
|
227
|
+
path: "",
|
|
228
|
+
message: "The spec does not match the schema.",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return { errors, branchOkLayerIndices };
|
|
232
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeBox Cyclic schema / instance-path inspection helpers for tier-1 error mapping.
|
|
3
|
+
*
|
|
4
|
+
* JSON-pointer reads against the validated value, `$defs`/`$ref` walking along
|
|
5
|
+
* instancePath and schemaPath, union-member inspection, and small schema-shape
|
|
6
|
+
* queries. Used only by validate-map-errors.ts — not public package surface.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export function isRecord(v: unknown): v is Record<string, unknown> {
|
|
10
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function lastSegment(path: string): string {
|
|
14
|
+
const i = path.lastIndexOf("/");
|
|
15
|
+
return i === -1 ? path : path.slice(i + 1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function pathSegments(path: string): string[] {
|
|
19
|
+
return path.split("/").filter((s) => s.length > 0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** JSON-pointer get (instancePath form: `/a/b/0`). */
|
|
23
|
+
export function pointerGet(root: unknown, path: string): unknown {
|
|
24
|
+
if (path === "" || path === "/") return root;
|
|
25
|
+
let cur: unknown = root;
|
|
26
|
+
for (const seg of pathSegments(path)) {
|
|
27
|
+
if (cur === null || cur === undefined) return undefined;
|
|
28
|
+
if (Array.isArray(cur)) {
|
|
29
|
+
const i = Number(seg);
|
|
30
|
+
cur = Number.isInteger(i) ? cur[i] : undefined;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!isRecord(cur)) return undefined;
|
|
34
|
+
cur = cur[seg];
|
|
35
|
+
}
|
|
36
|
+
return cur;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Resolve the root object schema of a TypeBox Cyclic (`$defs` + `$ref`). */
|
|
40
|
+
function cyclicRootSchema(schema: unknown): Record<string, unknown> | null {
|
|
41
|
+
if (!isRecord(schema)) return null;
|
|
42
|
+
const defs = schema["$defs"];
|
|
43
|
+
const ref = schema["$ref"];
|
|
44
|
+
if (isRecord(defs) && typeof ref === "string" && isRecord(defs[ref])) {
|
|
45
|
+
return defs[ref];
|
|
46
|
+
}
|
|
47
|
+
return isRecord(schema) ? schema : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function resolveRef(
|
|
51
|
+
node: Record<string, unknown>,
|
|
52
|
+
defs: Record<string, unknown> | null,
|
|
53
|
+
): Record<string, unknown> {
|
|
54
|
+
const ref = node["$ref"];
|
|
55
|
+
if (typeof ref !== "string" || defs === null) return node;
|
|
56
|
+
// TypeBox emits bare names ("PointParams") and sometimes JSON pointers.
|
|
57
|
+
const name = ref.startsWith("#/$defs/")
|
|
58
|
+
? ref.slice("#/$defs/".length)
|
|
59
|
+
: ref.startsWith("#/")
|
|
60
|
+
? null
|
|
61
|
+
: ref;
|
|
62
|
+
if (name !== null && isRecord(defs[name])) return defs[name];
|
|
63
|
+
return node;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Walk a Cyclic schema along an instance path, returning the schema that
|
|
68
|
+
* describes the value at that path (after following $refs).
|
|
69
|
+
*/
|
|
70
|
+
export function schemaAtInstancePath(rootSchema: unknown, instancePath: string): unknown {
|
|
71
|
+
const root = cyclicRootSchema(rootSchema);
|
|
72
|
+
if (root === null) return null;
|
|
73
|
+
const defs = isRecord(rootSchema) && isRecord(rootSchema["$defs"]) ? rootSchema["$defs"] : null;
|
|
74
|
+
let node: Record<string, unknown> = root;
|
|
75
|
+
for (const seg of pathSegments(instancePath)) {
|
|
76
|
+
node = resolveRef(node, defs);
|
|
77
|
+
const props = node["properties"];
|
|
78
|
+
if (isRecord(props) && isRecord(props[seg])) {
|
|
79
|
+
node = props[seg];
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Array index: follow `items` (object or tuple entry).
|
|
83
|
+
if (/^\d+$/.test(seg)) {
|
|
84
|
+
const items = node["items"];
|
|
85
|
+
if (isRecord(items)) {
|
|
86
|
+
node = items;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(items)) {
|
|
90
|
+
const entry: unknown = items[Number(seg)];
|
|
91
|
+
if (isRecord(entry)) {
|
|
92
|
+
node = entry;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// additionalProperties / patternProperties value schemas
|
|
98
|
+
if (isRecord(node["additionalProperties"])) {
|
|
99
|
+
node = node["additionalProperties"];
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return resolveRef(node, defs);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Resolve a TypeBox-relative schemaPath (`#/properties/x/anyOf/0`) against
|
|
109
|
+
* the schema that applies at `instancePath`'s parent object context.
|
|
110
|
+
* For Cyclic validation, `#` is relative to the nearest $ref target; we
|
|
111
|
+
* approximate by resolving at the instancePath node, then walking the path.
|
|
112
|
+
*/
|
|
113
|
+
export function schemaAtSchemaPath(
|
|
114
|
+
rootSchema: unknown,
|
|
115
|
+
instancePath: string,
|
|
116
|
+
schemaPath: string,
|
|
117
|
+
): unknown {
|
|
118
|
+
// Most useful cases: `#` means the schema of the instance node itself
|
|
119
|
+
// (e.g. additionalProperties on PointParams when instancePath is /params).
|
|
120
|
+
const base = schemaAtInstancePath(rootSchema, instancePath);
|
|
121
|
+
if (schemaPath === "#" || schemaPath === "") return base;
|
|
122
|
+
|
|
123
|
+
const defs = isRecord(rootSchema) && isRecord(rootSchema["$defs"]) ? rootSchema["$defs"] : null;
|
|
124
|
+
|
|
125
|
+
const parts = schemaPath
|
|
126
|
+
.replace(/^#\/?/, "")
|
|
127
|
+
.split("/")
|
|
128
|
+
.filter((p) => p.length > 0);
|
|
129
|
+
// If walking from base fails, fall back to walking from cyclic root def.
|
|
130
|
+
const tryWalk = (start: unknown): unknown => {
|
|
131
|
+
let cur = start;
|
|
132
|
+
for (const p of parts) {
|
|
133
|
+
if (cur === null || cur === undefined) return null;
|
|
134
|
+
if (Array.isArray(cur) && /^\d+$/.test(p)) {
|
|
135
|
+
cur = cur[Number(p)];
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!isRecord(cur)) return null;
|
|
139
|
+
const rec = resolveRef(cur, defs);
|
|
140
|
+
cur = rec[p];
|
|
141
|
+
}
|
|
142
|
+
return isRecord(cur) ? resolveRef(cur, defs) : cur;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const fromBase = tryWalk(base);
|
|
146
|
+
if (fromBase !== null && fromBase !== undefined) return fromBase;
|
|
147
|
+
const fromRoot = tryWalk(cyclicRootSchema(rootSchema));
|
|
148
|
+
if (fromRoot !== null && fromRoot !== undefined) return fromRoot;
|
|
149
|
+
// TypeBox 1 schemaPath is often relative to a $defs member (e.g. DataValues),
|
|
150
|
+
// not the Cyclic plot root — try each def as a base.
|
|
151
|
+
if (defs !== null) {
|
|
152
|
+
for (const def of Object.values(defs)) {
|
|
153
|
+
if (!isRecord(def)) continue;
|
|
154
|
+
const hit = tryWalk(def);
|
|
155
|
+
if (hit !== null && hit !== undefined) return hit;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface UnionMemberInfo {
|
|
162
|
+
refs: string[];
|
|
163
|
+
consts: string[];
|
|
164
|
+
allConst: boolean;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function unionMembers(schema: unknown): UnionMemberInfo {
|
|
168
|
+
const info: UnionMemberInfo = { refs: [], consts: [], allConst: true };
|
|
169
|
+
const anyOf =
|
|
170
|
+
isRecord(schema) && Array.isArray(schema["anyOf"]) ? (schema["anyOf"] as unknown[]) : [];
|
|
171
|
+
for (const member of anyOf) {
|
|
172
|
+
if (!isRecord(member)) continue;
|
|
173
|
+
const ref = member["$ref"];
|
|
174
|
+
if (typeof ref === "string") info.refs.push(ref.replace(/^#\/\$defs\//, ""));
|
|
175
|
+
const c = member["const"];
|
|
176
|
+
if (typeof c === "string" || typeof c === "number" || typeof c === "boolean") {
|
|
177
|
+
info.consts.push(String(c));
|
|
178
|
+
} else {
|
|
179
|
+
// nested anyOf of literals still counts as all-const if every branch is const
|
|
180
|
+
if (Array.isArray(member["anyOf"])) {
|
|
181
|
+
const nested = unionMembers(member);
|
|
182
|
+
if (nested.allConst && nested.consts.length > 0) {
|
|
183
|
+
info.consts.push(...nested.consts);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
info.allConst = false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (anyOf.length === 0) info.allConst = false;
|
|
191
|
+
return info;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function additionalPropertiesIsClosed(objectSchema: unknown): boolean {
|
|
195
|
+
if (!isRecord(objectSchema)) return true;
|
|
196
|
+
const ap = objectSchema["additionalProperties"];
|
|
197
|
+
// Explicit schema (object / boolean true) means keys are allowed; false/absent = closed.
|
|
198
|
+
if (ap === false || ap === undefined) return true;
|
|
199
|
+
if (ap === true) return false;
|
|
200
|
+
return typeof ap !== "object" || ap === null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function objectPropertyNames(schema: unknown): string[] {
|
|
204
|
+
if (!isRecord(schema)) return [];
|
|
205
|
+
const props = schema["properties"];
|
|
206
|
+
return isRecord(props) ? Object.keys(props) : [];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function numberBounds(schema: unknown): string[] {
|
|
210
|
+
if (!isRecord(schema)) return [];
|
|
211
|
+
const bounds: string[] = [];
|
|
212
|
+
if (typeof schema["minimum"] === "number") bounds.push(`>= ${schema["minimum"]}`);
|
|
213
|
+
if (typeof schema["exclusiveMinimum"] === "number")
|
|
214
|
+
bounds.push(`> ${schema["exclusiveMinimum"]}`);
|
|
215
|
+
if (typeof schema["maximum"] === "number") bounds.push(`<= ${schema["maximum"]}`);
|
|
216
|
+
if (typeof schema["exclusiveMaximum"] === "number")
|
|
217
|
+
bounds.push(`< ${schema["exclusiveMaximum"]}`);
|
|
218
|
+
return bounds;
|
|
219
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-free structural checks for facet wrap XOR grid form.
|
|
3
|
+
* Layer grammar: validate-structure-layers.ts (+ layer-rule/ribbon/computed-y). Color schemes: validate-structure-scales.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { SpecError } from "./errors.js";
|
|
6
|
+
|
|
7
|
+
export function coordFacetStructuralErrors(input: Record<string, unknown>): SpecError[] {
|
|
8
|
+
const coord = input["coord"];
|
|
9
|
+
const facet = input["facet"];
|
|
10
|
+
if (
|
|
11
|
+
typeof coord !== "object" ||
|
|
12
|
+
coord === null ||
|
|
13
|
+
Array.isArray(coord) ||
|
|
14
|
+
typeof facet !== "object" ||
|
|
15
|
+
facet === null ||
|
|
16
|
+
Array.isArray(facet)
|
|
17
|
+
) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const coordType = (coord as Record<string, unknown>)["type"];
|
|
21
|
+
if (coordType !== "fixed" && coordType !== "sf" && coordType !== "radial") return [];
|
|
22
|
+
const scales = (facet as Record<string, unknown>)["scales"];
|
|
23
|
+
if (scales === undefined || scales === "fixed") return [];
|
|
24
|
+
const coordName =
|
|
25
|
+
coordType === "sf" ? "coord_sf" : coordType === "radial" ? "coord_radial" : "coord_fixed";
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
code: "coord-fixed-free-scales",
|
|
29
|
+
path: "/facet/scales",
|
|
30
|
+
message: `${coordName} cannot use facet scales ${JSON.stringify(scales)} because panels would imply unequal physical data-unit lengths.`,
|
|
31
|
+
fix: {
|
|
32
|
+
description: `Use facet.scales = "fixed", or remove the ${coordName} coordinate.`,
|
|
33
|
+
example: "fixed",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function facetStructuralErrors(facet: Record<string, unknown>): SpecError[] {
|
|
40
|
+
const errors: SpecError[] = [];
|
|
41
|
+
const hasWrap = facet["wrap"] !== undefined;
|
|
42
|
+
const hasGrid = facet["rows"] !== undefined || facet["cols"] !== undefined;
|
|
43
|
+
if (hasWrap && hasGrid) {
|
|
44
|
+
errors.push({
|
|
45
|
+
code: "facet-form-ambiguous",
|
|
46
|
+
path: "/facet",
|
|
47
|
+
message:
|
|
48
|
+
"This facet mixes the wrap form (facet.wrap) with the grid form (facet.rows/facet.cols). Use wrap OR rows/cols, never both.",
|
|
49
|
+
fix: {
|
|
50
|
+
description: "Keep facet.wrap (and drop rows/cols), or keep rows/cols (and drop wrap).",
|
|
51
|
+
example: { wrap: { field: "group" }, ncol: 3 },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
} else if (!hasWrap && !hasGrid) {
|
|
55
|
+
errors.push({
|
|
56
|
+
code: "facet-form-missing",
|
|
57
|
+
path: "/facet",
|
|
58
|
+
message:
|
|
59
|
+
"This facet sets neither wrap nor rows/cols — there is no field to partition panels by.",
|
|
60
|
+
fix: {
|
|
61
|
+
description: "Set facet.wrap (wrap form) or facet.rows/facet.cols (grid form).",
|
|
62
|
+
example: { wrap: { field: "group" } },
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (facet["ncol"] !== undefined && !hasWrap) {
|
|
67
|
+
errors.push({
|
|
68
|
+
code: "facet-ncol-without-wrap",
|
|
69
|
+
path: "/facet/ncol",
|
|
70
|
+
message:
|
|
71
|
+
"facet.ncol only applies to the wrap form; the grid form's columns come from facet.cols' distinct values.",
|
|
72
|
+
fix: { description: "Remove ncol, or switch to the wrap form." },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* computed-y-mapped structural checks for geoms/stats that own y.
|
|
3
|
+
* Orchestrated by validate-structure-layers.ts.
|
|
4
|
+
*
|
|
5
|
+
* Each geom/stat family is checked independently (same as the pre-split
|
|
6
|
+
* sequential ifs) so an odd pairing can still emit more than one error.
|
|
7
|
+
*/
|
|
8
|
+
import type { SpecError } from "./errors.js";
|
|
9
|
+
import type { ChannelName, ChannelValue } from "./schema.js";
|
|
10
|
+
|
|
11
|
+
/** Reject data-mapped y when the geom/stat computes y. */
|
|
12
|
+
export function computedYMappedErrors(
|
|
13
|
+
geom: string,
|
|
14
|
+
stat: string,
|
|
15
|
+
layerPath: string,
|
|
16
|
+
/** Same shape as `effectiveChannel` — null unset already collapsed to undefined. */
|
|
17
|
+
mapped: (channel: ChannelName) => Exclude<ChannelValue, null> | undefined,
|
|
18
|
+
): SpecError[] {
|
|
19
|
+
const errors: SpecError[] = [];
|
|
20
|
+
const y = mapped("y");
|
|
21
|
+
// Unmapped or after_stat form ({ stat }) is fine; data-mapped y is not.
|
|
22
|
+
if (y === undefined || "stat" in y) return errors;
|
|
23
|
+
|
|
24
|
+
if (
|
|
25
|
+
geom === "bar" ||
|
|
26
|
+
geom === "histogram" ||
|
|
27
|
+
geom === "freqpoly" ||
|
|
28
|
+
(geom === "line" && stat === "bin")
|
|
29
|
+
) {
|
|
30
|
+
errors.push({
|
|
31
|
+
code: "computed-y-mapped",
|
|
32
|
+
path: `${layerPath}/aes/y`,
|
|
33
|
+
message: `The ${geom} geom computes y with the ${stat} stat, so aes.y must not map data. Use geom "col" for pre-computed heights, or unset y with null.`,
|
|
34
|
+
fix: {
|
|
35
|
+
description: 'Switch the layer to geom "col" (identity stat) to draw mapped y values.',
|
|
36
|
+
example: { geom: "col" },
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (geom === "density") {
|
|
42
|
+
errors.push({
|
|
43
|
+
code: "computed-y-mapped",
|
|
44
|
+
path: `${layerPath}/aes/y`,
|
|
45
|
+
message:
|
|
46
|
+
"The density geom computes y with the density stat, so aes.y must not map data. Map only x, or unset y with null.",
|
|
47
|
+
fix: {
|
|
48
|
+
description: "Remove the y mapping (or unset an inherited one with null).",
|
|
49
|
+
example: { geom: "density", aes: { y: null } },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (geom === "function" || stat === "function") {
|
|
55
|
+
errors.push({
|
|
56
|
+
code: "computed-y-mapped",
|
|
57
|
+
path: `${layerPath}/aes/y`,
|
|
58
|
+
message:
|
|
59
|
+
"The function geom/stat computes y from the named function, so aes.y must not map data. Unset y with null.",
|
|
60
|
+
fix: {
|
|
61
|
+
description: "Remove the y mapping (or unset an inherited one with null).",
|
|
62
|
+
example: { geom: "function", aes: { y: null }, params: { fun: "dnorm", xlim: [-3, 3] } },
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (geom === "dotplot" || stat === "bindot") {
|
|
68
|
+
errors.push({
|
|
69
|
+
code: "computed-y-mapped",
|
|
70
|
+
path: `${layerPath}/aes/y`,
|
|
71
|
+
message:
|
|
72
|
+
"The dotplot geom computes y stack positions with the bindot stat, so aes.y must not map data. Map only x, or unset y with null.",
|
|
73
|
+
fix: {
|
|
74
|
+
description: "Remove the y mapping (or unset an inherited one with null).",
|
|
75
|
+
example: { geom: "dotplot", aes: { y: null } },
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (geom === "line" && stat === "ecdf") {
|
|
81
|
+
errors.push({
|
|
82
|
+
code: "computed-y-mapped",
|
|
83
|
+
path: `${layerPath}/aes/y`,
|
|
84
|
+
message:
|
|
85
|
+
'The ecdf stat computes y (cumulative proportion), so aes.y must not map data. Map only x, or use y: { stat: "ecdf" }.',
|
|
86
|
+
fix: {
|
|
87
|
+
description: 'Remove the y mapping (or set y: { stat: "ecdf" }).',
|
|
88
|
+
example: { geom: "line", stat: "ecdf", aes: { y: null } },
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return errors;
|
|
94
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ribbon geom structural form checks (orientation contracts).
|
|
3
|
+
* Orchestrated by validate-structure-layers.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { SpecError } from "./errors.js";
|
|
6
|
+
import type { ChannelName } from "./schema.js";
|
|
7
|
+
import { isRecord, pushMissingChannel } from "./validate-structure-layer-shared.js";
|
|
8
|
+
|
|
9
|
+
export function ribbonStructuralErrors(
|
|
10
|
+
layer: Record<string, unknown>,
|
|
11
|
+
layerPath: string,
|
|
12
|
+
mapped: (channel: ChannelName) => unknown,
|
|
13
|
+
): SpecError[] {
|
|
14
|
+
const errors: SpecError[] = [];
|
|
15
|
+
const params = isRecord(layer["params"]) ? layer["params"] : {};
|
|
16
|
+
const pinned =
|
|
17
|
+
params["orientation"] === "x" || params["orientation"] === "y" ? params["orientation"] : null;
|
|
18
|
+
const xContract =
|
|
19
|
+
mapped("x") !== undefined && mapped("ymin") !== undefined && mapped("ymax") !== undefined;
|
|
20
|
+
const yContract =
|
|
21
|
+
mapped("y") !== undefined && mapped("xmin") !== undefined && mapped("xmax") !== undefined;
|
|
22
|
+
|
|
23
|
+
if (pinned === null && xContract && yContract) {
|
|
24
|
+
errors.push({
|
|
25
|
+
code: "ribbon-orientation-ambiguous",
|
|
26
|
+
path: `${layerPath}/params/orientation`,
|
|
27
|
+
message:
|
|
28
|
+
'This ribbon layer maps both x-orientation (x+ymin+ymax) and y-orientation (y+xmin+xmax) contracts. Set params.orientation to "x" or "y".',
|
|
29
|
+
fix: {
|
|
30
|
+
description: "Pin orientation explicitly.",
|
|
31
|
+
example: { params: { orientation: "x" } },
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
return errors;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const orientation: "x" | "y" | null =
|
|
38
|
+
pinned === "x" || pinned === "y" ? pinned : xContract ? "x" : yContract ? "y" : null;
|
|
39
|
+
|
|
40
|
+
const usesYContract =
|
|
41
|
+
orientation === "y" ||
|
|
42
|
+
(orientation === null &&
|
|
43
|
+
[mapped("y"), mapped("xmin"), mapped("xmax")].some((value) => value !== undefined));
|
|
44
|
+
const needed: ChannelName[] = usesYContract ? ["y", "xmin", "xmax"] : ["x", "ymin", "ymax"];
|
|
45
|
+
|
|
46
|
+
for (const channel of needed) {
|
|
47
|
+
if (mapped(channel) !== undefined) continue;
|
|
48
|
+
const suffix = ribbonContractSuffix(orientation);
|
|
49
|
+
pushMissingChannel(
|
|
50
|
+
errors,
|
|
51
|
+
layerPath,
|
|
52
|
+
channel,
|
|
53
|
+
`The ribbon geom ${suffix} requires a "${channel}" channel; map it in the layer's aes or the plot-level aes.`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return errors;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ribbonContractSuffix(orientation: "x" | "y" | null): string {
|
|
60
|
+
return orientation === null ? "for its interval contract" : `with orientation "${orientation}"`;
|
|
61
|
+
}
|