75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import "../core/metadata.ts";
|
|
import { defineMetadata, getMetadata } from "../core/metadata.ts";
|
|
import { callerFile } from "../core/paths.ts";
|
|
import { existsSync } from "node:fs";
|
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
|
|
export const ROOT_METADATA_KEY = "muddle:root";
|
|
|
|
export interface RootMetadata {
|
|
/** Absolute path of the directory. */
|
|
path: string;
|
|
}
|
|
|
|
/** Declares the static root of a controller. */
|
|
export function Root(path: string): ClassDecorator {
|
|
return (target) => {
|
|
const caller = callerFile();
|
|
const base = caller ? dirname(caller) : process.cwd();
|
|
const absolute = isAbsolute(path) ? path : resolve(base, path);
|
|
defineMetadata(
|
|
ROOT_METADATA_KEY,
|
|
{ path: absolute } satisfies RootMetadata,
|
|
target as object,
|
|
);
|
|
return target;
|
|
};
|
|
}
|
|
|
|
/** Reads the static root of a controller. */
|
|
export function getRoot(target: object): RootMetadata | undefined {
|
|
return getMetadata(ROOT_METADATA_KEY, target) as RootMetadata | undefined;
|
|
}
|
|
|
|
export const VIEW_ROOT_METADATA_KEY = "muddle:view-root";
|
|
|
|
export interface ViewRootMetadata {
|
|
/** Absolute path of the folder. */
|
|
path: string;
|
|
}
|
|
|
|
/** Declares the view folder of a controller. */
|
|
export function ViewRoot(path: string): ClassDecorator {
|
|
return (target) => {
|
|
const caller = callerFile();
|
|
const base = caller ? dirname(caller) : process.cwd();
|
|
const absolute = isAbsolute(path) ? path : resolve(base, path);
|
|
defineMetadata(
|
|
VIEW_ROOT_METADATA_KEY,
|
|
{ path: absolute } satisfies ViewRootMetadata,
|
|
target as object,
|
|
);
|
|
return target;
|
|
};
|
|
}
|
|
|
|
/** Reads the view folder of a controller. */
|
|
export function getViewRoot(target: object): ViewRootMetadata | undefined {
|
|
return getMetadata(VIEW_ROOT_METADATA_KEY, target) as
|
|
| ViewRootMetadata
|
|
| undefined;
|
|
}
|
|
|
|
/**
|
|
* Resolves the folder of the templates of a controller.
|
|
*/
|
|
export function resolveViewRoot(target: object, fallback: string): string {
|
|
const root = getViewRoot(target);
|
|
if (root) return root.path;
|
|
return fallback;
|
|
}
|
|
|
|
/** `true` when the directory exists. */
|
|
export function isDirectory(path: string): boolean {
|
|
return existsSync(path) && existsSync(join(path, "."));
|
|
}
|