Update VPN client and gateway behavior
This commit is contained in:
+30
-20
@@ -260,7 +260,7 @@ function dynamicClassBindings(files) {
|
||||
}));
|
||||
}
|
||||
|
||||
function bindComponentProps(definition, element, callerEnvironment, dynamicBindings) {
|
||||
function bindComponentProps(definition, element, callerEnvironment, callerFile, dynamicBindings) {
|
||||
const supplied = new Map();
|
||||
for (const attribute of element.openingElement.attributes) {
|
||||
if (attribute.type === 'JSXSpreadAttribute') {
|
||||
@@ -277,9 +277,10 @@ function bindComponentProps(definition, element, callerEnvironment, dynamicBindi
|
||||
callable: ['ArrowFunctionExpression', 'FunctionExpression'].includes(node.type) && producesJsx(node),
|
||||
node,
|
||||
environment: callerEnvironment,
|
||||
file: callerFile,
|
||||
});
|
||||
}
|
||||
supplied.set('children', { node: element.children, environment: callerEnvironment });
|
||||
supplied.set('children', { node: element.children, environment: callerEnvironment, file: callerFile });
|
||||
const environment = new Map(dynamicBindings.get(definition.file));
|
||||
const parameter = definition.node.params?.[0];
|
||||
if (parameter?.type === 'ObjectPattern') {
|
||||
@@ -289,7 +290,7 @@ function bindComponentProps(definition, element, callerEnvironment, dynamicBindi
|
||||
const target = property.value?.type === 'AssignmentPattern' ? property.value.left : property.value;
|
||||
const localName = target?.name;
|
||||
const fallback = property.value?.type === 'AssignmentPattern'
|
||||
? { node: property.value.right, environment: callerEnvironment }
|
||||
? { node: property.value.right, environment: callerEnvironment, file: definition.file }
|
||||
: null;
|
||||
if (sourceName && localName && (supplied.get(sourceName) || fallback)) {
|
||||
environment.set(localName, supplied.get(sourceName) || fallback);
|
||||
@@ -309,7 +310,7 @@ function producesJsx(node) {
|
||||
));
|
||||
}
|
||||
|
||||
function withLocalJsxBindings(node, environment, definitionNodes) {
|
||||
function withLocalJsxBindings(node, environment, definitionNodes, file) {
|
||||
const scoped = new Map(environment);
|
||||
const collect = (value) => {
|
||||
if (!value || typeof value !== 'object') return;
|
||||
@@ -323,6 +324,7 @@ function withLocalJsxBindings(node, environment, definitionNodes) {
|
||||
callable: ['ArrowFunctionExpression', 'FunctionExpression'].includes(value.init?.type),
|
||||
declaration: value,
|
||||
environment: scoped,
|
||||
file,
|
||||
node: value.init,
|
||||
});
|
||||
return;
|
||||
@@ -336,12 +338,12 @@ function withLocalJsxBindings(node, environment, definitionNodes) {
|
||||
return scoped;
|
||||
}
|
||||
|
||||
function bindCallParameters(callable, argumentsList, callerEnvironment) {
|
||||
function bindCallParameters(callable, argumentsList, callerEnvironment, callerFile) {
|
||||
const environment = new Map(callable.environment);
|
||||
for (let index = 0; index < callable.node.params.length; index += 1) {
|
||||
const parameter = callable.node.params[index];
|
||||
if (parameter?.type === 'Identifier' && argumentsList[index]) {
|
||||
environment.set(parameter.name, { node: argumentsList[index], environment: callerEnvironment });
|
||||
environment.set(parameter.name, { node: argumentsList[index], environment: callerEnvironment, file: callerFile });
|
||||
}
|
||||
}
|
||||
return environment;
|
||||
@@ -361,11 +363,17 @@ export function createStyleWitnesses(sources, { entry = 'App' } = {}) {
|
||||
const expand = (definition, ancestors, ancestorUnknown, environment, stack) => {
|
||||
if (stack.includes(definition)) throw new TypeError(`Recursive JSX witness component: ${definition.node.id?.name || definition.file}`);
|
||||
const nextStack = [...stack, definition];
|
||||
const entryEnvironment = withLocalJsxBindings(definition.node.body, environment, definitionNodes);
|
||||
const visit = (node, currentAncestors = ancestors, currentUnknown = ancestorUnknown, currentEnvironment = entryEnvironment) => {
|
||||
const entryEnvironment = withLocalJsxBindings(definition.node.body, environment, definitionNodes, definition.file);
|
||||
const visit = (
|
||||
node,
|
||||
currentAncestors = ancestors,
|
||||
currentUnknown = ancestorUnknown,
|
||||
currentEnvironment = entryEnvironment,
|
||||
currentFile = definition.file,
|
||||
) => {
|
||||
if (!node || typeof node !== 'object') return;
|
||||
if (Array.isArray(node)) {
|
||||
for (const child of node) visit(child, currentAncestors, currentUnknown, currentEnvironment);
|
||||
for (const child of node) visit(child, currentAncestors, currentUnknown, currentEnvironment, currentFile);
|
||||
return;
|
||||
}
|
||||
if (definitionNodes.has(node)) return;
|
||||
@@ -378,10 +386,11 @@ export function createStyleWitnesses(sources, { entry = 'App' } = {}) {
|
||||
if (callable?.callable) {
|
||||
const callEnvironment = withLocalJsxBindings(
|
||||
callable.node.body,
|
||||
bindCallParameters(callable, node.arguments, currentEnvironment),
|
||||
bindCallParameters(callable, node.arguments, currentEnvironment, currentFile),
|
||||
definitionNodes,
|
||||
callable.file || currentFile,
|
||||
);
|
||||
visit(callable.node.body, currentAncestors, currentUnknown, callEnvironment);
|
||||
visit(callable.node.body, currentAncestors, currentUnknown, callEnvironment, callable.file || currentFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -401,16 +410,16 @@ export function createStyleWitnesses(sources, { entry = 'App' } = {}) {
|
||||
if (!documentBody && !appOrBody) {
|
||||
throw new TypeError(`Unsupported JSX portal target in ${definition.file}`);
|
||||
}
|
||||
visit(node.arguments[0], [], false, currentEnvironment);
|
||||
visit(node.arguments[0], [], false, currentEnvironment, currentFile);
|
||||
if (appOrBody) {
|
||||
visit(node.arguments[0], [{ classes: ['app', 'client-app', 'is-gateway-app'], prefixes: [], unknown: false }], false, currentEnvironment);
|
||||
visit(node.arguments[0], [{ classes: ['app', 'client-app', 'is-gateway-app'], prefixes: [], unknown: false }], false, currentEnvironment, currentFile);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (node.type === 'JSXExpressionContainer' && node.expression?.type === 'Identifier') {
|
||||
const binding = currentEnvironment.get(node.expression.name);
|
||||
if (binding) {
|
||||
visit(binding.node, currentAncestors, currentUnknown, binding.environment);
|
||||
visit(binding.node, currentAncestors, currentUnknown, binding.environment, binding.file || currentFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -419,7 +428,7 @@ export function createStyleWitnesses(sources, { entry = 'App' } = {}) {
|
||||
const intrinsic = Boolean(name && /^[a-z]/.test(name));
|
||||
if (intrinsic) {
|
||||
const initialInfo = elementClassInfo(node.openingElement, currentEnvironment);
|
||||
const additions = [...imperativeByFile.get(definition.file).entries()]
|
||||
const additions = [...imperativeByFile.get(currentFile).entries()]
|
||||
.filter(([target]) => initialInfo.classes.includes(target))
|
||||
.flatMap(([, classes]) => classes);
|
||||
const info = elementClassInfo(node.openingElement, currentEnvironment, additions);
|
||||
@@ -432,26 +441,26 @@ export function createStyleWitnesses(sources, { entry = 'App' } = {}) {
|
||||
tag: name,
|
||||
unknown: info.unknown,
|
||||
});
|
||||
visit(node.children, [...currentAncestors, info], currentUnknown, currentEnvironment);
|
||||
visit(node.children, [...currentAncestors, info], currentUnknown, currentEnvironment, currentFile);
|
||||
return;
|
||||
}
|
||||
if (TRANSPARENT_JSX_COMPONENTS.has(name)) {
|
||||
visit(node.children, currentAncestors, currentUnknown, currentEnvironment);
|
||||
visit(node.children, currentAncestors, currentUnknown, currentEnvironment, currentFile);
|
||||
return;
|
||||
}
|
||||
const target = definitions.get(name);
|
||||
if (!target) throw new TypeError(`Unresolved JSX witness component: ${name} in ${definition.file}`);
|
||||
const targetEnvironment = bindComponentProps(target, node, currentEnvironment, dynamicByFile);
|
||||
const targetEnvironment = bindComponentProps(target, node, currentEnvironment, currentFile, dynamicByFile);
|
||||
expand(target, currentAncestors, currentUnknown, targetEnvironment, nextStack);
|
||||
return;
|
||||
}
|
||||
if (node.type === 'JSXFragment') {
|
||||
visit(node.children, currentAncestors, currentUnknown, currentEnvironment);
|
||||
visit(node.children, currentAncestors, currentUnknown, currentEnvironment, currentFile);
|
||||
return;
|
||||
}
|
||||
for (const [key, child] of Object.entries(node)) {
|
||||
if (['loc', 'start', 'end', 'extra', 'comments', 'tokens', 'errors'].includes(key)) continue;
|
||||
if (child && typeof child === 'object') visit(child, currentAncestors, currentUnknown, currentEnvironment);
|
||||
if (child && typeof child === 'object') visit(child, currentAncestors, currentUnknown, currentEnvironment, currentFile);
|
||||
}
|
||||
};
|
||||
visit(definition.node.body, ancestors, ancestorUnknown, entryEnvironment);
|
||||
@@ -521,6 +530,7 @@ const TRANSPARENT_JSX_COMPONENTS = new Set(['React.Fragment']);
|
||||
const hash = (value) => crypto.createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
||||
|
||||
function propertyFamily(property) {
|
||||
if (property.startsWith('--')) return property;
|
||||
if (!OBSERVED_PROPERTIES.has(property)) {
|
||||
throw new TypeError(`Unsupported CSS property in cascade proof: ${property}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user