diff --git a/compiler.d.ts b/compiler.d.ts new file mode 100644 index 0000000..59dfdb7 --- /dev/null +++ b/compiler.d.ts @@ -0,0 +1,50 @@ +import {RawSourceMap} from 'source-map' + +export type CompilerOptions = { + template?: string + file?: string + scopedCss?: boolean +} + +export type CompilerOutput = { + code: string + map: RawSourceMap +} + +export type CompilerOutputFragments = { + template: object + css: object + javascript: object +} + +export type PreProcessorOutput = { + code: string, + map?: RawSourceMap +} + +export type PreProcessorMeta = { + tagName: string, + fragments: CompilerOutputFragments, + options: CompilerOptions, + source: string +} + +export type ProcessorFunction = (code: string, meta: PreProcessorMeta) => PreProcessorOutput + +export type PreprocessorsMap = { + template: Map + javascript: Map + css: Map +} + +export type PostProcessorsMap = Map +export type PreProcessorType = 'template' | 'javascript' | 'css' + +// public API +export function compile(source: string, options?: CompilerOptions): CompilerOutput +export function registerPreprocessor( + type: PreProcessorType, + name: string, + fn: ProcessorFunction +): PreprocessorsMap +export function registerPostprocessor( fn: ProcessorFunction): PostProcessorsMap diff --git a/package-lock.json b/package-lock.json index e3509cd..5d9fc59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6393,6 +6393,12 @@ "integrity": "sha1-m7i6DoQfs/TPH+fCRenz+opf6Zw=", "dev": true }, + "typescript": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz", + "integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index 5d42ae4..c2c9619 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,11 @@ "main": "dist/index.js", "module": "dist/index.esm.js", "jsnext:main": "dist/index.esm.js", + "types": "./compiler.d.ts", "files": [ "dist", - "src" + "src", + "compiler.d.ts" ], "scripts": { "lint": "eslint src/ test/ build/", @@ -15,7 +17,8 @@ "cov-html": "nyc report --reporter=html", "build": "rollup -c build/rollup.node.config.js && rollup -c build/rollup.browser.config.js", "postest": "npm run cov-html", - "test": "npm run lint && nyc mocha -r esm test/*.spec.js test/**/*.spec.js", + "test-types": "tsc -p test", + "test": "npm run lint && nyc mocha -r esm test/*.spec.js test/**/*.spec.js && npm run test-types", "debug": "mocha --inspect --inspect-brk -r esm test/*.spec.js test/**/*.spec.js", "prepublishOnly": "npm run build && npm run test" }, @@ -50,7 +53,8 @@ "rollup-plugin-alias": "^2.2.0", "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-node-builtins": "^2.1.2", - "shelljs": "^0.8.4" + "shelljs": "^0.8.4", + "typescript": "^4.1.5" }, "author": "Gianluca Guarini (http://gianlucaguarini.com)", "license": "MIT", diff --git a/test/sourcemap.spec.js b/test/sourcemap.spec.js index 54f9320..f029b63 100644 --- a/test/sourcemap.spec.js +++ b/test/sourcemap.spec.js @@ -15,7 +15,7 @@ function getSourceByOutputPositions(source, positions) { }, '') } -function getGeneatedPositions(sourcemapConsumer, source, positions) { +function getGeneratedPositions(sourcemapConsumer, source, positions) { return positions.map(position => sourcemapConsumer.generatedPositionFor({...position, source})) } @@ -68,7 +68,7 @@ describe('Sourcemap specs', () => { // const expect(getSourceByPosition(source, 19, 4, 8)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-component.riot', [ {line: 19, column: 4}, {line: 19, column: 5}, {line: 19, column: 6}, @@ -82,7 +82,7 @@ describe('Sourcemap specs', () => { // value expect(getSourceByPosition(source, 5, 58, 62)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-component.riot', [ {line: 5, column: 58}, {line: 5, column: 59}, {line: 5, column: 60}, @@ -95,7 +95,7 @@ describe('Sourcemap specs', () => { // bar expect(getSourceByPosition(source, 13, 34, 36)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-component.riot', [ {line: 13, column: 34}, {line: 13, column: 35}, {line: 13, column: 36} @@ -107,7 +107,7 @@ describe('Sourcemap specs', () => { expect(getSourceByPosition(source, 9, 9, 11)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-component.riot', [ {line: 10, column: 9}, {line: 10, column: 10}, {line: 10, column: 11} @@ -134,7 +134,7 @@ describe('Sourcemap specs', () => { // const expect(getSourceByPosition(source, 19, 4, 8)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-babel-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-babel-component.riot', [ {line: 19, column: 4}, {line: 19, column: 5}, {line: 19, column: 6}, @@ -148,7 +148,7 @@ describe('Sourcemap specs', () => { // value expect(getSourceByPosition(source, 5, 58, 62)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-babel-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-babel-component.riot', [ {line: 5, column: 58}, {line: 5, column: 59}, {line: 5, column: 60}, @@ -161,7 +161,7 @@ describe('Sourcemap specs', () => { // bar expect(getSourceByPosition(source, 13, 34, 36)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-babel-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-babel-component.riot', [ {line: 13, column: 34}, {line: 13, column: 35}, {line: 13, column: 36} @@ -173,7 +173,7 @@ describe('Sourcemap specs', () => { expect(getSourceByPosition(source, 9, 9, 11)).to.be.equal( getSourceByOutputPositions(output, - getGeneatedPositions(sourcemapConsumer, 'my-babel-component.riot', [ + getGeneratedPositions(sourcemapConsumer, 'my-babel-component.riot', [ {line: 10, column: 9}, {line: 10, column: 10}, {line: 10, column: 11} @@ -185,4 +185,4 @@ describe('Sourcemap specs', () => { unregister('javascript', 'babel') }) -}) \ No newline at end of file +}) diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..6b16054 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,66 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "files": [ + "typing.spec.ts" + ] +} diff --git a/test/typing.spec.ts b/test/typing.spec.ts new file mode 100644 index 0000000..4f33754 --- /dev/null +++ b/test/typing.spec.ts @@ -0,0 +1,24 @@ +import {compile, registerPostprocessor, registerPreprocessor} from '../compiler' + + +// compile without options +compile('

hello

') + +// compile with options +compile('

hello

', { + file: 'test-file.riot', + scopedCss: true +}) + + +registerPostprocessor(function (code) { + return { + code: code.toUpperCase() + } +}) + +registerPreprocessor('javascript', 'upper', function (code) { + return { + code: code.toUpperCase() + } +})