diff --git a/CHANGELOG.md b/CHANGELOG.md index 310f4f4b..50aa4d50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,11 @@ ### ✨ Features and improvements +- Add `latest.json` to dist folder to allow using the full version of the spec [#490](https://github.com/maplibre/maplibre-style-spec/pull/490) - _...Add new stuff here..._ ### 🐞 Bug fixes + - _...Add new stuff here..._ ## 20.0.0 diff --git a/package.json b/package.json index 257cfc1f..71bd516c 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "types": "./dist/index.d.ts", "type": "module", "scripts": { - "build": "rollup --configPlugin @rollup/plugin-typescript -c rollup.config.ts", + "build": "rollup --configPlugin @rollup/plugin-typescript -c rollup.config.ts && cp ./src/reference/v8.json ./dist/latest.json", "generate-style-spec": "node --no-warnings --loader ts-node/esm build/generate-style-spec.ts", "generate-typings": "node --no-warnings --loader ts-node/esm build/generate-typings.ts", "test-build": "jest --selectProjects=build", diff --git a/src/migrate.ts b/src/migrate.ts index 822aa95f..7bd3f8f2 100644 --- a/src/migrate.ts +++ b/src/migrate.ts @@ -6,16 +6,14 @@ import {eachProperty} from './visit'; import type {StyleSpecification} from './types.g'; /** - * Migrate a Mapbox GL Style to the latest version. + * Migrate a Mapbox/MapLibre GL Style to the latest version. * - * @private - * @alias migrate - * @param {StyleSpecification} style a MapLibre Style - * @returns {StyleSpecification} a migrated style + * @param style - a MapLibre Style + * @returns a migrated style * @example - * var fs = require('fs'); - * var migrate = require('maplibre-gl-style-spec').migrate; - * var style = fs.readFileSync('./style.json', 'utf8'); + * const fs = require('fs'); + * csont migrate = require('@maplibre/maplibre-gl-style-spec').migrate; + * const style = fs.readFileSync('./style.json', 'utf8'); * fs.writeFileSync('./style.json', JSON.stringify(migrate(style))); */ export default function migrate(style: StyleSpecification): StyleSpecification { diff --git a/src/migrate/v9.test.ts b/src/migrate/v9.test.ts deleted file mode 100644 index b66ebcfe..00000000 --- a/src/migrate/v9.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import migrate from './v9'; - -describe('migrate v9', () => { - test('deref layers', () => { - const input = { - version: 8, - sources: { - a: {type: 'vector', tiles: ['http://dev/null']} - }, - layers: [{ - id: 'parent', - source: 'a', - 'source-layer': 'x', - type: 'fill' - }, { - id: 'child', - ref: 'parent' - }] - } as any; - - expect(migrate(input)).toEqual({ - version: 9, - sources: { - a: {type: 'vector', tiles: ['http://dev/null']} - }, - layers: [{ - id: 'parent', - source: 'a', - 'source-layer': 'x', - type: 'fill' - }, { - id: 'child', - source: 'a', - 'source-layer': 'x', - type: 'fill' - }] - }); - - }); - - test('declass style', () => { - const input = { - version: 8, - sources: { - a: {type: 'vector', tiles: ['http://dev/null']} - }, - layers: [{ - id: 'a', - source: 'a', - type: 'fill', - paint: {}, - 'paint.right': { - 'fill-color': 'red' - }, - 'paint.left': { - 'fill-color': 'blue' - } - }] - } as any; - - expect(migrate(input)).toEqual({ - version: 9, - sources: { - a: {type: 'vector', tiles: ['http://dev/null']} - }, - layers: [{ - id: 'a', - source: 'a', - type: 'fill', - paint: {} - }] - }); - - }); - -}); diff --git a/src/migrate/v9.ts b/src/migrate/v9.ts deleted file mode 100644 index 0db27a0c..00000000 --- a/src/migrate/v9.ts +++ /dev/null @@ -1,27 +0,0 @@ - -import deref from '../deref'; -import type {StyleSpecification} from '../types.g'; - -function eachLayer(style, callback) { - for (const k in style.layers) { - callback(style.layers[k]); - } -} - -export default function migrateV9(style: StyleSpecification): StyleSpecification { - (style.version as any) = 9; - - // remove user-specified refs - style.layers = deref(style.layers); - - // remove class-specific paint properties - eachLayer(style, (layer) => { - for (const k in layer) { - if (/paint\..*/.test(k)) { - delete layer[k]; - } - } - }); - - return style; -} diff --git a/src/validate/latest.ts b/src/validate/latest.ts deleted file mode 100644 index 91db6e9e..00000000 --- a/src/validate/latest.ts +++ /dev/null @@ -1,11 +0,0 @@ - -import validateStyle from '../validate_style.min'; - -/* - * Validate a style against the latest specification. This method is optimized - * to keep its bundle size small by refraining from requiring jslint or old - * style spec versions. - * @see validateStyleMin - * @deprecated This file exists for backwards compatibility and will be dropped in the next minor release. - */ -export default validateStyle; diff --git a/src/validate/validate.ts b/src/validate/validate.ts index 06c1e692..faf31ebd 100644 --- a/src/validate/validate.ts +++ b/src/validate/validate.ts @@ -25,6 +25,7 @@ import validateImage from './validate_image'; import validatePadding from './validate_padding'; import validateVariableAnchorOffsetCollection from './validate_variable_anchor_offset_collection'; import validateSprite from './validate_sprite'; +import ValidationError from '../error/validation_error'; const VALIDATORS = { '*'() { @@ -52,17 +53,30 @@ const VALIDATORS = { 'sprite': validateSprite, }; -// Main recursive validation function. Tracks: -// -// - key: string representing location of validation in style tree. Used only -// for more informative error reporting. -// - value: current value from style being evaluated. May be anything from a -// high level object that needs to be descended into deeper or a simple -// scalar value. -// - valueSpec: current spec being evaluated. Tracks value. -// - styleSpec: current full spec being evaluated. - -export default function validate(options) { +/** + * Main recursive validation function used internally. + * You should use `validateStyleMin` in the browser or `validateStyle` in node env. + * @param options - the options object + * @param options.key - string representing location of validation in style tree. Used only + * for more informative error reporting. + * @param options.value - current value from style being evaluated. May be anything from a + * high level object that needs to be descended into deeper or a simple + * scalar value. + * @param options.valueSpec - current spec being evaluated. Tracks value. + * @param options.styleSpec - current full spec being evaluated. + * @param options.validateSpec - the validate function itself + * @param options.style - the style object + * @param options.objectElementValidators - optional object of functions that will be called + * @returns an array of errors, or an empty array if no errors are found. + */ +export default function validate(options: { + key: any; + value: any; + valueSpec: any; + styleSpec: any; + validateSpec?: any; + style: any; + objectElementValidators?: any;}): ValidationError[] { const value = options.value; const valueSpec = options.valueSpec; const styleSpec = options.styleSpec; diff --git a/src/validate/validate_object.ts b/src/validate/validate_object.ts index 7b790e58..992bb100 100644 --- a/src/validate/validate_object.ts +++ b/src/validate/validate_object.ts @@ -10,7 +10,7 @@ export default function validateObject(options): Array { const style = options.style; const styleSpec = options.styleSpec; const validateSpec = options.validateSpec; - let errors = [] as Array; + let errors: ValidationError[] = []; const type = getType(object); if (type !== 'object') { diff --git a/src/validate_style.min.ts b/src/validate_style.min.ts index 4188496b..ca6d6757 100644 --- a/src/validate_style.min.ts +++ b/src/validate_style.min.ts @@ -11,28 +11,26 @@ import validateLayer from './validate/validate_layer'; import validateFilter from './validate/validate_filter'; import validatePaintProperty from './validate/validate_paint_property'; import validateLayoutProperty from './validate/validate_layout_property'; -import type {StyleSpecification} from './types.g'; import validateSprite from './validate/validate_sprite'; import validateGlyphsUrl from './validate/validate_glyphs_url'; +import ValidationError from './error/validation_error'; +import type {StyleSpecification} from './types.g'; /** - * Validate a MapLibre style against the style specification. This entrypoint, - * `maplibre-gl-style-spec/lib/validate_style.min`, is designed to produce as - * small a browserify bundle as possible by omitting unnecessary functionality - * and legacy style specifications. + * Validate a MapLibre style against the style specification. + * Use this when running in the browser. * - * @private - * @param {Object} style The style to be validated. - * @param {Object} [styleSpec] The style specification to validate against. - * If omitted, the latest style spec is used. - * @returns {Array} + * @param style - The style to be validated. + * @param styleSpec - The style specification to validate against. + * If omitted, the latest style spec is used. + * @returns an array of errors, or an empty array if no errors are found. * @example - * var validate = require('maplibre-gl-style-spec/lib/validate_style.min'); - * var errors = validate(style); + * const validate = require('@maplibre/maplibre-gl-style-spec/').validateStyleMin; + * const errors = validate(style); */ -function validateStyleMin(style: StyleSpecification, styleSpec = latestStyleSpec) { +function validateStyleMin(style: StyleSpecification, styleSpec = latestStyleSpec): Array { - let errors = []; + let errors: ValidationError[] = []; errors = errors.concat(validate({ key: '', diff --git a/src/validate_style.ts b/src/validate_style.ts index 27ad502b..7ab36e32 100644 --- a/src/validate_style.ts +++ b/src/validate_style.ts @@ -5,19 +5,17 @@ import readStyle from './read_style'; import type {StyleSpecification} from './types.g'; /** - * Validate a Mapbox GL style against the style specification. + * Validate a MapLibre GL style against the style specification. * - * @private - * @alias validate - * @param {StyleSpecification|string|Buffer} style The style to be validated. If a `String` - * or `Buffer` is provided, the returned errors will contain line numbers. - * @param {Object} [styleSpec] The style specification to validate against. - * If omitted, the spec version is inferred from the stylesheet. - * @returns {Array} + * @param style - The style to be validated. If a `String` or `Buffer` is provided, + * the returned errors will contain line numbers. + * @param styleSpec - The style specification to validate against. + * If omitted, the spec version is inferred from the stylesheet. + * @returns an array of errors, or an empty array if no errors are found. * @example - * var validate = require('maplibre-gl-style-spec').validate; - * var style = fs.readFileSync('./style.json', 'utf8'); - * var errors = validate(style); + * const validate = require('maplibre-gl-style-spec').validate; + * const style = fs.readFileSync('./style.json', 'utf8'); + * const errors = validate(style); */ export default function validateStyle(style: StyleSpecification | string | Buffer, styleSpec = v8): Array { diff --git a/test/build/style-spec.test.ts b/test/build/style-spec.test.ts index 1fa028ab..f7503c4b 100644 --- a/test/build/style-spec.test.ts +++ b/test/build/style-spec.test.ts @@ -6,27 +6,26 @@ const minBundle = fs.readFileSync('dist/index.mjs', 'utf8'); describe('@maplibre/maplibre-gl-style-spec npm package', () => { test('files build', async () => { - expect(await readdir('dist')).toMatchInlineSnapshot(` -[ - "gl-style-format.cjs", - "gl-style-format.cjs.map", - "gl-style-format.mjs", - "gl-style-format.mjs.map", - "gl-style-migrate.cjs", - "gl-style-migrate.cjs.map", - "gl-style-migrate.mjs", - "gl-style-migrate.mjs.map", - "gl-style-validate.cjs", - "gl-style-validate.cjs.map", - "gl-style-validate.mjs", - "gl-style-validate.mjs.map", - "index.cjs", - "index.cjs.map", - "index.d.ts", - "index.mjs", - "index.mjs.map", -] -`); + const dirContents = await readdir('dist'); + expect(dirContents).toContain('gl-style-format.cjs'); + expect(dirContents).toContain('gl-style-format.cjs.map'); + expect(dirContents).toContain('gl-style-format.mjs'); + expect(dirContents).toContain('gl-style-format.mjs.map'); + expect(dirContents).toContain('gl-style-migrate.cjs'); + expect(dirContents).toContain('gl-style-migrate.cjs.map'); + expect(dirContents).toContain('gl-style-migrate.mjs'); + expect(dirContents).toContain('gl-style-migrate.mjs.map'); + expect(dirContents).toContain('gl-style-validate.cjs'); + expect(dirContents).toContain('gl-style-validate.cjs.map'); + expect(dirContents).toContain('gl-style-validate.mjs'); + expect(dirContents).toContain('gl-style-validate.mjs.map'); + expect(dirContents).toContain('index.cjs'); + expect(dirContents).toContain('index.cjs.map'); + expect(dirContents).toContain('index.d.ts'); + expect(dirContents).toContain('index.mjs'); + expect(dirContents).toContain('index.mjs.map'); + expect(dirContents).toContain('latest.json'); + expect(dirContents).toHaveLength(18); }); test('exports components directly, not behind `default` - https://github.com/mapbox/mapbox-gl-js/issues/6601', async () => {