@stylable/core
Version:
CSS for Components
128 lines (123 loc) • 4.83 kB
text/typescript
import { FileProcessor, MinimalFS } from './cached-process-file';
import { createInfrastructure } from './create-infra-structure';
import { Diagnostics } from './diagnostics';
import { safeParse } from './parser';
import { processNamespace, StylableMeta, StylableProcessor } from './stylable-processor';
import { StylableResolver } from './stylable-resolver';
import {
StylableResults,
StylableTransformer,
TransformerOptions,
TransformHooks,
} from './stylable-transformer';
import { TimedCacheOptions } from './timed-cache';
import { IStylableOptimizer, ModuleResolver } from './types';
export interface StylableConfig {
projectRoot: string;
fileSystem: MinimalFS;
requireModule?: (path: string) => any;
delimiter?: string;
onProcess?: (meta: StylableMeta, path: string) => StylableMeta;
diagnostics?: Diagnostics;
hooks?: TransformHooks;
resolveOptions?: {
alias: any;
symlinks: boolean;
[key: string]: any;
};
optimizer?: IStylableOptimizer;
mode?: 'production' | 'development';
resolveNamespace?: typeof processNamespace;
timedCacheOptions?: Omit<TimedCacheOptions, 'createKey'>;
resolveModule?: ModuleResolver;
}
export class Stylable {
public static create(config: StylableConfig) {
return new this(
config.projectRoot,
config.fileSystem,
(id) => {
if (config.requireModule) {
return config.requireModule(id);
}
throw new Error('Javascript files are not supported without requireModule options');
},
config.delimiter,
config.onProcess,
config.diagnostics,
config.hooks,
config.resolveOptions,
config.optimizer,
config.mode,
config.resolveNamespace,
config.timedCacheOptions,
config.resolveModule
);
}
public fileProcessor: FileProcessor<StylableMeta>;
public resolver: StylableResolver;
public resolvePath: (ctx: string | undefined, path: string) => string;
constructor(
public projectRoot: string,
protected fileSystem: MinimalFS,
protected requireModule: (path: string) => any,
public delimiter: string = '__',
protected onProcess?: (meta: StylableMeta, path: string) => StylableMeta,
protected diagnostics = new Diagnostics(),
protected hooks: TransformHooks = {},
protected resolveOptions: any = {},
public optimizer?: IStylableOptimizer,
protected mode: 'production' | 'development' = 'production',
protected resolveNamespace?: typeof processNamespace,
protected timedCacheOptions: Omit<TimedCacheOptions, 'createKey'> = {
timeout: 1,
useTimer: true,
},
protected resolveModule?: ModuleResolver
) {
const { fileProcessor, resolvePath } = createInfrastructure(
projectRoot,
fileSystem,
onProcess,
resolveOptions,
this.resolveNamespace,
timedCacheOptions,
resolveModule
);
this.resolvePath = resolvePath;
this.fileProcessor = fileProcessor;
this.resolver = new StylableResolver(this.fileProcessor, this.requireModule);
}
public createTransformer(options: Partial<TransformerOptions> = {}) {
return new StylableTransformer({
delimiter: this.delimiter,
diagnostics: new Diagnostics(),
fileProcessor: this.fileProcessor,
requireModule: this.requireModule,
postProcessor: this.hooks.postProcessor,
replaceValueHook: this.hooks.replaceValueHook,
mode: this.mode,
...options,
});
}
public transform(meta: StylableMeta): StylableResults;
public transform(source: string, resourcePath: string): StylableResults;
public transform(
meta: string | StylableMeta,
resourcePath?: string,
options: Partial<TransformerOptions> = {}
): StylableResults {
if (typeof meta === 'string') {
// TODO: refactor to use fileProcessor
// meta = this.fileProcessor.processContent(meta, resourcePath + '');
const root = safeParse(meta, { from: resourcePath });
meta = new StylableProcessor(undefined, this.resolveNamespace).process(root);
}
const transformer = this.createTransformer(options);
this.fileProcessor.add(meta.source, meta);
return transformer.transform(meta);
}
public process(fullpath: string, context?: string, ignoreCache?: boolean): StylableMeta {
return this.fileProcessor.process(fullpath, ignoreCache, context);
}
}