From 625063fe3a22b1386956afa0e6c2d2eddab10ebd Mon Sep 17 00:00:00 2001 From: Eddy Chen <89349085+ecxyzzy@users.noreply.github.com> Date: Sun, 26 Nov 2023 22:22:32 -0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20migrate=20to=20postgres=20(?= =?UTF-8?q?#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-prod.yml | 1 - apps/api/src/routes/v1/rest/week/+endpoint.ts | 4 +- apps/api/src/routes/v1/rest/week/schema.ts | 19 +- libs/db/prisma/schema.prisma | 26 +- libs/db/sql/access_control.sql | 82 +++++ package.json | 1 + pnpm-lock.yaml | 304 ++++++------------ prettier.config.cjs | 13 +- tools/registrar-scraper/src/index.ts | 15 - 9 files changed, 202 insertions(+), 263 deletions(-) create mode 100644 libs/db/sql/access_control.sql diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index f433c33b..379c5b58 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -24,7 +24,6 @@ env: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} CERTIFICATE_ARN: ${{ secrets.CERTIFICATE_ARN }} DATABASE_URL: ${{ secrets.DATABASE_URL_PRODUCTION }} - DATABASE_URL_REGISTRAR_SCRAPER: ${{ secrets.DATABASE_URL_REGISTRAR_SCRAPER }} DATABASE_URL_WEBSOC_SCRAPER: ${{ secrets.DATABASE_URL_WEBSOC_SCRAPER }} HOSTED_ZONE_ID: ${{ secrets.HOSTED_ZONE_ID }} NODE_ENV: production diff --git a/apps/api/src/routes/v1/rest/week/+endpoint.ts b/apps/api/src/routes/v1/rest/week/+endpoint.ts index 61738cee..9c77d9e2 100644 --- a/apps/api/src/routes/v1/rest/week/+endpoint.ts +++ b/apps/api/src/routes/v1/rest/week/+endpoint.ts @@ -19,12 +19,12 @@ export const GET = createHandler(async (event, context, res) => { try { const parsedQuery = QuerySchema.parse(query); - if (!parsedQuery.year) { + if (!parsedQuery.hasParams) { const [month, day, year] = new Date() .toLocaleString("en-US", { timeZone: "America/Los_Angeles" }) .split(",")[0] .split("/") - .map((x) => parseInt(x, 10)); + .map((x) => Number.parseInt(x, 10)); parsedQuery.year = year; parsedQuery.month = month; diff --git a/apps/api/src/routes/v1/rest/week/schema.ts b/apps/api/src/routes/v1/rest/week/schema.ts index 32409574..2e574cbb 100644 --- a/apps/api/src/routes/v1/rest/week/schema.ts +++ b/apps/api/src/routes/v1/rest/week/schema.ts @@ -20,19 +20,10 @@ export const QuerySchema = z message: "The day provided is not valid for the month provided", }, ) - .or( - z.object({ - year: z.undefined(), - month: z.undefined(), - day: z.undefined(), - }), - ); - -z.setErrorMap((issue, ctx) => ({ - message: - issue.code === z.ZodIssueCode.invalid_union - ? "All fields must either be provided or left blank" - : ctx.defaultError, -})); + .transform((params) => ({ + hasParams: true, + ...params, + })) + .or(z.null().transform(() => ({ year: -1, month: -1, day: -1, hasParams: false }))); export type Query = z.infer; diff --git a/libs/db/prisma/schema.prisma b/libs/db/prisma/schema.prisma index 8a35d765..73496a1e 100644 --- a/libs/db/prisma/schema.prisma +++ b/libs/db/prisma/schema.prisma @@ -4,12 +4,13 @@ generator client { } datasource db { - provider = "mysql" - url = env("DATABASE_URL") - shadowDatabaseUrl = env("SHADOW_DATABASE_URL") + provider = "postgresql" + url = env("DATABASE_URL") } -// Do not modify anything above this line unless you know what you are doing. +// The parts above this line are used to configure the Prisma Client directly +// and has nothing to do with the database schema. +// You probably do not need to modify it. // Enums @@ -86,23 +87,6 @@ model Course { terms Json } -model CoursePrereq { - courseId String - forCourseId String - - @@id([courseId, forCourseId]) - @@unique([courseId, forCourseId], name: "idx") -} - -model CourseHistory { - ucinetid String - courseId String - term String - - @@id([ucinetid, courseId, term]) - @@unique([ucinetid, courseId, term], name: "idx") -} - model Instructor { ucinetid String @id name String diff --git a/libs/db/sql/access_control.sql b/libs/db/sql/access_control.sql new file mode 100644 index 00000000..05c80021 --- /dev/null +++ b/libs/db/sql/access_control.sql @@ -0,0 +1,82 @@ +-- This file is used to control access to the API database. +-- You probably do not need to modify this. +ALTER DEFAULT PRIVILEGES IN SCHEMA dev +GRANT +SELECT + ON TABLES TO public; + +ALTER DEFAULT PRIVILEGES IN SCHEMA public +GRANT +SELECT + ON TABLES TO public; + +CREATE ROLE api_staging_user LOGIN; + +GRANT USAGE ON SCHEMA dev TO api_staging_user; + +GRANT +SELECT + ON ALL TABLES IN SCHEMA dev TO api_staging_user; + +GRANT USAGE, +SELECT + ON ALL SEQUENCES IN SCHEMA dev TO api_staging_user; + +GRANT INSERT ON dev."CalendarTerm" TO api_staging_user; + +CREATE ROLE api_prod_user LOGIN; + +GRANT USAGE ON SCHEMA public TO api_prod_user; + +GRANT +SELECT + ON ALL TABLES IN SCHEMA public TO api_prod_user; + +GRANT USAGE, +SELECT + ON ALL SEQUENCES IN SCHEMA public TO api_prod_user; + +GRANT INSERT ON public."CalendarTerm" TO api_prod_user; + +CREATE ROLE api_websoc_scraper LOGIN; + +GRANT USAGE ON SCHEMA public TO api_websoc_scraper; + +GRANT USAGE, +SELECT + ON ALL SEQUENCES IN SCHEMA public TO api_websoc_scraper; + +GRANT +SELECT +, + INSERT, +UPDATE, +DELETE ON public."WebsocEnrollmentHistory" TO api_websoc_scraper; + +GRANT +SELECT +, + INSERT, +UPDATE, +DELETE ON public."WebsocSection" TO api_websoc_scraper; + +GRANT +SELECT +, + INSERT, +UPDATE, +DELETE ON public."WebsocSectionInstructor" TO api_websoc_scraper; + +GRANT +SELECT +, + INSERT, +UPDATE, +DELETE ON public."WebsocSectionMeeting" TO api_websoc_scraper; + +GRANT +SELECT +, + INSERT, +UPDATE, +DELETE ON public."WebsocSectionMeetingBuilding" TO api_websoc_scraper; diff --git a/package.json b/package.json index 8e92e5ab..1ceb6118 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "prettier": "3.1.0", "prettier-plugin-packagejson": "2.4.6", "prettier-plugin-prisma": "5.0.0", + "prettier-plugin-sql": "0.16.0", "turbo": "1.10.16", "typescript": "5.2.2", "unconfig": "0.3.11" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 259f6257..4045bc21 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 2.106.1(constructs@10.2.69) cz-conventional-changelog: specifier: 3.3.0 - version: 3.3.0 + version: 3.3.0(typescript@5.2.2) devmoji: specifier: 2.3.0 version: 2.3.0 @@ -74,6 +74,9 @@ importers: prettier-plugin-prisma: specifier: 5.0.0 version: 5.0.0(prettier@3.1.0) + prettier-plugin-sql: + specifier: 0.16.0 + version: 0.16.0(prettier@3.1.0) turbo: specifier: 1.10.16 version: 1.10.16 @@ -290,7 +293,7 @@ importers: version: 8.0.0 tsup: specifier: 7.2.0 - version: 7.2.0(ts-node@10.9.1)(typescript@5.2.2) + version: 7.2.0(typescript@5.2.2) tsx: specifier: 4.1.1 version: 4.1.1 @@ -2802,16 +2805,6 @@ packages: conventional-changelog-conventionalcommits: 7.0.2 dev: true - /@commitlint/config-validator@17.6.7: - resolution: {integrity: sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==} - engines: {node: '>=v14'} - requiresBuild: true - dependencies: - '@commitlint/types': 17.4.4 - ajv: 8.12.0 - dev: true - optional: true - /@commitlint/config-validator@18.4.0: resolution: {integrity: sha512-1y6qHMU3o4cYQSK+Y9EnmH6H1GRiwQGjnLIUOIKlekrmfc8MrMk1ByNmb8od4vK3qHJAaL/77/5n+1uyyIF5dA==} engines: {node: '>=v18'} @@ -2832,13 +2825,6 @@ packages: lodash.upperfirst: 4.3.1 dev: true - /@commitlint/execute-rule@17.4.0: - resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==} - engines: {node: '>=v14'} - requiresBuild: true - dev: true - optional: true - /@commitlint/execute-rule@18.4.0: resolution: {integrity: sha512-g013SWki6ZWhURBLOSXTaVQGWHdA0QlPJGiW4a+YpThezmJOemvc4LiKVpn13AjSKQ40QnmBqpBrxujOaSo+3A==} engines: {node: '>=v18'} @@ -2870,31 +2856,6 @@ packages: '@commitlint/types': 18.4.0 dev: true - /@commitlint/load@17.8.0: - resolution: {integrity: sha512-9VnGXYJCP4tXmR4YrwP8n5oX6T5ZsHfPQq6WuUQOvAI+QsDQMaTGgTRXr7us+xsjz+b+mMBSagogqfUx2aixyw==} - engines: {node: '>=v14'} - requiresBuild: true - dependencies: - '@commitlint/config-validator': 17.6.7 - '@commitlint/execute-rule': 17.4.0 - '@commitlint/resolve-extends': 17.6.7 - '@commitlint/types': 17.4.4 - '@types/node': 20.5.1 - chalk: 4.1.2 - cosmiconfig: 8.1.3 - cosmiconfig-typescript-loader: 4.3.0(@types/node@20.5.1)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.2.2) - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 - resolve-from: 5.0.0 - ts-node: 10.9.1(@types/node@18.18.5)(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - dev: true - optional: true - /@commitlint/load@18.4.2(typescript@5.2.2): resolution: {integrity: sha512-CKmzXdF9XwZJoVijAqpUlV9qzZOkyiYni4KuSCtTZVAAVudi9H84cJ4FqZxSwEP9G21vmoJiNrW8G042AsduVg==} engines: {node: '>=v18'} @@ -2940,20 +2901,6 @@ packages: minimist: 1.2.8 dev: true - /@commitlint/resolve-extends@17.6.7: - resolution: {integrity: sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==} - engines: {node: '>=v14'} - requiresBuild: true - dependencies: - '@commitlint/config-validator': 17.6.7 - '@commitlint/types': 17.4.4 - import-fresh: 3.3.0 - lodash.mergewith: 4.6.2 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - dev: true - optional: true - /@commitlint/resolve-extends@18.4.0: resolution: {integrity: sha512-qhgU6ach+S6sJMD9NjCYiEycOObGhxzWQLQzqlScJCv9zkPs15Bg0ffLXTQ3z7ipXv46XEKYMnSJzjLRw2Tlkg==} engines: {node: '>=v18'} @@ -2989,15 +2936,6 @@ packages: find-up: 5.0.0 dev: true - /@commitlint/types@17.4.4: - resolution: {integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==} - engines: {node: '>=v14'} - requiresBuild: true - dependencies: - chalk: 4.1.2 - dev: true - optional: true - /@commitlint/types@18.4.0: resolution: {integrity: sha512-MKeaFxt0I9fhqUb2E+YIzX/gZtmkuodJET/XKiZIMvXUff8Ee4Ih86eLg+yAm2jf1pwGBmU02uNOp0y094w2Uw==} engines: {node: '>=v18'} @@ -3005,14 +2943,6 @@ packages: chalk: 4.1.2 dev: true - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - requiresBuild: true - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - /@dabh/diagnostics@2.0.3: resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} dependencies: @@ -4377,12 +4307,6 @@ packages: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - requiresBuild: true - dev: true - /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} @@ -4405,14 +4329,6 @@ packages: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - requiresBuild: true - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@leichtgewicht/ip-codec@2.0.4: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} dev: false @@ -5207,26 +5123,6 @@ packages: resolution: {integrity: sha512-12HWfYmgUl4M2o76/TFufGtI68wl2k/b8qPrIrG7ci9YJLrpAtadpy897Bz5v29Mlkr7a1Hq4KHdQTKtU+2rhQ==} dev: true - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - requiresBuild: true - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - requiresBuild: true - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - requiresBuild: true - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - requiresBuild: true - dev: true - /@tsconfig/node18@18.2.2: resolution: {integrity: sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==} dev: true @@ -5386,12 +5282,6 @@ packages: /@types/node@18.18.5: resolution: {integrity: sha512-4slmbtwV59ZxitY4ixUZdy1uRLf9eSIvBWPQxNjhHYWEtn0FryfKpyS2cvADYXTayWdKEIsJengncrVvkI4I6A==} - /@types/node@20.5.1: - resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==} - requiresBuild: true - dev: true - optional: true - /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -5802,6 +5692,7 @@ packages: /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} + dev: false /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} @@ -5953,11 +5844,6 @@ packages: normalize-path: 3.0.0 picomatch: 2.3.1 - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - requiresBuild: true - dev: true - /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} dev: false @@ -6770,13 +6656,13 @@ packages: engines: {node: '>= 12'} dev: false - /commitizen@4.3.0: + /commitizen@4.3.0(typescript@5.2.2): resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==} engines: {node: '>= 12'} hasBin: true dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0 + cz-conventional-changelog: 3.3.0(typescript@5.2.2) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -6790,8 +6676,7 @@ packages: strip-bom: 4.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - typescript dev: true /commondir@1.0.1: @@ -6962,23 +6847,6 @@ packages: object-assign: 4.1.1 vary: 1.1.2 - /cosmiconfig-typescript-loader@4.3.0(@types/node@20.5.1)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.2.2): - resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==} - engines: {node: '>=12', npm: '>=6'} - requiresBuild: true - peerDependencies: - '@types/node': '*' - cosmiconfig: '>=7' - ts-node: '>=10' - typescript: '>=3' - dependencies: - '@types/node': 20.5.1 - cosmiconfig: 8.1.3 - ts-node: 10.9.1(@types/node@18.18.5)(typescript@5.2.2) - typescript: 5.2.2 - dev: true - optional: true - /cosmiconfig-typescript-loader@5.0.0(@types/node@18.18.5)(cosmiconfig@8.3.6)(typescript@5.2.2): resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} @@ -7023,6 +6891,7 @@ packages: js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 + dev: false /cosmiconfig@8.3.6(typescript@5.2.2): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} @@ -7040,11 +6909,6 @@ packages: typescript: 5.2.2 dev: true - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - requiresBuild: true - dev: true - /cross-fetch@3.1.6: resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} dependencies: @@ -7272,21 +7136,20 @@ packages: resolution: {integrity: sha512-NDshLupGa7gp4UG4sSNIqwYJqgSwvds0SvENntxoVoVvTzXcrHvd5gG2MWpbRpSNvk59dlmIe1IwNvSxN4IVmg==} dev: false - /cz-conventional-changelog@3.3.0: + /cz-conventional-changelog@3.3.0(typescript@5.2.2): resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} engines: {node: '>= 10'} dependencies: chalk: 2.4.2 - commitizen: 4.3.0 + commitizen: 4.3.0(typescript@5.2.2) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.3 optionalDependencies: - '@commitlint/load': 17.8.0 + '@commitlint/load': 18.4.2(typescript@5.2.2) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - typescript dev: true /dargs@7.0.0: @@ -7519,18 +7382,16 @@ packages: ts-interface-checker: 1.0.0 dev: true - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - requiresBuild: true - dev: true - /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} dependencies: path-type: 4.0.0 + /discontinuous-range@1.0.0: + resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} + dev: true + /dns-equal@1.0.0: resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} dev: false @@ -8626,6 +8487,11 @@ packages: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} dev: false + /get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: true + /get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} @@ -9781,6 +9647,11 @@ packages: engines: {'0': node >= 0.2.0} dev: true + /jsox@1.2.118: + resolution: {integrity: sha512-ubYWn4WOc7HA7icvcQuIni1I7Xx4bI4KbRXbXzlr5e48hvdizeAbflBx97B629ZNH5RZnQ657Z5Z8dFgxFVrSQ==} + hasBin: true + dev: true + /keyv@3.1.0: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} dependencies: @@ -10068,11 +9939,6 @@ packages: semver: 6.3.1 dev: false - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - requiresBuild: true - dev: true - /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -10272,6 +10138,10 @@ packages: ufo: 1.3.1 dev: true + /moo@0.5.2: + resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} + dev: true + /mrmime@1.0.1: resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} engines: {node: '>=10'} @@ -10315,6 +10185,16 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + /nearley@2.20.1: + resolution: {integrity: sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==} + hasBin: true + dependencies: + commander: 2.20.3 + moo: 0.5.2 + railroad-diagrams: 1.0.0 + randexp: 0.4.6 + dev: true + /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -10358,6 +10238,13 @@ packages: /node-releases@2.0.12: resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} + /node-sql-parser@4.11.0: + resolution: {integrity: sha512-ElheoPibjc7IVyRdsORgkzJi0DWm3f0LYSsm/eJIeUt3M/csDLTblLDR4zl5Qi7jmVjJ1KpEkPKSbgVGEzU5Xw==} + engines: {node: '>=8'} + dependencies: + big-integer: 1.6.51 + dev: true + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -10897,7 +10784,7 @@ packages: postcss-selector-parser: 6.0.13 dev: false - /postcss-load-config@4.0.1(ts-node@10.9.1): + /postcss-load-config@4.0.1: resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} engines: {node: '>= 14'} peerDependencies: @@ -10910,7 +10797,6 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - ts-node: 10.9.1(@types/node@18.18.5)(typescript@5.2.2) yaml: 2.3.1 dev: true @@ -11275,6 +11161,19 @@ packages: prettier: 3.1.0 dev: true + /prettier-plugin-sql@0.16.0(prettier@3.1.0): + resolution: {integrity: sha512-ISKL8EpiW9VSaHxmezr/lYiBNgcJvCF5V4NR2SCGZcv4vawn1negBD5jVVf7VN/wqTLd56U/taJiQPhQdbrYdA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + prettier: ^3.0.3 + dependencies: + jsox: 1.2.118 + node-sql-parser: 4.11.0 + prettier: 3.1.0 + sql-formatter: 13.1.0 + tslib: 2.6.2 + dev: true + /prettier@3.1.0: resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} engines: {node: '>=14'} @@ -11398,6 +11297,18 @@ packages: engines: {node: '>=8'} dev: true + /railroad-diagrams@1.0.0: + resolution: {integrity: sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==} + dev: true + + /randexp@0.4.6: + resolution: {integrity: sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==} + engines: {node: '>=0.12'} + dependencies: + discontinuous-range: 1.0.0 + ret: 0.1.15 + dev: true + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -11913,6 +11824,11 @@ packages: signal-exit: 3.0.7 dev: true + /ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + dev: true + /retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} @@ -12415,6 +12331,15 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: false + /sql-formatter@13.1.0: + resolution: {integrity: sha512-/nZQXuN7KzipFNM20ko+dHY4kOr9rymSfZLUDED8rhx3m8OK5y74jcyN+y1L51ZqHqiB0kp40VdpZP99uWvQdA==} + hasBin: true + dependencies: + argparse: 2.0.1 + get-stdin: 8.0.0 + nearley: 2.20.1 + dev: true + /stable@0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' @@ -12847,38 +12772,6 @@ packages: resolution: {integrity: sha512-yUeWbFBDiwPodNqrqpvQpGWheL6PvNu2/pVAb9yy2vzdkkflCgwVA4U2akByPCXzYTum3/5/nB92yKuiLpSo/Q==} dev: true - /ts-node@10.9.1(@types/node@18.18.5)(typescript@5.2.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - requiresBuild: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 18.18.5 - acorn: 8.10.0 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.2.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -12895,7 +12788,11 @@ packages: /tslib@2.5.2: resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==} - /tsup@7.2.0(ts-node@10.9.1)(typescript@5.2.2): + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + + /tsup@7.2.0(typescript@5.2.2): resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} engines: {node: '>=16.14'} hasBin: true @@ -12919,7 +12816,7 @@ packages: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.1(ts-node@10.9.1) + postcss-load-config: 4.0.1 resolve-from: 5.0.0 rollup: 3.26.3 source-map: 0.8.0-beta.0 @@ -13380,11 +13277,6 @@ packages: hasBin: true dev: false - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - requiresBuild: true - dev: true - /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -13862,12 +13754,6 @@ packages: yargs-parser: 21.1.1 dev: true - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - requiresBuild: true - dev: true - /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/prettier.config.cjs b/prettier.config.cjs index 891a43d9..bcba3a13 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -10,7 +10,18 @@ */ const config = { printWidth: 100, - plugins: ["prettier-plugin-packagejson", "prettier-plugin-prisma"], + plugins: ["prettier-plugin-packagejson", "prettier-plugin-prisma", "prettier-plugin-sql"], + overrides: [ + { + files: "*.sql", + options: { + language: "postgresql", + keywordCase: "upper", + expressionWidth: 80, + tabWidth: 2, + }, + }, + ], }; module.exports = config; diff --git a/tools/registrar-scraper/src/index.ts b/tools/registrar-scraper/src/index.ts index 8f49b8b9..a0755241 100644 --- a/tools/registrar-scraper/src/index.ts +++ b/tools/registrar-scraper/src/index.ts @@ -47,25 +47,10 @@ async function main() { data: Object.entries(courseInfo).map(createCourses(instructorInfo, prereqInfo, prereqLists)), skipDuplicates: true, }), - prisma.coursePrereq.deleteMany({ where: { courseId: { in: Object.keys(prereqInfo) } } }), - prisma.coursePrereq.createMany({ - data: Object.entries(prereqLists).flatMap(([forCourseId, prereqList]) => - prereqList.map((courseId) => ({ courseId, forCourseId })), - ), - skipDuplicates: true, - }), prisma.instructor.deleteMany({ where: { ucinetid: { in: Object.keys(instructorInfo) } } }), prisma.instructor.createMany({ data: Object.values(instructorInfo), }), - prisma.courseHistory.deleteMany({ where: { ucinetid: { in: Object.keys(instructorInfo) } } }), - prisma.courseHistory.createMany({ - data: Object.entries(instructorInfo).flatMap(([ucinetid, { courseHistory }]) => - Object.entries(courseHistory).flatMap(([courseId, terms]) => - terms.map((term) => ({ ucinetid, courseId, term })), - ), - ), - }), ]); }