From d2b94f17e6c93e85a694267aae659fd3f7895169 Mon Sep 17 00:00:00 2001 From: Dan G Date: Fri, 9 Aug 2024 13:01:18 +0100 Subject: [PATCH 01/12] [chore] bump passport to 0.7.0 (#3502) --- api.planx.uk/modules/test/controller.ts | 7 +++ api.planx.uk/modules/test/docs.yaml | 28 +++++++++++ api.planx.uk/modules/test/routes.test.ts | 14 ++++++ api.planx.uk/modules/test/routes.ts | 9 ++++ api.planx.uk/package.json | 2 +- api.planx.uk/pnpm-lock.yaml | 63 ++++++++++++------------ api.planx.uk/server.ts | 6 +++ api.planx.uk/session.ts | 12 +++++ 8 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 api.planx.uk/modules/test/controller.ts create mode 100644 api.planx.uk/modules/test/docs.yaml create mode 100644 api.planx.uk/modules/test/routes.test.ts create mode 100644 api.planx.uk/modules/test/routes.ts create mode 100644 api.planx.uk/session.ts diff --git a/api.planx.uk/modules/test/controller.ts b/api.planx.uk/modules/test/controller.ts new file mode 100644 index 0000000000..4ddda88468 --- /dev/null +++ b/api.planx.uk/modules/test/controller.ts @@ -0,0 +1,7 @@ +import { RequestHandler } from "express"; + +export const testSessionMethods: RequestHandler = (req, res) => { + const hasRegenerate = typeof req.session?.regenerate === "function"; + const hasSave = typeof req.session?.save === "function"; + res.status(200).json({ hasRegenerate, hasSave }); +}; diff --git a/api.planx.uk/modules/test/docs.yaml b/api.planx.uk/modules/test/docs.yaml new file mode 100644 index 0000000000..f8f960a65f --- /dev/null +++ b/api.planx.uk/modules/test/docs.yaml @@ -0,0 +1,28 @@ +openapi: 3.1.0 +info: + title: Planâś• API + version: 0.1.0 +tags: + - name: test + description: Requests for testing purposes +paths: + /test-session: + get: + summary: Test req.session object + description: Confirms session has necessary dummy methods registered + tags: ["test"] + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + hasRegenerate: + type: boolean + hasSave: + type: boolean + example: + hasRegenerate: true + hasSave: true diff --git a/api.planx.uk/modules/test/routes.test.ts b/api.planx.uk/modules/test/routes.test.ts new file mode 100644 index 0000000000..f951b9816c --- /dev/null +++ b/api.planx.uk/modules/test/routes.test.ts @@ -0,0 +1,14 @@ +import supertest from "supertest"; +import app from "../../server"; + +describe("Session setup", () => { + test("adds dummy methods to req.session to avoid passport/cookie-session incompatibility issue", async () => { + await supertest(app) + .get("/test-session") + .expect(200) + .then((res) => { + expect(res.body.hasRegenerate).toBe(true); + expect(res.body.hasSave).toBe(true); + }); + }); +}); diff --git a/api.planx.uk/modules/test/routes.ts b/api.planx.uk/modules/test/routes.ts new file mode 100644 index 0000000000..43fd8dacaf --- /dev/null +++ b/api.planx.uk/modules/test/routes.ts @@ -0,0 +1,9 @@ +import { Router } from "express"; +import { testSessionMethods } from "./controller"; + +const router = Router(); + +// in order to test the session setup, we need a dedicated test route +router.get("/test-session", testSessionMethods); + +export default router; diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index 500b8e5dc0..dd91afb7e9 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -39,7 +39,7 @@ "multer": "^1.4.5-lts.1", "nanoid": "^3.3.7", "notifications-node-client": "^8.2.0", - "passport": "^0.5.3", + "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0", "pino-noir": "^2.2.1", "slack-notify": "^2.0.7", diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index c927a676e1..7292539127 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -116,8 +116,8 @@ dependencies: specifier: ^8.2.0 version: 8.2.0 passport: - specifier: ^0.5.3 - version: 0.5.3 + specifier: ^0.7.0 + version: 0.7.0 passport-google-oauth20: specifier: ^2.0.0 version: 2.0.0 @@ -315,8 +315,8 @@ packages: '@jridgewell/trace-mapping': 0.3.25 dev: true - /@apidevtools/json-schema-ref-parser@11.6.4: - resolution: {integrity: sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==} + /@apidevtools/json-schema-ref-parser@11.7.0: + resolution: {integrity: sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==} engines: {node: '>= 16'} dependencies: '@jsdevtools/ono': 7.1.3 @@ -1571,7 +1571,7 @@ packages: '@babel/runtime': 7.25.0 '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1)(react@18.3.1) '@mui/types': 7.2.15 - '@mui/utils': 5.16.5(react@18.3.1) + '@mui/utils': 5.16.6(react@18.3.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 @@ -1579,12 +1579,12 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@mui/core-downloads-tracker@5.16.5: - resolution: {integrity: sha512-ziFn1oPm6VjvHQcdGcAO+fXvOQEgieIj0BuSqcltFU+JXIxjPdVYNTdn2HU7/Ak5Gabk6k2u7+9PV7oZ6JT5sA==} + /@mui/core-downloads-tracker@5.16.6: + resolution: {integrity: sha512-kytg6LheUG42V8H/o/Ptz3olSO5kUXW9zF0ox18VnblX6bO2yif1FPItgc3ey1t5ansb1+gbe7SatntqusQupg==} dev: false - /@mui/material@5.16.5(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-eQrjjg4JeczXvh/+8yvJkxWIiKNHVptB/AqpsKfZBWp5mUD5U3VsjODMuUl1K2BSq0omV3CiO/mQmWSSMKSmaA==} + /@mui/material@5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1607,10 +1607,10 @@ packages: '@babel/runtime': 7.25.0 '@emotion/react': 11.13.0(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(react@18.3.1) - '@mui/core-downloads-tracker': 5.16.5 - '@mui/system': 5.16.5(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) + '@mui/core-downloads-tracker': 5.16.6 + '@mui/system': 5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@mui/types': 7.2.15 - '@mui/utils': 5.16.5(react@18.3.1) + '@mui/utils': 5.16.6(react@18.3.1) '@popperjs/core': 2.11.8 '@types/react-transition-group': 4.4.10 clsx: 2.1.1 @@ -1622,8 +1622,8 @@ packages: react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) dev: false - /@mui/private-theming@5.16.5(react@18.3.1): - resolution: {integrity: sha512-CSLg0YkpDqg0aXOxtjo3oTMd3XWMxvNb5d0v4AYVqwOltU8q6GvnZjhWyCLjGSCrcgfwm6/VDjaKLPlR14wxIA==} + /@mui/private-theming@5.16.6(react@18.3.1): + resolution: {integrity: sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1635,13 +1635,13 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.0 - '@mui/utils': 5.16.5(react@18.3.1) + '@mui/utils': 5.16.6(react@18.3.1) prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/styled-engine@5.16.4(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1): - resolution: {integrity: sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==} + /@mui/styled-engine@5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1): + resolution: {integrity: sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -1664,8 +1664,8 @@ packages: react: 18.3.1 dev: false - /@mui/system@5.16.5(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1): - resolution: {integrity: sha512-uzIUGdrWddUx1HPxW4+B2o4vpgKyRxGe/8BxbfXVDPNPHX75c782TseoCnR/VyfnZJfqX87GcxDmnZEE1c031g==} + /@mui/system@5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1): + resolution: {integrity: sha512-5xgyJjBIMPw8HIaZpfbGAaFYPwImQn7Nyh+wwKWhvkoIeDosQ1ZMVrbTclefi7G8hNmqhip04duYwYpbBFnBgw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1685,10 +1685,10 @@ packages: '@babel/runtime': 7.25.0 '@emotion/react': 11.13.0(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(react@18.3.1) - '@mui/private-theming': 5.16.5(react@18.3.1) - '@mui/styled-engine': 5.16.4(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) + '@mui/private-theming': 5.16.6(react@18.3.1) + '@mui/styled-engine': 5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@mui/types': 7.2.15 - '@mui/utils': 5.16.5(react@18.3.1) + '@mui/utils': 5.16.6(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -1704,8 +1704,8 @@ packages: optional: true dev: false - /@mui/utils@5.16.5(react@18.3.1): - resolution: {integrity: sha512-CwhcA9y44XwK7k2joL3Y29mRUnoBt+gOZZdGyw7YihbEwEErJYBtDwbZwVgH68zAljGe/b+Kd5bzfl63Gi3R2A==} + /@mui/utils@5.16.6(react@18.3.1): + resolution: {integrity: sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1978,8 +1978,8 @@ packages: dependencies: undici-types: 5.26.5 - /@types/node@20.14.13: - resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} + /@types/node@20.14.14: + resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==} dependencies: undici-types: 5.26.5 dev: false @@ -3468,7 +3468,7 @@ packages: resolution: {integrity: sha512-4SbcbedPXTciySXiSnNNLuJXpvxFe5nqivbiEHXyL8P/w0wx2uW7YXNjnYgjW0e2e6vy+L/tMISU/oAiXCl57Q==} engines: {node: '>=10'} dependencies: - '@types/node': 20.14.13 + '@types/node': 20.14.14 jszip: 3.10.1 nanoid: 5.0.7 xml: 1.0.1 @@ -5607,7 +5607,7 @@ packages: engines: {node: '>=16.0.0'} hasBin: true dependencies: - '@apidevtools/json-schema-ref-parser': 11.6.4 + '@apidevtools/json-schema-ref-parser': 11.7.0 '@types/json-schema': 7.0.15 '@types/lodash': 4.17.0 cli-color: 2.0.4 @@ -6491,12 +6491,13 @@ packages: engines: {node: '>= 0.4.0'} dev: false - /passport@0.5.3: - resolution: {integrity: sha512-gGc+70h4gGdBWNsR3FuV3byLDY6KBTJAIExGFXTpQaYfbbcHCBlRRKx7RBQSpqEqc5Hh2qVzRs7ssvSfOpkUEA==} + /passport@0.7.0: + resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} engines: {node: '>= 0.4.0'} dependencies: passport-strategy: 1.0.0 pause: 0.0.1 + utils-merge: 1.0.1 dev: false /path-exists@4.0.0: @@ -8269,7 +8270,7 @@ packages: '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(react@18.3.1) '@formatjs/intl-listformat': 7.5.7 '@mui/base': 5.0.0-beta.40(react-dom@18.3.1)(react@18.3.1) - '@mui/material': 5.16.5(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1) + '@mui/material': 5.16.6(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1) ajv: 8.17.1 ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0-rc.12 diff --git a/api.planx.uk/server.ts b/api.planx.uk/server.ts index c9f99f93c0..068d86818e 100644 --- a/api.planx.uk/server.ts +++ b/api.planx.uk/server.ts @@ -14,6 +14,7 @@ import helmet from "helmet"; import { ServerError } from "./errors"; import airbrake from "./airbrake"; import { apiLimiter } from "./rateLimit"; +import { registerSessionStubs } from "./session"; import { googleStrategy } from "./modules/auth/strategy/google"; import authRoutes from "./modules/auth/routes"; import teamRoutes from "./modules/team/routes"; @@ -30,6 +31,7 @@ import fileRoutes from "./modules/file/routes"; import gisRoutes from "./modules/gis/routes"; import payRoutes from "./modules/pay/routes"; import sendRoutes from "./modules/send/routes"; +import testRoutes from "./modules/test/routes"; import { useSwaggerDocs } from "./docs"; import { Role } from "@opensystemslab/planx-core/types"; @@ -116,6 +118,9 @@ app.use( }), ); +// register stubs after cookieSession middleware initialisation +app.use(registerSessionStubs); + passport.use("google", googleStrategy); passport.serializeUser(function (user, cb) { @@ -145,6 +150,7 @@ app.use(sendRoutes); app.use(teamRoutes); app.use(userRoutes); app.use(webhookRoutes); +app.use(testRoutes); const errorHandler: ErrorRequestHandler = (errorObject, _req, res, _next) => { const { status = 500, message = "Something went wrong" } = (() => { diff --git a/api.planx.uk/session.ts b/api.planx.uk/session.ts new file mode 100644 index 0000000000..518d35190f --- /dev/null +++ b/api.planx.uk/session.ts @@ -0,0 +1,12 @@ +import { RequestHandler } from "http-proxy-middleware"; + +// this middleware registers dummy methods on req.session to resolve passport/cookie-session incompatibility +export const registerSessionStubs: RequestHandler = (req, _res, next): void => { + if (req.session && !req.session.regenerate) { + req.session.regenerate = (cb: (err?: Error) => void) => cb(); + } + if (req.session && !req.session.save) { + req.session.save = (cb: (err?: Error) => void) => cb(); + } + next(); +}; From 16d71e82382724dd2adb2935c9c5303a3a8d0c01 Mon Sep 17 00:00:00 2001 From: Dan G Date: Fri, 9 Aug 2024 13:47:13 +0100 Subject: [PATCH 02/12] [api] adopt ESM throughout (#3464) --- api.planx.uk/README.md | 1 + api.planx.uk/airbrake.ts | 2 +- api.planx.uk/client/index.test.ts | 6 +- api.planx.uk/client/index.ts | 6 +- api.planx.uk/errors/index.ts | 2 +- .../errors/{ServerError.ts => serverError.ts} | 0 api.planx.uk/helpers.test.ts | 6 +- api.planx.uk/helpers.ts | 6 +- api.planx.uk/index.ts | 2 +- api.planx.uk/jest.config.ts | 27 +- api.planx.uk/jest.setup.js | 2 +- .../lib/hasura/metadata/index.test.ts | 2 +- api.planx.uk/lib/hasura/metadata/index.ts | 2 +- api.planx.uk/lib/hasura/schema/index.test.ts | 2 +- api.planx.uk/lib/notify/index.test.ts | 4 +- api.planx.uk/lib/notify/index.ts | 6 +- api.planx.uk/modules/admin/routes.ts | 14 +- .../modules/admin/session/csv.test.ts | 4 +- api.planx.uk/modules/admin/session/csv.ts | 2 +- .../admin/session/digitalPlanningData.test.ts | 6 +- .../admin/session/digitalPlanningData.ts | 2 +- .../modules/admin/session/html.test.ts | 4 +- api.planx.uk/modules/admin/session/html.ts | 2 +- .../modules/admin/session/oneAppXML.test.ts | 4 +- .../modules/admin/session/oneAppXML.ts | 2 +- .../modules/admin/session/summary.test.ts | 6 +- api.planx.uk/modules/admin/session/summary.ts | 4 +- .../modules/admin/session/zip.test.ts | 4 +- api.planx.uk/modules/admin/session/zip.ts | 2 +- api.planx.uk/modules/analytics/controller.ts | 4 +- api.planx.uk/modules/analytics/index.test.ts | 4 +- api.planx.uk/modules/analytics/routes.ts | 4 +- api.planx.uk/modules/analytics/service.ts | 2 +- api.planx.uk/modules/auth/middleware.test.ts | 2 +- api.planx.uk/modules/auth/middleware.ts | 4 +- api.planx.uk/modules/auth/routes.ts | 4 +- api.planx.uk/modules/auth/service.test.ts | 2 +- api.planx.uk/modules/auth/service.ts | 9 +- api.planx.uk/modules/auth/strategy/google.ts | 2 +- api.planx.uk/modules/file/controller.ts | 10 +- api.planx.uk/modules/file/file.test.ts | 6 +- api.planx.uk/modules/file/routes.ts | 6 +- .../modules/file/service/deleteFile.ts | 4 +- api.planx.uk/modules/file/service/getFile.ts | 4 +- .../modules/file/service/uploadFile.ts | 10 +- .../modules/file/service/utils.test.ts | 2 +- api.planx.uk/modules/file/service/utils.ts | 4 +- .../modules/flows/copyFlow/controller.ts | 8 +- .../modules/flows/copyFlow/copyFlow.test.ts | 10 +- .../modules/flows/copyFlow/service.ts | 4 +- .../flows/copyFlowAsPortal/controller.ts | 8 +- .../copyFlowAsPortal/copyPortalAsFlow.test.ts | 8 +- .../modules/flows/copyFlowAsPortal/service.ts | 4 +- .../flows/downloadSchema/controller.ts | 6 +- .../modules/flows/downloadSchema/service.ts | 2 +- .../modules/flows/findReplace/controller.ts | 8 +- .../flows/findReplace/findReplace.test.ts | 8 +- .../modules/flows/findReplace/service.ts | 6 +- .../modules/flows/flattenFlow/controller.ts | 6 +- .../flows/flattenFlow/flattenFlow.test.ts | 6 +- .../modules/flows/moveFlow/controller.ts | 6 +- .../modules/flows/moveFlow/moveFlow.test.ts | 6 +- .../modules/flows/moveFlow/service.ts | 4 +- .../modules/flows/publish/controller.ts | 6 +- .../modules/flows/publish/publish.test.ts | 10 +- api.planx.uk/modules/flows/publish/service.ts | 6 +- api.planx.uk/modules/flows/routes.ts | 23 +- .../modules/flows/validate/controller.ts | 6 +- .../flows/validate/service/fileTypes.ts | 6 +- .../modules/flows/validate/service/index.ts | 10 +- .../flows/validate/service/inviteToPay.ts | 4 +- .../flows/validate/service/projectTypes.ts | 6 +- .../flows/validate/service/sections.ts | 6 +- .../modules/flows/validate/validate.test.ts | 12 +- api.planx.uk/modules/gis/routes.ts | 6 +- .../modules/gis/service/article4Schema.ts | 2 +- .../gis/service/classifiedRoads.test.ts | 6 +- .../modules/gis/service/digitalLand.ts | 58 +- .../modules/gis/service/helpers.test.js | 2 +- api.planx.uk/modules/gis/service/index.js | 10 +- .../modules/gis/service/index.test.ts | 6 +- .../metadata/barkingAndDagenham.ts | 2 +- .../local_authorities/metadata/barnet.ts | 2 +- .../local_authorities/metadata/birmingham.ts | 2 +- .../metadata/buckinghamshire.ts | 2 +- .../local_authorities/metadata/camden.ts | 2 +- .../local_authorities/metadata/canterbury.ts | 2 +- .../local_authorities/metadata/doncaster.ts | 2 +- .../metadata/epsomAndEwell.ts | 2 +- .../local_authorities/metadata/gateshead.ts | 2 +- .../local_authorities/metadata/gloucester.ts | 2 +- .../local_authorities/metadata/lambeth.ts | 2 +- .../local_authorities/metadata/medway.ts | 2 +- .../local_authorities/metadata/newcastle.ts | 2 +- .../local_authorities/metadata/southwark.ts | 2 +- .../local_authorities/metadata/stAlbans.ts | 2 +- .../local_authorities/metadata/tewkesbury.ts | 2 +- .../metadata/westBerkshire.ts | 2 +- api.planx.uk/modules/misc/controller.ts | 2 +- api.planx.uk/modules/misc/routes.test.ts | 2 +- api.planx.uk/modules/misc/routes.ts | 4 +- .../modules/ordnanceSurvey/controller.ts | 2 +- .../ordnanceSurvey/ordnanceSurvey.test.ts | 4 +- api.planx.uk/modules/ordnanceSurvey/routes.ts | 2 +- api.planx.uk/modules/pay/controller.ts | 12 +- api.planx.uk/modules/pay/helpers.ts | 4 +- api.planx.uk/modules/pay/index.test.ts | 4 +- api.planx.uk/modules/pay/middleware.ts | 6 +- api.planx.uk/modules/pay/proxy.ts | 2 +- api.planx.uk/modules/pay/routes.ts | 10 +- .../createPaymentSendEvents.test.ts | 8 +- .../inviteToPay/createPaymentSendEvents.ts | 8 +- .../pay/service/inviteToPay/index.test.ts | 8 +- .../modules/pay/service/inviteToPay/index.ts | 6 +- .../pay/service/inviteToPay/paymentRequest.ts | 6 +- .../inviteToPay/sendConfirmationEmail.test.ts | 8 +- .../inviteToPay/sendConfirmationEmail.ts | 6 +- .../inviteToPay/sendPaymentEmail.test.ts | 6 +- .../service/inviteToPay/sendPaymentEmail.ts | 6 +- .../modules/pay/service/utils.test.ts | 2 +- api.planx.uk/modules/pay/service/utils.ts | 2 +- api.planx.uk/modules/pay/types.ts | 2 +- .../modules/saveAndReturn/controller.ts | 6 +- api.planx.uk/modules/saveAndReturn/routes.ts | 8 +- .../service/resumeApplication.test.ts | 10 +- .../service/resumeApplication.ts | 12 +- .../saveAndReturn/service/utils.test.ts | 6 +- .../modules/saveAndReturn/service/utils.ts | 10 +- .../service/validateSession.test.ts | 14 +- .../saveAndReturn/service/validateSession.ts | 10 +- api.planx.uk/modules/saveAndReturn/types.ts | 4 +- api.planx.uk/modules/send/bops/bops.test.ts | 6 +- api.planx.uk/modules/send/bops/bops.ts | 6 +- .../send/createSendEvents/controller.ts | 4 +- .../modules/send/createSendEvents/types.ts | 4 +- .../send/downloadApplicationFiles/index.ts | 4 +- api.planx.uk/modules/send/email/index.test.ts | 4 +- api.planx.uk/modules/send/email/index.ts | 8 +- api.planx.uk/modules/send/email/service.ts | 10 +- api.planx.uk/modules/send/idox/nexus.test.ts | 2 +- api.planx.uk/modules/send/idox/nexus.ts | 6 +- api.planx.uk/modules/send/routes.ts | 20 +- api.planx.uk/modules/send/s3/index.test.ts | 6 +- api.planx.uk/modules/send/s3/index.ts | 10 +- .../modules/send/uniform/uniform.test.ts | 2 +- api.planx.uk/modules/send/uniform/uniform.ts | 6 +- .../modules/send/utils/exportZip.test.ts | 8 +- api.planx.uk/modules/send/utils/exportZip.ts | 8 +- api.planx.uk/modules/send/utils/helpers.ts | 2 +- api.planx.uk/modules/sendEmail/controller.ts | 8 +- api.planx.uk/modules/sendEmail/index.test.ts | 6 +- api.planx.uk/modules/sendEmail/routes.ts | 10 +- api.planx.uk/modules/sendEmail/types.ts | 2 +- api.planx.uk/modules/team/controller.test.ts | 4 +- api.planx.uk/modules/team/controller.ts | 6 +- api.planx.uk/modules/team/routes.ts | 6 +- api.planx.uk/modules/team/service.test.ts | 6 +- api.planx.uk/modules/team/service.ts | 2 +- api.planx.uk/modules/test/routes.test.ts | 2 +- api.planx.uk/modules/test/routes.ts | 2 +- api.planx.uk/modules/user/controller.ts | 8 +- api.planx.uk/modules/user/index.test.ts | 6 +- api.planx.uk/modules/user/routes.ts | 6 +- api.planx.uk/modules/webhooks/controller.ts | 22 +- api.planx.uk/modules/webhooks/routes.ts | 16 +- .../service/analyzeSessions/index.test.ts | 6 +- .../webhooks/service/analyzeSessions/index.ts | 8 +- .../analyzeSessions/operations.test.ts | 4 +- .../service/analyzeSessions/operations.ts | 4 +- .../service/lowcalSessionEvents/index.test.ts | 4 +- .../service/lowcalSessionEvents/index.ts | 6 +- .../service/lowcalSessionEvents/schema.ts | 4 +- .../paymentRequestEvents/index.test.ts | 6 +- .../service/paymentRequestEvents/index.ts | 6 +- .../service/paymentRequestEvents/schema.ts | 4 +- .../sanitiseApplicationData/index.test.ts | 4 +- .../service/sanitiseApplicationData/index.ts | 6 +- .../operations.test.ts | 8 +- .../sanitiseApplicationData/operations.ts | 8 +- .../service/sanitiseApplicationData/types.ts | 2 +- .../service/sendNotification/index.test.ts | 6 +- .../service/sendNotification/index.ts | 4 +- .../service/sendNotification/types.ts | 4 +- .../webhooks/service/validateInput/schema.ts | 4 +- .../service/validateInput/utils.test.ts | 2 +- .../webhooks/service/validateInput/utils.ts | 8 +- .../validateInput/validateInput.test.ts | 2 +- api.planx.uk/package.json | 25 +- api.planx.uk/pnpm-lock.yaml | 575 ++++++++++-------- api.planx.uk/server.test.js | 2 +- api.planx.uk/server.ts | 50 +- api.planx.uk/tests/mocks/inviteToPayData.ts | 2 +- api.planx.uk/tests/mocks/inviteToPayMocks.ts | 2 +- .../tests/mocks/saveAndReturnMocks.ts | 2 +- api.planx.uk/tsconfig.json | 12 +- api.planx.uk/tsconfig.test.json | 7 + api.planx.uk/types.ts | 7 +- 197 files changed, 962 insertions(+), 796 deletions(-) rename api.planx.uk/errors/{ServerError.ts => serverError.ts} (100%) create mode 100644 api.planx.uk/tsconfig.test.json diff --git a/api.planx.uk/README.md b/api.planx.uk/README.md index e9adb7dc07..033c944ba0 100644 --- a/api.planx.uk/README.md +++ b/api.planx.uk/README.md @@ -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 diff --git a/api.planx.uk/airbrake.ts b/api.planx.uk/airbrake.ts index 2a4a3449f6..8b191188a0 100644 --- a/api.planx.uk/airbrake.ts +++ b/api.planx.uk/airbrake.ts @@ -1,5 +1,5 @@ import { Notifier } from "@airbrake/node"; -import { isLiveEnv } from "./helpers"; +import { isLiveEnv } from "./helpers.js"; const airbrake = isLiveEnv() && diff --git a/api.planx.uk/client/index.test.ts b/api.planx.uk/client/index.test.ts index 7d8e1978f6..adc71fed0c 100644 --- a/api.planx.uk/client/index.test.ts +++ b/api.planx.uk/client/index.test.ts @@ -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(); diff --git a/api.planx.uk/client/index.ts b/api.planx.uk/client/index.ts index 6fb02ff19d..28ea7261b4 100644 --- a/api.planx.uk/client/index.ts +++ b/api.planx.uk/client/index.ts @@ -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 diff --git a/api.planx.uk/errors/index.ts b/api.planx.uk/errors/index.ts index d79eccd800..0258fbafd4 100644 --- a/api.planx.uk/errors/index.ts +++ b/api.planx.uk/errors/index.ts @@ -1 +1 @@ -export { ServerError } from "./ServerError"; +export { ServerError } from "./serverError.js"; diff --git a/api.planx.uk/errors/ServerError.ts b/api.planx.uk/errors/serverError.ts similarity index 100% rename from api.planx.uk/errors/ServerError.ts rename to api.planx.uk/errors/serverError.ts diff --git a/api.planx.uk/helpers.test.ts b/api.planx.uk/helpers.test.ts index 460201e362..1c83882fa5 100644 --- a/api.planx.uk/helpers.test.ts +++ b/api.planx.uk/helpers.test.ts @@ -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; diff --git a/api.planx.uk/helpers.ts b/api.planx.uk/helpers.ts index 3433f5a9cd..75276f782a 100644 --- a/api.planx.uk/helpers.ts +++ b/api.planx.uk/helpers.ts @@ -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; diff --git a/api.planx.uk/index.ts b/api.planx.uk/index.ts index 05defdea6c..1d24bfd20d 100644 --- a/api.planx.uk/index.ts +++ b/api.planx.uk/index.ts @@ -1,4 +1,4 @@ -import server from "./server"; +import server from "./server.js"; const PORT = process.env.PORT || 8001; diff --git a/api.planx.uk/jest.config.ts b/api.planx.uk/jest.config.ts index e8c198d6a9..40944444de 100644 --- a/api.planx.uk/jest.config.ts +++ b/api.planx.uk/jest.config.ts @@ -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: { @@ -20,3 +35,5 @@ export default { coverageReporters: ["lcov", "text-summary"], coverageDirectory: "./coverage", }; + +export default config; diff --git a/api.planx.uk/jest.setup.js b/api.planx.uk/jest.setup.js index f196628439..2a15cc9877 100644 --- a/api.planx.uk/jest.setup.js +++ b/api.planx.uk/jest.setup.js @@ -1,5 +1,5 @@ import dotenv from "dotenv"; -import { queryMock } from "./tests/graphqlQueryMock"; +import { queryMock } from "./tests/graphqlQueryMock.js"; dotenv.config({ path: "./.env.test", diff --git a/api.planx.uk/lib/hasura/metadata/index.test.ts b/api.planx.uk/lib/hasura/metadata/index.test.ts index c9526c31f6..6f413c4fc2 100644 --- a/api.planx.uk/lib/hasura/metadata/index.test.ts +++ b/api.planx.uk/lib/hasura/metadata/index.test.ts @@ -1,4 +1,4 @@ -import { createScheduledEvent, RequiredScheduledEventArgs } from "."; +import { createScheduledEvent, RequiredScheduledEventArgs } from "./index.js"; import Axios, { AxiosError } from "axios"; jest.mock("axios", () => ({ diff --git a/api.planx.uk/lib/hasura/metadata/index.ts b/api.planx.uk/lib/hasura/metadata/index.ts index b6e5fb4aaa..7dc74bdd94 100644 --- a/api.planx.uk/lib/hasura/metadata/index.ts +++ b/api.planx.uk/lib/hasura/metadata/index.ts @@ -90,4 +90,4 @@ const createScheduledEvent = async (args: RequiredScheduledEventArgs) => { } }; -export { createScheduledEvent, RequiredScheduledEventArgs }; +export { createScheduledEvent, type RequiredScheduledEventArgs }; diff --git a/api.planx.uk/lib/hasura/schema/index.test.ts b/api.planx.uk/lib/hasura/schema/index.test.ts index 5229f6ee8a..e090d3800a 100644 --- a/api.planx.uk/lib/hasura/schema/index.test.ts +++ b/api.planx.uk/lib/hasura/schema/index.test.ts @@ -1,4 +1,4 @@ -import { runSQL } from "."; +import { runSQL } from "./index.js"; import Axios, { AxiosError } from "axios"; jest.mock("axios", () => ({ diff --git a/api.planx.uk/lib/notify/index.test.ts b/api.planx.uk/lib/notify/index.test.ts index 997fc451e9..bc00911091 100644 --- a/api.planx.uk/lib/notify/index.test.ts +++ b/api.planx.uk/lib/notify/index.test.ts @@ -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"); diff --git a/api.planx.uk/lib/notify/index.ts b/api.planx.uk/lib/notify/index.ts index 7970f70cc3..1bbf95443a 100644 --- a/api.planx.uk/lib/notify/index.ts +++ b/api.planx.uk/lib/notify/index.ts @@ -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); diff --git a/api.planx.uk/modules/admin/routes.ts b/api.planx.uk/modules/admin/routes.ts index f64f23dd5d..d9d3872b23 100644 --- a/api.planx.uk/modules/admin/routes.ts +++ b/api.planx.uk/modules/admin/routes.ts @@ -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(); diff --git a/api.planx.uk/modules/admin/session/csv.test.ts b/api.planx.uk/modules/admin/session/csv.test.ts index 601231ffc2..4e520adf86 100644 --- a/api.planx.uk/modules/admin/session/csv.test.ts +++ b/api.planx.uk/modules/admin/session/csv.test.ts @@ -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`; diff --git a/api.planx.uk/modules/admin/session/csv.ts b/api.planx.uk/modules/admin/session/csv.ts index 974db8808e..dad369a0a2 100644 --- a/api.planx.uk/modules/admin/session/csv.ts +++ b/api.planx.uk/modules/admin/session/csv.ts @@ -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 diff --git a/api.planx.uk/modules/admin/session/digitalPlanningData.test.ts b/api.planx.uk/modules/admin/session/digitalPlanningData.test.ts index 30c66564af..ef1c753aec 100644 --- a/api.planx.uk/modules/admin/session/digitalPlanningData.test.ts +++ b/api.planx.uk/modules/admin/session/digitalPlanningData.test.ts @@ -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`; diff --git a/api.planx.uk/modules/admin/session/digitalPlanningData.ts b/api.planx.uk/modules/admin/session/digitalPlanningData.ts index 1089e1aef4..4e42b12dd0 100644 --- a/api.planx.uk/modules/admin/session/digitalPlanningData.ts +++ b/api.planx.uk/modules/admin/session/digitalPlanningData.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import { $api } from "../../../client"; +import { $api } from "../../../client/index.js"; /** * @swagger diff --git a/api.planx.uk/modules/admin/session/html.test.ts b/api.planx.uk/modules/admin/session/html.test.ts index 24dc985bbd..21dd78f45d 100644 --- a/api.planx.uk/modules/admin/session/html.test.ts +++ b/api.planx.uk/modules/admin/session/html.test.ts @@ -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`; diff --git a/api.planx.uk/modules/admin/session/html.ts b/api.planx.uk/modules/admin/session/html.ts index feaec34024..35d56cea18 100644 --- a/api.planx.uk/modules/admin/session/html.ts +++ b/api.planx.uk/modules/admin/session/html.ts @@ -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>; diff --git a/api.planx.uk/modules/admin/session/oneAppXML.test.ts b/api.planx.uk/modules/admin/session/oneAppXML.test.ts index af18f0d186..c9304dc268 100644 --- a/api.planx.uk/modules/admin/session/oneAppXML.test.ts +++ b/api.planx.uk/modules/admin/session/oneAppXML.test.ts @@ -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`; diff --git a/api.planx.uk/modules/admin/session/oneAppXML.ts b/api.planx.uk/modules/admin/session/oneAppXML.ts index 55985ec42e..a90f4d1cde 100644 --- a/api.planx.uk/modules/admin/session/oneAppXML.ts +++ b/api.planx.uk/modules/admin/session/oneAppXML.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from "express"; -import { $api } from "../../../client"; +import { $api } from "../../../client/index.js"; /** * @swagger diff --git a/api.planx.uk/modules/admin/session/summary.test.ts b/api.planx.uk/modules/admin/session/summary.test.ts index 75551c8cac..e57215459a 100644 --- a/api.planx.uk/modules/admin/session/summary.test.ts +++ b/api.planx.uk/modules/admin/session/summary.test.ts @@ -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`; diff --git a/api.planx.uk/modules/admin/session/summary.ts b/api.planx.uk/modules/admin/session/summary.ts index d74b93038d..1f6634f8dc 100644 --- a/api.planx.uk/modules/admin/session/summary.ts +++ b/api.planx.uk/modules/admin/session/summary.ts @@ -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 diff --git a/api.planx.uk/modules/admin/session/zip.test.ts b/api.planx.uk/modules/admin/session/zip.test.ts index 0444e5734a..ac1ab0b69c 100644 --- a/api.planx.uk/modules/admin/session/zip.test.ts +++ b/api.planx.uk/modules/admin/session/zip.test.ts @@ -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({ diff --git a/api.planx.uk/modules/admin/session/zip.ts b/api.planx.uk/modules/admin/session/zip.ts index a9ef0711eb..56a91b99db 100644 --- a/api.planx.uk/modules/admin/session/zip.ts +++ b/api.planx.uk/modules/admin/session/zip.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import { buildSubmissionExportZip } from "../../send/utils/exportZip"; +import { buildSubmissionExportZip } from "../../send/utils/exportZip.js"; /** * @swagger diff --git a/api.planx.uk/modules/analytics/controller.ts b/api.planx.uk/modules/analytics/controller.ts index ebc618516f..c4dfbf2ac3 100644 --- a/api.planx.uk/modules/analytics/controller.ts +++ b/api.planx.uk/modules/analytics/controller.ts @@ -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({ diff --git a/api.planx.uk/modules/analytics/index.test.ts b/api.planx.uk/modules/analytics/index.test.ts index 2c8d4df4b7..4112fc0dae 100644 --- a/api.planx.uk/modules/analytics/index.test.ts +++ b/api.planx.uk/modules/analytics/index.test.ts @@ -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(() => { diff --git a/api.planx.uk/modules/analytics/routes.ts b/api.planx.uk/modules/analytics/routes.ts index 41db272ead..22945515be 100644 --- a/api.planx.uk/modules/analytics/routes.ts +++ b/api.planx.uk/modules/analytics/routes.ts @@ -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(); diff --git a/api.planx.uk/modules/analytics/service.ts b/api.planx.uk/modules/analytics/service.ts index 9defd29fc5..413d0d971b 100644 --- a/api.planx.uk/modules/analytics/service.ts +++ b/api.planx.uk/modules/analytics/service.ts @@ -1,5 +1,5 @@ import { gql } from "graphql-request"; -import { $public } from "../../client"; +import { $public } from "../../client/index.js"; interface UpdateAnalyticsLogUserExit { analyticsLog: { diff --git a/api.planx.uk/modules/auth/middleware.test.ts b/api.planx.uk/modules/auth/middleware.test.ts index dae48a8ba9..03bb5195a4 100644 --- a/api.planx.uk/modules/auth/middleware.test.ts +++ b/api.planx.uk/modules/auth/middleware.test.ts @@ -1,4 +1,4 @@ -import { isEqual } from "./middleware"; +import { isEqual } from "./middleware.js"; describe("isEqual() helper function", () => { it("handles undefined secrets", () => { diff --git a/api.planx.uk/modules/auth/middleware.ts b/api.planx.uk/modules/auth/middleware.ts index 6d597a574c..487443e589 100644 --- a/api.planx.uk/modules/auth/middleware.ts +++ b/api.planx.uk/modules/auth/middleware.ts @@ -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"; diff --git a/api.planx.uk/modules/auth/routes.ts b/api.planx.uk/modules/auth/routes.ts index b041ca1fb8..f21fe81da8 100644 --- a/api.planx.uk/modules/auth/routes.ts +++ b/api.planx.uk/modules/auth/routes.ts @@ -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(); diff --git a/api.planx.uk/modules/auth/service.test.ts b/api.planx.uk/modules/auth/service.test.ts index e421582dae..9d521e039f 100644 --- a/api.planx.uk/modules/auth/service.test.ts +++ b/api.planx.uk/modules/auth/service.test.ts @@ -1,4 +1,4 @@ -import { checkUserCanAccessEnv } from "./service"; +import { checkUserCanAccessEnv } from "./service.js"; const mockIsStagingOnly = jest.fn(); diff --git a/api.planx.uk/modules/auth/service.ts b/api.planx.uk/modules/auth/service.ts index d4a6c39e0a..195b2df140 100644 --- a/api.planx.uk/modules/auth/service.ts +++ b/api.planx.uk/modules/auth/service.ts @@ -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 => { @@ -13,12 +13,11 @@ export const buildJWT = async (email: string): Promise => { "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"], diff --git a/api.planx.uk/modules/auth/strategy/google.ts b/api.planx.uk/modules/auth/strategy/google.ts index 83835af038..b266a8a163 100644 --- a/api.planx.uk/modules/auth/strategy/google.ts +++ b/api.planx.uk/modules/auth/strategy/google.ts @@ -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( { diff --git a/api.planx.uk/modules/file/controller.ts b/api.planx.uk/modules/file/controller.ts index 206750bb19..52a87eda76 100644 --- a/api.planx.uk/modules/file/controller.ts +++ b/api.planx.uk/modules/file/controller.ts @@ -1,10 +1,10 @@ import assert from "assert"; -import { uploadPrivateFile, uploadPublicFile } from "./service/uploadFile"; -import { buildFilePath } from "./service/utils"; -import { getFileFromS3 } from "./service/getFile"; +import { uploadPrivateFile, uploadPublicFile } from "./service/uploadFile.js"; +import { buildFilePath } from "./service/utils.js"; +import { getFileFromS3 } from "./service/getFile.js"; import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; -import { ServerError } from "../../errors"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; +import { ServerError } from "../../errors/index.js"; assert(process.env.AWS_S3_BUCKET); assert(process.env.AWS_S3_REGION); diff --git a/api.planx.uk/modules/file/file.test.ts b/api.planx.uk/modules/file/file.test.ts index 4495281c63..ace9ee2d9a 100644 --- a/api.planx.uk/modules/file/file.test.ts +++ b/api.planx.uk/modules/file/file.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import app from "../../server"; -import { deleteFilesByURL } from "./service/deleteFile"; -import { authHeader } from "../../tests/mockJWT"; +import app from "../../server.js"; +import { deleteFilesByURL } from "./service/deleteFile.js"; +import { authHeader } from "../../tests/mockJWT.js"; let mockPutObject: jest.Mocked<() => void>; let mockGetObject: jest.Mocked<() => void>; diff --git a/api.planx.uk/modules/file/routes.ts b/api.planx.uk/modules/file/routes.ts index 9f301b4ea2..76617030e4 100644 --- a/api.planx.uk/modules/file/routes.ts +++ b/api.planx.uk/modules/file/routes.ts @@ -5,7 +5,7 @@ import { useNoCache, useFilePermission, useTeamEditorAuth, -} from "../auth/middleware"; +} from "../auth/middleware.js"; import { downloadFileSchema, privateDownloadController, @@ -13,8 +13,8 @@ import { publicDownloadController, publicUploadController, uploadFileSchema, -} from "./controller"; -import { validate } from "../../shared/middleware/validate"; +} from "./controller.js"; +import { validate } from "../../shared/middleware/validate.js"; const router = Router(); diff --git a/api.planx.uk/modules/file/service/deleteFile.ts b/api.planx.uk/modules/file/service/deleteFile.ts index e4ef301d73..13b9622d4d 100644 --- a/api.planx.uk/modules/file/service/deleteFile.ts +++ b/api.planx.uk/modules/file/service/deleteFile.ts @@ -1,5 +1,5 @@ -import { DeleteObjectsRequest } from "aws-sdk/clients/s3"; -import { getS3KeyFromURL, s3Factory } from "./utils"; +import { DeleteObjectsRequest } from "aws-sdk/clients/s3.js"; +import { getS3KeyFromURL, s3Factory } from "./utils.js"; export const deleteFilesByURL = async ( fileURLs: string[], diff --git a/api.planx.uk/modules/file/service/getFile.ts b/api.planx.uk/modules/file/service/getFile.ts index 29b3c539cd..bf71940168 100644 --- a/api.planx.uk/modules/file/service/getFile.ts +++ b/api.planx.uk/modules/file/service/getFile.ts @@ -1,5 +1,5 @@ -import S3 from "aws-sdk/clients/s3"; -import { s3Factory } from "./utils"; +import S3 from "aws-sdk/clients/s3.js"; +import { s3Factory } from "./utils.js"; export const getFileFromS3 = async (fileId: string) => { const s3 = s3Factory(); diff --git a/api.planx.uk/modules/file/service/uploadFile.ts b/api.planx.uk/modules/file/service/uploadFile.ts index 44e1fe43e1..2c1979b55a 100644 --- a/api.planx.uk/modules/file/service/uploadFile.ts +++ b/api.planx.uk/modules/file/service/uploadFile.ts @@ -1,8 +1,8 @@ -import S3 from "aws-sdk/clients/s3"; +import S3 from "aws-sdk/clients/s3.js"; import { customAlphabet } from "nanoid"; -import { getType } from "mime"; -import { s3Factory } from "./utils"; -import { isLiveEnv } from "../../../helpers"; +import mime from "mime"; +import { s3Factory } from "./utils.js"; +import { isLiveEnv } from "../../../helpers.js"; const nanoid = customAlphabet("1234567890abcdefghijklmnopqrstuvwxyz", 8); export const uploadPublicFile = async ( @@ -67,7 +67,7 @@ export function generateFileParams( fileType: string | null; key: string; } { - const fileType = getType(filename); + const fileType = mime.getType(filename); const key = `${filekey || nanoid()}/${filename}`; const params = { diff --git a/api.planx.uk/modules/file/service/utils.test.ts b/api.planx.uk/modules/file/service/utils.test.ts index 6ed470b57f..95f300868b 100644 --- a/api.planx.uk/modules/file/service/utils.test.ts +++ b/api.planx.uk/modules/file/service/utils.test.ts @@ -1,4 +1,4 @@ -import { getS3KeyFromURL, s3Factory } from "./utils"; +import { getS3KeyFromURL, s3Factory } from "./utils.js"; describe("s3 Factory", () => { const OLD_ENV = process.env; diff --git a/api.planx.uk/modules/file/service/utils.ts b/api.planx.uk/modules/file/service/utils.ts index d7e97f1487..8d7da9c2ea 100644 --- a/api.planx.uk/modules/file/service/utils.ts +++ b/api.planx.uk/modules/file/service/utils.ts @@ -1,5 +1,5 @@ -import S3 from "aws-sdk/clients/s3"; -import { isLiveEnv } from "../../../helpers"; +import S3 from "aws-sdk/clients/s3.js"; +import { isLiveEnv } from "../../../helpers.js"; export function s3Factory() { return new S3({ diff --git a/api.planx.uk/modules/flows/copyFlow/controller.ts b/api.planx.uk/modules/flows/copyFlow/controller.ts index 0f8918995c..21ede22e00 100644 --- a/api.planx.uk/modules/flows/copyFlow/controller.ts +++ b/api.planx.uk/modules/flows/copyFlow/controller.ts @@ -1,8 +1,8 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; -import { Flow } from "../../../types"; -import { ServerError } from "../../../errors"; -import { copyFlow } from "./service"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; +import { Flow } from "../../../types.js"; +import { ServerError } from "../../../errors/index.js"; +import { copyFlow } from "./service.js"; interface CopyFlowResponse { message: string; diff --git a/api.planx.uk/modules/flows/copyFlow/copyFlow.test.ts b/api.planx.uk/modules/flows/copyFlow/copyFlow.test.ts index c02ad913e2..88d39889f5 100644 --- a/api.planx.uk/modules/flows/copyFlow/copyFlow.test.ts +++ b/api.planx.uk/modules/flows/copyFlow/copyFlow.test.ts @@ -1,10 +1,10 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader } from "../../../tests/mockJWT"; -import app from "../../../server"; -import { Flow } from "../../../types"; -import { userContext } from "../../auth/middleware"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; +import { Flow } from "../../../types.js"; +import { userContext } from "../../auth/middleware.js"; beforeEach(() => { queryMock.mockQuery({ diff --git a/api.planx.uk/modules/flows/copyFlow/service.ts b/api.planx.uk/modules/flows/copyFlow/service.ts index 68e31f46e8..c232cbc7e4 100644 --- a/api.planx.uk/modules/flows/copyFlow/service.ts +++ b/api.planx.uk/modules/flows/copyFlow/service.ts @@ -1,5 +1,5 @@ -import { makeUniqueFlow, getFlowData, insertFlow } from "../../../helpers"; -import { userContext } from "../../auth/middleware"; +import { makeUniqueFlow, getFlowData, insertFlow } from "../../../helpers.js"; +import { userContext } from "../../auth/middleware.js"; const copyFlow = async ( flowId: string, diff --git a/api.planx.uk/modules/flows/copyFlowAsPortal/controller.ts b/api.planx.uk/modules/flows/copyFlowAsPortal/controller.ts index be3892ca8f..e6d8bfb780 100644 --- a/api.planx.uk/modules/flows/copyFlowAsPortal/controller.ts +++ b/api.planx.uk/modules/flows/copyFlowAsPortal/controller.ts @@ -1,8 +1,8 @@ import { z } from "zod"; -import { Flow } from "../../../types"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; -import { copyPortalAsFlow } from "./service"; -import { ServerError } from "../../../errors"; +import { Flow } from "../../../types.js"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; +import { copyPortalAsFlow } from "./service.js"; +import { ServerError } from "../../../errors/index.js"; interface CopyFlowAsPortalResponse { message: string; diff --git a/api.planx.uk/modules/flows/copyFlowAsPortal/copyPortalAsFlow.test.ts b/api.planx.uk/modules/flows/copyFlowAsPortal/copyPortalAsFlow.test.ts index 7d4868aba4..468d29d93b 100644 --- a/api.planx.uk/modules/flows/copyFlowAsPortal/copyPortalAsFlow.test.ts +++ b/api.planx.uk/modules/flows/copyFlowAsPortal/copyPortalAsFlow.test.ts @@ -1,9 +1,9 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader } from "../../../tests/mockJWT"; -import app from "../../../server"; -import { Flow } from "../../../types"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; +import { Flow } from "../../../types.js"; beforeEach(() => { queryMock.mockQuery({ diff --git a/api.planx.uk/modules/flows/copyFlowAsPortal/service.ts b/api.planx.uk/modules/flows/copyFlowAsPortal/service.ts index 1139f484e8..20b4c73633 100644 --- a/api.planx.uk/modules/flows/copyFlowAsPortal/service.ts +++ b/api.planx.uk/modules/flows/copyFlowAsPortal/service.ts @@ -1,5 +1,5 @@ -import { getFlowData, getChildren, makeUniqueFlow } from "../../../helpers"; -import { Flow } from "../../../types"; +import { getFlowData, getChildren, makeUniqueFlow } from "../../../helpers.js"; +import { Flow } from "../../../types.js"; /** * Copies an internal portal and transforms it to be an independent flow diff --git a/api.planx.uk/modules/flows/downloadSchema/controller.ts b/api.planx.uk/modules/flows/downloadSchema/controller.ts index 4fb32b3f83..4f6664d7c8 100644 --- a/api.planx.uk/modules/flows/downloadSchema/controller.ts +++ b/api.planx.uk/modules/flows/downloadSchema/controller.ts @@ -1,8 +1,8 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; import { stringify } from "csv-stringify"; -import { getFlowSchema } from "./service"; -import { ServerError } from "../../../errors"; +import { getFlowSchema } from "./service.js"; +import { ServerError } from "../../../errors/index.js"; interface DownloadFlowSchemaResponse { message: string; diff --git a/api.planx.uk/modules/flows/downloadSchema/service.ts b/api.planx.uk/modules/flows/downloadSchema/service.ts index 32760c4b48..de83ba112a 100644 --- a/api.planx.uk/modules/flows/downloadSchema/service.ts +++ b/api.planx.uk/modules/flows/downloadSchema/service.ts @@ -1,4 +1,4 @@ -import { getFlowData } from "../../../helpers"; +import { getFlowData } from "../../../helpers.js"; interface FlowSchema { node: string; diff --git a/api.planx.uk/modules/flows/findReplace/controller.ts b/api.planx.uk/modules/flows/findReplace/controller.ts index c64387dc64..ebdca7275c 100644 --- a/api.planx.uk/modules/flows/findReplace/controller.ts +++ b/api.planx.uk/modules/flows/findReplace/controller.ts @@ -1,8 +1,8 @@ -import { Flow } from "../../../types"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { Flow } from "../../../types.js"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; import { z } from "zod"; -import { ServerError } from "../../../errors"; -import { findAndReplaceInFlow } from "./service"; +import { ServerError } from "../../../errors/index.js"; +import { findAndReplaceInFlow } from "./service.js"; import { FlowGraph } from "@opensystemslab/planx-core/types"; interface FindAndReplaceResponse { diff --git a/api.planx.uk/modules/flows/findReplace/findReplace.test.ts b/api.planx.uk/modules/flows/findReplace/findReplace.test.ts index 962fc88744..7f7e799853 100644 --- a/api.planx.uk/modules/flows/findReplace/findReplace.test.ts +++ b/api.planx.uk/modules/flows/findReplace/findReplace.test.ts @@ -1,9 +1,9 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader } from "../../../tests/mockJWT"; -import app from "../../../server"; -import { Flow } from "../../../types"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; +import { Flow } from "../../../types.js"; const auth = authHeader({ role: "platformAdmin" }); diff --git a/api.planx.uk/modules/flows/findReplace/service.ts b/api.planx.uk/modules/flows/findReplace/service.ts index 719b869c16..69102abe98 100644 --- a/api.planx.uk/modules/flows/findReplace/service.ts +++ b/api.planx.uk/modules/flows/findReplace/service.ts @@ -1,8 +1,8 @@ import { gql } from "graphql-request"; -import { getFlowData } from "../../../helpers"; -import { $api } from "../../../client"; +import { getFlowData } from "../../../helpers.js"; +import { $api } from "../../../client/index.js"; import { FlowGraph } from "@opensystemslab/planx-core/types"; -import { Flow } from "../../../types"; +import { Flow } from "../../../types.js"; interface MatchResult { matches: Flow["data"]; diff --git a/api.planx.uk/modules/flows/flattenFlow/controller.ts b/api.planx.uk/modules/flows/flattenFlow/controller.ts index ebe3d8498f..0d22b727fa 100644 --- a/api.planx.uk/modules/flows/flattenFlow/controller.ts +++ b/api.planx.uk/modules/flows/flattenFlow/controller.ts @@ -1,8 +1,8 @@ import { FlowGraph } from "@opensystemslab/planx-core/types"; import { z } from "zod"; -import { ServerError } from "../../../errors"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; -import { dataMerged } from "../../../helpers"; +import { ServerError } from "../../../errors/index.js"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; +import { dataMerged } from "../../../helpers.js"; type FlattenFlowDataResponse = FlowGraph; diff --git a/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts b/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts index 16fad1c204..a64b55f451 100644 --- a/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts +++ b/api.planx.uk/modules/flows/flattenFlow/flattenFlow.test.ts @@ -1,13 +1,13 @@ import supertest from "supertest"; -import app from "../../../server"; -import { queryMock } from "../../../tests/graphqlQueryMock"; +import app from "../../../server.js"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; import { childFlow, draftParentFlow, flattenedParentFlow, mockFlowData, -} from "../../../tests/mocks/validateAndPublishMocks"; +} from "../../../tests/mocks/validateAndPublishMocks.js"; beforeEach(() => { queryMock.mockQuery({ diff --git a/api.planx.uk/modules/flows/moveFlow/controller.ts b/api.planx.uk/modules/flows/moveFlow/controller.ts index 319ac0c1ca..49400faa1a 100644 --- a/api.planx.uk/modules/flows/moveFlow/controller.ts +++ b/api.planx.uk/modules/flows/moveFlow/controller.ts @@ -1,7 +1,7 @@ -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; import { z } from "zod"; -import { ServerError } from "../../../errors"; -import { moveFlow } from "./service"; +import { ServerError } from "../../../errors/index.js"; +import { moveFlow } from "./service.js"; interface MoveFlowResponse { message: string; diff --git a/api.planx.uk/modules/flows/moveFlow/moveFlow.test.ts b/api.planx.uk/modules/flows/moveFlow/moveFlow.test.ts index aedb1762b3..7cff49eeed 100644 --- a/api.planx.uk/modules/flows/moveFlow/moveFlow.test.ts +++ b/api.planx.uk/modules/flows/moveFlow/moveFlow.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader } from "../../../tests/mockJWT"; -import app from "../../../server"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; beforeEach(() => { queryMock.mockQuery({ diff --git a/api.planx.uk/modules/flows/moveFlow/service.ts b/api.planx.uk/modules/flows/moveFlow/service.ts index 6c05c62c40..c329162d87 100644 --- a/api.planx.uk/modules/flows/moveFlow/service.ts +++ b/api.planx.uk/modules/flows/moveFlow/service.ts @@ -1,6 +1,6 @@ import { gql } from "graphql-request"; -import { Flow } from "../../../types"; -import { $public, getClient } from "../../../client"; +import { Flow } from "../../../types.js"; +import { $public, getClient } from "../../../client/index.js"; import { Team } from "@opensystemslab/planx-core/types"; export const moveFlow = async (flowId: string, teamSlug: string) => { diff --git a/api.planx.uk/modules/flows/publish/controller.ts b/api.planx.uk/modules/flows/publish/controller.ts index 2eb95a8ef2..42675d09e7 100644 --- a/api.planx.uk/modules/flows/publish/controller.ts +++ b/api.planx.uk/modules/flows/publish/controller.ts @@ -1,8 +1,8 @@ import { Node } from "@opensystemslab/planx-core/types"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; import { z } from "zod"; -import { publishFlow } from "./service"; -import { ServerError } from "../../../errors"; +import { publishFlow } from "./service.js"; +import { ServerError } from "../../../errors/index.js"; interface PublishFlowResponse { message: string; diff --git a/api.planx.uk/modules/flows/publish/publish.test.ts b/api.planx.uk/modules/flows/publish/publish.test.ts index 2262e367a0..78a4b6a20c 100644 --- a/api.planx.uk/modules/flows/publish/publish.test.ts +++ b/api.planx.uk/modules/flows/publish/publish.test.ts @@ -1,10 +1,10 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader, getJWT } from "../../../tests/mockJWT"; -import app from "../../../server"; -import { userContext } from "../../auth/middleware"; -import { mockFlowData } from "../../../tests/mocks/validateAndPublishMocks"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader, getJWT } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; +import { userContext } from "../../auth/middleware.js"; +import { mockFlowData } from "../../../tests/mocks/validateAndPublishMocks.js"; beforeAll(() => { const getStoreMock = jest.spyOn(userContext, "getStore"); diff --git a/api.planx.uk/modules/flows/publish/service.ts b/api.planx.uk/modules/flows/publish/service.ts index ee7d03da74..6ffa007ee7 100644 --- a/api.planx.uk/modules/flows/publish/service.ts +++ b/api.planx.uk/modules/flows/publish/service.ts @@ -1,9 +1,9 @@ import * as jsondiffpatch from "jsondiffpatch"; -import { dataMerged, getMostRecentPublishedFlow } from "../../../helpers"; +import { dataMerged, getMostRecentPublishedFlow } from "../../../helpers.js"; import { gql } from "graphql-request"; import { FlowGraph, Node } from "@opensystemslab/planx-core/types"; -import { userContext } from "../../auth/middleware"; -import { getClient } from "../../../client"; +import { userContext } from "../../auth/middleware.js"; +import { getClient } from "../../../client/index.js"; interface PublishFlow { publishedFlow: { diff --git a/api.planx.uk/modules/flows/routes.ts b/api.planx.uk/modules/flows/routes.ts index 157bf6f679..f6df7d917a 100644 --- a/api.planx.uk/modules/flows/routes.ts +++ b/api.planx.uk/modules/flows/routes.ts @@ -1,29 +1,32 @@ import { Router } from "express"; -import { validate } from "../../shared/middleware/validate"; -import { usePlatformAdminAuth, useTeamEditorAuth } from "../auth/middleware"; -import { copyFlowController, copyFlowSchema } from "./copyFlow/controller"; +import { validate } from "../../shared/middleware/validate.js"; +import { usePlatformAdminAuth, useTeamEditorAuth } from "../auth/middleware.js"; +import { copyFlowController, copyFlowSchema } from "./copyFlow/controller.js"; import { copyFlowAsPortalSchema, copyPortalAsFlowController, -} from "./copyFlowAsPortal/controller"; +} from "./copyFlowAsPortal/controller.js"; import { downloadFlowSchema, downloadFlowSchemaController, -} from "./downloadSchema/controller"; +} from "./downloadSchema/controller.js"; import { findAndReplaceController, findAndReplaceSchema, -} from "./findReplace/controller"; +} from "./findReplace/controller.js"; import { flattenFlowData, flattenFlowDataController, -} from "./flattenFlow/controller"; -import { moveFlowController, moveFlowSchema } from "./moveFlow/controller"; -import { publishFlowController, publishFlowSchema } from "./publish/controller"; +} from "./flattenFlow/controller.js"; +import { moveFlowController, moveFlowSchema } from "./moveFlow/controller.js"; +import { + publishFlowController, + publishFlowSchema, +} from "./publish/controller.js"; import { validateAndDiffFlowController, validateAndDiffSchema, -} from "./validate/controller"; +} from "./validate/controller.js"; const router = Router(); router.post( diff --git a/api.planx.uk/modules/flows/validate/controller.ts b/api.planx.uk/modules/flows/validate/controller.ts index a974a7229f..109792e4f5 100644 --- a/api.planx.uk/modules/flows/validate/controller.ts +++ b/api.planx.uk/modules/flows/validate/controller.ts @@ -1,8 +1,8 @@ import { Node } from "@opensystemslab/planx-core/types"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; import { z } from "zod"; -import { validateAndDiffFlow } from "./service/index"; -import { ServerError } from "../../../errors"; +import { validateAndDiffFlow } from "./service/index.js"; +import { ServerError } from "../../../errors/index.js"; interface ValidateAndDiffResponse { message: string; diff --git a/api.planx.uk/modules/flows/validate/service/fileTypes.ts b/api.planx.uk/modules/flows/validate/service/fileTypes.ts index cee8cfc32f..7050ca31ec 100644 --- a/api.planx.uk/modules/flows/validate/service/fileTypes.ts +++ b/api.planx.uk/modules/flows/validate/service/fileTypes.ts @@ -4,10 +4,10 @@ import { FlowGraph, Node, } from "@opensystemslab/planx-core/types"; -import countBy from "lodash/countBy"; +import countBy from "lodash/countBy.js"; -import { isComponentType } from "../helpers"; -import { FlowValidationResponse } from "./index"; +import { isComponentType } from "../helpers.js"; +import { FlowValidationResponse } from "./index.js"; const validateFileTypes = (flowGraph: FlowGraph): FlowValidationResponse => { // Get all passport variables set by FileUpload and/or FileUploadAndLabel diff --git a/api.planx.uk/modules/flows/validate/service/index.ts b/api.planx.uk/modules/flows/validate/service/index.ts index 1702b3603a..ea40034406 100644 --- a/api.planx.uk/modules/flows/validate/service/index.ts +++ b/api.planx.uk/modules/flows/validate/service/index.ts @@ -1,11 +1,11 @@ import { ComponentType, Edges, Node } from "@opensystemslab/planx-core/types"; import * as jsondiffpatch from "jsondiffpatch"; -import { dataMerged, getMostRecentPublishedFlow } from "../../../../helpers"; -import { validateFileTypes } from "./fileTypes"; -import { validateInviteToPay } from "./inviteToPay"; -import { validateSections } from "./sections"; -import { validateProjectTypes } from "./projectTypes"; +import { dataMerged, getMostRecentPublishedFlow } from "../../../../helpers.js"; +import { validateFileTypes } from "./fileTypes.js"; +import { validateInviteToPay } from "./inviteToPay.js"; +import { validateSections } from "./sections.js"; +import { validateProjectTypes } from "./projectTypes.js"; type AlteredNode = { id: string; diff --git a/api.planx.uk/modules/flows/validate/service/inviteToPay.ts b/api.planx.uk/modules/flows/validate/service/inviteToPay.ts index 61a57fe020..6e85161978 100644 --- a/api.planx.uk/modules/flows/validate/service/inviteToPay.ts +++ b/api.planx.uk/modules/flows/validate/service/inviteToPay.ts @@ -4,8 +4,8 @@ import { hasComponentType, isComponentType, numberOfComponentType, -} from "../helpers"; -import { FlowValidationResponse } from "./index"; +} from "../helpers.js"; +import { FlowValidationResponse } from "./index.js"; const validateInviteToPay = (flowGraph: FlowGraph): FlowValidationResponse => { if (inviteToPayEnabled(flowGraph)) { diff --git a/api.planx.uk/modules/flows/validate/service/projectTypes.ts b/api.planx.uk/modules/flows/validate/service/projectTypes.ts index 2c65d71fb6..bd6ea4b9ef 100644 --- a/api.planx.uk/modules/flows/validate/service/projectTypes.ts +++ b/api.planx.uk/modules/flows/validate/service/projectTypes.ts @@ -1,9 +1,9 @@ import { getValidSchemaValues } from "@opensystemslab/planx-core"; import { ComponentType, FlowGraph } from "@opensystemslab/planx-core/types"; -import countBy from "lodash/countBy"; +import countBy from "lodash/countBy.js"; -import { isComponentType } from "../helpers"; -import { FlowValidationResponse } from "./index"; +import { isComponentType } from "../helpers.js"; +import { FlowValidationResponse } from "./index.js"; const validateProjectTypes = (flowGraph: FlowGraph): FlowValidationResponse => { // Get all passport values set by Answers of Checklists that set fn "proposal.projectType" diff --git a/api.planx.uk/modules/flows/validate/service/sections.ts b/api.planx.uk/modules/flows/validate/service/sections.ts index a955ae11ae..e28b67e6ca 100644 --- a/api.planx.uk/modules/flows/validate/service/sections.ts +++ b/api.planx.uk/modules/flows/validate/service/sections.ts @@ -1,8 +1,8 @@ import { ComponentType, FlowGraph } from "@opensystemslab/planx-core/types"; -import intersection from "lodash/intersection"; +import intersection from "lodash/intersection.js"; -import { isComponentType } from "../helpers"; -import { FlowValidationResponse } from "./index"; +import { isComponentType } from "../helpers.js"; +import { FlowValidationResponse } from "./index.js"; const validateSections = (flowGraph: FlowGraph): FlowValidationResponse => { if (getSectionNodeIds(flowGraph)?.length > 0) { diff --git a/api.planx.uk/modules/flows/validate/validate.test.ts b/api.planx.uk/modules/flows/validate/validate.test.ts index 1c2dfd09e4..e9349bbffb 100644 --- a/api.planx.uk/modules/flows/validate/validate.test.ts +++ b/api.planx.uk/modules/flows/validate/validate.test.ts @@ -1,12 +1,12 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { authHeader, getJWT } from "../../../tests/mockJWT"; -import app from "../../../server"; -import { flowWithInviteToPay } from "../../../tests/mocks/inviteToPayData"; -import { userContext } from "../../auth/middleware"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { authHeader, getJWT } from "../../../tests/mockJWT.js"; +import app from "../../../server.js"; +import { flowWithInviteToPay } from "../../../tests/mocks/inviteToPayData.js"; +import { userContext } from "../../auth/middleware.js"; import { FlowGraph } from "@opensystemslab/planx-core/types"; -import { mockFlowData } from "../../../tests/mocks/validateAndPublishMocks"; +import { mockFlowData } from "../../../tests/mocks/validateAndPublishMocks.js"; beforeAll(() => { const getStoreMock = jest.spyOn(userContext, "getStore"); diff --git a/api.planx.uk/modules/gis/routes.ts b/api.planx.uk/modules/gis/routes.ts index 28599716ce..1099a1b6ff 100644 --- a/api.planx.uk/modules/gis/routes.ts +++ b/api.planx.uk/modules/gis/routes.ts @@ -1,7 +1,7 @@ import { Router } from "express"; -import { locationSearch } from "./service"; -import { hasArticle4Schema } from "./service/article4Schema"; -import { classifiedRoadsSearch } from "./service/classifiedRoads"; +import { locationSearch } from "./service/index.js"; +import { hasArticle4Schema } from "./service/article4Schema.js"; +import { classifiedRoadsSearch } from "./service/classifiedRoads.js"; const router = Router(); diff --git a/api.planx.uk/modules/gis/service/article4Schema.ts b/api.planx.uk/modules/gis/service/article4Schema.ts index 890a18a09e..b18c5d5d16 100644 --- a/api.planx.uk/modules/gis/service/article4Schema.ts +++ b/api.planx.uk/modules/gis/service/article4Schema.ts @@ -1,6 +1,6 @@ import { NextFunction, Request, Response } from "express"; -import { localAuthorityMetadata } from "./digitalLand"; +import { localAuthorityMetadata } from "./digitalLand.js"; /** * @swagger diff --git a/api.planx.uk/modules/gis/service/classifiedRoads.test.ts b/api.planx.uk/modules/gis/service/classifiedRoads.test.ts index 169062176e..b16c79c8f1 100644 --- a/api.planx.uk/modules/gis/service/classifiedRoads.test.ts +++ b/api.planx.uk/modules/gis/service/classifiedRoads.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import loadOrRecordNockRequests from "../../../tests/loadOrRecordNockRequests"; -import app from "../../../server"; -import { PASSPORT_FN } from "./classifiedRoads"; +import loadOrRecordNockRequests from "../../../tests/loadOrRecordNockRequests.js"; +import app from "../../../server.js"; +import { PASSPORT_FN } from "./classifiedRoads.js"; it("returns an error if required query param is missing", async () => { await supertest(app) diff --git a/api.planx.uk/modules/gis/service/digitalLand.ts b/api.planx.uk/modules/gis/service/digitalLand.ts index 66405763fe..6453087eb7 100644 --- a/api.planx.uk/modules/gis/service/digitalLand.ts +++ b/api.planx.uk/modules/gis/service/digitalLand.ts @@ -5,9 +5,27 @@ import type { } from "@opensystemslab/planx-core/types"; import { gql } from "graphql-request"; import fetch from "isomorphic-fetch"; -import { addDesignatedVariable } from "./helpers"; -import { baseSchema } from "./local_authorities/metadata/base"; -import { $api } from "../../../client"; +import { addDesignatedVariable } from "./helpers.js"; +import { baseSchema } from "./local_authorities/metadata/base.js"; +import { $api } from "../../../client/index.js"; + +import * as barkingAndDagenham from "./local_authorities/metadata/barkingAndDagenham.js"; +import * as barnet from "./local_authorities/metadata/barnet.js"; +import * as birmingham from "./local_authorities/metadata/birmingham.js"; +import * as buckinghamshire from "./local_authorities/metadata/buckinghamshire.js"; +import * as camden from "./local_authorities/metadata/camden.js"; +import * as canterbury from "./local_authorities/metadata/canterbury.js"; +import * as doncaster from "./local_authorities/metadata/doncaster.js"; +import * as epsomAndEwell from "./local_authorities/metadata/epsomAndEwell.js"; +import * as gateshead from "./local_authorities/metadata/gateshead.js"; +import * as gloucester from "./local_authorities/metadata/gloucester.js"; +import * as lambeth from "./local_authorities/metadata/lambeth.js"; +import * as medway from "./local_authorities/metadata/medway.js"; +import * as newcastle from "./local_authorities/metadata/newcastle.js"; +import * as southwark from "./local_authorities/metadata/southwark.js"; +import * as stAlbans from "./local_authorities/metadata/stAlbans.js"; +import * as tewkesbury from "./local_authorities/metadata/tewkesbury.js"; +import * as westBerkshire from "./local_authorities/metadata/westBerkshire.js"; export interface LocalAuthorityMetadata { planningConstraints: { @@ -19,23 +37,23 @@ export interface LocalAuthorityMetadata { /** When a team publishes their granular Article 4 data, add them to this list. Key must match team slug */ export const localAuthorityMetadata: Record = { - "barking-and-dagenham": require("./local_authorities/metadata/barkingAndDagenham"), - barnet: require("./local_authorities/metadata/barnet"), - birmingham: require("./local_authorities/metadata/birmingham"), - buckinghamshire: require("./local_authorities/metadata/buckinghamshire"), - camden: require("./local_authorities/metadata/camden"), - canterbury: require("./local_authorities/metadata/canterbury"), - doncaster: require("./local_authorities/metadata/doncaster"), - "epsom-and-ewell": require("./local_authorities/metadata/epsomAndEwell"), - gateshead: require("./local_authorities/metadata/gateshead"), - gloucester: require("./local_authorities/metadata/gloucester"), - lambeth: require("./local_authorities/metadata/lambeth"), - medway: require("./local_authorities/metadata/medway"), - newcastle: require("./local_authorities/metadata/newcastle"), - southwark: require("./local_authorities/metadata/southwark"), - "st-albans": require("./local_authorities/metadata/stAlbans"), - tewkesbury: require("./local_authorities/metadata/tewkesbury"), - "west-berkshire": require("./local_authorities/metadata/westBerkshire"), + "barking-and-dagenham": barkingAndDagenham, + barnet, + birmingham, + buckinghamshire, + camden, + canterbury, + doncaster, + "epsom-and-ewell": epsomAndEwell, + gateshead, + gloucester, + lambeth, + medway, + newcastle, + southwark, + "st-albans": stAlbans, + tewkesbury, + "west-berkshire": westBerkshire, }; /** diff --git a/api.planx.uk/modules/gis/service/helpers.test.js b/api.planx.uk/modules/gis/service/helpers.test.js index 5ab0cad5b9..eabf53b2b7 100644 --- a/api.planx.uk/modules/gis/service/helpers.test.js +++ b/api.planx.uk/modules/gis/service/helpers.test.js @@ -2,7 +2,7 @@ import { squashResultLayers, rollupResultLayers, getA4Subvariables, -} from "./helpers"; +} from "./helpers.js"; describe("squashResultLayer helper function", () => { test("It should squash the list of layers passed in", () => { diff --git a/api.planx.uk/modules/gis/service/index.js b/api.planx.uk/modules/gis/service/index.js index c7129f3e37..da53b7b081 100644 --- a/api.planx.uk/modules/gis/service/index.js +++ b/api.planx.uk/modules/gis/service/index.js @@ -1,8 +1,8 @@ -const localAuthorities = { - braintree: require("./local_authorities/braintree"), - scotland: require("./local_authorities/scotland"), - digitalLand: require("./digitalLand"), -}; +import * as digitalLand from "./digitalLand.js"; +import * as scotland from "./local_authorities/scotland.js"; +import * as braintree from "./local_authorities/braintree.js"; + +const localAuthorities = { digitalLand, braintree, scotland }; /** * @swagger diff --git a/api.planx.uk/modules/gis/service/index.test.ts b/api.planx.uk/modules/gis/service/index.test.ts index 533454979d..cee3abeaa7 100644 --- a/api.planx.uk/modules/gis/service/index.test.ts +++ b/api.planx.uk/modules/gis/service/index.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import loadOrRecordNockRequests from "../../../tests/loadOrRecordNockRequests"; -import app from "../../../server"; -import { locationSearchWithTimeout } from "."; +import loadOrRecordNockRequests from "../../../tests/loadOrRecordNockRequests.js"; +import app from "../../../server.js"; +import { locationSearchWithTimeout } from "./index.js"; // Tests commented out due to reliance on external API calls and fallibility of nocks // Please comment in and run locally if making changes to /gis functionality diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/barkingAndDagenham.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/barkingAndDagenham.ts index 96d8eda3a7..fc5c2cec3d 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/barkingAndDagenham.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/barkingAndDagenham.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1UmxQ95SjU72j0KaVIIkrIfhdE_k_lcFNhUWBc53GEIA/edit#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/barnet.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/barnet.ts index 521e591ac8..25eb1c85bf 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/barnet.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/barnet.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1ZjqYdC7upA8YS9rBoyRIQPT1sqCXJBaxQDrvUh1todU/edit#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/birmingham.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/birmingham.ts index 7c734a413c..73d1d9936d 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/birmingham.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/birmingham.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/19t4DKDvyWix1Vf5huuQPVf9L8e6jcq1W/edit#gid=207440632 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/buckinghamshire.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/buckinghamshire.ts index 45c1e12d1f..94ef1bb2c0 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/buckinghamshire.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/buckinghamshire.ts @@ -9,7 +9,7 @@ https://environment.data.gov.uk/arcgis/rest/services https://inspire.wycombe.gov.uk/ (legacy) */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/camden.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/camden.ts index 2bd3461361..4726227fb4 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/camden.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/camden.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1pFzq0cv_cwDx33d8QgRPVfIXtiseSxgmwQb6cORCVYs/edit#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/canterbury.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/canterbury.ts index 33869533eb..93271a9e52 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/canterbury.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/canterbury.ts @@ -9,7 +9,7 @@ https://mapping.canterbury.gov.uk/arcgis/rest/services/ https://environment.data.gov.uk/arcgis/rest/services */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/doncaster.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/doncaster.ts index b049066050..c5d972e763 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/doncaster.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/doncaster.ts @@ -8,7 +8,7 @@ https://maps.doncaster.gov.uk/portal/apps/webappviewer/index.html?id=2435bce5ee1 https://www.doncaster.gov.uk/services/planning/houses-in-multiple-occupation-article-4-direction */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/epsomAndEwell.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/epsomAndEwell.ts index 0880301d9b..9b051745b6 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/epsomAndEwell.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/epsomAndEwell.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1BzYZ_YvJjOrY2afxPGWbPvV2g_FLBr0H/edit#gid=125611981 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/gateshead.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/gateshead.ts index bb46309ff9..070f298838 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/gateshead.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/gateshead.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/13RdEvCfydfSx6R6p4S742xubOhfea-tvR3n95sYUpvs/edit#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/gloucester.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/gloucester.ts index 431ac5a29b..f1556bc339 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/gloucester.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/gloucester.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction&dataset=art https://docs.google.com/spreadsheets/d/1ALSH4hiupdUlrA7Rq7jhfHnWr0-PcB-IzhsztPLl7FY/edit?gid=0#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/lambeth.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/lambeth.ts index 572c99d57e..339c259da5 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/lambeth.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/lambeth.ts @@ -9,7 +9,7 @@ https://gis.lambeth.gov.uk/arcgis/rest/services https://environment.data.gov.uk/arcgis/rest/services */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/medway.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/medway.ts index 58bd3e94d1..9a64535402 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/medway.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/medway.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://trello.com/c/cpNv0iyO/42-input-your-article-4-direction-information-into-this-spreadsheet */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/newcastle.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/newcastle.ts index 9fec202f66..c82f38c841 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/newcastle.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/newcastle.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1GhxQEuKeSnrchZ_quxg6Rg7fHEWPDUr7/edit#gid=915271261 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/southwark.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/southwark.ts index 22218376b3..4c275973e2 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/southwark.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/southwark.ts @@ -8,7 +8,7 @@ https://geo.southwark.gov.uk/connect/analyst/mobile/#/main https://environment.data.gov.uk/arcgis/rest/services */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/stAlbans.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/stAlbans.ts index 373358fed8..717f142015 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/stAlbans.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/stAlbans.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/17qaNhd7M-F90KZ34kVjyetTxfxECf1QUU8UI-aUiknU/edit#gid=0 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/tewkesbury.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/tewkesbury.ts index 9c84c7b13c..7140025940 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/tewkesbury.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/tewkesbury.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/19VMxVhzIt3z1CcvlhELuUxablfbw40Ri/edit#gid=1979469480 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/gis/service/local_authorities/metadata/westBerkshire.ts b/api.planx.uk/modules/gis/service/local_authorities/metadata/westBerkshire.ts index 3b46bd7dc3..56abd862de 100644 --- a/api.planx.uk/modules/gis/service/local_authorities/metadata/westBerkshire.ts +++ b/api.planx.uk/modules/gis/service/local_authorities/metadata/westBerkshire.ts @@ -8,7 +8,7 @@ https://www.planning.data.gov.uk/entity/?dataset=article-4-direction-area&geomet https://docs.google.com/spreadsheets/d/1dRTb8xhcJgsQB8zIFregenm5aEzrZGU_/edit#gid=322896440 */ -import { LocalAuthorityMetadata } from "../../digitalLand"; +import { LocalAuthorityMetadata } from "../../digitalLand.js"; const planningConstraints: LocalAuthorityMetadata["planningConstraints"] = { article4: { diff --git a/api.planx.uk/modules/misc/controller.ts b/api.planx.uk/modules/misc/controller.ts index 0d630dda8a..b89bf440aa 100644 --- a/api.planx.uk/modules/misc/controller.ts +++ b/api.planx.uk/modules/misc/controller.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { stringify } from "csv-stringify"; import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; export const healthCheck: RequestHandler = (_req, res) => res.json({ hello: "world" }); diff --git a/api.planx.uk/modules/misc/routes.test.ts b/api.planx.uk/modules/misc/routes.test.ts index 68b215bd3f..77bfd71c18 100644 --- a/api.planx.uk/modules/misc/routes.test.ts +++ b/api.planx.uk/modules/misc/routes.test.ts @@ -1,5 +1,5 @@ import supertest from "supertest"; -import app from "../../server"; +import app from "../../server.js"; describe("healthcheck endpoint", () => { it("always returns a 200", async () => { diff --git a/api.planx.uk/modules/misc/routes.ts b/api.planx.uk/modules/misc/routes.ts index c01ef42c1e..8642209986 100644 --- a/api.planx.uk/modules/misc/routes.ts +++ b/api.planx.uk/modules/misc/routes.ts @@ -1,10 +1,10 @@ -import { validate } from "./../../shared/middleware/validate"; +import { validate } from "./../../shared/middleware/validate.js"; import { Router } from "express"; import { downloadApplicationController, downloadApplicationSchema, healthCheck, -} from "./controller"; +} from "./controller.js"; const router = Router(); diff --git a/api.planx.uk/modules/ordnanceSurvey/controller.ts b/api.planx.uk/modules/ordnanceSurvey/controller.ts index 41508db02b..607e489196 100644 --- a/api.planx.uk/modules/ordnanceSurvey/controller.ts +++ b/api.planx.uk/modules/ordnanceSurvey/controller.ts @@ -1,4 +1,4 @@ -import { useProxy } from "../../shared/middleware/proxy"; +import { useProxy } from "../../shared/middleware/proxy.js"; import { NextFunction, Request, Response } from "express"; import { IncomingMessage } from "http"; diff --git a/api.planx.uk/modules/ordnanceSurvey/ordnanceSurvey.test.ts b/api.planx.uk/modules/ordnanceSurvey/ordnanceSurvey.test.ts index 56e38d548c..aead559dd3 100644 --- a/api.planx.uk/modules/ordnanceSurvey/ordnanceSurvey.test.ts +++ b/api.planx.uk/modules/ordnanceSurvey/ordnanceSurvey.test.ts @@ -1,8 +1,8 @@ import { Request } from "express"; import nock from "nock"; import supertest from "supertest"; -import app from "../../server"; -import { appendAPIKey, OS_DOMAIN } from "./controller"; +import app from "../../server.js"; +import { appendAPIKey, OS_DOMAIN } from "./controller.js"; const { get } = supertest(app); diff --git a/api.planx.uk/modules/ordnanceSurvey/routes.ts b/api.planx.uk/modules/ordnanceSurvey/routes.ts index b8f5204c94..db9039944e 100644 --- a/api.planx.uk/modules/ordnanceSurvey/routes.ts +++ b/api.planx.uk/modules/ordnanceSurvey/routes.ts @@ -1,5 +1,5 @@ import { Router } from "express"; -import { useOrdnanceSurveyProxy } from "./controller"; +import { useOrdnanceSurveyProxy } from "./controller.js"; const router = Router(); diff --git a/api.planx.uk/modules/pay/controller.ts b/api.planx.uk/modules/pay/controller.ts index 0f8a304335..57ae9a94b7 100644 --- a/api.planx.uk/modules/pay/controller.ts +++ b/api.planx.uk/modules/pay/controller.ts @@ -1,20 +1,20 @@ import assert from "assert"; import { Request } from "express"; import { responseInterceptor } from "http-proxy-middleware"; -import { logPaymentStatus } from "./helpers"; -import { usePayProxy } from "./proxy"; -import { $api } from "../../client"; -import { ServerError } from "../../errors"; +import { logPaymentStatus } from "./helpers.js"; +import { usePayProxy } from "./proxy.js"; +import { $api } from "../../client/index.js"; +import { ServerError } from "../../errors/index.js"; import { GovUKPayment, PaymentRequest } from "@opensystemslab/planx-core/types"; import { addGovPayPaymentIdToPaymentRequest, postPaymentNotificationToSlack, -} from "./service/utils"; +} from "./service/utils.js"; import { InviteToPayController, PaymentProxyController, PaymentRequestProxyController, -} from "./types"; +} from "./types.js"; assert(process.env.SLACK_WEBHOOK_URL); diff --git a/api.planx.uk/modules/pay/helpers.ts b/api.planx.uk/modules/pay/helpers.ts index ee8826cae7..76d8296c3c 100644 --- a/api.planx.uk/modules/pay/helpers.ts +++ b/api.planx.uk/modules/pay/helpers.ts @@ -1,6 +1,6 @@ import { gql } from "graphql-request"; -import airbrake from "../../airbrake"; -import { $api } from "../../client"; +import airbrake from "../../airbrake.js"; +import { $api } from "../../client/index.js"; export async function logPaymentStatus({ sessionId, diff --git a/api.planx.uk/modules/pay/index.test.ts b/api.planx.uk/modules/pay/index.test.ts index f2b9d5a6f4..9539d22f5d 100644 --- a/api.planx.uk/modules/pay/index.test.ts +++ b/api.planx.uk/modules/pay/index.test.ts @@ -1,8 +1,8 @@ import nock from "nock"; -import { queryMock } from "../../tests/graphqlQueryMock"; +import { queryMock } from "../../tests/graphqlQueryMock.js"; import supertest from "supertest"; -import app from "../../server"; +import app from "../../server.js"; jest.mock("@opensystemslab/planx-core", () => { return { diff --git a/api.planx.uk/modules/pay/middleware.ts b/api.planx.uk/modules/pay/middleware.ts index b036f0c09c..266cb37356 100644 --- a/api.planx.uk/modules/pay/middleware.ts +++ b/api.planx.uk/modules/pay/middleware.ts @@ -1,8 +1,8 @@ import { NextFunction, Request, RequestHandler, Response } from "express"; import { gql } from "graphql-request"; -import { $api } from "../../client"; -import { ServerError } from "../../errors"; -import { GovPayMetadata } from "./types"; +import { $api } from "../../client/index.js"; +import { ServerError } from "../../errors/index.js"; +import { GovPayMetadata } from "./types.js"; import { formatGovPayMetadata } from "@opensystemslab/planx-core"; import { GovPayMetadataValue, diff --git a/api.planx.uk/modules/pay/proxy.ts b/api.planx.uk/modules/pay/proxy.ts index f6507fcb89..446f59627d 100644 --- a/api.planx.uk/modules/pay/proxy.ts +++ b/api.planx.uk/modules/pay/proxy.ts @@ -1,6 +1,6 @@ import { Response, Request } from "express"; import { fixRequestBody, Options } from "http-proxy-middleware"; -import { useProxy } from "../../shared/middleware/proxy"; +import { useProxy } from "../../shared/middleware/proxy.js"; export const usePayProxy = ( options: Partial, diff --git a/api.planx.uk/modules/pay/routes.ts b/api.planx.uk/modules/pay/routes.ts index 928f3b764e..e7c0d9c155 100644 --- a/api.planx.uk/modules/pay/routes.ts +++ b/api.planx.uk/modules/pay/routes.ts @@ -4,19 +4,19 @@ import { inviteToPay, makeInviteToPayPaymentViaProxy, makePaymentViaProxy, -} from "./controller"; +} from "./controller.js"; import { buildPaymentPayload, fetchPaymentRequestDetails, isTeamUsingGovPay, -} from "./middleware"; +} from "./middleware.js"; import { inviteToPaySchema, paymentProxySchema, paymentRequestProxySchema, -} from "./types"; -import { validate } from "../../shared/middleware/validate"; -import { fetchPaymentRequestViaProxy } from "./service/inviteToPay"; +} from "./types.js"; +import { validate } from "../../shared/middleware/validate.js"; +import { fetchPaymentRequestViaProxy } from "./service/inviteToPay/index.js"; const router = Router(); diff --git a/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.test.ts b/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.test.ts index 2415f96bf6..d9cf2abbeb 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.test.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import app from "../../../../server"; -import { createScheduledEvent } from "../../../../lib/hasura/metadata"; -import { queryMock } from "../../../../tests/graphqlQueryMock"; -import { flowWithInviteToPay } from "../../../../tests/mocks/inviteToPayData"; +import app from "../../../../server.js"; +import { createScheduledEvent } from "../../../../lib/hasura/metadata/index.js"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; +import { flowWithInviteToPay } from "../../../../tests/mocks/inviteToPayData.js"; jest.mock("../../../../lib/hasura/metadata"); const mockedCreateScheduledEvent = createScheduledEvent as jest.MockedFunction< diff --git a/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.ts b/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.ts index 2c67cd6027..88380568d3 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/createPaymentSendEvents.ts @@ -4,10 +4,10 @@ import { gql } from "graphql-request"; import { CombinedResponse, createScheduledEvent, -} from "../../../../lib/hasura/metadata"; -import { $api, $public } from "../../../../client"; -import { getMostRecentPublishedFlow } from "../../../../helpers"; -import { Flow, Node } from "../../../../types"; +} from "../../../../lib/hasura/metadata/index.js"; +import { $api, $public } from "../../../../client/index.js"; +import { getMostRecentPublishedFlow } from "../../../../helpers.js"; +import { Flow, Node } from "../../../../types.js"; enum Destination { BOPS = "bops", diff --git a/api.planx.uk/modules/pay/service/inviteToPay/index.test.ts b/api.planx.uk/modules/pay/service/inviteToPay/index.test.ts index 1dac53c222..7e67732ced 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/index.test.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/index.test.ts @@ -1,6 +1,6 @@ import supertest from "supertest"; -import { queryMock } from "../../../../tests/graphqlQueryMock"; -import app from "../../../../server"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; +import app from "../../../../server.js"; import { validSessionQueryMock, notFoundQueryMock, @@ -10,14 +10,14 @@ import { unlockSessionQueryMock, getPublishedFlowDataQueryMock, createPaymentRequestQueryMock, -} from "../../../../tests/mocks/inviteToPayMocks"; +} from "../../../../tests/mocks/inviteToPayMocks.js"; import { payee, applicant, validSession, notFoundSession, paymentRequestResponse, -} from "../../../../tests/mocks/inviteToPayData"; +} from "../../../../tests/mocks/inviteToPayData.js"; describe("Invite to pay API route", () => { const inviteToPayBaseRoute = "/invite-to-pay"; diff --git a/api.planx.uk/modules/pay/service/inviteToPay/index.ts b/api.planx.uk/modules/pay/service/inviteToPay/index.ts index f7b095ca4d..263eea1e4b 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/index.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/index.ts @@ -1,3 +1,3 @@ -export * from "./paymentRequest"; -export * from "./sendPaymentEmail"; -export * from "./sendConfirmationEmail"; +export * from "./paymentRequest.js"; +export * from "./sendPaymentEmail.js"; +export * from "./sendConfirmationEmail.js"; diff --git a/api.planx.uk/modules/pay/service/inviteToPay/paymentRequest.ts b/api.planx.uk/modules/pay/service/inviteToPay/paymentRequest.ts index e69278d87e..f9e2b7179f 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/paymentRequest.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/paymentRequest.ts @@ -1,9 +1,9 @@ import { gql } from "graphql-request"; import { Request } from "express"; -import { fetchPaymentViaProxyWithCallback } from "../../controller"; +import { fetchPaymentViaProxyWithCallback } from "../../controller.js"; import { GovUKPayment } from "@opensystemslab/planx-core/types"; -import { $api } from "../../../../client"; -import { postPaymentNotificationToSlack } from "../utils"; +import { $api } from "../../../../client/index.js"; +import { postPaymentNotificationToSlack } from "../utils.js"; export const fetchPaymentRequestViaProxy = fetchPaymentViaProxyWithCallback( async (req: Request, govUkResponse: GovUKPayment) => { diff --git a/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.test.ts b/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.test.ts index 6150f6b4a2..48e10ac9c5 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.test.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import app from "../../../../server"; -import { queryMock } from "../../../../tests/graphqlQueryMock"; -import { sendAgentAndPayeeConfirmationEmail } from "./sendConfirmationEmail"; -import { sendEmail } from "../../../../lib/notify"; +import app from "../../../../server.js"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; +import { sendAgentAndPayeeConfirmationEmail } from "./sendConfirmationEmail.js"; +import { sendEmail } from "../../../../lib/notify/index.js"; jest.mock("../../../../lib/notify", () => ({ sendEmail: jest.fn(), diff --git a/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.ts b/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.ts index be197253be..36692bb626 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/sendConfirmationEmail.ts @@ -1,8 +1,8 @@ import { formatRawProjectTypes } from "@opensystemslab/planx-core"; import { gql } from "graphql-request"; -import { $api } from "../../../../client"; -import { sendEmail } from "../../../../lib/notify"; -import type { AgentAndPayeeSubmissionNotifyConfig } from "../../../../types"; +import { $api } from "../../../../client/index.js"; +import { sendEmail } from "../../../../lib/notify/index.js"; +import type { AgentAndPayeeSubmissionNotifyConfig } from "../../../../types.js"; export async function sendAgentAndPayeeConfirmationEmail(sessionId: string) { const { personalisation, applicantEmail, payeeEmail, projectTypes } = diff --git a/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.test.ts b/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.test.ts index 191dc6c522..2c4da1acd4 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.test.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.test.ts @@ -1,11 +1,11 @@ import supertest from "supertest"; -import app from "../../../../server"; -import { queryMock } from "../../../../tests/graphqlQueryMock"; +import app from "../../../../server.js"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; import { validatePaymentRequestNotFoundQueryMock, validatePaymentRequestQueryMock, -} from "../../../../tests/mocks/inviteToPayMocks"; +} from "../../../../tests/mocks/inviteToPayMocks.js"; const TEST_PAYMENT_REQUEST_ID = "09655c28-3f34-4619-9385-cd57312acc44"; diff --git a/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.ts b/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.ts index acb92aa972..0cc4b48ae8 100644 --- a/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.ts +++ b/api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.ts @@ -5,12 +5,12 @@ import { Template, getClientForTemplate, sendEmail, -} from "../../../../lib/notify"; -import { InviteToPayNotifyConfig } from "../../../../types"; +} from "../../../../lib/notify/index.js"; +import { InviteToPayNotifyConfig } from "../../../../types.js"; import { calculateExpiryDate, getServiceLink, -} from "../../../saveAndReturn/service/utils"; +} from "../../../saveAndReturn/service/utils.js"; interface SessionDetails { email: string; diff --git a/api.planx.uk/modules/pay/service/utils.test.ts b/api.planx.uk/modules/pay/service/utils.test.ts index 7ca52c07f4..90a325caa5 100644 --- a/api.planx.uk/modules/pay/service/utils.test.ts +++ b/api.planx.uk/modules/pay/service/utils.test.ts @@ -1,5 +1,5 @@ import { GovUKPayment } from "@opensystemslab/planx-core/types"; -import { isTestPayment } from "./utils"; +import { isTestPayment } from "./utils.js"; describe("isTestPayment() helper function", () => { const OLD_ENV = process.env; diff --git a/api.planx.uk/modules/pay/service/utils.ts b/api.planx.uk/modules/pay/service/utils.ts index 84dfd71a80..1c7c2dc062 100644 --- a/api.planx.uk/modules/pay/service/utils.ts +++ b/api.planx.uk/modules/pay/service/utils.ts @@ -1,5 +1,5 @@ import { GovUKPayment } from "@opensystemslab/planx-core/types"; -import { $api } from "../../../client"; +import { $api } from "../../../client/index.js"; import { gql } from "graphql-request"; import SlackNotify from "slack-notify"; diff --git a/api.planx.uk/modules/pay/types.ts b/api.planx.uk/modules/pay/types.ts index 9ce0d7a328..268324db37 100644 --- a/api.planx.uk/modules/pay/types.ts +++ b/api.planx.uk/modules/pay/types.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; import { PaymentRequest } from "@opensystemslab/planx-core/types"; export const paymentProxySchema = z.object({ diff --git a/api.planx.uk/modules/saveAndReturn/controller.ts b/api.planx.uk/modules/saveAndReturn/controller.ts index 4f1df04a49..d1c0d5a958 100644 --- a/api.planx.uk/modules/saveAndReturn/controller.ts +++ b/api.planx.uk/modules/saveAndReturn/controller.ts @@ -1,6 +1,6 @@ -import { resumeApplication } from "./service/resumeApplication"; -import { findSession, validateSession } from "./service/validateSession"; -import { ResumeApplication, ValidateSessionController } from "./types"; +import { resumeApplication } from "./service/resumeApplication.js"; +import { findSession, validateSession } from "./service/validateSession.js"; +import { ResumeApplication, ValidateSessionController } from "./types.js"; export const validateSessionController: ValidateSessionController = async ( _req, diff --git a/api.planx.uk/modules/saveAndReturn/routes.ts b/api.planx.uk/modules/saveAndReturn/routes.ts index eb946abbf1..df812e22bb 100644 --- a/api.planx.uk/modules/saveAndReturn/routes.ts +++ b/api.planx.uk/modules/saveAndReturn/routes.ts @@ -3,10 +3,10 @@ import { Router } from "express"; import { resumeApplicationController, validateSessionController, -} from "./controller"; -import { sendEmailLimiter } from "../../rateLimit"; -import { validate } from "../../shared/middleware/validate"; -import { resumeApplicationSchema, validateSessionSchema } from "./types"; +} from "./controller.js"; +import { sendEmailLimiter } from "../../rateLimit.js"; +import { validate } from "../../shared/middleware/validate.js"; +import { resumeApplicationSchema, validateSessionSchema } from "./types.js"; const router = Router(); diff --git a/api.planx.uk/modules/saveAndReturn/service/resumeApplication.test.ts b/api.planx.uk/modules/saveAndReturn/service/resumeApplication.test.ts index c1464a59c1..7cb57e8e8d 100644 --- a/api.planx.uk/modules/saveAndReturn/service/resumeApplication.test.ts +++ b/api.planx.uk/modules/saveAndReturn/service/resumeApplication.test.ts @@ -1,12 +1,12 @@ -import { LowCalSession } from "../../../types"; +import { LowCalSession } from "../../../types.js"; import supertest from "supertest"; -import app from "../../../server"; -import { queryMock } from "../../../tests/graphqlQueryMock"; +import app from "../../../server.js"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; import { mockLowcalSession, mockTeam, -} from "../../../tests/mocks/saveAndReturnMocks"; -import { buildContentFromSessions } from "./resumeApplication"; +} from "../../../tests/mocks/saveAndReturnMocks.js"; +import { buildContentFromSessions } from "./resumeApplication.js"; import { PartialDeep } from "type-fest"; import { Team } from "@opensystemslab/planx-core/types"; diff --git a/api.planx.uk/modules/saveAndReturn/service/resumeApplication.ts b/api.planx.uk/modules/saveAndReturn/service/resumeApplication.ts index 3c33c34e09..ba9f8d8f52 100644 --- a/api.planx.uk/modules/saveAndReturn/service/resumeApplication.ts +++ b/api.planx.uk/modules/saveAndReturn/service/resumeApplication.ts @@ -3,10 +3,14 @@ import type { SiteAddress, Team } from "@opensystemslab/planx-core/types"; import { differenceInDays } from "date-fns"; import { gql } from "graphql-request"; -import { $api } from "../../../client"; -import { sendEmail } from "../../../lib/notify"; -import { LowCalSession } from "../../../types"; -import { DAYS_UNTIL_EXPIRY, calculateExpiryDate, getResumeLink } from "./utils"; +import { $api } from "../../../client/index.js"; +import { sendEmail } from "../../../lib/notify/index.js"; +import { LowCalSession } from "../../../types.js"; +import { + DAYS_UNTIL_EXPIRY, + calculateExpiryDate, + getResumeLink, +} from "./utils.js"; /** * Send a "Resume" email to an applicant which list all open applications for a given council (team) diff --git a/api.planx.uk/modules/saveAndReturn/service/utils.test.ts b/api.planx.uk/modules/saveAndReturn/service/utils.test.ts index 6cf33d0649..de2af88a05 100644 --- a/api.planx.uk/modules/saveAndReturn/service/utils.test.ts +++ b/api.planx.uk/modules/saveAndReturn/service/utils.test.ts @@ -1,11 +1,11 @@ import { Team } from "@opensystemslab/planx-core/types"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import { LowCalSession, LowCalSessionData } from "../../../types"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import { LowCalSession, LowCalSessionData } from "../../../types.js"; import { getResumeLink, getSessionDetails, setupEmailEventTriggers, -} from "./utils"; +} from "./utils.js"; describe("getResumeLink util function", () => { it("should return the correct value for a custom domain", () => { diff --git a/api.planx.uk/modules/saveAndReturn/service/utils.ts b/api.planx.uk/modules/saveAndReturn/service/utils.ts index 492cacf10e..72ba0b4ed7 100644 --- a/api.planx.uk/modules/saveAndReturn/service/utils.ts +++ b/api.planx.uk/modules/saveAndReturn/service/utils.ts @@ -3,9 +3,13 @@ import { SiteAddress, Team } from "@opensystemslab/planx-core/types"; import { addDays, format } from "date-fns"; import { gql } from "graphql-request"; -import { $api } from "../../../client"; -import { Template, getClientForTemplate, sendEmail } from "../../../lib/notify"; -import { LowCalSession } from "../../../types"; +import { $api } from "../../../client/index.js"; +import { + Template, + getClientForTemplate, + sendEmail, +} from "../../../lib/notify/index.js"; +import { LowCalSession } from "../../../types.js"; const DAYS_UNTIL_EXPIRY = 28; const REMINDER_DAYS_FROM_EXPIRY = [7, 1]; diff --git a/api.planx.uk/modules/saveAndReturn/service/validateSession.test.ts b/api.planx.uk/modules/saveAndReturn/service/validateSession.test.ts index 64c51ee32f..b27d09948c 100644 --- a/api.planx.uk/modules/saveAndReturn/service/validateSession.test.ts +++ b/api.planx.uk/modules/saveAndReturn/service/validateSession.test.ts @@ -1,7 +1,7 @@ import supertest from "supertest"; -import { omit } from "lodash"; -import app from "../../../server"; -import { queryMock } from "../../../tests/graphqlQueryMock"; +import omit from "lodash/omit.js"; +import app from "../../../server.js"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; import { mockFlow, mockLowcalSession, @@ -13,10 +13,10 @@ import { stubUpdateLowcalSessionData, mockLockedSession, mockErrorSession, -} from "../../../tests/mocks/saveAndReturnMocks"; -import type { Node, Flow, Breadcrumb } from "../../../types"; -import { userContext } from "../../auth/middleware"; -import { getJWT } from "../../../tests/mockJWT"; +} from "../../../tests/mocks/saveAndReturnMocks.js"; +import type { Node, Flow, Breadcrumb } from "../../../types.js"; +import { userContext } from "../../auth/middleware.js"; +import { getJWT } from "../../../tests/mockJWT.js"; const validateSessionPath = "/validate-session"; const getStoreMock = jest.spyOn(userContext, "getStore"); diff --git a/api.planx.uk/modules/saveAndReturn/service/validateSession.ts b/api.planx.uk/modules/saveAndReturn/service/validateSession.ts index 921d09c40d..f62cf1cf50 100644 --- a/api.planx.uk/modules/saveAndReturn/service/validateSession.ts +++ b/api.planx.uk/modules/saveAndReturn/service/validateSession.ts @@ -1,6 +1,6 @@ import { gql } from "graphql-request"; -import { omit } from "lodash"; -import { getMostRecentPublishedFlow } from "../../../helpers"; +import omit from "lodash/omit.js"; +import { getMostRecentPublishedFlow } from "../../../helpers.js"; import { sortBreadcrumbs } from "@opensystemslab/planx-core"; import { ComponentType } from "@opensystemslab/planx-core/types"; import type { @@ -13,9 +13,9 @@ import type { LowCalSessionData, PublishedFlow, Node, -} from "../../../types"; -import { $api } from "../../../client"; -import { ValidationResponse } from "../types"; +} from "../../../types.js"; +import { $api } from "../../../client/index.js"; +import { ValidationResponse } from "../types.js"; export type ReconciledSession = { alteredSectionIds: Array; diff --git a/api.planx.uk/modules/saveAndReturn/types.ts b/api.planx.uk/modules/saveAndReturn/types.ts index ae66595bad..7f144d5639 100644 --- a/api.planx.uk/modules/saveAndReturn/types.ts +++ b/api.planx.uk/modules/saveAndReturn/types.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; -import { LowCalSessionData } from "../../types"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; +import { LowCalSessionData } from "../../types.js"; import { PaymentRequest } from "@opensystemslab/planx-core/types"; interface ResumeApplicationResponse { diff --git a/api.planx.uk/modules/send/bops/bops.test.ts b/api.planx.uk/modules/send/bops/bops.test.ts index 82ede07767..7ceb6f75ea 100644 --- a/api.planx.uk/modules/send/bops/bops.test.ts +++ b/api.planx.uk/modules/send/bops/bops.test.ts @@ -1,8 +1,8 @@ import nock from "nock"; import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import app from "../../../server"; -import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import app from "../../../server.js"; +import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks.js"; jest.mock("../../saveAndReturn/service/utils", () => ({ markSessionAsSubmitted: jest.fn(), diff --git a/api.planx.uk/modules/send/bops/bops.ts b/api.planx.uk/modules/send/bops/bops.ts index 0cc5585b79..99809fd214 100644 --- a/api.planx.uk/modules/send/bops/bops.ts +++ b/api.planx.uk/modules/send/bops/bops.ts @@ -1,9 +1,9 @@ import axios, { AxiosResponse } from "axios"; -import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils"; +import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js"; import { NextFunction, Request, Response } from "express"; import { gql } from "graphql-request"; -import { $api } from "../../../client"; -import { ServerError } from "../../../errors"; +import { $api } from "../../../client/index.js"; +import { ServerError } from "../../../errors/index.js"; interface SendToBOPSRequest { payload: { diff --git a/api.planx.uk/modules/send/createSendEvents/controller.ts b/api.planx.uk/modules/send/createSendEvents/controller.ts index 9cfd7c892f..4338ec3c9a 100644 --- a/api.planx.uk/modules/send/createSendEvents/controller.ts +++ b/api.planx.uk/modules/send/createSendEvents/controller.ts @@ -1,8 +1,8 @@ import { CombinedResponse, createScheduledEvent, -} from "../../../lib/hasura/metadata"; -import { CreateSendEventsController } from "./types"; +} from "../../../lib/hasura/metadata/index.js"; +import { CreateSendEventsController } from "./types.js"; // Create "One-off Scheduled Events" in Hasura from Send component for selected destinations const createSendEvents: CreateSendEventsController = async ( diff --git a/api.planx.uk/modules/send/createSendEvents/types.ts b/api.planx.uk/modules/send/createSendEvents/types.ts index e5151dadb8..ea383a88de 100644 --- a/api.planx.uk/modules/send/createSendEvents/types.ts +++ b/api.planx.uk/modules/send/createSendEvents/types.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { CombinedResponse } from "../../../lib/hasura/metadata"; -import { ValidatedRequestHandler } from "../../../shared/middleware/validate"; +import { CombinedResponse } from "../../../lib/hasura/metadata/index.js"; +import { ValidatedRequestHandler } from "../../../shared/middleware/validate.js"; const eventSchema = z.object({ localAuthority: z.string(), diff --git a/api.planx.uk/modules/send/downloadApplicationFiles/index.ts b/api.planx.uk/modules/send/downloadApplicationFiles/index.ts index a7d85a7132..d44a73dd40 100644 --- a/api.planx.uk/modules/send/downloadApplicationFiles/index.ts +++ b/api.planx.uk/modules/send/downloadApplicationFiles/index.ts @@ -1,6 +1,6 @@ import type { NextFunction, Request, Response } from "express"; -import { buildSubmissionExportZip } from "../utils/exportZip"; -import { getSessionData, getTeamEmailSettings } from "../email/service"; +import { buildSubmissionExportZip } from "../utils/exportZip.js"; +import { getSessionData, getTeamEmailSettings } from "../email/service.js"; export async function downloadApplicationFiles( req: Request, diff --git a/api.planx.uk/modules/send/email/index.test.ts b/api.planx.uk/modules/send/email/index.test.ts index c0b2cae2f1..30097622da 100644 --- a/api.planx.uk/modules/send/email/index.test.ts +++ b/api.planx.uk/modules/send/email/index.test.ts @@ -1,6 +1,6 @@ import supertest from "supertest"; -import { queryMock } from "../../../tests/graphqlQueryMock"; -import app from "../../../server"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; +import app from "../../../server.js"; const mockGenerateCSVData = jest.fn().mockResolvedValue([ { diff --git a/api.planx.uk/modules/send/email/index.ts b/api.planx.uk/modules/send/email/index.ts index 48e5d5f680..20dfc83fd3 100644 --- a/api.planx.uk/modules/send/email/index.ts +++ b/api.planx.uk/modules/send/email/index.ts @@ -1,12 +1,12 @@ import type { NextFunction, Request, Response } from "express"; -import { sendEmail } from "../../../lib/notify"; -import { EmailSubmissionNotifyConfig } from "../../../types"; -import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils"; +import { sendEmail } from "../../../lib/notify/index.js"; +import { EmailSubmissionNotifyConfig } from "../../../types.js"; +import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js"; import { getSessionEmailDetailsById, getTeamEmailSettings, insertAuditEntry, -} from "./service"; +} from "./service.js"; export async function sendToEmail( req: Request, diff --git a/api.planx.uk/modules/send/email/service.ts b/api.planx.uk/modules/send/email/service.ts index 7cb7e0e606..e5b1776be4 100644 --- a/api.planx.uk/modules/send/email/service.ts +++ b/api.planx.uk/modules/send/email/service.ts @@ -1,8 +1,10 @@ import { gql } from "graphql-request"; -import { $api } from "../../../client"; -import { NotifyPersonalisation } from "@opensystemslab/planx-core/dist/types/team"; -import { Session } from "@opensystemslab/planx-core/types"; -import { EmailSubmissionNotifyConfig } from "../../../types"; +import { $api } from "../../../client/index.js"; +import { + NotifyPersonalisation, + Session, +} from "@opensystemslab/planx-core/types"; +import { EmailSubmissionNotifyConfig } from "../../../types.js"; interface GetTeamEmailSettings { teams: { diff --git a/api.planx.uk/modules/send/idox/nexus.test.ts b/api.planx.uk/modules/send/idox/nexus.test.ts index e8e2bf793e..c5c0872de2 100644 --- a/api.planx.uk/modules/send/idox/nexus.test.ts +++ b/api.planx.uk/modules/send/idox/nexus.test.ts @@ -1,5 +1,5 @@ import supertest from "supertest"; -import app from "../../../server"; +import app from "../../../server.js"; describe(`sending an application to Idox Nexus`, () => { it("fails without authorization header", async () => { diff --git a/api.planx.uk/modules/send/idox/nexus.ts b/api.planx.uk/modules/send/idox/nexus.ts index 4adb6ad97f..109e304f0d 100644 --- a/api.planx.uk/modules/send/idox/nexus.ts +++ b/api.planx.uk/modules/send/idox/nexus.ts @@ -5,9 +5,9 @@ import fs from "fs"; import { gql } from "graphql-request"; import jwt from "jsonwebtoken"; import { Buffer } from "node:buffer"; -import { $api } from "../../../client"; -import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils"; -import { buildSubmissionExportZip } from "../utils/exportZip"; +import { $api } from "../../../client/index.js"; +import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js"; +import { buildSubmissionExportZip } from "../utils/exportZip.js"; interface UniformClient { clientId: string; diff --git a/api.planx.uk/modules/send/routes.ts b/api.planx.uk/modules/send/routes.ts index 5447f7ad3d..bcec19196b 100644 --- a/api.planx.uk/modules/send/routes.ts +++ b/api.planx.uk/modules/send/routes.ts @@ -1,14 +1,14 @@ import { Router } from "express"; -import { createSendEvents } from "./createSendEvents/controller"; -import { useHasuraAuth } from "../auth/middleware"; -import { sendToBOPS } from "./bops/bops"; -import { sendToUniform } from "./uniform/uniform"; -import { sendToEmail } from "./email"; -import { validate } from "../../shared/middleware/validate"; -import { combinedEventsPayloadSchema } from "./createSendEvents/types"; -import { downloadApplicationFiles } from "./downloadApplicationFiles"; -import { sendToS3 } from "./s3"; -import { sendToIdoxNexus } from "./idox/nexus"; +import { createSendEvents } from "./createSendEvents/controller.js"; +import { useHasuraAuth } from "../auth/middleware.js"; +import { sendToBOPS } from "./bops/bops.js"; +import { sendToUniform } from "./uniform/uniform.js"; +import { sendToEmail } from "./email/index.js"; +import { validate } from "../../shared/middleware/validate.js"; +import { combinedEventsPayloadSchema } from "./createSendEvents/types.js"; +import { downloadApplicationFiles } from "./downloadApplicationFiles/index.js"; +import { sendToS3 } from "./s3/index.js"; +import { sendToIdoxNexus } from "./idox/nexus.js"; const router = Router(); diff --git a/api.planx.uk/modules/send/s3/index.test.ts b/api.planx.uk/modules/send/s3/index.test.ts index 352c8c07ef..6538474ec5 100644 --- a/api.planx.uk/modules/send/s3/index.test.ts +++ b/api.planx.uk/modules/send/s3/index.test.ts @@ -1,7 +1,7 @@ import supertest from "supertest"; -import app from "../../../server"; -import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks"; -import { queryMock } from "../../../tests/graphqlQueryMock"; +import app from "../../../server.js"; +import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks.js"; +import { queryMock } from "../../../tests/graphqlQueryMock.js"; jest.mock("../../saveAndReturn/service/utils", () => ({ markSessionAsSubmitted: jest.fn(), diff --git a/api.planx.uk/modules/send/s3/index.ts b/api.planx.uk/modules/send/s3/index.ts index 26da23781d..51909b2428 100644 --- a/api.planx.uk/modules/send/s3/index.ts +++ b/api.planx.uk/modules/send/s3/index.ts @@ -2,11 +2,11 @@ import axios, { AxiosRequestConfig } from "axios"; import type { NextFunction, Request, Response } from "express"; import { gql } from "graphql-request"; -import { $api } from "../../../client"; -import { Passport } from "../../../types"; -import { uploadPrivateFile } from "../../file/service/uploadFile"; -import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils"; -import { isApplicationTypeSupported } from "../utils/helpers"; +import { $api } from "../../../client/index.js"; +import { Passport } from "../../../types.js"; +import { uploadPrivateFile } from "../../file/service/uploadFile.js"; +import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js"; +import { isApplicationTypeSupported } from "../utils/helpers.js"; interface CreateS3Application { insertS3Application: { diff --git a/api.planx.uk/modules/send/uniform/uniform.test.ts b/api.planx.uk/modules/send/uniform/uniform.test.ts index 1ba467ac74..32ffea8812 100644 --- a/api.planx.uk/modules/send/uniform/uniform.test.ts +++ b/api.planx.uk/modules/send/uniform/uniform.test.ts @@ -1,5 +1,5 @@ import supertest from "supertest"; -import app from "../../../server"; +import app from "../../../server.js"; describe(`sending an application to uniform`, () => { it("fails without authorization header", async () => { diff --git a/api.planx.uk/modules/send/uniform/uniform.ts b/api.planx.uk/modules/send/uniform/uniform.ts index 8b63aa4f2b..77b32ea8ad 100644 --- a/api.planx.uk/modules/send/uniform/uniform.ts +++ b/api.planx.uk/modules/send/uniform/uniform.ts @@ -5,9 +5,9 @@ import fs from "fs"; import { gql } from "graphql-request"; import jwt from "jsonwebtoken"; import { Buffer } from "node:buffer"; -import { $api } from "../../../client"; -import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils"; -import { buildSubmissionExportZip } from "../utils/exportZip"; +import { $api } from "../../../client/index.js"; +import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js"; +import { buildSubmissionExportZip } from "../utils/exportZip.js"; interface UniformClient { clientId: string; diff --git a/api.planx.uk/modules/send/utils/exportZip.test.ts b/api.planx.uk/modules/send/utils/exportZip.test.ts index ea9798d314..d8e6b58c99 100644 --- a/api.planx.uk/modules/send/utils/exportZip.test.ts +++ b/api.planx.uk/modules/send/utils/exportZip.test.ts @@ -1,7 +1,7 @@ -import { mockLowcalSession } from "../../../tests/mocks/saveAndReturnMocks"; -import { buildSubmissionExportZip } from "./exportZip"; -import type { LowCalSession } from "../../../types"; -import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks"; +import { mockLowcalSession } from "../../../tests/mocks/saveAndReturnMocks.js"; +import { buildSubmissionExportZip } from "./exportZip.js"; +import type { LowCalSession } from "../../../types.js"; +import { expectedPlanningPermissionPayload } from "../../../tests/mocks/digitalPlanningDataMocks.js"; jest.mock("fs", () => ({ mkdtempSync: () => "tmpdir", diff --git a/api.planx.uk/modules/send/utils/exportZip.ts b/api.planx.uk/modules/send/utils/exportZip.ts index 98843e53f2..bbe93696aa 100644 --- a/api.planx.uk/modules/send/utils/exportZip.ts +++ b/api.planx.uk/modules/send/utils/exportZip.ts @@ -1,11 +1,11 @@ import os from "os"; import path from "path"; -import { $api } from "../../../client"; +import { $api } from "../../../client/index.js"; import { stringify } from "csv-stringify"; import fs from "fs"; import str from "string-to-stream"; import AdmZip from "adm-zip"; -import { getFileFromS3 } from "../../file/service/getFile"; +import { getFileFromS3 } from "../../file/service/getFile.js"; import { hasRequiredDataForTemplate, generateMapHTML, @@ -13,10 +13,10 @@ import { generateDocxTemplateStream, } from "@opensystemslab/planx-core"; import { Passport } from "@opensystemslab/planx-core"; -import type { Passport as IPassport } from "../../../types"; +import type { Passport as IPassport } from "../../../types.js"; import type { Stream } from "node:stream"; import type { PlanXExportData } from "@opensystemslab/planx-core/types"; -import { isApplicationTypeSupported } from "./helpers"; +import { isApplicationTypeSupported } from "./helpers.js"; export async function buildSubmissionExportZip({ sessionId, diff --git a/api.planx.uk/modules/send/utils/helpers.ts b/api.planx.uk/modules/send/utils/helpers.ts index dda80de7f8..d149c9bb50 100644 --- a/api.planx.uk/modules/send/utils/helpers.ts +++ b/api.planx.uk/modules/send/utils/helpers.ts @@ -1,4 +1,4 @@ -import { Passport } from "../../../types"; +import { Passport } from "../../../types.js"; /** * Checks whether a session's passport data includes an application type supported by the ODP Schema diff --git a/api.planx.uk/modules/sendEmail/controller.ts b/api.planx.uk/modules/sendEmail/controller.ts index 0f3570c02f..fcb0c5163f 100644 --- a/api.planx.uk/modules/sendEmail/controller.ts +++ b/api.planx.uk/modules/sendEmail/controller.ts @@ -1,15 +1,15 @@ import { sendSinglePaymentEmail, sendAgentAndPayeeConfirmationEmail, -} from "../pay/service/inviteToPay"; -import { sendSingleApplicationEmail } from "../saveAndReturn/service/utils"; -import { ServerError } from "../../errors"; +} from "../pay/service/inviteToPay/index.js"; +import { sendSingleApplicationEmail } from "../saveAndReturn/service/utils.js"; +import { ServerError } from "../../errors/index.js"; import { NextFunction } from "express"; import { ConfirmationEmail, PaymentEmail, SingleApplicationEmail, -} from "./types"; +} from "./types.js"; export const singleApplicationEmailController: SingleApplicationEmail = async ( _req, diff --git a/api.planx.uk/modules/sendEmail/index.test.ts b/api.planx.uk/modules/sendEmail/index.test.ts index 153f1632de..3c696eceeb 100644 --- a/api.planx.uk/modules/sendEmail/index.test.ts +++ b/api.planx.uk/modules/sendEmail/index.test.ts @@ -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"; import { mockFlow, mockLowcalSession, @@ -8,7 +8,7 @@ import { mockSoftDeleteLowcalSession, mockValidateSingleSessionRequest, mockValidateSingleSessionRequestMissingSession, -} from "../../tests/mocks/saveAndReturnMocks"; +} from "../../tests/mocks/saveAndReturnMocks.js"; // https://docs.notifications.service.gov.uk/node.html#email-addresses const TEST_EMAIL = "simulate-delivered@notifications.service.gov.uk"; diff --git a/api.planx.uk/modules/sendEmail/routes.ts b/api.planx.uk/modules/sendEmail/routes.ts index b36b515744..07dc26a5e4 100644 --- a/api.planx.uk/modules/sendEmail/routes.ts +++ b/api.planx.uk/modules/sendEmail/routes.ts @@ -1,17 +1,17 @@ import { Router } from "express"; -import { useSendEmailAuth } from "../auth/middleware"; +import { useSendEmailAuth } from "../auth/middleware.js"; import { confirmationEmailController, paymentEmailController, singleApplicationEmailController, -} from "./controller"; -import { sendEmailLimiter } from "../../rateLimit"; -import { validate } from "../../shared/middleware/validate"; +} from "./controller.js"; +import { sendEmailLimiter } from "../../rateLimit.js"; +import { validate } from "../../shared/middleware/validate.js"; import { confirmationEmailSchema, paymentEmailSchema, singleApplicationEmailSchema, -} from "./types"; +} from "./types.js"; const router = Router(); diff --git a/api.planx.uk/modules/sendEmail/types.ts b/api.planx.uk/modules/sendEmail/types.ts index 4f17cd3a72..b070a4208c 100644 --- a/api.planx.uk/modules/sendEmail/types.ts +++ b/api.planx.uk/modules/sendEmail/types.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; interface SendEmailResponse { message: string; diff --git a/api.planx.uk/modules/team/controller.test.ts b/api.planx.uk/modules/team/controller.test.ts index e10dbae302..9d9e4d7e30 100644 --- a/api.planx.uk/modules/team/controller.test.ts +++ b/api.planx.uk/modules/team/controller.test.ts @@ -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 mockAddMember = jest.fn(); const mockRemoveMember = jest.fn(); diff --git a/api.planx.uk/modules/team/controller.ts b/api.planx.uk/modules/team/controller.ts index 69c3958eff..7447410e45 100644 --- a/api.planx.uk/modules/team/controller.ts +++ b/api.planx.uk/modules/team/controller.ts @@ -1,7 +1,7 @@ -import * as Service from "./service"; +import * as Service from "./service.js"; import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; -import { ServerError } from "../../errors"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; +import { ServerError } from "../../errors/index.js"; interface TeamMemberResponse { message: string; diff --git a/api.planx.uk/modules/team/routes.ts b/api.planx.uk/modules/team/routes.ts index 28a1d4186a..e9e112edf7 100644 --- a/api.planx.uk/modules/team/routes.ts +++ b/api.planx.uk/modules/team/routes.ts @@ -1,7 +1,7 @@ import { Router } from "express"; -import * as Controller from "./controller"; -import * as AuthMiddleware from "../auth/middleware"; -import { validate } from "../../shared/middleware/validate"; +import * as Controller from "./controller.js"; +import * as AuthMiddleware from "../auth/middleware.js"; +import { validate } from "../../shared/middleware/validate.js"; const router = Router(); diff --git a/api.planx.uk/modules/team/service.test.ts b/api.planx.uk/modules/team/service.test.ts index 2fba0d633e..e5f3e157d0 100644 --- a/api.planx.uk/modules/team/service.test.ts +++ b/api.planx.uk/modules/team/service.test.ts @@ -1,12 +1,12 @@ -import { getJWT } from "../../tests/mockJWT"; -import { userContext } from "../auth/middleware"; +import { getJWT } from "../../tests/mockJWT.js"; +import { userContext } from "../auth/middleware.js"; import { getUserAndTeam, addMember, removeMember, changeMemberRole, -} from "./service"; +} from "./service.js"; const getStoreMock = jest.spyOn(userContext, "getStore"); diff --git a/api.planx.uk/modules/team/service.ts b/api.planx.uk/modules/team/service.ts index 2e814cee49..a9c1b0a22d 100644 --- a/api.planx.uk/modules/team/service.ts +++ b/api.planx.uk/modules/team/service.ts @@ -1,4 +1,4 @@ -import { getClient } from "../../client"; +import { getClient } from "../../client/index.js"; import { TeamRole } from "@opensystemslab/planx-core/types"; interface UpsertMember { diff --git a/api.planx.uk/modules/test/routes.test.ts b/api.planx.uk/modules/test/routes.test.ts index f951b9816c..ab19578af7 100644 --- a/api.planx.uk/modules/test/routes.test.ts +++ b/api.planx.uk/modules/test/routes.test.ts @@ -1,5 +1,5 @@ import supertest from "supertest"; -import app from "../../server"; +import app from "../../server.js"; describe("Session setup", () => { test("adds dummy methods to req.session to avoid passport/cookie-session incompatibility issue", async () => { diff --git a/api.planx.uk/modules/test/routes.ts b/api.planx.uk/modules/test/routes.ts index 43fd8dacaf..5e27c27865 100644 --- a/api.planx.uk/modules/test/routes.ts +++ b/api.planx.uk/modules/test/routes.ts @@ -1,5 +1,5 @@ import { Router } from "express"; -import { testSessionMethods } from "./controller"; +import { testSessionMethods } from "./controller.js"; const router = Router(); diff --git a/api.planx.uk/modules/user/controller.ts b/api.planx.uk/modules/user/controller.ts index 11ea5cf0d1..9c4231e605 100644 --- a/api.planx.uk/modules/user/controller.ts +++ b/api.planx.uk/modules/user/controller.ts @@ -1,10 +1,10 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../shared/middleware/validate"; -import { getClient } from "../../client"; -import { ServerError } from "../../errors"; +import { ValidatedRequestHandler } from "../../shared/middleware/validate.js"; +import { getClient } from "../../client/index.js"; +import { ServerError } from "../../errors/index.js"; import { RequestHandler } from "express"; import { User } from "@opensystemslab/planx-core/types"; -import { userContext } from "../auth/middleware"; +import { userContext } from "../auth/middleware.js"; interface UserResponse { message: string; diff --git a/api.planx.uk/modules/user/index.test.ts b/api.planx.uk/modules/user/index.test.ts index c1d47b38e3..a04fe18470 100644 --- a/api.planx.uk/modules/user/index.test.ts +++ b/api.planx.uk/modules/user/index.test.ts @@ -1,7 +1,7 @@ import supertest from "supertest"; -import app from "../../server"; -import { authHeader, getJWT } from "../../tests/mockJWT"; -import { userContext } from "../auth/middleware"; +import app from "../../server.js"; +import { authHeader, getJWT } from "../../tests/mockJWT.js"; +import { userContext } from "../auth/middleware.js"; const getStoreMock = jest.spyOn(userContext, "getStore"); diff --git a/api.planx.uk/modules/user/routes.ts b/api.planx.uk/modules/user/routes.ts index c2d8fd9c36..94c2e8e722 100644 --- a/api.planx.uk/modules/user/routes.ts +++ b/api.planx.uk/modules/user/routes.ts @@ -1,13 +1,13 @@ import { Router } from "express"; -import { useLoginAuth, usePlatformAdminAuth } from "../auth/middleware"; -import { validate } from "../../shared/middleware/validate"; +import { useLoginAuth, usePlatformAdminAuth } from "../auth/middleware.js"; +import { validate } from "../../shared/middleware/validate.js"; import { createUserSchema, createUser, deleteUserSchema, deleteUser, getLoggedInUserDetails, -} from "./controller"; +} from "./controller.js"; const router = Router(); diff --git a/api.planx.uk/modules/webhooks/controller.ts b/api.planx.uk/modules/webhooks/controller.ts index 7e62483c7d..6fbd0ba6b5 100644 --- a/api.planx.uk/modules/webhooks/controller.ts +++ b/api.planx.uk/modules/webhooks/controller.ts @@ -1,21 +1,21 @@ -import { ServerError } from "../../errors"; -import { CreateSessionEventController } from "./service/lowcalSessionEvents/schema"; +import { ServerError } from ".././../errors/index.js"; +import { CreateSessionEventController } from "./service/lowcalSessionEvents/schema.js"; import { createSessionExpiryEvent, createSessionReminderEvent, -} from "./service/lowcalSessionEvents"; -import { SendSlackNotification } from "./service/sendNotification/types"; -import { sendSlackNotification } from "./service/sendNotification"; -import { CreatePaymentEventController } from "./service/paymentRequestEvents/schema"; +} from "./service/lowcalSessionEvents/index.js"; +import { SendSlackNotification } from "./service/sendNotification/types.js"; +import { sendSlackNotification } from "./service/sendNotification/index.js"; +import { CreatePaymentEventController } from "./service/paymentRequestEvents/schema.js"; import { createPaymentExpiryEvents, createPaymentInvitationEvents, createPaymentReminderEvents, -} from "./service/paymentRequestEvents"; -import { SanitiseApplicationData } from "./service/sanitiseApplicationData/types"; -import { sanitiseApplicationData } from "./service/sanitiseApplicationData"; -import { IsCleanJSONBController } from "./service/validateInput/schema"; -import { analyzeSessions } from "./service/analyzeSessions"; +} from "./service/paymentRequestEvents/index.js"; +import { SanitiseApplicationData } from "./service/sanitiseApplicationData/types.js"; +import { sanitiseApplicationData } from "./service/sanitiseApplicationData/index.js"; +import { IsCleanJSONBController } from "./service/validateInput/schema.js"; +import { analyzeSessions } from "./service/analyzeSessions/index.js"; export const sendSlackNotificationController: SendSlackNotification = async ( _req, diff --git a/api.planx.uk/modules/webhooks/routes.ts b/api.planx.uk/modules/webhooks/routes.ts index 67b7490a40..7c93646faa 100644 --- a/api.planx.uk/modules/webhooks/routes.ts +++ b/api.planx.uk/modules/webhooks/routes.ts @@ -1,7 +1,7 @@ import { Router } from "express"; -import { useHasuraAuth } from "../auth/middleware"; -import { createPaymentSendEvents } from "../pay/service/inviteToPay/createPaymentSendEvents"; -import { validate } from "../../shared/middleware/validate"; +import { useHasuraAuth } from "../auth/middleware.js"; +import { createPaymentSendEvents } from "../pay/service/inviteToPay/createPaymentSendEvents.js"; +import { validate } from "../../shared/middleware/validate.js"; import { isCleanJSONBController, createPaymentExpiryEventsController, @@ -12,11 +12,11 @@ import { sanitiseApplicationDataController, sendSlackNotificationController, analyzeSessionsController, -} from "./controller"; -import { sendSlackNotificationSchema } from "./service/sendNotification/schema"; -import { createPaymentEventSchema } from "./service/paymentRequestEvents/schema"; -import { createSessionEventSchema } from "./service/lowcalSessionEvents/schema"; -import { isCleanJSONBSchema } from "./service/validateInput/schema"; +} from "./controller.js"; +import { sendSlackNotificationSchema } from "./service/sendNotification/schema.js"; +import { createPaymentEventSchema } from "./service/paymentRequestEvents/schema.js"; +import { createSessionEventSchema } from "./service/lowcalSessionEvents/schema.js"; +import { isCleanJSONBSchema } from "./service/validateInput/schema.js"; const router = Router(); diff --git a/api.planx.uk/modules/webhooks/service/analyzeSessions/index.test.ts b/api.planx.uk/modules/webhooks/service/analyzeSessions/index.test.ts index da959adab7..f15c479835 100644 --- a/api.planx.uk/modules/webhooks/service/analyzeSessions/index.test.ts +++ b/api.planx.uk/modules/webhooks/service/analyzeSessions/index.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import app from "../../../../server"; -import * as operations from "./operations"; -import * as sharedOperations from "../sanitiseApplicationData/operations"; +import app from "../../../../server.js"; +import * as operations from "./operations.js"; +import * as sharedOperations from "../sanitiseApplicationData/operations.js"; const mockSend = jest.fn(); const mockSlackNotify = jest.fn().mockImplementation(() => { diff --git a/api.planx.uk/modules/webhooks/service/analyzeSessions/index.ts b/api.planx.uk/modules/webhooks/service/analyzeSessions/index.ts index 564efe2593..7da345cfa3 100644 --- a/api.planx.uk/modules/webhooks/service/analyzeSessions/index.ts +++ b/api.planx.uk/modules/webhooks/service/analyzeSessions/index.ts @@ -1,7 +1,7 @@ -import { postToSlack } from "../sanitiseApplicationData"; -import { operationHandler } from "../sanitiseApplicationData/operations"; -import { OperationResult } from "../sanitiseApplicationData/types"; -import { getAnalyzeSessionOperations } from "./operations"; +import { postToSlack } from "../sanitiseApplicationData/index.js"; +import { operationHandler } from "../sanitiseApplicationData/operations.js"; +import { OperationResult } from "../sanitiseApplicationData/types.js"; +import { getAnalyzeSessionOperations } from "./operations.js"; /** * Called by Hasura cron job `analyze_sessions` on a nightly basis diff --git a/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.test.ts b/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.test.ts index 898b35c0eb..e7b1dfe798 100644 --- a/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.test.ts +++ b/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.test.ts @@ -1,9 +1,9 @@ -import { queryMock } from "../../../../tests/graphqlQueryMock"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; import { getSubmittedUnAnalyzedSessionIds, updateLowcalSessionAllowListAnswers, -} from "./operations"; +} from "./operations.js"; jest.mock("../../../../lib/hasura/schema"); const mockFindSession = jest.fn(); diff --git a/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.ts b/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.ts index ca9ec158e2..98c6370ad1 100644 --- a/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.ts +++ b/api.planx.uk/modules/webhooks/service/analyzeSessions/operations.ts @@ -1,8 +1,8 @@ import { gql } from "graphql-request"; import { Passport } from "@opensystemslab/planx-core"; -import { $api } from "../../../../client"; -import { Operation } from "../sanitiseApplicationData/types"; +import { $api } from "../../../../client/index.js"; +import { Operation } from "../sanitiseApplicationData/types.js"; /** * ALLOW_LIST should stay in sync with diff --git a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.test.ts b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.test.ts index e9b4b2bcf8..5127d64a4e 100644 --- a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.test.ts +++ b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.test.ts @@ -1,6 +1,6 @@ import supertest from "supertest"; -import app from "../../../../server"; -import { createScheduledEvent } from "../../../../lib/hasura/metadata"; +import app from "../../../../server.js"; +import { createScheduledEvent } from "../../../../lib/hasura/metadata/index.js"; const { post } = supertest(app); diff --git a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.ts b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.ts index cd6d4b9855..af05363ad3 100644 --- a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.ts +++ b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/index.ts @@ -1,11 +1,11 @@ import { addDays } from "date-fns"; -import { createScheduledEvent } from "../../../../lib/hasura/metadata"; +import { createScheduledEvent } from "../../../../lib/hasura/metadata/index.js"; import { DAYS_UNTIL_EXPIRY, REMINDER_DAYS_FROM_EXPIRY, -} from "../../../saveAndReturn/service/utils"; -import { CreateSessionEvent } from "./schema"; +} from "../../../saveAndReturn/service/utils.js"; +import { CreateSessionEvent } from "./schema.js"; /** * Create "reminder" events for a lowcal_session record diff --git a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/schema.ts b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/schema.ts index 2bafddb4b5..a83dce4147 100644 --- a/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/schema.ts +++ b/api.planx.uk/modules/webhooks/service/lowcalSessionEvents/schema.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; -import { ScheduledEventResponse } from "../../../../lib/hasura/metadata"; +import { ValidatedRequestHandler } from "../../../../shared/middleware/validate.js"; +import { ScheduledEventResponse } from "../../../../lib/hasura/metadata/index.js"; export const createSessionEventSchema = z.object({ body: z.object({ diff --git a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.test.ts b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.test.ts index dc9346aeb9..6bc569e276 100644 --- a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.test.ts +++ b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.test.ts @@ -1,7 +1,7 @@ import supertest from "supertest"; -import app from "../../../../server"; -import { createScheduledEvent } from "../../../../lib/hasura/metadata"; -import { CreatePaymentEvent } from "./schema"; +import app from "../../../../server.js"; +import { createScheduledEvent } from "../../../../lib/hasura/metadata/index.js"; +import { CreatePaymentEvent } from "./schema.js"; const { post } = supertest(app); diff --git a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.ts b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.ts index c806a63550..b0f1c94c69 100644 --- a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.ts +++ b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/index.ts @@ -1,11 +1,11 @@ import { addDays } from "date-fns"; -import { createScheduledEvent } from "../../../../lib/hasura/metadata"; +import { createScheduledEvent } from "../../../../lib/hasura/metadata/index.js"; import { DAYS_UNTIL_EXPIRY, REMINDER_DAYS_FROM_EXPIRY, -} from "../../../saveAndReturn/service/utils"; -import { CreatePaymentEvent } from "./schema"; +} from "../../../saveAndReturn/service/utils.js"; +import { CreatePaymentEvent } from "./schema.js"; /** * Create two "invitation" events for a payments_request record: one for the nominee and one for the agent diff --git a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/schema.ts b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/schema.ts index 20fe20abd7..029b94dc85 100644 --- a/api.planx.uk/modules/webhooks/service/paymentRequestEvents/schema.ts +++ b/api.planx.uk/modules/webhooks/service/paymentRequestEvents/schema.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; -import { ScheduledEventResponse } from "../../../../lib/hasura/metadata"; +import { ValidatedRequestHandler } from "../../../../shared/middleware/validate.js"; +import { ScheduledEventResponse } from "../../../../lib/hasura/metadata/index.js"; export const createPaymentEventSchema = z.object({ body: z.object({ diff --git a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.test.ts b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.test.ts index 52457fa67f..24abe581a3 100644 --- a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.test.ts +++ b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.test.ts @@ -1,6 +1,6 @@ import supertest from "supertest"; -import app from "../../../../server"; -import * as operations from "./operations"; +import app from "../../../../server.js"; +import * as operations from "./operations.js"; const mockSend = jest.fn(); const mockSlackNotify = jest.fn().mockImplementation(() => { diff --git a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.ts b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.ts index d666c73c3e..1f54397767 100644 --- a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.ts +++ b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/index.ts @@ -1,8 +1,8 @@ import SlackNotify from "slack-notify"; -import { getOperations, operationHandler } from "./operations"; -import { OperationResult } from "./types"; -import { getFormattedEnvironment } from "../../../../helpers"; +import { getOperations, operationHandler } from "./operations.js"; +import { OperationResult } from "./types.js"; +import { getFormattedEnvironment } from "../../../../helpers.js"; /** * Called by Hasura cron job `sanitise_application_data` on a nightly basis diff --git a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.test.ts b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.test.ts index cec0532097..e4b15c7e90 100644 --- a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.test.ts +++ b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.test.ts @@ -1,5 +1,5 @@ -import { runSQL } from "../../../../lib/hasura/schema"; -import { queryMock } from "../../../../tests/graphqlQueryMock"; +import { runSQL } from "../../../../lib/hasura/schema/index.js"; +import { queryMock } from "../../../../tests/graphqlQueryMock.js"; import { mockIds, mockSanitiseBOPSApplicationsMutation, @@ -10,7 +10,7 @@ import { mockGetExpiredSessionIdsQuery, mockDeletePaymentRequests, mockDeleteFeedbackMutation, -} from "./mocks/queries"; +} from "./mocks/queries.js"; import { deleteHasuraEventLogs, getRetentionPeriod, @@ -25,7 +25,7 @@ import { deletePaymentRequests, deleteHasuraScheduledEventsForSubmittedSessions, deleteFeedback, -} from "./operations"; +} from "./operations.js"; jest.mock("../../../../lib/hasura/schema"); const mockRunSQL = runSQL as jest.MockedFunction; diff --git a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.ts b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.ts index 7f86686a68..5f6ce18237 100644 --- a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.ts +++ b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/operations.ts @@ -1,10 +1,10 @@ import { gql } from "graphql-request"; import { subMonths } from "date-fns"; -import { Operation, OperationResult, QueryResult } from "./types"; -import { runSQL } from "../../../../lib/hasura/schema"; -import { deleteFilesByURL } from "../../../file/service/deleteFile"; -import { $api } from "../../../../client"; +import { Operation, OperationResult, QueryResult } from "./types.js"; +import { runSQL } from "../../../../lib/hasura/schema/index.js"; +import { deleteFilesByURL } from "../../../file/service/deleteFile.js"; +import { $api } from "../../../../client/index.js"; import { Passport } from "@opensystemslab/planx-core"; const RETENTION_PERIOD_MONTHS = 6; diff --git a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/types.ts b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/types.ts index 2eef1e6677..45878199d2 100644 --- a/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/types.ts +++ b/api.planx.uk/modules/webhooks/service/sanitiseApplicationData/types.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../../shared/middleware/validate.js"; export interface OperationResult { operationName: string; diff --git a/api.planx.uk/modules/webhooks/service/sendNotification/index.test.ts b/api.planx.uk/modules/webhooks/service/sendNotification/index.test.ts index 433f8dc21b..464eaab70b 100644 --- a/api.planx.uk/modules/webhooks/service/sendNotification/index.test.ts +++ b/api.planx.uk/modules/webhooks/service/sendNotification/index.test.ts @@ -1,8 +1,8 @@ import supertest from "supertest"; -import app from "../../../../server"; +import app from "../../../../server.js"; import SlackNotify from "slack-notify"; -import { BOPSBody, EmailBody, S3Body, UniformBody } from "./types"; -import { $api } from "../../../../client"; +import { BOPSBody, EmailBody, S3Body, UniformBody } from "./types.js"; +import { $api } from "../../../../client/index.js"; import { CoreDomainClient } from "@opensystemslab/planx-core"; const mockSessionWithFee = { diff --git a/api.planx.uk/modules/webhooks/service/sendNotification/index.ts b/api.planx.uk/modules/webhooks/service/sendNotification/index.ts index c35bc225cf..c6a6160eed 100644 --- a/api.planx.uk/modules/webhooks/service/sendNotification/index.ts +++ b/api.planx.uk/modules/webhooks/service/sendNotification/index.ts @@ -7,8 +7,8 @@ import { EventType, S3EventData, UniformEventData, -} from "./types"; -import { $api } from "../../../../client"; +} from "./types.js"; +import { $api } from "../../../../client/index.js"; export const sendSlackNotification = async ( data: EventData, diff --git a/api.planx.uk/modules/webhooks/service/sendNotification/types.ts b/api.planx.uk/modules/webhooks/service/sendNotification/types.ts index 5373cebb5f..cdf96fcdab 100644 --- a/api.planx.uk/modules/webhooks/service/sendNotification/types.ts +++ b/api.planx.uk/modules/webhooks/service/sendNotification/types.ts @@ -1,12 +1,12 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; +import { ValidatedRequestHandler } from "../../../../shared/middleware/validate.js"; import { bopsSubmissionSchema, emailSubmissionSchema, s3SubmissionSchema, sendSlackNotificationSchema, uniformSubmissionSchema, -} from "./schema"; +} from "./schema.js"; interface SendSlackNotificationResponse { message: string; diff --git a/api.planx.uk/modules/webhooks/service/validateInput/schema.ts b/api.planx.uk/modules/webhooks/service/validateInput/schema.ts index f25250eb75..2a6ba837b6 100644 --- a/api.planx.uk/modules/webhooks/service/validateInput/schema.ts +++ b/api.planx.uk/modules/webhooks/service/validateInput/schema.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; -import { isCleanHTML, isObjectValid } from "./utils"; +import { ValidatedRequestHandler } from "../../../../shared/middleware/validate.js"; +import { isCleanHTML, isObjectValid } from "./utils.js"; // Definition: https://hasura.io/docs/latest/schema/postgres/input-validations/#response type HasuraValidateInputResponse = undefined | { message: string }; diff --git a/api.planx.uk/modules/webhooks/service/validateInput/utils.test.ts b/api.planx.uk/modules/webhooks/service/validateInput/utils.test.ts index 957a5b7e5c..3968d4511a 100644 --- a/api.planx.uk/modules/webhooks/service/validateInput/utils.test.ts +++ b/api.planx.uk/modules/webhooks/service/validateInput/utils.test.ts @@ -1,4 +1,4 @@ -import { isCleanHTML, isObjectValid } from "./utils"; +import { isCleanHTML, isObjectValid } from "./utils.js"; describe("isObjectValid", () => { it("calls the callback for each child if validator returns true", () => { diff --git a/api.planx.uk/modules/webhooks/service/validateInput/utils.ts b/api.planx.uk/modules/webhooks/service/validateInput/utils.ts index 0eb4c0a0b2..1ce7596936 100644 --- a/api.planx.uk/modules/webhooks/service/validateInput/utils.ts +++ b/api.planx.uk/modules/webhooks/service/validateInput/utils.ts @@ -1,8 +1,8 @@ -import { isObject } from "lodash"; +import isObject from "lodash/isObject.js"; import { JSDOM } from "jsdom"; import createDOMPurify from "dompurify"; -import { decode } from "he"; -import { reportError } from "../../../pay/helpers"; +import he from "he"; +import { reportError } from "../../../pay/helpers.js"; // Setup JSDOM and DOMPurify const window = new JSDOM("").window; @@ -45,7 +45,7 @@ export const isCleanHTML = (input: unknown): boolean => { // DOMPurify has not removed any attributes or values const isClean = cleanHTML.length === input.length || - decode(cleanHTML).length === decode(input).length; + he.decode(cleanHTML).length === he.decode(input).length; if (!isClean) logUncleanHTMLError(input, cleanHTML); diff --git a/api.planx.uk/modules/webhooks/service/validateInput/validateInput.test.ts b/api.planx.uk/modules/webhooks/service/validateInput/validateInput.test.ts index a1f87f754f..a49a22705b 100644 --- a/api.planx.uk/modules/webhooks/service/validateInput/validateInput.test.ts +++ b/api.planx.uk/modules/webhooks/service/validateInput/validateInput.test.ts @@ -1,5 +1,5 @@ import supertest from "supertest"; -import app from "../../../../server"; +import app from "../../../../server.js"; const { post } = supertest(app); const ENDPOINT = "/webhooks/hasura/validate-input/jsonb/clean-html"; diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index dd91afb7e9..6057cb4696 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -3,9 +3,15 @@ "license": "MPL-2.0", "private": true, "packageManager": "pnpm@8.6.6", + "type": "module", + "exports": "./dist/index.js", + "engines": { + "node": ">=18.16", + "pnpm": "8.6.6" + }, "dependencies": { "@airbrake/node": "^2.1.8", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#6b2fd26", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#df593a5", "@types/isomorphic-fetch": "^0.0.36", "adm-zip": "^0.5.10", "aws-sdk": "^2.1467.0", @@ -35,7 +41,7 @@ "jsondiffpatch": "^0.5.0", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", - "mime": "^3.0.0", + "mime": "^4.0.4", "multer": "^1.4.5-lts.1", "nanoid": "^3.3.7", "notifications-node-client": "^8.2.0", @@ -46,18 +52,19 @@ "string-to-stream": "^3.0.1", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.0", + "ts-node": "^10.9.2", "type-fest": "^4.18.1", "zod": "^3.23.5" }, "scripts": { - "dev": "ts-node-dev --files index.ts", + "dev": "tsx watch index.ts", "start": "node ./dist/index.js", "lint": "eslint '**/*.{js,ts}' && prettier -c .", "lint:fix": "eslint --fix '**/*.{js,ts}' && prettier -w .", "check": "tsc --noEmit && pnpm lint", - "test": "TZ=Europe/London jest --silent", - "test:coverage": "TZ=Europe/London jest; open ./coverage/lcov-report/index.html", - "test:watch": "TZ=Europe/London jest --coverage=false --watch", + "test": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest --no-cache", + "test:coverage": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest; open ./coverage/lcov-report/index.html", + "test:watch": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest --coverage=false --watch", "build": "rimraf ./dist && npx tsc && pnpm copy-swagger-files", "prepare": "cd .. && husky install api.planx.uk/.husky", "copy-swagger-files": "copyfiles '**/docs.yaml' dist" @@ -84,7 +91,6 @@ "@types/jsdom": "^21.1.6", "@types/jsonwebtoken": "^9.0.5", "@types/lodash": "^4.17.0", - "@types/mime": "^3.0.4", "@types/multer": "^1.4.11", "@types/node": "^18.19.13", "@types/passport": "^1.0.16", @@ -106,12 +112,11 @@ "json-stringify-pretty-compact": "^3.0.0", "lint-staged": "^15.0.2", "nock": "^13.5.4", - "node-dev": "^8.0.0", "prettier": "^3.2.4", "rimraf": "^5.0.5", "supertest": "^7.0.0", - "ts-jest": "^29.1.1", - "ts-node-dev": "^2.0.0", + "ts-jest": "^29.2.4", + "tsx": "^4.16.2", "typescript": "^5.5.2", "uuid": "^10.0.0" }, diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index 7292539127..0293e00482 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -14,8 +14,8 @@ dependencies: specifier: ^2.1.8 version: 2.1.8 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#6b2fd26 - version: github.com/theopensystemslab/planx-core/6b2fd26 + specifier: git+https://github.com/theopensystemslab/planx-core#df593a5 + version: github.com/theopensystemslab/planx-core/df593a5 '@types/isomorphic-fetch': specifier: ^0.0.36 version: 0.0.36 @@ -104,8 +104,8 @@ dependencies: specifier: ^4.17.21 version: 4.17.21 mime: - specifier: ^3.0.0 - version: 3.0.0 + specifier: ^4.0.4 + version: 4.0.4 multer: specifier: ^1.4.5-lts.1 version: 1.4.5-lts.1 @@ -136,6 +136,9 @@ dependencies: swagger-ui-express: specifier: ^5.0.0 version: 5.0.0(express@4.19.2) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@18.19.13)(typescript@5.5.2) type-fest: specifier: ^4.18.1 version: 4.18.1 @@ -189,9 +192,6 @@ devDependencies: '@types/lodash': specifier: ^4.17.0 version: 4.17.0 - '@types/mime': - specifier: ^3.0.4 - version: 3.0.4 '@types/multer': specifier: ^1.4.11 version: 1.4.11 @@ -245,7 +245,7 @@ devDependencies: version: 0.12.1(nock@13.5.4) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@18.19.13) + version: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) json-stringify-pretty-compact: specifier: ^3.0.0 version: 3.0.0 @@ -255,9 +255,6 @@ devDependencies: nock: specifier: ^13.5.4 version: 13.5.4 - node-dev: - specifier: ^8.0.0 - version: 8.0.0 prettier: specifier: ^3.2.4 version: 3.2.4 @@ -268,11 +265,11 @@ devDependencies: specifier: ^7.0.0 version: 7.0.0 ts-jest: - specifier: ^29.1.1 - version: 29.1.1(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2) - ts-node-dev: - specifier: ^2.0.0 - version: 2.0.0(@types/node@18.19.13)(typescript@5.5.2) + specifier: ^29.2.4 + version: 29.2.4(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2) + tsx: + specifier: ^4.16.2 + version: 4.16.2 typescript: specifier: ^5.5.2 version: 5.5.2 @@ -783,7 +780,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/trace-mapping': 0.3.9 - dev: true /@emotion/babel-plugin@11.12.0: resolution: {integrity: sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==} @@ -912,6 +908,15 @@ packages: resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} dev: false + /@esbuild/aix-ppc64@0.21.5: + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + /@esbuild/aix-ppc64@0.22.0: resolution: {integrity: sha512-uvQR2crZ/zgzSHDvdygHyNI+ze9zwS8mqz0YtGXotSqvEE0UkYE9s+FZKQNTt1VtT719mfP3vHrUdCpxBNQZhQ==} engines: {node: '>=18'} @@ -921,6 +926,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64@0.21.5: + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64@0.22.0: resolution: {integrity: sha512-UKhPb3o2gAB/bfXcl58ZXTn1q2oVu1rEu/bKrCtmm+Nj5MKUbrOwR5WAixE2v+lk0amWuwPvhnPpBRLIGiq7ig==} engines: {node: '>=18'} @@ -930,6 +944,15 @@ packages: dev: true optional: true + /@esbuild/android-arm@0.21.5: + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.22.0: resolution: {integrity: sha512-PBnyP+r8vJE4ifxsWys9l+Mc2UY/yYZOpX82eoyGISXXb3dRr0M21v+s4fgRKWMFPMSf/iyowqPW/u7ScSUkjQ==} engines: {node: '>=18'} @@ -939,6 +962,15 @@ packages: dev: true optional: true + /@esbuild/android-x64@0.21.5: + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.22.0: resolution: {integrity: sha512-IjTYtvIrjhR41Ijy2dDPgYjQHWG/x/A4KXYbs1fiU3efpRdoxMChK3oEZV6GPzVEzJqxFgcuBaiX1kwEvWUxSw==} engines: {node: '>=18'} @@ -948,6 +980,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64@0.21.5: + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.22.0: resolution: {integrity: sha512-mqt+Go4y9wRvEz81bhKd9RpHsQR1LwU8Xm6jZRUV/xpM7cIQFbFH6wBCLPTNsdELBvfoHeumud7X78jQQJv2TA==} engines: {node: '>=18'} @@ -957,6 +998,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64@0.21.5: + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.22.0: resolution: {integrity: sha512-vTaTQ9OgYc3VTaWtOE5pSuDT6H3d/qSRFRfSBbnxFfzAvYoB3pqKXA0LEbi/oT8GUOEAutspfRMqPj2ezdFaMw==} engines: {node: '>=18'} @@ -966,6 +1016,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64@0.21.5: + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.22.0: resolution: {integrity: sha512-0e1ZgoobJzaGnR4reD7I9rYZ7ttqdh1KPvJWnquUoDJhL0rYwdneeLailBzd2/4g/U5p4e5TIHEWa68NF2hFpQ==} engines: {node: '>=18'} @@ -975,6 +1034,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64@0.21.5: + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.22.0: resolution: {integrity: sha512-BFgyYwlCwRWyPQJtkzqq2p6pJbiiWgp0P9PNf7a5FQ1itKY4czPuOMAlFVItirSmEpRPCeImuwePNScZS0pL5Q==} engines: {node: '>=18'} @@ -984,6 +1052,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64@0.21.5: + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.22.0: resolution: {integrity: sha512-V/K2rctCUgC0PCXpN7AqT4hoazXKgIYugFGu/myk2+pfe6jTW2guz/TBwq4cZ7ESqusR/IzkcQaBkcjquuBWsw==} engines: {node: '>=18'} @@ -993,6 +1070,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm@0.21.5: + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.22.0: resolution: {integrity: sha512-KEMWiA9aGuPUD4BH5yjlhElLgaRXe+Eri6gKBoDazoPBTo1BXc/e6IW5FcJO9DoL19FBeCxgONyh95hLDNepIg==} engines: {node: '>=18'} @@ -1002,6 +1088,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32@0.21.5: + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.22.0: resolution: {integrity: sha512-r2ZZqkOMOrpUhzNwxI7uLAHIDwkfeqmTnrv1cjpL/rjllPWszgqmprd/om9oviKXUBpMqHbXmppvjAYgISb26Q==} engines: {node: '>=18'} @@ -1011,6 +1106,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64@0.21.5: + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.22.0: resolution: {integrity: sha512-qaowLrV/YOMAL2RfKQ4C/VaDzAuLDuylM2sd/LH+4OFirMl6CuDpRlCq4u49ZBaVV8pkI/Y+hTdiibvQRhojCA==} engines: {node: '>=18'} @@ -1020,6 +1124,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el@0.21.5: + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.22.0: resolution: {integrity: sha512-hgrezzjQTRxjkQ5k08J6rtZN5PNnkWx/Rz6Kmj9gnsdCAX1I4Dn4ZPqvFRkXo55Q3pnVQJBwbdtrTO7tMGtyVA==} engines: {node: '>=18'} @@ -1029,6 +1142,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64@0.21.5: + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.22.0: resolution: {integrity: sha512-ewxg6FLLUio883XgSjfULEmDl3VPv/TYNnRprVAS3QeGFLdCYdx1tIudBcd7n9jIdk82v1Ajov4jx87qW7h9+g==} engines: {node: '>=18'} @@ -1038,6 +1160,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64@0.21.5: + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.22.0: resolution: {integrity: sha512-Az5XbgSJC2lE8XK8pdcutsf9RgdafWdTpUK/+6uaDdfkviw/B4JCwAfh1qVeRWwOohwdsl4ywZrWBNWxwrPLFg==} engines: {node: '>=18'} @@ -1047,6 +1178,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x@0.21.5: + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.22.0: resolution: {integrity: sha512-8j4a2ChT9+V34NNNY9c/gMldutaJFmfMacTPq4KfNKwv2fitBCLYjee7c+Vxaha2nUhPK7cXcZpJtJ3+Y7ZdVQ==} engines: {node: '>=18'} @@ -1056,6 +1196,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64@0.21.5: + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.22.0: resolution: {integrity: sha512-JUQyOnpbAkkRFOk/AhsEemz5TfWN4FJZxVObUlnlNCbe7QBl61ZNfM4cwBXayQA6laMJMUcqLHaYQHAB6YQ95Q==} engines: {node: '>=18'} @@ -1065,6 +1214,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64@0.21.5: + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.22.0: resolution: {integrity: sha512-11PoCoHXo4HFNbLsXuMB6bpMPWGDiw7xETji6COdJss4SQZLvcgNoeSqWtATRm10Jj1uEHiaIk4N0PiN6x4Fcg==} engines: {node: '>=18'} @@ -1083,6 +1241,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64@0.21.5: + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.22.0: resolution: {integrity: sha512-ufjdW5tFJGUjlH9j/5cCE9lrwRffyZh+T4vYvoDKoYsC6IXbwaFeV/ENxeNXcxotF0P8CDzoICXVSbJaGBhkrw==} engines: {node: '>=18'} @@ -1092,6 +1259,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64@0.21.5: + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.22.0: resolution: {integrity: sha512-zY6ly/AoSmKnmNTowDJsK5ehra153/5ZhqxNLfq9NRsTTltetr+yHHcQ4RW7QDqw4JC8A1uC1YmeSfK9NRcK1w==} engines: {node: '>=18'} @@ -1101,6 +1277,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64@0.21.5: + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.22.0: resolution: {integrity: sha512-Kml5F7tv/1Maam0pbbCrvkk9vj046dPej30kFzlhXnhuCtYYBP6FGy/cLbc5yUT1lkZznGLf2OvuvmLjscO5rw==} engines: {node: '>=18'} @@ -1110,6 +1295,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32@0.21.5: + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.22.0: resolution: {integrity: sha512-IOgwn+mYTM3RrcydP4Og5IpXh+ftN8oF+HELTXSmbWBlujuci4Qa3DTeO+LEErceisI7KUSfEIiX+WOUlpELkw==} engines: {node: '>=18'} @@ -1119,6 +1313,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64@0.21.5: + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.22.0: resolution: {integrity: sha512-4bDHJrk2WHBXJPhy1y80X7/5b5iZTZP3LGcKIlAP1J+KqZ4zQAPMLEzftGyjjfcKbA4JDlPt/+2R/F1ZTeRgrw==} engines: {node: '>=18'} @@ -1281,7 +1484,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core@29.7.0: + /@jest/core@29.7.0(ts-node@10.9.2): resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -1302,7 +1505,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.13) + jest-config: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1547,7 +1750,6 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - dev: true /@jsdevtools/ono@7.1.3: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} @@ -1771,19 +1973,15 @@ packages: /@tsconfig/node10@1.0.11: resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - dev: true /@tsconfig/node12@1.0.11: resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true /@tsconfig/node14@1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true /@tsconfig/node16@1.0.4: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true /@types/adm-zip@0.5.0: resolution: {integrity: sha512-FCJBJq9ODsQZUNURo5ILAQueuA8WJhRvuihS3ke2iI25mJlfV2LK8jG2Qj2z2AWg8U0FtWWqBHVRetceLskSaw==} @@ -1963,10 +2161,6 @@ packages: /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - /@types/mime@3.0.4: - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} - dev: true - /@types/multer@1.4.11: resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==} dependencies: @@ -2102,14 +2296,6 @@ packages: resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} dev: true - /@types/strip-bom@3.0.0: - resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} - dev: true - - /@types/strip-json-comments@0.0.30: - resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} - dev: true - /@types/superagent@8.1.8: resolution: {integrity: sha512-nTqHJ2OTa7PFEpLahzSEEeFeqbMpmcN7OeayiOc7v+xk+/vyTKljRe+o4MPqSnPeRCMvtxuLG+5QqluUVQJOnA==} dependencies: @@ -2324,7 +2510,6 @@ packages: engines: {node: '>=0.4.0'} dependencies: acorn: 8.12.1 - dev: true /acorn@8.12.1: resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} @@ -2444,7 +2629,6 @@ packages: /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -2488,6 +2672,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: true + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -2679,11 +2867,6 @@ packages: pascalcase: 0.1.1 dev: true - /binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - dev: true - /bintrees@1.0.2: resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} dev: false @@ -2898,21 +3081,6 @@ packages: parse5-htmlparser2-tree-adapter: 7.0.0 dev: false - /chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - /ci-info@2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} dev: true @@ -3168,7 +3336,7 @@ packages: yaml: 1.10.2 dev: false - /create-jest@29.7.0(@types/node@18.19.13): + /create-jest@29.7.0(@types/node@18.19.13)(ts-node@10.9.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3177,7 +3345,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.13) + jest-config: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -3189,7 +3357,6 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} @@ -3273,18 +3440,10 @@ packages: resolution: {integrity: sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==} dev: false - /dateformat@3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dev: true - /dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} dev: true - /debounce@1.2.1: - resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} - dev: true - /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3449,7 +3608,6 @@ packages: /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - dev: true /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -3527,12 +3685,6 @@ packages: stream-shift: 1.0.3 dev: false - /dynamic-dedupe@0.3.0: - resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} - dependencies: - xtend: 4.0.2 - dev: true - /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -3546,6 +3698,14 @@ packages: resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} dev: false + /ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.9.2 + dev: true + /electron-to-chromium@1.5.2: resolution: {integrity: sha512-kc4r3U3V3WLaaZqThjYz/Y6z8tJe+7K0bbjUVo3i+LWIypVdMx5nXCkwRe6SWbY6ILqLdc1rKcKmr3HoH7wjSQ==} dev: true @@ -3645,6 +3805,37 @@ packages: - supports-color dev: true + /esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + dev: true + /esbuild@0.22.0: resolution: {integrity: sha512-zNYA6bFZsVnsU481FnGAQjLDW0Pl/8BGG7EvAp15RzUvGC+ME7hf1q7LvIfStEQBz/iEHuBJCYcOwPmNCf1Tlw==} engines: {node: '>=18'} @@ -3723,7 +3914,7 @@ packages: '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.5.2) eslint: 8.57.0 - jest: 29.7.0(@types/node@18.19.13) + jest: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) transitivePeerDependencies: - supports-color - typescript @@ -4149,10 +4340,10 @@ packages: dependencies: flat-cache: 3.2.0 - /filewatcher@3.0.1: - resolution: {integrity: sha512-Fro8py2B8EJupSP37Kyd4kjKZLr+5ksFq7Vbw8A392Z15Unq8016SPUDvO/AsDj5V6bbPk98PTAinpc5YhPbJw==} + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: - debounce: 1.2.1 + minimatch: 5.1.6 dev: true /fill-range@7.1.1: @@ -4351,6 +4542,12 @@ packages: engines: {node: '>=16'} dev: true + /get-tsconfig@4.7.6: + resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} @@ -4486,10 +4683,6 @@ packages: engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} dev: false - /growly@1.3.0: - resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} - dev: true - /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -4758,13 +4951,6 @@ packages: /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - dependencies: - binary-extensions: 2.3.0 - dev: true - /is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} dev: true @@ -4817,12 +5003,6 @@ packages: is-data-descriptor: 1.0.1 dev: true - /is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -4940,13 +5120,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: true - /isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} dev: false @@ -5048,6 +5221,17 @@ packages: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + /jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + /jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5086,7 +5270,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@18.19.13): + /jest-cli@29.7.0(@types/node@18.19.13)(ts-node@10.9.2): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5096,14 +5280,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0 + '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.13) + create-jest: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@18.19.13) + jest-config: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -5114,7 +5298,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@18.19.13): + /jest-config@29.7.0(@types/node@18.19.13)(ts-node@10.9.2): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5149,6 +5333,7 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 + ts-node: 10.9.2(@types/node@18.19.13)(typescript@5.5.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -5507,7 +5692,7 @@ packages: supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@18.19.13): + /jest@29.7.0(@types/node@18.19.13)(ts-node@10.9.2): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5517,10 +5702,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0 + '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@18.19.13) + jest-cli: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -5602,8 +5787,8 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - /json-schema-to-typescript@14.1.0: - resolution: {integrity: sha512-VIeAFQkn88gFh26MSHWG4uX7TjK/arTw0NVLMZn6vX1WrSF+P6xu5MyEdovu+9PJ0uiS5gm0wzwQvYW9eSq1uw==} + /json-schema-to-typescript@15.0.0: + resolution: {integrity: sha512-gOX3cJB4eL1ztMc3WUh569ubRcKnr8MnYk++6+/WaaN4bufGHSR6EcbUbvLZgirPQOfvni5SSGkRx0pYloYU8A==} engines: {node: '>=16.0.0'} hasBin: true dependencies: @@ -5894,7 +6079,6 @@ packages: /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true /makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -6014,9 +6198,9 @@ packages: hasBin: true dev: true - /mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} + /mime@4.0.4: + resolution: {integrity: sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==} + engines: {node: '>=16'} hasBin: true dev: false @@ -6035,6 +6219,13 @@ packages: dependencies: brace-expansion: 1.1.11 + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -6067,6 +6258,7 @@ packages: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true + dev: false /mkdirp@3.0.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} @@ -6159,21 +6351,6 @@ packages: - supports-color dev: true - /node-dev@8.0.0: - resolution: {integrity: sha512-GXc0KxmBXfQxMPdymOui40yvC5W/RXFwmuUDT65wvTAO/o9wAsddYC8q4EHKxq3Qqt+uLS/g7XKdgVcsjyk9lw==} - engines: {node: '>=14'} - hasBin: true - dependencies: - dateformat: 3.0.3 - dynamic-dedupe: 0.3.0 - filewatcher: 3.0.1 - get-package-type: 0.1.0 - minimist: 1.2.8 - node-notifier: 8.0.2 - resolve: 1.22.8 - semver: 7.6.3 - dev: true - /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -6204,17 +6381,6 @@ packages: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: true - /node-notifier@8.0.2: - resolution: {integrity: sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==} - dependencies: - growly: 1.3.0 - is-wsl: 2.2.0 - semver: 7.6.3 - shellwords: 0.1.1 - uuid: 8.3.2 - which: 2.0.2 - dev: true - /node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} dev: true @@ -6897,13 +7063,6 @@ packages: string_decoder: 1.3.0 dev: true - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - dev: true - /real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} @@ -6964,6 +7123,10 @@ packages: engines: {node: '>=8'} dev: true + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} deprecated: https://github.com/lydell/resolve-url#deprecated @@ -7003,14 +7166,6 @@ packages: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} dev: true - /rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -7219,10 +7374,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - /shellwords@0.1.1: - resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==} - dev: true - /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -7307,13 +7458,6 @@ packages: source-map: 0.6.1 dev: true - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - /source-map-url@0.4.1: resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} deprecated: See https://github.com/lydell/source-map-url#deprecated @@ -7438,11 +7582,6 @@ packages: dependencies: ansi-regex: 6.0.1 - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - /strip-bom@4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -7463,11 +7602,6 @@ packages: engines: {node: '>=12'} dev: true - /strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: true - /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -7668,17 +7802,13 @@ packages: punycode: 2.3.1 dev: false - /tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: true - - /ts-jest@29.1.1(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2): - resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + /ts-jest@29.2.4(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2): + resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 '@jest/types': ^29.0.0 babel-jest: ^29.0.0 esbuild: '*' @@ -7687,6 +7817,8 @@ packages: peerDependenciesMeta: '@babel/core': optional: true + '@jest/transform': + optional: true '@jest/types': optional: true babel-jest: @@ -7696,9 +7828,10 @@ packages: dependencies: '@babel/core': 7.24.0 bs-logger: 0.2.6 + ejs: 3.1.10 esbuild: 0.22.0 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@18.19.13) + jest: 29.7.0(@types/node@18.19.13)(ts-node@10.9.2) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -7708,34 +7841,6 @@ packages: yargs-parser: 21.1.1 dev: true - /ts-node-dev@2.0.0(@types/node@18.19.13)(typescript@5.5.2): - resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} - engines: {node: '>=0.8.0'} - hasBin: true - peerDependencies: - node-notifier: '*' - typescript: '*' - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - chokidar: 3.6.0 - dynamic-dedupe: 0.3.0 - minimist: 1.2.8 - mkdirp: 1.0.4 - resolve: 1.22.8 - rimraf: 2.7.1 - source-map-support: 0.5.21 - tree-kill: 1.2.2 - ts-node: 10.9.2(@types/node@18.19.13)(typescript@5.5.2) - tsconfig: 7.0.0 - typescript: 5.5.2 - transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - - '@types/node' - dev: true - /ts-node@10.9.2(@types/node@18.19.13)(typescript@5.5.2): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -7765,16 +7870,6 @@ packages: typescript: 5.5.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true - - /tsconfig@7.0.0: - resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} - dependencies: - '@types/strip-bom': 3.0.0 - '@types/strip-json-comments': 0.0.30 - strip-bom: 3.0.0 - strip-json-comments: 2.0.1 - dev: true /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -7799,6 +7894,17 @@ packages: typescript: 5.5.2 dev: true + /tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.6 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7860,7 +7966,6 @@ packages: resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==} engines: {node: '>=14.17'} hasBin: true - dev: true /uid2@0.0.4: resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} @@ -7970,14 +8075,8 @@ packages: hasBin: true dev: false - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: true - /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true /v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} @@ -8170,6 +8269,7 @@ packages: /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + dev: false /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -8233,7 +8333,6 @@ packages: /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} - dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} @@ -8259,8 +8358,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/6b2fd26: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/6b2fd26} + github.com/theopensystemslab/planx-core/df593a5: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/df593a5} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -8280,7 +8379,7 @@ packages: fast-xml-parser: 4.4.1 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) - json-schema-to-typescript: 14.1.0 + json-schema-to-typescript: 15.0.0 lodash: 4.17.21 marked: 13.0.3 prettier: 3.3.3 diff --git a/api.planx.uk/server.test.js b/api.planx.uk/server.test.js index 8a05da05c8..1967f1b9bf 100644 --- a/api.planx.uk/server.test.js +++ b/api.planx.uk/server.test.js @@ -1,6 +1,6 @@ import supertest from "supertest"; -import app from "./server"; +import app from "./server.js"; describe("authentication", () => { test("Failed login endpoint", async () => { diff --git a/api.planx.uk/server.ts b/api.planx.uk/server.ts index 068d86818e..7a17abb2dd 100644 --- a/api.planx.uk/server.ts +++ b/api.planx.uk/server.ts @@ -1,6 +1,6 @@ import "isomorphic-fetch"; import "express-async-errors"; -import { json, urlencoded } from "body-parser"; +import bodyParser from "body-parser"; import assert from "assert"; import cookieParser from "cookie-parser"; import cookieSession from "cookie-session"; @@ -11,28 +11,28 @@ import pinoLogger from "express-pino-logger"; import { Server } from "http"; import passport from "passport"; import helmet from "helmet"; -import { ServerError } from "./errors"; -import airbrake from "./airbrake"; -import { apiLimiter } from "./rateLimit"; -import { registerSessionStubs } from "./session"; -import { googleStrategy } from "./modules/auth/strategy/google"; -import authRoutes from "./modules/auth/routes"; -import teamRoutes from "./modules/team/routes"; -import miscRoutes from "./modules/misc/routes"; -import userRoutes from "./modules/user/routes"; -import webhookRoutes from "./modules/webhooks/routes"; -import analyticsRoutes from "./modules/analytics/routes"; -import adminRoutes from "./modules/admin/routes"; -import flowRoutes from "./modules/flows/routes"; -import ordnanceSurveyRoutes from "./modules/ordnanceSurvey/routes"; -import saveAndReturnRoutes from "./modules/saveAndReturn/routes"; -import sendEmailRoutes from "./modules/sendEmail/routes"; -import fileRoutes from "./modules/file/routes"; -import gisRoutes from "./modules/gis/routes"; -import payRoutes from "./modules/pay/routes"; -import sendRoutes from "./modules/send/routes"; -import testRoutes from "./modules/test/routes"; -import { useSwaggerDocs } from "./docs"; +import { ServerError } from "./errors/index.js"; +import airbrake from "./airbrake.js"; +import { apiLimiter } from "./rateLimit.js"; +import { registerSessionStubs } from "./session.js"; +import { googleStrategy } from "./modules/auth/strategy/google.js"; +import authRoutes from "./modules/auth/routes.js"; +import teamRoutes from "./modules/team/routes.js"; +import miscRoutes from "./modules/misc/routes.js"; +import userRoutes from "./modules/user/routes.js"; +import webhookRoutes from "./modules/webhooks/routes.js"; +import analyticsRoutes from "./modules/analytics/routes.js"; +import adminRoutes from "./modules/admin/routes.js"; +import flowRoutes from "./modules/flows/routes.js"; +import ordnanceSurveyRoutes from "./modules/ordnanceSurvey/routes.js"; +import saveAndReturnRoutes from "./modules/saveAndReturn/routes.js"; +import sendEmailRoutes from "./modules/sendEmail/routes.js"; +import fileRoutes from "./modules/file/routes.js"; +import gisRoutes from "./modules/gis/routes.js"; +import payRoutes from "./modules/pay/routes.js"; +import sendRoutes from "./modules/send/routes.js"; +import testRoutes from "./modules/test/routes.js"; +import { useSwaggerDocs } from "./docs/index.js"; import { Role } from "@opensystemslab/planx-core/types"; const app = express(); @@ -73,7 +73,7 @@ app.use( }), ); -app.use(json({ limit: "100mb" })); +app.use(bodyParser.json({ limit: "100mb" })); // Converts req.headers.cookie: string, to req.cookies: Record app.use(cookieParser()); @@ -132,7 +132,7 @@ passport.deserializeUser(function (obj: Express.User, cb) { }); app.use(passport.initialize()); app.use(passport.session()); -app.use(urlencoded({ extended: true })); +app.use(bodyParser.urlencoded({ extended: true })); // Setup API routes app.use(adminRoutes); diff --git a/api.planx.uk/tests/mocks/inviteToPayData.ts b/api.planx.uk/tests/mocks/inviteToPayData.ts index 6f0ad73dcf..d16dd52670 100644 --- a/api.planx.uk/tests/mocks/inviteToPayData.ts +++ b/api.planx.uk/tests/mocks/inviteToPayData.ts @@ -3,7 +3,7 @@ import type { PaymentRequest, FlowGraph, } from "@opensystemslab/planx-core/types"; -import { Flow } from "../../types"; +import { Flow } from "../../types.js"; export const validEmail = "the-payee@opensystemslab.io"; diff --git a/api.planx.uk/tests/mocks/inviteToPayMocks.ts b/api.planx.uk/tests/mocks/inviteToPayMocks.ts index c8d073a825..f3d15c2b20 100644 --- a/api.planx.uk/tests/mocks/inviteToPayMocks.ts +++ b/api.planx.uk/tests/mocks/inviteToPayMocks.ts @@ -8,7 +8,7 @@ import { paymentRequestResponse, validPaymentRequest, paymentAmountPence, -} from "./inviteToPayData"; +} from "./inviteToPayData.js"; export const validSessionQueryMock = { name: "GetSessionById", diff --git a/api.planx.uk/tests/mocks/saveAndReturnMocks.ts b/api.planx.uk/tests/mocks/saveAndReturnMocks.ts index 0fcdc37285..648ff7ea1f 100644 --- a/api.planx.uk/tests/mocks/saveAndReturnMocks.ts +++ b/api.planx.uk/tests/mocks/saveAndReturnMocks.ts @@ -1,5 +1,5 @@ import { v4 as uuidV4 } from "uuid"; -import type { LowCalSession, Flow } from "../../types"; +import type { LowCalSession, Flow } from "../../types.js"; import { Team } from "@opensystemslab/planx-core/types"; export const mockTeam = { diff --git a/api.planx.uk/tsconfig.json b/api.planx.uk/tsconfig.json index e4f0ab0763..9f126949e4 100644 --- a/api.planx.uk/tsconfig.json +++ b/api.planx.uk/tsconfig.json @@ -1,18 +1,22 @@ { + // as of July 24, esnext == es2022 and nodenext == node16 "compilerOptions": { "allowJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "lib": ["es2021"], - "module": "commonjs", - "moduleResolution": "node", + "lib": ["esnext"], + "module": "nodenext", + "moduleResolution": "nodenext", "noImplicitAny": true, "outDir": "dist", "resolveJsonModule": true, "rootDir": ".", "skipLibCheck": true, "strict": true, - "target": "es2021", + "target": "esnext", + // ensure the code is ready for transpilation by tsx/esbuild (used in dev) + "isolatedModules": true, + // TODO: implement "verbatimModuleSyntax" option (laborious) }, "exclude": ["node_modules", "dist"], } diff --git a/api.planx.uk/tsconfig.test.json b/api.planx.uk/tsconfig.test.json new file mode 100644 index 0000000000..ea5b7c77b4 --- /dev/null +++ b/api.planx.uk/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + } +} diff --git a/api.planx.uk/types.ts b/api.planx.uk/types.ts index 60c8272418..2c1bbf7378 100644 --- a/api.planx.uk/types.ts +++ b/api.planx.uk/types.ts @@ -1,5 +1,8 @@ -import { PaymentRequest } from "@opensystemslab/planx-core/dist/types"; -import { GovUKPayment, Team } from "@opensystemslab/planx-core/types"; +import { + GovUKPayment, + Team, + PaymentRequest, +} from "@opensystemslab/planx-core/types"; /** * @deprecated Migrating to Node from planx-core From b01ac93b3f1dbe4504c87311d894f0135e074efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Fri, 9 Aug 2024 15:35:54 +0100 Subject: [PATCH 03/12] fix: Flow layout issues (#3499) --- editor.planx.uk/src/pages/FlowEditor/floweditor.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss index 3c697d2a43..8f51ad279b 100644 --- a/editor.planx.uk/src/pages/FlowEditor/floweditor.scss +++ b/editor.planx.uk/src/pages/FlowEditor/floweditor.scss @@ -47,7 +47,8 @@ $fontMonospace: "Source Code Pro", monospace; li { list-style: none; padding: 0; - margin: 0; + margin: 0 auto; + width: max-content; > a:focus, > a:active { @@ -179,10 +180,10 @@ $fontMonospace: "Source Code Pro", monospace; &.type-Section { [data-layout="top-down"] & { - width: 100%; + width: 100% !important; } [data-layout="left-right"] & { - height: 100%; + height: 100% !important; } } From 51031bf0762fa03d4921fbd3dfd742959d119e94 Mon Sep 17 00:00:00 2001 From: Jo Humphrey <31373245+jamdelion@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:35:49 +0100 Subject: [PATCH 04/12] feat: Add new team editor - button and modal only (#3495) --- editor.planx.uk/src/lib/featureFlags.ts | 1 + .../components/Team/TeamMembers.tsx | 22 +++- .../Team/components/AddNewEditorModal.tsx | 105 ++++++++++++++++++ .../Team/{ => components}/MembersTable.tsx | 21 +++- .../tests/TeamMembers.addNewEditor.test.tsx | 33 ++++++ .../Team/tests/exampleTeamMembersData.tsx | 26 +++++ .../tests/helpers/setupTeamMembersScreen.tsx | 18 +++ .../pages/FlowEditor/components/Team/types.ts | 12 +- .../src/ui/editor/SettingsSection.tsx | 9 +- package.json | 3 + pnpm-lock.yaml | 13 +++ 11 files changed, 251 insertions(+), 12 deletions(-) create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Team/components/AddNewEditorModal.tsx rename editor.planx.uk/src/pages/FlowEditor/components/Team/{ => components}/MembersTable.tsx (77%) create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Team/tests/exampleTeamMembersData.tsx create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Team/tests/helpers/setupTeamMembersScreen.tsx diff --git a/editor.planx.uk/src/lib/featureFlags.ts b/editor.planx.uk/src/lib/featureFlags.ts index 1fa67da2f1..81d7e60f84 100644 --- a/editor.planx.uk/src/lib/featureFlags.ts +++ b/editor.planx.uk/src/lib/featureFlags.ts @@ -3,6 +3,7 @@ const AVAILABLE_FEATURE_FLAGS = [ "SEARCH", "OVERRIDE_CONSTRAINTS", "TREES", + "ADD_NEW_EDITOR", ] as const; type FeatureFlag = (typeof AVAILABLE_FEATURE_FLAGS)[number]; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx index f83e876016..868733eb95 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx @@ -1,12 +1,15 @@ import Container from "@mui/material/Container"; import Typography from "@mui/material/Typography"; -import React from "react"; +import React, { useState } from "react"; import SettingsSection from "ui/editor/SettingsSection"; -import { MembersTable } from "./MembersTable"; -import { Props, TeamMember } from "./types"; +import { AddNewEditorModal } from "./components/AddNewEditorModal"; +import { MembersTable } from "./components/MembersTable"; +import { TeamMember, TeamMembersProps } from "./types"; + +export const TeamMembers = ({ teamMembersByRole }: TeamMembersProps) => { + const [showModal, setShowModal] = useState(false); -export const TeamMembers: React.FC = ({ teamMembersByRole }) => { const platformAdmins = (teamMembersByRole.platformAdmin || []).filter( (member) => member.email, ); @@ -24,14 +27,18 @@ export const TeamMembers: React.FC = ({ teamMembersByRole }) => { return ( - + Team editors Editors have access to edit your services. - + @@ -54,6 +61,9 @@ export const TeamMembers: React.FC = ({ teamMembersByRole }) => { )} + {showModal && ( + + )} ); }; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/components/AddNewEditorModal.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/components/AddNewEditorModal.tsx new file mode 100644 index 0000000000..e31746f004 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/components/AddNewEditorModal.tsx @@ -0,0 +1,105 @@ +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import Typography from "@mui/material/Typography"; +import React from "react"; +import InputGroup from "ui/editor/InputGroup"; +import InputLabel from "ui/editor/InputLabel"; +import Input from "ui/shared/Input"; + +import { AddNewEditorModalProps } from "../types"; + +export const AddNewEditorModal = ({ + showModal, + setShowModal, +}: AddNewEditorModalProps) => ( + ({ + width: "100%", + maxWidth: theme.breakpoints.values.md, + borderRadius: 0, + borderTop: `20px solid ${theme.palette.primary.main}`, + background: "#FFF", + margin: theme.spacing(2), + }), + }} + open={showModal} + onClose={() => setShowModal(false)} + > +
+ + + + Add a new editor + + + + + { + console.log("bla"); // TODO in next PR + }} + value={""} + errorMessage={""} + id="firstname" + /> + + + { + console.log("bla"); // TODO in next PR + }} + value={""} + errorMessage={""} + id="lastname" + /> + + + { + console.log("bla"); // TODO in next PR + }} + value={""} + errorMessage={""} + id="email" + /> + + + + + + + + + +
+
+); diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/MembersTable.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/components/MembersTable.tsx similarity index 77% rename from editor.planx.uk/src/pages/FlowEditor/components/Team/MembersTable.tsx rename to editor.planx.uk/src/pages/FlowEditor/components/Team/components/MembersTable.tsx index 49d7ee8cdf..70139fcc15 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Team/MembersTable.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/components/MembersTable.tsx @@ -5,14 +5,18 @@ import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; +import { hasFeatureFlag } from "lib/featureFlags"; +import { AddButton } from "pages/Team"; import React from "react"; -import { StyledAvatar, StyledTableRow } from "./styles"; -import { TeamMember } from "./types"; +import { StyledAvatar, StyledTableRow } from "./../styles"; +import { MembersTableProps } from "./../types"; -export const MembersTable: React.FC<{ members: TeamMember[] }> = ({ +export const MembersTable = ({ members, -}) => { + showAddMemberButton, + setShowModal = () => true, +}: MembersTableProps) => { const roleLabels: Record = { platformAdmin: "Admin", teamEditor: "Editor", @@ -79,6 +83,15 @@ export const MembersTable: React.FC<{ members: TeamMember[] }> = ({ {member.email} ))} + {showAddMemberButton && hasFeatureFlag("ADD_NEW_EDITOR") && ( + + + setShowModal(true)}> + Add a new editor + + + + )} diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx new file mode 100644 index 0000000000..d7efde63b0 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx @@ -0,0 +1,33 @@ +/* eslint-disable jest/expect-expect */ +import { screen, within } from "@testing-library/react"; + +import { setupTeamMembersScreen } from "./helpers/setupTeamMembersScreen"; + +jest.mock("lib/featureFlags.ts", () => ({ + hasFeatureFlag: jest.fn().mockReturnValue(true), +})); + +describe("when a user views the Team members screen with the ADD_NEW_EDITOR feature flag enabled", () => { + beforeEach(async () => { + await setupTeamMembersScreen(); + }); + it("shows the 'add new editor' button", async () => { + const teamEditorsTable = screen.getByTestId("team-editors"); + await within(teamEditorsTable).findByText("Add a new editor"); + }); +}); + +describe("when a user with the ADD_NEW_EDITOR feature flag enabled presses 'add a new editor'", () => { + beforeEach(async () => { + const user = await setupTeamMembersScreen(); + const teamEditorsTable = screen.getByTestId("team-editors"); + const addEditorButton = await within(teamEditorsTable).findByText( + "Add a new editor" + ); + user.click(addEditorButton); + }); + it("opens the modal and displays the input fields", async () => { + expect(await screen.findByTestId("modal-create-user-button")).toBeVisible(); + expect(await screen.findByLabelText("First name")).toBeVisible(); + }); +}); diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/exampleTeamMembersData.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/exampleTeamMembersData.tsx new file mode 100644 index 0000000000..f9700d87ed --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/exampleTeamMembersData.tsx @@ -0,0 +1,26 @@ +import { Role } from "@opensystemslab/planx-core/types"; + +import { TeamMember } from "../types"; + +export const exampleTeamMembersData: Record = { + platformAdmin: [ + { + firstName: "Donella", + lastName: "Meadows", + email: "donella@example.com", + id: 1, + role: "platformAdmin", + }, + ], + teamEditor: [ + { + firstName: "Bill", + lastName: "Sharpe", + email: "bill@example.com", + id: 2, + role: "teamEditor", + }, + ], + teamViewer: [], + public: [], +}; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/helpers/setupTeamMembersScreen.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/helpers/setupTeamMembersScreen.tsx new file mode 100644 index 0000000000..6057a7d285 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/helpers/setupTeamMembersScreen.tsx @@ -0,0 +1,18 @@ +import { screen } from "@testing-library/react"; +import React from "react"; +import { DndProvider } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; + +import { setup } from "../../../../../../testUtils"; +import { TeamMembers } from "../../TeamMembers"; +import { exampleTeamMembersData } from "./../exampleTeamMembersData"; + +export async function setupTeamMembersScreen() { + const { user } = setup( + + + + ); + await screen.findByText("Team editors"); + return user; +} diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/types.ts b/editor.planx.uk/src/pages/FlowEditor/components/Team/types.ts index bb05972c4c..725f959212 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Team/types.ts +++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/types.ts @@ -1,9 +1,19 @@ import { Role, User } from "@opensystemslab/planx-core/types"; +import React, { SetStateAction } from "react"; export type TeamMember = Omit & { role: Role; }; -export interface Props { +export interface TeamMembersProps { teamMembersByRole: Record; } +export interface MembersTableProps { + members: TeamMember[]; + showAddMemberButton?: boolean; + setShowModal?: React.Dispatch>; +} +export type AddNewEditorModalProps = { + showModal: boolean; + setShowModal: React.Dispatch>; +}; diff --git a/editor.planx.uk/src/ui/editor/SettingsSection.tsx b/editor.planx.uk/src/ui/editor/SettingsSection.tsx index 30db4412d4..98b65108ea 100644 --- a/editor.planx.uk/src/ui/editor/SettingsSection.tsx +++ b/editor.planx.uk/src/ui/editor/SettingsSection.tsx @@ -5,6 +5,7 @@ import React, { ReactNode } from "react"; interface RootProps extends BoxProps { background?: boolean; + "data-testid"?: string; } const Root = styled(Box, { @@ -31,9 +32,15 @@ const Root = styled(Box, { export default function SettingsSection({ children, background, + testId, }: { children: ReactNode; background?: boolean; + testId?: string; }) { - return {children}; + return ( + + {children} + + ); } diff --git a/package.json b/package.json index 142ceb0058..1ef61da01a 100644 --- a/package.json +++ b/package.json @@ -13,5 +13,8 @@ "tests": "./scripts/start-containers-for-tests.sh", "analytics": "docker compose -f ./docker-compose.yml -f ./docker-compose.local.yml --profile mock-services --profile analytics up -d --quiet-pull", "logs": "docker compose logs --tail 30 -f" + }, + "devDependencies": { + "typescript": "5.4.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b9f1883a1..1687167033 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,3 +3,16 @@ lockfileVersion: '6.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false + +devDependencies: + typescript: + specifier: 5.4.3 + version: 5.4.3 + +packages: + + /typescript@5.4.3: + resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==} + engines: {node: '>=14.17'} + hasBin: true + dev: true From 12d008ae88aa1843455c5480bcaca5c5d6435c82 Mon Sep 17 00:00:00 2001 From: Rory Doak <138574807+RODO94@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:22:48 +0100 Subject: [PATCH 05/12] feat: Make external portals open in new tab when clicked (#3497) --- .../components/Flow/components/Portal.tsx | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Portal.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Portal.tsx index 5e00ef5a2d..c0de58e814 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Portal.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Flow/components/Portal.tsx @@ -14,12 +14,10 @@ import Hanger from "./Hanger"; import Question from "./Question"; const ExternalPortal: React.FC = (props) => { - const [copyNode, addExternalPortal] = useStore((state) => [ - state.copyNode, - state.addExternalPortal, - ]); const [href, setHref] = useState("Loading..."); + const addExternalPortal = useStore.getState().addExternalPortal; + const { data, loading } = useQuery( gql` query GetExternalPortal($id: uuid!) { @@ -77,12 +75,6 @@ const ExternalPortal: React.FC = (props) => { ); } - const handleContext = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - copyNode(props.id); - }; - let editHref = `${window.location.pathname}/nodes/${props.id}/edit`; if (parent) { editHref = `${window.location.pathname}/nodes/${parent}/nodes/${props.id}/edit`; @@ -91,10 +83,7 @@ const ExternalPortal: React.FC = (props) => { return ( <>