Skip to content

Commit

Permalink
[api] adopt ESM throughout (#3464)
Browse files Browse the repository at this point in the history
  • Loading branch information
freemvmt authored Aug 9, 2024
1 parent d2b94f1 commit 16d71e8
Show file tree
Hide file tree
Showing 197 changed files with 962 additions and 796 deletions.
1 change: 1 addition & 0 deletions api.planx.uk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Development notes:

- if you need to test or pull new changes from @opensystemslab/planx-document-templates or @opensystemslab/planx-core, make sure to update the commit hash in package.json first
- you can also use `pnpm link {{local relative path to @opensystemslab/planx-document-templates or @opensystemslab/planx-core}}` to manage local development changes these packages without having to reinstall. If you do this, remember to also run `pnpm unlink` to unlink the local directory and then also update the commit hash to point to the most recent version of the package.
- If you want to test particular files directly (e.g. `pnpm jest server.test.js`), note that since we now treat all files as ES modules, you'll need to export `NODE_OPTIONS="--experimental-vm-modules"` (or include it in every such command).

## Prior art

Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/airbrake.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Notifier } from "@airbrake/node";
import { isLiveEnv } from "./helpers";
import { isLiveEnv } from "./helpers.js";

const airbrake =
isLiveEnv() &&
Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/client/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CoreDomainClient } from "@opensystemslab/planx-core";
import { getClient } from ".";
import { userContext } from "../modules/auth/middleware";
import { getJWT } from "../tests/mockJWT";
import { getClient } from "./index.js";
import { userContext } from "../modules/auth/middleware.js";
import { getJWT } from "../tests/mockJWT.js";

test("getClient() throws an error if a store is not set", () => {
expect(() => getClient()).toThrow();
Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CoreDomainClient } from "@opensystemslab/planx-core";
import { userContext } from "../modules/auth/middleware";
import { ServerError } from "../errors";
import { buildJWTForAPIRole } from "../modules/auth/service";
import { userContext } from "../modules/auth/middleware.js";
import { ServerError } from "../errors/index.js";
import { buildJWTForAPIRole } from "../modules/auth/service.js";

/**
* Connects to Hasura using the "api" role
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { ServerError } from "./ServerError";
export { ServerError } from "./serverError.js";
File renamed without changes.
6 changes: 3 additions & 3 deletions api.planx.uk/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
getFlowData,
getFormattedEnvironment,
isLiveEnv,
} from "./helpers";
import { queryMock } from "./tests/graphqlQueryMock";
} from "./helpers.js";
import { queryMock } from "./tests/graphqlQueryMock.js";
import {
childFlow,
draftParentFlow,
flattenedParentFlow,
} from "./tests/mocks/validateAndPublishMocks";
} from "./tests/mocks/validateAndPublishMocks.js";

describe("getFormattedEnvironment() function", () => {
const OLD_ENV = process.env;
Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { gql } from "graphql-request";
import { capitalize } from "lodash";
import { Flow, Node } from "./types";
import capitalize from "lodash/capitalize.js";
import { Flow, Node } from "./types.js";
import { ComponentType, FlowGraph } from "@opensystemslab/planx-core/types";
import { $public, getClient } from "./client";
import { $public, getClient } from "./client/index.js";

export interface FlowData {
slug: string;
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import server from "./server";
import server from "./server.js";

const PORT = process.env.PORT || 8001;

Expand Down
27 changes: 22 additions & 5 deletions api.planx.uk/jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
export default {
import type { JestConfigWithTsJest } from "ts-jest";

const config: JestConfigWithTsJest = {
// ts-jest presets are deprecated, so we prefer to give an explicit manual config
testEnvironment: "node",
preset: "ts-jest",
transform: {
"^.+\\.js$": [
"esbuild-jest",
// esbuild-jest transformer is unmaintained and can't handle ts-with-esm, so we stick to ts-jest
// TODO: if tests are too slow, consider swapping out for @swc/jest
"^.+\\.[jt]s$": [
"ts-jest",
{
sourcemap: true,
useESM: true,
// we need a separate module/moduleResolution config for tests (jest v30 may fix this)
tsconfig: "tsconfig.test.json",
},
],
},
// mime v4 (which moves to pure ESM) may still have commonJS traces, so we transform it
transformIgnorePatterns: ["node_modules\\/.pnpm\\/(?!(mime))"],
testPathIgnorePatterns: ["dist/*"],
setupFilesAfterEnv: ["./jest.setup.js"],
// handle .ts files first, as ESM modules, and remove .js from imports for jest
moduleFileExtensions: ["ts", "js", "json"],
extensionsToTreatAsEsm: [".ts"],
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
// set up coverage collection
collectCoverage: true,
coverageThreshold: {
global: {
Expand All @@ -20,3 +35,5 @@ export default {
coverageReporters: ["lcov", "text-summary"],
coverageDirectory: "./coverage",
};

export default config;
2 changes: 1 addition & 1 deletion api.planx.uk/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dotenv from "dotenv";
import { queryMock } from "./tests/graphqlQueryMock";
import { queryMock } from "./tests/graphqlQueryMock.js";

dotenv.config({
path: "./.env.test",
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/lib/hasura/metadata/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createScheduledEvent, RequiredScheduledEventArgs } from ".";
import { createScheduledEvent, RequiredScheduledEventArgs } from "./index.js";
import Axios, { AxiosError } from "axios";

jest.mock("axios", () => ({
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/lib/hasura/metadata/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ const createScheduledEvent = async (args: RequiredScheduledEventArgs) => {
}
};

export { createScheduledEvent, RequiredScheduledEventArgs };
export { createScheduledEvent, type RequiredScheduledEventArgs };
2 changes: 1 addition & 1 deletion api.planx.uk/lib/hasura/schema/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { runSQL } from ".";
import { runSQL } from "./index.js";
import Axios, { AxiosError } from "axios";

jest.mock("axios", () => ({
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/lib/notify/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { sendEmail } from ".";
import { sendEmail } from "./index.js";
import { NotifyClient } from "notifications-node-client";
import { NotifyConfig } from "../../types";
import { NotifyConfig } from "../../types.js";

jest.mock("notifications-node-client");

Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/lib/notify/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NotifyClient } from "notifications-node-client";
import { softDeleteSession } from "../../modules/saveAndReturn/service/utils";
import { NotifyConfig } from "../../types";
import { $api, $public } from "../../client";
import { softDeleteSession } from "../../modules/saveAndReturn/service/utils.js";
import { NotifyConfig } from "../../types.js";
import { $api, $public } from "../../client/index.js";

const notifyClient = new NotifyClient(process.env.GOVUK_NOTIFY_API_KEY);

Expand Down
14 changes: 7 additions & 7 deletions api.planx.uk/modules/admin/routes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Router } from "express";
import { usePlatformAdminAuth } from "../auth/middleware";
import { getOneAppXML } from "./session/oneAppXML";
import { getCSVData, getRedactedCSVData } from "./session/csv";
import { getHTMLExport, getRedactedHTMLExport } from "./session/html";
import { generateZip } from "./session/zip";
import { getSessionSummary } from "./session/summary";
import { getDigitalPlanningApplicationPayload } from "./session/digitalPlanningData";
import { usePlatformAdminAuth } from "../auth/middleware.js";
import { getOneAppXML } from "./session/oneAppXML.js";
import { getCSVData, getRedactedCSVData } from "./session/csv.js";
import { getHTMLExport, getRedactedHTMLExport } from "./session/html.js";
import { generateZip } from "./session/zip.js";
import { getSessionSummary } from "./session/summary.js";
import { getDigitalPlanningApplicationPayload } from "./session/digitalPlanningData.js";

const router = Router();

Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/csv.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import supertest from "supertest";
import app from "../../../server";
import { authHeader } from "../../../tests/mockJWT";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/csv`;
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/admin/session/csv.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { stringify } from "csv-stringify";
import { NextFunction, Request, Response } from "express";
import { $api } from "../../../client";
import { $api } from "../../../client/index.js";

/**
* @swagger
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import supertest from "supertest";
import app from "../../../server";
import { authHeader } from "../../../tests/mockJWT";
import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";
import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks.js";

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/digital-planning-application`;
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/admin/session/digitalPlanningData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NextFunction, Request, Response } from "express";
import { $api } from "../../../client";
import { $api } from "../../../client/index.js";

/**
* @swagger
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/html.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import supertest from "supertest";
import app from "../../../server";
import { authHeader } from "../../../tests/mockJWT";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/html`;
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/admin/session/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type {
DrawBoundaryUserAction,
PlanXExportData,
} from "@opensystemslab/planx-core/types";
import { $api } from "../../../client/index.js";
import type { RequestHandler } from "express";
import { $api } from "../../../client";

type HTMLExportHandler = RequestHandler<{ sessionId: string }, string>;

Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/oneAppXML.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import supertest from "supertest";
import app from "../../../server";
import { authHeader } from "../../../tests/mockJWT";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/xml`;
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/admin/session/oneAppXML.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response, NextFunction } from "express";
import { $api } from "../../../client";
import { $api } from "../../../client/index.js";

/**
* @swagger
Expand Down
6 changes: 3 additions & 3 deletions api.planx.uk/modules/admin/session/summary.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import supertest from "supertest";
import app from "../../../server";
import { queryMock } from "../../../tests/graphqlQueryMock";
import { authHeader } from "../../../tests/mockJWT";
import app from "../../../server.js";
import { queryMock } from "../../../tests/graphqlQueryMock.js";
import { authHeader } from "../../../tests/mockJWT.js";

const endpoint = (strings: TemplateStringsArray) =>
`/admin/session/${strings[0]}/summary`;
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
import { NextFunction, Request, Response } from "express";
import { gql } from "graphql-request";

import { Breadcrumb, Flow, LowCalSession, Passport } from "../../../types";
import { $api } from "../../../client";
import { Breadcrumb, Flow, LowCalSession, Passport } from "../../../types.js";
import { $api } from "../../../client/index.js";

/**
* @swagger
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/admin/session/zip.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import supertest from "supertest";
import app from "../../../server";
import { authHeader } from "../../../tests/mockJWT";
import app from "../../../server.js";
import { authHeader } from "../../../tests/mockJWT.js";

jest.mock("../../send/utils/exportZip", () => ({
buildSubmissionExportZip: jest.fn().mockResolvedValue({
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/admin/session/zip.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NextFunction, Request, Response } from "express";
import { buildSubmissionExportZip } from "../../send/utils/exportZip";
import { buildSubmissionExportZip } from "../../send/utils/exportZip.js";

/**
* @swagger
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/analytics/controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from "zod";
import { trackAnalyticsLogExit } from "./service";
import { ValidatedRequestHandler } from "../../shared/middleware/validate";
import { trackAnalyticsLogExit } from "./service.js";
import { ValidatedRequestHandler } from "../../shared/middleware/validate.js";

export const logAnalyticsSchema = z.object({
query: z.object({
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/analytics/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import supertest from "supertest";
import app from "../../server";
import { queryMock } from "../../tests/graphqlQueryMock";
import app from "../../server.js";
import { queryMock } from "../../tests/graphqlQueryMock.js";

describe("Logging analytics", () => {
beforeEach(() => {
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/analytics/routes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { validate } from "./../../shared/middleware/validate";
import { validate } from "./../../shared/middleware/validate.js";
import { Router } from "express";
import {
logAnalyticsSchema,
logUserExitController,
logUserResumeController,
} from "./controller";
} from "./controller.js";

const router = Router();

Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/analytics/service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { gql } from "graphql-request";
import { $public } from "../../client";
import { $public } from "../../client/index.js";

interface UpdateAnalyticsLogUserExit {
analyticsLog: {
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/auth/middleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isEqual } from "./middleware";
import { isEqual } from "./middleware.js";

describe("isEqual() helper function", () => {
it("handles undefined secrets", () => {
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/auth/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import crypto from "crypto";
import assert from "assert";
import { ServerError } from "../../errors";
import { Template } from "../../lib/notify";
import { ServerError } from "../../errors/index.js";
import { Template } from "../../lib/notify/index.js";
import { expressjwt } from "express-jwt";

import passport from "passport";
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/auth/routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Router } from "express";
import * as Middleware from "./middleware";
import * as Controller from "./controller";
import * as Middleware from "./middleware.js";
import * as Controller from "./controller.js";

const router = Router();

Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/auth/service.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { checkUserCanAccessEnv } from "./service";
import { checkUserCanAccessEnv } from "./service.js";

const mockIsStagingOnly = jest.fn();

Expand Down
9 changes: 4 additions & 5 deletions api.planx.uk/modules/auth/service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { sign } from "jsonwebtoken";
import { $api } from "../../client";
import jwt from "jsonwebtoken";
import { $api } from "../../client/index.js";
import { User, Role } from "@opensystemslab/planx-core/types";

export const buildJWT = async (email: string): Promise<string | undefined> => {
Expand All @@ -13,12 +13,11 @@ export const buildJWT = async (email: string): Promise<string | undefined> => {
"https://hasura.io/jwt/claims": generateHasuraClaimsForUser(user),
};

const jwt = sign(data, process.env.JWT_SECRET!);
return jwt;
return jwt.sign(data, process.env.JWT_SECRET!);
};

export const buildJWTForAPIRole = () =>
sign(
jwt.sign(
{
"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles": ["api"],
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/modules/auth/strategy/google.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import { buildJWT } from "../service";
import { buildJWT } from "../service.js";

export const googleStrategy = new GoogleStrategy(
{
Expand Down
Loading

0 comments on commit 16d71e8

Please sign in to comment.