UNPKG

chrome-debugging-client

Version:

An async/await friendly Chrome debugging client with TypeScript support

248 lines 8.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * Generate Typescript interface to use with the DebuggingProtocol#domains(protocol) method. */ class ProtocolCodegen { constructor(options) { this.indentStack = [""]; this.code = undefined; let opts = options || {}; this.clientModuleName = opts.clientModuleName || "chrome-debugging-client"; this.indent = opts.indent || " "; this.typescript = !!opts.typescript; } get currentIndent() { return this.indentStack[this.indentStack.length - 1]; } generate(protocol) { this.code = ""; this.indentStack.length = 1; this.appendProtocolVersionComment(protocol.version); this.appendClientImport(); each(protocol.domains, domain => { let domainName = domain.domain; let events = domain.events; let commands = domain.commands; let types = domain.types; this.appendComment(domain); this.appendDomainClass(domainName, () => { each(events, event => { this.appendEventMember(event, domainName); }); this.appendClientMember(); this.appendDomainConstructor(); each(commands, command => { this.appendComment(command); this.appendCommandMethod(command, domainName); }); each(events, event => { this.appendComment(event); this.appendEventAccessors(event, domainName); }); }); this.generateDomainTypeNamespace(domainName, () => { each(types, type => { this.appendComment(type); this.appendType(type); }); each(events, event => { this.appendEventParametersType(event); this.appendEventHandlerType(event); }); each(commands, command => { this.appendCommandTypes(command); }); }); }); let code = this.code; this.code = undefined; return code; } appendProtocolVersionComment(version) { this.append("/**"); this.append(` * Debugging Protocol ${version.major}.${version.minor} Domains`); this.append(` * Generated on ${new Date()}`); this.append(" */"); } appendClientImport() { if (this.typescript) { this.append(`import { IDebuggingProtocolClient } from "${this.clientModuleName}";`); } else { this.append("\"use strict\";"); } } appendDomainClass(domainName, cb) { let moduleExport = this.typescript ? "export" : `module.exports.${domainName} =`; this.append(`${moduleExport} class ${domainName} {`); this.block(cb); this.append("}"); } generateDomainTypeNamespace(domainName, cb) { if (!this.typescript) return; this.append(`export namespace ${domainName} {`); this.block(cb); this.append("}"); } appendEventMember(event, domainName) { if (!this.typescript) { return; } let name = event.name; this.append(`private _${name}: ${domainName}.${name}_Handler = undefined;`); } appendClientMember() { if (!this.typescript) { return; } this.append("private _client: IDebuggingProtocolClient = undefined;"); } appendDomainConstructor() { let type = this.typescript ? ": IDebuggingProtocolClient" : ""; this.append(`constructor(client${type}) {`); this.block(() => { this.append("this._client = client;"); }); this.append("}"); } appendCommandMethod(command, domainName) { let name = command.name; let fullname = `${domainName}.${name}`; let paramsType = this.typescript ? `: ${fullname}_Parameters` : ""; let params = command.parameters ? `params${paramsType}` : ""; let paramsArg = command.parameters ? ", params" : ""; let returnType = this.typescript ? command.returns ? `<${fullname}_Return>` : "<void>" : ""; let returns = this.typescript ? `: Promise${returnType}` : ""; this.append(`${name}(${params})${returns} {`); this.block(() => { this.append(`return this._client.send${returnType}("${fullname}"${paramsArg});`); }); this.append("}"); } appendEventAccessors(event, domainName) { let name = event.name; let fullname = `${domainName}.${name}`; let handlerType = this.typescript ? `: ${fullname}_Handler` : ""; this.append(`get ${name}()${handlerType} {`); this.block(() => { this.append(`return this._${name};`); }); this.append("}"); this.append(`set ${name}(handler${handlerType}) {`); this.block(() => { this.append(`if (this._${name}) {`); this.block(() => { this.append(`this._client.removeListener("${fullname}", this._${name});`); }); this.append("}"); this.append(`this._${name} = handler;`); this.append("if (handler) {"); this.block(() => { this.append(`this._client.on("${fullname}", handler);`); }); this.append(`}`); }); this.append("}"); } appendType(type) { let properties = type.properties; if (type.type === "object" && properties && properties.length) { this.append(`export interface ${type.id} {`); this.block(() => { each(properties, prop => this.generateProperty(prop)); }); this.append("}"); } else { this.append(`export type ${type.id} = ${this.typeString(type)};`); } } appendEventParametersType(event) { this.generateObjectTypeAlias(`${event.name}_Parameters`, event.parameters); } appendEventHandlerType(event) { let params = event.parameters ? `params: ${event.name}_Parameters` : ""; this.append(`export type ${event.name}_Handler = (${params}) => void;`); } block(cb) { this.indentStack.push(this.currentIndent + this.indent); cb(); this.indentStack.pop(); } append(line) { this.code += this.currentIndent + line + "\n"; } generateProperty(desc) { this.appendComment(desc); this.append(this.namedTypeString(desc)); } appendComment(obj) { if (!obj.description) { return; } this.append(`/** ${obj.description} */`); } appendCommandTypes(command) { let name = command.name; this.generateObjectTypeAlias(`${name}_Parameters`, command.parameters); this.generateObjectTypeAlias(`${name}_Return`, command.returns); } generateObjectTypeAlias(name, props) { if (!props) { return; } if (props.length) { this.append(`export type ${name} = {`); this.block(() => { props.forEach(prop => this.generateProperty(prop)); }); this.append("};"); } else { this.append(`export type ${name} = any;`); } } namedTypeString(desc) { return `${desc.name}${desc.optional ? "?" : ""}: ${this.typeString(desc)};`; } typeString(desc) { if (desc.$ref) { return desc.$ref; } let properties = desc.properties; switch (desc.type) { case "integer": return "number"; case "number": case "boolean": case "any": return desc.type; case "string": if (desc.enum) { return desc.enum.map(str => JSON.stringify(str)).join(" | "); } return "string"; case "array": return this.typeString(desc.items) + "[]"; case "object": if (properties && properties.length) { return "{ " + properties.map(p => this.namedTypeString(p)).join(" ") + " }"; } return "any"; default: throw new Error("unexpected type" + JSON.stringify(desc)); } } } exports.default = ProtocolCodegen; function each(arr, cb) { if (!arr) { return; } for (let i = 0; i < arr.length; i++) { cb(arr[i]); } } //# sourceMappingURL=protocol-codegen.js.map