From 6e8447c82281269756e746de38845bd65fde1976 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sun, 12 Jan 2025 10:03:35 +0800 Subject: [PATCH] fix: not allow to override the `app.locals.__` method (#15) --- src/app.ts | 12 ++++++++++-- test/i18n.test.ts | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/app.ts b/src/app.ts index 9409885..aee5d18 100644 --- a/src/app.ts +++ b/src/app.ts @@ -93,7 +93,15 @@ export default class I18n implements ILifecycleBoot { return ctx.gettext(key, ...args); } // 在 view 中使用 `__(key, value, ...args)` - this.app.locals.gettext = gettextInContext; - this.app.locals.__ = gettextInContext; + Object.defineProperties(app.locals, { + __: { + value: gettextInContext, + enumerable: true, + }, + gettext: { + value: gettextInContext, + enumerable: true, + }, + }); } } diff --git a/test/i18n.test.ts b/test/i18n.test.ts index e6e88ac..cee8fff 100644 --- a/test/i18n.test.ts +++ b/test/i18n.test.ts @@ -90,6 +90,20 @@ describe('test/i18n.test.ts', () => { assert.strictEqual(ctx.app.__('en-us', 'Email {0} {1}', [ 'a', 'b' ]), 'Email a b'); assert.strictEqual(ctx.app.__('en-us', '', [ 'a', 'b' ]), ''); }); + + it('should ctx.locals.__() work', () => { + const ctx = app.mockContext(); + assert.equal(ctx.locals.__('Email %s', 'ok'), 'Email ok'); + ctx.locals.a = 'aaa'; + assert.equal(ctx.locals.a, 'aaa'); + assert.deepEqual(Object.keys(ctx.locals), [ '__', 'gettext', 'a' ]); + }); + + it('should not allow to override the app.locals.__', () => { + assert.throws(() => { + app.locals.__ = () => 'app.__'; + }, /Cannot assign to read only property '__' of object/); + }); }); describe('with cookieDomain', () => {