Skip to content

Commit

Permalink
fix: Bound class methods with decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
3y3 committed Dec 18, 2024
1 parent e353e58 commit 4f06386
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 13 deletions.
40 changes: 27 additions & 13 deletions src/commands/build/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {dirname, join, relative, resolve} from 'node:path';
import {access, link, mkdir, readFile, realpath, stat, unlink, writeFile} from 'node:fs/promises';
import {glob} from 'glob';

import {normalizePath} from '~/utils';
import {bounded, normalizePath} from '~/utils';
import {configPath} from '~/config';
import {
BUNDLE_FOLDER,
Expand Down Expand Up @@ -112,11 +112,11 @@ export class Run {
*
* @returns {Promise<string>}
*/
read = async (path: AbsolutePath) => {
@bounded async read(path: AbsolutePath) {
this.assertProjectScope(path);

return this.fs.readFile(path, 'utf8');
};
}

/**
* Run.input bounded write helper.
Expand All @@ -130,15 +130,26 @@ export class Run {
*
* @returns {Promise<void>}
*/
write = async (path: AbsolutePath, content: string) => {
@bounded async write(path: AbsolutePath, content: string) {
this.assertProjectScope(path);

await this.fs.mkdir(dirname(path), {recursive: true});
await this.fs.unlink(path).catch(() => {});
await this.fs.writeFile(path, content, 'utf8');
};
}

glob = async (pattern: string | string[], options: GlobOptions): Promise<NormalizedPath[]> => {
/**
* Glob wrapper with some default settings
*
* @param {string | string[]} pattern
* @param {GlobOptions} options
*
* @returns {NormalizedPath[]}
*/
@bounded async glob(
pattern: string | string[],
options: GlobOptions,
): Promise<NormalizedPath[]> {
const paths = await glob(pattern, {
dot: true,
nodir: true,
Expand All @@ -147,13 +158,13 @@ export class Run {
});

return paths.map(normalizePath);
};
}

copy = async (
@bounded async copy(
from: AbsolutePath,
to: AbsolutePath,
options: CopyOptions | CopyOptions['ignore'] = {},
) => {
) {
if (Array.isArray(options)) {
options = {ignore: options};
}
Expand Down Expand Up @@ -205,9 +216,12 @@ export class Run {
await hardlink(join(from, file), join(to, file));
}
}
};
}

realpath = async (path: AbsolutePath): Promise<AbsolutePath[]> => {
realpath(path: AbsolutePath): Promise<AbsolutePath[]>;
realpath(path: AbsolutePath, withStack: true): Promise<AbsolutePath[]>;
realpath(path: AbsolutePath, withStack: false): Promise<AbsolutePath>;
@bounded async realpath(path: AbsolutePath, withStack = true) {
const stack = [path];
while (this._copyMap[path]) {
path = this._copyMap[path];
Expand All @@ -222,8 +236,8 @@ export class Run {
}
} catch {}

return stack;
};
return withStack ? stack : stack[0];
}

private async assertProjectScope(path: AbsolutePath) {
const realpath = await this.realpath(path);
Expand Down
12 changes: 12 additions & 0 deletions src/utils/decorators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function bounded(_originalMethod: unknown, context: ClassMethodDecoratorContext) {
const methodName = context.name;

if (context.private) {
throw new Error(`'bound' cannot decorate private properties like ${methodName as string}.`);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
context.addInitializer(function (this: any) {
this[methodName] = this[methodName].bind(this);
});
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './path';
export * from './toc';
export * from './presets';
export * from './file';
export * from './decorators';
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"outDir": "build",
"module": "es2022",
"moduleResolution": "bundler",
"experimentalDecorators": false,
"paths": {
"~/*": ["./src/*"]
}
Expand Down

0 comments on commit 4f06386

Please sign in to comment.