From 3d3c13c08320c45abb232fc149320e4637c0cec8 Mon Sep 17 00:00:00 2001 From: Daniel Naab Date: Tue, 3 Sep 2024 14:12:52 -0500 Subject: [PATCH] Form service backend implemented (#297) * Refactor form service to use createService utility * Use injected db gateway in form service functions, without changes to the existing localStorage approach. * Add form db gateway functions * Wire form db gateways to application. * Wire form service to frontend via a client-side proxy and API routes * Fix a couple build issues * Move db gateway functions into the service that consumes it. There are failing tests, due to describe blocks defined in the shared `describeDatabase` helper not getting registered with Vitest. Pushing up to CI to run test there, and rule out a local config issue. * Get describeDatabase working in the auth and forms packages; mark integration tests of demo apps as "expect failure" due to dependency issues that need to be worked out. * Temp: deploy on this branch * Update lockfile * Always use ssl with demo apps * Trying to isolate db dependencies; get CLI working with NodeNext modules * Tweak imports for NodeNext * Testing * Builds working with refactored database structure and module settings. Includes an upgrade of Turborepo and new clean tasks. * Remove pnpm version in Github Actions script, in lieu of the packageManager key in package.json * Switch design package to NodeNext module resolution * Add tests for all the forms services (todo: submitForm). This necessitated giving the forms library the Rollup treatment, and moving some dependencies around to avoid intermixing nodejs deps with the design lib. * use createTestFormServiceContext in submitForm test * Fix build break in spotlight app * Use NodeNext in the base tsconfig.json * docassemble updated for nodenext * Wire existing data flow to submitForm. to be updated for server environment * Do one more test deploy * Remove test deploy --- .github/workflows/_terraform-apply.yml | 1 - .../workflows/_terraform-plan-pr-comment.yml | 1 - .github/workflows/_validate.yml | 1 - apps/cli/package.json | 5 +- .../src/cli-controller/cli-controller.test.ts | 2 +- apps/cli/src/cli-controller/index.ts | 4 +- apps/cli/src/cli-controller/secrets.ts | 7 +- apps/cli/src/index.ts | 4 +- apps/cli/tsconfig.json | 3 +- apps/rest-api/package.json | 2 +- apps/server-doj/package.json | 3 +- apps/server-doj/src/index.ts | 11 +- apps/server-doj/src/server.ts | 13 +- apps/server-doj/tests/integration.test.ts | 14 +- apps/server-doj/tsconfig.json | 2 +- apps/server-doj/vitest.config.ts | 2 - apps/server-kansas/package.json | 3 +- apps/server-kansas/src/index.ts | 11 +- apps/server-kansas/src/server.ts | 14 +- apps/server-kansas/tests/integration.test.ts | 15 +- apps/server-kansas/tsconfig.json | 3 +- apps/spotlight/package.json | 2 +- apps/spotlight/src/context.ts | 20 +- apps/spotlight/tsconfig.json | 3 +- infra/cdktf/package.json | 3 +- infra/core/package.json | 1 + infra/core/src/commands/delete-secret.test.ts | 5 +- infra/core/src/commands/delete-secret.ts | 2 +- .../src/commands/get-secret-key-list.test.ts | 4 +- .../core/src/commands/get-secret-key-list.ts | 2 +- infra/core/src/commands/get-secret.test.ts | 4 +- infra/core/src/commands/get-secret.ts | 2 +- infra/core/src/commands/get-secrets.test.ts | 4 +- infra/core/src/commands/get-secrets.ts | 2 +- infra/core/src/commands/index.ts | 12 +- .../commands/set-login-gov-secrets.test.ts | 6 +- .../src/commands/set-login-gov-secrets.ts | 4 +- infra/core/src/commands/set-secret.test.ts | 4 +- infra/core/src/commands/set-secret.ts | 2 +- infra/core/src/index.ts | 5 +- .../core/src/lib/adapters/aws-param-store.ts | 7 +- infra/core/src/lib/adapters/in-memory.ts | 2 +- infra/core/src/lib/adapters/index.ts | 6 +- infra/core/src/lib/index.ts | 6 +- infra/core/src/lib/types.ts | 2 +- package.json | 11 +- packages/auth/package.json | 1 + packages/auth/src/context/base.ts | 16 +- packages/auth/src/context/test.ts | 24 +- packages/auth/src/index.ts | 31 +- .../src/repository}/create-session.test.ts | 4 +- .../src/repository}/create-session.ts | 3 +- .../src/repository}/create-user.test.ts | 2 +- .../src/repository}/create-user.ts | 2 +- .../src/repository}/get-user-id.test.ts | 2 +- .../src/repository}/get-user-id.ts | 2 +- packages/auth/src/repository/index.ts | 15 + .../services/get-provider-redirect.test.ts | 4 +- .../src/services/get-provider-redirect.ts | 4 +- packages/auth/src/services/index.ts | 36 + packages/auth/src/services/logout.test.ts | 4 +- packages/auth/src/services/logout.ts | 4 +- .../process-provider-callback.test.ts | 9 +- .../src/services/process-provider-callback.ts | 6 +- .../services/process-session-cookie.test.ts | 4 +- .../src/services/process-session-cookie.ts | 4 +- packages/auth/tsconfig.json | 2 + packages/auth/vitest.config.ts | 2 + packages/common/package.json | 1 + .../migrations/20240820130044_forms.mjs | 21 + packages/database/package.json | 14 +- packages/database/rollup.config.js | 28 +- packages/database/src/clients/kysely/types.ts | 11 + packages/database/src/context/index.ts | 6 + packages/database/src/index.ts | 25 +- packages/dependency-graph/package.json | 1 + .../src/graph-dependencies.ts | 3 +- packages/dependency-graph/src/index.ts | 4 +- packages/design/package.json | 6 +- .../AvailableFormList.stories.tsx | 18 +- .../AvailableFormList.test.tsx | 4 +- .../design/src/AvailableFormList/index.tsx | 17 +- .../src/Form/ActionBar/ActionBar.stories.tsx | 2 +- .../src/Form/ActionBar/ActionBar.test.ts | 4 +- packages/design/src/Form/Form.stories.tsx | 4 +- packages/design/src/Form/Form.test.tsx | 4 +- .../src/Form/components/Address/index.tsx | 4 +- .../components/Checkbox/Checkbox.stories.tsx | 2 +- .../components/Checkbox/Checkbox.test.tsx | 4 +- .../src/Form/components/Checkbox/Checkbox.tsx | 2 +- .../src/Form/components/Checkbox/index.tsx | 2 +- .../components/Fieldset/Fieldset.stories.tsx | 2 +- .../components/Fieldset/Fieldset.test.tsx | 4 +- .../src/Form/components/Fieldset/index.tsx | 2 +- .../FormSummary/FormSummary.stories.tsx | 2 +- .../FormSummary/FormSummary.test.ts | 4 +- .../src/Form/components/FormSummary/index.tsx | 2 +- .../design/src/Form/components/Page/index.tsx | 2 +- .../PageSet/PageMenu/PageMenu.stories.tsx | 2 +- .../PageSet/PageMenu/PageMenu.test.tsx | 4 +- .../Form/components/PageSet/PageMenu/index.ts | 2 +- .../components/PageSet/PageSet.stories.tsx | 6 +- .../Form/components/PageSet/PageSet.test.tsx | 4 +- .../src/Form/components/PageSet/PageSet.tsx | 8 +- .../src/Form/components/PageSet/index.ts | 2 +- .../src/Form/components/Paragraph/index.tsx | 2 +- .../RadioGroup/RadioGroup.stories.tsx | 2 +- .../components/RadioGroup/RadioGroup.test.tsx | 4 +- .../Form/components/RadioGroup/RadioGroup.tsx | 2 +- .../src/Form/components/RadioGroup/index.tsx | 2 +- .../src/Form/components/Sequence/index.tsx | 2 +- .../SubmissionConfirmation.stories.tsx | 2 +- .../SubmissionConfirmation/index.tsx | 2 +- .../TextInput/TestInput.stories.tsx | 2 +- .../components/TextInput/TestInput.test.ts | 4 +- .../src/Form/components/TextInput/index.tsx | 2 +- packages/design/src/Form/components/index.tsx | 24 +- .../FormDelete/FormDelete.stories.tsx | 8 +- .../FormManager/FormDelete/FormDelete.test.ts | 4 +- .../src/FormManager/FormDelete/index.tsx | 23 +- .../DocumentImporter/index.tsx | 10 +- .../FormManager/FormDocumentImport/index.tsx | 39 +- .../FormEdit/AddPatternDropdown.tsx | 2 +- .../FormManager/FormEdit/FormEdit.stories.tsx | 8 +- .../src/FormManager/FormEdit/FormEdit.test.ts | 4 +- .../FormManager/FormEdit/PreviewPattern.tsx | 4 +- .../FormEdit/Toolbar/Toolbar.stories.tsx | 4 +- .../FormEdit/Toolbar/Toolbar.test.ts | 4 +- .../src/FormManager/FormEdit/Toolbar/index.ts | 2 +- .../CheckboxPatternEdit.stories.tsx | 10 +- .../components/CheckboxPatternEdit.tsx | 14 +- .../components/DraggableList.stories.tsx | 6 +- .../components/DraggableList.test.tsx | 4 +- .../components/FieldsetEdit.stories.tsx | 8 +- .../FormEdit/components/FieldsetEdit.test.tsx | 4 +- .../FormEdit/components/FieldsetEdit.tsx | 18 +- .../FormEdit/components/FormSummaryEdit.tsx | 14 +- .../components/InputPatternEdit.stories.tsx | 8 +- .../components/InputPatternEdit.test.tsx | 4 +- .../FormEdit/components/InputPatternEdit.tsx | 16 +- .../FormEdit/components/PageEdit.tsx | 16 +- .../components/PageSetEdit.stories.tsx | 6 +- .../FormEdit/components/PageSetEdit.test.tsx | 4 +- .../FormEdit/components/PageSetEdit.tsx | 12 +- .../ParagraphPatternEdit.stories.tsx | 8 +- .../components/ParagraphPatternEdit.test.tsx | 4 +- .../components/ParagraphPatternEdit.tsx | 16 +- .../PreviewSequencePattern/DraggableList.tsx | 2 +- .../PreviewSequencePattern/index.tsx | 6 +- .../RadioGroupPatternEdit.stories.tsx | 10 +- .../components/RadioGroupPatternEdit.test.tsx | 4 +- .../components/RadioGroupPatternEdit.tsx | 14 +- .../components/SubmissionConfirmationEdit.tsx | 8 +- .../components/common/MovePatternDropdown.tsx | 2 +- .../components/common/PatternEditActions.tsx | 4 +- .../components/common/PatternEditForm.tsx | 2 +- .../components/common/story-helper.tsx | 6 +- .../FormManager/FormEdit/components/index.ts | 22 +- .../design/src/FormManager/FormEdit/index.tsx | 9 +- .../design/src/FormManager/FormEdit/store.ts | 8 +- .../design/src/FormManager/FormEdit/types.ts | 2 +- .../FormManager/FormInspect/FormInspect.tsx | 2 +- .../src/FormManager/FormInspect/index.ts | 2 +- .../CreateNew/PDFFileSelect.stories.tsx | 8 +- .../FormList/CreateNew/PDFFileSelect.test.tsx | 4 +- .../FormList/CreateNew/file-input.test.ts | 4 +- .../FormManager/FormList/CreateNew/index.tsx | 6 +- .../FormManager/FormList/FormList.stories.tsx | 12 +- .../src/FormManager/FormList/FormList.test.ts | 4 +- .../FormManager/FormList/ManageFormsTable.tsx | 8 +- .../design/src/FormManager/FormList/index.tsx | 13 +- .../design/src/FormManager/FormList/store.ts | 14 +- .../src/FormManager/FormManager.stories.ts | 4 +- .../src/FormManager/FormManager.test.ts | 4 +- .../FormManagerLayout.stories.tsx | 10 +- .../FormManagerLayout.test.tsx | 4 +- .../FormManagerLayout/TopNavigation.tsx | 4 +- .../FormManager/FormManagerLayout/index.tsx | 8 +- .../FormPreview/FormPreview.stories.tsx | 8 +- .../FormPreview/FormPreview.test.ts | 4 +- .../src/FormManager/FormPreview/index.tsx | 6 +- .../NotificationAlert.stories.tsx | 2 +- .../Notifications/NotificationAlert.tsx | 2 +- .../Notifications/Notifications.stories.tsx | 6 +- .../Notifications/Notifications.tsx | 4 +- .../src/FormManager/Notifications/index.ts | 4 +- .../FormManager/Notifications/store.test.ts | 2 +- packages/design/src/FormManager/index.tsx | 102 +- packages/design/src/FormManager/store.tsx | 25 +- .../src/FormRouter/FormRouter.stories.ts | 8 +- .../design/src/FormRouter/FormRouter.test.ts | 4 +- packages/design/src/FormRouter/hooks.ts | 5 +- packages/design/src/FormRouter/index.tsx | 40 +- packages/design/src/index.ts | 15 +- packages/design/src/test-form.ts | 20 +- packages/design/tsconfig.json | 2 + packages/design/vite.config.ts | 2 +- packages/docassemble/package.json | 1 + packages/docassemble/src/client.test.ts | 2 +- packages/docassemble/src/client.ts | 2 +- packages/docassemble/src/context/index.ts | 2 +- packages/docassemble/src/context/test.ts | 2 +- packages/docassemble/src/index.ts | 2 +- packages/docassemble/tsconfig.json | 1 - packages/forms/package.json | 23 +- packages/forms/rollup.config.js | 54 + packages/forms/src/builder/builder.test.ts | 14 +- packages/forms/src/builder/index.ts | 2 +- packages/forms/src/config.ts | 1 - .../forms/src/context/browser/form-repo.ts | 141 + .../context/browser/session-repo.ts | 29 +- packages/forms/src/context/index.ts | 10 + packages/forms/src/context/test/index.ts | 24 + .../src/{service => }/context/test/storage.ts | 6 +- .../__tests__/doj-pardon-marijuana.test.ts | 2 +- .../forms/src/documents/pdf/parsing-api.ts | 1 - packages/forms/src/index.ts | 18 +- packages/forms/src/patterns/form-summary.ts | 4 +- packages/forms/src/patterns/index.ts | 13 + .../forms/src/repository/add-form.test.ts | 41 + packages/forms/src/repository/add-form.ts | 26 + .../forms/src/repository/delete-form.test.ts | 48 + packages/forms/src/repository/delete-form.ts | 21 + .../src/repository/get-form-list.test.ts | 46 + .../forms/src/repository/get-form-list.ts | 15 + .../forms/src/repository/get-form.test.ts | 47 + packages/forms/src/repository/get-form.ts | 42 + packages/forms/src/repository/index.ts | 34 + .../forms/src/repository/save-form.test.ts | 53 + packages/forms/src/repository/save-form.ts | 28 + packages/forms/src/repository/serialize.ts | 19 + .../src/service/context/browser/form-repo.ts | 129 - .../src/service/context/browser/index.ts | 45 - .../forms/src/service/context/test/index.ts | 12 - packages/forms/src/service/index.ts | 3 - .../forms/src/service/operations/add-form.ts | 11 - .../src/service/operations/delete-form.ts | 23 - .../src/service/operations/get-form-list.ts | 25 - .../forms/src/service/operations/get-form.ts | 21 - .../forms/src/service/operations/index.ts | 0 .../forms/src/service/operations/save-form.ts | 24 - .../service/operations/submit-form.test.ts | 22 - packages/forms/src/service/types.ts | 18 - packages/forms/src/services/add-form.test.ts | 38 + packages/forms/src/services/add-form.ts | 36 + .../forms/src/services/delete-form.test.ts | 39 + packages/forms/src/services/delete-form.ts | 31 + .../forms/src/services/get-form-list.test.ts | 75 + packages/forms/src/services/get-form-list.ts | 34 + packages/forms/src/services/get-form.test.ts | 40 + packages/forms/src/services/get-form.ts | 31 + packages/forms/src/services/index.ts | 27 + packages/forms/src/services/save-form.test.ts | 50 + packages/forms/src/services/save-form.ts | 34 + .../forms/src/services/submit-form.test.ts | 25 + .../operations => services}/submit-form.ts | 23 +- packages/forms/src/testing.ts | 17 + packages/forms/tsconfig.json | 11 +- packages/forms/vitest.config.ts | 12 +- packages/server/package.json | 10 +- .../src/components/AppAvailableFormList.tsx | 4 +- .../server/src/components/AppFormManager.tsx | 4 +- .../server/src/components/AppFormRouter.tsx | 6 +- packages/server/src/context.ts | 58 +- packages/server/src/lib/api-client.ts | 76 + packages/server/src/middleware.ts | 2 +- packages/server/src/pages/api/forms/[id].ts | 58 + packages/server/src/pages/api/forms/index.ts | 25 + packages/server/src/pages/forms/[id].ts | 29 + packages/server/src/pages/forms/index.astro | 6 +- packages/server/src/pages/signin/callback.ts | 4 +- packages/server/src/pages/signin/index.ts | 2 +- packages/server/src/pages/signout/confirm.ts | 4 +- packages/server/tsconfig.build.json | 2 +- packages/server/tsconfig.json | 3 +- pnpm-lock.yaml | 23791 +++++++++------- tsconfig.base.json | 4 +- turbo.json | 18 +- vitest.shared.ts | 2 +- workspace-dependencies.svg | 296 +- 280 files changed, 16030 insertions(+), 11465 deletions(-) rename packages/{database/src/gateways/sessions => auth/src/repository}/create-session.test.ts (90%) rename packages/{database/src/gateways/sessions => auth/src/repository}/create-session.ts (83%) rename packages/{database/src/gateways/users => auth/src/repository}/create-user.test.ts (94%) rename packages/{database/src/gateways/users => auth/src/repository}/create-user.ts (87%) rename packages/{database/src/gateways/users => auth/src/repository}/get-user-id.test.ts (90%) rename packages/{database/src/gateways/users => auth/src/repository}/get-user-id.ts (86%) create mode 100644 packages/auth/src/repository/index.ts create mode 100644 packages/auth/src/services/index.ts create mode 100644 packages/database/migrations/20240820130044_forms.mjs create mode 100644 packages/database/src/context/index.ts create mode 100644 packages/forms/rollup.config.js delete mode 100644 packages/forms/src/config.ts create mode 100644 packages/forms/src/context/browser/form-repo.ts rename packages/forms/src/{service => }/context/browser/session-repo.ts (54%) create mode 100644 packages/forms/src/context/index.ts create mode 100644 packages/forms/src/context/test/index.ts rename packages/forms/src/{service => }/context/test/storage.ts (83%) create mode 100644 packages/forms/src/repository/add-form.test.ts create mode 100644 packages/forms/src/repository/add-form.ts create mode 100644 packages/forms/src/repository/delete-form.test.ts create mode 100644 packages/forms/src/repository/delete-form.ts create mode 100644 packages/forms/src/repository/get-form-list.test.ts create mode 100644 packages/forms/src/repository/get-form-list.ts create mode 100644 packages/forms/src/repository/get-form.test.ts create mode 100644 packages/forms/src/repository/get-form.ts create mode 100644 packages/forms/src/repository/index.ts create mode 100644 packages/forms/src/repository/save-form.test.ts create mode 100644 packages/forms/src/repository/save-form.ts create mode 100644 packages/forms/src/repository/serialize.ts delete mode 100644 packages/forms/src/service/context/browser/form-repo.ts delete mode 100644 packages/forms/src/service/context/browser/index.ts delete mode 100644 packages/forms/src/service/context/test/index.ts delete mode 100644 packages/forms/src/service/index.ts delete mode 100644 packages/forms/src/service/operations/add-form.ts delete mode 100644 packages/forms/src/service/operations/delete-form.ts delete mode 100644 packages/forms/src/service/operations/get-form-list.ts delete mode 100644 packages/forms/src/service/operations/get-form.ts delete mode 100644 packages/forms/src/service/operations/index.ts delete mode 100644 packages/forms/src/service/operations/save-form.ts delete mode 100644 packages/forms/src/service/operations/submit-form.test.ts delete mode 100644 packages/forms/src/service/types.ts create mode 100644 packages/forms/src/services/add-form.test.ts create mode 100644 packages/forms/src/services/add-form.ts create mode 100644 packages/forms/src/services/delete-form.test.ts create mode 100644 packages/forms/src/services/delete-form.ts create mode 100644 packages/forms/src/services/get-form-list.test.ts create mode 100644 packages/forms/src/services/get-form-list.ts create mode 100644 packages/forms/src/services/get-form.test.ts create mode 100644 packages/forms/src/services/get-form.ts create mode 100644 packages/forms/src/services/index.ts create mode 100644 packages/forms/src/services/save-form.test.ts create mode 100644 packages/forms/src/services/save-form.ts create mode 100644 packages/forms/src/services/submit-form.test.ts rename packages/forms/src/{service/operations => services}/submit-form.ts (85%) create mode 100644 packages/forms/src/testing.ts create mode 100644 packages/server/src/lib/api-client.ts create mode 100644 packages/server/src/pages/api/forms/[id].ts create mode 100644 packages/server/src/pages/api/forms/index.ts create mode 100644 packages/server/src/pages/forms/[id].ts diff --git a/.github/workflows/_terraform-apply.yml b/.github/workflows/_terraform-apply.yml index 245cbea8..9290107e 100644 --- a/.github/workflows/_terraform-apply.yml +++ b/.github/workflows/_terraform-apply.yml @@ -31,7 +31,6 @@ jobs: uses: pnpm/action-setup@v4 id: pnpm-install with: - version: 8 run_install: false - name: Get pnpm store directory diff --git a/.github/workflows/_terraform-plan-pr-comment.yml b/.github/workflows/_terraform-plan-pr-comment.yml index f48100da..25e665c2 100644 --- a/.github/workflows/_terraform-plan-pr-comment.yml +++ b/.github/workflows/_terraform-plan-pr-comment.yml @@ -33,7 +33,6 @@ jobs: uses: pnpm/action-setup@v4 id: pnpm-install with: - version: 8 run_install: false - name: Get pnpm store directory diff --git a/.github/workflows/_validate.yml b/.github/workflows/_validate.yml index 70edf56a..38f321bb 100644 --- a/.github/workflows/_validate.yml +++ b/.github/workflows/_validate.yml @@ -25,7 +25,6 @@ jobs: uses: pnpm/action-setup@v4 id: pnpm-install with: - version: 9 run_install: false - name: Get pnpm store directory diff --git a/apps/cli/package.json b/apps/cli/package.json index 3f28c12b..613a3327 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -2,11 +2,12 @@ "name": "@atj/cli-app", "version": "1.0.0", "description": "10x ATJ command-line interface", - "type": "commonjs", + "type": "module", "license": "CC0", "main": "src/index.ts", "scripts": { - "build": "tsup src/* --format cjs", + "build": "tsup src/* --format esm", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "cli": "node dist/index.js", "dev": "tsup src/* --watch", "test": "vitest run --coverage" diff --git a/apps/cli/src/cli-controller/cli-controller.test.ts b/apps/cli/src/cli-controller/cli-controller.test.ts index 67ac22cc..96f08046 100644 --- a/apps/cli/src/cli-controller/cli-controller.test.ts +++ b/apps/cli/src/cli-controller/cli-controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; import { mock } from 'vitest-mock-extended'; -import { CliController } from '.'; +import { CliController } from './index.js'; describe('cli controller', () => { it('works', async () => { diff --git a/apps/cli/src/cli-controller/index.ts b/apps/cli/src/cli-controller/index.ts index da9815d7..b78b7424 100644 --- a/apps/cli/src/cli-controller/index.ts +++ b/apps/cli/src/cli-controller/index.ts @@ -1,8 +1,8 @@ import { Command } from 'commander'; import { createDependencyGraph } from '@atj/dependency-graph'; -import type { Context } from './types'; -import { addSecretCommands } from './secrets'; +import type { Context } from './types.js'; +import { addSecretCommands } from './secrets.js'; export const CliController = (ctx: Context) => { const cli = new Command().description( diff --git a/apps/cli/src/cli-controller/secrets.ts b/apps/cli/src/cli-controller/secrets.ts index 749997dd..3af58398 100644 --- a/apps/cli/src/cli-controller/secrets.ts +++ b/apps/cli/src/cli-controller/secrets.ts @@ -1,9 +1,8 @@ +import path from 'path'; import { Command } from 'commander'; -import { commands, getSecretsVault } from '@atj/infra-core'; -import { Context } from './types'; -import { type DeployEnv } from '@atj/infra-core/src/values'; -import path from 'path'; +import { type DeployEnv, commands, getSecretsVault } from '@atj/infra-core'; +import { type Context } from './types.js'; export const addSecretCommands = (ctx: Context, cli: Command) => { const cmd = cli diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index 0c086493..599810e9 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -1,5 +1,5 @@ -const { join } = require('path'); -const { CliController } = require('./cli-controller'); +import { join } from 'path'; +import { CliController } from './cli-controller/index.js'; // This should map to the directory containing the package.json. // By convention, assume that the originating process was run from the root diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index ea22b13a..11cf6557 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", "outDir": "./dist", "emitDeclarationOnly": true }, diff --git a/apps/rest-api/package.json b/apps/rest-api/package.json index 019867e3..e4824114 100644 --- a/apps/rest-api/package.json +++ b/apps/rest-api/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "esbuild src/index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js", "build:client": "tsup src/* --env.NODE_ENV production --dts-resolve", - "clean": "rm -rf dist tsconfig.tsbuildinfo", + "clean": "rimraf dist tsconfig.tsbuildinfo", "dev": "tsup src/* --watch" }, "dependencies": { diff --git a/apps/server-doj/package.json b/apps/server-doj/package.json index 35e5e103..649d5864 100644 --- a/apps/server-doj/package.json +++ b/apps/server-doj/package.json @@ -6,9 +6,10 @@ "license": "CC0", "main": "src/index.ts", "scripts": { - "start": "node dist/index.js", "build": "tsup src/* --format esm", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsup src/* --watch --format esm", + "start": "VCAP_SERVICES='{\"aws-rds\": [{ \"credentials\": { \"uri\": \"\" }}]}' node dist/index.js", "test": "vitest run --coverage" }, "dependencies": { diff --git a/apps/server-doj/src/index.ts b/apps/server-doj/src/index.ts index edca57e5..96981459 100644 --- a/apps/server-doj/src/index.ts +++ b/apps/server-doj/src/index.ts @@ -1,3 +1,4 @@ +import { createPostgresDatabaseContext } from '@atj/database/context'; import { createCustomServer } from './server.js'; const port = process.env.PORT || 4321; @@ -14,8 +15,8 @@ const getCloudGovServerSecrets = () => { }; const secrets = getCloudGovServerSecrets(); -createCustomServer({ dbUri: secrets?.dbUri }).then((server: any) => - server.listen(port, () => { - console.log(`Server running on http://localhost:${port}`); - }) -); +const db = await createPostgresDatabaseContext(secrets.dbUri, true); +const server = await createCustomServer(db); +server.listen(port, () => { + console.log(`Server running on http://localhost:${port}`); +}); diff --git a/apps/server-doj/src/server.ts b/apps/server-doj/src/server.ts index 943ab0a6..90fee824 100644 --- a/apps/server-doj/src/server.ts +++ b/apps/server-doj/src/server.ts @@ -1,16 +1,7 @@ -import { - createDatabaseGateway, - createPostgresDatabaseContext, -} from '@atj/database'; +import { type DatabaseContext } from '@atj/database'; import { createServer } from '@atj/server'; -export const createCustomServer = async (ctx: { - dbUri: string; -}): Promise => { - const db = createDatabaseGateway( - await createPostgresDatabaseContext(ctx.dbUri, true) - ); - +export const createCustomServer = async (db: DatabaseContext): Promise => { return createServer({ title: 'DOJ Form Service', db, diff --git a/apps/server-doj/tests/integration.test.ts b/apps/server-doj/tests/integration.test.ts index 73d8b3aa..91fd7671 100644 --- a/apps/server-doj/tests/integration.test.ts +++ b/apps/server-doj/tests/integration.test.ts @@ -1,18 +1,14 @@ import request from 'supertest'; import { describe, expect, test } from 'vitest'; -import { describeDatabase } from '@atj/database/testing'; + +import { createInMemoryDatabaseContext } from '@atj/database/context'; import { createCustomServer } from '../src/server'; describe('DOJ Form Service', () => { - test('avoid "No test suite found in file" error', async () => { - expect(true).toBe(true); - }); -}); - -describeDatabase('DOJ Form Service', () => { - test('renders the home page', async ({ db }) => { - const app = await createCustomServer({ dbUri: db.ctx.connectionUri }); + test('renders the home page', async () => { + const db = await createInMemoryDatabaseContext(); + const app = await createCustomServer(db); const response = await request(app).get('/'); expect(response.ok).toBe(true); expect(response.text).toMatch(/DOJ Form Service/); diff --git a/apps/server-doj/tsconfig.json b/apps/server-doj/tsconfig.json index ed4cddf1..11cf6557 100644 --- a/apps/server-doj/tsconfig.json +++ b/apps/server-doj/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "CommonJS", + "module": "NodeNext", "moduleResolution": "NodeNext", "outDir": "./dist", "emitDeclarationOnly": true diff --git a/apps/server-doj/vitest.config.ts b/apps/server-doj/vitest.config.ts index 55f8f580..d18c1f86 100644 --- a/apps/server-doj/vitest.config.ts +++ b/apps/server-doj/vitest.config.ts @@ -1,5 +1,4 @@ import { defineConfig } from 'vitest/config'; -import { getDatabaseTestContainerGlobalSetupPath } from '@atj/database'; import sharedTestConfig from '../../vitest.shared'; @@ -7,6 +6,5 @@ export default defineConfig({ ...sharedTestConfig, test: { ...sharedTestConfig.test, - globalSetup: [getDatabaseTestContainerGlobalSetupPath()], }, }); diff --git a/apps/server-kansas/package.json b/apps/server-kansas/package.json index df2b53dc..6458dd9f 100644 --- a/apps/server-kansas/package.json +++ b/apps/server-kansas/package.json @@ -6,9 +6,10 @@ "license": "CC0", "main": "src/index.ts", "scripts": { - "start": "node dist/index.js", "build": "tsup src/* --format esm", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsup src/* --watch --format esm", + "start": "VCAP_SERVICES='{\"aws-rds\": [{ \"credentials\": { \"uri\": \"\" }}]}' node dist/index.js", "test": "vitest run --coverage" }, "dependencies": { diff --git a/apps/server-kansas/src/index.ts b/apps/server-kansas/src/index.ts index edca57e5..96981459 100644 --- a/apps/server-kansas/src/index.ts +++ b/apps/server-kansas/src/index.ts @@ -1,3 +1,4 @@ +import { createPostgresDatabaseContext } from '@atj/database/context'; import { createCustomServer } from './server.js'; const port = process.env.PORT || 4321; @@ -14,8 +15,8 @@ const getCloudGovServerSecrets = () => { }; const secrets = getCloudGovServerSecrets(); -createCustomServer({ dbUri: secrets?.dbUri }).then((server: any) => - server.listen(port, () => { - console.log(`Server running on http://localhost:${port}`); - }) -); +const db = await createPostgresDatabaseContext(secrets.dbUri, true); +const server = await createCustomServer(db); +server.listen(port, () => { + console.log(`Server running on http://localhost:${port}`); +}); diff --git a/apps/server-kansas/src/server.ts b/apps/server-kansas/src/server.ts index 908d40f9..5a6ced54 100644 --- a/apps/server-kansas/src/server.ts +++ b/apps/server-kansas/src/server.ts @@ -1,16 +1,7 @@ -import { - createDatabaseGateway, - createPostgresDatabaseContext, -} from '@atj/database'; +import { type DatabaseContext } from '@atj/database'; import { createServer } from '@atj/server'; -export const createCustomServer = async (ctx: { - dbUri: string; -}): Promise => { - const db = createDatabaseGateway( - await createPostgresDatabaseContext(ctx.dbUri, true) - ); - +export const createCustomServer = async (db: DatabaseContext): Promise => { return createServer({ title: 'DOJ Form Service', db, @@ -22,6 +13,7 @@ export const createCustomServer = async (ctx: { }, isUserAuthorized: async (email: string) => { return [ + // 10x team members 'daniel.naab@gsa.gov', 'jim.moffet@gsa.gov', 'ethan.gardner@gsa.gov', diff --git a/apps/server-kansas/tests/integration.test.ts b/apps/server-kansas/tests/integration.test.ts index f602bed0..e7382113 100644 --- a/apps/server-kansas/tests/integration.test.ts +++ b/apps/server-kansas/tests/integration.test.ts @@ -1,18 +1,13 @@ import request from 'supertest'; import { describe, expect, test } from 'vitest'; -import { describeDatabase } from '@atj/database/testing'; +import { createInMemoryDatabaseContext } from '@atj/database/context'; import { createCustomServer } from '../src/server'; -describe('DOJ Form Service', () => { - test('avoid "No test suite found in file" error', async () => { - expect(true).toBe(true); - }); -}); - -describeDatabase('Kansas State Courts Form Service', () => { - test('renders the home page', async ({ db }) => { - const app = await createCustomServer({ dbUri: db.ctx.connectionUri }); +describe('Kansas State Courts Form Service', () => { + test('renders the home page', async () => { + const db = await createInMemoryDatabaseContext(); + const app = await createCustomServer(db); const response = await request(app).get('/'); expect(response.ok).toBe(true); expect(response.text).toMatch(/DOJ Form Service/); diff --git a/apps/server-kansas/tsconfig.json b/apps/server-kansas/tsconfig.json index 1e4b75b9..6f1380c8 100644 --- a/apps/server-kansas/tsconfig.json +++ b/apps/server-kansas/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", "emitDeclarationOnly": true, "outDir": "./dist" }, diff --git a/apps/spotlight/package.json b/apps/spotlight/package.json index 0a9a10f1..aacc8d0e 100644 --- a/apps/spotlight/package.json +++ b/apps/spotlight/package.json @@ -5,7 +5,7 @@ "scripts": { "astro": "astro", "build": "astro build", - "clean": "rm -rf dist", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "astro dev", "preview": "astro preview" }, diff --git a/apps/spotlight/src/context.ts b/apps/spotlight/src/context.ts index b3d92083..367eb67c 100644 --- a/apps/spotlight/src/context.ts +++ b/apps/spotlight/src/context.ts @@ -1,14 +1,19 @@ -import { FormConfig } from '@atj/forms'; +import { + type FormConfig, + type FormService, + createFormService, +} from '@atj/forms'; import { defaultFormConfig } from '@atj/forms'; -import { service } from '@atj/forms'; +import { BrowserFormRepository } from '@atj/forms/context'; import { type GithubRepository } from './lib/github'; +import { createTestBrowserFormService } from '@atj/forms/context'; export type AppContext = { baseUrl: `${string}/`; github: GithubRepository; formConfig: FormConfig; - formService: service.FormService; + formService: FormService; uswdsRoot: `${string}/`; }; @@ -33,8 +38,13 @@ const createAppContext = (env: any): AppContext => { const createAppFormService = () => { if (globalThis.window) { - return service.createBrowserFormService(); + const repository = new BrowserFormRepository(window.localStorage); + return createFormService({ + repository, + config: defaultFormConfig, + isUserLoggedIn: () => true, + }); } else { - return service.createTestFormService(); + return createTestBrowserFormService(); } }; diff --git a/apps/spotlight/tsconfig.json b/apps/spotlight/tsconfig.json index f2044fb5..a4ef7740 100644 --- a/apps/spotlight/tsconfig.json +++ b/apps/spotlight/tsconfig.json @@ -3,7 +3,8 @@ // https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/base.json "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", "jsx": "react", "resolveJsonModule": true }, diff --git a/infra/cdktf/package.json b/infra/cdktf/package.json index d330b041..94a583c1 100644 --- a/infra/cdktf/package.json +++ b/infra/cdktf/package.json @@ -10,7 +10,8 @@ "build:synth:main": "DEPLOY_ENV=main cdktf synth", "build:synth:staging": "DEPLOY_ENV=staging cdktf synth", "build:tsc": "tsc --pretty", - "clean": "rm -rf .gen cdktf.out", + "clean": "rimraf cdktf.out dist tsconfig.tsbuildinfo", + "clean:gen": "rimraf .gen", "deploy:main": "DEPLOY_ENV=main cdktf deploy", "deploy:staging": "DEPLOY_ENV=staging cdktf deploy", "dev": "tsc -w", diff --git a/infra/core/package.json b/infra/core/package.json index ea4873ed..7fd3a639 100644 --- a/infra/core/package.json +++ b/infra/core/package.json @@ -8,6 +8,7 @@ "types": "dist/index.d.js", "scripts": { "build": "tsc", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsc --watch", "test": "vitest run --coverage" }, diff --git a/infra/core/src/commands/delete-secret.test.ts b/infra/core/src/commands/delete-secret.test.ts index fe8f39ed..600c38fa 100644 --- a/infra/core/src/commands/delete-secret.test.ts +++ b/infra/core/src/commands/delete-secret.test.ts @@ -1,8 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { createInMemorySecretsVault } from '../lib'; -import { getSecretKeyList } from './get-secret-key-list'; -import { deleteSecret } from './delete-secret'; +import { createInMemorySecretsVault } from '../lib/index.js'; +import { deleteSecret } from './delete-secret.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/delete-secret.ts b/infra/core/src/commands/delete-secret.ts index 1de128f7..9bb43685 100644 --- a/infra/core/src/commands/delete-secret.ts +++ b/infra/core/src/commands/delete-secret.ts @@ -1,4 +1,4 @@ -import type { SecretKey, SecretsVault } from '../lib/types'; +import type { SecretKey, SecretsVault } from '../lib/types.js'; export const deleteSecret = async (vault: SecretsVault, key: SecretKey) => { return await vault.deleteSecret(key); diff --git a/infra/core/src/commands/get-secret-key-list.test.ts b/infra/core/src/commands/get-secret-key-list.test.ts index 8534b72f..296944b6 100644 --- a/infra/core/src/commands/get-secret-key-list.test.ts +++ b/infra/core/src/commands/get-secret-key-list.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { createInMemorySecretsVault } from '../lib'; -import { getSecretKeyList } from './get-secret-key-list'; +import { createInMemorySecretsVault } from '../lib/index.js'; +import { getSecretKeyList } from './get-secret-key-list.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/get-secret-key-list.ts b/infra/core/src/commands/get-secret-key-list.ts index d6787aa2..6964946d 100644 --- a/infra/core/src/commands/get-secret-key-list.ts +++ b/infra/core/src/commands/get-secret-key-list.ts @@ -1,4 +1,4 @@ -import { type SecretsVault } from '../lib/types'; +import { type SecretsVault } from '../lib/types.js'; export const getSecretKeyList = async (vault: SecretsVault) => { return await vault.getSecretKeys(); diff --git a/infra/core/src/commands/get-secret.test.ts b/infra/core/src/commands/get-secret.test.ts index d3947938..7377bb2c 100644 --- a/infra/core/src/commands/get-secret.test.ts +++ b/infra/core/src/commands/get-secret.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { getSecret } from './get-secret'; -import { createInMemorySecretsVault } from '../lib'; +import { getSecret } from './get-secret.js'; +import { createInMemorySecretsVault } from '../lib/index.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/get-secret.ts b/infra/core/src/commands/get-secret.ts index c502fa65..d0b8df68 100644 --- a/infra/core/src/commands/get-secret.ts +++ b/infra/core/src/commands/get-secret.ts @@ -1,4 +1,4 @@ -import { type SecretsVault } from '../lib/types'; +import { type SecretsVault } from '../lib/types.js'; export const getSecret = async (vault: SecretsVault, key: string) => { return await vault.getSecret(key); diff --git a/infra/core/src/commands/get-secrets.test.ts b/infra/core/src/commands/get-secrets.test.ts index 5878fa67..db17c73e 100644 --- a/infra/core/src/commands/get-secrets.test.ts +++ b/infra/core/src/commands/get-secrets.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { getSecrets } from './get-secrets'; -import { createInMemorySecretsVault } from '../lib'; +import { getSecrets } from './get-secrets.js'; +import { createInMemorySecretsVault } from '../lib/index.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/get-secrets.ts b/infra/core/src/commands/get-secrets.ts index 0667afdf..d856345a 100644 --- a/infra/core/src/commands/get-secrets.ts +++ b/infra/core/src/commands/get-secrets.ts @@ -1,4 +1,4 @@ -import { type SecretsVault } from '../lib/types'; +import { type SecretsVault } from '../lib/types.js'; export const getSecrets = async (vault: SecretsVault) => { const allKeys = await vault.getSecretKeys(); diff --git a/infra/core/src/commands/index.ts b/infra/core/src/commands/index.ts index d6fe8e09..c6174b88 100644 --- a/infra/core/src/commands/index.ts +++ b/infra/core/src/commands/index.ts @@ -1,6 +1,6 @@ -export { deleteSecret } from './delete-secret'; -export { getSecret } from './get-secret'; -export { getSecrets } from './get-secrets'; -export { getSecretKeyList } from './get-secret-key-list'; -export { setLoginGovSecrets } from './set-login-gov-secrets'; -export { setSecret } from './set-secret'; +export { deleteSecret } from './delete-secret.js'; +export { getSecret } from './get-secret.js'; +export { getSecrets } from './get-secrets.js'; +export { getSecretKeyList } from './get-secret-key-list.js'; +export { setLoginGovSecrets } from './set-login-gov-secrets.js'; +export { setSecret } from './set-secret.js'; diff --git a/infra/core/src/commands/set-login-gov-secrets.test.ts b/infra/core/src/commands/set-login-gov-secrets.test.ts index 1c6b1303..5388e98d 100644 --- a/infra/core/src/commands/set-login-gov-secrets.test.ts +++ b/infra/core/src/commands/set-login-gov-secrets.test.ts @@ -1,9 +1,9 @@ import { randomUUID } from 'crypto'; +import path from 'path'; import { describe, expect, it } from 'vitest'; -import { createInMemorySecretsVault } from '../lib'; -import { setLoginGovSecrets } from './set-login-gov-secrets'; -import path from 'path'; +import { createInMemorySecretsVault } from '../lib/index.js'; +import { setLoginGovSecrets } from './set-login-gov-secrets.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/set-login-gov-secrets.ts b/infra/core/src/commands/set-login-gov-secrets.ts index 197bd591..04f201bb 100644 --- a/infra/core/src/commands/set-login-gov-secrets.ts +++ b/infra/core/src/commands/set-login-gov-secrets.ts @@ -2,8 +2,8 @@ import { exec } from 'child_process'; import { promises as fs } from 'fs'; import { promisify } from 'util'; -import { type SecretsVault } from '../lib/types'; -import { type DeployEnv, getAppLoginGovKeys } from '../values'; +import { type SecretsVault } from '../lib/types.js'; +import { type DeployEnv, getAppLoginGovKeys } from '../values.js'; const execPromise = promisify(exec); diff --git a/infra/core/src/commands/set-secret.test.ts b/infra/core/src/commands/set-secret.test.ts index f79b30b0..cfff82be 100644 --- a/infra/core/src/commands/set-secret.test.ts +++ b/infra/core/src/commands/set-secret.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { setSecret } from './set-secret'; -import { createInMemorySecretsVault } from '../lib'; +import { setSecret } from './set-secret.js'; +import { createInMemorySecretsVault } from '../lib/index.js'; const getTestVault = (vaultData: any) => { const result = createInMemorySecretsVault(JSON.stringify(vaultData)); diff --git a/infra/core/src/commands/set-secret.ts b/infra/core/src/commands/set-secret.ts index e29467fd..45c759be 100644 --- a/infra/core/src/commands/set-secret.ts +++ b/infra/core/src/commands/set-secret.ts @@ -1,4 +1,4 @@ -import { type SecretsVault } from '../lib/types'; +import { type SecretsVault } from '../lib/types.js'; export const setSecret = async ( vault: SecretsVault, diff --git a/infra/core/src/index.ts b/infra/core/src/index.ts index 0b244e81..85a4f8b0 100644 --- a/infra/core/src/index.ts +++ b/infra/core/src/index.ts @@ -1,2 +1,3 @@ -export * as commands from './commands'; -export { getSecretsVault } from './lib'; +export * as commands from './commands/index.js'; +export { getSecretsVault } from './lib/index.js'; +export { type DeployEnv } from './values.js'; diff --git a/infra/core/src/lib/adapters/aws-param-store.ts b/infra/core/src/lib/adapters/aws-param-store.ts index f25e3f1b..32d8da46 100644 --- a/infra/core/src/lib/adapters/aws-param-store.ts +++ b/infra/core/src/lib/adapters/aws-param-store.ts @@ -9,7 +9,12 @@ import { SSMClient, } from '@aws-sdk/client-ssm'; -import type { SecretKey, SecretMap, SecretValue, SecretsVault } from '../types'; +import type { + SecretKey, + SecretMap, + SecretValue, + SecretsVault, +} from '../types.js'; export class AWSParameterStoreSecretsVault implements SecretsVault { client: SSMClient; diff --git a/infra/core/src/lib/adapters/in-memory.ts b/infra/core/src/lib/adapters/in-memory.ts index 6fd9e57a..4b5f4611 100644 --- a/infra/core/src/lib/adapters/in-memory.ts +++ b/infra/core/src/lib/adapters/in-memory.ts @@ -1,4 +1,4 @@ -import type { SecretMap, SecretsVault } from '../types'; +import type { SecretMap, SecretsVault } from '../types.js'; export class InMemorySecretsVault implements SecretsVault { constructor(private secretMap: SecretMap) {} diff --git a/infra/core/src/lib/adapters/index.ts b/infra/core/src/lib/adapters/index.ts index 40472729..6e9628d0 100644 --- a/infra/core/src/lib/adapters/index.ts +++ b/infra/core/src/lib/adapters/index.ts @@ -2,9 +2,9 @@ import { promises as fs } from 'fs'; import * as r from '@atj/common'; -import { AWSParameterStoreSecretsVault } from './aws-param-store'; -import { getSecretMapFromJsonString, type SecretsVault } from '../types'; -import { InMemorySecretsVault } from './in-memory'; +import { AWSParameterStoreSecretsVault } from './aws-param-store.js'; +import { getSecretMapFromJsonString, type SecretsVault } from '../types.js'; +import { InMemorySecretsVault } from './in-memory.js'; /** * Returns either a production vault or an in-memory vault initialized with the diff --git a/infra/core/src/lib/index.ts b/infra/core/src/lib/index.ts index d26c7aaf..8702eb7a 100644 --- a/infra/core/src/lib/index.ts +++ b/infra/core/src/lib/index.ts @@ -1,7 +1,7 @@ -import { type SecretMap, type SecretsVault } from './types'; +import { type SecretMap, type SecretsVault } from './types.js'; -export { getSecretMapFromJsonString } from './types'; -export * from './adapters'; +export { getSecretMapFromJsonString } from './types.js'; +export * from './adapters/index.js'; export const getSecretMap = async (vault: SecretsVault): Promise => { const secretKeys = await vault.getSecretKeys(); diff --git a/infra/core/src/lib/types.ts b/infra/core/src/lib/types.ts index 9c3c956a..d853b773 100644 --- a/infra/core/src/lib/types.ts +++ b/infra/core/src/lib/types.ts @@ -1,5 +1,5 @@ import * as z from 'zod'; -import { Result } from '@atj/common/src'; +import { type Result } from '@atj/common'; export type SecretKey = string; export type SecretValue = string | undefined; diff --git a/package.json b/package.json index 7be8f583..eedf645d 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "type": "module", "main": "index.js", "license": "CC0", + "packageManager": "pnpm@9.8.0", "scripts": { - "build": "turbo run build --filter=!infra-cdktf", + "build": "turbo run build --filter=!@atj/infra-cdktf", "clean": "turbo run clean", "dev": "turbo run dev --concurrency 18", "format": "prettier --write \"packages/*/src/**/*.{js,jsx,ts,tsx,scss}\"", @@ -22,6 +23,9 @@ "pre-commit": "pnpm format" }, "devDependencies": { + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", "@types/node": "^20.14.14", "@vitest/coverage-v8": "^2.0.5", "@vitest/ui": "^2.0.5", @@ -30,9 +34,12 @@ "husky": "^9.1.4", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", + "rimraf": "^6.0.1", + "rollup": "^4.20.0", + "rollup-plugin-typescript2": "^0.36.0", "ts-node": "^10.9.2", "tsup": "^8.2.4", - "turbo": "^1.13.4", + "turbo": "^2.0.14", "typescript": "^5.5.4", "vitest": "^2.0.5", "vitest-mock-extended": "^2.0.0" diff --git a/packages/auth/package.json b/packages/auth/package.json index 0e86b3b8..711b30f0 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -8,6 +8,7 @@ "types": "dist/index.d.js", "scripts": { "build": "tsc", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsc --watch", "test": "vitest run --coverage" }, diff --git a/packages/auth/src/context/base.ts b/packages/auth/src/context/base.ts index 786e2309..e4181e4f 100644 --- a/packages/auth/src/context/base.ts +++ b/packages/auth/src/context/base.ts @@ -1,16 +1,18 @@ import { Cookie, Lucia } from 'lucia'; -import { type DatabaseGateway } from '@atj/database'; +import { type AuthServiceContext, type UserSession } from '../index.js'; +import { + createPostgresLuciaAdapter, + createSqliteLuciaAdapter, +} from '../lucia.js'; +import { LoginGov } from '../provider.js'; +import { type AuthRepository } from '../repository/index.js'; -import { type AuthContext, type UserSession } from '..'; -import { createPostgresLuciaAdapter, createSqliteLuciaAdapter } from '../lucia'; -import { LoginGov } from '../provider'; - -export class BaseAuthContext implements AuthContext { +export class BaseAuthContext implements AuthServiceContext { private lucia?: Lucia; constructor( - public db: DatabaseGateway, + public db: AuthRepository, public provider: LoginGov, public getCookie: (name: string) => string | undefined, public setCookie: (cookie: Cookie) => void, diff --git a/packages/auth/src/context/test.ts b/packages/auth/src/context/test.ts index 6fc632f1..00eb32f9 100644 --- a/packages/auth/src/context/test.ts +++ b/packages/auth/src/context/test.ts @@ -1,15 +1,15 @@ import { Cookie, Lucia } from 'lucia'; import { vi } from 'vitest'; -import { - type DatabaseGateway, - createInMemoryDatabaseContext, - createDatabaseGateway, -} from '@atj/database'; +import { createInMemoryDatabaseContext } from '@atj/database/context'; -import { type AuthContext, type UserSession } from '..'; -import { createSqliteLuciaAdapter } from '../lucia'; -import { LoginGov } from '../provider'; +import { AuthServiceContext, UserSession } from '../index.js'; +import { createSqliteLuciaAdapter } from '../lucia.js'; +import { LoginGov } from '../provider.js'; +import { + createAuthRepository, + type AuthRepository, +} from '../repository/index.js'; type Options = { getCookie: (name: string) => string | undefined; @@ -26,9 +26,9 @@ export const createTestAuthContext = async (opts?: Partial) => { isUserAuthorized: opts?.isUserAuthorized || vi.fn(async () => true), }; const dbContext = await createInMemoryDatabaseContext(); - const database = createDatabaseGateway(dbContext); + const authRepo = createAuthRepository(dbContext); return new TestAuthContext( - database, + authRepo, new LoginGov({ loginGovUrl: 'https://idp.int.identitysandbox.gov', clientId: @@ -43,11 +43,11 @@ export const createTestAuthContext = async (opts?: Partial) => { ); }; -export class TestAuthContext implements AuthContext { +export class TestAuthContext implements AuthServiceContext { private lucia?: Lucia; constructor( - public db: DatabaseGateway, + public db: AuthRepository, public provider: LoginGov, public getCookie: (name: string) => string | undefined, public setCookie: (cookie: Cookie) => void, diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 590efe8f..158bef72 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -1,27 +1,20 @@ -import { type Cookie, type User, type Session, type Lucia } from 'lucia'; +import { type User, type Session } from 'lucia'; -import { type DatabaseGateway } from '@atj/database'; - -export { BaseAuthContext } from './context/base'; -import { type LoginGovOptions, LoginGov } from './provider'; +export { BaseAuthContext } from './context/base.js'; +import { type LoginGovOptions, LoginGov } from './provider.js'; export { type LoginGovOptions, LoginGov }; -export { getProviderRedirect } from './services/get-provider-redirect'; -export { logOut } from './services/logout'; -export { processProviderCallback } from './services/process-provider-callback'; -export { processSessionCookie } from './services/process-session-cookie'; +export { + type AuthRepository, + createAuthRepository, +} from './repository/index.js'; +export { getProviderRedirect } from './services/get-provider-redirect.js'; +export { logOut } from './services/logout.js'; +export { processProviderCallback } from './services/process-provider-callback.js'; +export { processSessionCookie } from './services/process-session-cookie.js'; export { User, Session }; +export { type AuthServiceContext } from './services/index.js'; export type UserSession = { user: User | null; session: Session | null; }; - -export type AuthContext = { - db: DatabaseGateway; - provider: LoginGov; - getCookie: (name: string) => string | undefined; - setCookie: (cookie: Cookie) => void; - setUserSession: (userSession: UserSession) => void; - getLucia: () => Promise; - isUserAuthorized: (email: string) => Promise; -}; diff --git a/packages/database/src/gateways/sessions/create-session.test.ts b/packages/auth/src/repository/create-session.test.ts similarity index 90% rename from packages/database/src/gateways/sessions/create-session.test.ts rename to packages/auth/src/repository/create-session.test.ts index fa803a29..369eac2c 100644 --- a/packages/database/src/gateways/sessions/create-session.test.ts +++ b/packages/auth/src/repository/create-session.test.ts @@ -1,7 +1,7 @@ import { expect, it } from 'vitest'; -import { type DbTestContext, describeDatabase } from '../../testing.js'; -import { createUser } from '../users/create-user.js'; +import { type DbTestContext, describeDatabase } from '@atj/database/testing'; +import { createUser } from './create-user.js'; import { createSession } from './create-session.js'; describeDatabase('create session', () => { diff --git a/packages/database/src/gateways/sessions/create-session.ts b/packages/auth/src/repository/create-session.ts similarity index 83% rename from packages/database/src/gateways/sessions/create-session.ts rename to packages/auth/src/repository/create-session.ts index a2fd9691..752c2a0a 100644 --- a/packages/database/src/gateways/sessions/create-session.ts +++ b/packages/auth/src/repository/create-session.ts @@ -1,5 +1,4 @@ -import { dateValue } from '../../clients/kysely/db-helpers.js'; -import { type DatabaseContext } from '../../context/types.js'; +import { type DatabaseContext, dateValue } from '@atj/database'; type Session = { id: string; diff --git a/packages/database/src/gateways/users/create-user.test.ts b/packages/auth/src/repository/create-user.test.ts similarity index 94% rename from packages/database/src/gateways/users/create-user.test.ts rename to packages/auth/src/repository/create-user.test.ts index 501f60d8..3b429a42 100644 --- a/packages/database/src/gateways/users/create-user.test.ts +++ b/packages/auth/src/repository/create-user.test.ts @@ -1,6 +1,6 @@ import { expect, it } from 'vitest'; -import { describeDatabase, type DbTestContext } from '../../testing.js'; +import { type DbTestContext, describeDatabase } from '@atj/database/testing'; import { createUser } from './create-user.js'; diff --git a/packages/database/src/gateways/users/create-user.ts b/packages/auth/src/repository/create-user.ts similarity index 87% rename from packages/database/src/gateways/users/create-user.ts rename to packages/auth/src/repository/create-user.ts index 0208b8e9..8f618538 100644 --- a/packages/database/src/gateways/users/create-user.ts +++ b/packages/auth/src/repository/create-user.ts @@ -1,6 +1,6 @@ import { randomUUID } from 'crypto'; -import { type DatabaseContext } from '../../context/types.js'; +import { type DatabaseContext } from '@atj/database'; export const createUser = async (ctx: DatabaseContext, email: string) => { const id = randomUUID(); diff --git a/packages/database/src/gateways/users/get-user-id.test.ts b/packages/auth/src/repository/get-user-id.test.ts similarity index 90% rename from packages/database/src/gateways/users/get-user-id.test.ts rename to packages/auth/src/repository/get-user-id.test.ts index 8dbaa102..03840cc0 100644 --- a/packages/database/src/gateways/users/get-user-id.test.ts +++ b/packages/auth/src/repository/get-user-id.test.ts @@ -1,7 +1,7 @@ import { randomUUID } from 'crypto'; import { expect, it } from 'vitest'; -import { type DbTestContext, describeDatabase } from '../../testing.js'; +import { type DbTestContext, describeDatabase } from '@atj/database/testing'; import { getUserId } from './get-user-id.js'; diff --git a/packages/database/src/gateways/users/get-user-id.ts b/packages/auth/src/repository/get-user-id.ts similarity index 86% rename from packages/database/src/gateways/users/get-user-id.ts rename to packages/auth/src/repository/get-user-id.ts index f4e6506a..4d4af6f3 100644 --- a/packages/database/src/gateways/users/get-user-id.ts +++ b/packages/auth/src/repository/get-user-id.ts @@ -1,4 +1,4 @@ -import { type DatabaseContext } from '../../index.js'; +import { type DatabaseContext } from '@atj/database'; export const getUserId = async (ctx: DatabaseContext, email: string) => { const db = await ctx.getKysely(); diff --git a/packages/auth/src/repository/index.ts b/packages/auth/src/repository/index.ts new file mode 100644 index 00000000..84b6c323 --- /dev/null +++ b/packages/auth/src/repository/index.ts @@ -0,0 +1,15 @@ +import { createService } from '@atj/common'; +import { type DatabaseContext } from '@atj/database'; + +import { createSession } from './create-session.js'; +import { createUser } from './create-user.js'; +import { getUserId } from './get-user-id.js'; + +export const createAuthRepository = (ctx: DatabaseContext) => + createService(ctx, { + createSession, + createUser, + getUserId, + }); + +export type AuthRepository = ReturnType; diff --git a/packages/auth/src/services/get-provider-redirect.test.ts b/packages/auth/src/services/get-provider-redirect.test.ts index 8626273e..63e6ee41 100644 --- a/packages/auth/src/services/get-provider-redirect.test.ts +++ b/packages/auth/src/services/get-provider-redirect.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest'; -import { createTestAuthContext } from '../context/test'; +import { createTestAuthContext } from '../context/test.js'; -import { getProviderRedirect } from './get-provider-redirect'; +import { getProviderRedirect } from './get-provider-redirect.js'; describe('getProviderRedirect database gateway', () => { it('returns cookies and redirect url', async () => { diff --git a/packages/auth/src/services/get-provider-redirect.ts b/packages/auth/src/services/get-provider-redirect.ts index 6cd8efb1..3988664d 100644 --- a/packages/auth/src/services/get-provider-redirect.ts +++ b/packages/auth/src/services/get-provider-redirect.ts @@ -1,7 +1,7 @@ import { generateCodeVerifier, generateState } from 'arctic'; -import { AuthContext } from '..'; +import { type AuthServiceContext } from './index.js'; -export const getProviderRedirect = async (ctx: AuthContext) => { +export const getProviderRedirect = async (ctx: AuthServiceContext) => { const state = generateState(); const codeVerifier = generateCodeVerifier(); const nonceCode = generateCodeVerifier(); diff --git a/packages/auth/src/services/index.ts b/packages/auth/src/services/index.ts new file mode 100644 index 00000000..d791ab9e --- /dev/null +++ b/packages/auth/src/services/index.ts @@ -0,0 +1,36 @@ +import { Cookie, Lucia } from 'lucia'; + +import { createService } from '@atj/common'; + +import { + type UserSession, + getProviderRedirect, + logOut, + processProviderCallback, + processSessionCookie, +} from '../index.js'; +import { LoginGov } from '../provider.js'; +import { type AuthRepository } from '../repository/index.js'; + +export type AuthServiceContext = { + db: AuthRepository; + provider: LoginGov; + getCookie: (name: string) => string | undefined; + setCookie: (cookie: Cookie) => void; + setUserSession: (userSession: UserSession) => void; + getLucia: () => Promise; + isUserAuthorized: (email: string) => Promise; +}; + +export const createAuthService = (ctx: AuthServiceContext) => + createService(ctx, { + getProviderRedirect, + logOut, + processProviderCallback, + processSessionCookie, + }); + +export type AuthService = Omit< + ReturnType, + 'getContext' +>; diff --git a/packages/auth/src/services/logout.test.ts b/packages/auth/src/services/logout.test.ts index bda56c67..a33efc12 100644 --- a/packages/auth/src/services/logout.test.ts +++ b/packages/auth/src/services/logout.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { createTestAuthContext } from '../context/test'; -import { logOut } from './logout'; +import { createTestAuthContext } from '../context/test.js'; +import { logOut } from './logout.js'; describe('logOut database gateway', () => { it('works', async () => { diff --git a/packages/auth/src/services/logout.ts b/packages/auth/src/services/logout.ts index bfba9bf5..00179c70 100644 --- a/packages/auth/src/services/logout.ts +++ b/packages/auth/src/services/logout.ts @@ -1,7 +1,7 @@ import { type Session } from 'lucia'; -import { type AuthContext } from '..'; +import { type AuthServiceContext } from './index.js'; -export const logOut = async (ctx: AuthContext, session: Session) => { +export const logOut = async (ctx: AuthServiceContext, session: Session) => { const lucia = await ctx.getLucia(); await lucia.invalidateSession(session.id); const sessionCookie = lucia.createBlankSessionCookie(); diff --git a/packages/auth/src/services/process-provider-callback.test.ts b/packages/auth/src/services/process-provider-callback.test.ts index 5c3b0469..9a777472 100644 --- a/packages/auth/src/services/process-provider-callback.test.ts +++ b/packages/auth/src/services/process-provider-callback.test.ts @@ -1,12 +1,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { processProviderCallback } from './process-provider-callback'; -import { createTestAuthContext } from '../context/test'; -import { AuthContext } from '..'; -import { success } from '@atj/common'; +import { processProviderCallback } from './process-provider-callback.js'; +import { createTestAuthContext } from '../context/test.js'; +import { type AuthServiceContext } from './index.js'; describe('processProviderCallback', () => { - let ctx: AuthContext; + let ctx: AuthServiceContext; beforeEach(async () => { // Set up global mocks diff --git a/packages/auth/src/services/process-provider-callback.ts b/packages/auth/src/services/process-provider-callback.ts index b4ba5919..4d5ac9b2 100644 --- a/packages/auth/src/services/process-provider-callback.ts +++ b/packages/auth/src/services/process-provider-callback.ts @@ -1,8 +1,8 @@ import { OAuth2RequestError } from 'arctic'; +import { randomUUID } from 'crypto'; import * as r from '@atj/common'; -import { type AuthContext } from '..'; -import { randomUUID } from 'crypto'; +import { type AuthServiceContext } from './index.js'; type LoginGovUser = { sub: string; @@ -19,7 +19,7 @@ type Params = { }; export const processProviderCallback = async ( - ctx: AuthContext, + ctx: AuthServiceContext, params: Params, storedParams: Params & { nonce: string | null }, fetchUserData: typeof fetchUserDataImpl = fetchUserDataImpl diff --git a/packages/auth/src/services/process-session-cookie.test.ts b/packages/auth/src/services/process-session-cookie.test.ts index b85b4428..3865760c 100644 --- a/packages/auth/src/services/process-session-cookie.test.ts +++ b/packages/auth/src/services/process-session-cookie.test.ts @@ -1,8 +1,8 @@ import { randomUUID } from 'crypto'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { createTestAuthContext } from '../context/test'; -import { processSessionCookie } from './process-session-cookie'; +import { createTestAuthContext } from '../context/test.js'; +import { processSessionCookie } from './process-session-cookie.js'; describe('processSessionCookie', () => { const today = new Date(2020, 1, 1); diff --git a/packages/auth/src/services/process-session-cookie.ts b/packages/auth/src/services/process-session-cookie.ts index 8bc66dcd..401a7122 100644 --- a/packages/auth/src/services/process-session-cookie.ts +++ b/packages/auth/src/services/process-session-cookie.ts @@ -2,10 +2,10 @@ import { verifyRequestOrigin } from 'lucia'; import { type VoidResult } from '@atj/common'; -import { type AuthContext } from '..'; +import { type AuthServiceContext } from './index.js'; export const processSessionCookie = async ( - ctx: AuthContext, + ctx: AuthServiceContext, request: Request ): Promise> => { if (request.method !== 'GET') { diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json index 24abc391..0efd82a1 100644 --- a/packages/auth/tsconfig.json +++ b/packages/auth/tsconfig.json @@ -2,6 +2,8 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "emitDeclarationOnly": false, + "module": "NodeNext", + "moduleResolution": "NodeNext", "outDir": "./dist", "rootDir": "./src" }, diff --git a/packages/auth/vitest.config.ts b/packages/auth/vitest.config.ts index 90197569..68cf95c0 100644 --- a/packages/auth/vitest.config.ts +++ b/packages/auth/vitest.config.ts @@ -1,11 +1,13 @@ import { defineConfig, mergeConfig } from 'vitest/config'; +import { getVitestDatabaseContainerGlobalSetupPath } from '@atj/database'; import sharedTestConfig from '../../vitest.shared'; export default mergeConfig( sharedTestConfig, defineConfig({ test: { + globalSetup: [getVitestDatabaseContainerGlobalSetupPath()], setupFiles: ['./vitest.setup.ts'], }, }) diff --git a/packages/common/package.json b/packages/common/package.json index 044662a8..dafd39e5 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -8,6 +8,7 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsc --watch" }, "dependencies": {} diff --git a/packages/database/migrations/20240820130044_forms.mjs b/packages/database/migrations/20240820130044_forms.mjs new file mode 100644 index 00000000..bda656d9 --- /dev/null +++ b/packages/database/migrations/20240820130044_forms.mjs @@ -0,0 +1,21 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +export async function up(knex) { + await knex.schema.createTable('forms', table => { + table.uuid('id').primary(); + // We don't have an immediate need to query over the form, so we'll just + // store it as `json` rather than `jsonb` + table.text('data').notNullable(); + //table.timestamps(true, true); + }); +} + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +export async function down(knex) { + await knex.schema.dropTableIfExists('forms'); +} diff --git a/packages/database/package.json b/packages/database/package.json index 439e13b8..30a065cf 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -6,21 +6,27 @@ "license": "CC0", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", + "types": "dist/types/index.d.ts", "exports": { ".": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js", "types": "./dist/types/index.d.ts" }, + "./context": { + "import": "./dist/esm/context.js", + "require": "./dist/cjs/context.js", + "types": "./dist/types/context/index.d.ts" + }, "./testing": { "import": "./dist/esm/testing.js", "require": "./dist/cjs/testing.js", "types": "./dist/types/testing.d.ts" } }, - "types": "dist/types/index.d.ts", "scripts": { "build": "rollup -c", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "rollup -c -w", "test": "vitest run --coverage" }, @@ -33,15 +39,9 @@ "pg": "^8.12.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "^15.2.3", "@testcontainers/postgresql": "^10.11.0", "@types/better-sqlite3": "^7.6.11", - "rollup": "^4.20.0", - "rollup-plugin-typescript2": "^0.36.0", "testcontainers": "^10.11.0", - "typescript": "^5.5.4", "vite-tsconfig-paths": "^4.3.2" } } diff --git a/packages/database/rollup.config.js b/packages/database/rollup.config.js index 53a464ef..91515950 100644 --- a/packages/database/rollup.config.js +++ b/packages/database/rollup.config.js @@ -5,20 +5,30 @@ import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import typescript from 'rollup-plugin-typescript2'; -import pkg from './package.json' assert { type: 'json' }; +import packageJson from './package.json' assert { type: 'json' }; +import workspacePackageJson from '../../package.json' assert { type: 'json' }; export default { - input: ['src/index.ts', 'src/testing.ts'], + //input: ['src/index.ts', 'src/context/index.ts', 'src/testing.ts'], + input: { + index: 'src/index.ts', + context: 'src/context/index.ts', + testing: 'src/testing.ts', + }, output: [ { dir: 'dist/esm', format: 'esm', sourcemap: true, + entryFileNames: '[name].js', + chunkFileNames: '[name]-[hash].js', }, { dir: 'dist/cjs', format: 'cjs', sourcemap: true, + entryFileNames: '[name].js', + chunkFileNames: '[name]-[hash].js', }, ], plugins: [ @@ -31,9 +41,15 @@ export default { }), ], external: (() => { - const dependencies = Object.keys(pkg.dependencies || {}); - const devDependencies = Object.keys(pkg.devDependencies || {}); - const builtins = builtinModules; - return [...new Set([...dependencies, ...devDependencies, ...builtins])]; + // Externalize all the things + return [ + ...new Set([ + ...Object.keys(packageJson.dependencies || {}), + ...Object.keys(packageJson.devDependencies || {}), + ...Object.keys(workspacePackageJson.dependencies || {}), + ...Object.keys(workspacePackageJson.devDependencies || {}), + ...builtinModules, + ]), + ]; })(), }; diff --git a/packages/database/src/clients/kysely/types.ts b/packages/database/src/clients/kysely/types.ts index 4d810938..4496d21a 100644 --- a/packages/database/src/clients/kysely/types.ts +++ b/packages/database/src/clients/kysely/types.ts @@ -12,6 +12,7 @@ export type Engine = 'sqlite' | 'postgres'; export interface Database { users: UsersTable; sessions: SessionsTable; + forms: FormsTable; } interface UsersTable { @@ -36,4 +37,14 @@ export type SessionsSelectable = Selectable>; export type SessionsInsertable = Insertable>; export type SessionsUpdateable = Updateable>; +interface FormsTable { + id: string; + data: string; // Blueprint; + created_at: Generated; + updated_at: Generated; +} +export type FormsTableSelectable = Selectable; +export type FormsTableInsertable = Insertable; +export type FormsTableUpdateable = Updateable; + export type DatabaseClient = Kysely; diff --git a/packages/database/src/context/index.ts b/packages/database/src/context/index.ts new file mode 100644 index 00000000..77f5111a --- /dev/null +++ b/packages/database/src/context/index.ts @@ -0,0 +1,6 @@ +export { + type FilesystemDatabaseContext, + createFilesystemDatabaseContext, +} from './file-system.js'; +export { createInMemoryDatabaseContext } from './in-memory.js'; +export { createPostgresDatabaseContext } from './postgres.js'; diff --git a/packages/database/src/index.ts b/packages/database/src/index.ts index f8c936ee..a3a716ba 100644 --- a/packages/database/src/index.ts +++ b/packages/database/src/index.ts @@ -1,32 +1,11 @@ import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; -import { createService } from '@atj/common'; - -import { DatabaseContext } from './context/types.js'; -import { createSession } from './gateways/sessions/create-session.js'; -import { createUser } from './gateways/users/create-user.js'; -import { getUserId } from './gateways/users/get-user-id.js'; - -export { - type FilesystemDatabaseContext, - createFilesystemDatabaseContext, -} from './context/file-system.js'; -export { createInMemoryDatabaseContext } from './context/in-memory.js'; -export { createPostgresDatabaseContext } from './context/postgres.js'; +export { dateValue } from './clients/kysely/db-helpers.js'; export { type Database } from './clients/kysely/types.js'; export { type DatabaseContext } from './context/types.js'; export { migrateDatabase } from './management/migrate-database.js'; -export const getDatabaseTestContainerGlobalSetupPath = () => { +export const getVitestDatabaseContainerGlobalSetupPath = () => { return join(dirname(fileURLToPath(import.meta.url)), '../../vitest.setup.ts'); }; - -export const createDatabaseGateway = (ctx: DatabaseContext) => - createService(ctx, { - createSession, - createUser, - getUserId, - }); - -export type DatabaseGateway = ReturnType; diff --git a/packages/dependency-graph/package.json b/packages/dependency-graph/package.json index cd6f6fa1..11fa3bd5 100644 --- a/packages/dependency-graph/package.json +++ b/packages/dependency-graph/package.json @@ -8,6 +8,7 @@ "types": "dist/index.d.js", "scripts": { "build": "tsc", + "clean": "rimraf dist tsconfig.tsbuildinfo coverage", "dev": "tsc --watch", "test": "echo no @atj/dependency-graph tests" }, diff --git a/packages/dependency-graph/src/graph-dependencies.ts b/packages/dependency-graph/src/graph-dependencies.ts index 98afbd06..2b08f484 100644 --- a/packages/dependency-graph/src/graph-dependencies.ts +++ b/packages/dependency-graph/src/graph-dependencies.ts @@ -1,8 +1,9 @@ import * as graphviz from 'graphviz'; -import { DependencyMap } from './get-dependencies'; +import { DependencyMap } from './get-dependencies.js'; const createGraphvizDigraph = (workspaceDependencies: DependencyMap) => { const graph = graphviz.digraph('workspace'); + graph.set('layout', 'neato'); Object.entries(workspaceDependencies).forEach( ([projectName, projectDependencies]) => { graph.addNode(projectName); diff --git a/packages/dependency-graph/src/index.ts b/packages/dependency-graph/src/index.ts index 3a7093c7..e66efff3 100644 --- a/packages/dependency-graph/src/index.ts +++ b/packages/dependency-graph/src/index.ts @@ -1,5 +1,5 @@ -import { getWorkspaceDependencies } from './get-dependencies'; -import { writeDependencyGraph } from './graph-dependencies'; +import { getWorkspaceDependencies } from './get-dependencies.js'; +import { writeDependencyGraph } from './graph-dependencies.js'; export const createDependencyGraph = async ( workspaceRoot: string, diff --git a/packages/design/package.json b/packages/design/package.json index 7c564972..0abb06c4 100644 --- a/packages/design/package.json +++ b/packages/design/package.json @@ -8,9 +8,9 @@ "build:lib": "vite build", "build:storybook": "storybook build", "build:styles": "gulp update", - "clean": "run-p: clean:*", - "clean:lib": "rm -rf dist", - "clean:styles": "rm -rf static", + "clean": "pnpm clean:lib && pnpm clean:styles", + "clean:lib": "rimraf dist", + "clean:styles": "rimraf static", "dev": "run-p dev:*", "dev:lib": "vite", "dev:storybook": "storybook dev -p 9009", diff --git a/packages/design/src/AvailableFormList/AvailableFormList.stories.tsx b/packages/design/src/AvailableFormList/AvailableFormList.stories.tsx index ff3326b2..dab6662d 100644 --- a/packages/design/src/AvailableFormList/AvailableFormList.stories.tsx +++ b/packages/design/src/AvailableFormList/AvailableFormList.stories.tsx @@ -1,18 +1,18 @@ +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; import type { Meta, StoryObj } from '@storybook/react'; -import AvailableFormList from '.'; -import { service } from '@atj/forms'; -import { createForm, nullSession } from '@atj/forms'; -import { MemoryRouter } from 'react-router-dom'; -import { FormManagerProvider } from '../FormManager/store'; -import { createTestFormManagerContext } from '../test-form'; -import React from 'react'; +import { type FormService, createForm, nullSession } from '@atj/forms'; +import { createTestBrowserFormService } from '@atj/forms/context'; +import { FormManagerProvider } from '../FormManager/store.js'; +import { createTestFormManagerContext } from '../test-form.js'; +import AvailableFormList from './index.js'; const meta: Meta = { title: 'FormManager/AvailableFormList', component: AvailableFormList, args: { - formService: service.createTestFormService({ + formService: createTestBrowserFormService({ 'form-1': createForm({ title: 'Form 1', description: 'Use this form to...', @@ -46,7 +46,7 @@ export const Empty = { title: 'Empty form list', component: AvailableFormList, args: { - formService: service.createTestFormService({}), + formService: createTestBrowserFormService({}) as FormService, urlForForm: () => `#`, urlForFormManager: () => `#`, }, diff --git a/packages/design/src/AvailableFormList/AvailableFormList.test.tsx b/packages/design/src/AvailableFormList/AvailableFormList.test.tsx index 25ec1095..d6e20e47 100644 --- a/packages/design/src/AvailableFormList/AvailableFormList.test.tsx +++ b/packages/design/src/AvailableFormList/AvailableFormList.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../test-helper'; -import meta, * as stories from './AvailableFormList.stories'; +import { describeStories } from '../test-helper.js'; +import meta, * as stories from './AvailableFormList.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/AvailableFormList/index.tsx b/packages/design/src/AvailableFormList/index.tsx index 9bb46ffb..cc646a8c 100644 --- a/packages/design/src/AvailableFormList/index.tsx +++ b/packages/design/src/AvailableFormList/index.tsx @@ -1,8 +1,10 @@ import React, { useEffect, useState } from 'react'; -import { service } from '@atj/forms'; -import * as AppRoutes from '../FormManager/routes'; import { Link } from 'react-router-dom'; +import { type FormService } from '@atj/forms'; + +import * as AppRoutes from '../FormManager/routes.js'; + type FormDetails = { id: string; title: string; @@ -16,16 +18,17 @@ export default function AvailableFormList({ urlForForm, urlForFormManager, }: { - formService: service.FormService; + formService: FormService; urlForForm: UrlForForm; urlForFormManager: UrlForFormManager; }) { const [forms, setForms] = useState([]); useEffect(() => { - const result = formService.getFormList(); - if (result.success) { - setForms(result.data); - } + formService.getFormList().then(result => { + if (result.success) { + setForms(result.data); + } + }); }, []); return ( <> diff --git a/packages/design/src/Form/ActionBar/ActionBar.stories.tsx b/packages/design/src/Form/ActionBar/ActionBar.stories.tsx index c1da7e44..2432d892 100644 --- a/packages/design/src/Form/ActionBar/ActionBar.stories.tsx +++ b/packages/design/src/Form/ActionBar/ActionBar.stories.tsx @@ -1,6 +1,6 @@ import type { Meta } from '@storybook/react'; -import ActionBar from '.'; +import ActionBar from './index.js'; export default { title: 'FormManager/ActionBar', diff --git a/packages/design/src/Form/ActionBar/ActionBar.test.ts b/packages/design/src/Form/ActionBar/ActionBar.test.ts index f24112b0..988efc20 100644 --- a/packages/design/src/Form/ActionBar/ActionBar.test.ts +++ b/packages/design/src/Form/ActionBar/ActionBar.test.ts @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../test-helper'; -import meta, * as stories from './ActionBar.stories'; +import { describeStories } from '../../test-helper.js'; +import meta, * as stories from './ActionBar.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/Form.stories.tsx b/packages/design/src/Form/Form.stories.tsx index eb922d4f..5233f9fe 100644 --- a/packages/design/src/Form/Form.stories.tsx +++ b/packages/design/src/Form/Form.stories.tsx @@ -1,8 +1,8 @@ import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; -import Form from '.'; -import { createTestFormContext, createTestSession } from '../test-form'; +import Form from './index.js'; +import { createTestFormContext, createTestSession } from '../test-form.js'; import { MemoryRouter } from 'react-router-dom'; const meta: Meta = { diff --git a/packages/design/src/Form/Form.test.tsx b/packages/design/src/Form/Form.test.tsx index 86e0c821..34b9e356 100644 --- a/packages/design/src/Form/Form.test.tsx +++ b/packages/design/src/Form/Form.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../test-helper'; -import meta, * as stories from './Form.stories'; +import { describeStories } from '../test-helper.js'; +import meta, * as stories from './Form.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/Address/index.tsx b/packages/design/src/Form/components/Address/index.tsx index 1da1b47c..e05df83f 100644 --- a/packages/design/src/Form/components/Address/index.tsx +++ b/packages/design/src/Form/components/Address/index.tsx @@ -2,9 +2,9 @@ import classNames from 'classnames'; import React from 'react'; import { useFormContext } from 'react-hook-form'; -import { AddressComponentProps } from '@atj/forms/src/patterns/address'; +import { type AddressComponentProps } from '@atj/forms'; -import { type PatternComponent } from '../..'; +import { type PatternComponent } from '../../index.js'; const Address: PatternComponent = props => { const { register } = useFormContext(); diff --git a/packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx b/packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx index 04655759..40953130 100644 --- a/packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx +++ b/packages/design/src/Form/components/Checkbox/Checkbox.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { type Meta, type StoryObj } from '@storybook/react'; -import { CheckboxPattern } from './Checkbox'; +import { CheckboxPattern } from './Checkbox.js'; import { CheckboxProps } from '@atj/forms'; const meta: Meta = { diff --git a/packages/design/src/Form/components/Checkbox/Checkbox.test.tsx b/packages/design/src/Form/components/Checkbox/Checkbox.test.tsx index 31494615..028c92ed 100644 --- a/packages/design/src/Form/components/Checkbox/Checkbox.test.tsx +++ b/packages/design/src/Form/components/Checkbox/Checkbox.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './Checkbox.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './Checkbox.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/Checkbox/Checkbox.tsx b/packages/design/src/Form/components/Checkbox/Checkbox.tsx index 07d14077..ae2f1004 100644 --- a/packages/design/src/Form/components/Checkbox/Checkbox.tsx +++ b/packages/design/src/Form/components/Checkbox/Checkbox.tsx @@ -3,7 +3,7 @@ import { useFormContext } from 'react-hook-form'; import { type CheckboxProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; export const CheckboxPattern: PatternComponent = props => { const { register } = useFormContext(); diff --git a/packages/design/src/Form/components/Checkbox/index.tsx b/packages/design/src/Form/components/Checkbox/index.tsx index 26aa0abb..8cb1c614 100644 --- a/packages/design/src/Form/components/Checkbox/index.tsx +++ b/packages/design/src/Form/components/Checkbox/index.tsx @@ -1,2 +1,2 @@ -import { CheckboxPattern } from './Checkbox'; +import { CheckboxPattern } from './Checkbox.js'; export default CheckboxPattern; diff --git a/packages/design/src/Form/components/Fieldset/Fieldset.stories.tsx b/packages/design/src/Form/components/Fieldset/Fieldset.stories.tsx index 6a5cd8be..55f3f558 100644 --- a/packages/design/src/Form/components/Fieldset/Fieldset.stories.tsx +++ b/packages/design/src/Form/components/Fieldset/Fieldset.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import Fieldset from '.'; +import Fieldset from './index.js'; export default { title: 'patterns/Fieldset', diff --git a/packages/design/src/Form/components/Fieldset/Fieldset.test.tsx b/packages/design/src/Form/components/Fieldset/Fieldset.test.tsx index e7e82414..e5cf4067 100644 --- a/packages/design/src/Form/components/Fieldset/Fieldset.test.tsx +++ b/packages/design/src/Form/components/Fieldset/Fieldset.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './Fieldset.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './Fieldset.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/Fieldset/index.tsx b/packages/design/src/Form/components/Fieldset/index.tsx index 54e925f7..d1f4f431 100644 --- a/packages/design/src/Form/components/Fieldset/index.tsx +++ b/packages/design/src/Form/components/Fieldset/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { type FieldsetProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const Fieldset: PatternComponent = props => { return ( diff --git a/packages/design/src/Form/components/FormSummary/FormSummary.stories.tsx b/packages/design/src/Form/components/FormSummary/FormSummary.stories.tsx index d667ba54..c0887d1a 100644 --- a/packages/design/src/Form/components/FormSummary/FormSummary.stories.tsx +++ b/packages/design/src/Form/components/FormSummary/FormSummary.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import FormSummary from '.'; +import FormSummary from './index.js'; export default { title: 'patterns/FormSummary', diff --git a/packages/design/src/Form/components/FormSummary/FormSummary.test.ts b/packages/design/src/Form/components/FormSummary/FormSummary.test.ts index 118a0ec6..9efa9802 100644 --- a/packages/design/src/Form/components/FormSummary/FormSummary.test.ts +++ b/packages/design/src/Form/components/FormSummary/FormSummary.test.ts @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './FormSummary.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './FormSummary.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/FormSummary/index.tsx b/packages/design/src/Form/components/FormSummary/index.tsx index 32186b5e..d9a009f6 100644 --- a/packages/design/src/Form/components/FormSummary/index.tsx +++ b/packages/design/src/Form/components/FormSummary/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { type FormSummaryProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const FormSummary: PatternComponent = props => { return ( diff --git a/packages/design/src/Form/components/Page/index.tsx b/packages/design/src/Form/components/Page/index.tsx index 7ae23ba5..bdb16004 100644 --- a/packages/design/src/Form/components/Page/index.tsx +++ b/packages/design/src/Form/components/Page/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { type PageProps } from '@atj/forms'; -import { type PatternComponent } from '../..'; +import { type PatternComponent } from '../../index.js'; const Page: PatternComponent = props => { return <>{props.children}; diff --git a/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.stories.tsx b/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.stories.tsx index 53b33341..c02560f5 100644 --- a/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.stories.tsx +++ b/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { PageMenu } from './PageMenu'; +import { PageMenu } from './PageMenu.js'; const meta: Meta = { title: 'patterns/PageSet/PageMenu', diff --git a/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.test.tsx b/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.test.tsx index f7a53a61..d3064785 100644 --- a/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.test.tsx +++ b/packages/design/src/Form/components/PageSet/PageMenu/PageMenu.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../../test-helper'; -import meta, * as stories from './PageMenu.stories'; +import { describeStories } from '../../../../test-helper.js'; +import meta, * as stories from './PageMenu.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/PageSet/PageMenu/index.ts b/packages/design/src/Form/components/PageSet/PageMenu/index.ts index 97d1cfed..76c88e50 100644 --- a/packages/design/src/Form/components/PageSet/PageMenu/index.ts +++ b/packages/design/src/Form/components/PageSet/PageMenu/index.ts @@ -1 +1 @@ -export { PageMenu } from './PageMenu'; +export { PageMenu } from './PageMenu.js'; diff --git a/packages/design/src/Form/components/PageSet/PageSet.stories.tsx b/packages/design/src/Form/components/PageSet/PageSet.stories.tsx index c9f00228..a9ca1c17 100644 --- a/packages/design/src/Form/components/PageSet/PageSet.stories.tsx +++ b/packages/design/src/Form/components/PageSet/PageSet.stories.tsx @@ -4,14 +4,14 @@ import type { Meta, StoryObj } from '@storybook/react'; import { type PageSetProps } from '@atj/forms'; -import { FormManagerProvider } from '../../../FormManager/store'; +import { FormManagerProvider } from '../../../FormManager/store.js'; import { createTestFormManagerContext, createTestSession, createTwoPatternTestForm, -} from '../../../test-form'; +} from '../../../test-form.js'; -import PageSet from './PageSet'; +import PageSet from './PageSet.js'; const meta: Meta = { title: 'patterns/PageSet', diff --git a/packages/design/src/Form/components/PageSet/PageSet.test.tsx b/packages/design/src/Form/components/PageSet/PageSet.test.tsx index f6e5d8f1..a528eecf 100644 --- a/packages/design/src/Form/components/PageSet/PageSet.test.tsx +++ b/packages/design/src/Form/components/PageSet/PageSet.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './PageSet.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './PageSet.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/PageSet/PageSet.tsx b/packages/design/src/Form/components/PageSet/PageSet.tsx index 25b6c6b5..205a7f48 100644 --- a/packages/design/src/Form/components/PageSet/PageSet.tsx +++ b/packages/design/src/Form/components/PageSet/PageSet.tsx @@ -2,11 +2,11 @@ import React from 'react'; import { type PageSetProps } from '@atj/forms'; -import { type PatternComponent } from '../..'; -import ActionBar from '../../../Form/ActionBar'; -import { useRouteParams } from '../../../FormRouter/hooks'; +import { type PatternComponent } from '../../index.js'; +import ActionBar from '../../../Form/ActionBar/index.js'; +import { useRouteParams } from '../../../FormRouter/hooks.js'; -import { PageMenu } from './PageMenu'; +import { PageMenu } from './PageMenu/index.js'; const PageSet: PatternComponent = props => { const { routeParams, pathname } = useRouteParams(); diff --git a/packages/design/src/Form/components/PageSet/index.ts b/packages/design/src/Form/components/PageSet/index.ts index c44b5138..70031249 100644 --- a/packages/design/src/Form/components/PageSet/index.ts +++ b/packages/design/src/Form/components/PageSet/index.ts @@ -1,2 +1,2 @@ -import PageSet from './PageSet'; +import PageSet from './PageSet.js'; export default PageSet; diff --git a/packages/design/src/Form/components/Paragraph/index.tsx b/packages/design/src/Form/components/Paragraph/index.tsx index 61f07e80..62abb80d 100644 --- a/packages/design/src/Form/components/Paragraph/index.tsx +++ b/packages/design/src/Form/components/Paragraph/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { type ParagraphProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const FormSummary: PatternComponent = props => { return ( diff --git a/packages/design/src/Form/components/RadioGroup/RadioGroup.stories.tsx b/packages/design/src/Form/components/RadioGroup/RadioGroup.stories.tsx index fe156755..03fb98d8 100644 --- a/packages/design/src/Form/components/RadioGroup/RadioGroup.stories.tsx +++ b/packages/design/src/Form/components/RadioGroup/RadioGroup.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { type Meta, type StoryObj } from '@storybook/react'; -import { RadioGroupPattern } from './RadioGroup'; +import { RadioGroupPattern } from './RadioGroup.js'; const meta: Meta = { title: 'patterns/RadioGroupPattern', diff --git a/packages/design/src/Form/components/RadioGroup/RadioGroup.test.tsx b/packages/design/src/Form/components/RadioGroup/RadioGroup.test.tsx index 846b73b0..762026c7 100644 --- a/packages/design/src/Form/components/RadioGroup/RadioGroup.test.tsx +++ b/packages/design/src/Form/components/RadioGroup/RadioGroup.test.tsx @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './RadioGroup.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './RadioGroup.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/RadioGroup/RadioGroup.tsx b/packages/design/src/Form/components/RadioGroup/RadioGroup.tsx index 267c4ec2..663302f7 100644 --- a/packages/design/src/Form/components/RadioGroup/RadioGroup.tsx +++ b/packages/design/src/Form/components/RadioGroup/RadioGroup.tsx @@ -3,7 +3,7 @@ import { useFormContext } from 'react-hook-form'; import { type RadioGroupProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; export const RadioGroupPattern: PatternComponent = props => { const { register } = useFormContext(); diff --git a/packages/design/src/Form/components/RadioGroup/index.tsx b/packages/design/src/Form/components/RadioGroup/index.tsx index 2f25849b..14e2e9a2 100644 --- a/packages/design/src/Form/components/RadioGroup/index.tsx +++ b/packages/design/src/Form/components/RadioGroup/index.tsx @@ -1,3 +1,3 @@ -import { RadioGroupPattern } from './RadioGroup'; +import { RadioGroupPattern } from './RadioGroup.js'; export default RadioGroupPattern; diff --git a/packages/design/src/Form/components/Sequence/index.tsx b/packages/design/src/Form/components/Sequence/index.tsx index 955b4765..5e952c03 100644 --- a/packages/design/src/Form/components/Sequence/index.tsx +++ b/packages/design/src/Form/components/Sequence/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const Sequence: PatternComponent = ({ children }) => { return <>{children}; diff --git a/packages/design/src/Form/components/SubmissionConfirmation/SubmissionConfirmation.stories.tsx b/packages/design/src/Form/components/SubmissionConfirmation/SubmissionConfirmation.stories.tsx index cc64b79c..0e936d01 100644 --- a/packages/design/src/Form/components/SubmissionConfirmation/SubmissionConfirmation.stories.tsx +++ b/packages/design/src/Form/components/SubmissionConfirmation/SubmissionConfirmation.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import SubmissionConfirmation from '.'; +import SubmissionConfirmation from './index.js'; export default { title: 'patterns/SubmissionConfirmation', diff --git a/packages/design/src/Form/components/SubmissionConfirmation/index.tsx b/packages/design/src/Form/components/SubmissionConfirmation/index.tsx index ce2b8a8b..ed863d74 100644 --- a/packages/design/src/Form/components/SubmissionConfirmation/index.tsx +++ b/packages/design/src/Form/components/SubmissionConfirmation/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { type SubmissionConfirmationProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const SubmissionConfirmation: PatternComponent< SubmissionConfirmationProps diff --git a/packages/design/src/Form/components/TextInput/TestInput.stories.tsx b/packages/design/src/Form/components/TextInput/TestInput.stories.tsx index 8ae4280b..1e9b84df 100644 --- a/packages/design/src/Form/components/TextInput/TestInput.stories.tsx +++ b/packages/design/src/Form/components/TextInput/TestInput.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import type { Meta, StoryObj } from '@storybook/react'; -import TextInput from '.'; +import TextInput from './index.js'; const meta: Meta = { title: 'patterns/TextInput', diff --git a/packages/design/src/Form/components/TextInput/TestInput.test.ts b/packages/design/src/Form/components/TextInput/TestInput.test.ts index 68b3fbdd..80dd2001 100644 --- a/packages/design/src/Form/components/TextInput/TestInput.test.ts +++ b/packages/design/src/Form/components/TextInput/TestInput.test.ts @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../../test-helper'; -import meta, * as stories from './TestInput.stories'; +import { describeStories } from '../../../test-helper.js'; +import meta, * as stories from './TestInput.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/Form/components/TextInput/index.tsx b/packages/design/src/Form/components/TextInput/index.tsx index 3c3b20ec..da57726a 100644 --- a/packages/design/src/Form/components/TextInput/index.tsx +++ b/packages/design/src/Form/components/TextInput/index.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { useFormContext } from 'react-hook-form'; import { type TextInputProps } from '@atj/forms'; -import { type PatternComponent } from '../../../Form'; +import { type PatternComponent } from '../../../Form/index.js'; const TextInput: PatternComponent = props => { const { register } = useFormContext(); diff --git a/packages/design/src/Form/components/index.tsx b/packages/design/src/Form/components/index.tsx index 594c2554..6acb16fa 100644 --- a/packages/design/src/Form/components/index.tsx +++ b/packages/design/src/Form/components/index.tsx @@ -1,16 +1,16 @@ -import { PatternComponent, type ComponentForPattern } from '..'; +import { PatternComponent, type ComponentForPattern } from '../index.js'; -import Address from './Address'; -import Checkbox from './Checkbox'; -import Fieldset from './Fieldset'; -import FormSummary from './FormSummary'; -import Page from './Page'; -import PageSet from './PageSet'; -import Paragraph from './Paragraph'; -import RadioGroup from './RadioGroup'; -import Sequence from './Sequence'; -import SubmissionConfirmation from './SubmissionConfirmation'; -import TextInput from './TextInput'; +import Address from './Address/index.js'; +import Checkbox from './Checkbox/index.js'; +import Fieldset from './Fieldset/index.js'; +import FormSummary from './FormSummary/index.js'; +import Page from './Page/index.js'; +import PageSet from './PageSet/index.js'; +import Paragraph from './Paragraph/index.js'; +import RadioGroup from './RadioGroup/index.js'; +import Sequence from './Sequence/index.js'; +import SubmissionConfirmation from './SubmissionConfirmation/index.js'; +import TextInput from './TextInput/index.js'; export const defaultPatternComponents: ComponentForPattern = { address: Address as PatternComponent, diff --git a/packages/design/src/FormManager/FormDelete/FormDelete.stories.tsx b/packages/design/src/FormManager/FormDelete/FormDelete.stories.tsx index e8b3dd55..f6d6caa7 100644 --- a/packages/design/src/FormManager/FormDelete/FormDelete.stories.tsx +++ b/packages/design/src/FormManager/FormDelete/FormDelete.stories.tsx @@ -2,10 +2,10 @@ import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import type { Meta, StoryObj } from '@storybook/react'; -import { service } from '@atj/forms'; +import { createTestBrowserFormService } from '@atj/forms/context'; -import FormDelete from '.'; -import { createTwoPatternTestForm } from '../../test-form'; +import { createTwoPatternTestForm } from '../../test-form.js'; +import FormDelete from './index.js'; const meta: Meta = { title: 'FormManager/FormDelete', @@ -19,7 +19,7 @@ const meta: Meta = { ], args: { formId: 'test-form', - formService: service.createTestFormService({ + formService: createTestBrowserFormService({ 'test-form': createTwoPatternTestForm(), }), }, diff --git a/packages/design/src/FormManager/FormDelete/FormDelete.test.ts b/packages/design/src/FormManager/FormDelete/FormDelete.test.ts index 040f50aa..fa9a9976 100644 --- a/packages/design/src/FormManager/FormDelete/FormDelete.test.ts +++ b/packages/design/src/FormManager/FormDelete/FormDelete.test.ts @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describeStories } from '../../test-helper'; -import meta, * as stories from './FormDelete.stories'; +import { describeStories } from '../../test-helper.js'; +import meta, * as stories from './FormDelete.stories.js'; describeStories(meta, stories); diff --git a/packages/design/src/FormManager/FormDelete/index.tsx b/packages/design/src/FormManager/FormDelete/index.tsx index 970cbc7b..7525b492 100644 --- a/packages/design/src/FormManager/FormDelete/index.tsx +++ b/packages/design/src/FormManager/FormDelete/index.tsx @@ -1,21 +1,26 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { service } from '@atj/forms'; +import type { Blueprint, FormService } from '@atj/forms'; export default function FormDelete({ formId, formService, }: { formId: string; - formService: service.FormService; + formService: FormService; }) { const navigate = useNavigate(); - const result = formService.getForm(formId); - if (!result.success) { - return
Form {formId} not found.
; - } - const form = result.data; + const [form, setForm] = useState(null); + useEffect(() => { + formService.getForm(formId).then(result => { + if (!result.success) { + navigate('/'); + } else { + setForm(result.data); + } + }); + }, []); const deleteForm = () => { formService.deleteForm(formId); navigate('/'); @@ -25,7 +30,7 @@ export default function FormDelete({

Delete form

Are you sure you want to delete the form:{' '} - {result.data.summary.title}? + {form?.summary.title}?