refactor: trim scope-security helpers and docs

Inline findScope and blocked-key checks, shorten ownPropertyOnly docs,
and drop implementation-detail push() unit tests.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Yang Jun
2026-07-21 21:32:08 +08:00
co-authored by Cursor
parent 6e8af35dd5
commit 78915d1a2e
5 changed files with 10 additions and 43 deletions
-11
View File
@@ -1,5 +1,4 @@
import { Context } from './context'
import { Drop } from '../drop/drop'
import { Scope } from './scope'
describe('Context', function () {
@@ -251,21 +250,11 @@ describe('Context', function () {
expect(ctx.getSync(['bar', 'foo'])).toEqual('foo')
expect(ctx.getSync(['bar', 'bar'])).toEqual(undefined)
})
it('should wrap plain objects with null prototype', function () {
const scope = ctx.push({ foo: 'FOO' })
expect(Object.getPrototypeOf(scope)).toBeNull()
})
it('should return pushed scope for in-place mutation', function () {
const scope = ctx.push({})
scope.item = 'ITEM'
expect(ctx.getSync(['item'])).toEqual('ITEM')
})
it('should push Drop instances as-is', function () {
class TestDrop extends Drop {}
const drop = new TestDrop()
const pushed = ctx.push(drop)
expect(pushed).toBe(drop)
})
})
describe('.pop()', function () {
it('should pop scope', async function () {
+5 -15
View File
@@ -118,17 +118,11 @@ export class Context {
})
}
private findScope (key: string | number) {
const hasKey = (obj: Scope) => {
if (obj == null) return false
return this.ownPropertyOnly
? hasOwnProperty.call(obj, key)
: key in obj
}
for (let i = this.scopes.length - 1; i >= 0; i--) {
const candidate = this.scopes[i]
if (hasKey(candidate)) return candidate
if (this.ownPropertyOnly ? hasOwnProperty.call(candidate, key) : key in candidate) return candidate
}
if (hasKey(this.environments)) return this.environments
if (this.ownPropertyOnly ? hasOwnProperty.call(this.environments, key) : key in this.environments) return this.environments
return this.globals
}
readProperty (obj: Scope, key: (PropertyKey | Drop)) {
@@ -163,14 +157,10 @@ export class Context {
const BLOCKED_SCOPE_KEYS = new Set(['__proto__', 'constructor', 'prototype'])
function shouldBlockScopeKeyRead (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean): boolean {
if (typeof key !== 'string' || !BLOCKED_SCOPE_KEYS.has(key)) return false
if (ownPropertyOnly) return true
return !hasOwnProperty.call(obj, key)
}
export function readJSProperty (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean) {
if (shouldBlockScopeKeyRead(obj, key, ownPropertyOnly)) return undefined
if (typeof key === 'string' && BLOCKED_SCOPE_KEYS.has(key)) {
if (ownPropertyOnly || !hasOwnProperty.call(obj, key)) return undefined
}
if (ownPropertyOnly && !hasOwnProperty.call(obj, key) && !(obj instanceof Drop)) return undefined
return obj[key]
}