UNPKG

rollup-plugin-drupal-sdc-generator

Version:

This is a [Rollup](https://rollupjs.org) plugin that creates [single directory components](https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components) for embedding your app in a [Drupal](https://www.drupal.org) module or theme.

129 lines (108 loc) 4.44 kB
'use strict'; var promises = require('node:fs/promises'); var node_path = require('node:path'); var node_url = require('node:url'); var yaml = require('yaml'); var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; const FILE_PATH = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))); const DIRECTORY_NAME = node_path.dirname(FILE_PATH); function drupalSdcGenerator({ directory: _directory, group, label: _label = 'My Component', } = {}) { const directory = _directory || node_path.join(DIRECTORY_NAME, '../templates'); const label = _label || 'My Component'; return { name: 'rollup-plugin-drupal-sdc-generator', async generateBundle(options, bundle) { for (const bundleId in bundle) { const { isEntry, name, fileName, type } = bundle[bundleId]; this.debug( `Working on ${bundleId} isEntry=${isEntry}, name=${name}, fileName=${fileName}, type=${type}`, ); if (Object.hasOwn(bundle, 'style.css')) { const bundleId = 'style.css'; const cssFileName = node_path.basename(options.dir); this.debug({ message: `Renaming ${bundleId} to ${cssFileName}.css`, }); bundle[bundleId].fileName = `${cssFileName}.css`; } if (type !== 'chunk' || !isEntry) { this.debug({ message: `Skipping ${bundleId}` }); continue; } const templateDirectory = typeof directory === 'object' ? directory[name] : directory; const files = await promises.readdir(templateDirectory); const templateLabel = typeof label === 'object' ? label[name] : label; const templateGroup = typeof group === 'object' ? group[name] : group; await Promise.all( files.map(async (file) => { const source = await promises.readFile( node_path.join(templateDirectory, file), 'utf8', ); const emittedFileName = file.replace('[name]', name); this.debug(`emitted filename is ${emittedFileName}`); const vars = { name, label: templateLabel }; const reducer = (acc, key) => { return acc .replaceAll( new RegExp(`(?<!\\[)\\[${key}](?!])`, 'g'), vars[key], ) .replaceAll(new RegExp(`\\[\\[${key}\\]]`, 'g'), `[${key}]`); }; const sourceDoc = yaml.parseDocument(source); if ( templateGroup && sourceDoc.contents && sourceDoc.contents.items ) { sourceDoc.add(sourceDoc.createPair('group', templateGroup)); } const applyVars = (str) => Object.keys(vars).reduce(reducer, str); const processComments = (node) => { if (!node) return; if (node.commentBefore != null) { node.commentBefore = applyVars(node.commentBefore); } if (node.comment != null) { node.comment = applyVars(node.comment); } }; yaml.visit(sourceDoc, { Pair(_, pair) { if (pair.key) { processComments(pair.key); if (typeof pair.key.value === 'string') { pair.key.value = applyVars(pair.key.value); } } if (pair.value) { processComments(pair.value); if (typeof pair.value.value === 'string') { pair.value.value = applyVars(pair.value.value); } } }, }); const emittedSource = yaml.stringify(sourceDoc); const emittedFile = { type: 'asset', fileName: emittedFileName, source: emittedSource, }; this.debug({ message: `Emitting ${bundleId} => ${emittedFile.fileName}`, }); this.emitFile(emittedFile); }), ); } }, }; } module.exports = drupalSdcGenerator;