From 1804b8de5565c791264388c3aa4d77cf45b393c0 Mon Sep 17 00:00:00 2001 From: Jakob Linskeseder Date: Tue, 4 Jan 2022 01:41:42 +0100 Subject: [PATCH] Use automatically generated types Fixes #1767 --- lib/handlebars.runtime.js | 2 +- package.json | 3 +- types/index.d.ts | 343 +++++++++----------------------------- types/index.ts | 125 ++++++++++++++ types/test.ts | 7 +- 5 files changed, 208 insertions(+), 272 deletions(-) create mode 100644 types/index.ts diff --git a/lib/handlebars.runtime.js b/lib/handlebars.runtime.js index 6b6270b2f..33686eba8 100644 --- a/lib/handlebars.runtime.js +++ b/lib/handlebars.runtime.js @@ -2,7 +2,7 @@ import { Exception } from '@handlebars/parser'; import * as base from './handlebars/base'; // Each of these augment the Handlebars object. No need to setup here. -// (This is done to easily share code between commonjs and browse envs) +// (This is done to easily share code between commonjs and browser envs) import SafeString from './handlebars/safe-string'; import * as Utils from './handlebars/utils'; import * as runtime from './handlebars/runtime'; diff --git a/package.json b/package.json index abba4f034..7fddd7e5c 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "prettier": "^1.19.1", "semver": "^5.0.1", "sinon": "^7.5.0", - "typescript": "^3.4.3", + "typescript": "^3.9.10", "uglify-js": "^3.1.4", "underscore": "^1.5.1", "webpack": "^1.12.6", @@ -83,6 +83,7 @@ }, "scripts": { "build": "grunt build", + "build:types": "tsc types/index.ts --declaration --emitDeclarationOnly --outDir types", "format": "prettier --write '**/*.js' && eslint --fix .", "lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types", "lint:eslint": "eslint --max-warnings 0 .", diff --git a/types/index.d.ts b/types/index.d.ts index 4275c50f4..fcd45838f 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,275 +1,86 @@ -/* These definitions were imported from https://github.com/DefinitelyTyped/DefinitelyTyped - * and includes previous contributions from the DefinitelyTyped community by: - * - Albert Willemsen - * - Boris Yankov - * - Jessica Franco - * - Masahiro Wakame - * - Raanan Weber - * - Sergei Dorogin - * - webbiesdk - * - Andrew Leedham - * - Nils Knappmeier - * For full history prior to their migration to handlebars.js, please see: - * https://github.com/DefinitelyTyped/DefinitelyTyped/commits/1ce60bdc07f10e0b076778c6c953271c072bc894/types/handlebars/index.d.ts - */ -// TypeScript Version: 2.3 -import { - parse, - parseWithoutProcessing, - ParseOptions, - AST -} from '@handlebars/parser'; - -declare namespace Handlebars { - export interface TemplateDelegate { - (context: T, options?: RuntimeOptions): string; - } - - export type Template = TemplateDelegate|string; - - export interface RuntimeOptions { - partial?: boolean; - depths?: any[]; - helpers?: { [name: string]: Function }; - partials?: { [name: string]: HandlebarsTemplateDelegate }; - decorators?: { [name: string]: Function }; - data?: any; - blockParams?: any[]; - allowCallsToHelperMissing?: boolean; - allowedProtoProperties?: { [name: string]: boolean }; - allowedProtoMethods?: { [name: string]: boolean }; - allowProtoPropertiesByDefault?: boolean; - allowProtoMethodsByDefault?: boolean; - } - - export interface HelperOptions { - fn: TemplateDelegate; - inverse: TemplateDelegate; - hash: any; - data?: any; - } - - export interface HelperDelegate { - (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; - } - export interface HelperDeclareSpec { - [key: string]: HelperDelegate; - } - - export { parse, parseWithoutProcessing, ParseOptions }; - - export function registerHelper(name: string, fn: HelperDelegate): void; - export function registerHelper(name: HelperDeclareSpec): void; - export function unregisterHelper(name: string): void; - - export function registerPartial(name: string, fn: Template): void; - export function registerPartial(spec: { [name: string]: HandlebarsTemplateDelegate }): void; - export function unregisterPartial(name: string): void; - - // TODO: replace Function with actual signature - export function registerDecorator(name: string, fn: Function): void; - export function unregisterDecorator(name: string): void; - - export function K(): void; - export function createFrame(object: any): any; - export function blockParams(obj: any[], ids: any[]): any[]; - export function log(level: number, obj: any): void; - - export function compile(input: any, options?: CompileOptions): HandlebarsTemplateDelegate; - export function precompile(input: any, options?: PrecompileOptions): TemplateSpecification; - export function template(precompilation: TemplateSpecification): HandlebarsTemplateDelegate; - - export function create(): typeof Handlebars; - - export const escapeExpression: typeof Utils.escapeExpression; - //export const Utils: typeof hbs.Utils; - export const logger: Logger; - export const templates: HandlebarsTemplates; - export const helpers: { [name: string]: HelperDelegate }; - export const partials: { [name: string]: any }; - // TODO: replace Function with actual signature - export const decorators: { [name: string]: Function }; - - export const VERSION: string; - - export function noConflict(): typeof Handlebars; - - export class Exception { - constructor(message: string, node?: hbs.AST.Node); - description: string; - fileName: string; - lineNumber?: any; - endLineNumber?: any; - message: string; - name: string; - number: number; - stack?: string; - column?: any; - endColumn?: any; - } - - export class SafeString { - constructor(str: string); - toString(): string; - toHTML(): string; - } - - export namespace Utils { - export function escapeExpression(str: string): string; - export function createFrame(object: any): any; - export function blockParams(obj: any[], ids: any[]): any[]; - export function isEmpty(obj: any) : boolean; - export function extend(obj: any, ...source: any[]): any; - export function toString(obj: any): string; - export function isArray(obj: any): boolean; - export function isFunction(obj: any): boolean; - } - - export namespace AST { - export const helpers: hbs.AST.helpers; - } - - export interface ICompiler { - accept(node: hbs.AST.Node): void; - Program(program: hbs.AST.Program): void; - BlockStatement(block: hbs.AST.BlockStatement): void; - PartialStatement(partial: hbs.AST.PartialStatement): void; - PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; - DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; - Decorator(decorator: hbs.AST.Decorator): void; - MustacheStatement(mustache: hbs.AST.MustacheStatement): void; - ContentStatement(content: hbs.AST.ContentStatement): void; - CommentStatement(comment?: hbs.AST.CommentStatement): void; - SubExpression(sexpr: hbs.AST.SubExpression): void; - PathExpression(path: hbs.AST.PathExpression): void; - StringLiteral(str: hbs.AST.StringLiteral): void; - NumberLiteral(num: hbs.AST.NumberLiteral): void; - BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; - UndefinedLiteral(): void; - NullLiteral(): void; - Hash(hash: hbs.AST.Hash): void; - } - - export class Visitor implements ICompiler { - accept(node: hbs.AST.Node): void; - acceptKey(node: hbs.AST.Node, name: string): void; - acceptArray(arr: hbs.AST.Expression[]): void; - Program(program: hbs.AST.Program): void; - BlockStatement(block: hbs.AST.BlockStatement): void; - PartialStatement(partial: hbs.AST.PartialStatement): void; - PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; - DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; - Decorator(decorator: hbs.AST.Decorator): void; - MustacheStatement(mustache: hbs.AST.MustacheStatement): void; - ContentStatement(content: hbs.AST.ContentStatement): void; - CommentStatement(comment?: hbs.AST.CommentStatement): void; - SubExpression(sexpr: hbs.AST.SubExpression): void; - PathExpression(path: hbs.AST.PathExpression): void; - StringLiteral(str: hbs.AST.StringLiteral): void; - NumberLiteral(num: hbs.AST.NumberLiteral): void; - BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; - UndefinedLiteral(): void; - NullLiteral(): void; - Hash(hash: hbs.AST.Hash): void; - } - - - export interface ResolvePartialOptions { - name: string; - helpers?: { [name: string]: Function }; - partials?: { [name: string]: HandlebarsTemplateDelegate }; - decorators?: { [name: string]: Function }; - data?: any; - } - - export namespace VM { - /** - * @deprecated - */ - export function resolvePartial(partial: HandlebarsTemplateDelegate | undefined, context: any, options: ResolvePartialOptions): HandlebarsTemplateDelegate; - } +import { ParseOptions, AST } from '@handlebars/parser'; +declare type BuiltinHelperName = "helperMissing" | "blockHelperMissing" | "each" | "if" | "unless" | "with" | "log" | "lookup"; +declare type KnownHelpers = { + [name in BuiltinHelperName | string]: boolean; +}; +declare type Template = TemplateDelegate | string; +interface CompileOptions { + data?: boolean; + compat?: boolean; + knownHelpers?: KnownHelpers; + knownHelpersOnly?: boolean; + noEscape?: boolean; + strict?: boolean; + assumeObjects?: boolean; + preventIndent?: boolean; + ignoreStandalone?: boolean; + explicitPartialContext?: boolean; +} +interface PrecompileOptions extends CompileOptions { + srcName?: string; + destName?: string; } - -/** -* Implement this interface on your MVW/MVVM/MVC views such as Backbone.View -**/ -export interface HandlebarsTemplatable { - template: HandlebarsTemplateDelegate; +interface RuntimeOptions { + partial?: boolean; + depths?: any[]; + helpers?: { + [name: string]: Function; + }; + partials?: { + [name: string]: TemplateDelegate; + }; + decorators?: { + [name: string]: Function; + }; + data?: any; + blockParams?: any[]; + allowCallsToHelperMissing?: boolean; + allowedProtoProperties?: { + [name: string]: boolean; + }; + allowedProtoMethods?: { + [name: string]: boolean; + }; + allowProtoPropertiesByDefault?: boolean; + allowProtoMethodsByDefault?: boolean; } - -// NOTE: for backward compatibility of this typing -export type HandlebarsTemplateDelegate = Handlebars.TemplateDelegate; - -export interface HandlebarsTemplates { - [index: string]: HandlebarsTemplateDelegate; +interface TemplateSpecification { } - -export interface TemplateSpecification { - +export interface TemplateDelegate { + (context: T, options?: RuntimeOptions): string; } - -// for backward compatibility of this typing -export type RuntimeOptions = Handlebars.RuntimeOptions; - -export interface CompileOptions { - data?: boolean; - compat?: boolean; - knownHelpers?: KnownHelpers; - knownHelpersOnly?: boolean; - noEscape?: boolean; - strict?: boolean; - assumeObjects?: boolean; - preventIndent?: boolean; - ignoreStandalone?: boolean; - explicitPartialContext?: boolean; +interface HelperOptions { + fn: TemplateDelegate; + inverse: TemplateDelegate; + hash: any; + data?: any; } - -export type KnownHelpers = { - [name in BuiltinHelperName | CustomHelperName]: boolean; -}; - -export type BuiltinHelperName = - "helperMissing"| - "blockHelperMissing"| - "each"| - "if"| - "unless"| - "with"| - "log"| - "lookup"; - -export type CustomHelperName = string; - -export interface PrecompileOptions extends CompileOptions { - srcName?: string; - destName?: string; +interface HelperDelegate { + (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; } - -export namespace hbs { - // for backward compatibility of this typing - export type SafeString = Handlebars.SafeString; - - export type Utils = typeof Handlebars.Utils; - - export { AST } +interface HelperDeclareSpec { + [key: string]: HelperDelegate; } - -export interface Logger { - DEBUG: number; - INFO: number; - WARN: number; - ERROR: number; - level: number; - - methodMap: { [level: number]: string }; - - log(level: number, obj: string): void; +interface SafeString { + new (str: string): void; + toString(): string; + toHTML(): string; } - -export type CompilerInfo = [number/* revision */, string /* versions */]; - -declare module "handlebars/runtime" { - export = Handlebars; +declare class Handlebars { + readonly VERSION: string; + SafeString: SafeString; + constructor(); + compile(input: any, options?: CompileOptions): TemplateDelegate; + precompile(input: any, options?: PrecompileOptions): TemplateSpecification; + parse(input: string, options?: ParseOptions): AST.Program; + parseWithoutProcessing(input: string, options?: ParseOptions): AST.Program; + registerHelper(name: HelperDeclareSpec | string, fn?: HelperDelegate): void; + unregisterHelper(name: string): void; + registerPartial(name: string, fn: Template): void; + registerPartial(spec: { + [name: string]: TemplateDelegate; + }): void; + unregisterPartial(name: string): void; } - -export default Handlebars; +declare const _default: Handlebars; +export default _default; diff --git a/types/index.ts b/types/index.ts new file mode 100644 index 000000000..8e167cee9 --- /dev/null +++ b/types/index.ts @@ -0,0 +1,125 @@ +import { + parse, + parseWithoutProcessing, + ParseOptions, + AST +} from '@handlebars/parser'; + +type BuiltinHelperName = + "helperMissing"| + "blockHelperMissing"| + "each"| + "if"| + "unless"| + "with"| + "log"| + "lookup"; + +type KnownHelpers = { + [name in BuiltinHelperName | string]: boolean; +}; + +type Template = TemplateDelegate|string; + +interface CompileOptions { + data?: boolean; + compat?: boolean; + knownHelpers?: KnownHelpers; + knownHelpersOnly?: boolean; + noEscape?: boolean; + strict?: boolean; + assumeObjects?: boolean; + preventIndent?: boolean; + ignoreStandalone?: boolean; + explicitPartialContext?: boolean; +} + +interface PrecompileOptions extends CompileOptions { + srcName?: string; + destName?: string; +} + +interface RuntimeOptions { + partial?: boolean; + depths?: any[]; + helpers?: { [name: string]: Function }; + partials?: { [name: string]: TemplateDelegate }; + decorators?: { [name: string]: Function }; + data?: any; + blockParams?: any[]; + allowCallsToHelperMissing?: boolean; + allowedProtoProperties?: { [name: string]: boolean }; + allowedProtoMethods?: { [name: string]: boolean }; + allowProtoPropertiesByDefault?: boolean; + allowProtoMethodsByDefault?: boolean; +} + +interface HandlebarsTemplates { + [index: string]: string; +} + +interface TemplateSpecification { + +} + +export interface TemplateDelegate { + (context: T, options?: RuntimeOptions): string; +} + +interface HelperOptions { + fn: TemplateDelegate; + inverse: TemplateDelegate; + hash: any; + data?: any; +} + +interface HelperDelegate { + (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; +} + +interface HelperDeclareSpec { + [key: string]: HelperDelegate; +} + +class TemplateSpecificationInstance implements TemplateSpecification {} + +interface SafeString { + new(str: string): void; + toString(): string; + toHTML(): string; +} + +class Handlebars { + public readonly VERSION: string; + public SafeString: SafeString; + constructor() { + } + compile(input: any, options?: CompileOptions): TemplateDelegate { + return (context) => ''; + } + precompile(input: any, options?: PrecompileOptions): TemplateSpecification { + return new TemplateSpecificationInstance(); + } + parse(input: string, options?: ParseOptions): AST.Program { + return parse(input, options); + } + parseWithoutProcessing(input: string, options?: ParseOptions): AST.Program { + return parseWithoutProcessing(input, options); + } + registerHelper(name: HelperDeclareSpec|string, fn?: HelperDelegate): void { + + } + unregisterHelper(name: string): void { + + } + registerPartial(name: string, fn: Template): void; + registerPartial(spec: { [name: string]: TemplateDelegate }): void; + registerPartial(name: string|{ [name: string]: TemplateDelegate }, fn?: Template): void { + + } + unregisterPartial(name: string): void { + + } +} + +export default new Handlebars(); \ No newline at end of file diff --git a/types/test.ts b/types/test.ts index 2010b89f8..3479b788b 100644 --- a/types/test.ts +++ b/types/test.ts @@ -4,8 +4,7 @@ * https://github.com/DefinitelyTyped/DefinitelyTyped/commits/1ce60bdc07f10e0b076778c6c953271c072bc894/types/handlebars/handlebars-tests.ts */ -import Handlebars from 'handlebars'; -import { HandlebarsTemplateDelegate, hbs } from 'handlebars'; +import Handlebars, { TemplateDelegate } from 'handlebars'; const context = { author: { firstName: 'Alan', lastName: 'Johnson' }, @@ -37,7 +36,7 @@ Handlebars.registerHelper('link_to', (context: typeof post) => { const post = { url: "/hello-world", body: "Hello World!" }; const context2 = { posts: [post] }; const source2 = '
    {{#posts}}
  • {{{link_to this}}}
  • {{/posts}}
'; -const template2: HandlebarsTemplateDelegate<{ posts: { url: string, body: string }[] }> = Handlebars.compile(source2); +const template2: TemplateDelegate<{ posts: { url: string, body: string }[] }> = Handlebars.compile(source2); template2(context2); Handlebars.registerHelper('link_to', (title: string, context: typeof post) => { @@ -93,7 +92,7 @@ const parsedTmplWithoutOptions = Handlebars.parse('

Hello, my name is {{name}} // Custom partial resolution. const originalResolvePartial = Handlebars.VM.resolvePartial; -Handlebars.VM.resolvePartial = (partial: HandlebarsTemplateDelegate | undefined, context: any, options: Handlebars.ResolvePartialOptions): HandlebarsTemplateDelegate => { +Handlebars.VM.resolvePartial = (partial: TemplateDelegate | undefined, context: any, options: Handlebars.ResolvePartialOptions): TemplateDelegate => { const name = options.name.replace(/my/,'your'); // transform name. options.name = name;