Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion workspaces/fetch-leetcode-problem-list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "module",
"exports": "./src/main.ts",
"scripts": {
"build": "cross-env NODE_OPTIONS=\"--import tsx\" webpack && chmod +x dist/fetch-leetcode-problem-list.cjs",
"build": "cross-env NODE_OPTIONS=\"--import tsx\" webpack",
"format": "prettier --color --write .",
"lint": "eslint --color --max-warnings=0 .",
"start": "tsx src/main.ts",
Expand Down
33 changes: 33 additions & 0 deletions workspaces/fetch-leetcode-problem-list/webpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { chmod } from "node:fs/promises";
import { builtinModules } from "node:module";
import path from "node:path";

import webpack, {
type Compiler,
type Configuration,
type ExternalItemFunctionData,
} from "webpack";
Expand All @@ -11,6 +13,35 @@ import { stripPrefixOrThrow } from "@code-chronicles/util/stripPrefixOrThrow";

import packageJson from "./package.json" with { type: "json" };

class WebpackMakeOutputExecutablePlugin {
// eslint-disable-next-line class-methods-use-this -- This is the interface expected by webpack.
apply(compiler: Compiler): void {
compiler.hooks.afterEmit.tapAsync(
"WebpackMakeOutputExecutablePlugin",
async (compilation) => {
const promises: Promise<void>[] = [];

for (const chunk of compilation.chunks) {
if (!chunk.canBeInitial()) {
continue;
}

for (const file of chunk.files) {
promises.push(
chmod(
path.join(compilation.outputOptions.path ?? ".", file),
0o755,
),
);
}
}

await Promise.all(promises);
},
);
}
}

const config: Configuration = {
target: "node",
entry: path.resolve(__dirname, packageJson.exports),
Expand Down Expand Up @@ -58,6 +89,8 @@ const config: Configuration = {
raw: true,
entryOnly: true,
}),

new WebpackMakeOutputExecutablePlugin(),
],
};

Expand Down
22 changes: 19 additions & 3 deletions workspaces/util/src/only.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import invariant from "invariant";
import nullthrows from "nullthrows";

export function only<T>(array: readonly T[]): T {
invariant(array.length === 1, "Expected a single element array!");
return array[0];
export function only<T>(iterable: Iterable<T>): T {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up not using the changes to this function, but this seems like a generally useful improvement.

if (Array.isArray(iterable)) {
const { length } = iterable;
invariant(
length === 1,
"Given array has length %d, not 1 as expected!",
length,
);
return iterable[0];
}

let elementBox: { element: T } | null = null;
for (const element of iterable) {
invariant(elementBox == null, "Iterable had multiple elements!");
elementBox = { element };
}

return nullthrows(elementBox, "Empty iterable!").element;
}
Loading