From 62e4e70d5b195cf95734465fe3f7a77c32e6115f Mon Sep 17 00:00:00 2001 From: Vasilii Kovalev Date: Thu, 29 Jul 2021 10:06:01 +0300 Subject: [PATCH] Version 5.0.2 (#31) ## Bug fixes * Fix incorrect type declarations ## Minor changes * Move source code to a single file to simplify maintaining and output * Remove unnecessary checks in `escapeRegExp` --- .prettierignore | 3 - README.md | 2 +- package.json | 10 ++-- postbuild.js | 3 - src/constants.ts | 11 ---- src/index.ts | 119 ++++++++++++++++++++++++++++++++++++-- src/tests/index.errors.ts | 3 +- src/tests/index.test.ts | 3 +- src/tests/index.types.ts | 3 +- src/types.ts | 84 --------------------------- src/utils.ts | 34 ----------- tsconfig.build.json | 11 +++- tsconfig.tslint.json | 2 +- tsconfig.types.json | 10 ---- 14 files changed, 134 insertions(+), 164 deletions(-) delete mode 100644 postbuild.js delete mode 100644 src/constants.ts delete mode 100644 src/types.ts delete mode 100644 src/utils.ts delete mode 100644 tsconfig.types.json diff --git a/.prettierignore b/.prettierignore index 699cc65..46f45ff 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,3 @@ -# Artifacts -dist - # Coverage directory coverage diff --git a/README.md b/README.md index efbbd96..7037dfc 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ A small, dependency-free and strongly typed template engine. [minzip-size-badge]: https://flat.badgen.net/bundlephobia/minzip/hydrate-text [size-link]: https://bundlephobia.com/package/hydrate-text [types-badge]: https://flat.badgen.net/npm/types/hydrate-text -[types-link]: https://github.com/vasilii-kovalev/hydrate-text/blob/main/src/types.ts +[types-link]: https://github.com/vasilii-kovalev/hydrate-text/blob/main/src/index.ts#L1-L75 [coverage-badge]: https://flat.badgen.net/coveralls/c/github/vasilii-kovalev/hydrate-text [coverage-link]: https://coveralls.io/github/vasilii-kovalev/hydrate-text [vulnerabilities-badge]: https://flat.badgen.net/snyk/vasilii-kovalev/hydrate-text diff --git a/package.json b/package.json index 2304acb..86573e7 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "hydrate-text", - "version": "5.0.1", + "version": "5.0.2", "description": "A small, dependency-free and strongly typed template engine.", "sideEffects": false, "type": "module", "main": "dist/index.js", - "types": "dist/types.d.ts", + "types": "dist/index.d.ts", "files": [ "dist" ], @@ -37,10 +37,8 @@ "prettier:fix": "prettier . --write", "lint": "npm-run-all tslint types eslint:check prettier:check", "test": "jest --coverage", - "build:js": "tsc --project tsconfig.build.json", - "build:types": "tsc --project tsconfig.types.json", - "build": "npm-run-all build:js build:types", - "postbuild": "node postbuild.js", + "build": "tsc --project tsconfig.build.json", + "postbuild": "prettier dist --write", "prepare": "npm-run-all build", "prepublishOnly": "npm-run-all lint test", "postversion": "git push && git push --tags" diff --git a/postbuild.js b/postbuild.js deleted file mode 100644 index 62fb5ba..0000000 --- a/postbuild.js +++ /dev/null @@ -1,3 +0,0 @@ -import fs from "fs"; - -fs.rmSync("./dist/types.js", { force: true }); diff --git a/src/constants.ts b/src/constants.ts deleted file mode 100644 index 5eaa4a5..0000000 --- a/src/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DefaultPrefix, DefaultSuffix, InterpolationOptions } from "./types"; - -const DEFAULT_INTERPOLATION_OPTIONS: InterpolationOptions< - DefaultPrefix, - DefaultSuffix -> = { - prefix: "{", - suffix: "}", -}; - -export { DEFAULT_INTERPOLATION_OPTIONS }; diff --git a/src/index.ts b/src/index.ts index adbe563..248d1cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,117 @@ -import { DEFAULT_INTERPOLATION_OPTIONS } from "./constants"; -import { ConfigureHydrateText, HydrateText } from "./types"; -import { escapeRegExp, isUndefined } from "./utils"; +type ValueType = string | boolean | number | bigint; + +type GetVariables< + Text extends string, + Prefix extends string, + Suffix extends string, +> = string extends Text + ? string + : Prefix extends "" + ? Suffix extends "" + ? // Prefix === "", Suffix === "" + Text extends `${infer Letter}${infer Rest}` + ? Letter | GetVariables + : never + : // Prefix === "", Suffix !== "" + Text extends `${infer Variable}${Suffix}${infer Rest}` + ? Variable | GetVariables + : never + : Suffix extends "" + ? // Prefix !== "", Suffix === "" + // eslint-disable-next-line @typescript-eslint/no-unused-vars + Text extends `${infer _Start}${Prefix}${infer Variable}` + ? Variable extends `${infer _Variable}${Prefix}${infer Rest}` + ? _Variable | GetVariables<`${Prefix}${Rest}`, Prefix, Suffix> + : Variable + : never + : // Prefix !== "", Suffix !== "" + // eslint-disable-next-line @typescript-eslint/no-unused-vars + Text extends `${infer _Start}${Prefix}${infer Variable}${Suffix}${infer Rest}` + ? Variable extends `${infer _Start}${Prefix}${infer _Variable}` + ? GetVariables< + `${_Start}${Prefix}${_Variable}${Suffix}${Rest}`, + Prefix, + Suffix + > + : Variable | GetVariables + : never; + +interface InterpolationOptions { + prefix: Prefix; + suffix: Suffix; +} + +type DefaultPrefix = "{"; + +type DefaultSuffix = "}"; + +interface HydrateText { + < + Text extends string, + Prefix extends string = DefaultPrefix, + Suffix extends string = DefaultSuffix, + >( + text: Text, + variables?: Record, ValueType>, + interpolationOptions?: InterpolationOptions, + ): string; +} + +interface ConfigureHydrateText { + < + _Prefix extends string = DefaultPrefix, + _Suffix extends string = DefaultSuffix, + >( + interpolationOptions: InterpolationOptions<_Prefix, _Suffix>, + ): < + Text extends string, + Prefix extends string = _Prefix, + Suffix extends string = _Suffix, + >( + text: Text, + variables?: Record, ValueType>, + interpolationOptions?: InterpolationOptions, + ) => string; +} + +const DEFAULT_INTERPOLATION_OPTIONS: InterpolationOptions< + DefaultPrefix, + DefaultSuffix +> = { + prefix: "{", + suffix: "}", +}; + +/* + Used to match `RegExp`. + Syntax characters: http://ecma-international.org/ecma-262/7.0/#sec-patterns. +*/ +const reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +const reHasRegExpChar = RegExp(reRegExpChar.source); + +/* + Source: https://github.com/lodash/lodash/blob/master/escapeRegExp.js + + Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", "?", + "(", ")", "[", "]", "{", "}", and "|" in `value`. +*/ +const escapeRegExp = (value: string): string => { + if (!value || !reHasRegExpChar.test(value)) { + return value; + } + + return value.replace(reRegExpChar, "\\$&"); +}; + +/* + Source: https://github.com/lodash/lodash/blob/master/isUndefined.js + + Checks if `value` is `undefined`. +*/ +const isUndefined = (value: unknown): value is undefined => { + return value === undefined; +}; const hydrateText: HydrateText = (text, variables, interpolationOptions) => { if (isUndefined(variables)) { @@ -48,4 +159,4 @@ export type { HydrateText, InterpolationOptions, ValueType, -} from "./types"; +}; diff --git a/src/tests/index.errors.ts b/src/tests/index.errors.ts index 7bc5776..839341b 100644 --- a/src/tests/index.errors.ts +++ b/src/tests/index.errors.ts @@ -1,5 +1,4 @@ -import { configureHydrateText, hydrateText } from ".."; -import { InterpolationOptions } from "../types"; +import { InterpolationOptions, configureHydrateText, hydrateText } from ".."; // Test Id: 538c85cdc1d3a5cf2ae0077f35e2637b // THROWS Expected 1-3 arguments, but got 0. diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts index ec8379d..73f6b55 100644 --- a/src/tests/index.test.ts +++ b/src/tests/index.test.ts @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ // import crypto from "crypto"; -import { configureHydrateText, hydrateText } from ".."; -import { InterpolationOptions } from "../types"; +import { InterpolationOptions, configureHydrateText, hydrateText } from ".."; // Inspired by: https://stackoverflow.com/a/11869589/11293963 // const getHash = (string: string) => diff --git a/src/tests/index.types.ts b/src/tests/index.types.ts index 4505b69..2fbe837 100644 --- a/src/tests/index.types.ts +++ b/src/tests/index.types.ts @@ -1,5 +1,4 @@ -import { configureHydrateText, hydrateText } from ".."; -import { InterpolationOptions } from "../types"; +import { InterpolationOptions, configureHydrateText, hydrateText } from ".."; // Test Id: e3d1bd7920d571fae01eb16c3b8343ba hydrateText(""); diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 0e0d57d..0000000 --- a/src/types.ts +++ /dev/null @@ -1,84 +0,0 @@ -type ValueType = string | boolean | number | bigint; - -type GetVariables< - Text extends string, - Prefix extends string, - Suffix extends string, -> = string extends Text - ? string - : Prefix extends "" - ? Suffix extends "" - ? // Prefix === "", Suffix === "" - Text extends `${infer Letter}${infer Rest}` - ? Letter | GetVariables - : never - : // Prefix === "", Suffix !== "" - Text extends `${infer Variable}${Suffix}${infer Rest}` - ? Variable | GetVariables - : never - : Suffix extends "" - ? // Prefix !== "", Suffix === "" - // eslint-disable-next-line @typescript-eslint/no-unused-vars - Text extends `${infer _Start}${Prefix}${infer Variable}` - ? Variable extends `${infer _Variable}${Prefix}${infer Rest}` - ? _Variable | GetVariables<`${Prefix}${Rest}`, Prefix, Suffix> - : Variable - : never - : // Prefix !== "", Suffix !== "" - // eslint-disable-next-line @typescript-eslint/no-unused-vars - Text extends `${infer _Start}${Prefix}${infer Variable}${Suffix}${infer Rest}` - ? Variable extends `${infer _Start}${Prefix}${infer _Variable}` - ? GetVariables< - `${_Start}${Prefix}${_Variable}${Suffix}${Rest}`, - Prefix, - Suffix - > - : Variable | GetVariables - : never; - -interface InterpolationOptions { - prefix: Prefix; - suffix: Suffix; -} - -type DefaultPrefix = "{"; - -type DefaultSuffix = "}"; - -interface HydrateText { - < - Text extends string, - Prefix extends string = DefaultPrefix, - Suffix extends string = DefaultSuffix, - >( - text: Text, - variables?: Record, ValueType>, - interpolationOptions?: InterpolationOptions, - ): string; -} - -interface ConfigureHydrateText { - < - _Prefix extends string = DefaultPrefix, - _Suffix extends string = DefaultSuffix, - >( - interpolationOptions: InterpolationOptions<_Prefix, _Suffix>, - ): < - Text extends string, - Prefix extends string = _Prefix, - Suffix extends string = _Suffix, - >( - text: Text, - variables?: Record, ValueType>, - interpolationOptions?: InterpolationOptions, - ) => string; -} - -export type { - ConfigureHydrateText, - DefaultPrefix, - DefaultSuffix, - HydrateText, - InterpolationOptions, - ValueType, -}; diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index a6ca40c..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - Used to match `RegExp`. - Syntax characters: http://ecma-international.org/ecma-262/7.0/#sec-patterns. -*/ -const reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -const reHasRegExpChar = RegExp(reRegExpChar.source); - -/* - Source: https://github.com/lodash/lodash/blob/master/escapeRegExp.js - - Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", "?", - "(", ")", "[", "]", "{", "}", and "|" in `value`. -*/ -const escapeRegExp = (value?: string): string => { - const string = String(value ?? ""); - - if (!string || !reHasRegExpChar.test(string)) { - return string; - } - - return string.replace(reRegExpChar, "\\$&"); -}; - -/* - Source: https://github.com/lodash/lodash/blob/master/isUndefined.js - - Checks if `value` is `undefined`. -*/ -const isUndefined = (value: unknown): value is undefined => { - return value === undefined; -}; - -export { escapeRegExp, isUndefined }; diff --git a/tsconfig.build.json b/tsconfig.build.json index dfd2a06..59edcd0 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,8 +1,17 @@ { "extends": "./tsconfig.json", "compilerOptions": { + "declaration": true, + "declarationDir": "./dist", "noEmit": false, "outDir": "./dist" }, - "exclude": ["**/tests/*.ts", "**/types.ts"] + "exclude": [ + "**/tests/*", + /* + Fixes error TS5055 ("Cannot write file '.../dist/index.d.ts' because + it would overwrite input file"). + */ + "dist/*" + ] } diff --git a/tsconfig.tslint.json b/tsconfig.tslint.json index 5c01623..2757cb5 100644 --- a/tsconfig.tslint.json +++ b/tsconfig.tslint.json @@ -1,4 +1,4 @@ { "extends": "./tsconfig.json", - "exclude": ["src/tests/index.errors.ts"] + "exclude": ["**/*.errors.ts"] } diff --git a/tsconfig.types.json b/tsconfig.types.json deleted file mode 100644 index 09425cc..0000000 --- a/tsconfig.types.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.build.json", - "compilerOptions": { - "declaration": true, - "declarationDir": "./dist", - "emitDeclarationOnly": true - }, - "exclude": [], - "include": ["src/types.ts"] -}