| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | #!/usr/bin/env node
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-30 18:43:18 +02:00
										 |  |  | // @ts-check
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | const fs = require('fs'); | 
					
						
							| 
									
										
										
										
											2021-01-06 12:41:17 -08:00
										 |  |  | const os = require('os'); | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | const path = require('path'); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | const yaml = require('yaml'); | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  | const channels = new Map(); | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  | const mixins = new Map(); | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | function raise(item) { | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   throw new Error('Invalid item: ' + JSON.stringify(item, null, 2)); | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function titleCase(name) { | 
					
						
							|  |  |  |   return name[0].toUpperCase() + name.substring(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | function inlineType(type, indent, wrapEnums = false) { | 
					
						
							|  |  |  |   if (typeof type === 'string') { | 
					
						
							|  |  |  |     const optional = type.endsWith('?'); | 
					
						
							|  |  |  |     if (optional) | 
					
						
							|  |  |  |       type = type.substring(0, type.length - 1); | 
					
						
							|  |  |  |     if (type === 'binary') | 
					
						
							|  |  |  |       return { ts: 'Binary', scheme: 'tBinary', optional }; | 
					
						
							| 
									
										
										
										
											2020-08-10 11:20:32 -07:00
										 |  |  |     if (type === 'json') | 
					
						
							|  |  |  |       return { ts: 'any', scheme: 'tAny', optional }; | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     if (['string', 'boolean', 'number', 'undefined'].includes(type)) | 
					
						
							|  |  |  |       return { ts: type, scheme: `t${titleCase(type)}`, optional }; | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |     if (channels.has(type)) { | 
					
						
							|  |  |  |       let derived = derivedClasses.get(type) || []; | 
					
						
							|  |  |  |       derived = [...derived, type]; | 
					
						
							|  |  |  |       return { ts: `${type}Channel`, scheme: `tChannel([${derived.map(c => `'${c}'`).join(', ')}])` , optional }; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     if (type === 'Channel') | 
					
						
							|  |  |  |       return { ts: `Channel`, scheme: `tChannel('*')`, optional }; | 
					
						
							|  |  |  |     return { ts: type, scheme: `tType('${type}')`, optional }; | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   if (type.type.startsWith('array')) { | 
					
						
							|  |  |  |     const optional = type.type.endsWith('?'); | 
					
						
							|  |  |  |     const inner = inlineType(type.items, indent, true); | 
					
						
							|  |  |  |     return { ts: `${inner.ts}[]`, scheme: `tArray(${inner.scheme})`, optional }; | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   if (type.type.startsWith('enum')) { | 
					
						
							|  |  |  |     const optional = type.type.endsWith('?'); | 
					
						
							|  |  |  |     const ts = type.literals.map(literal => `'${literal}'`).join(' | '); | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ts: wrapEnums ? `(${ts})` : ts, | 
					
						
							|  |  |  |       scheme: `tEnum([${type.literals.map(literal => `'${literal}'`).join(', ')}])`, | 
					
						
							|  |  |  |       optional | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   if (type.type.startsWith('object')) { | 
					
						
							|  |  |  |     const optional = type.type.endsWith('?'); | 
					
						
							|  |  |  |     const inner = properties(type.properties, indent + '  '); | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ts: `{\n${inner.ts}\n${indent}}`, | 
					
						
							|  |  |  |       scheme: `tObject({\n${inner.scheme}\n${indent}})`, | 
					
						
							|  |  |  |       optional | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   raise(type); | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  | function properties(properties, indent, onlyOptional) { | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   const ts = []; | 
					
						
							|  |  |  |   const scheme = []; | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  |   const visitProperties = props => { | 
					
						
							|  |  |  |     for (const [name, value] of Object.entries(props)) { | 
					
						
							|  |  |  |       if (name.startsWith('$mixin')) { | 
					
						
							|  |  |  |         visitProperties(mixins.get(value).properties); | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const inner = inlineType(value, indent); | 
					
						
							|  |  |  |       if (onlyOptional && !inner.optional) | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       ts.push(`${indent}${name}${inner.optional ? '?' : ''}: ${inner.ts},`); | 
					
						
							|  |  |  |       const wrapped = inner.optional ? `tOptional(${inner.scheme})` : inner.scheme; | 
					
						
							|  |  |  |       scheme.push(`${indent}${name}: ${wrapped},`); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   visitProperties(properties); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   return { ts: ts.join('\n'), scheme: scheme.join('\n') }; | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 17:26:59 -07:00
										 |  |  | function objectType(props, indent, onlyOptional = false) { | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   if (!Object.entries(props).length) | 
					
						
							|  |  |  |     return { ts: `{}`, scheme: `tObject({})` }; | 
					
						
							| 
									
										
										
										
											2020-07-29 17:26:59 -07:00
										 |  |  |   const inner = properties(props, indent + '  ', onlyOptional); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   return { ts: `{\n${inner.ts}\n${indent}}`, scheme: `tObject({\n${inner.scheme}\n${indent}})` }; | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const channels_ts = [ | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | `/**
 | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-06 12:41:17 -08:00
										 |  |  | // This file is generated by ${path.basename(__filename).split(path.sep).join(path.posix.sep)}, do not edit manually.
 | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-23 14:37:53 -08:00
										 |  |  | import type { CallMetadata } from './callMetadata'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 08:58:34 -07:00
										 |  |  | export type Binary = Buffer; | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:26:01 -08:00
										 |  |  | export interface Channel { | 
					
						
							| 
									
										
										
										
											2020-07-20 17:38:06 -07:00
										 |  |  | } | 
					
						
							|  |  |  | `];
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-24 15:16:33 -07:00
										 |  |  | const validator_ts = [ | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  | `/**
 | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This file is generated by ${path.basename(__filename)}, do not edit manually.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  | import { scheme, tOptional, tObject, tBoolean, tNumber, tString, tAny, tEnum, tArray, tBinary, tChannel, tType } from './validatorPrimitives'; | 
					
						
							|  |  |  | export type { Validator, ValidatorContext } from './validatorPrimitives'; | 
					
						
							|  |  |  | export { ValidationError, findValidator, maybeFindValidator, createMetadataValidator } from './validatorPrimitives'; | 
					
						
							| 
									
										
										
										
											2020-07-22 18:05:07 -07:00
										 |  |  | `];
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  | const debug_ts = [ | 
					
						
							|  |  |  | `/**
 | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This file is generated by ${path.basename(__filename).split(path.sep).join(path.posix.sep)}, do not edit manually.
 | 
					
						
							|  |  |  | `];
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 19:19:30 -04:00
										 |  |  | const slowMoActions = []; | 
					
						
							| 
									
										
										
										
											2021-06-29 15:28:15 -07:00
										 |  |  | const tracingSnapshots = []; | 
					
						
							| 
									
										
										
										
											2021-09-17 15:24:15 -07:00
										 |  |  | const pausesBeforeInputActions = []; | 
					
						
							| 
									
										
										
										
											2021-06-29 15:28:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  | const yml = fs.readFileSync(path.join(__dirname, '..', 'packages', 'protocol', 'src', 'protocol.yml'), 'utf-8'); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | const protocol = yaml.parse(yml); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function addScheme(name, s) { | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |   validator_ts.push(`scheme.${name} = ${s};`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | for (const [name, value] of Object.entries(protocol)) { | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |   if (value.type === 'interface') | 
					
						
							|  |  |  |     channels.set(name, value); | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  |   if (value.type === 'mixin') | 
					
						
							|  |  |  |     mixins.set(name, value); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 17:56:48 -07:00
										 |  |  | const derivedClasses = new Map(); | 
					
						
							|  |  |  | for (const [name, item] of Object.entries(protocol)) { | 
					
						
							|  |  |  |   if (item.type === 'interface' && item.extends) { | 
					
						
							|  |  |  |     let items = derivedClasses.get(item.extends); | 
					
						
							|  |  |  |     if (!items) { | 
					
						
							|  |  |  |       items = []; | 
					
						
							|  |  |  |       derivedClasses.set(item.extends, items); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     items.push(name); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:26:01 -08:00
										 |  |  | channels_ts.push(`// ----------- Initializer Traits -----------`); | 
					
						
							|  |  |  | channels_ts.push(`export type InitializerTraits<T> =`); | 
					
						
							|  |  |  | const entriesInReverse = Object.entries(protocol).reverse(); | 
					
						
							|  |  |  | for (const [name, item] of entriesInReverse) { | 
					
						
							|  |  |  |   if (item.type !== 'interface') | 
					
						
							|  |  |  |     continue; | 
					
						
							|  |  |  |   channels_ts.push(`    T extends ${name}Channel ? ${name}Initializer :`); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | channels_ts.push(`    object;`); | 
					
						
							|  |  |  | channels_ts.push(``); | 
					
						
							|  |  |  | channels_ts.push(`// ----------- Event Traits -----------`); | 
					
						
							|  |  |  | channels_ts.push(`export type EventsTraits<T> =`); | 
					
						
							|  |  |  | for (const [name, item] of entriesInReverse) { | 
					
						
							|  |  |  |   if (item.type !== 'interface') | 
					
						
							|  |  |  |     continue; | 
					
						
							|  |  |  |   channels_ts.push(`    T extends ${name}Channel ? ${name}Events :`); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | channels_ts.push(`    undefined;`); | 
					
						
							|  |  |  | channels_ts.push(``); | 
					
						
							|  |  |  | channels_ts.push(`// ----------- EventTarget Traits -----------`); | 
					
						
							|  |  |  | channels_ts.push(`export type EventTargetTraits<T> =`); | 
					
						
							|  |  |  | for (const [name, item] of entriesInReverse) { | 
					
						
							|  |  |  |   if (item.type !== 'interface') | 
					
						
							|  |  |  |     continue; | 
					
						
							|  |  |  |   channels_ts.push(`    T extends ${name}Channel ? ${name}EventTarget :`); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | channels_ts.push(`    undefined;`); | 
					
						
							|  |  |  | channels_ts.push(``); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | for (const [name, item] of Object.entries(protocol)) { | 
					
						
							|  |  |  |   if (item.type === 'interface') { | 
					
						
							|  |  |  |     const channelName = name; | 
					
						
							|  |  |  |     channels_ts.push(`// ----------- ${channelName} -----------`); | 
					
						
							|  |  |  |     const init = objectType(item.initializer || {}, ''); | 
					
						
							|  |  |  |     const initializerName = channelName + 'Initializer'; | 
					
						
							|  |  |  |     channels_ts.push(`export type ${initializerName} = ${init.ts};`); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |     let ancestorInit = init; | 
					
						
							|  |  |  |     let ancestor = item; | 
					
						
							|  |  |  |     while (!ancestor.initializer) { | 
					
						
							|  |  |  |       if (!ancestor.extends) | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       ancestor = channels.get(ancestor.extends); | 
					
						
							|  |  |  |       ancestorInit = objectType(ancestor.initializer || {}, ''); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     addScheme(`${channelName}Initializer`, ancestor.initializer ? ancestorInit.scheme : `tOptional(tObject({}))`); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:26:01 -08:00
										 |  |  |     channels_ts.push(`export interface ${channelName}EventTarget {`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     const ts_types = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-30 18:43:18 +02:00
										 |  |  |     /** @type{{eventName: string, eventType: string}[]} */ | 
					
						
							|  |  |  |     const eventTypes = []; | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     for (let [eventName, event] of Object.entries(item.events || {})) { | 
					
						
							|  |  |  |       if (event === null) | 
					
						
							|  |  |  |         event = {}; | 
					
						
							|  |  |  |       const parameters = objectType(event.parameters || {}, ''); | 
					
						
							|  |  |  |       const paramsName = `${channelName}${titleCase(eventName)}Event`; | 
					
						
							|  |  |  |       ts_types.set(paramsName, parameters.ts); | 
					
						
							|  |  |  |       channels_ts.push(`  on(event: '${eventName}', callback: (params: ${paramsName}) => void): this;`); | 
					
						
							| 
									
										
										
										
											2021-08-30 18:43:18 +02:00
										 |  |  |       eventTypes.push({eventName, eventType: paramsName}); | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |       addScheme(paramsName, event.parameters ? parameters.scheme : `tOptional(tObject({}))`); | 
					
						
							|  |  |  |       for (const derived of derivedClasses.get(channelName) || []) | 
					
						
							|  |  |  |         addScheme(`${derived}${titleCase(eventName)}Event`, `tType('${paramsName}')`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-11-17 15:26:01 -08:00
										 |  |  |     channels_ts.push(`}`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 15:26:01 -08:00
										 |  |  |     channels_ts.push(`export interface ${channelName}Channel extends ${channelName}EventTarget, ${(item.extends || '') + 'Channel'} {`); | 
					
						
							|  |  |  |     channels_ts.push(`  _type_${channelName}: boolean;`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     for (let [methodName, method] of Object.entries(item.commands || {})) { | 
					
						
							|  |  |  |       if (method === null) | 
					
						
							|  |  |  |         method = {}; | 
					
						
							| 
									
										
										
										
											2023-04-17 19:19:30 -04:00
										 |  |  |       if (method.flags?.slowMo) { | 
					
						
							|  |  |  |         slowMoActions.push(name + '.' + methodName); | 
					
						
							|  |  |  |         for (const derived of derivedClasses.get(name) || []) | 
					
						
							|  |  |  |           slowMoActions.push(derived + '.' + methodName); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (method.flags?.snapshot) { | 
					
						
							| 
									
										
										
										
											2021-06-29 15:28:15 -07:00
										 |  |  |         tracingSnapshots.push(name + '.' + methodName); | 
					
						
							| 
									
										
										
										
											2021-06-30 17:56:48 -07:00
										 |  |  |         for (const derived of derivedClasses.get(name) || []) | 
					
						
							|  |  |  |           tracingSnapshots.push(derived + '.' + methodName); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-04-17 19:19:30 -04:00
										 |  |  |       if (method.flags?.pausesBeforeInput) { | 
					
						
							| 
									
										
										
										
											2021-09-17 15:24:15 -07:00
										 |  |  |         pausesBeforeInputActions.push(name + '.' + methodName); | 
					
						
							|  |  |  |         for (const derived of derivedClasses.get(name) || []) | 
					
						
							|  |  |  |           pausesBeforeInputActions.push(derived + '.' + methodName); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |       const parameters = objectType(method.parameters || {}, ''); | 
					
						
							|  |  |  |       const paramsName = `${channelName}${titleCase(methodName)}Params`; | 
					
						
							| 
									
										
										
										
											2020-07-29 17:26:59 -07:00
										 |  |  |       const optionsName = `${channelName}${titleCase(methodName)}Options`; | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |       ts_types.set(paramsName, parameters.ts); | 
					
						
							| 
									
										
										
										
											2020-07-29 17:26:59 -07:00
										 |  |  |       ts_types.set(optionsName, objectType(method.parameters || {}, '', true).ts); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |       addScheme(paramsName, method.parameters ? parameters.scheme : `tOptional(tObject({}))`); | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |       for (const derived of derivedClasses.get(channelName) || []) | 
					
						
							|  |  |  |         addScheme(`${derived}${titleCase(methodName)}Params`, `tType('${paramsName}')`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const resultName = `${channelName}${titleCase(methodName)}Result`; | 
					
						
							|  |  |  |       const returns = objectType(method.returns || {}, ''); | 
					
						
							|  |  |  |       ts_types.set(resultName, method.returns ? returns.ts : 'void'); | 
					
						
							| 
									
										
										
										
											2022-07-01 09:58:07 -07:00
										 |  |  |       addScheme(resultName, method.returns ? returns.scheme : `tOptional(tObject({}))`); | 
					
						
							|  |  |  |       for (const derived of derivedClasses.get(channelName) || []) | 
					
						
							|  |  |  |         addScheme(`${derived}${titleCase(methodName)}Result`, `tType('${resultName}')`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-23 14:37:53 -08:00
										 |  |  |       channels_ts.push(`  ${methodName}(params${method.parameters ? '' : '?'}: ${paramsName}, metadata?: CallMetadata): Promise<${resultName}>;`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     channels_ts.push(`}`); | 
					
						
							|  |  |  |     for (const [typeName, typeValue] of ts_types) | 
					
						
							|  |  |  |       channels_ts.push(`export type ${typeName} = ${typeValue};`); | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  |     channels_ts.push(``); | 
					
						
							| 
									
										
										
										
											2021-08-30 18:43:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     channels_ts.push(`export interface ${channelName}Events {`); | 
					
						
							|  |  |  |     for (const {eventName, eventType} of eventTypes) | 
					
						
							|  |  |  |         channels_ts.push(`  '${eventName}': ${eventType};`); | 
					
						
							|  |  |  |     channels_ts.push(`}\n`); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   } else if (item.type === 'object') { | 
					
						
							|  |  |  |     const inner = objectType(item.properties, ''); | 
					
						
							|  |  |  |     channels_ts.push(`export type ${name} = ${inner.ts};`); | 
					
						
							| 
									
										
										
										
											2021-03-24 06:37:10 -07:00
										 |  |  |     channels_ts.push(``); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |     addScheme(name, inner.scheme); | 
					
						
							| 
									
										
										
										
											2021-11-01 17:12:19 -07:00
										 |  |  |   } else if (item.type === 'enum') { | 
					
						
							|  |  |  |     const ts = item.literals.map(literal => `'${literal}'`).join(' | '); | 
					
						
							|  |  |  |     channels_ts.push(`export type ${name} = ${ts};`) | 
					
						
							|  |  |  |     addScheme(name, `tEnum([${item.literals.map(literal => `'${literal}'`).join(', ')}])`); | 
					
						
							| 
									
										
										
										
											2020-07-22 19:38:19 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-17 19:19:30 -04:00
										 |  |  | debug_ts.push(`export const slowMoActions = new Set([
 | 
					
						
							|  |  |  |   '${slowMoActions.join(`',\n  '`)}' | 
					
						
							|  |  |  | ]);`);
 | 
					
						
							|  |  |  | debug_ts.push(''); | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  | debug_ts.push(`export const commandsWithTracingSnapshots = new Set([
 | 
					
						
							| 
									
										
										
										
											2021-06-29 15:28:15 -07:00
										 |  |  |   '${tracingSnapshots.join(`',\n  '`)}' | 
					
						
							|  |  |  | ]);`);
 | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  | debug_ts.push(''); | 
					
						
							|  |  |  | debug_ts.push(`export const pausesBeforeInputActions = new Set([
 | 
					
						
							| 
									
										
										
										
											2021-09-17 15:24:15 -07:00
										 |  |  |   '${pausesBeforeInputActions.join(`',\n  '`)}' | 
					
						
							|  |  |  | ]);`);
 | 
					
						
							| 
									
										
										
										
											2021-06-29 15:28:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-30 15:08:21 -07:00
										 |  |  | let hasChanges = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function writeFile(filePath, content) { | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  |   try { | 
					
						
							|  |  |  |     const existing = fs.readFileSync(filePath, 'utf8'); | 
					
						
							|  |  |  |     if (existing === content) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |   } catch (e) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-30 15:08:21 -07:00
										 |  |  |   hasChanges = true; | 
					
						
							|  |  |  |   const root = path.join(__dirname, '..'); | 
					
						
							|  |  |  |   console.log(`Writing //${path.relative(root, filePath)}`); | 
					
						
							|  |  |  |   fs.writeFileSync(filePath, content, 'utf8'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-20 18:41:51 -07:00
										 |  |  | writeFile(path.join(__dirname, '..', 'packages', 'protocol', 'src', 'channels.ts'), channels_ts.join('\n')); | 
					
						
							|  |  |  | writeFile(path.join(__dirname, '..', 'packages', 'playwright-core', 'src', 'protocol', 'debug.ts'), debug_ts.join('\n')); | 
					
						
							| 
									
										
										
										
											2021-10-11 10:52:17 -04:00
										 |  |  | writeFile(path.join(__dirname, '..', 'packages', 'playwright-core', 'src', 'protocol', 'validator.ts'), validator_ts.join('\n')); | 
					
						
							| 
									
										
										
										
											2020-07-30 15:08:21 -07:00
										 |  |  | process.exit(hasChanges ? 1 : 0); |