UNPKG

npm-template-sync

Version:

Keep npm package in sync with its template

173 lines (146 loc) 3.82 kB
import { join, dirname } from "path"; import fs, { createWriteStream } from "fs"; import { isScalar } from "hinted-tree-merger"; export const defaultEncodingOptions = { encoding: "utf8" }; export function asArray(o) { return Array.isArray(o) ? o : o === undefined ? [] : [o]; } export function asScalar(o) { return Array.isArray(o) && o.length === 1 ? o[0] : o; } export function setProperty(properties, attributePath, value) { const m = attributePath.match(/^(\w+)\.(.*)/); if (m) { const key = m[1]; if (properties[key] === undefined) { properties[key] = {}; } setProperty(properties[key], m[2], value); } else { properties[attributePath] = value; } } /** * */ export function jspath(object, path, cb) { let parts = path.split("."); parts = parts.reduce((a, c) => { const m = c.match(/^(\w+)\['(.+)'\]$/); return m ? [...a, m[1], m[2]] : [...a, c]; }, []); const last = parts.pop(); for (const p of parts) { if (p === "$") { continue; } const n = object[p]; if (n === undefined) { return undefined; } object = n; } if (cb !== undefined) { cb(object[last], value => { object[last] = value; }); } return object[last]; } export function actions2message(actions, prefix, name) { return actions2messages(actions, prefix, name).join("\n"); } export function actions2messages(actions, prefix, name) { const messages = Object.entries(actions).map(([slot, action]) => { const toValue = s => (s !== undefined && isScalar(s) ? s : undefined); const verbs = ["add", "remove", "update"] .map(verb => [ verb, action.map(x => toValue(x[verb])).filter(x => x !== undefined) ]) .filter(([name, value]) => value.length > 0) .map(([name, value]) => `${name} ${value}`); verbs.push(`(${slot.replace(/\[\d*\]/, "")})`); const a = action.reduce((a, c) => Object.assign(a, c), { type: "chore" }); if (a.type) { prefix = a.type; if (a.scope) { prefix += `(${a.scope})`; } prefix += ": "; } return prefix + verbs.join(" "); }); return messages.length === 0 ? [`${prefix}merge from template ${name}`] : messages; } export function aggregateActions(actions, action, hint) { if (hint) { for (const key of ["type", "scope"]) { if (hint[key]) { action[key] = hint[key]; } } } if (actions[action.path] === undefined) { actions[action.path] = [action]; } else { actions[action.path].push(action); } delete action.path; } export function log(level, ...args) { switch (level) { case "warn": console.warn(...args); break; default: console.log(...args); break; } /* const prefixKeys = { branch: 1, severity: "info" }; const valueKeys = { message: "v", timestamp: "d" }; const prefix = Object.keys(prefixKeys).reduce((a, c) => { if (arg[c]) { if (prefixKeys[c] !== arg[c]) { a.push(arg[c]); } delete arg[c]; } return a; }, []); const values = Object.keys(arg).reduce((a, c) => { if (arg[c] !== undefined) { switch (valueKeys[c]) { case "v": a.push(arg[c]); break; case "d": break; default: a.push(`${c}=${JSON.stringify(arg[c])}`); } } return a; }, []); console.log(`${prefix.join(",")}: ${values.join(" ")}`); */ } export async function dumpTemplateEntries(template, dest) { for (const entry of template.entryCache.values()) { if (entry.isBlob) { const d = join(dest, entry.name); await fs.promises.mkdir(dirname(d), { recursive: true }); const s = await entry.getReadStream(); s.pipe(createWriteStream(d)); } } }