moost 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +63 -10
- package/dist/index.d.ts +59 -6
- package/dist/index.mjs +63 -11
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -48,7 +48,7 @@ let stamped = false;
|
|
|
48
48
|
if (stamped) return;
|
|
49
49
|
stamped = true;
|
|
50
50
|
stampModuleIdentity({
|
|
51
|
-
version: "0.7.
|
|
51
|
+
version: "0.7.5",
|
|
52
52
|
path: typeof __filename === "string" ? __filename : require("url").pathToFileURL(__filename).href
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -3182,6 +3182,38 @@ function _define_property(obj, key, value) {
|
|
|
3182
3182
|
return getHandlerPaths(moost, getController(), method ?? getMethod() ?? "", opts);
|
|
3183
3183
|
}
|
|
3184
3184
|
|
|
3185
|
+
//#endregion
|
|
3186
|
+
//#region packages/moost/src/wooks-owner.ts
|
|
3187
|
+
/** Per Wooks instance: the first claim of each adapter (by `name`) bound into it. */ const owners = /* @__PURE__ */ new WeakMap();
|
|
3188
|
+
/** Wooks instances already warned about: the warning is logged once per instance. */ const warned = /* @__PURE__ */ new WeakSet();
|
|
3189
|
+
/**
|
|
3190
|
+
* Records that `app` binds the handlers of its `adapter` (the adapter's `name`) into `wooks`
|
|
3191
|
+
* (the Wooks instance its routes go to: `wooksApp.getWooks()`). Adapters call it from `onInit`.
|
|
3192
|
+
*
|
|
3193
|
+
* Adapters created without a Wooks app of their own share the process-wide global Wooks, so two
|
|
3194
|
+
* apps in one process (typically in tests) route through one router. When another app already
|
|
3195
|
+
* bound handlers of the same adapter into `wooks`, and either adapter created its Wooks app
|
|
3196
|
+
* (`opts.created`), it warns — once per Wooks instance, with the app's logger. Apps that share
|
|
3197
|
+
* a Wooks app they pass in on purpose stay silent; re-initialising the same app does not warn.
|
|
3198
|
+
* A disposed app still counts: `dispose()` does not remove its routes.
|
|
3199
|
+
*/ function claimWooks(app, wooks, adapter, opts) {
|
|
3200
|
+
const created = opts?.created === true;
|
|
3201
|
+
let byAdapter = owners.get(wooks);
|
|
3202
|
+
if (!byAdapter) {
|
|
3203
|
+
byAdapter = /* @__PURE__ */ new Map();
|
|
3204
|
+
owners.set(wooks, byAdapter);
|
|
3205
|
+
}
|
|
3206
|
+
const owner = byAdapter.get(adapter);
|
|
3207
|
+
if (owner === void 0) byAdapter.set(adapter, {
|
|
3208
|
+
app,
|
|
3209
|
+
created
|
|
3210
|
+
});
|
|
3211
|
+
else if (owner.app !== app && (created || owner.created) && !warned.has(wooks)) {
|
|
3212
|
+
warned.add(wooks);
|
|
3213
|
+
app.getLogger().warn(`[moost] A second Moost app binds "${adapter}" handlers into the Wooks instance another app already uses (adapters created without their own Wooks app share the process-wide global one). Both apps' routes now live in one router: an event on a route both register runs the first app's handler chain, and when that throws, its error is swallowed and the next app's chain runs instead. Call clearGlobalWooks() before creating each app (e.g. in a test's beforeEach): the next adapter then gets a fresh Wooks. (Logged once per Wooks instance.)`);
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3185
3217
|
//#endregion
|
|
3186
3218
|
//#region packages/moost/src/i18n.ts
|
|
3187
3219
|
var _globalThis, _STATE, _state, _state1, _state2, _state3, _state4;
|
|
@@ -3221,6 +3253,7 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3221
3253
|
translate: state.translate,
|
|
3222
3254
|
get: opts.scope
|
|
3223
3255
|
};
|
|
3256
|
+
state.noPathPrefix = opts?.pathPrefix === false ? state.translate : void 0;
|
|
3224
3257
|
const locales = opts?.locales ?? (isMap ? Object.keys(translate) : void 0);
|
|
3225
3258
|
state.locales = translate && locales?.length ? Object.freeze([...locales]) : NO_LOCALES;
|
|
3226
3259
|
state.failureLogged = false;
|
|
@@ -3369,21 +3402,31 @@ function translateContext(event, locale, scope) {
|
|
|
3369
3402
|
* event's locale — the body itself when there is no translation ({@link useTranslation}).
|
|
3370
3403
|
*
|
|
3371
3404
|
* - each entry of `errors` (and of its entries' `details`): by its `code` (unless `custom`),
|
|
3372
|
-
* else by its message text, its English `message` being the fallback;
|
|
3373
|
-
*
|
|
3374
|
-
*
|
|
3405
|
+
* else by its message text, its English `message` being the fallback; the translator gets the
|
|
3406
|
+
* entry's `path`, `code` and `custom` ({@link TTranslateContext});
|
|
3407
|
+
* - the top `message`: by `code` when the body has one (the translator gets that `code`); else,
|
|
3408
|
+
* when it is the first entry's message (`path: message`), the first entry's translation
|
|
3409
|
+
* (`path: ` dropped with `setTranslator(t, { pathPrefix: false })`); else by its text.
|
|
3375
3410
|
*
|
|
3376
3411
|
* `MoostHttp` applies it to every error body when it creates the HTTP app.
|
|
3377
3412
|
*/ function translateErrorBody(body, ctx) {
|
|
3378
3413
|
const event = ctx ?? (0, _wooksjs_event_core.current)();
|
|
3379
|
-
|
|
3380
|
-
const
|
|
3414
|
+
const translate = state.translate;
|
|
3415
|
+
const locale = (0, _wooksjs_event_core.useLocale)(event).get();
|
|
3416
|
+
if (!translate || locale === void 0) return body;
|
|
3417
|
+
const base = translateContext(event, locale, readScope(event));
|
|
3418
|
+
const t = (id, params, fallback, entry) => callTranslator(translate, id, params, entry ? entryContext(base, entry) : base) ?? untranslated(id, params, fallback);
|
|
3381
3419
|
const source = Array.isArray(body.errors) ? body.errors : void 0;
|
|
3382
3420
|
const errors = source && translateEntries(source, t);
|
|
3383
3421
|
let message;
|
|
3384
|
-
if (typeof body.code === "string" && body.code) message =
|
|
3385
|
-
|
|
3386
|
-
|
|
3422
|
+
if (typeof body.code === "string" && body.code) message = callTranslator(translate, body.code, body.params, {
|
|
3423
|
+
...base,
|
|
3424
|
+
code: body.code
|
|
3425
|
+
}) ?? untranslated(body.code, body.params, body.message);
|
|
3426
|
+
else if (source && errors && isEntry(source[0]) && body.message === topMessage(source[0])) {
|
|
3427
|
+
const first = errors[0];
|
|
3428
|
+
message = state.noPathPrefix === translate ? first.message : topMessage(first);
|
|
3429
|
+
} else message = t(body.message, body.params, body.message);
|
|
3387
3430
|
return errors ? {
|
|
3388
3431
|
...body,
|
|
3389
3432
|
message,
|
|
@@ -3421,13 +3464,22 @@ function mapTranslator(map) {
|
|
|
3421
3464
|
function isEntry(value) {
|
|
3422
3465
|
return typeof value === "object" && value !== null && typeof value.message === "string";
|
|
3423
3466
|
}
|
|
3467
|
+
/** `base` with the entry's `path` and `code` (each only when a string) and `custom: true`. */ function entryContext(base, { path, code, custom }) {
|
|
3468
|
+
const hasCode = typeof code === "string" && code !== "";
|
|
3469
|
+
if (typeof path !== "string" && !hasCode && custom !== true) return base;
|
|
3470
|
+
const out = { ...base };
|
|
3471
|
+
if (typeof path === "string") out.path = path;
|
|
3472
|
+
if (hasCode) out.code = code;
|
|
3473
|
+
if (custom === true) out.custom = true;
|
|
3474
|
+
return out;
|
|
3475
|
+
}
|
|
3424
3476
|
function translateEntries(entries, t) {
|
|
3425
3477
|
return entries.map((entry) => {
|
|
3426
3478
|
if (!isEntry(entry)) return entry;
|
|
3427
3479
|
const id = typeof entry.code === "string" && entry.code && entry.custom !== true ? entry.code : entry.message;
|
|
3428
3480
|
const out = {
|
|
3429
3481
|
...entry,
|
|
3430
|
-
message: t(id, entry.params, entry.message)
|
|
3482
|
+
message: t(id, entry.params, entry.message, entry)
|
|
3431
3483
|
};
|
|
3432
3484
|
if (Array.isArray(entry.details)) out.details = translateEntries(entry.details, t);
|
|
3433
3485
|
return out;
|
|
@@ -3500,6 +3552,7 @@ Object.defineProperty(exports, 'cached', {
|
|
|
3500
3552
|
return _wooksjs_event_core.cached;
|
|
3501
3553
|
}
|
|
3502
3554
|
});
|
|
3555
|
+
exports.claimWooks = claimWooks;
|
|
3503
3556
|
Object.defineProperty(exports, 'clearGlobalWooks', {
|
|
3504
3557
|
enumerable: true,
|
|
3505
3558
|
get: function () {
|
package/dist/index.d.ts
CHANGED
|
@@ -1649,6 +1649,27 @@ declare function mergeSorted<T extends {
|
|
|
1649
1649
|
priority: number;
|
|
1650
1650
|
}>(...lists: (T[] | readonly T[] | undefined)[]): T[];
|
|
1651
1651
|
|
|
1652
|
+
/** The options of {@link claimWooks}. */
|
|
1653
|
+
interface TClaimWooksOptions {
|
|
1654
|
+
/**
|
|
1655
|
+
* The adapter created its Wooks app itself (none was passed in), so it routes through the
|
|
1656
|
+
* process-wide global Wooks. Default `false`: an app passed in — sharing it is deliberate.
|
|
1657
|
+
*/
|
|
1658
|
+
created?: boolean;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Records that `app` binds the handlers of its `adapter` (the adapter's `name`) into `wooks`
|
|
1662
|
+
* (the Wooks instance its routes go to: `wooksApp.getWooks()`). Adapters call it from `onInit`.
|
|
1663
|
+
*
|
|
1664
|
+
* Adapters created without a Wooks app of their own share the process-wide global Wooks, so two
|
|
1665
|
+
* apps in one process (typically in tests) route through one router. When another app already
|
|
1666
|
+
* bound handlers of the same adapter into `wooks`, and either adapter created its Wooks app
|
|
1667
|
+
* (`opts.created`), it warns — once per Wooks instance, with the app's logger. Apps that share
|
|
1668
|
+
* a Wooks app they pass in on purpose stay silent; re-initialising the same app does not warn.
|
|
1669
|
+
* A disposed app still counts: `dispose()` does not remove its routes.
|
|
1670
|
+
*/
|
|
1671
|
+
declare function claimWooks(app: Moost, wooks: object, adapter: string, opts?: TClaimWooksOptions): void;
|
|
1672
|
+
|
|
1652
1673
|
/**
|
|
1653
1674
|
* Sets the controller context for the current event scope.
|
|
1654
1675
|
* Called internally by adapters when dispatching events to handlers.
|
|
@@ -1771,7 +1792,11 @@ declare function defineInterceptor(def: TInterceptorDef, priority?: TInterceptor
|
|
|
1771
1792
|
*/
|
|
1772
1793
|
declare function definePipeFn<T extends TObject = TEmpty>(fn: TPipeFn<T>, priority?: TPipePriority): TPipeFn<T>;
|
|
1773
1794
|
|
|
1774
|
-
/**
|
|
1795
|
+
/**
|
|
1796
|
+
* What a translator gets besides the text: the event's locale, its scope and the event itself —
|
|
1797
|
+
* plus, when an error body is translated ({@link translateErrorBody}), the entry's `path` and
|
|
1798
|
+
* `code`.
|
|
1799
|
+
*/
|
|
1775
1800
|
interface TTranslateContext {
|
|
1776
1801
|
/** `useLocale().get()` of the event the text is translated for. */
|
|
1777
1802
|
locale: string | undefined;
|
|
@@ -1782,6 +1807,25 @@ interface TTranslateContext {
|
|
|
1782
1807
|
scope?: string;
|
|
1783
1808
|
/** The event context — read anything else your policy needs from it. */
|
|
1784
1809
|
event: EventContext;
|
|
1810
|
+
/**
|
|
1811
|
+
* The field path (`'items.0.name'`, `''` for the root) of the error entry being
|
|
1812
|
+
* translated — word a message per field. Only set by {@link translateErrorBody}, for its
|
|
1813
|
+
* `errors` entries (and their `details`); error bodies are never memoized, while the memoized
|
|
1814
|
+
* {@link TTranslation.messages} never carry a path.
|
|
1815
|
+
*/
|
|
1816
|
+
path?: string;
|
|
1817
|
+
/**
|
|
1818
|
+
* The code of the error entry (or error body) being translated — also when `text` is the
|
|
1819
|
+
* entry's own message (an entry marked `custom`, or one translated by its text). Only set by
|
|
1820
|
+
* {@link translateErrorBody}.
|
|
1821
|
+
*/
|
|
1822
|
+
code?: string;
|
|
1823
|
+
/**
|
|
1824
|
+
* `true` when the error entry carries the app's own message (`custom: true`, e.g. from
|
|
1825
|
+
* `@expect.message`): `text` is that message — keep it unless you translate it as text. Only
|
|
1826
|
+
* set by {@link translateErrorBody}.
|
|
1827
|
+
*/
|
|
1828
|
+
custom?: boolean;
|
|
1785
1829
|
}
|
|
1786
1830
|
/**
|
|
1787
1831
|
* The app's translator. `text` is a message id: an error/message code (`WF_EXPIRED`,
|
|
@@ -1813,6 +1857,13 @@ interface TTranslatorOptions {
|
|
|
1813
1857
|
* request input: only the first 32 scopes seen per generation get a {@link TTranslation.key}.
|
|
1814
1858
|
*/
|
|
1815
1859
|
scope?: () => string | number | undefined;
|
|
1860
|
+
/**
|
|
1861
|
+
* `false`: a translated error body's top `message` that repeats its first entry is just that
|
|
1862
|
+
* entry's text, without the `path: ` prefix ({@link translateErrorBody}) — also when the entry
|
|
1863
|
+
* has no translation (its English text). Bodies of events without a locale are not touched.
|
|
1864
|
+
* Default `true`: `path: <translated>`, like the untranslated message.
|
|
1865
|
+
*/
|
|
1866
|
+
pathPrefix?: boolean;
|
|
1816
1867
|
}
|
|
1817
1868
|
/** `t(id, params?, fallback?)` — see {@link useTranslate}. */
|
|
1818
1869
|
type TTranslateFn = (id: string, params?: Record<string, unknown>, fallback?: string) => string;
|
|
@@ -1910,9 +1961,11 @@ declare function useTranslation(ctx?: EventContext): TTranslation | undefined;
|
|
|
1910
1961
|
* event's locale — the body itself when there is no translation ({@link useTranslation}).
|
|
1911
1962
|
*
|
|
1912
1963
|
* - each entry of `errors` (and of its entries' `details`): by its `code` (unless `custom`),
|
|
1913
|
-
* else by its message text, its English `message` being the fallback;
|
|
1914
|
-
*
|
|
1915
|
-
*
|
|
1964
|
+
* else by its message text, its English `message` being the fallback; the translator gets the
|
|
1965
|
+
* entry's `path`, `code` and `custom` ({@link TTranslateContext});
|
|
1966
|
+
* - the top `message`: by `code` when the body has one (the translator gets that `code`); else,
|
|
1967
|
+
* when it is the first entry's message (`path: message`), the first entry's translation
|
|
1968
|
+
* (`path: ` dropped with `setTranslator(t, { pathPrefix: false })`); else by its text.
|
|
1916
1969
|
*
|
|
1917
1970
|
* `MoostHttp` applies it to every error body when it creates the HTTP app.
|
|
1918
1971
|
*/
|
|
@@ -1928,5 +1981,5 @@ declare function createLogger(opts?: Partial<TProstoLoggerOptions>): ProstoLogge
|
|
|
1928
1981
|
/** Default colored console transport used by Moost loggers. */
|
|
1929
1982
|
declare const loggerConsoleTransport: _prostojs_logger.TProstoLoggerTransportFn<any>;
|
|
1930
1983
|
|
|
1931
|
-
export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, Locale, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, detachedKind, disposeInstances, forkEventContext, formatMessage, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, getTranslator, getTranslatorLocales, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, registerMessages, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptOriginal, setInterceptResult, setOvertake, setTranslator, stampModuleIdentity, stampOnce, translateErrorBody, useControllerContext, useHandlerPaths, useInterceptOriginal, useInterceptResult, useOvertake, useScopeId, useTranslate, useTranslation, withControllerContext };
|
|
1932
|
-
export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TForkEventContextOptions, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TIsolatedSlot, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives, TRegistryMergeOptions, TRunDetachedOptions, TTranslate, TTranslateContext, TTranslation, TTranslations, TTranslatorOptions, TWithControllerContextOptions };
|
|
1984
|
+
export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, Locale, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, claimWooks, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, detachedKind, disposeInstances, forkEventContext, formatMessage, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, getTranslator, getTranslatorLocales, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, registerMessages, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptOriginal, setInterceptResult, setOvertake, setTranslator, stampModuleIdentity, stampOnce, translateErrorBody, useControllerContext, useHandlerPaths, useInterceptOriginal, useInterceptResult, useOvertake, useScopeId, useTranslate, useTranslation, withControllerContext };
|
|
1985
|
+
export type { TAny, TAnyFn, TClaimWooksOptions, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TForkEventContextOptions, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TIsolatedSlot, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives, TRegistryMergeOptions, TRunDetachedOptions, TTranslate, TTranslateContext, TTranslation, TTranslations, TTranslatorOptions, TWithControllerContextOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -47,7 +47,7 @@ let stamped = false;
|
|
|
47
47
|
if (stamped) return;
|
|
48
48
|
stamped = true;
|
|
49
49
|
stampModuleIdentity({
|
|
50
|
-
version: "0.7.
|
|
50
|
+
version: "0.7.5",
|
|
51
51
|
path: typeof __filename === "string" ? __filename : import.meta.url
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -3181,6 +3181,38 @@ function _define_property(obj, key, value) {
|
|
|
3181
3181
|
return getHandlerPaths(moost, getController(), method ?? getMethod() ?? "", opts);
|
|
3182
3182
|
}
|
|
3183
3183
|
|
|
3184
|
+
//#endregion
|
|
3185
|
+
//#region packages/moost/src/wooks-owner.ts
|
|
3186
|
+
/** Per Wooks instance: the first claim of each adapter (by `name`) bound into it. */ const owners = /* @__PURE__ */ new WeakMap();
|
|
3187
|
+
/** Wooks instances already warned about: the warning is logged once per instance. */ const warned = /* @__PURE__ */ new WeakSet();
|
|
3188
|
+
/**
|
|
3189
|
+
* Records that `app` binds the handlers of its `adapter` (the adapter's `name`) into `wooks`
|
|
3190
|
+
* (the Wooks instance its routes go to: `wooksApp.getWooks()`). Adapters call it from `onInit`.
|
|
3191
|
+
*
|
|
3192
|
+
* Adapters created without a Wooks app of their own share the process-wide global Wooks, so two
|
|
3193
|
+
* apps in one process (typically in tests) route through one router. When another app already
|
|
3194
|
+
* bound handlers of the same adapter into `wooks`, and either adapter created its Wooks app
|
|
3195
|
+
* (`opts.created`), it warns — once per Wooks instance, with the app's logger. Apps that share
|
|
3196
|
+
* a Wooks app they pass in on purpose stay silent; re-initialising the same app does not warn.
|
|
3197
|
+
* A disposed app still counts: `dispose()` does not remove its routes.
|
|
3198
|
+
*/ function claimWooks(app, wooks, adapter, opts) {
|
|
3199
|
+
const created = opts?.created === true;
|
|
3200
|
+
let byAdapter = owners.get(wooks);
|
|
3201
|
+
if (!byAdapter) {
|
|
3202
|
+
byAdapter = /* @__PURE__ */ new Map();
|
|
3203
|
+
owners.set(wooks, byAdapter);
|
|
3204
|
+
}
|
|
3205
|
+
const owner = byAdapter.get(adapter);
|
|
3206
|
+
if (owner === void 0) byAdapter.set(adapter, {
|
|
3207
|
+
app,
|
|
3208
|
+
created
|
|
3209
|
+
});
|
|
3210
|
+
else if (owner.app !== app && (created || owner.created) && !warned.has(wooks)) {
|
|
3211
|
+
warned.add(wooks);
|
|
3212
|
+
app.getLogger().warn(`[moost] A second Moost app binds "${adapter}" handlers into the Wooks instance another app already uses (adapters created without their own Wooks app share the process-wide global one). Both apps' routes now live in one router: an event on a route both register runs the first app's handler chain, and when that throws, its error is swallowed and the next app's chain runs instead. Call clearGlobalWooks() before creating each app (e.g. in a test's beforeEach): the next adapter then gets a fresh Wooks. (Logged once per Wooks instance.)`);
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3184
3216
|
//#endregion
|
|
3185
3217
|
//#region packages/moost/src/i18n.ts
|
|
3186
3218
|
var _globalThis, _STATE, _state, _state1, _state2, _state3, _state4;
|
|
@@ -3220,6 +3252,7 @@ const state = (_globalThis = globalThis)[_STATE = STATE] ?? (_globalThis[_STATE]
|
|
|
3220
3252
|
translate: state.translate,
|
|
3221
3253
|
get: opts.scope
|
|
3222
3254
|
};
|
|
3255
|
+
state.noPathPrefix = opts?.pathPrefix === false ? state.translate : void 0;
|
|
3223
3256
|
const locales = opts?.locales ?? (isMap ? Object.keys(translate) : void 0);
|
|
3224
3257
|
state.locales = translate && locales?.length ? Object.freeze([...locales]) : NO_LOCALES;
|
|
3225
3258
|
state.failureLogged = false;
|
|
@@ -3368,21 +3401,31 @@ function translateContext(event, locale, scope) {
|
|
|
3368
3401
|
* event's locale — the body itself when there is no translation ({@link useTranslation}).
|
|
3369
3402
|
*
|
|
3370
3403
|
* - each entry of `errors` (and of its entries' `details`): by its `code` (unless `custom`),
|
|
3371
|
-
* else by its message text, its English `message` being the fallback;
|
|
3372
|
-
*
|
|
3373
|
-
*
|
|
3404
|
+
* else by its message text, its English `message` being the fallback; the translator gets the
|
|
3405
|
+
* entry's `path`, `code` and `custom` ({@link TTranslateContext});
|
|
3406
|
+
* - the top `message`: by `code` when the body has one (the translator gets that `code`); else,
|
|
3407
|
+
* when it is the first entry's message (`path: message`), the first entry's translation
|
|
3408
|
+
* (`path: ` dropped with `setTranslator(t, { pathPrefix: false })`); else by its text.
|
|
3374
3409
|
*
|
|
3375
3410
|
* `MoostHttp` applies it to every error body when it creates the HTTP app.
|
|
3376
3411
|
*/ function translateErrorBody(body, ctx) {
|
|
3377
3412
|
const event = ctx ?? current$1();
|
|
3378
|
-
|
|
3379
|
-
const
|
|
3413
|
+
const translate = state.translate;
|
|
3414
|
+
const locale = useLocale$1(event).get();
|
|
3415
|
+
if (!translate || locale === void 0) return body;
|
|
3416
|
+
const base = translateContext(event, locale, readScope(event));
|
|
3417
|
+
const t = (id, params, fallback, entry) => callTranslator(translate, id, params, entry ? entryContext(base, entry) : base) ?? untranslated(id, params, fallback);
|
|
3380
3418
|
const source = Array.isArray(body.errors) ? body.errors : void 0;
|
|
3381
3419
|
const errors = source && translateEntries(source, t);
|
|
3382
3420
|
let message;
|
|
3383
|
-
if (typeof body.code === "string" && body.code) message =
|
|
3384
|
-
|
|
3385
|
-
|
|
3421
|
+
if (typeof body.code === "string" && body.code) message = callTranslator(translate, body.code, body.params, {
|
|
3422
|
+
...base,
|
|
3423
|
+
code: body.code
|
|
3424
|
+
}) ?? untranslated(body.code, body.params, body.message);
|
|
3425
|
+
else if (source && errors && isEntry(source[0]) && body.message === topMessage(source[0])) {
|
|
3426
|
+
const first = errors[0];
|
|
3427
|
+
message = state.noPathPrefix === translate ? first.message : topMessage(first);
|
|
3428
|
+
} else message = t(body.message, body.params, body.message);
|
|
3386
3429
|
return errors ? {
|
|
3387
3430
|
...body,
|
|
3388
3431
|
message,
|
|
@@ -3420,13 +3463,22 @@ function mapTranslator(map) {
|
|
|
3420
3463
|
function isEntry(value) {
|
|
3421
3464
|
return typeof value === "object" && value !== null && typeof value.message === "string";
|
|
3422
3465
|
}
|
|
3466
|
+
/** `base` with the entry's `path` and `code` (each only when a string) and `custom: true`. */ function entryContext(base, { path, code, custom }) {
|
|
3467
|
+
const hasCode = typeof code === "string" && code !== "";
|
|
3468
|
+
if (typeof path !== "string" && !hasCode && custom !== true) return base;
|
|
3469
|
+
const out = { ...base };
|
|
3470
|
+
if (typeof path === "string") out.path = path;
|
|
3471
|
+
if (hasCode) out.code = code;
|
|
3472
|
+
if (custom === true) out.custom = true;
|
|
3473
|
+
return out;
|
|
3474
|
+
}
|
|
3423
3475
|
function translateEntries(entries, t) {
|
|
3424
3476
|
return entries.map((entry) => {
|
|
3425
3477
|
if (!isEntry(entry)) return entry;
|
|
3426
3478
|
const id = typeof entry.code === "string" && entry.code && entry.custom !== true ? entry.code : entry.message;
|
|
3427
3479
|
const out = {
|
|
3428
3480
|
...entry,
|
|
3429
|
-
message: t(id, entry.params, entry.message)
|
|
3481
|
+
message: t(id, entry.params, entry.message, entry)
|
|
3430
3482
|
};
|
|
3431
3483
|
if (Array.isArray(entry.details)) out.details = translateEntries(entry.details, t);
|
|
3432
3484
|
return out;
|
|
@@ -3437,4 +3489,4 @@ function topMessage(entry) {
|
|
|
3437
3489
|
}
|
|
3438
3490
|
|
|
3439
3491
|
//#endregion
|
|
3440
|
-
export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, ContextInjector, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, Locale, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, ProstoLogger, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, cached, clearGlobalWooks, createEventContext, createLogger, createProvideRegistry, createReplaceRegistry, current, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, detachedKind, disposeInstances, eventTypeKey, forkEventContext, formatMessage, getClassKey, getConstructor, getContextInjector, getGlobalWooks, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, getTranslator, getTranslatorLocales, globalKey, isConstructor, isThenable, key, loggerConsoleTransport, mergeSorted, registerEventScope, registerMessages, replaceContextInjector, resetContextInjector, resolvePipe, run, setControllerContext, setInfactLoggingOptions, setInterceptOriginal, setInterceptResult, setOvertake, setTranslator, stampModuleIdentity, stampOnce, translateErrorBody, useControllerContext, useHandlerPaths, useInterceptOriginal, useInterceptResult, useLocale, useLogger, useOvertake, useScopeId, useTranslate, useTranslation, withControllerContext };
|
|
3492
|
+
export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, ContextInjector, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, Locale, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, ProstoLogger, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, cached, claimWooks, clearGlobalWooks, createEventContext, createLogger, createProvideRegistry, createReplaceRegistry, current, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, detachedKind, disposeInstances, eventTypeKey, forkEventContext, formatMessage, getClassKey, getConstructor, getContextInjector, getGlobalWooks, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, getTranslator, getTranslatorLocales, globalKey, isConstructor, isThenable, key, loggerConsoleTransport, mergeSorted, registerEventScope, registerMessages, replaceContextInjector, resetContextInjector, resolvePipe, run, setControllerContext, setInfactLoggingOptions, setInterceptOriginal, setInterceptResult, setOvertake, setTranslator, stampModuleIdentity, stampOnce, translateErrorBody, useControllerContext, useHandlerPaths, useInterceptOriginal, useInterceptResult, useLocale, useLogger, useOvertake, useScopeId, useTranslate, useTranslation, withControllerContext };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moost",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "moost",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
"@prostojs/infact": "^0.6.1",
|
|
42
42
|
"@prostojs/logger": "^0.4.3",
|
|
43
43
|
"@prostojs/mate": "^0.5.1",
|
|
44
|
-
"@wooksjs/event-core": "^0.8.
|
|
44
|
+
"@wooksjs/event-core": "^0.8.2",
|
|
45
45
|
"hookable": "^5.5.3",
|
|
46
|
-
"wooks": "^0.8.
|
|
46
|
+
"wooks": "^0.8.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@wooksjs/event-http": "^0.8.
|
|
50
|
-
"@wooksjs/http-body": "^0.8.
|
|
49
|
+
"@wooksjs/event-http": "^0.8.2",
|
|
50
|
+
"@wooksjs/http-body": "^0.8.2",
|
|
51
51
|
"vitest": "4.1.12",
|
|
52
|
-
"@moostjs/event-http": "^0.7.
|
|
52
|
+
"@moostjs/event-http": "^0.7.5"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"pub": "pnpm publish --access public",
|