Skip to content

Commit 5518092

Browse files
authored
feat: migrate to ESM (#968)
* feat: migrate to ESM * build: fixup `generate-types` script * build: update `ts-node` config to use ESM * build: disable `verbatimModuleSyntax` for `ts-node` There is currently a bug in ts-node where it completely ignores the `module` and `moduleResolution` options kulshekhar/ts-jest#4198 * test: use ESM export for jest
1 parent cd653a1 commit 5518092

16 files changed

+67
-63
lines changed

jest.config.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ const config: Config.InitialOptions = {
1010
lines: 100,
1111
},
1212
},
13+
extensionsToTreatAsEsm: ['.ts'],
1314
transform: {
1415
"^.+\\.tsx?$": [
1516
"ts-jest",
1617
{
1718
tsconfig: "test/tsconfig.json",
19+
useESM: true,
1820
},
1921
],
2022
},
@@ -27,5 +29,4 @@ const config: Config.InitialOptions = {
2729
testRegex: /test\/.*\/.*.test.ts/u.source,
2830
};
2931

30-
// We have to use a CommonJS export here due to `verbatimModuleSyntax`
31-
module.exports = config;
32+
export default config;

package-lock.json

+38-22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "@octokit/webhooks",
33
"version": "0.0.0-development",
4+
"type": "module",
45
"description": "GitHub webhook events toolset for Node.js",
56
"keywords": [],
67
"repository": "github:octokit/webhooks.js",
@@ -9,11 +10,11 @@
910
"scripts": {
1011
"build": "node scripts/build.mjs && tsc -p tsconfig.json",
1112
"coverage": "jest --coverage && open coverage/lcov-report/index.html",
12-
"generate-types": "ts-node --transpile-only scripts/generate-types.ts",
13+
"generate-types": "node --loader=ts-node/esm scripts/generate-types.ts",
1314
"lint": "prettier --check 'src/**/*.{ts,json}' 'scripts/**/*' 'test/**/*.ts' README.md package.json",
1415
"lint:fix": "prettier --write 'src/**/*.{ts,json}' 'scripts/**/*' 'test/**/*.ts' README.md package.json",
1516
"pretest": "npm run -s lint",
16-
"test": "jest --coverage",
17+
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest --coverage",
1718
"validate:ts": "tsc --noEmit --noImplicitAny --target es2020 --esModuleInterop --moduleResolution node16 --module node16 --allowImportingTsExtensions test/typescript-validate.ts"
1819
},
1920
"prettier": {},
@@ -43,14 +44,13 @@
4344
"@octokit/request-error": "^5.0.0",
4445
"@octokit/webhooks-methods": "^4.0.0",
4546
"@wolfy1339/openapi-webhooks-types": "5.1.3",
46-
"aggregate-error": "^3.1.0"
47+
"aggregate-error": "^5.0.0"
4748
},
4849
"devDependencies": {
4950
"@jest/types": "^29.0.0",
5051
"@octokit/tsconfig": "^2.0.0",
5152
"@types/jest": "^29.0.0",
5253
"@types/node": "^20.0.0",
53-
"@types/prettier": "^2.0.0",
5454
"@wolfy1339/openapi-webhooks": "5.1.3",
5555
"axios": "^1.0.0",
5656
"esbuild": "^0.20.0",

scripts/build.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async function main() {
4343
bundle: true,
4444
platform: "node",
4545
target: "node18",
46-
format: "cjs",
46+
format: "esm",
4747
...sharedOptions,
4848
}),
4949
// Build an ESM browser bundle

scripts/generate-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as fs from "node:fs";
55
import type { OpenAPI3, OperationObject, PathItemObject } from "./types.js";
66
import { format } from "prettier";
77

8-
const schema = require("@wolfy1339/openapi-webhooks").schemas[
8+
const schema = (await import("@wolfy1339/openapi-webhooks")).default.schemas[
99
"api.github.com"
1010
] as OpenAPI3;
1111

src/event-handler/receive.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @ts-ignore to address #245
21
import AggregateError from "aggregate-error";
32
import type {
43
EmitterWebhookEvent,
@@ -35,7 +34,6 @@ export function receiverHandle(state: State, event: EmitterWebhookEvent) {
3534
if (event instanceof Error) {
3635
const error = Object.assign(new AggregateError([event]), {
3736
event,
38-
errors: [event],
3937
});
4038

4139
errorHandlers.forEach((handler) => wrapErrorHandler(handler, error));
@@ -85,7 +83,6 @@ export function receiverHandle(state: State, event: EmitterWebhookEvent) {
8583
const error = new AggregateError(errors) as WebhookEventHandlerError;
8684
Object.assign(error, {
8785
event,
88-
errors,
8986
});
9087

9188
errorHandlers.forEach((handler) => wrapErrorHandler(handler, error));

src/middleware/node/middleware.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// remove type imports from http for Deno compatibility
22
// see https://github.com/octokit/octokit.js/issues/2075#issuecomment-817361886
3-
// import type { IncomingMessage, ServerResponse } from "node:http";
4-
type IncomingMessage = any;
5-
type ServerResponse = any;
3+
import type { IncomingMessage, ServerResponse } from "node:http";
64

75
import type { WebhookEventName } from "../../generated/webhook-identifiers.js";
86

@@ -112,7 +110,7 @@ export async function middleware(
112110

113111
if (didTimeout) return true;
114112

115-
const err = Array.from(error as WebhookEventHandlerError)[0];
113+
const err = Array.from((error as WebhookEventHandlerError).errors)[0];
116114
const errorMessage = err.message
117115
? `${err.name}: ${err.message}`
118116
: "Error: An Unspecified error occurred";

src/types.ts

+1-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { webhooks as OpenAPIWebhooks } from "@wolfy1339/openapi-webhooks-ty
33
import type { EventPayloadMap } from "./generated/webhook-identifiers.js";
44
import type { Logger } from "./createLogger.js";
55
import type { emitterEventNames } from "./generated/webhook-names.js";
6+
import type AggregateError from "aggregate-error";
67

78
export type WebhookEventName = keyof EventPayloadMap;
89
export type ExtractEvents<TEventName> =
@@ -75,20 +76,3 @@ export interface WebhookEventHandlerError<TTransformed = unknown>
7576
? EmitterWebhookEvent
7677
: EmitterWebhookEvent & TTransformed;
7778
}
78-
79-
/**
80-
* Workaround for TypeScript incompatibility with types exported by aggregate-error.
81-
* Credit: https://git.io/JUEEr
82-
* @copyright Sindre Sorhus
83-
* @license MIT (https://git.io/JUEEK)
84-
* @see https://github.com/octokit/webhooks.js/pull/270/files
85-
*/
86-
declare class AggregateError<T extends Error = Error>
87-
extends Error
88-
implements Iterable<T>
89-
{
90-
readonly name: "AggregateError";
91-
constructor(errors: ReadonlyArray<T | { [key: string]: any } | string>);
92-
93-
[Symbol.iterator](): IterableIterator<T>;
94-
}

test/integration/event-handler-test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ describe("when a handler throws an error", () => {
9191
} catch (error: any) {
9292
expect(error.message).toMatch(/oops/);
9393

94-
const errors = Array.from(error);
94+
const errors = Array.from(error.errors);
9595

9696
expect(errors.length).toBe(1);
97-
expect((Array.from(error) as { message: string }[])[0].message).toBe(
98-
"oops",
99-
);
97+
expect(
98+
(Array.from(error.errors) as { message: string }[])[0].message,
99+
).toBe("oops");
100100

101101
expect(error instanceof Error).toBeTruthy();
102102
}
@@ -194,7 +194,7 @@ test("multiple errors in same event handler", async () => {
194194
});
195195
} catch (error: any) {
196196
expect(error.message).toMatch("oops");
197-
expect(Array.from(error).length).toBe(2);
197+
expect(Array.from(error.errors).length).toBe(2);
198198

199199
expect(error instanceof Error);
200200
}

test/integration/node-middleware.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { createServer } from "node:http";
22
import { readFileSync } from "node:fs";
33

44
import { sign } from "@octokit/webhooks-methods";
5+
import { jest } from "@jest/globals";
56

67
// import without types
7-
const express = require("express");
8+
// @ts-expect-error
9+
const express = (await import("express")).default;
810

911
import { createNodeMiddleware, Webhooks } from "../../src/index.ts";
1012

test/integration/smoke-test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
createEventHandler,
44
emitterEventNames,
55
} from "../../src/index.ts";
6+
import { jest } from "@jest/globals";
67

78
test("@octokit/webhooks", () => {
89
const emitWarningSpy = jest.spyOn(process, "emitWarning");

test/typescript-validate.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export default async function () {
182182

183183
webhooks.onError((error) => {
184184
console.log(error.event.name);
185-
const [firstError] = Array.from(error);
185+
const [firstError] = Array.from(error.errors);
186186
console.log(firstError.status);
187187
console.log(firstError.headers);
188188
console.log(firstError.request);

test/unit/createLogger-test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createLogger } from "../../src/createLogger.ts";
2+
import { jest } from "@jest/globals";
23

34
const noop = () => {};
45

test/unit/event-handler-on-test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { receiverOn } from "../../src/event-handler/on.ts";
22
import type { State } from "../../src/types.ts";
3+
import { jest } from "@jest/globals";
34

45
function noop() {}
56

test/unit/event-handler-wrap-error-handler-test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { wrapErrorHandler } from "../../src/event-handler/wrap-error-handler.ts";
2+
import { jest } from "@jest/globals";
23

34
const noop = () => {};
45

tsconfig.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
"include": ["src/**/*"],
44
"ts-node": {
55
"compilerOptions": {
6-
"module": "CommonJS",
7-
"esModuleInterop": true
6+
"verbatimModuleSyntax": false
87
}
98
},
109
"compilerOptions": {
10+
"lib": ["ESNext"],
11+
"module": "Node16",
12+
"moduleResolution": "node16",
1113
"esModuleInterop": true,
1214
"declaration": true,
1315
"outDir": "pkg/dist-types",

0 commit comments

Comments
 (0)