@ribajs/core
Version:
Core module of Riba.js
92 lines (80 loc) • 2.38 kB
text/typescript
import { camelCase } from "@ribajs/utils/src/type.js";
import { Formatter, FormatterFn, Formatters } from "../types/index.js";
import { ModuleElementService } from "./module-element.service.js";
/** Warn once per legacy formatter id per session (camelCase alias). */
const formatterDeprecationWarned = new Set<string>();
function warnFormatterDeprecationOnce(legacyId: string, canonicalId: string) {
if (formatterDeprecationWarned.has(legacyId)) return;
formatterDeprecationWarned.add(legacyId);
console.warn(
`[Riba] Formatter "${legacyId}" is deprecated; use "${canonicalId}" instead.`,
);
}
/**
* Registers the same formatter under a camelCase id and logs deprecation when used.
*/
function wrapDeprecatedFormatterAlias(
formatter: Formatter,
legacyId: string,
canonicalId: string,
): Formatter {
const wrap = (fn: FormatterFn | undefined): FormatterFn | undefined => {
if (!fn) return fn;
const wrapped: FormatterFn = function (
this: unknown,
val: any,
...args: any[]
) {
warnFormatterDeprecationOnce(legacyId, canonicalId);
return fn.call(this, val, ...args);
};
return wrapped;
};
return {
...formatter,
name: legacyId,
read: wrap(formatter.read),
publish: wrap(formatter.publish),
};
}
export class FormatterService extends ModuleElementService {
protected type: "binder" | "formatter" | "components" | "services" =
"formatter";
/**
*
*/
constructor(formatters: Formatters) {
super(formatters);
}
/**
* Regist a formatter with his name
*/
public register(
formatter: Formatter,
fallbackName?: string,
forceFallback = false,
): Formatters {
const name = forceFallback
? fallbackName || formatter.name
: formatter.name || fallbackName;
if (!name) {
throw new Error("Formatter name not found!");
}
this.elements[name] = formatter;
// Back-compat: kebab-case is canonical; register camelCase alias with deprecation.
if (name.includes("-")) {
const legacyId = camelCase(name);
if (
legacyId !== name &&
!Object.prototype.hasOwnProperty.call(this.elements, legacyId)
) {
this.elements[legacyId] = wrapDeprecatedFormatterAlias(
formatter,
legacyId,
name,
);
}
}
return this.elements;
}
}