Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | 1x 21x 21x 21x 21x 21x 21x 21x 21x 45x 1x 8x 216x 8x 72x 72x 72x 54x 72x 72x 54x 18x 54x 18x 72x 72x 72x 72x 72x | import type {
UiNode,
UiNodeAnchorAttributes,
UiNodeAttributes,
UiNodeGroupEnum,
UiNodeImageAttributes,
UiNodeInputAttributes,
UiNodeInputAttributesTypeEnum,
UiNodeScriptAttributes,
UiNodeTextAttributes,
} from "@ory/client"
/**
* Returns the node's label.
*
* @param node
* @return label
*/
export const getNodeLabel = (node: UiNode): string => {
const attributes = node.attributes
Iif (isUiNodeAnchorAttributes(attributes)) {
return attributes.title.text
}
Iif (isUiNodeImageAttributes(attributes)) {
return node.meta.label?.text || ""
}
Iif (isUiNodeInputAttributes(attributes)) {
if (attributes.label?.text) {
return attributes.label.text
}
}
return node.meta.label?.text || ""
}
/**
* A TypeScript type guard for nodes of the type <a>
*
* @param attrs
*/
export function isUiNodeAnchorAttributes(
attrs: UiNodeAttributes,
): attrs is UiNodeAnchorAttributes & { node_type: "a" } {
return attrs.node_type === "a"
}
/**
* A TypeScript type guard for nodes of the type <img>
*
* @param attrs
*/
export function isUiNodeImageAttributes(
attrs: UiNodeAttributes,
): attrs is UiNodeImageAttributes & { node_type: "img" } {
return attrs.node_type === "img"
}
/**
* A TypeScript type guard for nodes of the type <input>
*
* @param attrs
*/
export function isUiNodeInputAttributes(
attrs: UiNodeAttributes,
): attrs is UiNodeInputAttributes & { node_type: "input" } {
return attrs.node_type === "input"
}
/**
* A TypeScript type guard for nodes of the type <span>{text}</span>
*
* @param attrs
*/
export function isUiNodeTextAttributes(
attrs: UiNodeAttributes,
): attrs is UiNodeTextAttributes & { node_type: "text" } {
return attrs.node_type === "text"
}
/**
* A TypeScript type guard for nodes of the type <script>
*
* @param attrs
*/
export function isUiNodeScriptAttributes(
attrs: UiNodeAttributes,
): attrs is UiNodeScriptAttributes & { node_type: "script" } {
return attrs.node_type === "script"
}
/**
* Returns a node's ID.
*
* @param attributes
*/
export function getNodeId({ attributes }: UiNode) {
if (isUiNodeInputAttributes(attributes)) {
return attributes.name
} else {
return attributes.id
}
}
/**
* Return the node input attribute type
* In <input> elements we have a variety of types, such as text, password, email, etc.
* When the attribute is null or the `type` attribute is not present, we assume it has no defined type.
* @param attr
* @returns type of node
*/
export const getNodeInputType = (attr: any): string => attr?.["type"] ?? ""
export type FilterNodesByGroups = {
nodes: Array<UiNode>
groups?: Array<UiNodeGroupEnum | string> | UiNodeGroupEnum | string
withoutDefaultGroup?: boolean
attributes?:
| Array<UiNodeInputAttributesTypeEnum | string>
| UiNodeInputAttributesTypeEnum
| string
withoutDefaultAttributes?: boolean
excludeAttributes?:
| Array<UiNodeInputAttributesTypeEnum | string>
| UiNodeInputAttributesTypeEnum
| string
}
/**
* Filters nodes by their groups and attributes.
* If no filtering options are specified, all nodes are returned.
* Will always add default nodes unless `withoutDefaultGroup` is true.
* Will always add default attributes unless `withoutDefaultAttributes` is true.
* @param {Object} filterNodesByGroups - An object containing the nodes and the filtering options.
* @param {Array<UiNode>} filterNodesByGroups.nodes - An array of nodes.
* @param {Array<UiNodeGroupEnum | string> | string} filterNodesByGroups.groups - An array or comma seperated strings of groups to filter by.
* @param {boolean} filterNodesByGroups.withoutDefaultGroup - If true, will not add default nodes under the 'default' category.
* @param {Array<UiNodeInputAttributesTypeEnum | string> | string} filterNodesByGroups.attributes - An array or comma seperated strings of attributes to filter by.
* @param {boolean} filterNodesByGroups.withoutDefaultAttributes - If true, will not add default attributes such as 'hidden' and 'script'.
*/
export const filterNodesByGroups = ({
nodes,
groups,
withoutDefaultGroup,
attributes,
withoutDefaultAttributes,
excludeAttributes,
}: FilterNodesByGroups) => {
const search = (s: Array<string> | string) =>
typeof s === "string" ? s.split(",") : s
return nodes.filter(({ group, attributes: attr }) => {
// if we have not specified any group or attribute filters, return all nodes
Iif (!groups && !attributes && !excludeAttributes) return true
const g = search(groups) || []
if (!withoutDefaultGroup) {
g.push("default")
}
// filter the attributes
const a = search(attributes) || []
if (!withoutDefaultAttributes) {
// always add hidden fields e.g. csrf
if (group.includes("default")) {
a.push("hidden")
}
// automatically add the necessary fields for webauthn and totp
if (group.includes("webauthn") || group.includes("totp")) {
a.push("input", "script")
}
}
// filter the attributes to exclude
const ea = search(excludeAttributes) || []
const filterGroup = groups ? g.includes(group) : true
const filterAttributes = attributes
? a.includes(getNodeInputType(attr))
: true
const filterExcludeAttributes = excludeAttributes
? !ea.includes(getNodeInputType(attr))
: true
return filterGroup && filterAttributes && filterExcludeAttributes
})
}
|