Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
974bf71
CCM-12896: Generate JSON schemas during make config
gareth-allan Nov 21, 2025
09fd304
CCM-12896: Initial application to generate TS event types
gareth-allan Nov 24, 2025
36462b0
CCM-12896: Generate validation code from JSON schema using ajv
gareth-allan Nov 24, 2025
c770db9
CCM-12896: Dependency updates for security
gareth-allan Nov 25, 2025
742c4f2
CCM-12896: Use generated type to build an event
gareth-allan Nov 25, 2025
fa1220a
CCM-12896: Properly set dev dependencies for typescript-schema-generator
gareth-allan Nov 25, 2025
bc5a1b1
CCM-12896: Initial version of script to generate types
gareth-allan Nov 25, 2025
f14c68c
CCM:12896: Initial version of script to generate validators
gareth-allan Nov 26, 2025
7158fab
CCM-12896: Update generate-validators to use the real event schemas#
gareth-allan Nov 26, 2025
de2a8ac
CCM-12896: Tidy up type and validator generation code
gareth-allan Nov 26, 2025
7a5f24d
CCM-12896: Add npm clean to Makefile clean target
gareth-allan Nov 27, 2025
c55cf6e
CCM-12896: Reorganise Makefiles to make code generation run only what…
gareth-allan Nov 27, 2025
ecbec10
CCM-12896: Make flattened schemas dereference properties too
gareth-allan Nov 27, 2025
e7efe5f
CCM-12896: Removed unnecessary ESLint ignore
gareth-allan Nov 27, 2025
9d58fc0
CCM-12896: Optimise schema generation done as part of code generation
gareth-allan Nov 27, 2025
2b21473
CCM-12896: Use make generate command to generate code when deploying …
gareth-allan Nov 27, 2025
9863588
CCM-12896: Schema fixes
gareth-allan Nov 27, 2025
fe69993
CCM-12896: Use make generate in workflow
gareth-allan Nov 28, 2025
a6643bc
CCM-12896: Try setting up Node before generating dependencies
gareth-allan Nov 28, 2025
6f015c3
CCM-12896: Use tsx instead of ts-node for doc generation
gareth-allan Nov 28, 2025
531d53d
CCM-12896: Remove unnecessary dependency from typescript-schema-gener…
gareth-allan Nov 28, 2025
b45c516
CCM-12896: Fix test error
gareth-allan Nov 28, 2025
dc25973
CCM-12896: Revert doc test change to tsx
gareth-allan Nov 28, 2025
808b248
CCM-12896: Extend mesh-poll test coverage
gareth-allan Nov 28, 2025
56b64ff
Revert "CCM-12896: Revert doc test change to tsx"
gareth-allan Nov 28, 2025
dfc8173
CCM-12896: Small post-self-review changes
gareth-allan Nov 28, 2025
ade615d
CCM-12896: Temporarily disable coverage checks for typescript-schema-…
gareth-allan Nov 28, 2025
08299ea
CCM-12896: Fix make build command
gareth-allan Nov 28, 2025
429d12c
CCM-12896: Add temporary debug to pre.sh
gareth-allan Dec 1, 2025
38fd969
CCM-12896: Test running make via NPM
gareth-allan Dec 1, 2025
4d8f672
CCM-12896: Use NPM to generate dependencies, instead of Makefile
gareth-allan Dec 1, 2025
50b5bc7
CCM-12896: Remove commented-out code
gareth-allan Dec 2, 2025
54a90df
CCM-12896: Added a README.md to typescript-schema-generator
gareth-allan Dec 2, 2025
f7f51fc
CCM-12896: Added a note on generated code to main README.md
gareth-allan Dec 2, 2025
0bb868b
CCM-12896: Add unit tests for typescript-schema-generator
gareth-allan Dec 3, 2025
5a3ed70
Merge branch 'main' into feature/CCM-12896_ts_event_type_generation
gareth-allan Dec 3, 2025
597f791
CCM-12896: Resolve CodeQL issues
gareth-allan Dec 3, 2025
248659c
CCM-12896: Make test more explicit about type files generated
gareth-allan Dec 4, 2025
e84bd02
CCM-12896: Move generated code to a digital-letters-events package
gareth-allan Dec 5, 2025
26f2746
CCM-12896: Fix linting and unit tests after package change
gareth-allan Dec 5, 2025
0dfc912
CCM-12896: Fix path for output directory
gareth-allan Dec 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/stage-2-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
npm ci
- name: "Generate dependencies"
run: |
npm run generate-dependencies --workspaces --if-present
npm run generate-dependencies
git diff --exit-code
test-unit:
name: "Unit tests"
Expand All @@ -71,7 +71,7 @@ jobs:
npm ci
- name: "Generate dependencies"
run: |
npm run generate-dependencies --workspaces --if-present
npm run generate-dependencies
- name: "Run unit test suite"
run: |
make test-unit
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
npm ci
- name: "Generate dependencies"
run: |
npm run generate-dependencies --workspaces --if-present
npm run generate-dependencies
- name: "Run linting"
run: |
make test-lint
Expand All @@ -120,7 +120,7 @@ jobs:
npm ci
- name: "Generate dependencies"
run: |
npm run generate-dependencies --workspaces --if-present
npm run generate-dependencies
- name: "Run typecheck"
run: |
make test-typecheck
Expand Down
37 changes: 0 additions & 37 deletions .github/workflows/stage-3-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,40 +44,3 @@ jobs:
uses: ./.github/actions/build-docs
with:
version: "${{ inputs.version }}"



# artefact-1:
# name: "Artefact 1"
# runs-on: ubuntu-latest
# timeout-minutes: 3
# steps:
# - name: "Checkout code"
# uses: actions/checkout@v5
# - name: "Build artefact 1"
# run: |
# echo "Building artefact 1 ..."
# - name: "Check artefact 1"
# run: |
# echo "Checking artefact 1 ..."
# - name: "Upload artefact 1"
# run: |
# echo "Uploading artefact 1 ..."
# # Use either action/cache or action/upload-artifact
# artefact-n:
# name: "Artefact n"
# runs-on: ubuntu-latest
# timeout-minutes: 3
# steps:
# - name: "Checkout code"
# uses: actions/checkout@v5
# - name: "Build artefact n"
# run: |
# echo "Building artefact n ..."
# - name: "Check artefact n"
# run: |
# echo "Checking artefact n ..."
# - name: "Upload artefact n"
# run: |
# echo "Uploading artefact n ..."
# # Use either action/cache or action/upload-artifact
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ quick-start: config clean build serve-docs # Quick start target to setup, build
dependencies: # Install dependencies needed to build and test the project @Pipeline
# TODO: Implement installation of your project dependencies

generate: # Generate any autogenerated output @Pipeline
npm run generate-dependencies

build: # Build the project artefact @Pipeline
$(MAKE) -C docs build

Expand All @@ -30,12 +33,14 @@ clean:: # Clean-up project resources (main) @Operations
$(MAKE) -C src/eventcatalogasyncapiimporter clean
$(MAKE) -C src/eventcatalogasyncapiimporter clean-output
rm -f .version
# TODO: Implement project resources clean-up step
npm run clean

config:: _install-dependencies version # Configure development environment (main) @Configuration
$(MAKE) -C docs install
$(MAKE) -C src/cloudevents install
$(MAKE) -C src/eventcatalogasyncapiimporter install
npm install
$(MAKE) generate

serve-docs:
$(MAKE) -C docs s
Expand All @@ -50,5 +55,5 @@ ${VERBOSE}.SILENT: \
build \
clean \
config \
dependencies \
generate \
deploy \
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ Installation and configuration of the toolchain dependencies
make config
```

Note that the `make config` command will also build the flattened event schemas and auto-generate a Typescript
type and JS validator code for each event. See the [typescript-schema-generator](src/typescript-schema-generator/)
package for more details.

## Usage

### Testing
Expand Down
1 change: 0 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ build: clean build-schemas copy-schema-docs copy-schema-yaml-docs copy-schemas b

build-ci: build-schemas-ci copy-schema-docs copy-schema-yaml-docs copy-schemas build-eventcatalog build-docs show-build-output


build-eventcatalog:
$(MAKE) build-eventcatalog-prereq
make -C $(EVENT_CAT_ROOT_DIR) build BASE_URL=$(EVENT_CAT_URL)
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/terraform/components/dl/pre.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

npm ci

npm run generate-dependencies --workspaces --if-present
Comment thread
gareth-allan marked this conversation as resolved.
npm run generate-dependencies

npm run lambda-build --workspaces --if-present
7 changes: 4 additions & 3 deletions lambdas/mesh-poll/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"dependencies": {
"aws-lambda": "^1.0.7"
"aws-lambda": "^1.0.7",
"typescript-schema-generator": "^0.0.1"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.2",
"@types/aws-lambda": "^8.10.155",
"@types/jest": "^30.0.0",
"jest": "^30.2.0",
"@types/jest": "^29.5.14",
"jest": "^29.7.0",
Comment thread
gareth-allan marked this conversation as resolved.
"jest-mock-extended": "^4.0.0",
"typescript": "^5.9.3"
},
Expand Down
44 changes: 41 additions & 3 deletions lambdas/mesh-poll/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,55 @@
import type { Context } from 'aws-lambda';
import { mockDeep } from 'jest-mock-extended';
import { PDMResourceSubmitted } from 'typescript-schema-generator';
import { handler } from '..';

const context = mockDeep<Context>();
const callback = jest.fn();

describe('event-logging Lambda', () => {
it('logs the input event and returns 200', async () => {
const event = { foo: 'bar' };
const context = mockDeep<Context>();
const callback = jest.fn();
const event: PDMResourceSubmitted = {
type: 'uk.nhs.notify.digital.letters.pdm.resource.submitted.v1',
source:
'/nhs/england/notify/staging/dev-647563337/data-plane/digitalletters/pdm',
dataschema:
'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10-draft/data/digital-letters-pdm-resource-submitted-data.schema.json',
specversion: '1.0',
id: '0249e529-f947-4012-819e-b634eb71be79',
subject:
'customer/7ff8ed41-cd5f-20e4-ef4e-34f96d8cc8ac/75027ace-9b8c-bcfe-866e-6c24242cffc3/q58dnxk5e/4cbek805wwx/yiaw7bl0d/her/1ccb7eb8-c6fe-0a42-279a-2a0e48ff1ca9/zk',
time: '2025-11-21T16:01:52.268Z',
datacontenttype: 'application/json',
traceparent: '00-ee4790eb6821064c645406abe918b3da-3a4e6957ce2a15de-01',
tracestate: 'nisi quis',
partitionkey: 'customer-7ff8ed41',
recordedtime: '2025-11-21T16:01:53.268Z',
sampledrate: 1,
sequence: '00000000000350773861',
severitytext: 'INFO',
severitynumber: 2,
dataclassification: 'restricted',
dataregulation: 'ISO-27001',
datacategory: 'non-sensitive',
data: {
messageReference: 'incididunt Ut aute laborum',
senderId: 'officia voluptate culpa Ut dolor',
resourceId: 'a2bcbb42-ab7e-42b6-88d6-74f8d3ca4a09',
retryCount: 97_903_257,
},
};

const result = await handler(event, context, callback);

expect(result).toEqual({
statusCode: 200,
body: 'Event logged',
});
});

it('throws an error if an invalid event is provided', async () => {
const invalidEvent = { foo: 'bar' };

await expect(handler(invalidEvent, context, callback)).rejects.toThrow();
});
});
50 changes: 48 additions & 2 deletions lambdas/mesh-poll/src/index.ts
Comment thread
gareth-allan marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,9 +1,55 @@
/* eslint-disable no-console -- Allowing console logging as this is an example file. */
// Replace me with the actual code for your Lambda function
import { Handler } from 'aws-lambda';
import { PDMResourceSubmitted } from 'typescript-schema-generator';
Comment thread
tdroza-nhs marked this conversation as resolved.
Outdated
import eventValidator from 'typescript-schema-generator/PDMResourceSubmitted.js';

export const handler: Handler = async (event) => {
// eslint-disable-next-line no-console
export const handler: Handler = async (event: PDMResourceSubmitted) => {
console.log('Received event:', event);

// We can build a new PDMResourceSubmitted event object like this:
const pdmResourceSubmittedEvent: PDMResourceSubmitted = {
type: 'uk.nhs.notify.digital.letters.pdm.resource.submitted.v1',
source:
'/nhs/england/notify/staging/dev-647563337/data-plane/digitalletters/pdm',
dataschema:
'https://notify.nhs.uk/cloudevents/schemas/digital-letters/2025-10-draft/data/digital-letters-pdm-resource-submitted-data.schema.json',
specversion: '1.0',
id: '0249e529-f947-4012-819e-b634eb71be79',
subject:
'customer/7ff8ed41-cd5f-20e4-ef4e-34f96d8cc8ac/75027ace-9b8c-bcfe-866e-6c24242cffc3/q58dnxk5e/4cbek805wwx/yiaw7bl0d/her/1ccb7eb8-c6fe-0a42-279a-2a0e48ff1ca9/zk',
time: '2025-11-21T16:01:52.268Z',
datacontenttype: 'application/json',
traceparent: '00-ee4790eb6821064c645406abe918b3da-3a4e6957ce2a15de-01',
tracestate: 'nisi quis',
partitionkey: 'customer-7ff8ed41',
recordedtime: '2025-11-21T16:01:53.268Z',
sampledrate: 1,
sequence: '00000000000350773861',
severitytext: 'INFO',
severitynumber: 2,
dataclassification: 'restricted',
dataregulation: 'ISO-27001',
datacategory: 'non-sensitive',
data: {
messageReference: 'incididunt Ut aute laborum',
senderId: 'officia voluptate culpa Ut dolor',
resourceId: 'a2bcbb42-ab7e-42b6-88d6-74f8d3ca4a09',
retryCount: 97_903_257,
},
};

console.log('PDM resource submitted event:', pdmResourceSubmittedEvent);

// We can validate an event like this:
const isEventValid = eventValidator(event);
if (isEventValid) {
console.log('pdmResourceSubmittedEvent is valid!');
} else {
console.error('Validation failure!', eventValidator.errors);
throw new Error('Event validation failed');
}

return {
statusCode: 200,
body: 'Event logged',
Expand Down
4 changes: 4 additions & 0 deletions lambdas/mesh-poll/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"compilerOptions": {
"allowJs": true,
"isolatedModules": true
},
"extends": "@tsconfig/node22/tsconfig.json",
"include": [
"src/**/*",
Expand Down
Loading