From 7a2a41f2087b07e8ef1feaf3881bdcc3fd4922ca Mon Sep 17 00:00:00 2001 From: Jack Franklin Date: Thu, 2 Apr 2020 15:25:19 +0100 Subject: [PATCH] chore: move code to src/ and emit with TypeScript (#5568) This updates our `tsconfig.json` so it emits our JavaScript files as well as type checking them. We compile into `./lib` which we then ship in our npm package. The source code has moved from `./lib` into `./src`. Because the `src/` directory is exclusively JS files, this change is a no-op in terms of code functionality but is the first step towards being able to replace `src/X.js` with `src/X.ts` in a way that allows us to migrate incrementally. The `lib` directory is gitignored, and the `src` directory is npmignored. On `npm publish` we will now run `npm run tsc` in order to generate the outputted code. --- .eslintignore | 1 + .gitignore | 2 +- .npmignore | 3 + install.js | 56 +- package.json | 9 +- {lib => src}/.eslintrc.js | 0 {lib => src}/Accessibility.js | 0 {lib => src}/Browser.js | 0 {lib => src}/BrowserFetcher.js | 0 {lib => src}/Connection.js | 0 {lib => src}/Coverage.js | 0 {lib => src}/DOMWorld.js | 0 {lib => src}/DeviceDescriptors.js | 0 {lib => src}/Dialog.js | 0 {lib => src}/EmulationManager.js | 0 {lib => src}/Errors.js | 0 {lib => src}/Events.js | 0 {lib => src}/ExecutionContext.js | 0 {lib => src}/FrameManager.js | 0 {lib => src}/Input.js | 0 {lib => src}/JSHandle.js | 0 {lib => src}/Launcher.js | 0 {lib => src}/LifecycleWatcher.js | 0 {lib => src}/Multimap.js | 0 {lib => src}/NetworkManager.js | 0 {lib => src}/Page.js | 1 - {lib => src}/PipeTransport.js | 0 {lib => src}/Puppeteer.js | 0 {lib => src}/Target.js | 0 {lib => src}/TaskQueue.js | 0 {lib => src}/TimeoutSettings.js | 0 {lib => src}/Tracing.js | 0 {lib => src}/USKeyboardLayout.js | 0 {lib => src}/WebSocketTransport.js | 0 {lib => src}/Worker.js | 0 {lib => src}/api.js | 0 {lib => src}/externs.d.ts | 0 {lib => src}/helper.js | 0 src/protocol.d.ts | 15157 ++++++++++++++++++++++ tsconfig.json | 4 +- utils/protocol-types-generator/index.js | 4 +- 41 files changed, 15214 insertions(+), 23 deletions(-) rename {lib => src}/.eslintrc.js (100%) rename {lib => src}/Accessibility.js (100%) rename {lib => src}/Browser.js (100%) rename {lib => src}/BrowserFetcher.js (100%) rename {lib => src}/Connection.js (100%) rename {lib => src}/Coverage.js (100%) rename {lib => src}/DOMWorld.js (100%) rename {lib => src}/DeviceDescriptors.js (100%) rename {lib => src}/Dialog.js (100%) rename {lib => src}/EmulationManager.js (100%) rename {lib => src}/Errors.js (100%) rename {lib => src}/Events.js (100%) rename {lib => src}/ExecutionContext.js (100%) rename {lib => src}/FrameManager.js (100%) rename {lib => src}/Input.js (100%) rename {lib => src}/JSHandle.js (100%) rename {lib => src}/Launcher.js (100%) rename {lib => src}/LifecycleWatcher.js (100%) rename {lib => src}/Multimap.js (100%) rename {lib => src}/NetworkManager.js (100%) rename {lib => src}/Page.js (99%) rename {lib => src}/PipeTransport.js (100%) rename {lib => src}/Puppeteer.js (100%) rename {lib => src}/Target.js (100%) rename {lib => src}/TaskQueue.js (100%) rename {lib => src}/TimeoutSettings.js (100%) rename {lib => src}/Tracing.js (100%) rename {lib => src}/USKeyboardLayout.js (100%) rename {lib => src}/WebSocketTransport.js (100%) rename {lib => src}/Worker.js (100%) rename {lib => src}/api.js (100%) rename {lib => src}/externs.d.ts (100%) rename {lib => src}/helper.js (100%) create mode 100644 src/protocol.d.ts diff --git a/.eslintignore b/.eslintignore index e00d69d9cdbde..4b5508b266ee9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,3 +7,4 @@ node6/* node6-test/* node6-testrunner/* experimental/ +lib/ diff --git a/.gitignore b/.gitignore index ebdd78888fcd5..929700b27190f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,6 @@ package-lock.json yarn.lock /node6 -/lib/protocol.d.ts /utils/browser/puppeteer-web.js /index.d.ts +/lib diff --git a/.npmignore b/.npmignore index b24ba6246e4c6..d6dacff1440a1 100644 --- a/.npmignore +++ b/.npmignore @@ -43,3 +43,6 @@ experimental # exclude types, see https://github.com/puppeteer/puppeteer/issues/3878 /index.d.ts + +# don't expose src/ as we ship the generated code in lib/ +/src diff --git a/install.js b/install.js index 21bf712e6ec44..114bc7dc1144b 100644 --- a/install.js +++ b/install.js @@ -14,6 +14,45 @@ * limitations under the License. */ +const fs = require('fs'); +const path = require('path'); +const child_process = require('child_process'); +const {promisify} = require('util'); + +const fsAccess = promisify(fs.access); +const exec = promisify(child_process.exec); + +const fileExists = async filePath => fsAccess(filePath).then(() => true).catch(() => false); + +/* + * Now Puppeteer is built with TypeScript, we need to ensure that + * locally we have the generated output before trying to install. + * + * For users installing puppeteer this is fine, they will have the + * generated lib/ directory as we ship it when we publish to npm. + * + * However, if you're cloning the repo to contribute, you won't have the + * generated lib/ directory so this script checks if we need to run + * TypeScript first to ensure the output exists and is in the right + * place. + */ +async function compileTypeScript() { + return exec('npm run tsc').catch(err => { + console.error('Error running TypeScript', err); + process.exit(1); + }); +} + +async function ensureLibDirectoryExists() { + const libPath = path.join(__dirname, 'lib'); + const libExists = await fileExists(libPath); + if (libExists) return; + + logPolitely('Compiling TypeScript before install...'); + await compileTypeScript(); +} + + /** * This file is part of public API. * @@ -29,6 +68,8 @@ const supportedProducts = { }; async function download() { + await ensureLibDirectoryExists(); + const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host || process.env.npm_package_config_puppeteer_download_host; const puppeteer = require('./index'); const product = process.env.PUPPETEER_PRODUCT || process.env.npm_config_puppeteer_product || process.env.npm_package_config_puppeteer_product || 'chrome'; @@ -53,7 +94,6 @@ async function download() { // Do nothing if the revision is already downloaded. if (revisionInfo.local) { - generateProtocolTypesIfNecessary(false /* updated */, product); logPolitely(`${supportedProducts[product]} is already in ${revisionInfo.folderPath}; skipping download.`); return; } @@ -78,7 +118,7 @@ async function download() { logPolitely(`${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}`); localRevisions = localRevisions.filter(revision => revision !== revisionInfo.revision); const cleanupOldVersions = localRevisions.map(revision => browserFetcher.remove(revision)); - Promise.all([...cleanupOldVersions, generateProtocolTypesIfNecessary(true /* updated */, product)]); + Promise.all([...cleanupOldVersions]); } /** @@ -118,18 +158,6 @@ async function download() { return `${Math.round(mb * 10) / 10} Mb`; } - function generateProtocolTypesIfNecessary(updated, product) { - if (product !== 'chrome') - return; - const fs = require('fs'); - const path = require('path'); - if (!fs.existsSync(path.join(__dirname, 'utils', 'protocol-types-generator'))) - return; - if (!updated && fs.existsSync(path.join(__dirname, 'lib', 'protocol.d.ts'))) - return; - return require('./utils/protocol-types-generator'); - } - function getFirefoxNightlyVersion(host) { const https = require('https'); const promise = new Promise((resolve, reject) => { diff --git a/package.json b/package.json index 4c1be89cde0d6..8c9bebdce7e96 100644 --- a/package.json +++ b/package.json @@ -16,16 +16,19 @@ "funit": "PUPPETEER_PRODUCT=firefox node test/test.js", "debug-unit": "node --inspect-brk test/test.js", "test-doclint": "node utils/doclint/check_public_api/test/test.js && node utils/doclint/preprocessor/test.js", - "test": "npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-types && node utils/testrunner/test/test.js", + "test": "npm run tsc && npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-types && node utils/testrunner/test/test.js", + "prepublishOnly": "npm run tsc", + "dev-install": "npm run tsc && node install.js", "install": "node install.js", "lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run tsc && npm run doc", "doc": "node utils/doclint/cli.js", "coverage": "cross-env COVERAGE=true npm run unit", - "tsc": "tsc --version && tsc -p .", + "tsc": "tsc --version && tsc -p . && cp src/protocol.d.ts lib/ && cp src/externs.d.ts lib/", "apply-next-version": "node utils/apply_next_version.js", "bundle": "npx browserify -r ./index.js:puppeteer -o utils/browser/puppeteer-web.js", "test-types": "node utils/doclint/generate_types && tsc --version && tsc -p utils/doclint/generate_types/test/", - "unit-bundle": "node utils/browser/test.js" + "unit-bundle": "node utils/browser/test.js", + "update-protocol-d-ts": "node utils/protocol-types-generator" }, "author": "The Chromium Authors", "license": "Apache-2.0", diff --git a/lib/.eslintrc.js b/src/.eslintrc.js similarity index 100% rename from lib/.eslintrc.js rename to src/.eslintrc.js diff --git a/lib/Accessibility.js b/src/Accessibility.js similarity index 100% rename from lib/Accessibility.js rename to src/Accessibility.js diff --git a/lib/Browser.js b/src/Browser.js similarity index 100% rename from lib/Browser.js rename to src/Browser.js diff --git a/lib/BrowserFetcher.js b/src/BrowserFetcher.js similarity index 100% rename from lib/BrowserFetcher.js rename to src/BrowserFetcher.js diff --git a/lib/Connection.js b/src/Connection.js similarity index 100% rename from lib/Connection.js rename to src/Connection.js diff --git a/lib/Coverage.js b/src/Coverage.js similarity index 100% rename from lib/Coverage.js rename to src/Coverage.js diff --git a/lib/DOMWorld.js b/src/DOMWorld.js similarity index 100% rename from lib/DOMWorld.js rename to src/DOMWorld.js diff --git a/lib/DeviceDescriptors.js b/src/DeviceDescriptors.js similarity index 100% rename from lib/DeviceDescriptors.js rename to src/DeviceDescriptors.js diff --git a/lib/Dialog.js b/src/Dialog.js similarity index 100% rename from lib/Dialog.js rename to src/Dialog.js diff --git a/lib/EmulationManager.js b/src/EmulationManager.js similarity index 100% rename from lib/EmulationManager.js rename to src/EmulationManager.js diff --git a/lib/Errors.js b/src/Errors.js similarity index 100% rename from lib/Errors.js rename to src/Errors.js diff --git a/lib/Events.js b/src/Events.js similarity index 100% rename from lib/Events.js rename to src/Events.js diff --git a/lib/ExecutionContext.js b/src/ExecutionContext.js similarity index 100% rename from lib/ExecutionContext.js rename to src/ExecutionContext.js diff --git a/lib/FrameManager.js b/src/FrameManager.js similarity index 100% rename from lib/FrameManager.js rename to src/FrameManager.js diff --git a/lib/Input.js b/src/Input.js similarity index 100% rename from lib/Input.js rename to src/Input.js diff --git a/lib/JSHandle.js b/src/JSHandle.js similarity index 100% rename from lib/JSHandle.js rename to src/JSHandle.js diff --git a/lib/Launcher.js b/src/Launcher.js similarity index 100% rename from lib/Launcher.js rename to src/Launcher.js diff --git a/lib/LifecycleWatcher.js b/src/LifecycleWatcher.js similarity index 100% rename from lib/LifecycleWatcher.js rename to src/LifecycleWatcher.js diff --git a/lib/Multimap.js b/src/Multimap.js similarity index 100% rename from lib/Multimap.js rename to src/Multimap.js diff --git a/lib/NetworkManager.js b/src/NetworkManager.js similarity index 100% rename from lib/NetworkManager.js rename to src/NetworkManager.js diff --git a/lib/Page.js b/src/Page.js similarity index 99% rename from lib/Page.js rename to src/Page.js index 5d94eecf4ad06..9be58789a2ba9 100644 --- a/lib/Page.js +++ b/src/Page.js @@ -30,7 +30,6 @@ const {Worker: PuppeteerWorker} = require('./Worker'); const {createJSHandle} = require('./JSHandle'); const {Accessibility} = require('./Accessibility'); const {TimeoutSettings} = require('./TimeoutSettings'); - const writeFileAsync = helper.promisify(fs.writeFile); class Page extends EventEmitter { diff --git a/lib/PipeTransport.js b/src/PipeTransport.js similarity index 100% rename from lib/PipeTransport.js rename to src/PipeTransport.js diff --git a/lib/Puppeteer.js b/src/Puppeteer.js similarity index 100% rename from lib/Puppeteer.js rename to src/Puppeteer.js diff --git a/lib/Target.js b/src/Target.js similarity index 100% rename from lib/Target.js rename to src/Target.js diff --git a/lib/TaskQueue.js b/src/TaskQueue.js similarity index 100% rename from lib/TaskQueue.js rename to src/TaskQueue.js diff --git a/lib/TimeoutSettings.js b/src/TimeoutSettings.js similarity index 100% rename from lib/TimeoutSettings.js rename to src/TimeoutSettings.js diff --git a/lib/Tracing.js b/src/Tracing.js similarity index 100% rename from lib/Tracing.js rename to src/Tracing.js diff --git a/lib/USKeyboardLayout.js b/src/USKeyboardLayout.js similarity index 100% rename from lib/USKeyboardLayout.js rename to src/USKeyboardLayout.js diff --git a/lib/WebSocketTransport.js b/src/WebSocketTransport.js similarity index 100% rename from lib/WebSocketTransport.js rename to src/WebSocketTransport.js diff --git a/lib/Worker.js b/src/Worker.js similarity index 100% rename from lib/Worker.js rename to src/Worker.js diff --git a/lib/api.js b/src/api.js similarity index 100% rename from lib/api.js rename to src/api.js diff --git a/lib/externs.d.ts b/src/externs.d.ts similarity index 100% rename from lib/externs.d.ts rename to src/externs.d.ts diff --git a/lib/helper.js b/src/helper.js similarity index 100% rename from lib/helper.js rename to src/helper.js diff --git a/src/protocol.d.ts b/src/protocol.d.ts new file mode 100644 index 0000000000000..a2e75409fa163 --- /dev/null +++ b/src/protocol.d.ts @@ -0,0 +1,15157 @@ +// This is generated from /utils/protocol-types-generator/index.js + type binary = string; +declare global { + module Protocol { + export module Accessibility { + /** + * Unique accessibility node identifier. + */ + export type AXNodeId = string; + /** + * Enum of possible property types. + */ + export type AXValueType = "boolean"|"tristate"|"booleanOrUndefined"|"idref"|"idrefList"|"integer"|"node"|"nodeList"|"number"|"string"|"computedString"|"token"|"tokenList"|"domRelation"|"role"|"internalRole"|"valueUndefined"; + /** + * Enum of possible property sources. + */ + export type AXValueSourceType = "attribute"|"implicit"|"style"|"contents"|"placeholder"|"relatedElement"; + /** + * Enum of possible native property sources (as a subtype of a particular AXValueSourceType). + */ + export type AXValueNativeSourceType = "figcaption"|"label"|"labelfor"|"labelwrapped"|"legend"|"tablecaption"|"title"|"other"; + /** + * A single source for a computed AX property. + */ + export interface AXValueSource { + /** + * What type of source this is. + */ + type: AXValueSourceType; + /** + * The value of this property source. + */ + value?: AXValue; + /** + * The name of the relevant attribute, if any. + */ + attribute?: string; + /** + * The value of the relevant attribute, if any. + */ + attributeValue?: AXValue; + /** + * Whether this source is superseded by a higher priority source. + */ + superseded?: boolean; + /** + * The native markup source for this value, e.g. a