import type { ParserOptions as ParserOpts } from "@babel/parser"; export type { ParserOpts }; /** * These are the options that 'babel-template' actually accepts and typechecks * when called. All other options are passed through to the parser. */ export type PublicOpts = { /** * A set of placeholder names to automatically accept, ignoring the given * pattern entirely. * * This option can be used when using %%foo%% style placeholders. */ placeholderWhitelist?: Set; /** * A pattern to search for when looking for Identifier and StringLiteral * nodes that can be replaced. * * 'false' will disable placeholder searching entirely, leaving only the * 'placeholderWhitelist' value to find replacements. * * Defaults to /^[_$A-Z0-9]+$/. * * This option can be used when using %%foo%% style placeholders. */ placeholderPattern?: RegExp | false; /** * 'true' to pass through comments from the template into the resulting AST, * or 'false' to automatically discard comments. Defaults to 'false'. */ preserveComments?: boolean; /** * 'true' to use %%foo%% style placeholders, 'false' to use legacy placeholders * described by placeholderPattern or placeholderWhitelist. * When it is not set, it behaves as 'true' if there are syntactic placeholders, * otherwise as 'false'. */ syntacticPlaceholders?: boolean | null; }; export type TemplateOpts = { parser: ParserOpts; placeholderWhitelist?: Set; placeholderPattern?: RegExp | false; preserveComments?: boolean; syntacticPlaceholders?: boolean; }; export function merge(a: TemplateOpts, b: TemplateOpts): TemplateOpts { const { placeholderWhitelist = a.placeholderWhitelist, placeholderPattern = a.placeholderPattern, preserveComments = a.preserveComments, syntacticPlaceholders = a.syntacticPlaceholders, } = b; return { parser: { ...a.parser, ...b.parser, }, placeholderWhitelist, placeholderPattern, preserveComments, syntacticPlaceholders, }; } export function validate(opts: unknown): TemplateOpts { if (opts != null && typeof opts !== "object") { throw new Error("Unknown template options."); } const { placeholderWhitelist, placeholderPattern, preserveComments, syntacticPlaceholders, ...parser } = opts || ({} as any); if (placeholderWhitelist != null && !(placeholderWhitelist instanceof Set)) { throw new Error( "'.placeholderWhitelist' must be a Set, null, or undefined", ); } if ( placeholderPattern != null && !(placeholderPattern instanceof RegExp) && placeholderPattern !== false ) { throw new Error( "'.placeholderPattern' must be a RegExp, false, null, or undefined", ); } if (preserveComments != null && typeof preserveComments !== "boolean") { throw new Error( "'.preserveComments' must be a boolean, null, or undefined", ); } if ( syntacticPlaceholders != null && typeof syntacticPlaceholders !== "boolean" ) { throw new Error( "'.syntacticPlaceholders' must be a boolean, null, or undefined", ); } if ( syntacticPlaceholders === true && (placeholderWhitelist != null || placeholderPattern != null) ) { throw new Error( "'.placeholderWhitelist' and '.placeholderPattern' aren't compatible" + " with '.syntacticPlaceholders: true'", ); } return { parser, placeholderWhitelist: placeholderWhitelist || undefined, placeholderPattern: placeholderPattern == null ? undefined : placeholderPattern, preserveComments: preserveComments == null ? undefined : preserveComments, syntacticPlaceholders: syntacticPlaceholders == null ? undefined : syntacticPlaceholders, }; } export type PublicReplacements = { [x: string]: unknown } | Array; export type TemplateReplacements = { [x: string]: unknown } | void; export function normalizeReplacements( replacements: unknown, ): TemplateReplacements { if (Array.isArray(replacements)) { return replacements.reduce((acc, replacement, i) => { acc["$" + i] = replacement; return acc; }, {}); } else if (typeof replacements === "object" || replacements == null) { return (replacements as any) || undefined; } throw new Error( "Template replacements must be an array, object, null, or undefined", ); }