diff --git a/.eslintrc b/.eslintrc index 142e0d8b..f9398f91 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,6 +7,7 @@ "plugin:@typescript-eslint/recommended" ], "rules": { + "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-unused-vars": [ "warn", diff --git a/README.md b/README.md index 8067a72b..48ef0399 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,70 @@ # PlanX Core -This package is a declarative boundary between the data access layer (GraphQL/Hasura/Postgres) and the PlanX domain. +This package is a declarative wrapper for the core data structures and operations of [PlanX](https://github.com/theopensystemslab/planx-new). -## Running locally +It also includes data processing functions for the various export formats of PlanX application data. + +## Structure + +The package is structured by functional responsibility. Here is a summary of what each directory contains: + + ./src + ├── requests # a data access client exposing declarative interfaces for common database operations + ├── models # a set of functions and classes that encapsulate the functionality of domain objects + ├── exports # data processing functions to convert application data into third-party data formats + ├── templates # data processing functions to convert application data into various document formats + └── types # a set of Typescript types for the exported functions and structures of this package + +## Conventions + +Requests: + +- `CoreDomainClient` sets up individual resource clients which each expose a declarative interface for operations on that resource. +- Functions or methods that begin with an underscore (e.g `$admin.session._destroy`) are intended as development/test utilities and do not represent actions that should be a part of application code. +- Instances of `CoreDomainClient` should be named `$` to indicate the permission set it has been granted, e.g. `$api` or `$public` + +Models: + +- Rich data structures which have implicit rules around how data should be read or manipulated are best represented as classes which encapsulate behaviours in methods. +- Simple data structures which have few or no rules around how data should be read or manipulated are best represented as simple objects/arrays with a clear type definition. + +Exports / Templates: + +- Prefer stream processing where possible. + +Types: + +- Following the [robustness principle](https://en.wikipedia.org/wiki/Robustness_principle), types should generally be represented as an `interface` for inputs and as a `type` for outputs with a known structure. + +## Local Development - Install [pnpm](https://pnpm.io) globally if you don't have it already `npm i pnpm -g` - Install dependencies `pnpm i` Other useful package scripts: - * `pnpm test`: run the test suite - * `pnpm check`: check and fix type and linting errors - * `pnpm build`: build the package +- `pnpm build`: generate package exports and examples + +- `pnpm check`: scan for type and style errors +- `pnpm lint`: scan for style errors +- `pnpm lint:fix`: fix style errors + +- `pnpm test`: run unit tests +- `pnpm test:coverage`: run unit tests with coverage report -## Debugging +### Debugging Setting the environment variable `DEBUG` to any truthy value turns on the console output for debugging (useful for setup and teardown issues). ## Publishing -This node package is published via Github and can be referenced in a `package.json`, like so: +This node package is published via Github and can be referenced in a `pnpm` style `package.json` file, like so: "dependencies": { - "@opensystemslab/planx-core": "git://github.com/theopensystemslab/planx-core.git#commit-ish", + "@opensystemslab/planx-core": "github:theopensystemslab/planx-core#commit-ish", ... } ## License -This repository is licensed under the [Open Government License v3](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). +This repository is licensed under the [The Mozilla Public License (MPL) Version 2](https://github.com/theopensystemslab/planx-core/blob/main/LICENSE). diff --git a/jest.config.ts b/jest.config.ts index e6f84d61..c0634656 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -9,7 +9,8 @@ export default { }, ], }, - testPathIgnorePatterns: ["dist/*"], + testPathIgnorePatterns: ["dist/*", "tests/*"], + setupFilesAfterEnv: ["./jest.setup.js"], collectCoverage: true, coverageReporters: ["html", "lcov", "text-summary"], coverageDirectory: "./coverage", diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 00000000..ab160275 --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,2 @@ +process.env.HASURA_GRAPHQL_ADMIN_SECRET = "👻"; +process.env.HASURA_GRAPHQL_URL = "👻"; diff --git a/package.json b/package.json index 0d0a0fe4..a0fbfb84 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ ], "module": "./dist/index.js", "main": "./dist/index.js", - "types": "./dist/index.d.ts", "lint-staged": { "src/**/*.{js,ts}": "eslint --fix", "src/**/*": "prettier -w" @@ -30,6 +29,7 @@ "require": "./types/index.js" } }, + "types": "./dist/index.d.ts", "scripts": { "build": "rimraf ./types ./dist && tsc --project ./tsconfig.types.json && tsc && pnpm copy-json-schema", "examples": "rimraf ./examples && ts-node ./src/templates/generateExamples.ts", @@ -91,13 +91,14 @@ "@types/lodash.set": "^4.3.7", "@types/lodash.startcase": "^4.4.7", "@types/node": "^18.16.19", - "@types/react": "^18.2.15", "@types/react-dom": "^18.2.13", "@types/uuid": "^9.0.5", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", "esbuild": "^0.19.4", + "@types/react": "^18.2.17", + "@typescript-eslint/eslint-plugin": "^6.2.0", + "@typescript-eslint/parser": "^6.2.0", "esbuild-jest": "^0.5.0", + "eslint": "^8.46.0", "eslint-plugin-simple-import-sort": "^10.0.0", "husky": "^8.0.3", "jest": "^29.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e6286a9..434d88b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,13 +7,13 @@ settings: dependencies: '@emotion/react': specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.15)(react@18.2.0) + version: 11.11.1(@types/react@18.2.17)(react@18.2.0) '@emotion/styled': specifier: ^11.11.0 - version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) + version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.17)(react@18.2.0) '@mui/material': specifier: ^5.14.13 - version: 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + version: 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.17)(react-dom@18.2.0)(react@18.2.0) '@types/geojson': specifier: ^7946.0.11 version: 7946.0.11 @@ -143,8 +143,8 @@ devDependencies: specifier: ^18.16.19 version: 18.16.19 '@types/react': - specifier: ^18.2.15 - version: 18.2.15 + specifier: ^18.2.17 + version: 18.2.17 '@types/react-dom': specifier: ^18.2.13 version: 18.2.13 @@ -152,11 +152,11 @@ devDependencies: specifier: ^9.0.5 version: 9.0.5 '@typescript-eslint/eslint-plugin': - specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.2.2) + specifier: ^6.2.0 + version: 6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.51.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^5.62.0 - version: 5.62.0(eslint@8.51.0)(typescript@5.2.2) + specifier: ^6.2.0 + version: 6.2.0(eslint@8.51.0)(typescript@5.2.2) esbuild: specifier: ^0.19.4 version: 0.19.4 @@ -630,7 +630,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0): + /@emotion/react@11.11.1(@types/react@18.2.17)(react@18.2.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' @@ -646,7 +646,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.15 + '@types/react': 18.2.17 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -665,7 +665,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0): + /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.17)(react@18.2.0): resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -678,11 +678,11 @@ packages: '@babel/runtime': 7.22.6 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.17)(react@18.2.0) '@emotion/serialize': 1.1.2 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.15 + '@types/react': 18.2.17 react: 18.2.0 dev: false @@ -913,11 +913,6 @@ packages: eslint: 8.51.0 eslint-visitor-keys: 3.4.3 - /@eslint-community/regexpp@4.5.1: - resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - /@eslint-community/regexpp@4.6.2: resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -1328,7 +1323,7 @@ packages: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} dev: false - /@mui/base@5.0.0-beta.19(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): + /@mui/base@5.0.0-beta.19(@types/react@18.2.17)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-maNBgAscddyPNzFZQUJDF/puxM27Li+NqSBsr/lAP8TLns2VvWS2SoL3OKFOIoRnAMKGY/Ic6Aot6gCYeQnssA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1341,10 +1336,10 @@ packages: dependencies: '@babel/runtime': 7.23.2 '@floating-ui/react-dom': 2.0.2(react-dom@18.2.0)(react@18.2.0) - '@mui/types': 7.2.6(@types/react@18.2.15) - '@mui/utils': 5.14.13(@types/react@18.2.15)(react@18.2.0) + '@mui/types': 7.2.6(@types/react@18.2.17) + '@mui/utils': 5.14.13(@types/react@18.2.17)(react@18.2.0) '@popperjs/core': 2.11.8 - '@types/react': 18.2.15 + '@types/react': 18.2.17 clsx: 2.0.0 prop-types: 15.8.1 react: 18.2.0 @@ -1355,7 +1350,7 @@ packages: resolution: {integrity: sha512-3ZUbzcH4yloLKlV6Y+S0Edn2wef9t+EGHSfEkwVCn8E0ULdshifEFgfEroKRegQifDIwcKS/ofccxuZ8njTAYg==} dev: false - /@mui/material@5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): + /@mui/material@5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.17)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-iPEFwhoVG789UVsXX4gqd1eJUlcLW1oceqwJYQN8Z4MpcAKfL9Lv3fda65AwG7pQ5lf+d7IbHzm4m48SWZxI2g==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1373,14 +1368,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) - '@mui/base': 5.0.0-beta.19(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.17)(react@18.2.0) + '@mui/base': 5.0.0-beta.19(@types/react@18.2.17)(react-dom@18.2.0)(react@18.2.0) '@mui/core-downloads-tracker': 5.14.13 - '@mui/system': 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react@18.2.0) - '@mui/types': 7.2.6(@types/react@18.2.15) - '@mui/utils': 5.14.13(@types/react@18.2.15)(react@18.2.0) - '@types/react': 18.2.15 + '@mui/system': 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.17)(react@18.2.0) + '@mui/types': 7.2.6(@types/react@18.2.17) + '@mui/utils': 5.14.13(@types/react@18.2.17)(react@18.2.0) + '@types/react': 18.2.17 '@types/react-transition-group': 4.4.7 clsx: 2.0.0 csstype: 3.1.2 @@ -1391,7 +1386,7 @@ packages: react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@mui/private-theming@5.14.13(@types/react@18.2.15)(react@18.2.0): + /@mui/private-theming@5.14.13(@types/react@18.2.17)(react@18.2.0): resolution: {integrity: sha512-5EFqk4tqiSwPguj4NW/6bUf4u1qoUWXy9lrKfNh9H6oAohM+Ijv/7qSxFjnxPGBctj469/Sc5aKAR35ILBKZLQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1402,8 +1397,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.13(@types/react@18.2.15)(react@18.2.0) - '@types/react': 18.2.15 + '@mui/utils': 5.14.13(@types/react@18.2.17)(react@18.2.0) + '@types/react': 18.2.17 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -1423,14 +1418,14 @@ packages: dependencies: '@babel/runtime': 7.23.2 '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.17)(react@18.2.0) csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react@18.2.0): + /@mui/system@5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.17)(react@18.2.0): resolution: {integrity: sha512-+5+Dx50lG4csbx2sGjrKLozXQJeCpJ4dIBZolyFLkZ+XphD1keQWouLUvJkPQ3MSglLLKuD37pp52YjMncZMEQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1447,20 +1442,20 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) - '@mui/private-theming': 5.14.13(@types/react@18.2.15)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.17)(react@18.2.0) + '@mui/private-theming': 5.14.13(@types/react@18.2.17)(react@18.2.0) '@mui/styled-engine': 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.6(@types/react@18.2.15) - '@mui/utils': 5.14.13(@types/react@18.2.15)(react@18.2.0) - '@types/react': 18.2.15 + '@mui/types': 7.2.6(@types/react@18.2.17) + '@mui/utils': 5.14.13(@types/react@18.2.17)(react@18.2.0) + '@types/react': 18.2.17 clsx: 2.0.0 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.6(@types/react@18.2.15): + /@mui/types@7.2.6(@types/react@18.2.17): resolution: {integrity: sha512-7sjLQrUmBwufm/M7jw/quNiPK/oor2+pGUQP2CULRcFCArYTq78oJ3D5esTaL0UMkXKJvDqXn6Ike69yAOBQng==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1468,10 +1463,10 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.15 + '@types/react': 18.2.17 dev: false - /@mui/utils@5.14.13(@types/react@18.2.15)(react@18.2.0): + /@mui/utils@5.14.13(@types/react@18.2.17)(react@18.2.0): resolution: {integrity: sha512-2AFpyXWw7uDCIqRu7eU2i/EplZtks5LAMzQvIhC79sPV9IhOZU2qwOWVnPtdctRXiQJOAaXulg+A37pfhEueQw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1483,7 +1478,7 @@ packages: dependencies: '@babel/runtime': 7.23.2 '@types/prop-types': 15.7.8 - '@types/react': 18.2.15 + '@types/react': 18.2.17 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 @@ -1725,17 +1720,17 @@ packages: /@types/react-dom@18.2.13: resolution: {integrity: sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==} dependencies: - '@types/react': 18.2.15 + '@types/react': 18.2.17 dev: true /@types/react-transition-group@4.4.7: resolution: {integrity: sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg==} dependencies: - '@types/react': 18.2.15 + '@types/react': 18.2.17 dev: false - /@types/react@18.2.15: - resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} + /@types/react@18.2.17: + resolution: {integrity: sha512-u+e7OlgPPh+aryjOm5UJMX32OvB2E3QASOAqVMY6Ahs90djagxwv2ya0IctglNbNTexC12qCSMZG47KPfy1hAA==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 @@ -1772,47 +1767,50 @@ packages: '@types/yargs-parser': 21.0.0 dev: true - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/eslint-plugin@6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2) + '@eslint-community/regexpp': 4.6.2 + '@typescript-eslint/parser': 6.2.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/type-utils': 6.2.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.2.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.2.0 debug: 4.3.4 eslint: 8.51.0 graphemer: 1.4.0 ignore: 5.2.4 + natural-compare: 1.4.0 natural-compare-lite: 1.4.0 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.2.2) + ts-api-utils: 1.0.3(typescript@5.2.2) typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.62.0(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/parser@6.2.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.2.0 debug: 4.3.4 eslint: 8.51.0 typescript: 5.2.2 @@ -1820,85 +1818,84 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@5.62.0: - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/scope-manager@6.2.0: + resolution: {integrity: sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/visitor-keys': 6.2.0 dev: true - /@typescript-eslint/type-utils@5.62.0(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/type-utils@6.2.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: '*' + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.2.0(eslint@8.51.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.51.0 - tsutils: 3.21.0(typescript@5.2.2) + ts-api-utils: 1.0.3(typescript@5.2.2) typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@5.62.0: - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/types@6.2.0: + resolution: {integrity: sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==} + engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@5.62.0(typescript@5.2.2): - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@6.2.0(typescript@5.2.2): + resolution: {integrity: sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/visitor-keys': 6.2.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.2.2) + ts-api-utils: 1.0.3(typescript@5.2.2) typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/utils@6.2.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2) eslint: 8.51.0 - eslint-scope: 5.1.1 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@5.62.0: - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/visitor-keys@6.2.0: + resolution: {integrity: sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/types': 6.2.0 eslint-visitor-keys: 3.4.3 dev: true @@ -2452,7 +2449,7 @@ packages: dev: true /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -2799,14 +2796,6 @@ packages: eslint: 8.51.0 dev: true - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2889,11 +2878,6 @@ packages: dependencies: estraverse: 5.3.0 - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -5525,6 +5509,15 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false + /ts-api-utils@1.0.3(typescript@5.2.2): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.2.2 + dev: true + /ts-jest@29.1.1(@babel/core@7.22.8)(esbuild@0.19.4)(jest@29.7.0)(typescript@5.2.2): resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5591,20 +5584,6 @@ packages: yn: 3.1.1 dev: true - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /tsutils@3.21.0(typescript@5.2.2): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.2.2 - dev: true - /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} diff --git a/src/export/bops/mocks/flow.ts b/src/export/bops/mocks/flow.ts index e4660633..4454b129 100644 --- a/src/export/bops/mocks/flow.ts +++ b/src/export/bops/mocks/flow.ts @@ -1,5 +1,7 @@ +import type { FlowGraph } from "../../../types"; + // Mock publishedFLow generated from Lambeths' LDC service on 27.04.2023 -export const mockPublishedLDCFlow = { +export const mockPublishedLDCFlow: FlowGraph = { _root: { edges: [ "CmZmDeqskJ", diff --git a/src/models/passport/passport.test.ts b/src/models/passport/passport.test.ts index 2ac57079..690a6b74 100644 --- a/src/models/passport/passport.test.ts +++ b/src/models/passport/passport.test.ts @@ -7,6 +7,10 @@ import { singleFileQuestion, } from "./mocks"; +type ArrayWithURLProp = Array<{ + url: string; +}>; + describe("Passport", () => { describe("constructor", () => { it("throws when given no data", () => { @@ -34,7 +38,11 @@ describe("Passport", () => { const result = passport.files(); expect(result).toHaveLength(1); expect(result).toEqual([ - singleFileQuestion.data!["property.drawing.elevation"]![0].url, + ( + singleFileQuestion.data![ + "property.drawing.elevation" + ] as ArrayWithURLProp + )[0].url, ]); }); @@ -43,8 +51,16 @@ describe("Passport", () => { const result = passport.files(); expect(result).toHaveLength(2); expect(result).toEqual([ - multipleFileQuestions.data!["property.drawing.elevation"]![0].url, - multipleFileQuestions.data!["proposal.drawing.elevation"]![0].url, + ( + multipleFileQuestions.data![ + "property.drawing.elevation" + ] as ArrayWithURLProp + )[0].url, + ( + multipleFileQuestions.data![ + "proposal.drawing.elevation" + ] as ArrayWithURLProp + )[0].url, ]); }); @@ -53,26 +69,82 @@ describe("Passport", () => { const result = passport.files(); expect(result).toHaveLength(7); expect(result).toEqual([ - multipleFilesMultipleQuestions.data!["property.drawing.elevation"]![0] - .url, - multipleFilesMultipleQuestions.data!["property.drawing.elevation"]![1] - .url, - multipleFilesMultipleQuestions.data!["proposal.drawing.elevation"]![0] - .url, - multipleFilesMultipleQuestions.data!["property.drawing.sitePlan"]![0] - .url, - multipleFilesMultipleQuestions.data!["property.drawing.sitePlan"]![1] - .url, - multipleFilesMultipleQuestions.data!["property.drawing.sitePlan"]![2] - .url, - multipleFilesMultipleQuestions.data!["proposal.drawing.sitePlan"]![0] - .url, + ( + multipleFilesMultipleQuestions.data![ + "property.drawing.elevation" + ] as ArrayWithURLProp + )[0].url, + ( + multipleFilesMultipleQuestions.data![ + "property.drawing.elevation" + ] as ArrayWithURLProp + )[1].url, + ( + multipleFilesMultipleQuestions.data![ + "proposal.drawing.elevation" + ] as ArrayWithURLProp + )[0].url, + ( + multipleFilesMultipleQuestions.data![ + "property.drawing.sitePlan" + ] as ArrayWithURLProp + )[0].url, + ( + multipleFilesMultipleQuestions.data![ + "property.drawing.sitePlan" + ] as ArrayWithURLProp + )[1].url, + ( + multipleFilesMultipleQuestions.data![ + "property.drawing.sitePlan" + ] as ArrayWithURLProp + )[2].url, + ( + multipleFilesMultipleQuestions.data![ + "proposal.drawing.sitePlan" + ] as ArrayWithURLProp + )[0].url, ]); }); }); + describe("has() method", () => { + it("returns true for non-empty values", () => { + const passport = new Passport({ + data: { + a: { + b: ["it", "works"], + c: ["Yes"], + d: 0, + }, + }, + }); + expect(passport.has(["a", "b"])).toBe(true); + expect(passport.has(["a", "c"])).toBe(true); + expect(passport.has(["a", "d"])).toBe(true); + }); + it("returns false for empty values", () => { + const passport = new Passport({ + data: { + a: { + "b.c": [], + d: {}, + e: null, + f: undefined, + g: [[]], + }, + }, + }); + expect(passport.has(["a", "b.c"])).toEqual(false); + expect(passport.has(["a", "d"])).toEqual(false); + expect(passport.has(["a", "e"])).toEqual(false); + expect(passport.has(["a", "f"])).toEqual(false); + expect(passport.has(["a", "g"])).toEqual(false); + }); + }); + describe("strings() method", () => { - test("it accesses data from a simple object", () => { + it("accesses data from a simple object", () => { const passport = new Passport({ data: { a: { @@ -299,4 +371,23 @@ describe("Passport", () => { expect(passport.number(["a"])).toEqual(4); }); }); + + describe("any() method", () => { + test("it accesses any Value", () => { + const passport = new Passport({ + data: { + a: { + b: 1, + "b.c": { + d: { + "e.f.g": "4", + }, + }, + }, + }, + }); + expect(passport.any(["a", "b"])).toEqual(1); + expect(passport.any(["a", "b.c"])).toEqual({ d: { "e.f.g": "4" } }); + }); + }); }); diff --git a/src/models/passport/passport.ts b/src/models/passport/passport.ts index edc6c0f0..c9daa5b3 100644 --- a/src/models/passport/passport.ts +++ b/src/models/passport/passport.ts @@ -17,13 +17,22 @@ export class Passport { } files() { - const isFileUploadQuestion = (question) => has(question?.[0], "url"); - const getFileURLs = (questionWithFiles) => - questionWithFiles.map((question) => question.url); + const isFileUploadQuestion = (question: { url: string }[]): boolean => + has(question?.[0], "url"); + + const getFileURLs = (questionWithFiles: { url: string }[]): string[] => + questionWithFiles.map((question) => question?.url); return Object.values(this.data) - .filter(isFileUploadQuestion) - .flatMap(getFileURLs); + .filter((questions) => + isFileUploadQuestion(questions as { url: string }[]), + ) + .flatMap((questions) => getFileURLs(questions as { url: string }[])); + } + + has(path: KeyPath): boolean { + const valueString = this.string(path).trim(); + return !["", "{}", "[]"].includes(valueString); } strings(path: KeyPath): string[] { @@ -33,6 +42,7 @@ export class Passport { } else if (Array.isArray(values)) { return values.map((x) => String(x)); } + if (typeof values === "object") return [JSON.stringify(values)]; return [String(values)]; } @@ -47,6 +57,11 @@ export class Passport { number(path: KeyPath): number { return +(this.strings(path)[0] || 0); } + + any(path: KeyPath): unknown { + if (!this.has(path)) return; + return get({ data: this.data, path })!; + } } function get({ diff --git a/src/models/session/mocks/large-real-life-flow.ts b/src/models/session/mocks/large-real-life-flow.ts index 8a2095df..38f70d73 100644 --- a/src/models/session/mocks/large-real-life-flow.ts +++ b/src/models/session/mocks/large-real-life-flow.ts @@ -1,4 +1,6 @@ -export const breadcrumbs = { +import type { Breadcrumbs, FlowGraph } from "../../../types"; + +export const breadcrumbs: Breadcrumbs = { CmZmDeqskJ: { auto: false, }, @@ -7,7 +9,7 @@ export const breadcrumbs = { // Service: "apply-for-lawful-development-certificate", Buckinghamshire // Date: 27/03/23 -export const flow = { +export const flow: FlowGraph = { _root: { edges: [ "CmZmDeqskJ", diff --git a/src/requests/index.test.ts b/src/requests/index.test.ts index 4736df70..bea94bb2 100644 --- a/src/requests/index.test.ts +++ b/src/requests/index.test.ts @@ -1,6 +1,21 @@ import { CoreDomainClient } from "./index"; describe("CoreDomainClient", () => { + const OriginalEnv = process.env; + + beforeEach(() => { + jest.resetModules(); + process.env = { + ...OriginalEnv, + HASURA_GRAPHQL_ADMIN_SECRET: "shhh", + HASURA_GRAPHQL_URL: "http://a.b.c", + }; + }); + + afterAll(() => { + process.env = OriginalEnv; + }); + test("instantiating a client without any arguments", () => { const core = new CoreDomainClient(); expect(core).toBeInstanceOf(CoreDomainClient); diff --git a/src/requests/index.ts b/src/requests/index.ts index e13dadf6..5349fc37 100644 --- a/src/requests/index.ts +++ b/src/requests/index.ts @@ -1,28 +1,25 @@ +import assert from "node:assert"; + import type { GraphQLClient } from "graphql-request"; -import slugify from "lodash.kebabcase"; import { ExportClient } from "../export"; -import type { KeyPath, PaymentRequest, Session } from "../types"; import { ApplicationClient } from "./application"; import { getDocumentTemplateNamesForFlow, getDocumentTemplateNamesForSession, } from "./document-templates"; -import { createFlow, FlowClient, publishFlow } from "./flow"; +import { FlowClient } from "./flow"; import { Auth, getGraphQLClient } from "./graphql"; -import { createPaymentRequest, PaymentRequestClient } from "./payment-request"; +import { PaymentRequestClient } from "./payment-request"; import { formatRawProjectTypes } from "./project-types"; -import { - getSessionById, - lockSession, - SessionClient, - unlockSession, -} from "./session"; -import { createTeam, TeamClient } from "./team"; -import { createUser, UserClient } from "./user"; +import { SessionClient } from "./session"; +import { TeamClient } from "./team"; +import { UserClient } from "./user"; const defaultURL = process.env.HASURA_GRAPHQL_URL!; +assert(process.env.HASURA_GRAPHQL_URL); +// declarative data access client export class CoreDomainClient { client!: GraphQLClient; protected url: string; @@ -56,45 +53,10 @@ export class CoreDomainClient { } // TODO: refactor below into client namespaces (e.g. SessionClient) - // namspacing prevents this class from growing too unwieldy while still allowing for + // namespacing prevents this class from growing too unwieldy while still allowing for // a simple interface for callers. // Namespacing also allows for terser function names (e.g. `client.session.lock("123")`) - async createUser(args: { - firstName: string; - lastName: string; - email: string; - }): Promise { - return createUser(this.client, args); - } - - async createTeam(args: { - name: string; - slug: string | undefined; - logo: string; - primaryColor: string; - homepage: string; - submissionEmail: string; - }): Promise { - const slug = args.slug ? args.slug : slugify(args.name); - return createTeam(this.client, { ...args, slug }); - } - - async createFlow(args: { - teamId: number; - slug: string; - data?: object; - }): Promise { - return createFlow(this.client, args); - } - - async publishFlow(args: { - flow: { id: string; data: object }; - publisherId: number; - }): Promise { - return publishFlow(this.client, args); - } - // TODO: Remove this once planx-new updated async getDocumentTemplateNames(flowId: string): Promise { return getDocumentTemplateNamesForFlow(this.client, flowId); @@ -110,28 +72,6 @@ export class CoreDomainClient { return getDocumentTemplateNamesForSession(this.client, sessionId); } - async getSessionById(sessionId: string): Promise { - return getSessionById(this.client, sessionId); - } - - async lockSession(sessionId: string): Promise { - return lockSession(this.client, sessionId); - } - - async unlockSession(sessionId: string): Promise { - return unlockSession(this.client, sessionId); - } - - async createPaymentRequest(args: { - sessionId: string; - applicantName: string; - payeeName: string; - payeeEmail: string; - sessionPreviewKeys: Array; - }): Promise { - return createPaymentRequest(this.client, args); - } - /** * Convert and formats raw project types as a formatted list * @example diff --git a/src/types/flow.ts b/src/types/flow.ts index 9fcccdcd..310cbeae 100644 --- a/src/types/flow.ts +++ b/src/types/flow.ts @@ -1,6 +1,8 @@ import { ComponentType } from "./component"; import type { Value } from "./data"; +export type FlowId = string; + export type NodeId = string; export type Edges = Array; diff --git a/src/types/payment-request.ts b/src/types/payment-request.ts index 126a3dab..b05285eb 100644 --- a/src/types/payment-request.ts +++ b/src/types/payment-request.ts @@ -1,4 +1,4 @@ -import { Value } from "./data"; +import { DataObject } from "./data"; export interface PaymentRequest { id: string; @@ -7,7 +7,7 @@ export interface PaymentRequest { payeeName: string; payeeEmail: string; paymentAmount: number; - sessionPreviewData: { [key: string]: Value }; + sessionPreviewData: DataObject; paidAt: string; createdAt: string; govPayPaymentId: string; diff --git a/tsconfig.json b/tsconfig.json index 2642ea59..f036ed79 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,5 +17,5 @@ "outDir": "dist" }, "include": ["./src/*", "./src/**/*"], - "exclude": ["./src/*.test.ts", "./src/**/*.test.ts", "./src/**/mocks"] + "exclude": ["*.test.ts", "./src/**/mocks"] } diff --git a/tsconfig.types.json b/tsconfig.types.json index 39e65466..3ceef972 100644 --- a/tsconfig.types.json +++ b/tsconfig.types.json @@ -10,6 +10,7 @@ "noImplicitAny": false, "resolveJsonModule": true, "skipLibCheck": true, + "jsx": "react", "strict": true, "rootDir": "./src/types", "declaration": true, @@ -17,5 +18,5 @@ "outDir": "types" }, "include": ["./src/types/*"], - "exclude": ["./src/*.test.ts"] + "exclude": ["*.test.ts"] }