diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index 3f17c1f479..27b1560166 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -13,7 +13,7 @@ "@airbrake/node": "^2.1.8", "@aws-sdk/client-s3": "^3.696.0", "@aws-sdk/s3-request-presigner": "^3.701.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "@types/isomorphic-fetch": "^0.0.36", "adm-zip": "^0.5.10", "axios": "^1.7.4", diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index e1beae8474..9279cf8f9e 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -21,8 +21,8 @@ dependencies: specifier: ^3.701.0 version: 3.701.0 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 '@types/isomorphic-fetch': specifier: ^0.0.36 version: 0.0.36 @@ -3959,8 +3959,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -5225,7 +5225,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -5481,8 +5481,8 @@ packages: semver: 7.6.3 dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -6059,8 +6059,8 @@ packages: hasBin: true dev: true - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -6891,8 +6891,8 @@ packages: engines: {node: '>=16'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -7306,8 +7306,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -7322,18 +7322,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/e2e/tests/api-driven/package.json b/e2e/tests/api-driven/package.json index 074c8c301b..606a64005e 100644 --- a/e2e/tests/api-driven/package.json +++ b/e2e/tests/api-driven/package.json @@ -7,7 +7,7 @@ "packageManager": "pnpm@8.6.6", "dependencies": { "@cucumber/cucumber": "^9.3.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "axios": "^1.7.4", "dotenv": "^16.3.1", "dotenv-expand": "^10.0.0", diff --git a/e2e/tests/api-driven/pnpm-lock.yaml b/e2e/tests/api-driven/pnpm-lock.yaml index 26645a568a..e9f30826e1 100644 --- a/e2e/tests/api-driven/pnpm-lock.yaml +++ b/e2e/tests/api-driven/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^9.3.0 version: 9.3.0 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 axios: specifier: ^1.7.4 version: 1.7.4 @@ -1209,8 +1209,8 @@ packages: esutils: 2.0.3 dev: false - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -1785,7 +1785,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -1955,8 +1955,8 @@ packages: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -2191,8 +2191,8 @@ packages: engines: {node: '>= 0.8.0'} dev: false - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -2607,8 +2607,8 @@ packages: engines: {node: '>=10'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -2810,8 +2810,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -2826,18 +2826,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/e2e/tests/ui-driven/package.json b/e2e/tests/ui-driven/package.json index b5aaa364e3..514b990987 100644 --- a/e2e/tests/ui-driven/package.json +++ b/e2e/tests/ui-driven/package.json @@ -8,7 +8,7 @@ "postinstall": "./install-dependencies.sh" }, "dependencies": { - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "axios": "^1.7.4", "dotenv": "^16.3.1", "eslint": "^8.56.0", diff --git a/e2e/tests/ui-driven/pnpm-lock.yaml b/e2e/tests/ui-driven/pnpm-lock.yaml index 75407766b7..4552b235fd 100644 --- a/e2e/tests/ui-driven/pnpm-lock.yaml +++ b/e2e/tests/ui-driven/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 axios: specifier: ^1.7.4 version: 1.7.4 @@ -1090,8 +1090,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -1690,7 +1690,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -1814,8 +1814,8 @@ packages: js-tokens: 4.0.0 dev: false - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -2072,8 +2072,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -2431,8 +2431,8 @@ packages: engines: {node: '>=12.20'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -2599,8 +2599,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -2615,18 +2615,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/editor.planx.uk/package.json b/editor.planx.uk/package.json index 637e6d9f84..d81643d9a0 100644 --- a/editor.planx.uk/package.json +++ b/editor.planx.uk/package.json @@ -15,7 +15,7 @@ "@mui/material": "^5.15.10", "@mui/utils": "^5.15.11", "@opensystemslab/map": "1.0.0-alpha.4", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "@tiptap/core": "^2.4.0", "@tiptap/extension-bold": "^2.0.3", "@tiptap/extension-bubble-menu": "^2.1.13", diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index c985baee32..c683e55797 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -48,8 +48,8 @@ dependencies: specifier: 1.0.0-alpha.4 version: 1.0.0-alpha.4 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3(@types/react@18.2.45) + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851(@types/react@18.2.45) '@tiptap/core': specifier: ^2.4.0 version: 2.4.0(@tiptap/pm@2.0.3) @@ -3291,7 +3291,7 @@ packages: '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.1.2(react-dom@18.2.0)(react@18.2.0) '@mui/types': 7.2.19(@types/react@18.2.45) - '@mui/utils': 5.15.11(@types/react@18.2.45)(react@18.2.0) + '@mui/utils': 5.16.6(@types/react@18.2.45)(react@18.2.0) '@popperjs/core': 2.11.8 '@types/react': 18.2.45 clsx: 2.1.1 @@ -3314,7 +3314,7 @@ packages: '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) '@mui/types': 7.2.19(@types/react@18.2.45) - '@mui/utils': 5.15.11(@types/react@18.2.45)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.2.45)(react@18.3.1) '@popperjs/core': 2.11.8 '@types/react': 18.2.45 clsx: 2.1.1 @@ -4279,7 +4279,7 @@ packages: '@storybook/csf': 0.1.11 '@storybook/global': 5.0.0 '@storybook/icons': 1.2.12(react-dom@18.2.0)(react@18.2.0) - '@types/lodash': 4.14.202 + '@types/lodash': 4.17.13 color-convert: 2.0.1 dequal: 2.0.3 lodash: 4.17.21 @@ -5490,7 +5490,6 @@ packages: /@types/lodash@4.17.13: resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} - dev: false /@types/markdown-it@14.1.2: resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} @@ -7634,8 +7633,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -10023,7 +10022,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -10450,8 +10449,8 @@ packages: react: 18.2.0 dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -11438,8 +11437,8 @@ packages: hasBin: true dev: true - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -13523,6 +13522,11 @@ packages: engines: {node: '>=16'} dev: false + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} + engines: {node: '>=16'} + dev: false + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -14462,9 +14466,9 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - github.com/theopensystemslab/planx-core/ccf9ac3(@types/react@18.2.45): - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} - id: github.com/theopensystemslab/planx-core/ccf9ac3 + github.com/theopensystemslab/planx-core/29b4851(@types/react@18.2.45): + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} + id: github.com/theopensystemslab/planx-core/29b4851 name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -14479,18 +14483,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/FeeBreakdown.tsx b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/FeeBreakdown.tsx index 5ef73fc59f..ae545d4098 100644 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/FeeBreakdown.tsx +++ b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/FeeBreakdown.tsx @@ -140,10 +140,10 @@ export const FeeBreakdown: React.FC = () => {
- + - - + + diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/types.ts b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/types.ts deleted file mode 100644 index 176cf87724..0000000000 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface FeeBreakdown { - amount: { - applicationFee: number; - total: number; - reduction: number; - vat: number | undefined; - }; - reductions: string[]; - exemptions: string[]; -} - -export interface PassportFeeFields { - "application.fee.calculated": number; - "application.fee.payable": number; - "application.fee.payable.vat": number; - "application.fee.reduction.alternative": boolean; - "application.fee.reduction.parishCouncil": boolean; - "application.fee.reduction.sports": boolean; - "application.fee.exemption.disability": boolean; - "application.fee.exemption.resubmission": boolean; -}; \ No newline at end of file diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.test.ts b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.test.ts deleted file mode 100644 index 5312cb12c2..0000000000 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.test.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { logger } from "airbrake"; -import { useStore } from "pages/FlowEditor/lib/store"; -import { vi } from "vitest"; - -import { useFeeBreakdown } from "./useFeeBreakdown"; - -vi.mock("pages/FlowEditor/lib/store", () => ({ - useStore: vi.fn(), -})); - -vi.mock("airbrake", () => ({ - logger: { - notify: vi.fn(), - }, -})); - -describe("useFeeBreakdown() hook", () => { - describe("valid data", () => { - it("returns a fee breakdown for number inputs", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result).toEqual({ - amount: { - applicationFee: 1000, - total: 800, - reduction: 200, - vat: 160, - }, - exemptions: [], - reductions: [], - }); - }); - - it("returns a fee breakdown for number tuple inputs", () => { - const mockPassportData = { - "application.fee.calculated": [1000], - "application.fee.payable": [800], - "application.fee.payable.vat": [160], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result).toEqual({ - amount: { - applicationFee: 1000, - total: 800, - reduction: 200, - vat: 160, - }, - exemptions: [], - reductions: [], - }); - }); - - it("parses 'true' reduction values to a list of keys", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.reduction.alternative": ["true"], - "application.fee.reduction.parishCouncil": ["true"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result?.reductions).toHaveLength(2); - expect(result?.reductions).toEqual( - expect.arrayContaining(["alternative", "parishCouncil"]) - ); - }); - - it("does not parse 'false' reduction values to a list of keys", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.reduction.alternative": ["false"], - "application.fee.reduction.parishCouncil": ["false"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result?.reductions).toHaveLength(0); - }); - - it("does not parse non-schema reduction values", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.reduction.alternative": ["true"], - "application.fee.reduction.parishCouncil": ["false"], - "application.fee.reduction.someReason": ["true"], - "application.fee.reduction.someOtherReason": ["false"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([ - mockPassportData, - "test-session", - ]); - - const result = useFeeBreakdown(); - - expect(result?.reductions).toEqual(expect.not.arrayContaining(["someReason"])) - expect(result?.reductions).toEqual(expect.not.arrayContaining(["someOtherReason"])) - }); - - it("parses 'true' exemption values to a list of keys", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.exemption.disability": ["true"], - "application.fee.exemption.resubmission": ["true"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result?.exemptions).toHaveLength(2); - expect(result?.exemptions).toEqual( - expect.arrayContaining(["disability", "resubmission"]) - ); - }); - - it("does not parse 'false' exemption values to a list of keys", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.exemption.disability": ["false"], - "application.fee.exemption.resubmission": ["false"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result?.exemptions).toHaveLength(0); - }); - - it("does not parse non-schema exemption values", () => { - const mockPassportData = { - "application.fee.calculated": 1000, - "application.fee.payable": 800, - "application.fee.payable.vat": 160, - "application.fee.exemption.disability": ["false"], - "application.fee.exemption.resubmission": ["false"], - "application.fee.exemption.someReason": ["true"], - "application.fee.exemption.someOtherReason": ["false"], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([ - mockPassportData, - "test-session", - ]); - - const result = useFeeBreakdown(); - - expect(result?.exemptions).toEqual( - expect.not.arrayContaining(["someReason"]) - ); - expect(result?.exemptions).toEqual( - expect.not.arrayContaining(["someOtherReason"]) - ); - }); - }); - - describe("invalid inputs", () => { - it("returns undefined for missing data", () => { - const mockPassportData = { - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result).toBeUndefined(); - }); - - it("returns undefined for partial data", () => { - const mockPassportData = { - "application.fee.calculated": [1000], - "application.fee.payable.vat": [160], - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result).toBeUndefined(); - }); - - it("returns undefined for incorrect data", () => { - const mockPassportData = { - "application.fee.calculated": "some string", - "application.fee.payable": [800, 700], - "application.fee.payable.vat": false, - "some.other.fields": ["abc", "xyz"], - }; - - vi.mocked(useStore).mockReturnValue([mockPassportData, "test-session"]); - - const result = useFeeBreakdown(); - - expect(result).toBeUndefined(); - }); - - it("calls Airbrake if invalid inputs are provided", () => { - const mockPassportData = { - "some.other.fields": ["abc", "xyz"], - }; - const mockSessionId = "test-session"; - - vi.mocked(useStore).mockReturnValue([mockPassportData, mockSessionId]); - const loggerSpy = vi.spyOn(logger, "notify"); - - const result = useFeeBreakdown(); - - expect(result).toBeUndefined(); - - expect(loggerSpy).toHaveBeenCalledWith( - expect.stringContaining(mockSessionId), - ); - - expect(loggerSpy).toHaveBeenCalledWith( - expect.stringContaining("ZodError"), - ); - }); - }); -}); diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.tsx b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.tsx index b1e6b10c1d..bad94a386e 100644 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.tsx +++ b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/useFeeBreakdown.tsx @@ -1,9 +1,8 @@ +import { getFeeBreakdown } from "@opensystemslab/planx-core"; +import { FeeBreakdown } from "@opensystemslab/planx-core/types"; import { logger } from "airbrake"; import { useStore } from "pages/FlowEditor/lib/store"; -import { FeeBreakdown } from "./types"; -import { createPassportSchema } from "./utils"; - /** * Parses the users's Passport for data variables associated with their fee * Currently relies on static `application.fee.x` variables @@ -18,15 +17,13 @@ export const useFeeBreakdown = (): FeeBreakdown | undefined => { ]); if (!passportData) return - const schema = createPassportSchema(); - const result = schema.safeParse(passportData); - - if (!result.success) { + try { + const feeBreakdown = getFeeBreakdown(passportData); + return feeBreakdown; + } catch (error) { logger.notify( - `Failed to parse fee breakdown data from passport for session ${sessionId}. Error: ${result.error}`, + `Failed to parse fee breakdown data from passport for session ${sessionId}. Error: ${error}`, ); return; } - - return result.data; }; diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.test.ts b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.test.ts deleted file mode 100644 index 935c8cb066..0000000000 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { PassportFeeFields } from "./types"; -import { calculateReduction, toFeeBreakdown, toNumber } from "./utils"; - -describe("toNumber() helper function", () => { - it("outputs a number when passed a number", () => { - const input = 12; - const output = toNumber(input); - - expect(output).toEqual(input); - }); - - it("outputs a number when passed a number tuple", () => { - const input: [number] = [12]; - const output = toNumber(input); - - expect(output).toEqual(12); - }); -}); - -describe("calculateReduction() helper function", () => { - it("correctly outputs the reduction when a calculated value is provided", () => { - const input: PassportFeeFields = { - "application.fee.calculated": 100, - "application.fee.payable": 50, - "application.fee.payable.vat": 0, - "application.fee.reduction.alternative": false, - "application.fee.reduction.parishCouncil": false, - "application.fee.reduction.sports": false, - "application.fee.exemption.disability": false, - "application.fee.exemption.resubmission": false, - }; - const reduction = calculateReduction(input); - - expect(reduction).toEqual(50); - }); - - it("defaults to 0 when calculated is 0", () => { - const input: PassportFeeFields = { - "application.fee.calculated": 0, - "application.fee.payable": 100, - "application.fee.payable.vat": 0, - "application.fee.reduction.alternative": false, - "application.fee.reduction.parishCouncil": false, - "application.fee.reduction.sports": false, - "application.fee.exemption.disability": false, - "application.fee.exemption.resubmission": false, - }; - const reduction = calculateReduction(input); - - expect(reduction).toEqual(0); - }); -}); - -describe("toFeeBreakdown() helper function", () => { - it("correctly maps fields", () => { - const input: PassportFeeFields = { - "application.fee.calculated": 100, - "application.fee.payable": 50, - "application.fee.payable.vat": 10, - "application.fee.reduction.alternative": false, - "application.fee.reduction.parishCouncil": false, - "application.fee.reduction.sports": false, - "application.fee.exemption.disability": false, - "application.fee.exemption.resubmission": false, - }; - - const { amount } = toFeeBreakdown(input); - - expect(amount.applicationFee).toEqual(input["application.fee.calculated"]); - expect(amount.total).toEqual(input["application.fee.payable"]); - expect(amount.vat).toEqual(input["application.fee.payable.vat"]); - expect(amount.reduction).toEqual(50); - }); - - it("sets applicationFee to payable amount if no calculated value is provided", () => { - const input: PassportFeeFields = { - "application.fee.calculated": 0, - "application.fee.payable.vat": 10, - "application.fee.payable": 50, - "application.fee.reduction.alternative": false, - "application.fee.reduction.parishCouncil": false, - "application.fee.reduction.sports": false, - "application.fee.exemption.disability": false, - "application.fee.exemption.resubmission": false, - }; - - const { amount } = toFeeBreakdown(input); - - expect(amount.applicationFee).toEqual(input["application.fee.payable"]); - }); -}); diff --git a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.ts b/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.ts deleted file mode 100644 index 759c5438db..0000000000 --- a/editor.planx.uk/src/@planx/components/Pay/Public/FeeBreakdown/utils.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { z } from "zod"; - -import { FeeBreakdown, PassportFeeFields } from "./types"; - -export const toNumber = (input: number | [number]) => - Array.isArray(input) ? input[0] : input; - -/** - * Convert a Passport value to an actual boolean - */ -const toBoolean = (val: ["true" | "false"]) => val[0] === "true"; - - -/** - * Iterate over exemptions or reductions to find matches, returning the granular keys - */ - const getGranularKeys = ( - data: PassportFeeFields, - prefix: "application.fee.reduction" | "application.fee.exemption" - ) => { - const keys = Object.keys(data) as (keyof PassportFeeFields)[]; - const intersectingKeys = keys.filter( - (key) => key.startsWith(prefix) && Boolean(data[key]) - ); - const granularKeys = intersectingKeys.map((key) => - key.replace(prefix + ".", "") - ); - - return granularKeys; - }; - -/** - * A "reduction" is the sum of the difference between calculated and payable - */ -export const calculateReduction = (data: PassportFeeFields) => - data["application.fee.calculated"] - ? data["application.fee.calculated"] - data["application.fee.payable"] - : 0; - -/** - * Transform Passport data to a FeeBreakdown - */ -export const toFeeBreakdown = (data: PassportFeeFields): FeeBreakdown => ({ - amount: { - applicationFee: - data["application.fee.calculated"] || - data["application.fee.payable"], - total: data["application.fee.payable"], - vat: data["application.fee.payable.vat"], - reduction: calculateReduction(data), - }, - reductions: getGranularKeys(data, "application.fee.reduction"), - exemptions: getGranularKeys(data, "application.fee.exemption"), -}); - -export const createPassportSchema = () => { - const questionSchema = z.number().nonnegative(); - const setValueSchema = z.tuple([z.coerce.number().nonnegative()]); - const feeSchema = z - .union([questionSchema, setValueSchema]) - .transform(toNumber); - - /** Describes how boolean values are set via PlanX components */ - const booleanSchema = z - .tuple([z.enum(["true", "false"])]) - .default(["false"]) - .transform(toBoolean) - - const schema = z - .object({ - "application.fee.calculated": feeSchema.optional().default(0), - "application.fee.payable": feeSchema, - "application.fee.payable.vat": feeSchema.optional().default(0), - "application.fee.reduction.alternative": booleanSchema, - "application.fee.reduction.parishCouncil": booleanSchema, - "application.fee.reduction.sports": booleanSchema, - "application.fee.exemption.disability": booleanSchema, - "application.fee.exemption.resubmission": booleanSchema, - }) - .transform(toFeeBreakdown); - - return schema; -};