UNPKG

@plaiceholder/tailwindcss

Version:

Roll-you-own placeholders for Tailwind.

246 lines (193 loc) 5.3 kB
import plugin$1 from 'tailwindcss/plugin.js'; import childProcess from 'child_process'; import v8 from 'v8'; import crypto from 'crypto'; var cryptoRandomString = length => { if (!Number.isFinite(length)) { throw new TypeError('Expected a finite number'); } return crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length); }; var uniqueString = () => cryptoRandomString(32); const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g; var escapeStringRegexp = string => { if (typeof string !== 'string') { throw new TypeError('Expected a string'); } return string.replace(matchOperatorsRegex, '\\$&'); }; class Subsume { static parse(text, id) { return (new Subsume(id)).parse(text); } static parseAll(text, ids) { if (ids && !Array.isArray(ids)) { throw new TypeError('IDs is supposed to be an array'); } const result = {data: new Map(), rest: text}; const idList = ids ? ids : Subsume._extractIDs(text); if (!ids) { try { Subsume._checkIntegrity(text); } catch (error) { throw new Error(`Could not parse because the string's integrity is compromised: ${error.message}`); } } for (const id of idList) { if (result.data.get(id)) { throw new Error('IDs aren\'t supposed to be repeated at the same level in a string'); } const res = Subsume.parse(result.rest, id); result.data.set(id, res.data); result.rest = res.rest; } return result; } static _extractIDs(text) { try { Subsume._checkIntegrity(text); } catch (error) { throw new Error(`Could not extract IDs because the string's integrity is compromised: ${error.message}`); } const idRegex = /@@\[(.{32})\]@@.*##\[\1\]##/g; const idList = []; let match; do { match = idRegex.exec(text); if (match) { const [, id] = match; idList.push(id); } } while (match); return idList; } static _checkIntegrity(text) { const delimiterRegex = /([#|@])\1\[(.{32})\]\1{2}/g; const ids = new Map(); const idStack = []; let match; do { match = delimiterRegex.exec(text); if (match) { const [, embedToken, id] = match; if (embedToken === '@') { let map = ids; for (const el of idStack) { map = map.get(el); } if (map.get(id)) { throw new Error('There are duplicate IDs in the same scope.'); } map.set(id, new Map()); idStack.push(id); } else { idStack.pop(); } } } while (match); if (idStack.length !== 0) { throw new Error('There is a mismatch between prefixes and suffixes'); } return ids; } constructor(id) { if (id && (id.includes('@@[') || id.includes('##['))) { throw new Error('`@@[` and `##[` cannot be used in the ID'); } this.id = id ? id : uniqueString(); this.prefix = `@@[${this.id}]@@`; this.postfix = `##[${this.id}]##`; this.regex = new RegExp(escapeStringRegexp(this.prefix) + '([\\S\\s]*)' + escapeStringRegexp(this.postfix), 'g'); } compose(text) { return this.prefix + text + this.postfix; } parse(text) { try { Subsume._checkIntegrity(text); } catch (error) { throw new Error(`Could not extract IDs because the string's integrity is compromised: ${error.message}`); } const ret = {}; ret.rest = text.replace(this.regex, (m, p1) => { if (p1) { ret.data = p1; } return ''; }); return ret; } } var subsume = Subsume; const HUNDRED_MEGABYTES = 1000 * 1000 * 100; var makeSynchronous = function_ => { return (...arguments_) => { const serializedArguments = v8.serialize(arguments_).toString('hex'); const subsume$1 = new subsume(); const input = ` const v8 = require('v8'); const Subsume = require('subsume'); const subsume = new Subsume('${subsume$1.id}'); const send = value => { const serialized = v8.serialize(value).toString('hex'); process.stdout.write(subsume.compose(serialized)); }; (async () => { try { const arguments_ = v8.deserialize(Buffer.from('${serializedArguments}', 'hex')); const result = await (${function_})(...arguments_); send({result}); } catch (error) { send({error}); } })(); `; const {error: subprocessError, stdout, stderr} = childProcess.spawnSync(process.execPath, ['-'], { input, encoding: 'utf8', maxBuffer: HUNDRED_MEGABYTES, env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' } }); if (subprocessError) { throw subprocessError; } const {data, rest} = subsume$1.parse(stdout); process.stdout.write(rest); process.stderr.write(stderr); if (!data) { return; } const {error, result} = v8.deserialize(Buffer.from(data, 'hex')); if (error) { throw error; } return result; }; }; const classNamePrefix = "plaiceholder"; const getPlaiceholder = makeSynchronous(async buffer => { const { getPlaiceholder } = await import('plaiceholder'); const { css } = await getPlaiceholder(buffer); return css; }); var plugin = plugin$1.withOptions(function (options = {}) { return function ({ matchUtilities }) { matchUtilities({ [classNamePrefix]: function (src) { const file = options.resolver(src); return getPlaiceholder(file); } }); }; }); export { plugin as default }; //# sourceMappingURL=plugin.esm.js.map