@mapbox/mapbox-gl-style-spec
Version:
a specification for mapbox gl styles
57 lines (47 loc) • 1.76 kB
text/typescript
import refProperties from './util/ref_properties';
import type {LayerSpecification} from './types';
function deref(layer: LayerSpecification, parent: LayerSpecification): LayerSpecification {
const result = {} as LayerSpecification;
for (const k in layer) {
if (k !== 'ref') {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
result[k] = layer[k];
}
}
refProperties.forEach((k) => {
if (k in parent) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
result[k] = parent[k];
}
});
return result;
}
/**
* Given an array of layers, some of which may contain `ref` properties
* whose value is the `id` of another property, return a new array where
* such layers have been augmented with the 'type', 'source', etc. properties
* from the parent layer, and the `ref` property has been removed.
*
* The input is not modified. The output may contain references to portions
* of the input.
*
* @private
* @param {Array<Layer>} layers
* @returns {Array<Layer>}
*/
export default function derefLayers(layers: Array<LayerSpecification>): Array<LayerSpecification> {
layers = layers.slice();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const map: Record<string, LayerSpecification> = Object.create(null);
for (const layer of layers) {
map[layer.id] = layer;
}
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
if (layer && 'ref' in layer) {
const parent = map[(layer as LayerSpecification & {ref: string}).ref];
if (parent) layers[i] = deref(layer, parent);
}
}
return layers;
}