From 731638a6126ac65790a6b737e94b3d0885c6e947 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Wed, 5 Jun 2024 15:09:20 +0530 Subject: [PATCH 1/4] Typesafe paramter parsing --- .../src/file-preamble.test.ts | 3 +- packages/protoplugin-test/src/helpers.ts | 6 +- .../protoplugin-test/src/parse-option.test.ts | 126 ++++++++++-------- packages/protoplugin-test/src/target.test.ts | 4 +- packages/protoplugin/src/create-es-plugin.ts | 18 +-- packages/protoplugin/src/index.ts | 1 + packages/protoplugin/src/parameter.ts | 51 ++++--- packages/protoplugin/src/schema.ts | 47 ++++--- 8 files changed, 153 insertions(+), 103 deletions(-) diff --git a/packages/protoplugin-test/src/file-preamble.test.ts b/packages/protoplugin-test/src/file-preamble.test.ts index a4bea0448..dcc5bc10d 100644 --- a/packages/protoplugin-test/src/file-preamble.test.ts +++ b/packages/protoplugin-test/src/file-preamble.test.ts @@ -187,8 +187,9 @@ describe("GeneratedFile.preamble", () => { "const placeholder = 1; // ensure file is not considered empty", ); }, - parseOption() { + parseOptions() { // accept all options + return {}; }, returnLinesOfFirstFile: true, }); diff --git a/packages/protoplugin-test/src/helpers.ts b/packages/protoplugin-test/src/helpers.ts index 8159ef08a..e5acf3a34 100644 --- a/packages/protoplugin-test/src/helpers.ts +++ b/packages/protoplugin-test/src/helpers.ts @@ -34,7 +34,9 @@ import assert from "node:assert"; let upstreamProtobuf: UpstreamProtobuf | undefined; -type PluginInit = Parameters[0]; +type PluginInit = Parameters< + typeof createEcmaScriptPlugin> +>[0]; // prettier-ignore type CreateTestPluginAndRunOptions = @@ -48,7 +50,7 @@ type CreateTestPluginAndRunOptions { - let foo: number | undefined; - let bar = false; - let baz: string[] = []; - let plugin: Plugin; - beforeEach(() => { - foo = undefined; - bar = false; - baz = []; - const noop = () => { - // - }; - plugin = createEcmaScriptPlugin({ + interface Options { + foo?: number; + bar: boolean; + baz: string[]; + } + const runPlugin = ( + onOptions: (options: Options) => void, + req: MessageInitShape, + ) => { + const generate = ({ options }: Schema) => onOptions(options); + createEcmaScriptPlugin({ name: "test", version: "v1", - parseOption(key, value) { - switch (key) { - case "foo": - foo = parseInt(value); - if (isNaN(foo)) { - throw "please provide an integer for foo"; + parseOptions(options): Options { + const parsed: Options = { bar: false, baz: [] }; + for (const { key, value } of options) { + switch (key) { + case "foo": { + const foo = parseInt(value); + if (isNaN(foo)) { + throw "please provide an integer for foo"; + } + parsed.foo = foo; + break; } - break; - case "bar": - if (value.length > 0) { - throw "bar does not take a value"; - } - bar = true; - break; - case "baz": - if (value.length == 0) { - throw "please provide a value"; - } - baz.push(value); - break; - default: - throw new Error(); + case "bar": + if (value.length > 0) { + throw "bar does not take a value"; + } + parsed.bar = true; + break; + case "baz": + if (value.length == 0) { + throw "please provide a value"; + } + parsed.baz.push(value); + break; + default: + throw new Error(); + } } + return parsed; }, - generateTs: noop, - generateJs: noop, - generateDts: noop, - }); - }); + generateTs: generate, + generateJs: generate, + generateDts: generate, + }).run(create(CodeGeneratorRequestDesc, req)); + }; test("parse as expected on the happy path", () => { - plugin.run( + runPlugin( + (options) => { + expect(options.foo).toBe(123); + expect(options.bar).toBe(true); + expect(options.baz).toStrictEqual(["a", "b"]); + }, create(CodeGeneratorRequestDesc, { parameter: "foo=123,bar,baz=a,baz=b", }), ); - expect(foo).toBe(123); - expect(bar).toBe(true); - expect(baz).toStrictEqual(["a", "b"]); }); test("error from parseOption is wrapped", () => { - const req = create(CodeGeneratorRequestDesc, { - parameter: "foo=abc", - }); - expect(() => plugin.run(req)).toThrowError( + expect(() => + runPlugin(() => {}, { + parameter: "foo=abc", + }), + ).toThrowError( /^invalid option "foo=abc": please provide an integer for foo$/, ); }); test("unknown option raises an error", () => { - const req = create(CodeGeneratorRequestDesc, { - parameter: "unknown", - }); - expect(() => plugin.run(req)).toThrowError(/^invalid option "unknown"$/); + expect(() => + runPlugin(() => {}, { + parameter: "unknown", + }), + ).toThrowError(/^invalid option "unknown"$/); }); test("unknown option with value raises an error", () => { - const req = create(CodeGeneratorRequestDesc, { - parameter: "unknown=bar", - }); - expect(() => plugin.run(req)).toThrowError( - /^invalid option "unknown=bar"$/, - ); + expect(() => + runPlugin(() => {}, { + parameter: "unknown=bar", + }), + ).toThrowError(/^invalid option "unknown=bar"$/); }); }); diff --git a/packages/protoplugin-test/src/target.test.ts b/packages/protoplugin-test/src/target.test.ts index ee0de7b73..743fb900d 100644 --- a/packages/protoplugin-test/src/target.test.ts +++ b/packages/protoplugin-test/src/target.test.ts @@ -22,7 +22,9 @@ import type { import type { CodeGeneratorResponse } from "@bufbuild/protobuf/wkt"; describe("target", () => { - type PluginInit = Parameters[0]; + type PluginInit = Parameters< + typeof createEcmaScriptPlugin> + >[0]; let generateTs: jest.Mock; let generateJs: jest.Mock["generateJs"]>; let generateDts: jest.Mock["generateDts"]>; diff --git a/packages/protoplugin/src/create-es-plugin.ts b/packages/protoplugin/src/create-es-plugin.ts index ee7678cf6..1ab548bed 100644 --- a/packages/protoplugin/src/create-es-plugin.ts +++ b/packages/protoplugin/src/create-es-plugin.ts @@ -30,7 +30,7 @@ import type { Plugin } from "./plugin.js"; import { transpile } from "./transpile.js"; import { parseParameter } from "./parameter.js"; -interface PluginInit { +interface PluginInit { /** * Name of this code generator plugin. */ @@ -45,7 +45,7 @@ interface PluginInit { * An optional parsing function which can be used to parse your own plugin * options. */ - parseOption?: (key: string, value: string) => void; + parseOptions?: (rawOptions: { key: string; value: string }[]) => Options; /** * The earliest edition supported by this plugin. Defaults to the minimum @@ -65,7 +65,7 @@ interface PluginInit { * * Note that this is required to be provided for plugin initialization. */ - generateTs: (schema: Schema, target: "ts") => void; + generateTs: (schema: Schema, target: "ts") => void; /** * A optional function which will generate JavaScript files based on proto @@ -77,7 +77,7 @@ interface PluginInit { * JavaScript files. If not, the plugin framework will transpile the files * itself. */ - generateJs?: (schema: Schema, target: "js") => void; + generateJs?: (schema: Schema, target: "js") => void; /** * A optional function which will generate TypeScript declaration files @@ -89,7 +89,7 @@ interface PluginInit { * declaration files. If not, the plugin framework will transpile the files * itself. */ - generateDts?: (schema: Schema, target: "dts") => void; + generateDts?: (schema: Schema, target: "dts") => void; /** * An optional function which will transpile a given set of files. @@ -117,7 +117,9 @@ interface PluginInit { * The plugin can generate JavaScript, TypeScript, or TypeScript declaration * files. */ -export function createEcmaScriptPlugin(init: PluginInit): Plugin { +export function createEcmaScriptPlugin( + init: PluginInit, +): Plugin { let transpileJs = false; let transpileDts = false; return { @@ -126,7 +128,7 @@ export function createEcmaScriptPlugin(init: PluginInit): Plugin { run(req) { const minimumEdition = init.minimumEdition ?? minimumEditionUpstream; const maximumEdition = init.maximumEdition ?? maximumEditionUpstream; - const parameter = parseParameter(req.parameter, init.parseOption); + const parameter = parseParameter(req.parameter, init.parseOptions); const schema = createSchema( req, parameter, @@ -208,7 +210,7 @@ export function createEcmaScriptPlugin(init: PluginInit): Plugin { tsFiles, transpileJs, transpileDts, - parameter.jsImportStyle, + parameter.parsed.jsImportStyle, ); files.push(...transpiledFiles); } diff --git a/packages/protoplugin/src/index.ts b/packages/protoplugin/src/index.ts index 5930b0e06..b362b9bf3 100644 --- a/packages/protoplugin/src/index.ts +++ b/packages/protoplugin/src/index.ts @@ -24,6 +24,7 @@ export { export type { Target } from "./target.js"; export type { Schema } from "./schema.js"; +export type { EcmaScriptPluginParameters } from "./parameter.js"; export type { GeneratedFile, FileInfo } from "./generated-file.js"; export type { ImportSymbol } from "./import-symbol.js"; export { createImportSymbol } from "./import-symbol.js"; diff --git a/packages/protoplugin/src/parameter.ts b/packages/protoplugin/src/parameter.ts index 47e958684..8f4389d1c 100644 --- a/packages/protoplugin/src/parameter.ts +++ b/packages/protoplugin/src/parameter.ts @@ -16,7 +16,7 @@ import type { Target } from "./target.js"; import type { RewriteImports } from "./import-path.js"; import { PluginOptionError } from "./error.js"; -export interface ParsedParameter { +export interface EcmaScriptPluginParameters { targets: Target[]; tsNocheck: boolean; bootstrapWkt: boolean; @@ -24,13 +24,19 @@ export interface ParsedParameter { rewriteImports: RewriteImports; importExtension: string; jsImportStyle: "module" | "legacy_commonjs"; - sanitizedParameter: string; } -export function parseParameter( +export interface ParsedParameter { + parsed: T & EcmaScriptPluginParameters; + sanitized: string; +} + +export function parseParameter( parameter: string, - parseExtraOption: ((key: string, value: string) => void) | undefined, -): ParsedParameter { + parseExtraOptions: + | ((rawOptions: { key: string; value: string }[]) => T) + | undefined, +): ParsedParameter { let targets: Target[] = ["js", "dts"]; let tsNocheck = false; let bootstrapWkt = false; @@ -38,6 +44,8 @@ export function parseParameter( const rewriteImports: RewriteImports = []; let importExtension = ""; let jsImportStyle: "module" | "legacy_commonjs" = "module"; + const extraParameters: { key: string; value: string }[] = []; + const extraParametersRaw: string[] = []; const rawParameters: string[] = []; for (const { key, value, raw } of splitParameter(parameter)) { // Whether this key/value plugin parameter pair should be @@ -136,24 +144,19 @@ export function parseParameter( break; } default: - if (parseExtraOption === undefined) { + if (parseExtraOptions === undefined) { throw new PluginOptionError(raw); } - try { - parseExtraOption(key, value); - } catch (e) { - throw new PluginOptionError(raw, e); - } + extraParameters.push({ key, value }); + extraParametersRaw.push(raw); break; } if (!sanitize) { rawParameters.push(raw); } } - - const sanitizedParameter = rawParameters.join(","); - - return { + const sanitizedParameters = rawParameters.join(","); + const ecmaScriptPluginParameters = { targets, tsNocheck, bootstrapWkt, @@ -161,8 +164,24 @@ export function parseParameter( importExtension, jsImportStyle, keepEmptyFiles, - sanitizedParameter, }; + if (parseExtraOptions === undefined || extraParameters.length === 0) { + return { + parsed: ecmaScriptPluginParameters as T & EcmaScriptPluginParameters, + sanitized: sanitizedParameters, + }; + } + try { + return { + parsed: Object.assign( + ecmaScriptPluginParameters, + parseExtraOptions(extraParameters), + ), + sanitized: sanitizedParameters, + }; + } catch (err) { + throw new PluginOptionError(extraParametersRaw.join(","), err); + } } function splitParameter( diff --git a/packages/protoplugin/src/schema.ts b/packages/protoplugin/src/schema.ts index e7ae58e0e..fcf5fce02 100644 --- a/packages/protoplugin/src/schema.ts +++ b/packages/protoplugin/src/schema.ts @@ -36,7 +36,10 @@ import { createGeneratedFile } from "./generated-file.js"; import { createImportSymbol } from "./import-symbol.js"; import type { Target } from "./target.js"; import { deriveImportPath, rewriteImportPath } from "./import-path.js"; -import type { ParsedParameter } from "./parameter.js"; +import type { + EcmaScriptPluginParameters, + ParsedParameter, +} from "./parameter.js"; import { makeFilePreamble } from "./file-preamble.js"; import { localDescName, localShapeName, generateFilePath } from "./names.js"; import { createRuntimeImports } from "./runtime-imports.js"; @@ -45,7 +48,7 @@ import { createRuntimeImports } from "./runtime-imports.js"; * Schema describes the files and types that the plugin is requested to * generate. */ -export interface Schema { +export interface Schema { /** * The files we are asked to generate. */ @@ -61,6 +64,11 @@ export interface Schema { */ readonly targets: readonly Target[]; + /** + * Parsed plugin options. They include the default options available by all ecmascript plugins. + */ + readonly options: Options & EcmaScriptPluginParameters; + /** * Generate a new file with the given name. */ @@ -80,19 +88,19 @@ export interface Schema { readonly proto: CodeGeneratorRequest; } -interface SchemaController extends Schema { +interface SchemaController extends Schema { getFileInfo: () => FileInfo[]; prepareGenerate(target: Target): void; } -export function createSchema( +export function createSchema( request: CodeGeneratorRequest, - parameter: ParsedParameter, + parameter: ParsedParameter, pluginName: string, pluginVersion: string, minimumEdition: Edition, maximumEdition: Edition, -): SchemaController { +): SchemaController { const { allFiles, filesToGenerate } = getFilesToGenerate( request, minimumEdition, @@ -100,13 +108,13 @@ export function createSchema( ); let target: Target | undefined; const generatedFiles: GeneratedFileController[] = []; - const runtime = createRuntimeImports(parameter.bootstrapWkt); + const runtime = createRuntimeImports(parameter.parsed.bootstrapWkt); const resolveDescImport: ResolveDescImportFn = (desc, typeOnly) => createImportSymbol( localDescName(desc), generateFilePath( desc.kind == "file" ? desc : desc.file, - parameter.bootstrapWkt, + parameter.parsed.bootstrapWkt, filesToGenerate, ), typeOnly, @@ -114,7 +122,11 @@ export function createSchema( const resolveShapeImport: ResolveShapeImportFn = (desc) => createImportSymbol( localShapeName(desc), - generateFilePath(desc.file, parameter.bootstrapWkt, filesToGenerate), + generateFilePath( + desc.file, + parameter.parsed.bootstrapWkt, + filesToGenerate, + ), true, ); const createPreamble: CreatePreambleFn = (descFile) => @@ -122,20 +134,21 @@ export function createSchema( descFile, pluginName, pluginVersion, - parameter.sanitizedParameter, - parameter.tsNocheck, + parameter.sanitized, + parameter.parsed.tsNocheck, ); const rewriteImport: RewriteImportFn = (importPath) => rewriteImportPath( importPath, - parameter.rewriteImports, - parameter.importExtension, + parameter.parsed.rewriteImports, + parameter.parsed.importExtension, ); return { - targets: parameter.targets, + targets: parameter.parsed.targets, proto: request, files: filesToGenerate, allFiles: allFiles, + options: parameter.parsed, typesInFile: nestedTypes, generateFile(name) { if (target === undefined) { @@ -146,7 +159,7 @@ export function createSchema( const genFile = createGeneratedFile( name, deriveImportPath(name), - target === "js" ? parameter.jsImportStyle : "module", // ts and dts always use import/export, only js may use commonjs + target === "js" ? parameter.parsed.jsImportStyle : "module", // ts and dts always use import/export, only js may use commonjs rewriteImport, resolveDescImport, resolveShapeImport, @@ -159,7 +172,9 @@ export function createSchema( getFileInfo() { return generatedFiles .map((f) => f.getFileInfo()) - .filter((fi) => parameter.keepEmptyFiles || fi.content.length > 0); + .filter( + (fi) => parameter.parsed.keepEmptyFiles || fi.content.length > 0, + ); }, prepareGenerate(newTarget) { target = newTarget; From 76d3297ebca1d70b220f08ff056acfc843d81773 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Wed, 5 Jun 2024 15:52:53 +0530 Subject: [PATCH 2/4] docs --- docs/writing_plugins.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/writing_plugins.md b/docs/writing_plugins.md index a218bc230..e96c4c255 100644 --- a/docs/writing_plugins.md +++ b/docs/writing_plugins.md @@ -369,13 +369,13 @@ automatically generate the correct export for CommonJS. ### Parsing plugin options -The plugin framework recognizes a set of pre-defined key/value pairs that can be passed to all plugins when executed (i.e. `target`, `keep_empty_files`, etc.), but if your plugin needs to be passed additional parameters, you can specify a `parseOption` function as part of your plugin initialization. +The plugin framework recognizes a set of pre-defined key/value pairs that can be passed to all plugins when executed (i.e. `target`, `keep_empty_files`, etc.), but if your plugin needs to be passed additional parameters, you can specify a `parseOptions` function as part of your plugin initialization. ```ts -parseOption(key: string, value: string | undefined): void; +parseOptions(rawOptions: {key: string, value: string}[]): T; ``` -This function will be invoked by the framework, passing in any key/value pairs that it does not recognize from its pre-defined list. +This function will be invoked by the framework, passing in any key/value pairs that it does not recognize from its pre-defined list. The returned option will be merged with the pre-defined options and passed to the generate functions along via the `options` property of the schema. ### Using custom Protobuf options From 4501106563bc8aaa5cbe4914fec8c4c3ded5c204 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Thu, 6 Jun 2024 18:55:18 +0530 Subject: [PATCH 3/4] Add docs; export input type --- packages/protoplugin/src/create-es-plugin.ts | 3 +- packages/protoplugin/src/index.ts | 2 +- packages/protoplugin/src/parameter.ts | 81 +++++++++++++++++--- packages/protoplugin/src/schema.ts | 7 +- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/packages/protoplugin/src/create-es-plugin.ts b/packages/protoplugin/src/create-es-plugin.ts index 1ab548bed..dfe288dee 100644 --- a/packages/protoplugin/src/create-es-plugin.ts +++ b/packages/protoplugin/src/create-es-plugin.ts @@ -29,6 +29,7 @@ import type { FileInfo } from "./generated-file.js"; import type { Plugin } from "./plugin.js"; import { transpile } from "./transpile.js"; import { parseParameter } from "./parameter.js"; +import type { RawPluginOptions } from "./parameter.js"; interface PluginInit { /** @@ -45,7 +46,7 @@ interface PluginInit { * An optional parsing function which can be used to parse your own plugin * options. */ - parseOptions?: (rawOptions: { key: string; value: string }[]) => Options; + parseOptions?: (rawOptions: RawPluginOptions) => Options; /** * The earliest edition supported by this plugin. Defaults to the minimum diff --git a/packages/protoplugin/src/index.ts b/packages/protoplugin/src/index.ts index b362b9bf3..beee1805c 100644 --- a/packages/protoplugin/src/index.ts +++ b/packages/protoplugin/src/index.ts @@ -24,7 +24,7 @@ export { export type { Target } from "./target.js"; export type { Schema } from "./schema.js"; -export type { EcmaScriptPluginParameters } from "./parameter.js"; +export type { EcmaScriptPluginOptions } from "./parameter.js"; export type { GeneratedFile, FileInfo } from "./generated-file.js"; export type { ImportSymbol } from "./import-symbol.js"; export { createImportSymbol } from "./import-symbol.js"; diff --git a/packages/protoplugin/src/parameter.ts b/packages/protoplugin/src/parameter.ts index 8f4389d1c..a961b7d29 100644 --- a/packages/protoplugin/src/parameter.ts +++ b/packages/protoplugin/src/parameter.ts @@ -16,26 +16,83 @@ import type { Target } from "./target.js"; import type { RewriteImports } from "./import-path.js"; import { PluginOptionError } from "./error.js"; -export interface EcmaScriptPluginParameters { +/** + * Standard plugin options that every ECMAScript plugin supports. + */ +export interface EcmaScriptPluginOptions { + /** + * Controls whether the plugin generates JavaScript, TypeScript, + * or TypeScript declaration files. + * + * The default is ["js", "dts]. + */ targets: Target[]; + /** + * Add an extension to every import, for example ".js" or ".ts". + * + * The default is "". + */ + importExtension: string; + /** + * Generate `import` statements or `require()` calls. + * + * The default is "module". + */ + jsImportStyle: "module" | "legacy_commonjs"; + /** + * Generate an annotation at the top of each file to skip type checks: + * `// @ts-nocheck`. + * + * The default is false. + */ tsNocheck: boolean; - bootstrapWkt: boolean; + /** + * Prune empty files from the output. + * + * The default is false. + */ keepEmptyFiles: boolean; + /** + * @private + */ + bootstrapWkt: boolean; + /** + * @private + */ rewriteImports: RewriteImports; - importExtension: string; - jsImportStyle: "module" | "legacy_commonjs"; } export interface ParsedParameter { - parsed: T & EcmaScriptPluginParameters; + parsed: T & EcmaScriptPluginOptions; sanitized: string; } +/** + * Raw options to parse. + * + * For example, if a plugin is run with the options foo=123,bar,baz=a,baz=b + * the raw options are: + * + * ```ts + * [ + * { key: "foo", value: "123" }, + * { key: "bar", value: "" }, + * { key: "baz", value: "a" }, + * { key: "baz", value: "b" }, + * ] + * ``` + * + * If your plugin does not recognize an option, it must throw an Error in + * parseOptions. + */ +export type RawPluginOptions = { + key: string; + value: string; +}[]; + export function parseParameter( parameter: string, - parseExtraOptions: - | ((rawOptions: { key: string; value: string }[]) => T) - | undefined, + parseExtraOptions: ((rawOptions: RawPluginOptions) => T) | undefined, ): ParsedParameter { let targets: Target[] = ["js", "dts"]; let tsNocheck = false; @@ -44,7 +101,7 @@ export function parseParameter( const rewriteImports: RewriteImports = []; let importExtension = ""; let jsImportStyle: "module" | "legacy_commonjs" = "module"; - const extraParameters: { key: string; value: string }[] = []; + const extraParameters: RawPluginOptions = []; const extraParametersRaw: string[] = []; const rawParameters: string[] = []; for (const { key, value, raw } of splitParameter(parameter)) { @@ -156,7 +213,7 @@ export function parseParameter( } } const sanitizedParameters = rawParameters.join(","); - const ecmaScriptPluginParameters = { + const ecmaScriptPluginOptions = { targets, tsNocheck, bootstrapWkt, @@ -167,14 +224,14 @@ export function parseParameter( }; if (parseExtraOptions === undefined || extraParameters.length === 0) { return { - parsed: ecmaScriptPluginParameters as T & EcmaScriptPluginParameters, + parsed: ecmaScriptPluginOptions as T & EcmaScriptPluginOptions, sanitized: sanitizedParameters, }; } try { return { parsed: Object.assign( - ecmaScriptPluginParameters, + ecmaScriptPluginOptions, parseExtraOptions(extraParameters), ), sanitized: sanitizedParameters, diff --git a/packages/protoplugin/src/schema.ts b/packages/protoplugin/src/schema.ts index fcf5fce02..2ffcb865a 100644 --- a/packages/protoplugin/src/schema.ts +++ b/packages/protoplugin/src/schema.ts @@ -36,10 +36,7 @@ import { createGeneratedFile } from "./generated-file.js"; import { createImportSymbol } from "./import-symbol.js"; import type { Target } from "./target.js"; import { deriveImportPath, rewriteImportPath } from "./import-path.js"; -import type { - EcmaScriptPluginParameters, - ParsedParameter, -} from "./parameter.js"; +import type { EcmaScriptPluginOptions, ParsedParameter } from "./parameter.js"; import { makeFilePreamble } from "./file-preamble.js"; import { localDescName, localShapeName, generateFilePath } from "./names.js"; import { createRuntimeImports } from "./runtime-imports.js"; @@ -67,7 +64,7 @@ export interface Schema { /** * Parsed plugin options. They include the default options available by all ecmascript plugins. */ - readonly options: Options & EcmaScriptPluginParameters; + readonly options: Options & EcmaScriptPluginOptions; /** * Generate a new file with the given name. From c41eeaf69b2a421afa2bcaeea751459ea00705c8 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Thu, 6 Jun 2024 18:58:24 +0530 Subject: [PATCH 4/4] format comment --- packages/protoplugin/src/schema.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/protoplugin/src/schema.ts b/packages/protoplugin/src/schema.ts index 2ffcb865a..9b6c92117 100644 --- a/packages/protoplugin/src/schema.ts +++ b/packages/protoplugin/src/schema.ts @@ -62,7 +62,8 @@ export interface Schema { readonly targets: readonly Target[]; /** - * Parsed plugin options. They include the default options available by all ecmascript plugins. + * Parsed plugin options. They include the standard options for all + * plugins, and options parsed by your plugin. */ readonly options: Options & EcmaScriptPluginOptions;