MCPcopy Index your code
hub / github.com/browserless/browserless / buildSchemas

Function buildSchemas

scripts/build-schemas.js:56–181  ·  view source on GitHub ↗
(
  externalHTTPRoutes = [],
  externalWebSocketRoutes = [],
)

Source from the content-addressed store, hash-verified

54 * @param {string[]} externalWebSocketRoutes Additional WS routes to parse
55 */
56const buildSchemas = async (
57 externalHTTPRoutes = [],
58 externalWebSocketRoutes = [],
59) => {
60 const { getRouteFiles, tsExtension } = await import('../build/utils.js');
61
62 const schemas = ['BodySchema', 'QuerySchema', 'ResponseSchema'];
63 const settings = {
64 ignoreErrors: true,
65 noExtraProps: true,
66 required: true,
67 };
68
69 const { compilerOptions } = JSON.parse(
70 await fs.readFile('tsconfig.json', 'utf-8'),
71 );
72
73 const { Config } = await import('../build/config.js');
74 const [httpRoutes, wsRoutes] = await getRouteFiles(new Config());
75
76 // Depending on if we're parsing an external projects routes,
77 // skip the prebuilt ones. This makes it much faster to build
78 const routesToParse = (
79 moduleMain
80 ? [...httpRoutes, ...wsRoutes]
81 : [...externalHTTPRoutes, ...externalWebSocketRoutes]
82 ).filter((r) => r.endsWith(tsExtension));
83
84 if (routesToParse.length === 0) {
85 return;
86 }
87
88 // Build a SINGLE TypeScript program for every route up front. Previously a
89 // fresh program was created per route, which re-parsed the entire standard
90 // lib and the large transitive `.d.ts` graph (puppeteer-core, playwright,
91 // @types/node) once per file — the dominant cost of this script. One shared
92 // program does that work a single time.
93 //
94 // Schema generation must be deterministic and independent of the consumer's
95 // runtime module settings. Under moduleResolution "nodenext"/"node16", types
96 // pulled from dual CJS/ESM packages (e.g. puppeteer-core) serialize as
97 // absolute-path `import("...",{with:{"resolution-mode":"import"}}).Type`
98 // $ref names that the ajv-backed validator cannot resolve at request time.
99 // Forcing the canonical es2022/bundler resolution yields stable, named $refs
100 // for every consumer regardless of how their own tsconfig is configured.
101 const program = TJS.getProgramFromFiles(
102 routesToParse,
103 { ...compilerOptions, module: 'es2022', moduleResolution: 'bundler' },
104 './',
105 );
106
107 // `uniqueNames` lets identically-named interfaces (e.g. every route's
108 // `BodySchema`) coexist in one program by suffixing each definition with a
109 // hash. We use it only to address the specific symbol a given route exports;
110 // the suffixes are stripped from the emitted files (see stripHashSuffixes).
111 const generator = TJS.buildGenerator(program, {
112 ...settings,
113 uniqueNames: true,

Callers 2

build-schemas.jsFile · 0.85
buildFunction · 0.85

Calls 4

getRouteFilesFunction · 0.85
stripHashSuffixesFunction · 0.85
getMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected