diff --git a/.changeset/silver-experts-attend.md b/.changeset/silver-experts-attend.md new file mode 100644 index 00000000..19ed1dfa --- /dev/null +++ b/.changeset/silver-experts-attend.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/wonder-stuff-server": major +--- + +Make Runtime a TS enum diff --git a/.changeset/young-cameras-fail.md b/.changeset/young-cameras-fail.md new file mode 100644 index 00000000..f08f9f67 --- /dev/null +++ b/.changeset/young-cameras-fail.md @@ -0,0 +1,5 @@ +--- +"ws-dev-build-settings": minor +--- + +Stop building Flow type definitions diff --git a/.github/workflows/node-ci.yml b/.github/workflows/node-ci.yml index ea00f530..406e2cbf 100644 --- a/.github/workflows/node-ci.yml +++ b/.github/workflows/node-ci.yml @@ -75,9 +75,6 @@ jobs: - name: Build Types run: yarn build:types - - name: Build Flow Types - run: yarn build:flowtypes - # Linting / type checking - name: Eslint uses: Khan/actions@full-or-limited-v0 diff --git a/build-scripts/flowgen.d.ts b/build-scripts/flowgen.d.ts deleted file mode 100644 index b60a72b7..00000000 --- a/build-scripts/flowgen.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module "flowgen"; diff --git a/build-scripts/gen-flow-types.ts b/build-scripts/gen-flow-types.ts deleted file mode 100644 index 4d0a4cd4..00000000 --- a/build-scripts/gen-flow-types.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as fglob from "fast-glob"; -import {compiler, beautify} from "flowgen"; - -const rootDir = path.join(__dirname, ".."); -const files = fglob.sync("packages/wonder-stuff-*/dist/**/*.d.ts", { - cwd: rootDir, -}); - -if (files.length) { - console.log(`found ${files.length} files`); -} else { - throw new Error("no typescript type definitions found"); -} - -// The node API for `flowgen` doesn't have an option to add a flow header -// so we need to do it ourselves. -const HEADER = `/** - * Flowtype definitions for data - * Generated by Flowgen from a Typescript Definition - * Flowgen v1.21.0 - * @flow - */ -`; - -let errorCount = 0; -for (const inFile of files) { - const outFile = inFile.replace(".d.ts", ".js.flow"); - - const overrideFile = outFile.replace("/dist/", "/src/"); - if (fs.existsSync(overrideFile)) { - console.log(`copying\nfrom: ${overrideFile}\nto: ${outFile}`); - fs.cpSync( - path.join(rootDir, overrideFile), - path.join(rootDir, outFile), - ); - continue; - } - - try { - const source = fs.readFileSync(path.join(rootDir, inFile), "utf-8"); - const options = {inexact: false}; - let contents: string = compiler.compileDefinitionString( - source, - options, - ); - contents = beautify(contents); - - // `flowgen` sometimes outputs code that uses `mixins` instead of `extends` - // so we do some post-processing on the files to clean that up. - if (contents.includes(" mixins ")) { - contents = contents.replace(/ mixins /g, " extends "); - console.log("replacing 'mixins' with 'extends'"); - } - - fs.writeFileSync( - path.join(rootDir, outFile), - HEADER + contents, - "utf-8", - ); - console.log(`✅ wrote: ${outFile}`); - } catch (e) { - errorCount += 1; - console.log(`❌ error processing: ${inFile}: ${e}`); - } -} - -// Fail the build step if there were any files we couldn't process -process.exit(errorCount); diff --git a/build-scripts/remove-test-types-from-dist.ts b/build-scripts/remove-test-types-from-dist.ts deleted file mode 100644 index b7d160ea..00000000 --- a/build-scripts/remove-test-types-from-dist.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as fglob from "fast-glob"; - -const rootDir = path.join(__dirname, ".."); -const files = fglob.sync("packages/wonder-stuff-*/dist/**/__tests__/*.d.ts", { - cwd: rootDir, -}); - -for (const file of files) { - fs.unlinkSync(path.join(rootDir, file)); -} - -const dirs = fglob.sync("packages/wonder-stuff-*/dist/**/__tests__", { - cwd: rootDir, - onlyFiles: false, -}); - -for (const dir of dirs) { - fs.rmdirSync(path.join(rootDir, dir)); -} diff --git a/build-settings/flowgen.d.ts b/build-settings/flowgen.d.ts deleted file mode 100644 index f83f7460..00000000 --- a/build-settings/flowgen.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Adapted from https://github.com/joarwilk/flowgen/blob/master/index.js.flow - -declare module "flowgen" { - export type Options = { - jsdoc?: boolean; - interfaceRecords?: boolean; - moduleExports?: boolean; - quiet?: boolean; - inexact?: boolean; - }; - - export type Compiler = { - compileTest(path: string, target: string): void; - compileDefinitionString( - string: string, - options?: Options, - mapSourceCode?: ( - source: string | void, - fileName: string, - ) => string | void, - ): string; - compileDefinitionFile( - path: string, - options?: Options, - mapSourceCode?: ( - source: string | void, - fileName: string, - ) => string | void, - ): string; - - // Low-level exports - reset(options?: Options): void; - setChecker(checker: any /* ts.TypeChecker */): void; - compile(sourceFile: any /* ts.SourceFile */): string; - }; - - export function beautify(str: string): string; - export const compiler: Compiler; -} diff --git a/package.json b/package.json index 5c9f2c70..b9a4dabd 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "express-async-handler": "^1.2.0", "express-winston": "^4.2.0", "fast-glob": "^3.3.0", - "flowgen": "git+https://git@github.com/Khan/flowgen.git#fa8050929948fb4313f738301285fb44625678c4", "heapdump": "^0.3.15", "jest": "^29.6.1", "jest-extended": "^4.0.0", @@ -82,8 +81,7 @@ "scripts": { "build": "rollup -c build-settings/rollup.config.js", "build:prodsizecheck": "rollup -c build-settings/rollup.config.js --configPlatforms='browser' --configFormats='esm' --configEnvironment='production'", - "build:types": "yarn tsc --build --verbose tsconfig-build.json && node -r @swc-node/register build-scripts/remove-test-types-from-dist.ts", - "build:flowtypes": "node -r @swc-node/register build-scripts/gen-flow-types.ts", + "build:types": "yarn tsc --build --verbose tsconfig-build.json", "build:docs": "typedoc", "watch": "rollup -c build-settings/rollup.config.js --watch", "clean": "rm -rf packages/wonder-stuff-*/dist && rm -rf packages/wonder-stuff-*/node_modules && rm -f packages/*/*.tsbuildinfo", diff --git a/packages/tsconfig-shared.json b/packages/tsconfig-shared.json index 5daceea7..47456fac 100644 --- a/packages/tsconfig-shared.json +++ b/packages/tsconfig-shared.json @@ -1,6 +1,16 @@ // This file is used by the tsconfig.json files in each package. /* Visit https://aka.ms/tsconfig to read more about this file */ { + "exclude": [ + "dist", + "**/*.test.*", + "**/__tests__/**", + "**/*.testdata.*", + "**/__testdata__/**", + "**/*.stories.*", + "**/__stories__/**", + "**/*.cypress.*" + ], "extends": "../tsconfig-common.json", "compilerOptions": { "composite": true, diff --git a/packages/wonder-stuff-render-server/src/__tests__/run-server.test.ts b/packages/wonder-stuff-render-server/src/__tests__/run-server.test.ts index 3232b263..e50caef1 100644 --- a/packages/wonder-stuff-render-server/src/__tests__/run-server.test.ts +++ b/packages/wonder-stuff-render-server/src/__tests__/run-server.test.ts @@ -116,7 +116,9 @@ describe("#runServer", () => { const fakeRenderEnvironment: any = { render: jest.fn(), }; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("test"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Test, + ); jest.spyOn(WSServer, "getLogger").mockReturnValue(pretendLogger); jest.spyOn(WSServer, "getAppEngineInfo").mockReturnValue({} as any); const pretendApp = { @@ -146,7 +148,9 @@ describe("#runServer", () => { const fakeRenderEnvironment: any = { render: jest.fn(), }; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("test"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Test, + ); jest.spyOn(WSServer, "getLogger").mockReturnValue(pretendLogger); jest.spyOn(WSServer, "getAppEngineInfo").mockReturnValue({} as any); const pretendApp = { @@ -190,7 +194,9 @@ describe("#runServer", () => { const fakeRenderEnvironment: any = { render: jest.fn(), }; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("test"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Test, + ); jest.spyOn(WSServer, "getLogger").mockReturnValue(pretendLogger); jest.spyOn(WSServer, "getAppEngineInfo").mockReturnValue({} as any); const pretendApp = { @@ -225,7 +231,9 @@ describe("#runServer", () => { it("should start the gateway", async () => { // Arrange const fakeRenderEnvironment: any = {render: jest.fn()}; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("test"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Test, + ); jest.spyOn(WSServer, "getAppEngineInfo").mockReturnValue({} as any); const pretendApp = { use: jest.fn().mockReturnThis(), @@ -283,7 +291,9 @@ describe("#runServer", () => { // Arrange process.env.KA_ALLOW_HEAPDUMP = "1"; const fakeRenderEnvironment: any = {render: jest.fn()}; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("test"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Test, + ); jest.spyOn(WSServer, "getAppEngineInfo").mockReturnValue({} as any); const pretendApp = { use: jest.fn().mockReturnThis(), diff --git a/packages/wonder-stuff-render-server/src/__tests__/start-trace-agent-impl.test.ts b/packages/wonder-stuff-render-server/src/__tests__/start-trace-agent-impl.test.ts index de2f5206..9875f836 100644 --- a/packages/wonder-stuff-render-server/src/__tests__/start-trace-agent-impl.test.ts +++ b/packages/wonder-stuff-render-server/src/__tests__/start-trace-agent-impl.test.ts @@ -8,7 +8,9 @@ jest.mock("@khanacademy/wonder-stuff-server"); describe("#startTraceAgent", () => { it("should start the trace agent as disabled when not in production", () => { // Arrange - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("development"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Development, + ); const startSpy = jest.spyOn(TraceAgent, "start"); // Act @@ -20,7 +22,9 @@ describe("#startTraceAgent", () => { it("should start the trace agent as enabled when in production", () => { // Arrange - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("production"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Production, + ); const startSpy = jest.spyOn(TraceAgent, "start"); // Act @@ -33,7 +37,9 @@ describe("#startTraceAgent", () => { it("should return the tracer", () => { // Arrange const pretendTracer = {} as any; - jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue("production"); + jest.spyOn(WSServer, "getRuntimeMode").mockReturnValue( + WSServer.Runtime.Production, + ); jest.spyOn(TraceAgent, "start").mockReturnValue(pretendTracer); // Act diff --git a/packages/wonder-stuff-server/src/middleware/__tests__/request-authentication.test.ts b/packages/wonder-stuff-server/src/middleware/__tests__/request-authentication.test.ts index 0709e8f9..aa7be462 100644 --- a/packages/wonder-stuff-server/src/middleware/__tests__/request-authentication.test.ts +++ b/packages/wonder-stuff-server/src/middleware/__tests__/request-authentication.test.ts @@ -3,12 +3,13 @@ import {secret} from "@khanacademy/wonder-stuff-core"; import * as GetRuntimeMode from "../../get-runtime-mode"; import * as GetLogger from "../../get-logger"; import {requestAuthentication} from "../request-authentication"; +import {Runtime} from "../../types"; describe("#requestAuthentication", () => { describe("when not in production", () => { beforeEach(() => { jest.spyOn(GetRuntimeMode, "getRuntimeMode").mockReturnValue( - "development", + Runtime.Development, ); }); @@ -193,7 +194,7 @@ describe("#requestAuthentication", () => { describe("when in production", () => { beforeEach(() => { jest.spyOn(GetRuntimeMode, "getRuntimeMode").mockReturnValue( - "production", + Runtime.Production, ); }); diff --git a/packages/wonder-stuff-server/src/middleware/wrap-with-middleware.ts b/packages/wonder-stuff-server/src/middleware/wrap-with-middleware.ts index fa37586c..4c8c63ad 100644 --- a/packages/wonder-stuff-server/src/middleware/wrap-with-middleware.ts +++ b/packages/wonder-stuff-server/src/middleware/wrap-with-middleware.ts @@ -1,8 +1,7 @@ import express from "express"; import type {Application} from "express"; import * as lw from "@google-cloud/logging-winston"; -import type {Logger, RequestAuthentication, RuntimeValue} from "../types"; -import {Runtime} from "../types"; +import {Logger, RequestAuthentication, Runtime} from "../types"; import {attachAppEngineRequestID} from "./attach-app-engine-request-id"; import {commonServiceRoutes} from "./common-service-routes"; import {defaultErrorLogging} from "./default-error-logging"; @@ -13,7 +12,7 @@ import {requestAuthentication} from "./request-authentication"; export const wrapWithMiddleware = async ( app: Application, logger: Logger, - mode: RuntimeValue, + mode: Runtime, requestAuthOptions?: RequestAuthentication, ): Promise => { // Setup the middleware around the app. diff --git a/packages/wonder-stuff-server/src/types.ts b/packages/wonder-stuff-server/src/types.ts index 80664348..38b171e4 100644 --- a/packages/wonder-stuff-server/src/types.ts +++ b/packages/wonder-stuff-server/src/types.ts @@ -24,14 +24,11 @@ export type Logger = WinstonLogger; /** * The runtime modes that a gateway can run under. */ -// TODO(FEI-5001): Replace with TS enum -export const Runtime = { - Production: "production" as const, - Development: "development" as const, - Test: "test" as const, -} as const; - -export type RuntimeValue = (typeof Runtime)[keyof typeof Runtime]; +export enum Runtime { + Production = "production", + Development = "development", + Test = "test", +} /** * Options to configure logging. @@ -40,7 +37,7 @@ export type LoggingOptions = { /** * The runtime mode. */ - mode: RuntimeValue; + mode: Runtime; /** * Log only if the level of a logged entry is less than or equal to this * level. Enables filtering out of debug message in production, for example. @@ -100,7 +97,7 @@ export type ServerOptions = { /** * What runtime mode the server is running under. */ - readonly mode: RuntimeValue; + readonly mode: Runtime; /** * Optional value in milliseconds for keepalive timeout of the server. * For running in Google Cloud, this should be higher than the load