MCPcopy Create free account
hub / github.com/SeleniumHQ/selenium / projectSchema

Function projectSchema

javascript/selenium-webdriver/project_bidi_schema.mjs:600–687  ·  view source on GitHub ↗
(ast, model, links = {})

Source from the content-addressed store, hash-verified

598 * @returns {{schemaVersion: number, commands: object[], events: object[], types: object, domains: object}} The schema.
599 */
600export function projectSchema(ast, model, links = {}) {
601 const types = {}
602 for (const def of normalizeAst(ast)) {
603 if (!def?.Name) continue
604 const node = projectType(def)
605 // Types the normalizer minted for anonymous CDDL constructs (hoisted enums /
606 // inline records, union arms) carry their decomposition so a binding can name
607 // or nest them idiomatically without parsing the synthetic key. `owner` is the
608 // type the construct was lifted out of; `label` is the member name within it.
609 if (def['x-selenium-synthetic']) {
610 node.synthetic = true
611 node.owner = def['x-selenium-owner']
612 node.label = def['x-selenium-label']
613 }
614 // Link to the type's definition in the live spec, when the index covers it —
615 // the readable prose section where one exists, else the CDDL production.
616 // Synthetic types have no spec definition and are (correctly) never in it.
617 const typeHref = links.types?.[def.Name.toLowerCase()]
618 if (typeHref) node.specHref = typeHref
619 types[def.Name] = node
620 }
621 for (const [name, node] of Object.entries(types))
622 if (node.kind === 'union') node.selector = unionSelector(name, types)
623 // Override the result-grouping unions: they are dispatched by request id, so a
624 // payload selector for them is meaningless (and would be empty/ambiguous).
625 for (const name of correlatedUnions(types)) types[name].selector = { correlated: true }
626 // A first-class union whose every arm is an object rejects a non-object payload
627 // instead of passing it through. (An alias-union like input.Origin, which carries
628 // bare-string arms, is intentionally left unflagged so those arms still pass through.)
629 for (const node of Object.values(types))
630 if (node.kind === 'union' && node.variants.every((v) => variantIsObject(v, types))) node.objectOnly = true
631
632 const commands = []
633 const events = []
634 const envelopeParams = commandEnvelopeParams(types)
635 // Commands and events link to their own prose section (`#command-*` / `#event-*`),
636 // keyed by the wire method; domains to their `#module-*` section. Present-only-when-known.
637 const link = (map, key) => (typeof key === 'string' ? map?.[key.toLowerCase()] : undefined)
638 for (const [domain, entry] of Object.entries(model)) {
639 for (const c of entry.commands ?? []) {
640 const cmd = {
641 domain,
642 method: c.method,
643 name: c.name,
644 // Prefer the envelope's params (it captures inline params the model drops).
645 params: typeRef(envelopeParams.get(c.method) ?? c.params),
646 result: typeRef(c.result),
647 }
648 const href = link(links.commands, c.method)
649 if (href) cmd.specHref = href
650 commands.push(cmd)
651 }
652 for (const e of entry.events ?? []) {
653 const ev = { domain, method: e.method, name: e.name, params: typeRef(envelopeParams.get(e.method) ?? e.params) }
654 const href = link(links.events, e.method)
655 if (href) ev.specHref = href
656 events.push(ev)
657 }

Callers 2

mainFunction · 0.85

Calls 15

normalizeAstFunction · 0.90
projectTypeFunction · 0.85
unionSelectorFunction · 0.85
correlatedUnionsFunction · 0.85
variantIsObjectFunction · 0.85
commandEnvelopeParamsFunction · 0.85
typeRefFunction · 0.85
linkFunction · 0.85
reachableTypesFunction · 0.85
extractVendorFunction · 0.85
valuesMethod · 0.80
filterMethod · 0.80

Tested by

no test coverage detected