UNPKG

@gouvfr/dsfr-nexus

Version:

Le module `dsfr-nexus` est l'interface de ligne de commande (CLI) centrale du Système de Design de l’État - DSFR. Il offre des outils pour gérer et compiler les ressources du DSFR

200 lines (165 loc) 5.11 kB
import yaml from 'yaml'; import { PageNode } from '../page-node.js'; import { log } from '@gouvfr/dsfr-forge'; class DirectiveNode extends PageNode { constructor (data, state) { super(data, state); this._name = data.name; this._properties = data.properties; } structure (data, state) { const parameters = data.attributes; delete data.attributes; if (!parameters) { return super.structure(data, state); } const properties = {}; const attributes = {}; for (const key in parameters) { const parts = key.split('.'); let current = properties; switch (parts[0]) { case 'attributes': current = attributes; parts.shift(); break; case 'id': attributes.id = parameters[key]; break; // TODO: id outside properties case 'class': if (!data.classes) data.classes = []; data.classes.push(...parameters.class.split(' ').map(c => c.trim()).filter(Boolean)); // TODO: class outside properties (in attributes and remove classes) continue; } while (parts.length > 1) { const part = parts.shift(); if (!current[part]) current[part] = {}; current = current[part]; } const lastPart = parts.shift(); if (lastPart) { try { current[lastPart] = yaml.parse(parameters[key]); } catch (e) { log.warn(`Failed to parse property "${key}" as YAML : ${e.message}`); // If parsing fails, store the value as a string current[lastPart] = parameters[key]; } } } data.properties = properties; data.attributes = attributes; return super.structure(data, state); } get properties () { return this._properties; } getStringProperty (key) { const value = this.properties[key]; if (value === undefined || value === null) return undefined; return String(value).trim(); } getBooleanProperty (key) { const value = this.properties[key]; if (value === undefined || value === null) return undefined; switch (typeof value) { case 'string': return value.toLowerCase() === 'true'; case 'boolean': return value; case 'number': return value !== 0; default: log.error(`Unsupported type for boolean property "${key}": ${typeof value}`); } return undefined; } getNumberProperty (key) { const value = this.properties[key]; if (value === undefined || value === null) return undefined; const number = Number(value); return isNaN(number) ? undefined : number; } getArrayProperty (key, type = 'string', length = null) { const value = this.properties[key]; if (value === undefined || value === null) return undefined; let array; switch (typeof value) { case 'string': array = value.split(',').map(item => item.trim()).filter(Boolean); break; case 'object': if (Array.isArray(value)) { array = value; } else { array = Object.values(value); } break; case type: array = [value]; break; default: log.error(`Unsupported type for array property "${key}": ${typeof value}`); return undefined; } if (array.length === 0 || array[0] === undefined) return undefined; if (length !== null && !isNaN(length) && length > 0) { if (array.length > length) array.length = length; if (array.length < length) array.push(...new Array(length - array.length).fill(array[0])); } switch (type) { case 'string': return array.map(item => String(item)); case 'number': return array.map(item => { const number = Number(item); return isNaN(number) ? array[0] : number; }); case 'boolean': return array.map(item => item === true); //TODO: case 'object': default: throw new Error(`Unsupported type: ${type}`); } } getObjectProperty (key) { const value = this.properties[key]; if (value === undefined || value === null) return undefined; if (typeof value === 'string') { if (/"\s*:/.test(value)) { // If the value looks like a JSON object, try to parse it as JSON first try { return JSON.parse(value); } catch (e) { log.warn(`Failed to parse object property "${key}" as JSON : ${e.message}`); } } if (/:\s+/.test(value)) { // If the value looks like a YAML object, try to parse it as YAML try { return yaml.parse(value); } catch (e) { log.warn(`Failed to parse object property "${key}" as YAML : ${e.message}`); } } } if (typeof value !== 'object') { return undefined; } return value; } get name () { return this._name; } get data () { return { ...super.data, name: this.name, properties: this.properties, }; } } export { DirectiveNode };