(node: JSXNodeInternal)
| 197 | }; |
| 198 | |
| 199 | const validateJSXNode = (node: JSXNodeInternal) => { |
| 200 | if (qDev) { |
| 201 | const { type, props, immutableProps, children } = node; |
| 202 | invoke(undefined, () => { |
| 203 | const isQwikC = isQwikComponent(type); |
| 204 | if (!isString(type) && !isFunction(type)) { |
| 205 | throw new Error( |
| 206 | `The <Type> of the JSX element must be either a string or a function. Instead, it's a "${typeof type}": ${String( |
| 207 | type |
| 208 | )}.` |
| 209 | ); |
| 210 | } |
| 211 | if (children) { |
| 212 | const flatChildren = isArray(children) ? children.flat() : [children]; |
| 213 | if (isString(type) || isQwikC) { |
| 214 | flatChildren.forEach((child: unknown) => { |
| 215 | if (!isValidJSXChild(child)) { |
| 216 | const typeObj = typeof child; |
| 217 | let explanation = ''; |
| 218 | if (typeObj === 'object') { |
| 219 | if (child?.constructor) { |
| 220 | explanation = `it's an instance of "${child?.constructor.name}".`; |
| 221 | } else { |
| 222 | explanation = `it's a object literal: ${printObjectLiteral(child as {})} `; |
| 223 | } |
| 224 | } else if (typeObj === 'function') { |
| 225 | explanation += `it's a function named "${(child as Function).name}".`; |
| 226 | } else { |
| 227 | explanation = `it's a "${typeObj}": ${String(child)}.`; |
| 228 | } |
| 229 | |
| 230 | throw new Error( |
| 231 | `One of the children of <${type}> is not an accepted value. JSX children must be either: string, boolean, number, <element>, Array, undefined/null, or a Promise/Signal. Instead, ${explanation}\n` |
| 232 | ); |
| 233 | } |
| 234 | }); |
| 235 | } |
| 236 | if (isBrowser) { |
| 237 | if (isFunction(type) || immutableProps) { |
| 238 | const keys: Record<string, boolean> = {}; |
| 239 | flatChildren.forEach((child: unknown) => { |
| 240 | if (isJSXNode(child) && child.key != null) { |
| 241 | const key = String(child.type) + ':' + child.key; |
| 242 | if (keys[key]) { |
| 243 | const err = createJSXError( |
| 244 | `Multiple JSX sibling nodes with the same key.\nThis is likely caused by missing a custom key in a for loop`, |
| 245 | child |
| 246 | ); |
| 247 | if (err) { |
| 248 | if (isString(child.type)) { |
| 249 | logOnceWarn(err); |
| 250 | } else { |
| 251 | logOnceWarn(err); |
| 252 | } |
| 253 | } |
| 254 | } else { |
| 255 | keys[key] = true; |
| 256 | } |
no test coverage detected
searching dependent graphs…