From 7a7c578971b1831dcdc944361244dce9bc84aa92 Mon Sep 17 00:00:00 2001 From: Miorel-Lucian Palii Date: Sun, 15 Sep 2024 11:07:58 -0700 Subject: [PATCH 1/2] download-leetcode-submissions --- .../post-leetcode-potd-to-discord.yml | 2 +- .../nullthrows-npm-1.1.1-3d1f817134.patch | 21 ++++++ workspaces/adventure-pack/package.json | 2 +- .../download-leetcode-submissions/.gitignore | 2 + .../download-leetcode-submissions/README.md | 23 ++++++- .../eslint.config.mjs | 2 +- .../package.json | 10 ++- .../src/getDirnameForSubmission.ts | 2 +- .../src/getFilenameForSubmission.ts | 4 +- .../download-leetcode-submissions/src/main.ts | 14 ++-- .../src/readPriorSubmissions.ts | 4 +- .../src/writeSubmissionsMetadataAndHashes.ts | 8 +-- .../webpack.config.ts | 68 +++++++++++++++++++ .../generate-health-report/package.json | 2 +- workspaces/leetcode-api/package.json | 2 +- workspaces/util/package.json | 2 +- yarn.lock | 21 ++++-- 17 files changed, 158 insertions(+), 31 deletions(-) create mode 100644 .yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch create mode 100644 workspaces/download-leetcode-submissions/webpack.config.ts diff --git a/.github/workflows/post-leetcode-potd-to-discord.yml b/.github/workflows/post-leetcode-potd-to-discord.yml index d8142d8c..b63bce16 100644 --- a/.github/workflows/post-leetcode-potd-to-discord.yml +++ b/.github/workflows/post-leetcode-potd-to-discord.yml @@ -34,7 +34,7 @@ jobs: uses: ./.github/workflows/set-up-everything - name: Prepare secrets - run: (cd workspaces/post-leetcode-potd-to-discord && echo "$SECRETS_FILE" > secrets_DO_NOT_COMMIT_OR_SHARE.json) + run: echo "$SECRETS_FILE" > workspaces/post-leetcode-potd-to-discord/secrets_DO_NOT_COMMIT_OR_SHARE.json env: SECRETS_FILE: ${{ secrets.SECRETS_FILE }} diff --git a/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch b/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch new file mode 100644 index 00000000..5b4890b8 --- /dev/null +++ b/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch @@ -0,0 +1,21 @@ +diff --git a/nullthrows.d.ts b/nullthrows.d.ts +index d4953f2f47b79701e5f125b9c041fb185668dd53..a39a37b30cd206e037ecbbb66bc90dacd6adb3af 100644 +--- a/nullthrows.d.ts ++++ b/nullthrows.d.ts +@@ -1,5 +1,15 @@ + /** + * Throws if value is null or undefined, otherwise returns value. + */ ++declare function nullthrows( ++ value?: T | null, ++ message?: string, ++): NonNullable; ++ ++// Patched based on https://github.com/microsoft/TypeScript/issues/46770#issuecomment-1039459991 and https://github.com/zertosh/nullthrows/pull/15 ++ ++declare namespace nullthrows { ++ export { nullthrows as default }; ++} ++export = nullthrows; + +-export default function nullthrows(value?: T | null, message?: string): T; diff --git a/workspaces/adventure-pack/package.json b/workspaces/adventure-pack/package.json index 53a65c2d..064f5ddd 100644 --- a/workspaces/adventure-pack/package.json +++ b/workspaces/adventure-pack/package.json @@ -59,7 +59,7 @@ "dependencies": { "immutability-helper": "3.1.1", "invariant": "2.2.4", - "nullthrows": "1.1.1", + "nullthrows": "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch", "react": "18.3.1", "react-dom": "18.3.1", "react-syntax-highlighter": "15.5.0" diff --git a/workspaces/download-leetcode-submissions/.gitignore b/workspaces/download-leetcode-submissions/.gitignore index 254665fd..01d9bea2 100644 --- a/workspaces/download-leetcode-submissions/.gitignore +++ b/workspaces/download-leetcode-submissions/.gitignore @@ -3,3 +3,5 @@ secrets_DO_NOT_COMMIT_OR_SHARE.json submissions/ submissions.jsonl submissions.sha512 + +dist/ diff --git a/workspaces/download-leetcode-submissions/README.md b/workspaces/download-leetcode-submissions/README.md index 2d37349e..ad7ba578 100644 --- a/workspaces/download-leetcode-submissions/README.md +++ b/workspaces/download-leetcode-submissions/README.md @@ -19,7 +19,7 @@ To use: nano secrets_DO_NOT_COMMIT_OR_SHARE.json ``` -2. **Run the script!** +2. **Run the script!** You can run a development version: ```sh # Install dependencies, if you haven't already: @@ -33,7 +33,26 @@ To use: yarn start ``` -Submissions will be downloaded to a directory named `submissions`, grouped by problem and problem number range. Filenames take the form `{yyyymmdd-date}-{submission-id}-{result}.{extension}`, resulting in full paths like `submissions/2101-2200/2163-kth-distinct-string-in-an-array/20240805-1345920313-ac.c` for an accepted C solution submitted on August 5th, 2024. + Or, build and run a distribution version: + + ```sh + # It's easiest to do this from the package's directory: + cd workspaces/download-leetcode-submissions + + # Install dependencies, if you haven't already: + yarn + + # Package the script into an executable: + yarn build + + # Run it with Node! + node dist/download-leetcode-submissions.cjs + + # Or if your system can handle executable files, try running it directly: + ./dist/download-leetcode-submissions.cjs + ``` + + Submissions will be downloaded to a directory named `submissions`, grouped by problem and problem number range. Filenames take the form `{yyyymmdd-date}-{submission-id}-{result}.{extension}`, resulting in full paths like `submissions/2101-2200/2163-kth-distinct-string-in-an-array/20240805-1345920313-ac.c` for an accepted C solution submitted on August 5th, 2024. ## Metadata Files diff --git a/workspaces/download-leetcode-submissions/eslint.config.mjs b/workspaces/download-leetcode-submissions/eslint.config.mjs index 82476bdb..2eaeb5ee 100644 --- a/workspaces/download-leetcode-submissions/eslint.config.mjs +++ b/workspaces/download-leetcode-submissions/eslint.config.mjs @@ -1,3 +1,3 @@ import config from "@code-chronicles/eslint-config"; -export default [...config, { ignores: ["submissions/"] }]; +export default [...config, { ignores: ["dist/", "submissions/"] }]; diff --git a/workspaces/download-leetcode-submissions/package.json b/workspaces/download-leetcode-submissions/package.json index 6afa8f83..979db703 100644 --- a/workspaces/download-leetcode-submissions/package.json +++ b/workspaces/download-leetcode-submissions/package.json @@ -12,8 +12,10 @@ "name": "Miorel-Lucian Palii", "url": "https://github.com/miorel" }, + "type": "module", "exports": "./src/main.ts", "scripts": { + "build": "cross-env NODE_OPTIONS=\"--import tsx\" webpack && chmod +x dist/download-leetcode-submissions.cjs", "format": "prettier --color --write .", "lint": "eslint --color --max-warnings=0 .", "start": "tsx src/main.ts", @@ -22,15 +24,19 @@ "dependencies": { "@code-chronicles/leetcode-api": "workspace:*", "@code-chronicles/util": "workspace:*", - "nullthrows": "1.1.1", + "nullthrows": "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch", "zod": "3.23.8" }, "devDependencies": { "@code-chronicles/eslint-config": "workspace:*", "@types/node": "22.5.5", + "cross-env": "7.0.3", "eslint": "9.10.0", "prettier": "3.3.3", + "ts-loader": "9.5.1", "tsx": "4.19.1", - "typescript": "5.6.2" + "typescript": "5.6.2", + "webpack": "5.94.0", + "webpack-cli": "5.1.4" } } diff --git a/workspaces/download-leetcode-submissions/src/getDirnameForSubmission.ts b/workspaces/download-leetcode-submissions/src/getDirnameForSubmission.ts index 5187992a..e4afb2c9 100644 --- a/workspaces/download-leetcode-submissions/src/getDirnameForSubmission.ts +++ b/workspaces/download-leetcode-submissions/src/getDirnameForSubmission.ts @@ -1,6 +1,6 @@ import path from "node:path"; -import type { TransformedSubmission } from "./transformSubmission"; +import type { TransformedSubmission } from "./transformSubmission.js"; const PROBLEMS_PER_GROUP = 100; diff --git a/workspaces/download-leetcode-submissions/src/getFilenameForSubmission.ts b/workspaces/download-leetcode-submissions/src/getFilenameForSubmission.ts index 0610c96d..c5db38bb 100644 --- a/workspaces/download-leetcode-submissions/src/getFilenameForSubmission.ts +++ b/workspaces/download-leetcode-submissions/src/getFilenameForSubmission.ts @@ -3,8 +3,8 @@ import nullthrows from "nullthrows"; import { SUBMISSION_STATUS_TO_ABBREVIATION } from "@code-chronicles/leetcode-api"; import { timestampInSecondsToYearMonthDay } from "@code-chronicles/util/timestampInSecondsToYearMonthDay"; -import { LANGUAGE_TO_FILE_EXTENSION } from "./constants"; -import type { TransformedSubmission } from "./transformSubmission"; +import { LANGUAGE_TO_FILE_EXTENSION } from "./constants.js"; +import type { TransformedSubmission } from "./transformSubmission.js"; export function getFilenameForSubmission({ id, diff --git a/workspaces/download-leetcode-submissions/src/main.ts b/workspaces/download-leetcode-submissions/src/main.ts index e2eb6bc7..32e4a2c8 100644 --- a/workspaces/download-leetcode-submissions/src/main.ts +++ b/workspaces/download-leetcode-submissions/src/main.ts @@ -10,16 +10,16 @@ import { promiseAllLimitingConcurrency } from "@code-chronicles/util/promiseAllL import { sleep } from "@code-chronicles/util/sleep"; import { whileReturnsTrueAsync } from "@code-chronicles/util/whileReturnsTrueAsync"; -import { CONCURRENCY_LIMIT } from "./constants"; -import { getFilenameForSubmission } from "./getFilenameForSubmission"; -import { getDirnameForSubmission } from "./getDirnameForSubmission"; -import { readPriorSubmissions } from "./readPriorSubmissions"; -import { readSecrets } from "./readSecrets"; +import { CONCURRENCY_LIMIT } from "./constants.js"; +import { getDirnameForSubmission } from "./getDirnameForSubmission.js"; +import { getFilenameForSubmission } from "./getFilenameForSubmission.js"; +import { readPriorSubmissions } from "./readPriorSubmissions.js"; +import { readSecrets } from "./readSecrets.js"; import { transformSubmission, type TransformedSubmission, -} from "./transformSubmission"; -import { writeSubmissionsMetadataAndHashes } from "./writeSubmissionsMetadataAndHashes"; +} from "./transformSubmission.js"; +import { writeSubmissionsMetadataAndHashes } from "./writeSubmissionsMetadataAndHashes.js"; async function main(): Promise { // TODO: maybe create the file from a template if it doesn't exist diff --git a/workspaces/download-leetcode-submissions/src/readPriorSubmissions.ts b/workspaces/download-leetcode-submissions/src/readPriorSubmissions.ts index ba7c0f42..07b709b1 100644 --- a/workspaces/download-leetcode-submissions/src/readPriorSubmissions.ts +++ b/workspaces/download-leetcode-submissions/src/readPriorSubmissions.ts @@ -2,8 +2,8 @@ import fsPromises from "node:fs/promises"; import { getLines } from "@code-chronicles/util/getLines"; -import { METADATA_FILE } from "./constants"; -import type { TransformedSubmission } from "./transformSubmission"; +import { METADATA_FILE } from "./constants.js"; +import type { TransformedSubmission } from "./transformSubmission.js"; export async function readPriorSubmissions(): Promise< Map diff --git a/workspaces/download-leetcode-submissions/src/writeSubmissionsMetadataAndHashes.ts b/workspaces/download-leetcode-submissions/src/writeSubmissionsMetadataAndHashes.ts index 3bf96c9b..c5134df5 100644 --- a/workspaces/download-leetcode-submissions/src/writeSubmissionsMetadataAndHashes.ts +++ b/workspaces/download-leetcode-submissions/src/writeSubmissionsMetadataAndHashes.ts @@ -1,9 +1,9 @@ import { writeFile } from "node:fs/promises"; -import { METADATA_FILE, HASHES_FILE } from "./constants"; -import { getFilenameForSubmission } from "./getFilenameForSubmission"; -import { getDirnameForSubmission } from "./getDirnameForSubmission"; -import type { TransformedSubmission } from "./transformSubmission"; +import { METADATA_FILE, HASHES_FILE } from "./constants.js"; +import { getDirnameForSubmission } from "./getDirnameForSubmission.js"; +import { getFilenameForSubmission } from "./getFilenameForSubmission.js"; +import type { TransformedSubmission } from "./transformSubmission.js"; export async function writeSubmissionsMetadataAndHashes( submissionsMap: ReadonlyMap, diff --git a/workspaces/download-leetcode-submissions/webpack.config.ts b/workspaces/download-leetcode-submissions/webpack.config.ts new file mode 100644 index 00000000..33601c43 --- /dev/null +++ b/workspaces/download-leetcode-submissions/webpack.config.ts @@ -0,0 +1,68 @@ +import { builtinModules } from "node:module"; +import path from "node:path"; + +import webpack, { + type Configuration, + type ExternalItemFunctionData, +} from "webpack"; + +import { stripPrefix } from "@code-chronicles/util/stripPrefix"; +import { stripPrefixOrThrow } from "@code-chronicles/util/stripPrefixOrThrow"; + +import packageJson from "./package.json" with { type: "module" }; + +const config: Configuration = { + target: "node", + entry: path.resolve(__dirname, packageJson.exports), + output: { + filename: + stripPrefixOrThrow(packageJson.name, "@code-chronicles/") + ".cjs", + path: path.resolve(__dirname, "dist"), + }, + + module: { + rules: [ + { + test: /\.tsx?$/, + use: [ + { + loader: "ts-loader", + options: { + compilerOptions: { + noEmit: false, + }, + }, + }, + ], + exclude: /\bnode_modules\b/, + }, + ], + }, + + resolve: { + extensions: [".tsx", ".ts", "..."], + extensionAlias: { + ".js": [".ts", ".tsx", ".js"], + }, + }, + + externalsType: "commonjs", + externals: ({ request }: ExternalItemFunctionData) => + Promise.resolve( + request != null && + (builtinModules.includes(request) || + builtinModules.includes(stripPrefix(request, "node:"))) + ? request + : undefined, + ), + + plugins: [ + new webpack.BannerPlugin({ + banner: "#!/usr/bin/env node\n", + raw: true, + entryOnly: true, + }), + ], +}; + +export default config; diff --git a/workspaces/generate-health-report/package.json b/workspaces/generate-health-report/package.json index 2b43d329..e779e0c6 100644 --- a/workspaces/generate-health-report/package.json +++ b/workspaces/generate-health-report/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@code-chronicles/util": "workspace:*", - "nullthrows": "1.1.1" + "nullthrows": "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" }, "devDependencies": { "@code-chronicles/eslint-config": "workspace:*", diff --git a/workspaces/leetcode-api/package.json b/workspaces/leetcode-api/package.json index f768a1d0..a5d66f3b 100644 --- a/workspaces/leetcode-api/package.json +++ b/workspaces/leetcode-api/package.json @@ -23,7 +23,7 @@ "dependencies": { "@code-chronicles/util": "workspace:*", "invariant": "2.2.4", - "nullthrows": "1.1.1", + "nullthrows": "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch", "zod": "3.23.8" }, "devDependencies": { diff --git a/workspaces/util/package.json b/workspaces/util/package.json index 8596fcc7..13d6fd41 100644 --- a/workspaces/util/package.json +++ b/workspaces/util/package.json @@ -24,7 +24,7 @@ }, "dependencies": { "invariant": "2.2.4", - "nullthrows": "1.1.1", + "nullthrows": "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch", "zod": "3.23.8" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index e6ea4960..94e585fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -473,7 +473,7 @@ __metadata: immutability-helper: "npm:3.1.1" invariant: "npm:2.2.4" jest: "npm:29.7.0" - nullthrows: "npm:1.1.1" + nullthrows: "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" prettier: "npm:3.3.3" prettier-plugin-java: "npm:2.6.4" react: "npm:18.3.1" @@ -514,11 +514,15 @@ __metadata: "@code-chronicles/leetcode-api": "workspace:*" "@code-chronicles/util": "workspace:*" "@types/node": "npm:22.5.5" + cross-env: "npm:7.0.3" eslint: "npm:9.10.0" - nullthrows: "npm:1.1.1" + nullthrows: "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" prettier: "npm:3.3.3" + ts-loader: "npm:9.5.1" tsx: "npm:4.19.1" typescript: "npm:5.6.2" + webpack: "npm:5.94.0" + webpack-cli: "npm:5.1.4" zod: "npm:3.23.8" languageName: unknown linkType: soft @@ -588,7 +592,7 @@ __metadata: "@code-chronicles/util": "workspace:*" "@types/node": "npm:22.5.5" eslint: "npm:9.10.0" - nullthrows: "npm:1.1.1" + nullthrows: "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" prettier: "npm:3.3.3" ts-node: "npm:10.9.2" typescript: "npm:5.6.2" @@ -623,7 +627,7 @@ __metadata: eslint: "npm:9.10.0" graphql: "npm:16.9.0" invariant: "npm:2.2.4" - nullthrows: "npm:1.1.1" + nullthrows: "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" prettier: "npm:3.3.3" ts-node: "npm:10.9.2" typescript: "npm:5.6.2" @@ -681,7 +685,7 @@ __metadata: eslint: "npm:9.10.0" invariant: "npm:2.2.4" jest: "npm:29.7.0" - nullthrows: "npm:1.1.1" + nullthrows: "patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch" prettier: "npm:3.3.3" ts-jest: "npm:29.2.5" type-fest: "npm:4.26.1" @@ -6386,6 +6390,13 @@ __metadata: languageName: node linkType: hard +"nullthrows@patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch": + version: 1.1.1 + resolution: "nullthrows@patch:nullthrows@npm%3A1.1.1#~/.yarn/patches/nullthrows-npm-1.1.1-3d1f817134.patch::version=1.1.1&hash=c31495" + checksum: 10c0/dde30293d9d05c1595ab780194df4173768b4047c417503409411a084f9b97d71a304f6ebdf82dda997a95edf12fe92baf9130d1beba54f6ac9176450a19b548 + languageName: node + linkType: hard + "object-inspect@npm:^1.13.1": version: 1.13.2 resolution: "object-inspect@npm:1.13.2" From a98594fec6d292906d962dd2fcff7525992df56e Mon Sep 17 00:00:00 2001 From: Miorel-Lucian Palii Date: Sun, 15 Sep 2024 17:45:12 -0700 Subject: [PATCH 2/2] update readme --- workspaces/download-leetcode-submissions/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/workspaces/download-leetcode-submissions/README.md b/workspaces/download-leetcode-submissions/README.md index ad7ba578..f7dfd07a 100644 --- a/workspaces/download-leetcode-submissions/README.md +++ b/workspaces/download-leetcode-submissions/README.md @@ -98,6 +98,10 @@ As such it's safe to run the script multiple times, without redoing too much wor Like the rest of the [Code Chronicles Leetcode ecosystem](../../), this package is structured as a Node module, using [Yarn](https://yarnpkg.com/) as the package manager. -You can install dependencies by running `yarn`, either in this package's directory, or in the repository root. The usual `yarn format`, `yarn lint`, and `yarn typecheck` scripts are available to aid in development and occasionally to annoy. +You can install dependencies by running `yarn`, either in this package's directory, or in the repository root. The usual `yarn format`, `yarn lint`, and `yarn typecheck` scripts are available to aid in development and occasionally to annoy. Read more in the repository's general [development guide](../../DEVELOPMENT.md). -See also the repository's general [development guide](../../DEVELOPMENT.md). +This package supports an additional `package.json` script: + +### `yarn build` + +Builds a distribution version of this package, in a `dist` directory within the package's workspace.