@terrazzo/parser
Version:
Parser/validator for the Design Tokens Community Group (DTCG) standard.
265 lines • 8.67 kB
TypeScript
import type { AnyNode, DocumentNode } from '@humanwhocodes/momoa';
import type { TokenNormalized } from '@terrazzo/token-tools';
import type Logger from './logger.js';
export interface BuildHookOptions {
/** Map of tokens */
tokens: Record<string, TokenNormalized>;
/** Query transformed values */
getTransforms(params: TransformParams): TokenTransformed[];
/** Momoa documents */
sources: InputSource[];
outputFile: (
/** Filename to output (relative to outDir) */
filename: string,
/** Contents to write to file */
contents: string | Buffer) => void;
}
export interface BuildRunnerResult {
outputFiles: OutputFile[];
}
export interface BuildEndHookOptions {
/** Map of tokens */
tokens: Record<string, TokenNormalized>;
/** Query transformed values */
getTransforms(params: TransformParams): TokenTransformed[];
/** Momoa documents */
sources: InputSource[];
/** Final files to be written */
outputFiles: OutputFileExpanded[];
}
export interface Config {
/**
* Path to tokens.json
* @default "./tokens.json"
*/
tokens?: string | string[];
/**
* Output directory
* @default "./tokens/"
*/
outDir?: string;
/** Specify plugins */
plugins?: Plugin[];
/** Specify linting settings */
lint?: {
/** Configure build behavior */
build?: {
/**
* Should linters run with `tz build`?
* @default true
*/
enabled?: boolean;
};
/** Configure lint rules */
rules?: Record<string, LintRuleShorthand | LintRuleLonghand>;
};
/** Ignore token groups */
ignore?: {
/** Token patterns to ignore. Accepts globs. */
tokens?: string[];
/** Ignore deprecated tokens */
deprecated?: boolean;
};
}
export interface ConfigInit {
tokens: URL[];
outDir: URL;
plugins: Plugin[];
lint: {
build: NonNullable<NonNullable<Config['lint']>['build']>;
rules: Record<string, LintRuleLonghand>;
};
ignore: {
tokens: NonNullable<NonNullable<Config['ignore']>['tokens']>;
deprecated: NonNullable<NonNullable<Config['ignore']>['deprecated']>;
};
}
export interface ConfigOptions {
logger?: Logger;
/** @terrazzo/parser needs cwd so this can be run without Node.js. Importing defineConfig from @terrazzo/cli doesn’t need this. */
cwd: URL;
}
export interface InputSource {
filename?: URL;
src: any;
document: DocumentNode;
}
export interface LintNotice {
/** Lint message shown to the user */
message: string;
/** Erring node (used to point to a specific line) */
node?: AnyNode;
}
export type LintRuleSeverity = 'error' | 'warn' | 'off';
export type LintRuleShorthand = LintRuleSeverity | 0 | 1 | 2;
export type LintRuleLonghand = [LintRuleSeverity | 0 | 1 | 2, any];
export interface LintRuleNormalized<O = any> {
id: string;
severity: LintRuleSeverity;
options?: O;
}
export type LintReportDescriptor<MessageIds extends string> = {
/** To error on a specific token source file, provide an erring node */
node?: AnyNode;
/** To error on a specific token source file, also provide the source */
source?: InputSource;
/** Provide data for messages */
data?: Record<string, unknown>;
} & ({
/** Provide the error message to display */
message: string;
messageId?: never;
} | {
message?: never;
/** Provide the error message ID */
messageId: MessageIds;
});
export interface LintRule<MessageIds extends string, LintRuleOptions extends object | undefined = undefined, LintRuleDocs = unknown> {
meta?: LintRuleMetaData<MessageIds, LintRuleOptions, LintRuleDocs>;
/**
* Function which returns an object with methods that ESLint calls to “visit”
* nodes while traversing the abstract syntax tree.
*/
create(context: Readonly<LintRuleContext<MessageIds, LintRuleOptions>>): void | Promise<void>;
/**
* Default options the rule will be run with
*/
defaultOptions: LintRuleOptions;
}
export interface LintRuleContext<MessageIds extends string, LintRuleOptions extends object | undefined = undefined> {
/** The rule ID. */
id: string;
/**
* An array of the configured options for this rule. This array does not
* include the rule severity.
*/
options: LintRuleOptions;
/** The current working directory. */
cwd?: URL;
/** Source file the token came from. */
src: string;
/** Source file location. */
filename?: URL;
/** ID:Token map of all tokens. */
tokens: Record<string, TokenNormalized>;
/** Reports a problem in the code. */
report(descriptor: LintReportDescriptor<MessageIds>): void;
}
export interface LintRuleMetaData<MessageIds extends string, LintRuleOptions extends object | undefined = undefined, LintRuleDocs = unknown> {
/**
* Documentation for the rule
*/
docs?: LintRuleDocs & LintRuleMetaDataDocs;
/**
* A map of messages which the rule can report. The key is the messageId, and
* the string is the parameterised error string.
*/
messages?: Record<MessageIds, string>;
/**
* Specifies default options for the rule. If present, any user-provided
* options in their config will be merged on top of them recursively. This
* merging will be applied directly to `context.options`.
*/
defaultOptions?: LintRuleOptions;
}
export interface LintRuleMetaDataDocs {
/** Concise description of the rule. */
description: string;
/** The URL of the rule's docs. */
url?: string;
}
export interface OutputFile {
/** Filename, relative to outDir */
filename: string;
/** File contents */
contents: string | Buffer;
/** Plugin name that generated the file */
plugin?: string;
/** Time taken to generate file */
time?: number;
}
export interface OutputFileExpanded extends OutputFile {
/** The `name` of the plugin that produced this file. */
plugin: string;
/** How long this output took to make. */
time: number;
}
export interface Plugin {
name: string;
/** Read config, and optionally modify */
config?(config: ConfigInit): void | ConfigInit | undefined;
/**
* Declare:
* - `"pre"`: run this plugin BEFORE all others
* - `"post"`: run this plugin AFTER all others
* - (default) run this plugin in default order (array order)
*/
enforce?: 'pre' | 'post';
/** Throw lint errors/warnings */
lint?(): Record<string, LintRule<any, any, any>>;
transform?(options: TransformHookOptions): Promise<void>;
build?(options: BuildHookOptions): Promise<void>;
buildEnd?(result: BuildRunnerResult): Promise<void>;
}
/** Transformed token with a single value. Note that this may be any type! */
export interface TokenTransformedSingleValue {
/** Original Token ID */
id: string;
/** ID unique to this format. */
localID?: string;
type: 'SINGLE_VALUE';
value: string;
/**
* The mode of this value
* @default "."
*/
mode: string;
/** The original token. */
token: TokenNormalized;
}
/** Transformed token with multiple values. Note that this may be any type! */
export interface TokenTransformedMultiValue {
/** Original Token ID */
id: string;
/** ID unique to this format.*/
localID?: string;
type: 'MULTI_VALUE';
value: Record<string, string>;
/**
* The mode of this value
* @default "."
*/
mode: string;
/** The original token */
token: TokenNormalized;
}
export type TokenTransformed = TokenTransformedSingleValue | TokenTransformedMultiValue;
export interface TransformParams {
/** ID of an existing format */
format: string;
/** Glob of tokens to select (e.g. `"color.*"` to select all tokens starting with `"color."`) */
id?: string | string[];
/** $type(s) to filter for */
$type?: string | string[];
/**
* Mode name, if selecting a mode
* @default "."
*/
mode?: string | string[];
}
export interface TransformHookOptions {
/** Map of tokens */
tokens: Record<string, TokenNormalized>;
/** Query transformed values */
getTransforms(params: TransformParams): TokenTransformed[];
/** Update transformed values */
setTransform(id: string, params: {
format: string;
localID?: string;
value: string | Record<string, string>;
mode?: string;
}): void;
/** Momoa documents */
sources: InputSource[];
}
//# sourceMappingURL=types.d.ts.map