diff --git a/.eslintrc.yaml b/.eslintrc.yaml index edb20bfe1..2036b6e0e 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -35,7 +35,7 @@ rules: [error, { alphabetize: { order: "asc" }, groups: [["builtin", "external", "internal"], "parent", "sibling"] }] no-async-promise-executor: off # This isn't a real module, just types, which apparently doesn't resolve. - import/no-unresolved: [error, { ignore: ["express-serve-static-core"] }] + import/no-unresolved: [error, { ignore: ["express-serve-static-core", "code-server"] }] settings: # Does not work with CommonJS unfortunately. diff --git a/src/node/plugin.ts b/src/node/plugin.ts index 2c0519ac1..33047e826 100644 --- a/src/node/plugin.ts +++ b/src/node/plugin.ts @@ -8,6 +8,21 @@ import { version } from "./constants" import * as util from "./util" const fsp = fs.promises +/** + * Inject code-server when `require`d. This is required because the API provides + * more than just types so these need to be provided at run-time. + */ +const originalLoad = require("module")._load +// eslint-disable-next-line @typescript-eslint/no-explicit-any +require("module")._load = function (request: string, parent: object, isMain: boolean): any { + if (request === "code-server") { + return { + field, + } + } + return originalLoad.apply(this, [request, parent, isMain]) +} + interface Plugin extends pluginapi.Plugin { /** * These fields are populated from the plugin's package.json diff --git a/test/test-plugin/src/index.ts b/test/test-plugin/src/index.ts index fb1869447..7d14a7bc6 100644 --- a/test/test-plugin/src/index.ts +++ b/test/test-plugin/src/index.ts @@ -1,8 +1,8 @@ +import * as cs from "code-server" import * as express from "express" import * as fspath from "path" -import * as pluginapi from "../../../typings/pluginapi" -export const plugin: pluginapi.Plugin = { +export const plugin: cs.Plugin = { displayName: "Test Plugin", routerPath: "/test-plugin", homepageURL: "https://example.com", diff --git a/test/test-plugin/tsconfig.json b/test/test-plugin/tsconfig.json index 0956ead88..5afea81bf 100644 --- a/test/test-plugin/tsconfig.json +++ b/test/test-plugin/tsconfig.json @@ -42,8 +42,10 @@ /* 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'. */ + "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, + "paths": { + "code-server": ["../../typings/pluginapi"] + } /* 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. */ diff --git a/typings/pluginapi.d.ts b/typings/pluginapi.d.ts index 06ce35fb4..f9b07602b 100644 --- a/typings/pluginapi.d.ts +++ b/typings/pluginapi.d.ts @@ -1,7 +1,7 @@ /** * This file describes the code-server plugin API for adding new applications. */ -import { Logger } from "@coder/logger" +import { field, Logger } from "@coder/logger" import * as express from "express" /** @@ -78,6 +78,13 @@ import * as express from "express" * ] */ +/** + * Use to add a field to a log. + * + * Re-exported so plugins don't have to import duplicate copies of the logger. + */ +export { field } + /** * Your plugin module must have a top level export "plugin" that implements this interface. *