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;
+ }
+}