-
Notifications
You must be signed in to change notification settings - Fork 9k
/
index.js
104 lines (101 loc) · 4.17 KB
/
index.js
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
// @ts-check
const path = require('path');
const puppeteer = require('../..');
module.exports = puppeteer.launch({
pipe: false,
executablePath: process.env.BINARY,
}).then(async browser => {
const origin = browser.wsEndpoint().match(/ws:\/\/([0-9A-Za-z:\.]*)\//)[1];
const page = await browser.newPage();
await page.goto(`http://${origin}/json/protocol`);
const json = JSON.parse(await page.evaluate(() => document.documentElement.innerText));
const version = await browser.version();
await browser.close();
const output = `// This is generated from /utils/protocol-types-generator/index.js
type binary = string;
declare global {
module Protocol {${json.domains.map(domain => `${domain.description ? `
/**
* ${domain.description}
*/` : ''}
export module ${domain.domain} {${(domain.types || []).map(type => `${type.description ? `
/**
* ${type.description}
*/` : ''}${type.properties ? `
export interface ${type.id} {${(type.properties || []).map(property => `${property.description ? `
/**
* ${property.description}
*/` : ''}
${property.name}${property.optional ? '?' : ''}: ${typeOfProperty(property)};`).join(``)}
}` : `
export type ${type.id} = ${typeOfProperty(type)};`}`).join('')}
${(domain.events || []).map(event => `${event.description ? `
/**
* ${event.description}
*/` : ''}${event.parameters ? `
export type ${event.name}Payload = {${event.parameters.map(parameter => `${parameter.description ? `
/**
* ${parameter.description}
*/` : ''}
${parameter.name}${parameter.optional ? '?' : ''}: ${typeOfProperty(parameter)};`).join(``)}
}` : `
export type ${event.name}Payload = void;`}`).join('')}
${(domain.commands || []).map(command => `${command.description ? `
/**
* ${command.description}
*/` : ''}
export type ${command.name}Parameters = {${(command.parameters || []).map(parameter => `${parameter.description ? `
/**
* ${parameter.description}
*/` : ''}
${parameter.name}${parameter.optional ? '?' : ''}: ${typeOfProperty(parameter)};`).join(``)}
}
export type ${command.name}ReturnValue = {${(command.returns || []).map(retVal => `${retVal.description ? `
/**
* ${retVal.description}
*/` : ''}
${retVal.name}${retVal.optional ? '?' : ''}: ${typeOfProperty(retVal)};`).join(``)}
}`).join('')}
}
`).join('')}
export interface Events {${json.domains.map(domain => (domain.events || []).map(event => `
"${domain.domain}.${event.name}": ${domain.domain}.${event.name}Payload;`).join('')).join('')}
}
export interface CommandParameters {${json.domains.map(domain => (domain.commands || []).map(command => `
"${domain.domain}.${command.name}": ${domain.domain}.${command.name}Parameters;`).join('')).join('')}
}
export interface CommandReturnValues {${json.domains.map(domain => (domain.commands || []).map(command => `
"${domain.domain}.${command.name}": ${domain.domain}.${command.name}ReturnValue;`).join('')).join('')}
}
}
}
// empty export to keep file a module
export {}
`;
const outputPath = path.join(__dirname, '..', '..', 'lib', 'protocol.d.ts');
require('fs').writeFileSync(outputPath, output);
console.log(`Wrote protocol.d.ts for ${version} to ${path.relative(process.cwd(), outputPath)}`);
});
/**
* @typedef {Object} Property
* @property {string=} $ref
* @property {!Array=} enum
* @property {string=} type
* @property {!Property=} items
* @property {string=} description
*/
/**
* @param {!Property} property
* @param {string=} domain
*/
function typeOfProperty(property, domain) {
if (property.$ref) return property.$ref.includes('.') || !domain ? property.$ref : domain + '.' + property.$ref;
if (property.enum) return property.enum.map(value => JSON.stringify(value)).join('|');
switch (property.type) {
case 'array':
return typeOfProperty(property.items, domain) + '[]';
case 'integer':
return 'number';
}
return property.type;
}