assign-gingerly 0.0.74 → 0.0.76
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/DX/installForwarding.js +1 -1
- package/DX/installForwarding.ts +1 -1
- package/README.md +2 -0
- package/assignFrom.js +18 -17
- package/assignFrom.ts +23 -23
- package/assignFromAsync.js +14 -13
- package/assignFromAsync.ts +15 -15
- package/assignGingerly.js +46 -42
- package/assignGingerly.ts +131 -124
- package/assignPermissions/PermissionProcessor.js +166 -0
- package/assignPermissions/PermissionProcessor.ts +210 -0
- package/assignPermissions/isAllowedImportPath.js +2 -6
- package/assignPermissions/isAllowedImportPath.ts +3 -5
- package/assignPermissions/isAllowedUrl.js +18 -0
- package/assignPermissions/isAllowedUrl.ts +15 -0
- package/assignTentatively.js +9 -11
- package/assignTentatively.ts +11 -13
- package/beVigilant.js +1 -1
- package/beVigilant.ts +1 -1
- package/buildCSSQuery.js +1 -1
- package/buildCSSQuery.ts +1 -1
- package/eachTime.js +5 -6
- package/eachTime.ts +12 -15
- package/enhanceAll.js +3 -3
- package/enhanceAll.ts +4 -4
- package/evaluatePathWithAsyncMethods.js +12 -8
- package/evaluatePathWithAsyncMethods.ts +129 -117
- package/handlers/addEventListener.js +11 -11
- package/handlers/addEventListener.ts +12 -13
- package/handlers/lazyLoad.ts +7 -7
- package/handlers/lazyLoadSwitch.ts +3 -3
- package/handlers/manageTemplateList.js +10 -10
- package/handlers/manageTemplateList.ts +12 -12
- package/handlers/rangeSelector.ts +3 -3
- package/index.js +2 -3
- package/index.ts +2 -3
- package/inferencer/types/assign-gingerly/types.d.ts +37 -23
- package/inferencer/types/el-maker/types.d.ts +33 -0
- package/inferencer/types/scratch-box/types.d.ts +3 -0
- package/inferencer/types/truth-sourcer/types.d.ts +4 -0
- package/package.json +25 -23
- package/parseWithAttrs.js +1 -1
- package/parseWithAttrs.ts +1 -1
- package/processHandlerCommands.js +5 -7
- package/processHandlerCommands.ts +12 -15
- package/{getValues.js → resolve/getValues.js} +19 -8
- package/{getValues.ts → resolve/getValues.ts} +331 -314
- package/{resolveIdRef.js → resolve/resolveIdRef.js} +1 -1
- package/{resolveIdRef.ts → resolve/resolveIdRef.ts} +1 -1
- package/{resolveValues.ts → resolve/resolveValues.ts} +1 -1
- package/types/assign-gingerly/types.d.ts +37 -8
- package/utils/findClassPrototypeInPath.js +57 -0
- package/utils/findClassPrototypeInPath.ts +62 -0
- package/utils/isAsyncSpawn.js +20 -0
- package/utils/isAsyncSpawn.ts +17 -0
- package/assignPermissions/restrictedProps.js +0 -43
- package/assignPermissions/restrictedProps.ts +0 -53
- package/resolveAndAssignFeatures.js +0 -36
- package/resolveAndAssignFeatures.ts +0 -43
- /package/{resolveTemplate.js → resolve/resolveTemplate.js} +0 -0
- /package/{resolveTemplate.ts → resolve/resolveTemplate.ts} +0 -0
- /package/{resolveValues.js → resolve/resolveValues.js} +0 -0
|
@@ -78,7 +78,7 @@ export function resolveIdVariable(varName, target, pin) {
|
|
|
78
78
|
// Fire-and-forget: log correction suggestion
|
|
79
79
|
const capturedConfig = config;
|
|
80
80
|
const capturedVarName = varName;
|
|
81
|
-
import('
|
|
81
|
+
import('../DX/pinCorrector.js').then(module => {
|
|
82
82
|
module.logConfigCorrection(target, capturedVarName, capturedConfig);
|
|
83
83
|
}).catch(() => { });
|
|
84
84
|
}
|
|
@@ -91,7 +91,7 @@ export function resolveIdVariable(
|
|
|
91
91
|
// Fire-and-forget: log correction suggestion
|
|
92
92
|
const capturedConfig = config;
|
|
93
93
|
const capturedVarName = varName;
|
|
94
|
-
import('
|
|
94
|
+
import('../DX/pinCorrector.js').then(module => {
|
|
95
95
|
module.logConfigCorrection(target, capturedVarName, capturedConfig);
|
|
96
96
|
}).catch(() => {});
|
|
97
97
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { getValue, getValues } from './getValues.js';
|
|
11
|
-
import type { ResolveValuesOptions } from '
|
|
11
|
+
import type { ResolveValuesOptions } from '../types/assign-gingerly/types.js';
|
|
12
12
|
|
|
13
13
|
export type { ResolveValuesOptions };
|
|
14
14
|
|
|
@@ -424,6 +424,11 @@ export interface GetValuesOptions extends IAssignGingerlyOptions {
|
|
|
424
424
|
*/
|
|
425
425
|
root?: any;
|
|
426
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Optional permission processor for guarding method calls during RHS resolution.
|
|
429
|
+
*/
|
|
430
|
+
permissionProcessor?: PermissionProcessor;
|
|
431
|
+
|
|
427
432
|
/**
|
|
428
433
|
* Synchronous protocol handlers for resolving protocol-prefixed values.
|
|
429
434
|
* Each handler receives the key portion and MUST return synchronously.
|
|
@@ -449,6 +454,11 @@ export interface ResolveValuesOptions extends IAssignGingerlyOptions {
|
|
|
449
454
|
*/
|
|
450
455
|
root?: any;
|
|
451
456
|
|
|
457
|
+
/**
|
|
458
|
+
* Optional permission processor for guarding method calls during RHS resolution.
|
|
459
|
+
*/
|
|
460
|
+
permissionProcessor?: PermissionProcessor;
|
|
461
|
+
|
|
452
462
|
/**
|
|
453
463
|
* Protocol handlers for resolving protocol-prefixed values (e.g., 'globalThis://key').
|
|
454
464
|
* Each handler receives the key portion and returns the resolved value (sync or async).
|
|
@@ -695,7 +705,7 @@ export interface HandlerConfig {
|
|
|
695
705
|
* Handlers are invoked when a LHS key ends with ' =>'.
|
|
696
706
|
*/
|
|
697
707
|
export interface AssignFromHandler {
|
|
698
|
-
assign(lhsTarget: any, resolvedParams: Record<string, any>, options: any,
|
|
708
|
+
assign(lhsTarget: any, resolvedParams: Record<string, any>, options: any, permissionProcessor?: PermissionProcessor): Promise<void> | void;
|
|
699
709
|
}
|
|
700
710
|
|
|
701
711
|
/**
|
|
@@ -873,7 +883,7 @@ export interface LazyLoadInstantiatedContext {
|
|
|
873
883
|
export declare class LazyLoadHandler implements AssignFromHandler {
|
|
874
884
|
config: any;
|
|
875
885
|
constructor(config: any);
|
|
876
|
-
assign(lhsTarget: any, resolvedParams: Record<string, any>, options?: any,
|
|
886
|
+
assign(lhsTarget: any, resolvedParams: Record<string, any>, options?: any, permissionProcessor?: PermissionProcessor): Promise<void>;
|
|
877
887
|
protected onCloneInserted(nodes: Node[], lhsTarget: Element, resolvedParams: Record<string, any>): Promise<void>;
|
|
878
888
|
}
|
|
879
889
|
|
|
@@ -931,11 +941,11 @@ export interface AddEventListenerConfig extends AssignDispatchVector {
|
|
|
931
941
|
* Phase II+: object form for a restricted property setting.
|
|
932
942
|
*/
|
|
933
943
|
export interface RestrictedPropSetting {
|
|
934
|
-
|
|
935
|
-
useMethod?: string;
|
|
936
|
-
attr?: string;
|
|
937
|
-
|
|
938
|
-
allowCrossDomain?: boolean;
|
|
944
|
+
props: string | string[];
|
|
945
|
+
useMethod?: string; // Phase II: redirect to a safe method
|
|
946
|
+
attr?: boolean | string | string[]; // Phase III: also watch setAttribute for these attrs
|
|
947
|
+
allowFromSameDomain?: boolean; // Phase III: allow same-origin URLs
|
|
948
|
+
allowCrossDomain?: boolean; // Phase III: allow any URL
|
|
939
949
|
}
|
|
940
950
|
|
|
941
951
|
/**
|
|
@@ -958,7 +968,8 @@ export interface AssignPermissions {
|
|
|
958
968
|
* Restricted property settings.
|
|
959
969
|
* Phase I: string entries are property names that cannot be assigned.
|
|
960
970
|
* Phase II: an object with useMethod redirects ordinary assignment to that
|
|
961
|
-
* method; command operations remain blocked. Phase III+ adds attr
|
|
971
|
+
* method; command operations remain blocked. Phase III+ adds props, attr,
|
|
972
|
+
* allowFromSameDomain, and allowCrossDomain support.
|
|
962
973
|
*
|
|
963
974
|
* NOTE: This is a property-assignment guard only. Method calls (setAttribute, etc.)
|
|
964
975
|
* are not blocked — see Phase III+. Event listeners can still be registered, but
|
|
@@ -972,3 +983,21 @@ export interface AssignPermissions {
|
|
|
972
983
|
/** Restricted method settings (Phase IV+) */
|
|
973
984
|
restrictedMethodSettings?: Array<string | RestrictedMethodConfig>;
|
|
974
985
|
}
|
|
986
|
+
|
|
987
|
+
//#region Permissions
|
|
988
|
+
export interface RestrictedPropSettingsMap {
|
|
989
|
+
props: Map<string, RestrictedPropSetting | undefined>;
|
|
990
|
+
attrs: Map<string, RestrictedPropSetting | undefined>;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
export declare class PermissionProcessor {
|
|
994
|
+
constructor(permissions: AssignPermissions | undefined);
|
|
995
|
+
get crossDomainImports(): boolean;
|
|
996
|
+
get hasProps(): boolean;
|
|
997
|
+
get hasAttrs(): boolean;
|
|
998
|
+
checkRestrictedProp(key: string): boolean;
|
|
999
|
+
checkRestrictedMethod(methodName: string): boolean;
|
|
1000
|
+
redirectRestrictedProp(target: any, key: string, value: any): boolean;
|
|
1001
|
+
checkRestrictedAttributeCall(methodName: string, args: any[]): { blocked: boolean; attrName?: string };
|
|
1002
|
+
}
|
|
1003
|
+
//#endregion
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isAllowedImportPath } from '../assignPermissions/isAllowedImportPath.js';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when a dynamic import path is not covered by the allowed-import policy.
|
|
4
|
+
*/
|
|
5
|
+
export class ImportNotAllowedError extends Error {
|
|
6
|
+
path;
|
|
7
|
+
constructor(path) {
|
|
8
|
+
super(`Import path "${path}" is not allowed.`);
|
|
9
|
+
this.path = path;
|
|
10
|
+
this.name = 'ImportNotAllowedError';
|
|
11
|
+
console.error(`ImportNotAllowedError: ${path}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when a module does not export a class that satisfies the required criteria.
|
|
16
|
+
*/
|
|
17
|
+
export class NoMatchingExportError extends Error {
|
|
18
|
+
path;
|
|
19
|
+
constructor(path) {
|
|
20
|
+
super(`Module "${path}" does not export a matching class with a prototype.`);
|
|
21
|
+
this.path = path;
|
|
22
|
+
this.name = 'NoMatchingExportError';
|
|
23
|
+
console.error(`NoMatchingExportError: ${path}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Base check: value must be a function with a prototype (i.e., a class constructor).
|
|
28
|
+
*/
|
|
29
|
+
function isClassWithPrototype(value) {
|
|
30
|
+
return typeof value === 'function' && value.prototype !== undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Dynamically import a module at the given path, validate the path against the
|
|
34
|
+
* allowed-import policy, and return the first exported class whose prototype passes
|
|
35
|
+
* the optional criteria check.
|
|
36
|
+
*
|
|
37
|
+
* The default export is checked first. If it does not satisfy the checks, all named
|
|
38
|
+
* exports are scanned. If no matching class is found, a `NoMatchingExportError` is thrown.
|
|
39
|
+
*/
|
|
40
|
+
export async function findClassPrototypeInPath(path, criteria) {
|
|
41
|
+
if (!isAllowedImportPath(path)) {
|
|
42
|
+
throw new ImportNotAllowedError(path);
|
|
43
|
+
}
|
|
44
|
+
const module = await import(path);
|
|
45
|
+
const candidates = [
|
|
46
|
+
module.default,
|
|
47
|
+
...Object.values(module).filter((exported) => exported !== module.default),
|
|
48
|
+
];
|
|
49
|
+
for (const exported of candidates) {
|
|
50
|
+
if (!isClassWithPrototype(exported))
|
|
51
|
+
continue;
|
|
52
|
+
if (criteria && !criteria(exported))
|
|
53
|
+
continue;
|
|
54
|
+
return exported;
|
|
55
|
+
}
|
|
56
|
+
throw new NoMatchingExportError(path);
|
|
57
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isAllowedImportPath } from '../assignPermissions/isAllowedImportPath.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a dynamic import path is not covered by the allowed-import policy.
|
|
5
|
+
*/
|
|
6
|
+
export class ImportNotAllowedError extends Error {
|
|
7
|
+
constructor(public readonly path: string) {
|
|
8
|
+
super(`Import path "${path}" is not allowed.`);
|
|
9
|
+
this.name = 'ImportNotAllowedError';
|
|
10
|
+
console.error(`ImportNotAllowedError: ${path}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when a module does not export a class that satisfies the required criteria.
|
|
16
|
+
*/
|
|
17
|
+
export class NoMatchingExportError extends Error {
|
|
18
|
+
constructor(public readonly path: string) {
|
|
19
|
+
super(`Module "${path}" does not export a matching class with a prototype.`);
|
|
20
|
+
this.name = 'NoMatchingExportError';
|
|
21
|
+
console.error(`NoMatchingExportError: ${path}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Base check: value must be a function with a prototype (i.e., a class constructor).
|
|
27
|
+
*/
|
|
28
|
+
function isClassWithPrototype(value: any): boolean {
|
|
29
|
+
return typeof value === 'function' && value.prototype !== undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Dynamically import a module at the given path, validate the path against the
|
|
34
|
+
* allowed-import policy, and return the first exported class whose prototype passes
|
|
35
|
+
* the optional criteria check.
|
|
36
|
+
*
|
|
37
|
+
* The default export is checked first. If it does not satisfy the checks, all named
|
|
38
|
+
* exports are scanned. If no matching class is found, a `NoMatchingExportError` is thrown.
|
|
39
|
+
*/
|
|
40
|
+
export async function findClassPrototypeInPath<T = any>(
|
|
41
|
+
path: string,
|
|
42
|
+
criteria?: (proto: any) => boolean
|
|
43
|
+
): Promise<{ new(): T }> {
|
|
44
|
+
if (!isAllowedImportPath(path)) {
|
|
45
|
+
throw new ImportNotAllowedError(path);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const module = await import(path);
|
|
49
|
+
|
|
50
|
+
const candidates = [
|
|
51
|
+
module.default,
|
|
52
|
+
...Object.values(module).filter((exported: any) => exported !== module.default),
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
for (const exported of candidates) {
|
|
56
|
+
if (!isClassWithPrototype(exported)) continue;
|
|
57
|
+
if (criteria && !criteria(exported)) continue;
|
|
58
|
+
return exported as { new(): T };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw new NoMatchingExportError(path);
|
|
62
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines if a function is an async spawner (returns a Promise<Constructor>)
|
|
3
|
+
* rather than a synchronous constructor.
|
|
4
|
+
*
|
|
5
|
+
* Heuristic:
|
|
6
|
+
* - AsyncFunction (async () => ...) → async spawner
|
|
7
|
+
* - Arrow function (no .prototype) → async spawner (assumed to return Promise<Constructor>)
|
|
8
|
+
* - Class or function declaration (has .prototype) → synchronous constructor
|
|
9
|
+
*/
|
|
10
|
+
export function isAsyncSpawn(fn) {
|
|
11
|
+
if (typeof fn !== 'function')
|
|
12
|
+
return false;
|
|
13
|
+
// Explicit async function
|
|
14
|
+
if (fn.constructor.name === 'AsyncFunction')
|
|
15
|
+
return true;
|
|
16
|
+
// Arrow function or non-constructor function (no .prototype)
|
|
17
|
+
if (fn.prototype === undefined)
|
|
18
|
+
return true;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines if a function is an async spawner (returns a Promise<Constructor>)
|
|
3
|
+
* rather than a synchronous constructor.
|
|
4
|
+
*
|
|
5
|
+
* Heuristic:
|
|
6
|
+
* - AsyncFunction (async () => ...) → async spawner
|
|
7
|
+
* - Arrow function (no .prototype) → async spawner (assumed to return Promise<Constructor>)
|
|
8
|
+
* - Class or function declaration (has .prototype) → synchronous constructor
|
|
9
|
+
*/
|
|
10
|
+
export function isAsyncSpawn(fn: any): boolean {
|
|
11
|
+
if (typeof fn !== 'function') return false;
|
|
12
|
+
// Explicit async function
|
|
13
|
+
if (fn.constructor.name === 'AsyncFunction') return true;
|
|
14
|
+
// Arrow function or non-constructor function (no .prototype)
|
|
15
|
+
if (fn.prototype === undefined) return true;
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
const warnedOnce = new Set();
|
|
2
|
-
function warnRestricted(key) {
|
|
3
|
-
if (!warnedOnce.has(key)) {
|
|
4
|
-
warnedOnce.add(key);
|
|
5
|
-
console.warn(`assignGingerly: property '${key}' is in restrictedPropSettings — assignment skipped.`);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
export function buildRestrictedPropSet(permissions) {
|
|
9
|
-
const settings = permissions?.restrictedPropSettings;
|
|
10
|
-
if (!settings || settings.length === 0)
|
|
11
|
-
return undefined;
|
|
12
|
-
const restrictedPropSet = new Map();
|
|
13
|
-
for (const setting of settings) {
|
|
14
|
-
const prop = typeof setting === 'string' ? setting : setting.prop;
|
|
15
|
-
if (restrictedPropSet.has(prop)) {
|
|
16
|
-
throw new Error(`assignGingerly: duplicate restrictedPropSettings entry for '${prop}'.`);
|
|
17
|
-
}
|
|
18
|
-
restrictedPropSet.set(prop, typeof setting === 'string' ? undefined : setting);
|
|
19
|
-
}
|
|
20
|
-
return restrictedPropSet;
|
|
21
|
-
}
|
|
22
|
-
export function checkRestrictedProp(restrictedPropSet, key) {
|
|
23
|
-
if (!restrictedPropSet || !restrictedPropSet.has(key))
|
|
24
|
-
return false;
|
|
25
|
-
warnRestricted(key);
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
export function redirectRestrictedProp(restrictedPropSet, target, key, value) {
|
|
29
|
-
if (!restrictedPropSet || !restrictedPropSet.has(key))
|
|
30
|
-
return false;
|
|
31
|
-
const setting = restrictedPropSet.get(key);
|
|
32
|
-
if (!setting?.useMethod) {
|
|
33
|
-
warnRestricted(key);
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
const method = target?.[setting.useMethod];
|
|
37
|
-
if (typeof method !== 'function') {
|
|
38
|
-
warnRestricted(key);
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
method.call(target, value);
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { AssignPermissions, RestrictedPropSetting } from '../types/assign-gingerly/types.js';
|
|
2
|
-
|
|
3
|
-
export type RestrictedPropSettingsMap = Map<string, RestrictedPropSetting | undefined>;
|
|
4
|
-
|
|
5
|
-
const warnedOnce = new Set<string>();
|
|
6
|
-
|
|
7
|
-
function warnRestricted(key: string): void {
|
|
8
|
-
if (!warnedOnce.has(key)) {
|
|
9
|
-
warnedOnce.add(key);
|
|
10
|
-
console.warn(`assignGingerly: property '${key}' is in restrictedPropSettings — assignment skipped.`);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function buildRestrictedPropSet(permissions: AssignPermissions | undefined): RestrictedPropSettingsMap | undefined {
|
|
15
|
-
const settings = permissions?.restrictedPropSettings;
|
|
16
|
-
if (!settings || settings.length === 0) return undefined;
|
|
17
|
-
const restrictedPropSet: RestrictedPropSettingsMap = new Map();
|
|
18
|
-
for (const setting of settings) {
|
|
19
|
-
const prop = typeof setting === 'string' ? setting : setting.prop;
|
|
20
|
-
if (restrictedPropSet.has(prop)) {
|
|
21
|
-
throw new Error(`assignGingerly: duplicate restrictedPropSettings entry for '${prop}'.`);
|
|
22
|
-
}
|
|
23
|
-
restrictedPropSet.set(prop, typeof setting === 'string' ? undefined : setting);
|
|
24
|
-
}
|
|
25
|
-
return restrictedPropSet;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function checkRestrictedProp(restrictedPropSet: RestrictedPropSettingsMap | undefined, key: string): boolean {
|
|
29
|
-
if (!restrictedPropSet || !restrictedPropSet.has(key)) return false;
|
|
30
|
-
warnRestricted(key);
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function redirectRestrictedProp(
|
|
35
|
-
restrictedPropSet: RestrictedPropSettingsMap | undefined,
|
|
36
|
-
target: any,
|
|
37
|
-
key: string,
|
|
38
|
-
value: any
|
|
39
|
-
): boolean {
|
|
40
|
-
if (!restrictedPropSet || !restrictedPropSet.has(key)) return false;
|
|
41
|
-
const setting = restrictedPropSet.get(key);
|
|
42
|
-
if (!setting?.useMethod) {
|
|
43
|
-
warnRestricted(key);
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
const method = target?.[setting.useMethod];
|
|
47
|
-
if (typeof method !== 'function') {
|
|
48
|
-
warnRestricted(key);
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
method.call(target, value);
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* resolveAndAssignFeatures - Thin wrapper around assignFeatures for backward compatibility.
|
|
3
|
-
*
|
|
4
|
-
* Resolves all configured spawns (including async fallback spawns and string import paths)
|
|
5
|
-
* and installs feature getters on the class prototype, then delegates to the registry's
|
|
6
|
-
* assignFeatures implementation.
|
|
7
|
-
*
|
|
8
|
-
* This is kept as a convenience entry point for callers that already await this function.
|
|
9
|
-
* The actual resolution logic lives in assignFeatures.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* import { resolveAndAssignFeatures } from 'assign-gingerly/resolveAndAssignFeatures.js';
|
|
13
|
-
*
|
|
14
|
-
* await resolveAndAssignFeatures(MyElement, {
|
|
15
|
-
* roundabout: {
|
|
16
|
-
* customData: {...},
|
|
17
|
-
* withAttrs: {...},
|
|
18
|
-
* callbackForwarding: ['connectedCallback']
|
|
19
|
-
* },
|
|
20
|
-
* faceUp: {
|
|
21
|
-
* callbackForwarding: ['connectedCallback', 'disconnectedCallback']
|
|
22
|
-
* }
|
|
23
|
-
* });
|
|
24
|
-
*/
|
|
25
|
-
import { assignFeatures } from './assignFeatures.js';
|
|
26
|
-
/**
|
|
27
|
-
* Resolves all configured spawns and calls assignFeatures on the registry.
|
|
28
|
-
*
|
|
29
|
-
* @param ElementClass - The custom element class (must have static supportedFeatures)
|
|
30
|
-
* @param featuresConfig - Feature configurations (spawn will be resolved from fallbackSpawn if missing)
|
|
31
|
-
* @param registry - Optional CustomElementRegistry (defaults to global customElements)
|
|
32
|
-
*/
|
|
33
|
-
export async function resolveAndAssignFeatures(ElementClass, featuresConfig, registry) {
|
|
34
|
-
const reg = registry || customElements;
|
|
35
|
-
await assignFeatures(ElementClass, featuresConfig, reg.featuresRegistry);
|
|
36
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* resolveAndAssignFeatures - Thin wrapper around assignFeatures for backward compatibility.
|
|
3
|
-
*
|
|
4
|
-
* Resolves all configured spawns (including async fallback spawns and string import paths)
|
|
5
|
-
* and installs feature getters on the class prototype, then delegates to the registry's
|
|
6
|
-
* assignFeatures implementation.
|
|
7
|
-
*
|
|
8
|
-
* This is kept as a convenience entry point for callers that already await this function.
|
|
9
|
-
* The actual resolution logic lives in assignFeatures.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* import { resolveAndAssignFeatures } from 'assign-gingerly/resolveAndAssignFeatures.js';
|
|
13
|
-
*
|
|
14
|
-
* await resolveAndAssignFeatures(MyElement, {
|
|
15
|
-
* roundabout: {
|
|
16
|
-
* customData: {...},
|
|
17
|
-
* withAttrs: {...},
|
|
18
|
-
* callbackForwarding: ['connectedCallback']
|
|
19
|
-
* },
|
|
20
|
-
* faceUp: {
|
|
21
|
-
* callbackForwarding: ['connectedCallback', 'disconnectedCallback']
|
|
22
|
-
* }
|
|
23
|
-
* });
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import { FeatureConfigsMap } from './types/assign-gingerly/types.js';
|
|
27
|
-
import { assignFeatures } from './assignFeatures.js';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Resolves all configured spawns and calls assignFeatures on the registry.
|
|
31
|
-
*
|
|
32
|
-
* @param ElementClass - The custom element class (must have static supportedFeatures)
|
|
33
|
-
* @param featuresConfig - Feature configurations (spawn will be resolved from fallbackSpawn if missing)
|
|
34
|
-
* @param registry - Optional CustomElementRegistry (defaults to global customElements)
|
|
35
|
-
*/
|
|
36
|
-
export async function resolveAndAssignFeatures(
|
|
37
|
-
ElementClass: Function,
|
|
38
|
-
featuresConfig: FeatureConfigsMap,
|
|
39
|
-
registry?: any
|
|
40
|
-
): Promise<void> {
|
|
41
|
-
const reg = registry || customElements;
|
|
42
|
-
await assignFeatures(ElementClass, featuresConfig, reg.featuresRegistry);
|
|
43
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|