Use ESM in Node.js code generation scripts (#2739)
This commit is contained in:
@@ -1,13 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
import { ArgumentParser } from "argparse";
|
||||
import * as path from "node:path";
|
||||
import spec from "./style-spec.mjs";
|
||||
import colorParser from "csscolorparser";
|
||||
|
||||
const { ArgumentParser } = require("argparse");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const spec = require('./style-spec');
|
||||
const colorParser = require('csscolorparser');
|
||||
|
||||
require('./style-code');
|
||||
import { camelize, camelizeWithLeadingLowercase, readAndCompile, writeIfModified } from "./style-code.mjs";
|
||||
|
||||
// Parse command line
|
||||
const args = (() => {
|
||||
@@ -21,22 +17,33 @@ const args = (() => {
|
||||
return parser.parse_args();
|
||||
})();
|
||||
|
||||
function parseCSSColor(str) {
|
||||
function parseCSSColor(/** @type {string} **/ str) {
|
||||
const color = colorParser.parseCSSColor(str);
|
||||
if (!color) throw new Error("Could not parse CSS color");
|
||||
return [
|
||||
color[0] / 255 * color[3], color[1] / 255 * color[3], color[2] / 255 * color[3], color[3]
|
||||
];
|
||||
}
|
||||
|
||||
global.isLightProperty = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
*/
|
||||
function isLightProperty(property) {
|
||||
return property['light-property'] === true;
|
||||
};
|
||||
|
||||
global.isOverridable = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
*/
|
||||
function isOverridable(property) {
|
||||
return ['text-color'].includes(property.name);
|
||||
};
|
||||
|
||||
global.expressionType = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
* @returns {string}
|
||||
*/
|
||||
function expressionType(property) {
|
||||
switch (property.type) {
|
||||
case 'boolean':
|
||||
return 'BooleanType';
|
||||
@@ -57,7 +64,12 @@ global.expressionType = function (property) {
|
||||
}
|
||||
};
|
||||
|
||||
global.evaluatedType = function (property) {
|
||||
/**
|
||||
*
|
||||
* @param {any} property
|
||||
* @returns {string}
|
||||
*/
|
||||
function evaluatedType(property) {
|
||||
if (/-translate-anchor$/.test(property.name)) {
|
||||
return 'TranslateAnchorType';
|
||||
}
|
||||
@@ -102,7 +114,12 @@ global.evaluatedType = function (property) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} property
|
||||
* @param {any} type
|
||||
*/
|
||||
function attributeUniformType(property, type) {
|
||||
/** @type {Record<string, string[]>} **/
|
||||
const attributeNameExceptions = {
|
||||
'text-opacity': ['opacity'],
|
||||
'icon-opacity': ['opacity'],
|
||||
@@ -120,6 +137,7 @@ function attributeUniformType(property, type) {
|
||||
'fill-pattern': ['pattern_to', 'pattern_from'],
|
||||
'fill-extrusion-pattern': ['pattern_to', 'pattern_from']
|
||||
}
|
||||
/** @type {string[]} **/
|
||||
const names = attributeNameExceptions[property.name] ||
|
||||
[ property.name.replace(type + '-', '').replace(/-/g, '_') ];
|
||||
|
||||
@@ -128,7 +146,10 @@ function attributeUniformType(property, type) {
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
global.layoutPropertyType = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
*/
|
||||
function layoutPropertyType(property) {
|
||||
switch (property['property-type']) {
|
||||
case 'data-driven':
|
||||
case 'cross-faded-data-driven':
|
||||
@@ -138,7 +159,13 @@ global.layoutPropertyType = function (property) {
|
||||
}
|
||||
};
|
||||
|
||||
global.paintPropertyType = function (property, type) {
|
||||
/**
|
||||
*
|
||||
* @param {any} property
|
||||
* @param {any} type
|
||||
* @returns
|
||||
*/
|
||||
function paintPropertyType(property, type) {
|
||||
switch (property['property-type']) {
|
||||
case 'data-driven':
|
||||
if (isOverridable(property))
|
||||
@@ -153,7 +180,10 @@ global.paintPropertyType = function (property, type) {
|
||||
}
|
||||
};
|
||||
|
||||
global.propertyValueType = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
*/
|
||||
function propertyValueType(property) {
|
||||
switch (property['property-type']) {
|
||||
case 'color-ramp':
|
||||
return `ColorRampPropertyValue`;
|
||||
@@ -162,6 +192,11 @@ global.propertyValueType = function (property) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} property
|
||||
* @param {number} num
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatNumber(property, num = 0) {
|
||||
if (evaluatedType(property) === "float") {
|
||||
const str = num.toString();
|
||||
@@ -170,7 +205,10 @@ function formatNumber(property, num = 0) {
|
||||
return num.toString();
|
||||
}
|
||||
|
||||
global.defaultValue = function (property) {
|
||||
/**
|
||||
* @param {any} property
|
||||
*/
|
||||
function defaultValue(property) {
|
||||
// https://github.com/mapbox/mapbox-gl-native/issues/5258
|
||||
if (property.name === 'line-round-limit') {
|
||||
return 1;
|
||||
@@ -210,7 +248,7 @@ global.defaultValue = function (property) {
|
||||
return `{ ${color} }`;
|
||||
}
|
||||
case 'array':
|
||||
const defaults = (property.default || []).map((e) => defaultValue({ type: property.value, default: e }));
|
||||
const defaults = (property.default || []).map((/** @type {any} **/ e) => defaultValue({ type: property.value, default: e }));
|
||||
if (property.length) {
|
||||
return `{{${defaults.join(', ')}}}`;
|
||||
} else {
|
||||
@@ -222,7 +260,7 @@ global.defaultValue = function (property) {
|
||||
};
|
||||
|
||||
console.log("Generating style code...");
|
||||
const root = path.dirname(__dirname);
|
||||
const root = path.join(import.meta.dirname, "..")
|
||||
const outLocation = args.out ? args.out : root;
|
||||
|
||||
const layerHpp = readAndCompile(`include/mbgl/style/layers/layer.hpp.ejs`, root);
|
||||
@@ -241,7 +279,9 @@ spec.paint_line['line-floor-width'] = {
|
||||
};
|
||||
|
||||
const layers = Object.keys(spec.layer.type.values).map((type) => {
|
||||
const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => {
|
||||
|
||||
/** @type {any[]} */
|
||||
const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((/** @type {any} **/ memo, name) => {
|
||||
if (name !== 'visibility') {
|
||||
spec[`layout_${type}`][name].name = name;
|
||||
memo.push(spec[`layout_${type}`][name]);
|
||||
@@ -253,7 +293,8 @@ const layers = Object.keys(spec.layer.type.values).map((type) => {
|
||||
// to get a deterministic order.
|
||||
layoutProperties.sort((a, b) => collator.compare(a.name, b.name));
|
||||
|
||||
const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => {
|
||||
/** @type {any[]} */
|
||||
const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((/** @type {any} **/ memo, name) => {
|
||||
spec[`paint_${type}`][name].name = name;
|
||||
memo.push(spec[`paint_${type}`][name]);
|
||||
return memo;
|
||||
@@ -273,7 +314,27 @@ const layers = Object.keys(spec.layer.type.values).map((type) => {
|
||||
};
|
||||
});
|
||||
|
||||
for (const layer of layers) {
|
||||
function setupGlobalEjsHelpers() {
|
||||
const funcs = {
|
||||
layoutPropertyType,
|
||||
evaluatedType,
|
||||
isOverridable,
|
||||
expressionType,
|
||||
defaultValue,
|
||||
paintPropertyType,
|
||||
propertyValueType,
|
||||
camelize,
|
||||
camelizeWithLeadingLowercase
|
||||
};
|
||||
for (const [funcName, func] of Object.entries(funcs)) {
|
||||
// @ts-ignore
|
||||
global[funcName] = func;
|
||||
}
|
||||
}
|
||||
|
||||
setupGlobalEjsHelpers();
|
||||
|
||||
for (let layer of layers) {
|
||||
const layerFileName = layer.type.replace('-', '_');
|
||||
|
||||
writeIfModified(`src/mbgl/style/layers/${layerFileName}_layer_properties.hpp`, propertiesHpp(layer), outLocation);
|
||||
@@ -289,7 +350,8 @@ for (const layer of layers) {
|
||||
}
|
||||
|
||||
// Light
|
||||
const lightProperties = Object.keys(spec[`light`]).reduce((memo, name) => {
|
||||
/** @type {any[]} **/
|
||||
const lightProperties = Object.keys(spec[`light`]).reduce((/** @type {any} **/ memo, name) => {
|
||||
var property = spec[`light`][name];
|
||||
property.name = name;
|
||||
property['light-property'] = true;
|
||||
1
scripts/global.d.ts
vendored
Normal file
1
scripts/global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module "csscolorparser"
|
||||
@@ -3,9 +3,16 @@
|
||||
"strict": true,
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"module": "NodeNext"
|
||||
"module": "NodeNext",
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true,
|
||||
"maxNodeModuleJsDepth": 0
|
||||
},
|
||||
"include": [
|
||||
"**/*.mjs"
|
||||
"./**/*.mjs",
|
||||
"**/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,42 +1,63 @@
|
||||
// Global functions //
|
||||
// EJS Helpers
|
||||
|
||||
const ejs = require('ejs');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import ejs from "ejs";
|
||||
import fs from "node:fs";
|
||||
|
||||
global.iff = function (condition, val) {
|
||||
import path from "node:path";
|
||||
|
||||
/**
|
||||
* @param {() => boolean} condition
|
||||
* @param {string} val
|
||||
* @returns {string}
|
||||
*/
|
||||
export function iff(condition, val) {
|
||||
return condition() ? val : "";
|
||||
};
|
||||
|
||||
global.camelize = function (str) {
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
export function camelize(str) {
|
||||
return str.replace(/(?:^|-)(.)/g, function (_, x) {
|
||||
return x.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
global.camelizeWithLeadingLowercase = function (str) {
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
export function camelizeWithLeadingLowercase(str) {
|
||||
return str.replace(/-(.)/g, function (_, x) {
|
||||
return x.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
global.snakeCaseUpper = function snakeCaseUpper(str) {
|
||||
export function snakeCaseUpper(/** @type {string} **/ str) {
|
||||
return str.replace(/-/g, "_").toUpperCase();
|
||||
};
|
||||
|
||||
global.unhyphenate = function (str) {
|
||||
export function unhyphenate (/** @type {string} **/ str) {
|
||||
return str.replace(/-/g, " ");
|
||||
};
|
||||
|
||||
// Write out a list of files that this script is modifying so that we can check
|
||||
var files = [];
|
||||
/** @type {string[]} **/
|
||||
let files = [];
|
||||
process.on('exit', function() {
|
||||
const list = path.join(path.dirname(process.argv[1]), path.basename(process.argv[1], '.js') + '.list');
|
||||
console.log(`Writing files that this script modifies to: ${list}`);
|
||||
fs.writeFileSync(list, files.join("\n"));
|
||||
});
|
||||
|
||||
global.writeIfModified = function(filename, newContent, output) {
|
||||
/**
|
||||
*
|
||||
* @param {string} filename
|
||||
* @param {string} newContent
|
||||
* @param {string} output
|
||||
*/
|
||||
export function writeIfModified(filename, newContent, output) {
|
||||
if (output) {
|
||||
filename = path.resolve(path.join(output, filename));
|
||||
}
|
||||
@@ -61,7 +82,13 @@ global.writeIfModified = function(filename, newContent, output) {
|
||||
console.warn(`* Updating outdated file '${filename}'`);
|
||||
};
|
||||
|
||||
global.readAndCompile = function(filename, root) {
|
||||
/**
|
||||
*
|
||||
* @param {string} filename
|
||||
* @param {string} root
|
||||
* @returns
|
||||
*/
|
||||
export function readAndCompile(filename, root) {
|
||||
if (root) {
|
||||
filename = path.resolve(path.join(root, filename));
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
const referenceSpec = require('../scripts/style-spec-reference/v8');
|
||||
import referenceSpec from "../scripts/style-spec-reference/v8.json" with { type: "json" };
|
||||
|
||||
referenceSpec.layer.type.values["location-indicator"] = {};
|
||||
referenceSpec["layout_location-indicator"] = {
|
||||
/** @type {any} */
|
||||
let modifiedReferenceSpec = referenceSpec;
|
||||
|
||||
modifiedReferenceSpec.layer.type.values["location-indicator"] = {};
|
||||
modifiedReferenceSpec["layout_location-indicator"] = {
|
||||
"top-image": {
|
||||
"type": "resolvedImage",
|
||||
"property-type": "data-constant",
|
||||
@@ -37,7 +40,7 @@ referenceSpec["layout_location-indicator"] = {
|
||||
}
|
||||
};
|
||||
|
||||
referenceSpec["paint_location-indicator"] = {
|
||||
modifiedReferenceSpec["paint_location-indicator"] = {
|
||||
"perspective-compensation": {
|
||||
"type": "number",
|
||||
"default": "0.85",
|
||||
@@ -65,7 +68,6 @@ referenceSpec["paint_location-indicator"] = {
|
||||
},
|
||||
"bearing": {
|
||||
"type": "number",
|
||||
"default": "0",
|
||||
"default": 0,
|
||||
"period": 360,
|
||||
"units": "degrees",
|
||||
@@ -176,21 +178,7 @@ referenceSpec["paint_location-indicator"] = {
|
||||
},
|
||||
"transition": true,
|
||||
"doc": "The color for drawing the accuracy radius border. To adjust transparency, set the alpha component of the color accordingly."
|
||||
},
|
||||
"bearing": {
|
||||
"type": "number",
|
||||
"default": "0",
|
||||
"default": 0,
|
||||
"period": 360,
|
||||
"units": "degrees",
|
||||
"property-type": "data-constant",
|
||||
"expression": {
|
||||
"interpolated": false,
|
||||
"parameters": [ ]
|
||||
},
|
||||
"transition": false,
|
||||
"doc": "The bearing of the location indicator."
|
||||
}
|
||||
};
|
||||
|
||||
var spec = module.exports = referenceSpec
|
||||
export default modifiedReferenceSpec;
|
||||
Reference in New Issue
Block a user