From d8f85a888c92fc513a2e4cb701c085a7ab98063a Mon Sep 17 00:00:00 2001 From: Pedro Pupo Sa da Costa Date: Mon, 5 Feb 2024 17:27:42 +0000 Subject: [PATCH] refactor: move analytics and github providers --- apps/docs/tsconfig.json | 4 +- apps/e2e-web/tsconfig.json | 4 +- apps/next-app/pages/analytics/index.tsx | 38 ----- apps/next-app/pages/index.page.tsx | 2 +- .../[questionBank]/annexes/index.page.tsx | 2 +- .../[questionBank]/docs/[docId].page.tsx | 2 +- .../[questionBank]/docs/index.page.tsx | 2 +- .../flashcards/[collectionId]/[seed].page.tsx | 2 +- .../flashcards/[collectionId]/index.page.tsx | 2 +- .../[questionBank]/flashcards/index.page.tsx | 2 +- .../modules/[questionBank]/index.page.tsx | 2 +- .../[learningObjectiveId]/index.page.tsx | 2 +- .../[learningObjectiveId]/questions.page.tsx | 2 +- .../[learningObjectiveId]/tree.page.tsx | 2 +- .../learning-objectives/index.page.tsx | 2 +- .../questions/[questionId].page.tsx | 2 +- .../[questionBank]/questions/index.page.tsx | 2 +- .../[questionBank]/settings/index.page.tsx | 2 +- .../tests/[testId]/exam.page.tsx | 2 +- .../tests/[testId]/review.page.tsx | 2 +- .../tests/[testId]/study.page.tsx | 2 +- .../[questionBank]/tests/create.page.tsx | 2 +- .../[questionBank]/tests/index.page.tsx | 2 +- apps/next-app/tsconfig.json | 24 ++- libs/base/env/tsconfig.json | 1 + libs/base/errors/src/lib/question-errors.ts | 5 +- libs/base/errors/tsconfig.json | 1 + libs/base/types/.eslintrc.json | 4 - libs/base/types/src/index.ts | 14 -- libs/base/types/src/lib/analytics.ts | 36 ----- libs/base/types/src/lib/blog.ts | 10 -- libs/base/types/src/lib/question-bank.ts | 10 -- libs/base/types/src/types.d.ts | 1 - libs/base/utils/tsconfig.json | 5 +- libs/core/{app => analytics}/.eslintrc.json | 0 .../types => core/analytics}/project.json | 8 +- .../core/analytics/src/entities/page-event.ts | 23 +++ .../analytics/src/entities/track-event.ts | 27 ++++ libs/core/analytics/src/index.ts | 2 + libs/core/analytics/tsconfig.json | 8 + libs/core/app/src/index.ts | 10 -- libs/core/github/src/config/oktokit.ts | 37 ----- libs/core/github/src/entities/new-issue.ts | 10 ++ .../src/entities/question-edit.ts} | 8 +- .../github/src/functions/create-new-issue.ts | 33 ---- libs/core/github/src/index.ts | 4 +- libs/core/github/tsconfig.json | 7 +- .../{schemas => question-bank}/.eslintrc.json | 0 .../{schemas => question-bank}/project.json | 11 +- libs/core/question-bank/src/index.ts | 22 +++ .../src/questions/get-new-variant.ts | 5 +- .../src/questions/get-question-preview.ts | 4 +- .../src/questions/get-question.ts | 12 +- .../src/questions/get-questions.test.ts | 4 +- .../src/schemas/question-bank-doc-schema.ts} | 2 +- .../schemas}/question-bank-question-schema.ts | 6 +- .../src/schemas}/question-bank-schema.ts | 2 +- .../question-variant-one-two-schema.ts | 0 .../question-variant-simple-schema.ts | 0 .../question-variant-true-or-false-schema.ts | 0 .../src/tests/create-test.ts | 10 +- .../get-number-of-available-questions.ts | 2 +- .../src/tests/process-test.ts} | 2 +- .../question-bank/src/types}/ids.ts | 0 .../src/types}/question-bank-annexes.ts | 0 .../src/types}/question-bank-docs.ts | 0 .../src/types}/question-bank-flashcards.ts | 0 .../question-bank-question-templates.ts | 0 .../src/types}/question-bank-subjects.ts | 0 .../question-bank/src/types/question-bank.ts | 57 +++++++ .../question-bank/src/types}/question.ts | 0 .../src/types}/test-questions.ts | 0 .../question-bank/src/types}/test.ts | 0 libs/core/question-bank/tsconfig.json | 8 + libs/core/schemas/src/index.ts | 12 -- libs/core/schemas/tsconfig.json | 4 - libs/core/search/.eslintrc.json | 5 + libs/core/{app => search}/project.json | 8 +- libs/core/search/src/index.ts | 4 + .../src/question-bank}/annex-search.ts | 6 +- .../src/question-bank}/doc-search.ts | 4 +- .../learning-objective-search.ts | 4 +- .../src/question-bank}/question-search.ts | 6 +- .../{base/types => core/search}/tsconfig.json | 1 + libs/providers/analytics/src/analytics.ts | 32 ++++ .../src/config/postgres-connection.ts | 10 -- .../analytics/src/entities/page-event.ts | 23 +++ .../analytics/src/entities/track-event.ts | 34 ++++ .../analytics/src/functions/create-events.ts | 18 ++- .../src/functions/page-visits-analytics.ts | 81 ---------- libs/providers/analytics/src/index.ts | 6 +- libs/providers/analytics/tsconfig.json | 2 +- .../blog/executors/compile/executor.ts | 3 +- libs/providers/blog/src/blog.ts | 12 +- .../{meta-schema.ts => entities/blog-post.ts} | 12 +- libs/providers/blog/src/index.ts | 5 +- libs/providers/blog/tsconfig.json | 5 +- libs/providers/github/.eslintrc.json | 5 + libs/providers/github/project.json | 22 +++ libs/providers/github/src/common/env.ts | 22 +++ .../github/src/functions/create-new-issue.ts | 24 +++ .../src/functions/create-new-question-pr.ts | 18 ++- libs/providers/github/src/github.ts | 28 ++++ libs/providers/github/src/index.ts | 1 + .../app => providers/github}/tsconfig.json | 2 +- .../executors/compile/executor.ts | 4 +- .../executors/parse-los-xlsx/executor.ts | 2 +- .../executors}/connect-question-bank.ts | 2 +- .../parse-learning-objectives-xlsx.ts | 2 +- .../executors}/parse-question-bank.ts | 4 +- libs/providers/question-bank/src/index.ts | 11 +- .../question-bank-provider.test.ts} | 12 +- .../src/provider/question-bank-provider.ts | 111 ++++++++++++++ .../question-bank/src/question-bank.ts | 145 ------------------ libs/providers/question-bank/tsconfig.json | 7 +- libs/providers/search/.eslintrc.json | 13 ++ libs/providers/search/project.json | 22 +++ libs/providers/search/src/index.ts | 0 libs/providers/search/tsconfig.json | 8 + .../analytics/src/use-analytics-plugin.ts | 5 +- libs/react/analytics/src/use-analytics.tsx | 2 +- libs/react/analytics/tsconfig.json | 6 +- .../src/theme/theme-override-color-scheme.tsx | 3 +- libs/react/components/tsconfig.json | 11 +- .../src/annexes/annex-search/annex-search.tsx | 2 +- .../src/docs/doc-content/doc-content.tsx | 2 +- .../src/docs/doc-search/doc-search.tsx | 2 +- .../flashcard-with-own-control.tsx | 2 +- .../flashcard-collection-list.tsx | 2 +- .../flashcard-list/flashcard-list.tsx | 2 +- .../flashcard-test/flashcard-test.tsx | 2 +- .../create-use-persistence-hook.ts | 2 +- .../layouts/layout-module/layout-module.tsx | 2 +- .../learning-objective-overview.tsx | 2 +- .../learning-objective-questions.tsx | 2 +- .../learning-objective-tree.tsx | 2 +- .../learning-objectives-search.tsx | 2 +- .../overview-modules/overview-modules.tsx | 2 +- .../overview-welcome/welcome.stories.tsx | 2 +- .../overviews/overview-welcome/welcome.tsx | 2 +- .../question-overview.mock.ts | 1 + .../question-overview/question-overview.tsx | 21 ++- .../question-search/question-search.tsx | 2 +- .../src/tests/__mocks__/test-progress.mock.ts | 2 +- .../components/test-error/test-error.tsx | 2 +- .../use-test-progress/use-test-progress.ts | 2 +- .../src/tests/test-maker/test-maker.tsx | 6 +- .../src/tests/test-search/test-search.tsx | 4 +- libs/react/containers/tsconfig.json | 9 +- libs/react/games/tsconfig.json | 4 +- libs/trpc/client/tsconfig.json | 7 +- libs/trpc/mock/tsconfig.json | 2 +- libs/trpc/server/src/common/providers.ts | 17 ++ libs/trpc/server/src/common/search-indexes.ts | 2 +- libs/trpc/server/src/next/static-handler.ts | 11 +- .../src/routers/common/analytics-router.ts | 39 +---- .../server/src/routers/common/blog-router.ts | 2 +- .../src/routers/common/github-router.ts | 12 +- .../src/routers/common/search-router.ts | 20 +-- .../server/src/routers/common/tests-router.ts | 9 +- .../src/routers/containers/annexes-router.ts | 6 +- .../src/routers/containers/blog-router.ts | 2 +- .../src/routers/containers/docs-router.ts | 6 +- .../routers/containers/flashcards-router.ts | 4 +- .../src/routers/containers/layouts-router.ts | 4 +- .../containers/learning-objectives-router.ts | 6 +- .../routers/containers/overviews-router.ts | 2 +- .../routers/containers/questions-router.ts | 9 +- .../src/routers/pages/blog-pages-router.ts | 2 +- .../src/routers/pages/modules-pages-router.ts | 6 +- libs/trpc/server/tsconfig.json | 4 +- tsconfig.base.json | 9 +- types.d.ts | 20 +++ 173 files changed, 849 insertions(+), 747 deletions(-) delete mode 100644 apps/next-app/pages/analytics/index.tsx delete mode 100644 libs/base/types/.eslintrc.json delete mode 100644 libs/base/types/src/index.ts delete mode 100644 libs/base/types/src/lib/analytics.ts delete mode 100644 libs/base/types/src/lib/blog.ts delete mode 100644 libs/base/types/src/lib/question-bank.ts delete mode 100644 libs/base/types/src/types.d.ts rename libs/core/{app => analytics}/.eslintrc.json (100%) rename libs/{base/types => core/analytics}/project.json (64%) create mode 100644 libs/core/analytics/src/entities/page-event.ts create mode 100644 libs/core/analytics/src/entities/track-event.ts create mode 100644 libs/core/analytics/src/index.ts create mode 100644 libs/core/analytics/tsconfig.json delete mode 100644 libs/core/app/src/index.ts delete mode 100644 libs/core/github/src/config/oktokit.ts create mode 100644 libs/core/github/src/entities/new-issue.ts rename libs/core/{schemas/src/question-edit-schema.ts => github/src/entities/question-edit.ts} (68%) delete mode 100644 libs/core/github/src/functions/create-new-issue.ts rename libs/core/{schemas => question-bank}/.eslintrc.json (100%) rename libs/core/{schemas => question-bank}/project.json (59%) create mode 100644 libs/core/question-bank/src/index.ts rename libs/core/{app => question-bank}/src/questions/get-new-variant.ts (91%) rename libs/core/{app => question-bank}/src/questions/get-question-preview.ts (93%) rename libs/core/{app => question-bank}/src/questions/get-question.ts (97%) rename libs/core/{app => question-bank}/src/questions/get-questions.test.ts (93%) rename libs/{providers/question-bank/src/question-bank-docs-meta-schema.ts => core/question-bank/src/schemas/question-bank-doc-schema.ts} (83%) rename libs/core/{schemas/src => question-bank/src/schemas}/question-bank-question-schema.ts (78%) rename libs/core/{schemas/src => question-bank/src/schemas}/question-bank-schema.ts (95%) rename libs/core/{schemas/src => question-bank/src/schemas}/question-variant-one-two-schema.ts (100%) rename libs/core/{schemas/src => question-bank/src/schemas}/question-variant-simple-schema.ts (100%) rename libs/core/{schemas/src => question-bank/src/schemas}/question-variant-true-or-false-schema.ts (100%) rename libs/core/{app => question-bank}/src/tests/create-test.ts (88%) rename libs/core/{app => question-bank}/src/tests/get-number-of-available-questions.ts (90%) rename libs/core/{app/src/tests/process-test.tsx => question-bank/src/tests/process-test.ts} (95%) rename libs/{base/types/src/lib => core/question-bank/src/types}/ids.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/question-bank-annexes.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/question-bank-docs.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/question-bank-flashcards.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/question-bank-question-templates.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/question-bank-subjects.ts (100%) create mode 100644 libs/core/question-bank/src/types/question-bank.ts rename libs/{base/types/src/lib => core/question-bank/src/types}/question.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/test-questions.ts (100%) rename libs/{base/types/src/lib => core/question-bank/src/types}/test.ts (100%) create mode 100644 libs/core/question-bank/tsconfig.json delete mode 100644 libs/core/schemas/src/index.ts delete mode 100644 libs/core/schemas/tsconfig.json create mode 100644 libs/core/search/.eslintrc.json rename libs/core/{app => search}/project.json (65%) create mode 100644 libs/core/search/src/index.ts rename libs/core/{app/src/search => search/src/question-bank}/annex-search.ts (96%) rename libs/core/{app/src/search => search/src/question-bank}/doc-search.ts (96%) rename libs/core/{app/src/search => search/src/question-bank}/learning-objective-search.ts (97%) rename libs/core/{app/src/search => search/src/question-bank}/question-search.ts (96%) rename libs/{base/types => core/search}/tsconfig.json (69%) create mode 100644 libs/providers/analytics/src/analytics.ts delete mode 100644 libs/providers/analytics/src/config/postgres-connection.ts create mode 100644 libs/providers/analytics/src/entities/page-event.ts create mode 100644 libs/providers/analytics/src/entities/track-event.ts delete mode 100644 libs/providers/analytics/src/functions/page-visits-analytics.ts rename libs/providers/blog/src/{meta-schema.ts => entities/blog-post.ts} (59%) create mode 100644 libs/providers/github/.eslintrc.json create mode 100644 libs/providers/github/project.json create mode 100644 libs/providers/github/src/common/env.ts create mode 100644 libs/providers/github/src/functions/create-new-issue.ts rename libs/{core => providers}/github/src/functions/create-new-question-pr.ts (91%) create mode 100644 libs/providers/github/src/github.ts create mode 100644 libs/providers/github/src/index.ts rename libs/{core/app => providers/github}/tsconfig.json (69%) rename libs/providers/question-bank/{executors/common => src/executors}/connect-question-bank.ts (98%) rename libs/providers/question-bank/{executors/common => src/executors}/parse-learning-objectives-xlsx.ts (98%) rename libs/providers/question-bank/{executors/common => src/executors}/parse-question-bank.ts (98%) rename libs/providers/question-bank/src/{question-bank.test.ts => provider/question-bank-provider.test.ts} (88%) create mode 100644 libs/providers/question-bank/src/provider/question-bank-provider.ts delete mode 100644 libs/providers/question-bank/src/question-bank.ts create mode 100644 libs/providers/search/.eslintrc.json create mode 100644 libs/providers/search/project.json create mode 100644 libs/providers/search/src/index.ts create mode 100644 libs/providers/search/tsconfig.json create mode 100644 libs/trpc/server/src/common/providers.ts create mode 100644 types.d.ts diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 9d92bbfe0..ae9343aea 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -10,7 +10,7 @@ "allowSyntheticDefaultImports": true, "strict": true, "types": ["react"], - "lib": ["esnext", "dom"], + "lib": ["esnext", "dom"] }, - "files": [".storybook/preview.tsx"], + "files": [".storybook/preview.tsx"] } diff --git a/apps/e2e-web/tsconfig.json b/apps/e2e-web/tsconfig.json index ad2bb620f..87f53f8d5 100644 --- a/apps/e2e-web/tsconfig.json +++ b/apps/e2e-web/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "sourceMap": false, - "types": ["cypress", "node"], + "types": ["cypress", "node"] }, - "include": ["src/**/*.ts", "cypress.config.ts"], + "include": ["src/**/*.ts", "cypress.config.ts"] } diff --git a/apps/next-app/pages/analytics/index.tsx b/apps/next-app/pages/analytics/index.tsx deleted file mode 100644 index 6af0012c8..000000000 --- a/apps/next-app/pages/analytics/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as fs from "fs/promises"; -import { - LineChart, - Line, - CartesianGrid, - XAxis, - YAxis, - Tooltip, - Legend, -} from "recharts"; -import { trpc } from "@chair-flight/trpc/client"; -import { staticHandler } from "@chair-flight/trpc/server"; -import type { NextPage } from "next"; - -const useVisitsPerDay = trpc.common.analytics.visitsPerDay.useSuspenseQuery; - -const AnalyticsPage: NextPage = () => { - const [{ views, paths }] = useVisitsPerDay(); - return ( - - {paths.map((path) => ( - - ))} - - - - - - - ); -}; - -export const getStaticProps = staticHandler(async ({ helper }) => { - await helper.common.analytics.visitsPerDay.prefetch(); - return { props: {}, revalidate: 60 * 15 }; -}, fs); - -export default AnalyticsPage; diff --git a/apps/next-app/pages/index.page.tsx b/apps/next-app/pages/index.page.tsx index 18d9c075f..4624f53c3 100644 --- a/apps/next-app/pages/index.page.tsx +++ b/apps/next-app/pages/index.page.tsx @@ -7,7 +7,7 @@ import { } from "@chair-flight/react/components"; import { LayoutPublic, OverviewWelcome } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { NextPage } from "next"; export const Page: NextPage = () => { diff --git a/apps/next-app/pages/modules/[questionBank]/annexes/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/annexes/index.page.tsx index 7591630fa..33e95e132 100644 --- a/apps/next-app/pages/modules/[questionBank]/annexes/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/annexes/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, AnnexSearch } from "@chair-flight/react/containers"; import { staticHandler, staticPathsHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/docs/[docId].page.tsx b/apps/next-app/pages/modules/[questionBank]/docs/[docId].page.tsx index ad5d18853..d49b81990 100644 --- a/apps/next-app/pages/modules/[questionBank]/docs/[docId].page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/docs/[docId].page.tsx @@ -22,7 +22,7 @@ import { } from "@chair-flight/react/containers"; import { trpc } from "@chair-flight/trpc/client"; import { staticHandler, staticPathsHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/docs/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/docs/index.page.tsx index 7d36ef11b..201e0f066 100644 --- a/apps/next-app/pages/modules/[questionBank]/docs/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/docs/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { DocSearch, LayoutModule } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/[seed].page.tsx b/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/[seed].page.tsx index c0aab257f..da595ad4d 100644 --- a/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/[seed].page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/[seed].page.tsx @@ -2,7 +2,7 @@ import { getRandomId } from "@chair-flight/base/utils"; import { AppHead } from "@chair-flight/react/components"; import { FlashcardTest, LayoutModule } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/index.page.tsx index 9ef9f1662..a6830501e 100644 --- a/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/flashcards/[collectionId]/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { FlashcardList, LayoutModule } from "@chair-flight/react/containers"; import { staticHandler, staticPathsHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/flashcards/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/flashcards/index.page.tsx index afe1fe003..db8a6b19c 100644 --- a/apps/next-app/pages/modules/[questionBank]/flashcards/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/flashcards/index.page.tsx @@ -6,7 +6,7 @@ import { LayoutModule, } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/index.page.tsx index 30027e8dc..1a0e1efb4 100644 --- a/apps/next-app/pages/modules/[questionBank]/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, OverviewModules } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/index.page.tsx index e5c9f4ff3..31d1d32b5 100644 --- a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/index.page.tsx @@ -8,7 +8,7 @@ import { LearningObjectiveTree, } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/questions.page.tsx b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/questions.page.tsx index 0702fd464..2af4c1504 100644 --- a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/questions.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/questions.page.tsx @@ -4,7 +4,7 @@ import { LearningObjectiveQuestions, } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/tree.page.tsx b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/tree.page.tsx index ac28dea8d..8a67b69b2 100644 --- a/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/tree.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/learning-objectives/[learningObjectiveId]/tree.page.tsx @@ -4,7 +4,7 @@ import { LearningObjectiveTree, } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/learning-objectives/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/learning-objectives/index.page.tsx index d0403694c..4a0a71848 100644 --- a/apps/next-app/pages/modules/[questionBank]/learning-objectives/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/learning-objectives/index.page.tsx @@ -5,7 +5,7 @@ import { LearningObjectivesSearch, } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx b/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx index 6fa050380..15554978a 100644 --- a/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx @@ -3,7 +3,7 @@ import { getRandomId } from "@chair-flight/base/utils"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, QuestionOverview } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/questions/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/questions/index.page.tsx index 2a4a502b8..c9c030fdb 100644 --- a/apps/next-app/pages/modules/[questionBank]/questions/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/questions/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, QuestionSearch } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/settings/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/settings/index.page.tsx index 7dfd09340..392f797ff 100644 --- a/apps/next-app/pages/modules/[questionBank]/settings/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/settings/index.page.tsx @@ -3,7 +3,7 @@ import { MissingPathParameter } from "@chair-flight/base/errors"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, UserSettings } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/exam.page.tsx b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/exam.page.tsx index 8749425b9..de50b34c1 100644 --- a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/exam.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/exam.page.tsx @@ -6,7 +6,7 @@ import { } from "@chair-flight/react/components"; import { TestExam } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { NextPage } from "next"; type Props = { diff --git a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/review.page.tsx b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/review.page.tsx index bbfec2b9f..08c2102a3 100644 --- a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/review.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/review.page.tsx @@ -2,7 +2,7 @@ import { MissingPathParameter } from "@chair-flight/base/errors"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, TestReview } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/study.page.tsx b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/study.page.tsx index 3980bb423..be0b2a4e7 100644 --- a/apps/next-app/pages/modules/[questionBank]/tests/[testId]/study.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/tests/[testId]/study.page.tsx @@ -7,7 +7,7 @@ import { } from "@chair-flight/react/components"; import { TestStudy } from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { NextPage } from "next"; type Props = { diff --git a/apps/next-app/pages/modules/[questionBank]/tests/create.page.tsx b/apps/next-app/pages/modules/[questionBank]/tests/create.page.tsx index 13b5fdeb8..ec0fa5221 100644 --- a/apps/next-app/pages/modules/[questionBank]/tests/create.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/tests/create.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, TestMaker } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/pages/modules/[questionBank]/tests/index.page.tsx b/apps/next-app/pages/modules/[questionBank]/tests/index.page.tsx index 4d2a9562b..a49b622e6 100644 --- a/apps/next-app/pages/modules/[questionBank]/tests/index.page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/tests/index.page.tsx @@ -2,7 +2,7 @@ import * as fs from "node:fs/promises"; import { AppHead } from "@chair-flight/react/components"; import { LayoutModule, TestSearch } from "@chair-flight/react/containers"; import { staticHandler } from "@chair-flight/trpc/server"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { GetStaticPaths, NextPage } from "next"; diff --git a/apps/next-app/tsconfig.json b/apps/next-app/tsconfig.json index f56dee02a..a135921c9 100644 --- a/apps/next-app/tsconfig.json +++ b/apps/next-app/tsconfig.json @@ -1,26 +1,20 @@ { "extends": "../../tsconfig.base.json", + "files": ["../../types.d.ts", "index.d.ts", "next-env.d.ts"], + "include": ["pages/**/*.ts", "pages/**/*.tsx", ".next/types/**/*.ts"], "compilerOptions": { "jsx": "preserve", + "allowJs": true, + "esModuleInterop": true, "isolatedModules": true, "incremental": true, + "strictNullChecks": true, "types": ["node", "react"], "lib": ["esnext", "dom"], - "allowJs": true, - "esModuleInterop": true, "plugins": [ { - "name": "next", - }, - ], - "strictNullChecks": true, - }, - "include": [ - "index.d.ts", - "next-env.d.ts", - "pages/**/*.ts", - "pages/**/*.tsx", - ".next/types/**/*.ts", - ], - "exclude": ["node_modules"], + "name": "next" + } + ] + } } diff --git a/libs/base/env/tsconfig.json b/libs/base/env/tsconfig.json index cf5207786..de61c4fdb 100644 --- a/libs/base/env/tsconfig.json +++ b/libs/base/env/tsconfig.json @@ -1,4 +1,5 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"] } diff --git a/libs/base/errors/src/lib/question-errors.ts b/libs/base/errors/src/lib/question-errors.ts index 14f3ee014..6af7c33dc 100644 --- a/libs/base/errors/src/lib/question-errors.ts +++ b/libs/base/errors/src/lib/question-errors.ts @@ -1,11 +1,10 @@ import { DataError } from "./generic-errors"; -import type { QuestionBankQuestionTemplate } from "@chair-flight/base/types"; export class BadQuestionError extends DataError { - question: QuestionBankQuestionTemplate; + question: { id: string }; configurationParams: Record; constructor( - question: QuestionBankQuestionTemplate, + question: { id: string }, configurationParams: Record, ) { super( diff --git a/libs/base/errors/tsconfig.json b/libs/base/errors/tsconfig.json index cf5207786..de61c4fdb 100644 --- a/libs/base/errors/tsconfig.json +++ b/libs/base/errors/tsconfig.json @@ -1,4 +1,5 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"] } diff --git a/libs/base/types/.eslintrc.json b/libs/base/types/.eslintrc.json deleted file mode 100644 index 5c8c45852..000000000 --- a/libs/base/types/.eslintrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": ["../../../.eslintrc.json"], - "ignorePatterns": ["!**/*"] -} diff --git a/libs/base/types/src/index.ts b/libs/base/types/src/index.ts deleted file mode 100644 index 4e5fc8381..000000000 --- a/libs/base/types/src/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import "./types.d.ts"; - -export * from "./lib/blog"; -export * from "./lib/analytics"; -export * from "./lib/ids"; -export * from "./lib/question"; -export * from "./lib/question-bank"; -export * from "./lib/question-bank-annexes"; -export * from "./lib/question-bank-docs"; -export * from "./lib/question-bank-flashcards"; -export * from "./lib/question-bank-question-templates"; -export * from "./lib/question-bank-subjects"; -export * from "./lib/test"; -export * from "./lib/test-questions"; diff --git a/libs/base/types/src/lib/analytics.ts b/libs/base/types/src/lib/analytics.ts deleted file mode 100644 index 016b3df90..000000000 --- a/libs/base/types/src/lib/analytics.ts +++ /dev/null @@ -1,36 +0,0 @@ -export type PageEvent = { - anonymousId: string; - title: string; - path: string; - resolvedPath: string; - height: number; - width: number; - referrer?: string; - timestamp: number; -}; - -export type TrackEvent = { - eventName: T; - anonymousId: string; - timestamp: number; - path: string; - resolvedPath: string; - properties: TrackEventPayload; -}; - -export type SimplifiedTrackEvent = { - eventName: string; - anonymousId: string; - timestamp: number; - path: string; - resolvedPath: string; - properties: Record; -}; - -export type TrackEventMap = { - "themeButton.switch": Record; -}; - -export type TrackEventName = keyof TrackEventMap; - -export type TrackEventPayload = TrackEventMap[T]; diff --git a/libs/base/types/src/lib/blog.ts b/libs/base/types/src/lib/blog.ts deleted file mode 100644 index 0556f1994..000000000 --- a/libs/base/types/src/lib/blog.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type BlogPost = { - title: string; - filename: string; - description: string; - author: string; - date: string; - imageUrl: string | null; - content: string; - tag: "Technical" | "Feature" | "Content"; -}; diff --git a/libs/base/types/src/lib/question-bank.ts b/libs/base/types/src/lib/question-bank.ts deleted file mode 100644 index 522de0868..000000000 --- a/libs/base/types/src/lib/question-bank.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type QuestionBankName = "type" | "atpl" | "prep"; - -export type QuestionBankResource = - | "questions" - | "learningObjectives" - | "annexes" - | "flashcards" - | "courses" - | "subjects" - | "docs"; diff --git a/libs/base/types/src/types.d.ts b/libs/base/types/src/types.d.ts deleted file mode 100644 index a3d4a031b..000000000 --- a/libs/base/types/src/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -import "@total-typescript/ts-reset"; diff --git a/libs/base/utils/tsconfig.json b/libs/base/utils/tsconfig.json index 0635630f1..cdde824ae 100644 --- a/libs/base/utils/tsconfig.json +++ b/libs/base/utils/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"], "compilerOptions": { - "types": ["vitest/globals"], - }, + "types": ["vitest/globals"] + } } diff --git a/libs/core/app/.eslintrc.json b/libs/core/analytics/.eslintrc.json similarity index 100% rename from libs/core/app/.eslintrc.json rename to libs/core/analytics/.eslintrc.json diff --git a/libs/base/types/project.json b/libs/core/analytics/project.json similarity index 64% rename from libs/base/types/project.json rename to libs/core/analytics/project.json index 2db4e1117..a99eb36f4 100644 --- a/libs/base/types/project.json +++ b/libs/core/analytics/project.json @@ -1,20 +1,20 @@ { - "name": "base-types", + "name": "core-analytics", "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/base/types/src", + "sourceRoot": "libs/core/analytics/src", "projectType": "library", "targets": { "lint": { "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["libs/base/types/**/*.ts"] + "lintFilePatterns": ["libs/core/analytics/**/*.ts"] } }, "typecheck": { "executor": "nx:run-commands", "options": { - "commands": ["tsc -p libs/base/types/tsconfig.json"] + "commands": ["tsc -p libs/core/analytics/tsconfig.json"] } } }, diff --git a/libs/core/analytics/src/entities/page-event.ts b/libs/core/analytics/src/entities/page-event.ts new file mode 100644 index 000000000..0d1102a1c --- /dev/null +++ b/libs/core/analytics/src/entities/page-event.ts @@ -0,0 +1,23 @@ +import { z } from "zod"; + +export type PageEvent = { + anonymousId: string; + title: string; + path: string; + resolvedPath: string; + height: number; + width: number; + referrer?: string; + timestamp: number; +}; + +export const PageEventSchema: z.ZodSchema = z.object({ + anonymousId: z.string(), + title: z.string(), + path: z.string(), + resolvedPath: z.string(), + height: z.number(), + width: z.number(), + referrer: z.string().optional(), + timestamp: z.number(), +}); diff --git a/libs/core/analytics/src/entities/track-event.ts b/libs/core/analytics/src/entities/track-event.ts new file mode 100644 index 000000000..a1e6aa56f --- /dev/null +++ b/libs/core/analytics/src/entities/track-event.ts @@ -0,0 +1,27 @@ +import { z } from "zod"; + +type TrackEventMap = { + "themeButton.switch": Record; +}; + +type TrackEventBase = { + eventName: T; + anonymousId: string; + timestamp: number; + path: string; + resolvedPath: string; + properties: TrackEventMap[T]; +}; + +export type TrackEvent = TrackEventBase; +export type TrackEventName = TrackEvent["eventName"]; +export type TrackEventPayload = TrackEventMap[T]; + +export const TrackEventSchema: z.ZodSchema = z.object({ + eventName: z.string(), + anonymousId: z.string(), + path: z.string(), + resolvedPath: z.string(), + timestamp: z.number(), + properties: z.object({}).passthrough(), +}) as unknown as z.ZodSchema; diff --git a/libs/core/analytics/src/index.ts b/libs/core/analytics/src/index.ts new file mode 100644 index 000000000..c8c8a5b76 --- /dev/null +++ b/libs/core/analytics/src/index.ts @@ -0,0 +1,2 @@ +export * from "./entities/page-event"; +export * from "./entities/track-event"; diff --git a/libs/core/analytics/tsconfig.json b/libs/core/analytics/tsconfig.json new file mode 100644 index 000000000..cdde824ae --- /dev/null +++ b/libs/core/analytics/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"], + "compilerOptions": { + "types": ["vitest/globals"] + } +} diff --git a/libs/core/app/src/index.ts b/libs/core/app/src/index.ts deleted file mode 100644 index 02c475b6f..000000000 --- a/libs/core/app/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from "./questions/get-new-variant"; -export * from "./questions/get-question"; -export * from "./questions/get-question-preview"; -export * from "./tests/create-test"; -export * from "./tests/process-test"; -export * from "./tests/get-number-of-available-questions"; -export * from "./search/learning-objective-search"; -export * from "./search/question-search"; -export * from "./search/annex-search"; -export * from "./search/doc-search"; diff --git a/libs/core/github/src/config/oktokit.ts b/libs/core/github/src/config/oktokit.ts deleted file mode 100644 index ec9af64cf..000000000 --- a/libs/core/github/src/config/oktokit.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Octokit } from "octokit"; -import { - getEnvVariableOrDefault, - getEnvVariableOrThrow, -} from "@chair-flight/base/env"; - -let octokit: Octokit; - -export const getOctokit = (): { - octokit: Octokit; - originOwner: string; - originRepo: string; - upstreamOwner: string; - upstreamRepo: string; -} => { - if (!octokit) { - octokit = new Octokit({ - auth: getEnvVariableOrThrow("PROVIDER_GITHUB_TOKEN"), - }); - } - const upstreamOwner = getEnvVariableOrThrow( - "PROVIDER_GITHUB_PROJECT_UPSTREAM_OWNER", - ); - const upstreamRepo = getEnvVariableOrThrow( - "PROVIDER_GITHUB_PROJECT_UPSTREAM_REPO", - ); - const originOwner = getEnvVariableOrDefault( - "PROVIDER_GITHUB_PROJECT_ORIGIN_OWNER", - upstreamOwner, - ); - const originRepo = getEnvVariableOrDefault( - "PROVIDER_GITHUB_PROJECT_ORIGIN_REPO", - upstreamRepo, - ); - - return { octokit, originOwner, originRepo, upstreamOwner, upstreamRepo }; -}; diff --git a/libs/core/github/src/entities/new-issue.ts b/libs/core/github/src/entities/new-issue.ts new file mode 100644 index 000000000..1f24cf461 --- /dev/null +++ b/libs/core/github/src/entities/new-issue.ts @@ -0,0 +1,10 @@ +import { z } from "zod"; + +export const newIssueSchema = z.object({ + title: z.string().min(5).max(50), + description: z.string().min(10).max(1000), + debugData: z.record(z.unknown()), + href: z.string(), +}); + +export type NewIssue = z.infer; diff --git a/libs/core/schemas/src/question-edit-schema.ts b/libs/core/github/src/entities/question-edit.ts similarity index 68% rename from libs/core/schemas/src/question-edit-schema.ts rename to libs/core/github/src/entities/question-edit.ts index 12e44f920..209616827 100644 --- a/libs/core/schemas/src/question-edit-schema.ts +++ b/libs/core/github/src/entities/question-edit.ts @@ -1,6 +1,8 @@ import { z } from "zod"; -import { questionBankQuestionSchema } from "./question-bank-question-schema"; -import { questionBankNameSchema } from "./question-bank-schema"; +import { + questionBankQuestionSchema, + questionBankNameSchema, +} from "@chair-flight/core/question-bank"; export const questionEditSchema = z.object({ question: questionBankQuestionSchema, @@ -12,3 +14,5 @@ export const questionEditSchema = z.object({ description: z.string(), }), }); + +export type QuestionEdit = z.infer; diff --git a/libs/core/github/src/functions/create-new-issue.ts b/libs/core/github/src/functions/create-new-issue.ts deleted file mode 100644 index 641407559..000000000 --- a/libs/core/github/src/functions/create-new-issue.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { z } from "zod"; -import { getOctokit } from "../config/oktokit"; - -export const newIssueSchema = z.object({ - title: z.string().min(5).max(50), - description: z.string().min(10).max(1000), - debugData: z.record(z.unknown()), - href: z.string(), -}); - -export const createNewIssue = async ( - schema: z.infer, -) => { - const { title, description, debugData, href } = schema; - const { octokit, originOwner, originRepo } = getOctokit(); - - const response = await octokit.rest.issues.create({ - owner: originOwner, - repo: originRepo, - title: `[App Bug Report] ${title}`, - body: [ - `## Data\n`, - `**href** : ${href}\n`, - "```", - JSON.stringify(debugData, null, 2), - "```", - `\n\n---\n\n## Description\n`, - description, - ].join("\n"), - }); - - return { url: response.data.html_url }; -}; diff --git a/libs/core/github/src/index.ts b/libs/core/github/src/index.ts index 8b4ca7e9f..8ecbca761 100644 --- a/libs/core/github/src/index.ts +++ b/libs/core/github/src/index.ts @@ -1,2 +1,2 @@ -export { createNewIssue, newIssueSchema } from "./functions/create-new-issue"; -export { createNewQuestionPr } from "./functions/create-new-question-pr"; +export * from "./entities/new-issue"; +export * from "./entities/question-edit"; diff --git a/libs/core/github/tsconfig.json b/libs/core/github/tsconfig.json index b25d09e31..cdde824ae 100644 --- a/libs/core/github/tsconfig.json +++ b/libs/core/github/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "types": ["node"], - }, "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"], + "compilerOptions": { + "types": ["vitest/globals"] + } } diff --git a/libs/core/schemas/.eslintrc.json b/libs/core/question-bank/.eslintrc.json similarity index 100% rename from libs/core/schemas/.eslintrc.json rename to libs/core/question-bank/.eslintrc.json diff --git a/libs/core/schemas/project.json b/libs/core/question-bank/project.json similarity index 59% rename from libs/core/schemas/project.json rename to libs/core/question-bank/project.json index 44dddffb7..beb910bee 100644 --- a/libs/core/schemas/project.json +++ b/libs/core/question-bank/project.json @@ -1,23 +1,22 @@ { - "name": "core-schemas", + "name": "core-question-bank", "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/core/schemas/src", + "sourceRoot": "libs/core/question-bank/src", "projectType": "library", "targets": { "lint": { "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["libs/core/schemas/**/*.ts"] + "lintFilePatterns": ["libs/core/question-bank/**/*.ts"] } }, "typecheck": { "executor": "nx:run-commands", "options": { - "commands": ["tsc -p libs/core/schemas/tsconfig.json"] + "commands": ["tsc -p libs/core/question-bank/tsconfig.json"] } } }, - "tags": [], - "implicitDependencies": [] + "tags": [] } diff --git a/libs/core/question-bank/src/index.ts b/libs/core/question-bank/src/index.ts new file mode 100644 index 000000000..c046ec963 --- /dev/null +++ b/libs/core/question-bank/src/index.ts @@ -0,0 +1,22 @@ +export * from "./questions/get-new-variant"; +export * from "./questions/get-question"; +export * from "./questions/get-question-preview"; +export * from "./schemas/question-bank-doc-schema"; +export * from "./schemas/question-bank-schema"; +export * from "./schemas/question-bank-question-schema"; +export * from "./schemas/question-variant-one-two-schema"; +export * from "./schemas/question-variant-simple-schema"; +export * from "./schemas/question-variant-true-or-false-schema"; +export * from "./tests/create-test"; +export * from "./tests/process-test"; +export * from "./tests/get-number-of-available-questions"; +export * from "./types/ids"; +export * from "./types/question"; +export * from "./types/question-bank"; +export * from "./types/question-bank-annexes"; +export * from "./types/question-bank-docs"; +export * from "./types/question-bank-flashcards"; +export * from "./types/question-bank-question-templates"; +export * from "./types/question-bank-subjects"; +export * from "./types/test"; +export * from "./types/test-questions"; diff --git a/libs/core/app/src/questions/get-new-variant.ts b/libs/core/question-bank/src/questions/get-new-variant.ts similarity index 91% rename from libs/core/app/src/questions/get-new-variant.ts rename to libs/core/question-bank/src/questions/get-new-variant.ts index e2a83b094..d34d5e9c6 100644 --- a/libs/core/app/src/questions/get-new-variant.ts +++ b/libs/core/question-bank/src/questions/get-new-variant.ts @@ -1,9 +1,6 @@ import { UnimplementedError } from "@chair-flight/base/errors"; import { getRandomId } from "@chair-flight/base/utils"; -import type { - QuestionVariant, - QuestionVariantType, -} from "@chair-flight/base/types"; +import type { QuestionVariant, QuestionVariantType } from "../types/question"; export const getNewVariant = (type: QuestionVariantType): QuestionVariant => { const common = { diff --git a/libs/core/app/src/questions/get-question-preview.ts b/libs/core/question-bank/src/questions/get-question-preview.ts similarity index 93% rename from libs/core/app/src/questions/get-question-preview.ts rename to libs/core/question-bank/src/questions/get-question-preview.ts index f8160dd41..32c2e5dfa 100644 --- a/libs/core/app/src/questions/get-question-preview.ts +++ b/libs/core/question-bank/src/questions/get-question-preview.ts @@ -1,10 +1,10 @@ import type { - QuestionBankQuestionTemplate, QuestionVariant, QuestionVariantOneTwo, QuestionVariantSimple, QuestionVariantTrueOrFalse, -} from "@chair-flight/base/types"; +} from "../types/question"; +import type { QuestionBankQuestionTemplate } from "../types/question-bank-question-templates"; const getQuestionVariantSimplePreview = ( variant: QuestionVariantSimple, diff --git a/libs/core/app/src/questions/get-question.ts b/libs/core/question-bank/src/questions/get-question.ts similarity index 97% rename from libs/core/app/src/questions/get-question.ts rename to libs/core/question-bank/src/questions/get-question.ts index a445a426e..87c7ddf43 100644 --- a/libs/core/app/src/questions/get-question.ts +++ b/libs/core/question-bank/src/questions/get-question.ts @@ -5,15 +5,17 @@ import { getRandomShuffler, } from "@chair-flight/base/utils"; import type { - TestQuestion, - TestQuestionMultipleChoice, - QuestionBankQuestionTemplate, - TestQuestionType, QuestionVariantCalculation, QuestionVariantOneTwo, QuestionVariantSimple, QuestionVariantTrueOrFalse, -} from "@chair-flight/base/types"; +} from "../types/question"; +import type { QuestionBankQuestionTemplate } from "../types/question-bank-question-templates"; +import type { + TestQuestion, + TestQuestionMultipleChoice, + TestQuestionType, +} from "../types/test-questions"; const getQuestionMultipleChoiceFromSimple = ({ template, diff --git a/libs/core/app/src/questions/get-questions.test.ts b/libs/core/question-bank/src/questions/get-questions.test.ts similarity index 93% rename from libs/core/app/src/questions/get-questions.test.ts rename to libs/core/question-bank/src/questions/get-questions.test.ts index 94f965bc6..6120c16cf 100644 --- a/libs/core/app/src/questions/get-questions.test.ts +++ b/libs/core/question-bank/src/questions/get-questions.test.ts @@ -1,8 +1,8 @@ import { getQuestion } from "./get-question"; -import type { QuestionBankQuestionTemplate } from "@chair-flight/base/types"; +import type { QuestionBankQuestionTemplate } from "../types/question-bank-question-templates"; describe("getQuestions", () => { - it("generates a one two question idempotently", () => { + it("generates a one two idempotent question", () => { const questionTemplate: QuestionBankQuestionTemplate = { srcLocation: "...", id: "QYFPA3CY4E", diff --git a/libs/providers/question-bank/src/question-bank-docs-meta-schema.ts b/libs/core/question-bank/src/schemas/question-bank-doc-schema.ts similarity index 83% rename from libs/providers/question-bank/src/question-bank-docs-meta-schema.ts rename to libs/core/question-bank/src/schemas/question-bank-doc-schema.ts index 83a5d5914..83d2cd15d 100644 --- a/libs/providers/question-bank/src/question-bank-docs-meta-schema.ts +++ b/libs/core/question-bank/src/schemas/question-bank-doc-schema.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import type { QuestionBankDoc } from "@chair-flight/base/types"; +import type { QuestionBankDoc } from "../types/question-bank-docs"; export const QuestionBankDocSchema: z.ZodSchema = z.object({ id: z.string(), diff --git a/libs/core/schemas/src/question-bank-question-schema.ts b/libs/core/question-bank/src/schemas/question-bank-question-schema.ts similarity index 78% rename from libs/core/schemas/src/question-bank-question-schema.ts rename to libs/core/question-bank/src/schemas/question-bank-question-schema.ts index e457c0f54..96f37d773 100644 --- a/libs/core/schemas/src/question-bank-question-schema.ts +++ b/libs/core/question-bank/src/schemas/question-bank-question-schema.ts @@ -2,9 +2,9 @@ import { z } from "zod"; import { questionOneTwoSchema } from "./question-variant-one-two-schema"; import { questionSimpleSchema } from "./question-variant-simple-schema"; import { questionTrueOrFalseSchema } from "./question-variant-true-or-false-schema"; -import type { QuestionBankQuestionTemplate } from "@chair-flight/base/types"; +import type { QuestionBankQuestionTemplate } from "../types/question-bank-question-templates"; -export const LearningObjectiveId = z.string(); +export const LearningObjectiveIdSchema = z.string(); export const questionVariantSchema = z.discriminatedUnion("type", [ questionSimpleSchema, @@ -15,7 +15,7 @@ export const questionVariantSchema = z.discriminatedUnion("type", [ export const questionBankQuestionSchema: z.ZodType = z.object({ id: z.string(), - learningObjectives: LearningObjectiveId.array(), + learningObjectives: LearningObjectiveIdSchema.array(), explanation: z.string(), srcLocation: z.string(), variants: z diff --git a/libs/core/schemas/src/question-bank-schema.ts b/libs/core/question-bank/src/schemas/question-bank-schema.ts similarity index 95% rename from libs/core/schemas/src/question-bank-schema.ts rename to libs/core/question-bank/src/schemas/question-bank-schema.ts index 1c694cc84..6ef88b713 100644 --- a/libs/core/schemas/src/question-bank-schema.ts +++ b/libs/core/question-bank/src/schemas/question-bank-schema.ts @@ -3,7 +3,7 @@ import { assertType, type IsEqual } from "@chair-flight/base/utils"; import type { QuestionBankName, QuestionBankResource, -} from "@chair-flight/base/types"; +} from "../types/question-bank"; export const questionBankNameSchema = z.enum(["type", "atpl", "prep"]); diff --git a/libs/core/schemas/src/question-variant-one-two-schema.ts b/libs/core/question-bank/src/schemas/question-variant-one-two-schema.ts similarity index 100% rename from libs/core/schemas/src/question-variant-one-two-schema.ts rename to libs/core/question-bank/src/schemas/question-variant-one-two-schema.ts diff --git a/libs/core/schemas/src/question-variant-simple-schema.ts b/libs/core/question-bank/src/schemas/question-variant-simple-schema.ts similarity index 100% rename from libs/core/schemas/src/question-variant-simple-schema.ts rename to libs/core/question-bank/src/schemas/question-variant-simple-schema.ts diff --git a/libs/core/schemas/src/question-variant-true-or-false-schema.ts b/libs/core/question-bank/src/schemas/question-variant-true-or-false-schema.ts similarity index 100% rename from libs/core/schemas/src/question-variant-true-or-false-schema.ts rename to libs/core/question-bank/src/schemas/question-variant-true-or-false-schema.ts diff --git a/libs/core/app/src/tests/create-test.ts b/libs/core/question-bank/src/tests/create-test.ts similarity index 88% rename from libs/core/app/src/tests/create-test.ts rename to libs/core/question-bank/src/tests/create-test.ts index 43f6f007c..d7c940c3e 100644 --- a/libs/core/app/src/tests/create-test.ts +++ b/libs/core/question-bank/src/tests/create-test.ts @@ -4,13 +4,11 @@ import { getRandomIdGenerator, getRandomShuffler, } from "@chair-flight/base/utils"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; import { getQuestion } from "../questions/get-question"; -import type { - QuestionBankName, - QuestionBankQuestionTemplate, - Test, -} from "@chair-flight/base/types"; +import { questionBankNameSchema } from "../schemas/question-bank-schema"; +import type { QuestionBankName } from "../types/question-bank"; +import type { QuestionBankQuestionTemplate } from "../types/question-bank-question-templates"; +import type { Test } from "../types/test"; export type NewTestConfiguration = { mode: "study" | "exam"; diff --git a/libs/core/app/src/tests/get-number-of-available-questions.ts b/libs/core/question-bank/src/tests/get-number-of-available-questions.ts similarity index 90% rename from libs/core/app/src/tests/get-number-of-available-questions.ts rename to libs/core/question-bank/src/tests/get-number-of-available-questions.ts index 2e6f8c60f..ebcb1b5e9 100644 --- a/libs/core/app/src/tests/get-number-of-available-questions.ts +++ b/libs/core/question-bank/src/tests/get-number-of-available-questions.ts @@ -1,4 +1,4 @@ -import type { LearningObjectiveId } from "@chair-flight/base/types"; +import type { LearningObjectiveId } from "../types/ids"; export const getNumberOfAvailableQuestions = ( subject: { diff --git a/libs/core/app/src/tests/process-test.tsx b/libs/core/question-bank/src/tests/process-test.ts similarity index 95% rename from libs/core/app/src/tests/process-test.tsx rename to libs/core/question-bank/src/tests/process-test.ts index 7532c41c7..8a9cfc5ca 100644 --- a/libs/core/app/src/tests/process-test.tsx +++ b/libs/core/question-bank/src/tests/process-test.ts @@ -1,5 +1,5 @@ import { DateTime, Duration } from "luxon"; -import type { Test } from "@chair-flight/base/types"; +import type { Test } from "../types/test"; const getClockTime = (milliseconds: number) => { const duration = Duration.fromMillis(milliseconds); diff --git a/libs/base/types/src/lib/ids.ts b/libs/core/question-bank/src/types/ids.ts similarity index 100% rename from libs/base/types/src/lib/ids.ts rename to libs/core/question-bank/src/types/ids.ts diff --git a/libs/base/types/src/lib/question-bank-annexes.ts b/libs/core/question-bank/src/types/question-bank-annexes.ts similarity index 100% rename from libs/base/types/src/lib/question-bank-annexes.ts rename to libs/core/question-bank/src/types/question-bank-annexes.ts diff --git a/libs/base/types/src/lib/question-bank-docs.ts b/libs/core/question-bank/src/types/question-bank-docs.ts similarity index 100% rename from libs/base/types/src/lib/question-bank-docs.ts rename to libs/core/question-bank/src/types/question-bank-docs.ts diff --git a/libs/base/types/src/lib/question-bank-flashcards.ts b/libs/core/question-bank/src/types/question-bank-flashcards.ts similarity index 100% rename from libs/base/types/src/lib/question-bank-flashcards.ts rename to libs/core/question-bank/src/types/question-bank-flashcards.ts diff --git a/libs/base/types/src/lib/question-bank-question-templates.ts b/libs/core/question-bank/src/types/question-bank-question-templates.ts similarity index 100% rename from libs/base/types/src/lib/question-bank-question-templates.ts rename to libs/core/question-bank/src/types/question-bank-question-templates.ts diff --git a/libs/base/types/src/lib/question-bank-subjects.ts b/libs/core/question-bank/src/types/question-bank-subjects.ts similarity index 100% rename from libs/base/types/src/lib/question-bank-subjects.ts rename to libs/core/question-bank/src/types/question-bank-subjects.ts diff --git a/libs/core/question-bank/src/types/question-bank.ts b/libs/core/question-bank/src/types/question-bank.ts new file mode 100644 index 000000000..37830b850 --- /dev/null +++ b/libs/core/question-bank/src/types/question-bank.ts @@ -0,0 +1,57 @@ +import type { QuestionBankAnnexes } from "./question-bank-annexes"; +import type { QuestionBankDoc } from "./question-bank-docs"; +import type { QuestionBankFlashcardCollection } from "./question-bank-flashcards"; +import type { QuestionBankQuestionTemplate } from "./question-bank-question-templates"; +import type { + QuestionBankCourse, + QuestionBankLearningObjective, + QuestionBankSubject, +} from "./question-bank-subjects"; + +export type QuestionBankName = "type" | "atpl" | "prep"; + +export type QuestionBankResource = + | "questions" + | "learningObjectives" + | "annexes" + | "flashcards" + | "courses" + | "subjects" + | "docs"; + +export type QuestionBankNameToType = { + questions: QuestionBankQuestionTemplate; + learningObjectives: QuestionBankLearningObjective; + annexes: QuestionBankAnnexes; + flashcards: QuestionBankFlashcardCollection; + subjects: QuestionBankSubject; + courses: QuestionBankCourse; + docs: QuestionBankDoc; +}; + +export type QuestionBankResourceArrays = { + [K in QuestionBankResource]: QuestionBankNameToType[K][] | undefined; +}; + +export type QuestionBankResourceMaps = { + [K in QuestionBankResource]: + | Record + | undefined; +}; + +export interface QuestionBankProvider { + getName: () => QuestionBankName; + has: (r: QuestionBankResource) => Promise; + getAll: ( + r: T, + ) => Promise; + getSome: ( + r: T, + id: string[], + ) => Promise; + getOne: ( + r: T, + id: string, + ) => Promise; + preloadForStaticRender: (fs: MiniFs) => Promise; +} diff --git a/libs/base/types/src/lib/question.ts b/libs/core/question-bank/src/types/question.ts similarity index 100% rename from libs/base/types/src/lib/question.ts rename to libs/core/question-bank/src/types/question.ts diff --git a/libs/base/types/src/lib/test-questions.ts b/libs/core/question-bank/src/types/test-questions.ts similarity index 100% rename from libs/base/types/src/lib/test-questions.ts rename to libs/core/question-bank/src/types/test-questions.ts diff --git a/libs/base/types/src/lib/test.ts b/libs/core/question-bank/src/types/test.ts similarity index 100% rename from libs/base/types/src/lib/test.ts rename to libs/core/question-bank/src/types/test.ts diff --git a/libs/core/question-bank/tsconfig.json b/libs/core/question-bank/tsconfig.json new file mode 100644 index 000000000..cdde824ae --- /dev/null +++ b/libs/core/question-bank/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"], + "compilerOptions": { + "types": ["vitest/globals"] + } +} diff --git a/libs/core/schemas/src/index.ts b/libs/core/schemas/src/index.ts deleted file mode 100644 index 4da3ce190..000000000 --- a/libs/core/schemas/src/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export { - questionBankNameSchema, - questionBankResourceSchema, -} from "./question-bank-schema"; -export { questionEditSchema } from "./question-edit-schema"; -export { - questionBankQuestionSchema, - questionVariantSchema, -} from "./question-bank-question-schema"; -export { questionOneTwoSchema } from "./question-variant-one-two-schema"; -export { questionSimpleSchema } from "./question-variant-simple-schema"; -export { questionTrueOrFalseSchema } from "./question-variant-true-or-false-schema"; diff --git a/libs/core/schemas/tsconfig.json b/libs/core/schemas/tsconfig.json deleted file mode 100644 index cf5207786..000000000 --- a/libs/core/schemas/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "include": ["src/**/*.ts"], -} diff --git a/libs/core/search/.eslintrc.json b/libs/core/search/.eslintrc.json new file mode 100644 index 000000000..8ba3202ba --- /dev/null +++ b/libs/core/search/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [] +} diff --git a/libs/core/app/project.json b/libs/core/search/project.json similarity index 65% rename from libs/core/app/project.json rename to libs/core/search/project.json index 5e3751103..e8f086caa 100644 --- a/libs/core/app/project.json +++ b/libs/core/search/project.json @@ -1,20 +1,20 @@ { - "name": "core-app", + "name": "core-search", "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/core/app/src", + "sourceRoot": "libs/core/search/src", "projectType": "library", "targets": { "lint": { "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["libs/core/app/**/*.ts"] + "lintFilePatterns": ["libs/core/search/**/*.ts"] } }, "typecheck": { "executor": "nx:run-commands", "options": { - "commands": ["tsc -p libs/core/app/tsconfig.json"] + "commands": ["tsc -p libs/core/search/tsconfig.json"] } } }, diff --git a/libs/core/search/src/index.ts b/libs/core/search/src/index.ts new file mode 100644 index 000000000..99b5dfd80 --- /dev/null +++ b/libs/core/search/src/index.ts @@ -0,0 +1,4 @@ +export * from "./question-bank/learning-objective-search"; +export * from "./question-bank/question-search"; +export * from "./question-bank/annex-search"; +export * from "./question-bank/doc-search"; diff --git a/libs/core/app/src/search/annex-search.ts b/libs/core/search/src/question-bank/annex-search.ts similarity index 96% rename from libs/core/app/src/search/annex-search.ts rename to libs/core/search/src/question-bank/annex-search.ts index c7f1ff87b..d9cf2b501 100644 --- a/libs/core/app/src/search/annex-search.ts +++ b/libs/core/search/src/question-bank/annex-search.ts @@ -1,12 +1,12 @@ import { z } from "zod"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; import type { AnnexId, + LearningObjectiveId, QuestionBankName, QuestionId, SubjectId, - LearningObjectiveId, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { QuestionBank } from "@chair-flight/providers/question-bank"; import type { default as MiniSearch, SearchOptions } from "minisearch"; diff --git a/libs/core/app/src/search/doc-search.ts b/libs/core/search/src/question-bank/doc-search.ts similarity index 96% rename from libs/core/app/src/search/doc-search.ts rename to libs/core/search/src/question-bank/doc-search.ts index 86bab09a1..5d372dc30 100644 --- a/libs/core/app/src/search/doc-search.ts +++ b/libs/core/search/src/question-bank/doc-search.ts @@ -1,11 +1,11 @@ import { z } from "zod"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; import type { DocId, QuestionBankName, SubjectId, LearningObjectiveId, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { QuestionBank } from "@chair-flight/providers/question-bank"; import type { default as MiniSearch, SearchOptions } from "minisearch"; diff --git a/libs/core/app/src/search/learning-objective-search.ts b/libs/core/search/src/question-bank/learning-objective-search.ts similarity index 97% rename from libs/core/app/src/search/learning-objective-search.ts rename to libs/core/search/src/question-bank/learning-objective-search.ts index 66bdf2fb4..4c504ce02 100644 --- a/libs/core/app/src/search/learning-objective-search.ts +++ b/libs/core/search/src/question-bank/learning-objective-search.ts @@ -1,12 +1,12 @@ import { z } from "zod"; import { makeMap } from "@chair-flight/base/utils"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; import type { CourseId, LearningObjectiveId, QuestionBankName, SubjectId, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { QuestionBank } from "@chair-flight/providers/question-bank"; import type { default as MiniSearch, SearchOptions } from "minisearch"; diff --git a/libs/core/app/src/search/question-search.ts b/libs/core/search/src/question-bank/question-search.ts similarity index 96% rename from libs/core/app/src/search/question-search.ts rename to libs/core/search/src/question-bank/question-search.ts index 80d577a02..d1acea492 100644 --- a/libs/core/app/src/search/question-search.ts +++ b/libs/core/search/src/question-bank/question-search.ts @@ -1,12 +1,12 @@ import { z } from "zod"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { getQuestionPreview } from "../questions/get-question-preview"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { getQuestionPreview } from "@chair-flight/core/question-bank"; import type { QuestionBankName, QuestionId, QuestionVariantId, SubjectId, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { QuestionBank } from "@chair-flight/providers/question-bank"; import type { default as MiniSearch, SearchOptions } from "minisearch"; diff --git a/libs/base/types/tsconfig.json b/libs/core/search/tsconfig.json similarity index 69% rename from libs/base/types/tsconfig.json rename to libs/core/search/tsconfig.json index cf5207786..de61c4fdb 100644 --- a/libs/base/types/tsconfig.json +++ b/libs/core/search/tsconfig.json @@ -1,4 +1,5 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"] } diff --git a/libs/providers/analytics/src/analytics.ts b/libs/providers/analytics/src/analytics.ts new file mode 100644 index 000000000..16de60cca --- /dev/null +++ b/libs/providers/analytics/src/analytics.ts @@ -0,0 +1,32 @@ +import { PrismaClient } from "@prisma/client"; +import { getEnvVariableOrThrow } from "@chair-flight/base/env"; +import { createPageEvent, createTrackEvent } from "./functions/create-events"; +import type { PageEvent } from "./entities/page-event"; +import type { TrackEvent } from "./entities/track-event"; + +interface AnalyticsProvider { + createPageEvent: (event: PageEvent) => Promise; + createTrackEvent: (event: TrackEvent) => Promise; +} + +export class Analytics implements AnalyticsProvider { + private prisma: PrismaClient; + + constructor() { + this.prisma = new PrismaClient({ + datasources: { + db: { + url: getEnvVariableOrThrow("PROVIDER_POSTGRES_ANALYTICS_PRISMA_URL"), + }, + }, + }); + } + + async createPageEvent(event: PageEvent) { + return createPageEvent(this.prisma, event); + } + + async createTrackEvent(event: TrackEvent) { + return createTrackEvent(this.prisma, event); + } +} diff --git a/libs/providers/analytics/src/config/postgres-connection.ts b/libs/providers/analytics/src/config/postgres-connection.ts deleted file mode 100644 index 289aa5e75..000000000 --- a/libs/providers/analytics/src/config/postgres-connection.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PrismaClient } from "@prisma/client"; -import { getEnvVariableOrThrow } from "@chair-flight/base/env"; - -export const prisma = new PrismaClient({ - datasources: { - db: { - url: getEnvVariableOrThrow("PROVIDER_POSTGRES_ANALYTICS_PRISMA_URL"), - }, - }, -}); diff --git a/libs/providers/analytics/src/entities/page-event.ts b/libs/providers/analytics/src/entities/page-event.ts new file mode 100644 index 000000000..0d1102a1c --- /dev/null +++ b/libs/providers/analytics/src/entities/page-event.ts @@ -0,0 +1,23 @@ +import { z } from "zod"; + +export type PageEvent = { + anonymousId: string; + title: string; + path: string; + resolvedPath: string; + height: number; + width: number; + referrer?: string; + timestamp: number; +}; + +export const PageEventSchema: z.ZodSchema = z.object({ + anonymousId: z.string(), + title: z.string(), + path: z.string(), + resolvedPath: z.string(), + height: z.number(), + width: z.number(), + referrer: z.string().optional(), + timestamp: z.number(), +}); diff --git a/libs/providers/analytics/src/entities/track-event.ts b/libs/providers/analytics/src/entities/track-event.ts new file mode 100644 index 000000000..148f306cd --- /dev/null +++ b/libs/providers/analytics/src/entities/track-event.ts @@ -0,0 +1,34 @@ +import { z } from "zod"; + +type TrackEventMap = { + "themeButton.switch": Record; +}; + +type TrackEventBase = { + eventName: T; + anonymousId: string; + timestamp: number; + path: string; + resolvedPath: string; + properties: TrackEventMap[T]; +}; + +type SimplifiedTrackEvent = { + eventName: string; + anonymousId: string; + timestamp: number; + path: string; + resolvedPath: string; + properties: Record; +}; + +export type TrackEvent = TrackEventBase; + +export const TrackEventSchema: z.ZodSchema = z.object({ + eventName: z.string(), + anonymousId: z.string(), + path: z.string(), + resolvedPath: z.string(), + timestamp: z.number(), + properties: z.object({}).passthrough(), +}); diff --git a/libs/providers/analytics/src/functions/create-events.ts b/libs/providers/analytics/src/functions/create-events.ts index fd61755b9..dc2d2e39a 100644 --- a/libs/providers/analytics/src/functions/create-events.ts +++ b/libs/providers/analytics/src/functions/create-events.ts @@ -1,11 +1,14 @@ import { getEnvVariableOrThrow } from "@chair-flight/base/env"; -import { prisma } from "../config/postgres-connection"; -import type { PageEvent, SimplifiedTrackEvent } from "@chair-flight/base/types"; -import type { Prisma } from "@prisma/client"; +import type { PageEvent } from "../entities/page-event"; +import type { TrackEvent } from "../entities/track-event"; +import type { PrismaClient } from "@prisma/client"; const environment = getEnvVariableOrThrow("NODE_ENV"); -export const createPageEvent = async (event: PageEvent) => { +export const createPageEvent = async ( + prisma: PrismaClient, + event: PageEvent, +) => { await prisma.pageEvent.create({ data: { environment, @@ -21,7 +24,10 @@ export const createPageEvent = async (event: PageEvent) => { }); }; -export const createTrackEvent = async (event: SimplifiedTrackEvent) => { +export const createTrackEvent = async ( + prisma: PrismaClient, + event: TrackEvent, +) => { await prisma.trackEvent.create({ data: { environment, @@ -30,7 +36,7 @@ export const createTrackEvent = async (event: SimplifiedTrackEvent) => { eventName: event.eventName, path: event.path, resolvedPath: event.resolvedPath, - properties: event.properties as Prisma.InputJsonValue, + properties: event.properties, }, }); }; diff --git a/libs/providers/analytics/src/functions/page-visits-analytics.ts b/libs/providers/analytics/src/functions/page-visits-analytics.ts deleted file mode 100644 index 62312dfaa..000000000 --- a/libs/providers/analytics/src/functions/page-visits-analytics.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { DateTime } from "luxon"; -import { prisma } from "../config/postgres-connection"; - -const FirstDateWeCareAbout = new Date("2023-07-30"); - -export const getPageVisits = async () => { - const data = await prisma.pageEventDailyCount.findMany({ - where: { - timestamp: { - gte: FirstDateWeCareAbout, - }, - }, - orderBy: { - timestamp: "asc", - }, - }); - - const views = data.reduce>>( - (acc, curr) => { - const { timestamp, path, count } = curr; - const name = DateTime.fromJSDate(timestamp).toFormat("yyyy-MM-dd"); - let existingDate = acc.find((item) => item["name"] === name); - if (!existingDate) acc.push({ name }); - existingDate ??= acc.at(-1) as Record; - existingDate[path] = count; - return acc; - }, - [], - ); - - const paths = data.reduce((acc, curr) => { - const { path } = curr; - if (!acc.includes(path)) acc.push(path); - return acc; - }, []); - return { views, paths }; -}; - -export const generateDailyCounts = async () => { - const lastCalculateCount = await prisma.pageEventDailyCount.findFirst({ - orderBy: { - timestamp: "desc", - }, - }); - - const lastDay = lastCalculateCount?.timestamp ?? FirstDateWeCareAbout; - const yesterday = DateTime.now().minus({ days: 1 }).toJSDate(); - const firstDay = lastDay < yesterday ? lastDay : yesterday; - - type DailyCount = { - count: number; - timestamp: Date; - environment: string; - path: string; - }; - - const dailyCounts = await prisma.$queryRaw` - SELECT - count, - "timestamp2" as "timestamp", - environment, - path - FROM ( - SELECT - COUNT(*)::integer as "count", - DATE_TRUNC('day', timestamp) as "timestamp2", - environment as "environment", - path as "path" - FROM "PageEvent" - WHERE "timestamp" >= ${firstDay} - GROUP BY "timestamp2", "path", "environment" - ORDER BY "timestamp2" ASC - ) as subquery - ORDER BY "timestamp2" ASC; - `; - - await prisma.pageEventDailyCount.createMany({ - data: dailyCounts, - skipDuplicates: true, - }); -}; diff --git a/libs/providers/analytics/src/index.ts b/libs/providers/analytics/src/index.ts index 86cb71373..a1f1e9b83 100644 --- a/libs/providers/analytics/src/index.ts +++ b/libs/providers/analytics/src/index.ts @@ -1,5 +1 @@ -export { createPageEvent, createTrackEvent } from "./functions/create-events"; -export { - getPageVisits, - generateDailyCounts, -} from "./functions/page-visits-analytics"; +export { Analytics } from "./analytics"; diff --git a/libs/providers/analytics/tsconfig.json b/libs/providers/analytics/tsconfig.json index 095dd39fa..38b50d525 100644 --- a/libs/providers/analytics/tsconfig.json +++ b/libs/providers/analytics/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../../tsconfig.base.json", "compilerOptions": {}, - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts"] } diff --git a/libs/providers/blog/executors/compile/executor.ts b/libs/providers/blog/executors/compile/executor.ts index 6bc1f0454..662b19659 100644 --- a/libs/providers/blog/executors/compile/executor.ts +++ b/libs/providers/blog/executors/compile/executor.ts @@ -2,8 +2,7 @@ import * as fs from "node:fs/promises"; import * as path from "node:path"; import { parse } from "yaml"; import { NOOP } from "@chair-flight/base/utils"; -import { blogPostSchema } from "../../src"; -import type { BlogPost } from "@chair-flight/base/types"; +import { blogPostSchema, type BlogPost } from "../../src/entities/blog-post"; import type { ExecutorContext } from "@nx/devkit"; type ExecutorOptions = Record; diff --git a/libs/providers/blog/src/blog.ts b/libs/providers/blog/src/blog.ts index 900b8dc77..a8299b45b 100644 --- a/libs/providers/blog/src/blog.ts +++ b/libs/providers/blog/src/blog.ts @@ -1,19 +1,17 @@ import { DateTime } from "luxon"; import { getUrlPathOnServer } from "@chair-flight/base/env"; import { NotFoundError } from "@chair-flight/base/errors"; -import type { BlogPost } from "@chair-flight/base/types"; +import type { BlogPost } from "./entities/blog-post"; -type ReadFile = (path: string, string: "utf-8") => Promise; +const A_LONG_TIME_AGO = "2020-01-01T00:00:00.000"; interface BlogProvider { getDateOfLastPost: () => Promise; getAllPosts: () => Promise; getPost: (postId: string) => Promise; - preloadForStaticRender: (args: { readFile: ReadFile }) => Promise; + preloadForStaticRender: (fs: MiniFs) => Promise; } -const A_LONG_TIME_AGO = "2020-01-01T00:00:00.000"; - export class Blog implements BlogProvider { private postMeta: BlogPost[] | undefined = undefined; @@ -43,7 +41,7 @@ export class Blog implements BlogProvider { return post; } - async preloadForStaticRender({ readFile }: { readFile: ReadFile }) { + async preloadForStaticRender({ readFile }: MiniFs) { const cwd = process.cwd(); const appPath = "/apps/next-app"; const path = [ @@ -55,5 +53,3 @@ export class Blog implements BlogProvider { this.postMeta = file as BlogPost[]; } } - -export const blog = new Blog(); diff --git a/libs/providers/blog/src/meta-schema.ts b/libs/providers/blog/src/entities/blog-post.ts similarity index 59% rename from libs/providers/blog/src/meta-schema.ts rename to libs/providers/blog/src/entities/blog-post.ts index 79b9a9d8a..de5bac224 100644 --- a/libs/providers/blog/src/meta-schema.ts +++ b/libs/providers/blog/src/entities/blog-post.ts @@ -1,5 +1,15 @@ import { z } from "zod"; -import type { BlogPost } from "@chair-flight/base/types"; + +export type BlogPost = { + title: string; + filename: string; + description: string; + author: string; + date: string; + imageUrl: string | null; + content: string; + tag: "Technical" | "Feature" | "Content"; +}; export const blogPostSchema: z.ZodSchema = z.object({ title: z.string(), diff --git a/libs/providers/blog/src/index.ts b/libs/providers/blog/src/index.ts index 909e0c984..9c77b92c4 100644 --- a/libs/providers/blog/src/index.ts +++ b/libs/providers/blog/src/index.ts @@ -1,4 +1 @@ -export { blog } from "./blog"; -export { blogPostSchema } from "./meta-schema"; - -export type { Blog } from "./blog"; +export { Blog } from "./blog"; diff --git a/libs/providers/blog/tsconfig.json b/libs/providers/blog/tsconfig.json index 287d3efb3..7f92793a5 100644 --- a/libs/providers/blog/tsconfig.json +++ b/libs/providers/blog/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts", "executors/**/*.mts", "executors/**/*.ts"], + "files": ["../../../types.d.ts"], "compilerOptions": { - "types": ["vitest/globals", "@testing-library/jest-dom"], - }, + "types": ["vitest/globals", "@testing-library/jest-dom"] + } } diff --git a/libs/providers/github/.eslintrc.json b/libs/providers/github/.eslintrc.json new file mode 100644 index 000000000..8ba3202ba --- /dev/null +++ b/libs/providers/github/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [] +} diff --git a/libs/providers/github/project.json b/libs/providers/github/project.json new file mode 100644 index 000000000..f67c30cba --- /dev/null +++ b/libs/providers/github/project.json @@ -0,0 +1,22 @@ +{ + "name": "providers-github", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/providers/github/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/providers/github/**/*.ts"] + } + }, + "typecheck": { + "executor": "nx:run-commands", + "options": { + "commands": ["tsc -p libs/providers/github/tsconfig.json"] + } + } + }, + "tags": [] +} diff --git a/libs/providers/github/src/common/env.ts b/libs/providers/github/src/common/env.ts new file mode 100644 index 000000000..f997b5f81 --- /dev/null +++ b/libs/providers/github/src/common/env.ts @@ -0,0 +1,22 @@ +import { + getEnvVariableOrDefault, + getEnvVariableOrThrow, +} from "@chair-flight/base/env"; + +export const upstreamOwner = getEnvVariableOrThrow( + "PROVIDER_GITHUB_PROJECT_UPSTREAM_OWNER", +); + +export const upstreamRepo = getEnvVariableOrThrow( + "PROVIDER_GITHUB_PROJECT_UPSTREAM_REPO", +); + +export const originOwner = getEnvVariableOrDefault( + "PROVIDER_GITHUB_PROJECT_ORIGIN_OWNER", + upstreamOwner, +); + +export const originRepo = getEnvVariableOrDefault( + "PROVIDER_GITHUB_PROJECT_ORIGIN_REPO", + upstreamRepo, +); diff --git a/libs/providers/github/src/functions/create-new-issue.ts b/libs/providers/github/src/functions/create-new-issue.ts new file mode 100644 index 000000000..880cd4f0f --- /dev/null +++ b/libs/providers/github/src/functions/create-new-issue.ts @@ -0,0 +1,24 @@ +import { originOwner, originRepo } from "../common/env"; +import type { NewIssue } from "@chair-flight/core/github"; +import type { Octokit } from "octokit"; + +export const createNewIssue = async (octokit: Octokit, newIssue: NewIssue) => { + const { title, description, debugData, href } = newIssue; + + const response = await octokit.rest.issues.create({ + owner: originOwner, + repo: originRepo, + title: `[App Bug Report] ${title}`, + body: [ + `## Data\n`, + `**href** : ${href}\n`, + "```", + JSON.stringify(debugData, null, 2), + "```", + `\n\n---\n\n## Description\n`, + description, + ].join("\n"), + }); + + return { url: response.data.html_url }; +}; diff --git a/libs/core/github/src/functions/create-new-question-pr.ts b/libs/providers/github/src/functions/create-new-question-pr.ts similarity index 91% rename from libs/core/github/src/functions/create-new-question-pr.ts rename to libs/providers/github/src/functions/create-new-question-pr.ts index fbfb7dd17..5f212409f 100644 --- a/libs/core/github/src/functions/create-new-question-pr.ts +++ b/libs/providers/github/src/functions/create-new-question-pr.ts @@ -2,21 +2,25 @@ import * as babelPlugin from "prettier/plugins/babel"; import * as estreePlugin from "prettier/plugins/estree"; import { format } from "prettier/standalone"; import { getRandomId } from "@chair-flight/base/utils"; -import { getOctokit } from "../config/oktokit"; -import type { QuestionBankQuestionTemplate } from "@chair-flight/base/types"; -import type { questionEditSchema } from "@chair-flight/core/schemas"; -import type { z } from "zod"; +import { + originOwner, + originRepo, + upstreamOwner, + upstreamRepo, +} from "../common/env"; +import type { QuestionEdit } from "@chair-flight/core/github"; +import type { QuestionBankQuestionTemplate } from "@chair-flight/core/question-bank"; +import type { Octokit } from "octokit"; export const createNewQuestionPr = async ( - schema: z.infer, + octokit: Octokit, + schema: QuestionEdit, ) => { const { question: { srcLocation, ...question }, requestData, } = schema; const prId = getRandomId(); - const { octokit, originOwner, originRepo, upstreamOwner, upstreamRepo } = - getOctokit(); const baseBranch = "main"; const newBranch = `feat-question-${question.id}-${prId}`; const normalizedSrcLocation = srcLocation diff --git a/libs/providers/github/src/github.ts b/libs/providers/github/src/github.ts new file mode 100644 index 000000000..5717fe736 --- /dev/null +++ b/libs/providers/github/src/github.ts @@ -0,0 +1,28 @@ +import { Octokit } from "octokit"; +import { getEnvVariableOrThrow } from "@chair-flight/base/env"; +import { createNewIssue } from "./functions/create-new-issue"; +import { createNewQuestionPr } from "./functions/create-new-question-pr"; +import type { NewIssue, QuestionEdit } from "@chair-flight/core/github"; + +interface GithubProvider { + createNewQuestionPr(newQuestion: QuestionEdit): Promise<{ url: string }>; + createNewIssue(newIssue: NewIssue): Promise<{ url: string }>; +} + +export class Github implements GithubProvider { + private static octokit: Octokit; + + constructor() { + Github.octokit = new Octokit({ + auth: getEnvVariableOrThrow("PROVIDER_GITHUB_TOKEN"), + }); + } + + async createNewQuestionPr(newQuestion: QuestionEdit) { + return await createNewQuestionPr(Github.octokit, newQuestion); + } + + async createNewIssue(newIssue: NewIssue) { + return await createNewIssue(Github.octokit, newIssue); + } +} diff --git a/libs/providers/github/src/index.ts b/libs/providers/github/src/index.ts new file mode 100644 index 000000000..fee842833 --- /dev/null +++ b/libs/providers/github/src/index.ts @@ -0,0 +1 @@ +export { Github } from "./github"; diff --git a/libs/core/app/tsconfig.json b/libs/providers/github/tsconfig.json similarity index 69% rename from libs/core/app/tsconfig.json rename to libs/providers/github/tsconfig.json index 5e7280d8a..de61c4fdb 100644 --- a/libs/core/app/tsconfig.json +++ b/libs/providers/github/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.test.*"], + "files": ["../../../types.d.ts"] } diff --git a/libs/providers/question-bank/executors/compile/executor.ts b/libs/providers/question-bank/executors/compile/executor.ts index 99bba739e..95676aa6d 100644 --- a/libs/providers/question-bank/executors/compile/executor.ts +++ b/libs/providers/question-bank/executors/compile/executor.ts @@ -1,7 +1,7 @@ import * as fs from "node:fs/promises"; import * as path from "node:path"; import { NOOP } from "@chair-flight/base/utils"; -import { connectQuestionBank } from "../common/connect-question-bank"; +import { connectQuestionBank } from "../../src/executors/connect-question-bank"; import { getPaths, readAllCoursesFromFs, @@ -11,7 +11,7 @@ import { readAllQuestionsFromFs, readAllSubjectsFromFs, readAllDocsFromFs, -} from "../common/parse-question-bank"; +} from "../../src/executors/parse-question-bank"; import type { ExecutorContext } from "@nx/devkit"; type ExecutorOptions = Record; diff --git a/libs/providers/question-bank/executors/parse-los-xlsx/executor.ts b/libs/providers/question-bank/executors/parse-los-xlsx/executor.ts index 425e20967..4d56e3cd6 100644 --- a/libs/providers/question-bank/executors/parse-los-xlsx/executor.ts +++ b/libs/providers/question-bank/executors/parse-los-xlsx/executor.ts @@ -1,6 +1,6 @@ import * as fs from "node:fs/promises"; import * as path from "node:path"; -import { parseLearningObjectivesXlsx } from "../common/parse-learning-objectives-xlsx"; +import { parseLearningObjectivesXlsx } from "../../src/executors/parse-learning-objectives-xlsx"; type ExecutorOptions = { xlsxPath: string; diff --git a/libs/providers/question-bank/executors/common/connect-question-bank.ts b/libs/providers/question-bank/src/executors/connect-question-bank.ts similarity index 98% rename from libs/providers/question-bank/executors/common/connect-question-bank.ts rename to libs/providers/question-bank/src/executors/connect-question-bank.ts index b0a6b521d..9830f07f2 100644 --- a/libs/providers/question-bank/executors/common/connect-question-bank.ts +++ b/libs/providers/question-bank/src/executors/connect-question-bank.ts @@ -9,7 +9,7 @@ import type { QuestionBankSubject, SubjectId, QuestionBankDoc, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; export const connectQuestionBank = ({ questions, diff --git a/libs/providers/question-bank/executors/common/parse-learning-objectives-xlsx.ts b/libs/providers/question-bank/src/executors/parse-learning-objectives-xlsx.ts similarity index 98% rename from libs/providers/question-bank/executors/common/parse-learning-objectives-xlsx.ts rename to libs/providers/question-bank/src/executors/parse-learning-objectives-xlsx.ts index 1e47e4e14..16ef0682b 100644 --- a/libs/providers/question-bank/executors/common/parse-learning-objectives-xlsx.ts +++ b/libs/providers/question-bank/src/executors/parse-learning-objectives-xlsx.ts @@ -2,7 +2,7 @@ import * as XLSX from "xlsx"; import type { LearningObjectiveId, QuestionBankLearningObjectiveJson, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; const courseNames: Record = { "ATPL(A)": "ATPL_A", diff --git a/libs/providers/question-bank/executors/common/parse-question-bank.ts b/libs/providers/question-bank/src/executors/parse-question-bank.ts similarity index 98% rename from libs/providers/question-bank/executors/common/parse-question-bank.ts rename to libs/providers/question-bank/src/executors/parse-question-bank.ts index 14a049ba4..ecc8af573 100644 --- a/libs/providers/question-bank/executors/common/parse-question-bank.ts +++ b/libs/providers/question-bank/src/executors/parse-question-bank.ts @@ -1,7 +1,7 @@ import * as fs from "node:fs/promises"; import * as path from "node:path"; import { parse } from "yaml"; -import { QuestionBankDocSchema } from "../../src/question-bank-docs-meta-schema"; +import { QuestionBankDocSchema } from "@chair-flight/core/question-bank"; import type { QuestionBankQuestionTemplate, QuestionBankQuestionTemplateJson, @@ -16,7 +16,7 @@ import type { QuestionBankCourse, QuestionBankSubject, QuestionBankDoc, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { ExecutorContext } from "@nx/devkit"; const MATTER_REGEX = diff --git a/libs/providers/question-bank/src/index.ts b/libs/providers/question-bank/src/index.ts index 417291385..f6f62b449 100644 --- a/libs/providers/question-bank/src/index.ts +++ b/libs/providers/question-bank/src/index.ts @@ -1,10 +1 @@ -import { QuestionBank } from "./question-bank"; -import type { QuestionBankName } from "@chair-flight/base/types"; - -export const questionBanks: Record = { - type: new QuestionBank("type"), - atpl: new QuestionBank("atpl"), - prep: new QuestionBank("prep"), -}; - -export type { QuestionBank }; +export { QuestionBank } from "./provider/question-bank-provider"; diff --git a/libs/providers/question-bank/src/question-bank.test.ts b/libs/providers/question-bank/src/provider/question-bank-provider.test.ts similarity index 88% rename from libs/providers/question-bank/src/question-bank.test.ts rename to libs/providers/question-bank/src/provider/question-bank-provider.test.ts index b0d2b274c..b3ef4e344 100644 --- a/libs/providers/question-bank/src/question-bank.test.ts +++ b/libs/providers/question-bank/src/provider/question-bank-provider.test.ts @@ -1,7 +1,13 @@ import * as fs from "node:fs/promises"; -import { questionBankQuestionSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "./index"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import { questionBankQuestionSchema } from "@chair-flight/core/question-bank"; +import { QuestionBank } from "./question-bank-provider"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; + +const questionBanks: Record = { + type: new QuestionBank("type"), + atpl: new QuestionBank("atpl"), + prep: new QuestionBank("prep"), +}; describe("QuestionBank", async () => { await Promise.all( diff --git a/libs/providers/question-bank/src/provider/question-bank-provider.ts b/libs/providers/question-bank/src/provider/question-bank-provider.ts new file mode 100644 index 000000000..c1f61353f --- /dev/null +++ b/libs/providers/question-bank/src/provider/question-bank-provider.ts @@ -0,0 +1,111 @@ +import { getUrlPathOnServer } from "@chair-flight/base/env"; +import { NotFoundError } from "@chair-flight/base/errors"; +import type { + QuestionBankName, + QuestionBankResource, + QuestionBankProvider, + QuestionBankResourceArrays, + QuestionBankResourceMaps, + QuestionBankNameToType, +} from "@chair-flight/core/question-bank"; + +const resources: QuestionBankResource[] = [ + "questions", + "learningObjectives", + "annexes", + "flashcards", + "subjects", + "courses", + "docs", +]; + +export class QuestionBank implements QuestionBankProvider { + private questionBankName: QuestionBankName; + + private resourceArrays = resources.reduce((s, r) => { + s[r] = undefined; + return s; + }, {} as QuestionBankResourceArrays); + + private resourceMaps = resources.reduce((s, r) => { + s[r] = undefined; + return s; + }, {} as QuestionBankResourceMaps); + + constructor(questionBankName: QuestionBankName) { + this.questionBankName = questionBankName; + } + + getName() { + return this.questionBankName; + } + + async has(resource: QuestionBankResource) { + const all = await this.getAll(resource); + return all.length > 0; + } + + async getAll(resource: T) { + if (!this.resourceArrays[resource]) { + const urlPath = getUrlPathOnServer(); + const bankPath = `/content/content-question-bank-${this.getName()}`; + const baseApiPath = `${urlPath}${bankPath}`; + const apiPath = `${baseApiPath}/${resource}.json`; + const response = await fetch(apiPath); + const json = (await response.json()) as QuestionBankNameToType[T][]; + type ArrayType = (typeof this.resourceArrays)[typeof resource]; + this.resourceArrays[resource] = json as ArrayType; + } + const all = this.resourceArrays[resource] as QuestionBankNameToType[T][]; + return all; + } + + async getSome(resource: T, ids: string[]) { + if (!ids.length) { + return []; + } + if (!this.resourceMaps[resource]) { + const all = await this.getAll(resource); + const map = all.reduce>( + (s, q) => { + s[q.id] = q; + return s; + }, + {}, + ); + type MapType = (typeof this.resourceMaps)[typeof resource]; + this.resourceMaps[resource] = map as MapType; + } + const map = this.resourceMaps[resource] as Record< + string, + QuestionBankNameToType[T] + >; + return ids.map((id) => map[id]).filter(Boolean); + } + + async getOne(resource: T, id: string) { + const data = (await this.getSome(resource, [id]))[0]; + if (!data) { + throw new NotFoundError(`QuestionBank has no ${resource} with id ${id}`); + } + return data; + } + + async preloadForStaticRender({ readFile }: MiniFs) { + await Promise.all( + resources.map(async (resource) => { + const cwd = process.cwd(); + const appPath = "/apps/next-app"; + const path = [ + cwd, + cwd.includes(appPath) ? "" : appPath, + `/public/content/content-question-bank-${this.getName()}`, + `/${resource}.json`, + ].join(""); + const file = JSON.parse(await readFile(path, "utf-8")); + // @ts-expect-error Hard to type. Covered in tests + this.resourceArrays[resource] = file; + }), + ); + } +} diff --git a/libs/providers/question-bank/src/question-bank.ts b/libs/providers/question-bank/src/question-bank.ts deleted file mode 100644 index d621a3790..000000000 --- a/libs/providers/question-bank/src/question-bank.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { getUrlPathOnServer } from "@chair-flight/base/env"; -import { NotFoundError } from "@chair-flight/base/errors"; -import type { - QuestionBankQuestionTemplate, - QuestionBankAnnexes, - QuestionBankLearningObjective, - QuestionBankName, - QuestionBankFlashcardCollection, - QuestionBankSubject, - QuestionBankCourse, - QuestionBankDoc, -} from "@chair-flight/base/types"; - -type Resource = - | "questions" - | "learningObjectives" - | "annexes" - | "flashcards" - | "courses" - | "subjects" - | "docs"; - -type NameToType = { - questions: QuestionBankQuestionTemplate; - learningObjectives: QuestionBankLearningObjective; - annexes: QuestionBankAnnexes; - flashcards: QuestionBankFlashcardCollection; - subjects: QuestionBankSubject; - courses: QuestionBankCourse; - docs: QuestionBankDoc; -}; - -type ResourceArrays = { - [K in Resource]: NameToType[K][] | undefined; -}; - -type ResourceMaps = { - [K in Resource]: Record | undefined; -}; - -type ReadFile = (path: string, string: "utf-8") => Promise; - -interface IQuestionBank { - getName: () => QuestionBankName; - has: (r: Resource) => Promise; - getAll: (r: T) => Promise; - getSome: (r: T, id: string[]) => Promise; - getOne: (r: T, id: string) => Promise; - preloadForStaticRender: (args: { readFile: ReadFile }) => Promise; -} - -const resources: Resource[] = [ - "questions", - "learningObjectives", - "annexes", - "flashcards", - "subjects", - "courses", - "docs", -]; - -export class QuestionBank implements IQuestionBank { - private questionBankName: QuestionBankName; - - private resourceArrays: ResourceArrays = resources.reduce((s, r) => { - s[r] = undefined; - return s; - }, {} as ResourceArrays); - - private resourceMaps: ResourceMaps = resources.reduce((s, r) => { - s[r] = undefined; - return s; - }, {} as ResourceMaps); - - constructor(questionBankName: QuestionBankName) { - this.questionBankName = questionBankName; - } - - getName() { - return this.questionBankName; - } - - async has(resource: Resource) { - const all = await this.getAll(resource); - return all.length > 0; - } - - async getAll(resource: T) { - if (!this.resourceArrays[resource]) { - const urlPath = getUrlPathOnServer(); - const bankPath = `/content/content-question-bank-${this.getName()}`; - const baseApiPath = `${urlPath}${bankPath}`; - const apiPath = `${baseApiPath}/${resource}.json`; - const response = await fetch(apiPath); - const json = (await response.json()) as NameToType[T][]; - type ArrayType = (typeof this.resourceArrays)[typeof resource]; - this.resourceArrays[resource] = json as ArrayType; - } - const all = this.resourceArrays[resource] as NameToType[T][]; - return all; - } - - async getSome(resource: T, ids: string[]) { - if (!ids.length) { - return []; - } - if (!this.resourceMaps[resource]) { - const all = await this.getAll(resource); - const map = all.reduce>((s, q) => { - s[q.id] = q; - return s; - }, {}); - type MapType = (typeof this.resourceMaps)[typeof resource]; - this.resourceMaps[resource] = map as MapType; - } - const map = this.resourceMaps[resource] as Record; - return ids.map((id) => map[id]).filter(Boolean); - } - - async getOne(resource: T, id: string) { - const data = (await this.getSome(resource, [id]))[0]; - if (!data) { - throw new NotFoundError(`QuestionBank has no ${resource} with id ${id}`); - } - return data; - } - - async preloadForStaticRender({ readFile }: { readFile: ReadFile }) { - await Promise.all( - resources.map(async (resource) => { - const cwd = process.cwd(); - const appPath = "/apps/next-app"; - const path = [ - cwd, - cwd.includes(appPath) ? "" : appPath, - `/public/content/content-question-bank-${this.getName()}`, - `/${resource}.json`, - ].join(""); - const file = JSON.parse(await readFile(path, "utf-8")); - // @ts-expect-error Hard to type. Covered in tests - this.resourceArrays[resource] = file; - }), - ); - } -} diff --git a/libs/providers/question-bank/tsconfig.json b/libs/providers/question-bank/tsconfig.json index 287d3efb3..44cc3ad27 100644 --- a/libs/providers/question-bank/tsconfig.json +++ b/libs/providers/question-bank/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", - "include": ["src/**/*.ts", "executors/**/*.mts", "executors/**/*.ts"], + "include": ["src/**/*.ts", "executors/**/*.ts"], + "files": ["../../../types.d.ts"], "compilerOptions": { - "types": ["vitest/globals", "@testing-library/jest-dom"], - }, + "types": ["vitest/globals"] + } } diff --git a/libs/providers/search/.eslintrc.json b/libs/providers/search/.eslintrc.json new file mode 100644 index 000000000..31958a0c1 --- /dev/null +++ b/libs/providers/search/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["./package.json", "./executors.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/nx-plugin-checks": "error" + } + } + ] +} diff --git a/libs/providers/search/project.json b/libs/providers/search/project.json new file mode 100644 index 000000000..e76e3e06b --- /dev/null +++ b/libs/providers/search/project.json @@ -0,0 +1,22 @@ +{ + "name": "providers-search", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "libs/providers/search/src", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/providers/search/**/*.ts"] + } + }, + "typecheck": { + "executor": "nx:run-commands", + "options": { + "commands": ["tsc -p libs/providers/search/tsconfig.json"] + } + } + }, + "tags": [] +} diff --git a/libs/providers/search/src/index.ts b/libs/providers/search/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/libs/providers/search/tsconfig.json b/libs/providers/search/tsconfig.json new file mode 100644 index 000000000..44cc3ad27 --- /dev/null +++ b/libs/providers/search/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts", "executors/**/*.ts"], + "files": ["../../../types.d.ts"], + "compilerOptions": { + "types": ["vitest/globals"] + } +} diff --git a/libs/react/analytics/src/use-analytics-plugin.ts b/libs/react/analytics/src/use-analytics-plugin.ts index 041963213..09a6f71bf 100644 --- a/libs/react/analytics/src/use-analytics-plugin.ts +++ b/libs/react/analytics/src/use-analytics-plugin.ts @@ -1,6 +1,7 @@ import { useRouter } from "next/dist/client/router"; import { NOOP } from "@chair-flight/base/utils"; import { trpc } from "@chair-flight/trpc/client"; +import type { TrackEventName } from "@chair-flight/core/analytics"; import type { AnalyticsPlugin } from "analytics"; type OriginalPageViewProps = { @@ -20,7 +21,7 @@ type OriginalPageViewProps = { type OriginalTrackEventProps = { payload: { type: "track"; - event: string; + event: TrackEventName; anonymousId: string; properties: Record; }; @@ -55,7 +56,7 @@ export const useAnalyticsPlugin = (): AnalyticsPlugin => { anonymousId: props.payload.anonymousId, path: router.pathname, resolvedPath: router.asPath, - properties: props.payload.properties, + properties: props.payload.properties as Record, timestamp: Date.now(), }); }, diff --git a/libs/react/analytics/src/use-analytics.tsx b/libs/react/analytics/src/use-analytics.tsx index 5012b4cb9..007e8201f 100644 --- a/libs/react/analytics/src/use-analytics.tsx +++ b/libs/react/analytics/src/use-analytics.tsx @@ -3,7 +3,7 @@ import { useAnalyticsPlugin } from "./use-analytics-plugin"; import type { TrackEventName, TrackEventPayload, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/analytics"; import type { AnalyticsInstance } from "analytics"; import type { FunctionComponent, PropsWithChildren } from "react"; diff --git a/libs/react/analytics/tsconfig.json b/libs/react/analytics/tsconfig.json index 728f416f3..85a911f4d 100644 --- a/libs/react/analytics/tsconfig.json +++ b/libs/react/analytics/tsconfig.json @@ -1,8 +1,8 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts", "src/**/*.tsx"], - "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"], + "files": ["../../../types.d.ts"], "compilerOptions": { - "lib": ["dom", "ESNext"], - }, + "lib": ["dom", "ESNext"] + } } diff --git a/libs/react/components/src/theme/theme-override-color-scheme.tsx b/libs/react/components/src/theme/theme-override-color-scheme.tsx index 08cd047c8..d78b62647 100644 --- a/libs/react/components/src/theme/theme-override-color-scheme.tsx +++ b/libs/react/components/src/theme/theme-override-color-scheme.tsx @@ -1,10 +1,9 @@ import { GlobalStyles } from "@mui/material"; -import type { QuestionBankName } from "@chair-flight/base/types"; import type { DefaultPaletteRange } from "@mui/joy/styles/types"; import type { FC } from "react"; export type ThemeOverrideColorSchemeProps = { - questionBank?: QuestionBankName; + questionBank?: "type" | "prep" | "atpl"; }; const getGlobalColorScheme = (palette: DefaultPaletteRange) => ({ diff --git a/libs/react/components/tsconfig.json b/libs/react/components/tsconfig.json index 35c83e282..01ead8654 100644 --- a/libs/react/components/tsconfig.json +++ b/libs/react/components/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts", "src/**/*.tsx"], - "files": ["../../../node_modules/@nx/next/typings/image.d.ts"], + "files": [ + "../../../node_modules/@nx/next/typings/image.d.ts", + "../../../types.d.ts" + ], "compilerOptions": { - "lib": ["dom"], - "types": ["vitest/globals", "@testing-library/jest-dom"], - }, + "lib": ["dom", "ESNext"], + "types": ["vitest/globals", "@testing-library/jest-dom"] + } } diff --git a/libs/react/containers/src/annexes/annex-search/annex-search.tsx b/libs/react/containers/src/annexes/annex-search/annex-search.tsx index 9b847ca73..2bf698ea7 100644 --- a/libs/react/containers/src/annexes/annex-search/annex-search.tsx +++ b/libs/react/containers/src/annexes/annex-search/annex-search.tsx @@ -8,7 +8,7 @@ import { trpc } from "@chair-flight/trpc/client"; import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { container, getRequiredParam } from "../../wraper/container"; import { AnnexSearchItem } from "./annex-search-item"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { SearchListProps } from "@chair-flight/react/components"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; diff --git a/libs/react/containers/src/docs/doc-content/doc-content.tsx b/libs/react/containers/src/docs/doc-content/doc-content.tsx index 2c92687c5..f0bcca5fb 100644 --- a/libs/react/containers/src/docs/doc-content/doc-content.tsx +++ b/libs/react/containers/src/docs/doc-content/doc-content.tsx @@ -3,7 +3,7 @@ import { Markdown } from "@chair-flight/react/components"; import { trpc } from "@chair-flight/trpc/client"; import { container, getRequiredParam } from "../../wraper"; import type { Container } from "../../wraper/container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { questionBank: QuestionBankName; docId: string }; diff --git a/libs/react/containers/src/docs/doc-search/doc-search.tsx b/libs/react/containers/src/docs/doc-search/doc-search.tsx index 138b1603f..705446f1a 100644 --- a/libs/react/containers/src/docs/doc-search/doc-search.tsx +++ b/libs/react/containers/src/docs/doc-search/doc-search.tsx @@ -9,7 +9,7 @@ import { SearchHeader, SearchList } from "@chair-flight/react/components"; import { trpc } from "@chair-flight/trpc/client"; import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { container, getRequiredParam } from "../../wraper/container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/flashcards/components/fashcard-with-own-control/flashcard-with-own-control.tsx b/libs/react/containers/src/flashcards/components/fashcard-with-own-control/flashcard-with-own-control.tsx index 5e1fa8876..bacb3a85c 100644 --- a/libs/react/containers/src/flashcards/components/fashcard-with-own-control/flashcard-with-own-control.tsx +++ b/libs/react/containers/src/flashcards/components/fashcard-with-own-control/flashcard-with-own-control.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { Flashcard } from "@chair-flight/react/components"; -import type { QuestionBankFlashcardContent } from "@chair-flight/base/types"; +import type { QuestionBankFlashcardContent } from "@chair-flight/core/question-bank"; import type { FunctionComponent } from "react"; export const FlashcardWithOwnControl: FunctionComponent< diff --git a/libs/react/containers/src/flashcards/flashcard-collection-list/flashcard-collection-list.tsx b/libs/react/containers/src/flashcards/flashcard-collection-list/flashcard-collection-list.tsx index 071d684ee..e285b63a6 100644 --- a/libs/react/containers/src/flashcards/flashcard-collection-list/flashcard-collection-list.tsx +++ b/libs/react/containers/src/flashcards/flashcard-collection-list/flashcard-collection-list.tsx @@ -11,7 +11,7 @@ import { } from "@mui/joy"; import { trpc } from "@chair-flight/trpc/client"; import { container, getRequiredParam } from "../../wraper/container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/flashcards/flashcard-list/flashcard-list.tsx b/libs/react/containers/src/flashcards/flashcard-list/flashcard-list.tsx index c2486662d..33d5fbaed 100644 --- a/libs/react/containers/src/flashcards/flashcard-list/flashcard-list.tsx +++ b/libs/react/containers/src/flashcards/flashcard-list/flashcard-list.tsx @@ -2,7 +2,7 @@ import { Grid } from "@mui/joy"; import { trpc } from "@chair-flight/trpc/client"; import { container, getRequiredParam } from "../../wraper/container"; import { FlashcardWithOwnControl } from "../components/fashcard-with-own-control"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/flashcards/flashcard-test/flashcard-test.tsx b/libs/react/containers/src/flashcards/flashcard-test/flashcard-test.tsx index 8cf68a033..a623f3eb4 100644 --- a/libs/react/containers/src/flashcards/flashcard-test/flashcard-test.tsx +++ b/libs/react/containers/src/flashcards/flashcard-test/flashcard-test.tsx @@ -3,7 +3,7 @@ import { FlashcardTinder } from "@chair-flight/react/components"; import { trpc } from "@chair-flight/trpc/client"; import { container, getRequiredParam } from "../../wraper/container"; import { FlashcardWithOwnControl } from "../components/fashcard-with-own-control"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/hooks/use-persistence/create-use-persistence-hook.ts b/libs/react/containers/src/hooks/use-persistence/create-use-persistence-hook.ts index d1722b329..24bbf0817 100644 --- a/libs/react/containers/src/hooks/use-persistence/create-use-persistence-hook.ts +++ b/libs/react/containers/src/hooks/use-persistence/create-use-persistence-hook.ts @@ -1,6 +1,6 @@ import { create } from "zustand"; import { devtools, persist } from "zustand/middleware"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; type PersistenceHook = { data: T; diff --git a/libs/react/containers/src/layouts/layout-module/layout-module.tsx b/libs/react/containers/src/layouts/layout-module/layout-module.tsx index f9d7f72e6..dac3ae882 100644 --- a/libs/react/containers/src/layouts/layout-module/layout-module.tsx +++ b/libs/react/containers/src/layouts/layout-module/layout-module.tsx @@ -36,7 +36,7 @@ import { } from "../components/app-buttons"; import { BugReportButton } from "../components/app-buttons/app-buttons"; import { usePageTransition } from "../hooks/use-page-transition"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; const HEADER_HEIGHT = 48; diff --git a/libs/react/containers/src/learning-objectives/learning-objective-overview/learning-objective-overview.tsx b/libs/react/containers/src/learning-objectives/learning-objective-overview/learning-objective-overview.tsx index 288b2664b..077d9cae4 100644 --- a/libs/react/containers/src/learning-objectives/learning-objective-overview/learning-objective-overview.tsx +++ b/libs/react/containers/src/learning-objectives/learning-objective-overview/learning-objective-overview.tsx @@ -6,7 +6,7 @@ import { container, getRequiredParam } from "../../wraper"; import type { LearningObjectiveId, QuestionBankName, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/learning-objectives/learning-objective-questions/learning-objective-questions.tsx b/libs/react/containers/src/learning-objectives/learning-objective-questions/learning-objective-questions.tsx index f40ce2a87..7d6eb835d 100644 --- a/libs/react/containers/src/learning-objectives/learning-objective-questions/learning-objective-questions.tsx +++ b/libs/react/containers/src/learning-objectives/learning-objective-questions/learning-objective-questions.tsx @@ -4,7 +4,7 @@ import { container, getRequiredParam } from "../../wraper"; import type { LearningObjectiveId, QuestionBankName, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { QuestionListProps } from "@chair-flight/react/components"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; diff --git a/libs/react/containers/src/learning-objectives/learning-objective-tree/learning-objective-tree.tsx b/libs/react/containers/src/learning-objectives/learning-objective-tree/learning-objective-tree.tsx index c77f56cc9..7ae2d7560 100644 --- a/libs/react/containers/src/learning-objectives/learning-objective-tree/learning-objective-tree.tsx +++ b/libs/react/containers/src/learning-objectives/learning-objective-tree/learning-objective-tree.tsx @@ -4,7 +4,7 @@ import { container, getRequiredParam } from "../../wraper"; import type { LearningObjectiveId, QuestionBankName, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { LearningObjectiveListProps } from "@chair-flight/react/components"; import type { AppRouterOutput } from "@chair-flight/trpc/server"; diff --git a/libs/react/containers/src/learning-objectives/learning-objectives-search/learning-objectives-search.tsx b/libs/react/containers/src/learning-objectives/learning-objectives-search/learning-objectives-search.tsx index 6e0550a93..bb2e34478 100644 --- a/libs/react/containers/src/learning-objectives/learning-objectives-search/learning-objectives-search.tsx +++ b/libs/react/containers/src/learning-objectives/learning-objectives-search/learning-objectives-search.tsx @@ -10,7 +10,7 @@ import { import { trpc } from "@chair-flight/trpc/client"; import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { container, getRequiredParam } from "../../wraper/container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/overviews/overview-modules/overview-modules.tsx b/libs/react/containers/src/overviews/overview-modules/overview-modules.tsx index 4f0eca9b0..32e3fdfe1 100644 --- a/libs/react/containers/src/overviews/overview-modules/overview-modules.tsx +++ b/libs/react/containers/src/overviews/overview-modules/overview-modules.tsx @@ -8,7 +8,7 @@ import { container } from "../../wraper/container"; import { default as previewAtpl } from "./images/atpl.png"; import { default as previewB737 } from "./images/b737.png"; import { default as previewPrep } from "./images/prep.png"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; const zoomIn = keyframes` 0% { transform: scale(1); } diff --git a/libs/react/containers/src/overviews/overview-welcome/welcome.stories.tsx b/libs/react/containers/src/overviews/overview-welcome/welcome.stories.tsx index 8ddb9d05e..28a518f6d 100644 --- a/libs/react/containers/src/overviews/overview-welcome/welcome.stories.tsx +++ b/libs/react/containers/src/overviews/overview-welcome/welcome.stories.tsx @@ -1,7 +1,7 @@ import { trpcMsw } from "@chair-flight/trpc/mock"; import { OverviewWelcome } from "./welcome"; import { mockData } from "./welcome.mock"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Meta, StoryObj } from "@storybook/react"; type Story = StoryObj; diff --git a/libs/react/containers/src/overviews/overview-welcome/welcome.tsx b/libs/react/containers/src/overviews/overview-welcome/welcome.tsx index 1e4101573..9c65f5adb 100644 --- a/libs/react/containers/src/overviews/overview-welcome/welcome.tsx +++ b/libs/react/containers/src/overviews/overview-welcome/welcome.tsx @@ -13,7 +13,7 @@ import { import { trpc } from "@chair-flight/trpc/client"; import { container } from "../../wraper/container"; import { RightContainer } from "./welcome-right-container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; type Props = { diff --git a/libs/react/containers/src/questions/question-overview/question-overview.mock.ts b/libs/react/containers/src/questions/question-overview/question-overview.mock.ts index da7cf7c03..6bce299e6 100644 --- a/libs/react/containers/src/questions/question-overview/question-overview.mock.ts +++ b/libs/react/containers/src/questions/question-overview/question-overview.mock.ts @@ -43,4 +43,5 @@ export const mockData: AppRouterOutput["containers"]["questions"]["getQuestionOv href: "/modules/atpl/learning-objectives/010.01", }, ], + editLink: "/modules/atpl/questions/Q000YBA1ON/edit", }; diff --git a/libs/react/containers/src/questions/question-overview/question-overview.tsx b/libs/react/containers/src/questions/question-overview/question-overview.tsx index 3710481c9..6be5f5cbc 100644 --- a/libs/react/containers/src/questions/question-overview/question-overview.tsx +++ b/libs/react/containers/src/questions/question-overview/question-overview.tsx @@ -4,6 +4,7 @@ import { default as OpenInNewIcon } from "@mui/icons-material/OpenInNew"; import { default as RefreshIcon } from "@mui/icons-material/Refresh"; import { Button, + CircularProgress, Divider, Link, List, @@ -19,7 +20,10 @@ import { tabListClasses, } from "@mui/joy"; import { getRandomId, getRandomShuffler } from "@chair-flight/base/utils"; -import { getQuestion, getQuestionPreview } from "@chair-flight/core/app"; +import { + getQuestion, + getQuestionPreview, +} from "@chair-flight/core/question-bank"; import { ImageViewer, MarkdownClient, @@ -32,7 +36,7 @@ import type { QuestionBankName, QuestionTemplateId, QuestionVariantId, -} from "@chair-flight/base/types"; +} from "@chair-flight/core/question-bank"; import type { DrawingPoints, QuestionMultipleChoiceStatus as Status, @@ -180,6 +184,13 @@ export const QuestionOverview = container( Variants + + Edit + ( })} + + + ); }, diff --git a/libs/react/containers/src/questions/question-search/question-search.tsx b/libs/react/containers/src/questions/question-search/question-search.tsx index c13a6d85b..35648850c 100644 --- a/libs/react/containers/src/questions/question-search/question-search.tsx +++ b/libs/react/containers/src/questions/question-search/question-search.tsx @@ -7,7 +7,7 @@ import { QuestionList, SearchHeader } from "@chair-flight/react/components"; import { trpc } from "@chair-flight/trpc/client"; import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { container, getRequiredParam } from "../../wraper/container"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { SearchListProps } from "@chair-flight/react/components"; import type { AppRouterOutput } from "@chair-flight/trpc/client"; diff --git a/libs/react/containers/src/tests/__mocks__/test-progress.mock.ts b/libs/react/containers/src/tests/__mocks__/test-progress.mock.ts index d32347aaa..a5b9e206f 100644 --- a/libs/react/containers/src/tests/__mocks__/test-progress.mock.ts +++ b/libs/react/containers/src/tests/__mocks__/test-progress.mock.ts @@ -1,4 +1,4 @@ -import type { Test } from "@chair-flight/base/types"; +import type { Test } from "@chair-flight/core/question-bank"; export const testProgressMock: { tests: Record; diff --git a/libs/react/containers/src/tests/components/test-error/test-error.tsx b/libs/react/containers/src/tests/components/test-error/test-error.tsx index 316300d25..de946a996 100644 --- a/libs/react/containers/src/tests/components/test-error/test-error.tsx +++ b/libs/react/containers/src/tests/components/test-error/test-error.tsx @@ -2,7 +2,7 @@ import { useRouter } from "next/router"; import { Link, Typography } from "@mui/joy"; import { NotFoundError } from "@chair-flight/base/errors"; import { Ups } from "@chair-flight/react/components"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { FunctionComponent } from "react"; export const TestError: FunctionComponent<{ error: Error }> = ({ error }) => { diff --git a/libs/react/containers/src/tests/hooks/use-test-progress/use-test-progress.ts b/libs/react/containers/src/tests/hooks/use-test-progress/use-test-progress.ts index d392f9e52..a76f3463f 100644 --- a/libs/react/containers/src/tests/hooks/use-test-progress/use-test-progress.ts +++ b/libs/react/containers/src/tests/hooks/use-test-progress/use-test-progress.ts @@ -1,7 +1,7 @@ import { create } from "zustand"; import { devtools, persist } from "zustand/middleware"; import { userPreferences } from "../../../user/hooks/use-user-preferences"; -import type { Test } from "@chair-flight/base/types"; +import type { Test } from "@chair-flight/core/question-bank"; type TestProgress = { tests: Record; diff --git a/libs/react/containers/src/tests/test-maker/test-maker.tsx b/libs/react/containers/src/tests/test-maker/test-maker.tsx index f505017dc..77beec25d 100644 --- a/libs/react/containers/src/tests/test-maker/test-maker.tsx +++ b/libs/react/containers/src/tests/test-maker/test-maker.tsx @@ -25,7 +25,7 @@ import { import { getNumberOfAvailableQuestions, newTestConfigurationSchema, -} from "@chair-flight/core/app"; +} from "@chair-flight/core/question-bank"; import { HookFormSelect, NestedCheckboxSelect, @@ -39,8 +39,8 @@ import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { useBugReportDebugData } from "../../user/user-bug-report"; import { container } from "../../wraper/container"; import { useTestProgress } from "../hooks/use-test-progress"; -import type { QuestionBankName } from "@chair-flight/base/types"; -import type { NewTestConfiguration } from "@chair-flight/core/app"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; +import type { NewTestConfiguration } from "@chair-flight/core/question-bank"; import type { NestedCheckboxSelectProps } from "@chair-flight/react/components"; const useSubjects = trpc.common.tests.getSubjects.useSuspenseQuery; diff --git a/libs/react/containers/src/tests/test-search/test-search.tsx b/libs/react/containers/src/tests/test-search/test-search.tsx index d54194bf0..204f1dc2f 100644 --- a/libs/react/containers/src/tests/test-search/test-search.tsx +++ b/libs/react/containers/src/tests/test-search/test-search.tsx @@ -18,7 +18,7 @@ import { selectClasses, } from "@mui/joy"; import { z } from "zod"; -import { processTest } from "@chair-flight/core/app"; +import { processTest } from "@chair-flight/core/question-bank"; import { HookFormSelect, SearchFilters, @@ -27,7 +27,7 @@ import { import { createUsePersistenceHook } from "../../hooks/use-persistence"; import { container } from "../../wraper/container"; import { useTestProgress } from "../hooks/use-test-progress"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; type Props = { questionBank: QuestionBankName; diff --git a/libs/react/containers/tsconfig.json b/libs/react/containers/tsconfig.json index 372e2eb3f..01ead8654 100644 --- a/libs/react/containers/tsconfig.json +++ b/libs/react/containers/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../../tsconfig.base.json", "include": ["src/**/*.ts", "src/**/*.tsx"], - "files": ["../../../node_modules/@nx/next/typings/image.d.ts"], + "files": [ + "../../../node_modules/@nx/next/typings/image.d.ts", + "../../../types.d.ts" + ], "compilerOptions": { "lib": ["dom", "ESNext"], - "types": ["vitest/globals", "@testing-library/jest-dom"], - }, + "types": ["vitest/globals", "@testing-library/jest-dom"] + } } diff --git a/libs/react/games/tsconfig.json b/libs/react/games/tsconfig.json index 79c8eaa06..ec8473e0a 100644 --- a/libs/react/games/tsconfig.json +++ b/libs/react/games/tsconfig.json @@ -3,6 +3,6 @@ "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"], "compilerOptions": { - "lib": ["dom"], - }, + "lib": ["dom"] + } } diff --git a/libs/trpc/client/tsconfig.json b/libs/trpc/client/tsconfig.json index 7ffa48c6f..85a911f4d 100644 --- a/libs/trpc/client/tsconfig.json +++ b/libs/trpc/client/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "lib": ["dom", "ESNext"], - }, "include": ["src/**/*.ts", "src/**/*.tsx"], + "files": ["../../../types.d.ts"], + "compilerOptions": { + "lib": ["dom", "ESNext"] + } } diff --git a/libs/trpc/mock/tsconfig.json b/libs/trpc/mock/tsconfig.json index 0b4b1fa7f..a1434b71e 100644 --- a/libs/trpc/mock/tsconfig.json +++ b/libs/trpc/mock/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../../tsconfig.base.json", - "compilerOptions": {}, "include": ["src/**/*.ts", "src/**/*.tsx"], + "files": ["../../../types.d.ts"] } diff --git a/libs/trpc/server/src/common/providers.ts b/libs/trpc/server/src/common/providers.ts new file mode 100644 index 000000000..a6c36d0c0 --- /dev/null +++ b/libs/trpc/server/src/common/providers.ts @@ -0,0 +1,17 @@ +import { Analytics } from "@chair-flight/providers/analytics"; +import { Blog } from "@chair-flight/providers/blog"; +import { Github } from "@chair-flight/providers/github"; +import { QuestionBank } from "@chair-flight/providers/question-bank"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; + +export const questionBanks: Record = { + type: new QuestionBank("type"), + atpl: new QuestionBank("atpl"), + prep: new QuestionBank("prep"), +}; + +export const blog = new Blog(); + +export const github = new Github(); + +export const analytics = new Analytics(); diff --git a/libs/trpc/server/src/common/search-indexes.ts b/libs/trpc/server/src/common/search-indexes.ts index 2f1569db0..d95cfdfa3 100644 --- a/libs/trpc/server/src/common/search-indexes.ts +++ b/libs/trpc/server/src/common/search-indexes.ts @@ -12,7 +12,7 @@ import type { LearningObjectiveSearchResult as LoSearchResult, learningObjectiveSearchDocument as LoSearchDocument, LearningObjectiveSearchField as LoSearchField, -} from "@chair-flight/core/app"; +} from "@chair-flight/core/search"; export const learningObjectiveSearchResults = new Map(); export const questionSearchResults = new Map(); diff --git a/libs/trpc/server/src/next/static-handler.ts b/libs/trpc/server/src/next/static-handler.ts index a727a2ffe..f32b0c9fd 100644 --- a/libs/trpc/server/src/next/static-handler.ts +++ b/libs/trpc/server/src/next/static-handler.ts @@ -1,5 +1,4 @@ -import { blog } from "@chair-flight/providers/blog"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { blog, questionBanks } from "../common/providers"; import { getTrpcHelper } from "./trpc-helper"; import type { TrpcHelper } from "./trpc-helper"; import type { @@ -15,10 +14,6 @@ import type { ParsedUrlQuery } from "querystring"; const repositories = [...Object.values(questionBanks), blog]; -type FS = { - readFile: (path: string, string: "utf-8") => Promise; -}; - export const staticHandler = < Props extends Record, Params extends ParsedUrlQuery = ParsedUrlQuery, @@ -32,7 +27,7 @@ export const staticHandler = < context: GetStaticPropsContext; helper: TrpcHelper; }) => Promise>, - fs: FS, + fs: MiniFs, ): GetStaticProps => { return async (context) => { await Promise.all(repositories.map((qb) => qb.preloadForStaticRender(fs))); @@ -66,7 +61,7 @@ export const staticPathsHandler = < context: GetStaticPathsContext; helper: TrpcHelper; }) => Promise>, - fs: FS, + fs: MiniFs, ): GetStaticPaths => { return async (context) => { await Promise.all(repositories.map((qb) => qb.preloadForStaticRender(fs))); diff --git a/libs/trpc/server/src/routers/common/analytics-router.ts b/libs/trpc/server/src/routers/common/analytics-router.ts index ef4c65872..2145a0a2c 100644 --- a/libs/trpc/server/src/routers/common/analytics-router.ts +++ b/libs/trpc/server/src/routers/common/analytics-router.ts @@ -1,42 +1,15 @@ -import { z } from "zod"; import { - createPageEvent, - createTrackEvent, - generateDailyCounts, - getPageVisits, -} from "@chair-flight/providers/analytics"; + PageEventSchema, + TrackEventSchema, +} from "@chair-flight/core/analytics"; +import { analytics } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; -import type { PageEvent, SimplifiedTrackEvent } from "@chair-flight/base/types"; - -const PageEventSchema: z.ZodSchema = z.object({ - anonymousId: z.string(), - title: z.string(), - path: z.string(), - resolvedPath: z.string(), - height: z.number(), - width: z.number(), - referrer: z.string().optional(), - timestamp: z.number(), -}); - -const TrackEventSchema: z.ZodSchema = z.object({ - eventName: z.string(), - anonymousId: z.string(), - path: z.string(), - resolvedPath: z.string(), - timestamp: z.number(), - properties: z.object({}).passthrough(), -}); export const analyticsRouter = router({ createPageEvent: publicProcedure .input(PageEventSchema) - .mutation(async ({ input }) => createPageEvent(input)), + .mutation(async ({ input }) => analytics.createPageEvent(input)), trackEvent: publicProcedure .input(TrackEventSchema) - .mutation(async ({ input }) => createTrackEvent(input)), - visitsPerDay: publicProcedure.query(async () => { - await generateDailyCounts(); - return getPageVisits(); - }), + .mutation(async ({ input }) => analytics.createTrackEvent(input)), }); diff --git a/libs/trpc/server/src/routers/common/blog-router.ts b/libs/trpc/server/src/routers/common/blog-router.ts index 9958c4272..59c58e4e2 100644 --- a/libs/trpc/server/src/routers/common/blog-router.ts +++ b/libs/trpc/server/src/routers/common/blog-router.ts @@ -1,4 +1,4 @@ -import { blog } from "@chair-flight/providers/blog"; +import { blog } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const blogRouter = router({ diff --git a/libs/trpc/server/src/routers/common/github-router.ts b/libs/trpc/server/src/routers/common/github-router.ts index 2b36a51be..533e402c6 100644 --- a/libs/trpc/server/src/routers/common/github-router.ts +++ b/libs/trpc/server/src/routers/common/github-router.ts @@ -1,16 +1,12 @@ -import { - createNewIssue, - createNewQuestionPr, - newIssueSchema, -} from "@chair-flight/core/github"; -import { questionEditSchema } from "@chair-flight/core/schemas"; +import { newIssueSchema, questionEditSchema } from "@chair-flight/core/github"; +import { github } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const githubRouter = router({ createIssue: publicProcedure .input(newIssueSchema) - .mutation(({ input }) => createNewIssue(input)), + .mutation(({ input }) => github.createNewIssue(input)), updateQuestion: publicProcedure .input(questionEditSchema) - .mutation(async ({ input }) => createNewQuestionPr(input)), + .mutation(async ({ input }) => github.createNewQuestionPr(input)), }); diff --git a/libs/trpc/server/src/routers/common/search-router.ts b/libs/trpc/server/src/routers/common/search-router.ts index f26b35ac5..e6bbd80f3 100644 --- a/libs/trpc/server/src/routers/common/search-router.ts +++ b/libs/trpc/server/src/routers/common/search-router.ts @@ -1,18 +1,18 @@ import { - searchLearningObjectivesParams, - populateLearningObjectivesSearchIndex, - searchLearningObjectives, - searchAnnexesParams, populateAnnexesSearchIndex, + populateDocsSearchIndex, + populateLearningObjectivesSearchIndex, + populateQuestionsSearchIndex, searchAnnexes, - searchDocsParams, + searchAnnexesParams, searchDocs, - populateDocsSearchIndex, - searchQuestionsParams, + searchDocsParams, + searchLearningObjectives, + searchLearningObjectivesParams, searchQuestions, - populateQuestionsSearchIndex, -} from "@chair-flight/core/app"; -import { questionBanks } from "@chair-flight/providers/question-bank"; + searchQuestionsParams, +} from "@chair-flight/core/search"; +import { questionBanks } from "../../common/providers"; import { annexSearchIndex, annexSearchResults, diff --git a/libs/trpc/server/src/routers/common/tests-router.ts b/libs/trpc/server/src/routers/common/tests-router.ts index 26623d847..b3a8f24c9 100644 --- a/libs/trpc/server/src/routers/common/tests-router.ts +++ b/libs/trpc/server/src/routers/common/tests-router.ts @@ -1,8 +1,11 @@ import { z } from "zod"; import { makeMap } from "@chair-flight/base/utils"; -import { createTest, newTestConfigurationSchema } from "@chair-flight/core/app"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { + createTest, + newTestConfigurationSchema, +} from "@chair-flight/core/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const testsRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/annexes-router.ts b/libs/trpc/server/src/routers/containers/annexes-router.ts index c8f1087d7..5a6c682f6 100644 --- a/libs/trpc/server/src/routers/containers/annexes-router.ts +++ b/libs/trpc/server/src/routers/containers/annexes-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; -import { getAnnexesSearchFilters } from "@chair-flight/core/app"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { getAnnexesSearchFilters } from "@chair-flight/core/search"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const annexesContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/blog-router.ts b/libs/trpc/server/src/routers/containers/blog-router.ts index 48760af7e..9590e9892 100644 --- a/libs/trpc/server/src/routers/containers/blog-router.ts +++ b/libs/trpc/server/src/routers/containers/blog-router.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { blog } from "@chair-flight/providers/blog"; import { compileMdx } from "../../common/compile-mdx"; +import { blog } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const blogContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/docs-router.ts b/libs/trpc/server/src/routers/containers/docs-router.ts index c5c737ed6..ee555ff56 100644 --- a/libs/trpc/server/src/routers/containers/docs-router.ts +++ b/libs/trpc/server/src/routers/containers/docs-router.ts @@ -1,9 +1,9 @@ import { z } from "zod"; import { makeMap } from "@chair-flight/base/utils"; -import { getDocsSearchFilters } from "@chair-flight/core/app"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { getDocsSearchFilters } from "@chair-flight/core/search"; import { compileMdx } from "../../common/compile-mdx"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const docsContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/flashcards-router.ts b/libs/trpc/server/src/routers/containers/flashcards-router.ts index bb520d4df..2d5848e96 100644 --- a/libs/trpc/server/src/routers/containers/flashcards-router.ts +++ b/libs/trpc/server/src/routers/containers/flashcards-router.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { getRandomShuffler } from "@chair-flight/base/utils"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const flashcardsContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/layouts-router.ts b/libs/trpc/server/src/routers/containers/layouts-router.ts index bac357a1e..418a162e8 100644 --- a/libs/trpc/server/src/routers/containers/layouts-router.ts +++ b/libs/trpc/server/src/routers/containers/layouts-router.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const layoutsContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/learning-objectives-router.ts b/libs/trpc/server/src/routers/containers/learning-objectives-router.ts index 0d6683945..3bda6c608 100644 --- a/libs/trpc/server/src/routers/containers/learning-objectives-router.ts +++ b/libs/trpc/server/src/routers/containers/learning-objectives-router.ts @@ -1,11 +1,11 @@ import { z } from "zod"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; import { getLearningObjectivesSearchFilters, populateLearningObjectivesSearchIndex, populateQuestionsSearchIndex, -} from "@chair-flight/core/app"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +} from "@chair-flight/core/search"; +import { questionBanks } from "../../common/providers"; import { learningObjectiveSearchIndex, learningObjectiveSearchResults, diff --git a/libs/trpc/server/src/routers/containers/overviews-router.ts b/libs/trpc/server/src/routers/containers/overviews-router.ts index 6b93e6d27..edb076d7a 100644 --- a/libs/trpc/server/src/routers/containers/overviews-router.ts +++ b/libs/trpc/server/src/routers/containers/overviews-router.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const overviewsContainersRouter = router({ diff --git a/libs/trpc/server/src/routers/containers/questions-router.ts b/libs/trpc/server/src/routers/containers/questions-router.ts index 2f3a4a208..eb58bc02a 100644 --- a/libs/trpc/server/src/routers/containers/questions-router.ts +++ b/libs/trpc/server/src/routers/containers/questions-router.ts @@ -1,8 +1,8 @@ import { z } from "zod"; import { makeMap } from "@chair-flight/base/utils"; -import { getQuestionsSearchFilters } from "@chair-flight/core/app"; -import { questionBankNameSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankNameSchema } from "@chair-flight/core/question-bank"; +import { getQuestionsSearchFilters } from "@chair-flight/core/search"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const questionsContainersRouter = router({ @@ -24,6 +24,7 @@ export const questionsContainersRouter = router({ ); const rawAnnexes = await qb.getSome("annexes", annexIds); const rawLos = await qb.getSome("learningObjectives", loIds); + const editLink = `/modules/${questionBank}/questions/${id}/edit`; const annexes = makeMap( rawAnnexes, @@ -40,7 +41,7 @@ export const questionsContainersRouter = router({ href: `/modules/${questionBank}/learning-objectives/${lo.id}`, })); - return { template, annexes, learningObjectives }; + return { template, annexes, learningObjectives, editLink }; }), getQuestionSearch: publicProcedure .input( diff --git a/libs/trpc/server/src/routers/pages/blog-pages-router.ts b/libs/trpc/server/src/routers/pages/blog-pages-router.ts index 5b720a6c6..3262c0e6e 100644 --- a/libs/trpc/server/src/routers/pages/blog-pages-router.ts +++ b/libs/trpc/server/src/routers/pages/blog-pages-router.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { blog } from "@chair-flight/providers/blog"; +import { blog } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; export const blogPagesRouter = router({ diff --git a/libs/trpc/server/src/routers/pages/modules-pages-router.ts b/libs/trpc/server/src/routers/pages/modules-pages-router.ts index cf1749809..2dfd6790f 100644 --- a/libs/trpc/server/src/routers/pages/modules-pages-router.ts +++ b/libs/trpc/server/src/routers/pages/modules-pages-router.ts @@ -1,8 +1,8 @@ import { z } from "zod"; -import { questionBankResourceSchema } from "@chair-flight/core/schemas"; -import { questionBanks } from "@chair-flight/providers/question-bank"; +import { questionBankResourceSchema } from "@chair-flight/core/question-bank"; +import { questionBanks } from "../../common/providers"; import { publicProcedure, router } from "../../config/trpc"; -import type { QuestionBankName } from "@chair-flight/base/types"; +import type { QuestionBankName } from "@chair-flight/core/question-bank"; export const modulesPagesRouter = router({ getIndexGenerationPaths: publicProcedure diff --git a/libs/trpc/server/tsconfig.json b/libs/trpc/server/tsconfig.json index 2f1db5f5c..de61c4fdb 100644 --- a/libs/trpc/server/tsconfig.json +++ b/libs/trpc/server/tsconfig.json @@ -1,7 +1,5 @@ { "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "lib": ["ESNext", "dom"], - }, "include": ["src/**/*.ts"], + "files": ["../../../types.d.ts"] } diff --git a/tsconfig.base.json b/tsconfig.base.json index 1d1a32b9c..d6de9cc6b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -31,12 +31,15 @@ "@chair-flight/base/errors": ["libs/base/errors/src/index.ts"], "@chair-flight/base/types": ["libs/base/types/src/index.ts"], "@chair-flight/base/utils": ["libs/base/utils/src/index.ts"], + "@chair-flight/core/analytics": ["libs/core/analytics/src/index.ts"], + "@chair-flight/core/blog": ["libs/core/blog/src/index.ts"], + "@chair-flight/core/github": ["libs/core/github/src/index.ts"], + "@chair-flight/core/question-bank": ["libs/core/question-bank/src/index.ts"], + "@chair-flight/core/search": ["libs/core/search/src/index.ts"], "@chair-flight/providers/analytics": ["libs/providers/analytics/src/index.ts"], "@chair-flight/providers/blog": ["libs/providers/blog/src/index.ts"], + "@chair-flight/providers/github": ["libs/providers/github/src/index.ts"], "@chair-flight/providers/question-bank": ["libs/providers/question-bank/src/index.ts"], - "@chair-flight/core/app": ["libs/core/app/src/index.ts"], - "@chair-flight/core/github": ["libs/core/github/src/index.ts"], - "@chair-flight/core/schemas": ["libs/core/schemas/src/index.ts"], "@chair-flight/react/analytics": ["libs/react/analytics/src/index.ts"], "@chair-flight/react/components": ["libs/react/components/src/index.ts"], "@chair-flight/react/containers": ["libs/react/containers/src/index.ts"], diff --git a/types.d.ts b/types.d.ts new file mode 100644 index 000000000..ff37b1fdb --- /dev/null +++ b/types.d.ts @@ -0,0 +1,20 @@ +import "@total-typescript/ts-reset"; + +declare global { + /** + * A convenience type that replaces the FS types. + * + * This is used to parse the question bank at build time, but not have + * FS included at runtime, which is not compatible with EDGE. + */ + interface MiniFs { + readFile: (path: string, string: "utf-8") => Promise; + } + + /** + * A convenience type that represents MDX documents. + */ + interface MdxDocument { + content: string; + } +}