154 lines
4.3 KiB
TypeScript
154 lines
4.3 KiB
TypeScript
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<string>;
|
|
/**
|
|
* 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<string>;
|
|
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<unknown>;
|
|
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",
|
|
);
|
|
}
|