-
-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
431 additions
and
545 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,73 @@ | ||
import path from "node:path"; | ||
import { glob } from "glob"; | ||
import { build } from "tsup"; | ||
import { ensureCacheDirExists } from "../ensureCacheDirExists"; | ||
import { FIXES_BANNER } from "./compilationFixes"; | ||
import buildWalletSetupFunction from "../utils/buildWalletSetupFunction"; | ||
import path from 'node:path' | ||
import fs from 'fs-extra' | ||
import { glob } from 'glob' | ||
import { build } from 'tsup' | ||
|
||
const OUT_DIR_NAME = "wallet-setup-dist"; | ||
import { ensureCacheDirExists } from '../ensureCacheDirExists' | ||
import buildWalletSetupFunction from '../utils/buildWalletSetupFunction' | ||
import { extractWalletSetupFunction } from '../utils/extractWalletSetupFunction' | ||
import { getWalletSetupFuncHash } from '../utils/getWalletSetupFuncHash' | ||
import { FIXES_BANNER } from './compilationFixes' | ||
|
||
const createGlobPattern = (walletSetupDir: string) => | ||
path.join(walletSetupDir, "**", "*.setup.{ts,js,mjs}"); | ||
const OUT_DIR_NAME = '.wallet-setup-dist' | ||
|
||
export async function compileWalletSetupFunctions( | ||
walletSetupDir: string, | ||
debug: boolean | ||
) { | ||
const outDir = path.join(ensureCacheDirExists(), OUT_DIR_NAME); | ||
const createGlobPattern = (walletSetupDir: string) => path.join(walletSetupDir, '**', '*.setup.{ts,js,mjs}') | ||
|
||
const globPattern = createGlobPattern(walletSetupDir); | ||
const fileList = await glob(globPattern); | ||
export async function compileWalletSetupFunctions(walletSetupDir: string, debug: boolean) { | ||
const outDir = path.join(ensureCacheDirExists(), OUT_DIR_NAME) | ||
|
||
fs.ensureDirSync(outDir) | ||
|
||
const globPattern = createGlobPattern(walletSetupDir) | ||
const fileList = await glob(globPattern) | ||
|
||
if (debug) { | ||
console.log("[DEBUG] Found the following wallet setup files:"); | ||
console.log(fileList, "\n"); | ||
console.log('[DEBUG] Found the following wallet setup files:') | ||
console.log(fileList, '\n') | ||
} | ||
|
||
// TODO: This error message is copied over from another function. Refactor this. | ||
if (!fileList.length) { | ||
throw new Error( | ||
[ | ||
`No wallet setup files found at ${walletSetupDir}`, | ||
"Remember that all wallet setup files must end with `.setup.{ts,js,mjs}` extension!", | ||
].join("\n") | ||
); | ||
'Remember that all wallet setup files must end with `.setup.{ts,js,mjs}` extension!' | ||
].join('\n') | ||
) | ||
} | ||
|
||
await build({ | ||
name: "cli-build", | ||
name: 'cli-build', | ||
silent: true, | ||
entry: fileList, | ||
clean: true, | ||
outDir, | ||
format: "esm", | ||
format: 'esm', | ||
splitting: true, | ||
sourcemap: false, | ||
config: false, | ||
// TODO: Make this list configurable. | ||
external: [ | ||
"@synthetixio/synpress", | ||
"@playwright/test", | ||
"playwright-core", | ||
"esbuild", | ||
"tsup", | ||
], | ||
external: ['@synthetixio/synpress', '@playwright/test', 'playwright-core', 'esbuild', 'tsup'], | ||
banner: { | ||
js: FIXES_BANNER, | ||
js: FIXES_BANNER | ||
}, | ||
esbuildOptions(options) { | ||
// TODO: In this step, if the debug file is present, we should modify `console.log` so it prints from which file the log is coming from. | ||
// We're dropping `console.log` and `debugger` statements because they do not play nicely with the Playwright Test Runner. | ||
options.drop = debug ? [] : ["console", "debugger"]; | ||
}, | ||
}); | ||
options.drop = debug ? [] : ['console', 'debugger'] | ||
} | ||
}) | ||
|
||
const functionStrings = await Promise.all( | ||
fileList.map(async (fileName) => { | ||
const walletSetupFunction = await import(fileName); | ||
const setupFunctionHashes = await Promise.all( | ||
fileList.map(async (filePath) => { | ||
const sourceCode = fs.readFileSync(filePath, 'utf8') | ||
const functionString = extractWalletSetupFunction(sourceCode) | ||
|
||
return buildWalletSetupFunction(walletSetupFunction.toString()); | ||
}) | ||
); | ||
const rawFunctionBuild = buildWalletSetupFunction(functionString) | ||
|
||
console.log({functionStrings}) | ||
return getWalletSetupFuncHash(rawFunctionBuild) | ||
}) | ||
) | ||
|
||
return { outDir, functionStrings: functionStrings }; | ||
return { outDir, setupFunctionHashes } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,23 @@ | ||
import { getUniqueWalletSetupFunctions } from "./utils/getUniqueWalletSetupFunctions"; | ||
import { triggerCacheCreation } from "./utils/triggerCacheCreation"; | ||
import { getUniqueWalletSetupFunctions } from './utils/getUniqueWalletSetupFunctions' | ||
import { triggerCacheCreation } from './utils/triggerCacheCreation' | ||
|
||
export async function createCache( | ||
walletSetupDirPath: string, | ||
functionStrings: string[], | ||
hashes: string[], | ||
downloadExtension: () => Promise<string>, | ||
force = false | ||
) { | ||
const setupFunctions = await getUniqueWalletSetupFunctions( | ||
walletSetupDirPath | ||
); | ||
const setupFunctions = await getUniqueWalletSetupFunctions(walletSetupDirPath) | ||
|
||
const cacheCreationPromises = await triggerCacheCreation( | ||
setupFunctions, | ||
functionStrings, | ||
downloadExtension, | ||
force | ||
); | ||
const cacheCreationPromises = await triggerCacheCreation(setupFunctions, hashes, downloadExtension, force) | ||
|
||
if (cacheCreationPromises.length === 0) { | ||
console.log("No new setup functions to cache. Exiting..."); | ||
return; | ||
console.log('No new setup functions to cache. Exiting...') | ||
return | ||
} | ||
|
||
// TODO: This line has no unit test. Not sure how to do it. Look into it later. | ||
await Promise.all(cacheCreationPromises); | ||
await Promise.all(cacheCreationPromises) | ||
|
||
console.log("All wallet setup functions are now cached!"); | ||
console.log('All wallet setup functions are now cached!') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,15 @@ | ||
import { transformSync } from "esbuild"; | ||
import { FIXES_BANNER } from "../cli/compilationFixes"; | ||
import { transformSync } from 'esbuild' | ||
|
||
export default function buildWalletSetupFunction( | ||
walletSetupFunctionString: string | ||
) { | ||
export default function buildWalletSetupFunction(walletSetupFunctionString: string) { | ||
const { code } = transformSync(walletSetupFunctionString, { | ||
format: "esm", | ||
format: 'esm', | ||
minifyWhitespace: true, | ||
target: "es2022", | ||
drop: ["console", "debugger"], | ||
loader: "ts", | ||
logLevel: "silent", | ||
platform: "node", | ||
banner: FIXES_BANNER, | ||
}); | ||
target: 'es2022', | ||
drop: ['console', 'debugger'], | ||
loader: 'ts', | ||
logLevel: 'silent', | ||
platform: 'node' | ||
}) | ||
|
||
return code; | ||
return code | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export function extractWalletSetupFunction(sourceCode: string): string { | ||
const match = sourceCode.match(/defineWalletSetup\s*\([^,]*,\s*(async\s*\([^)]*\)\s*=>\s*{[\s\S]*?})\s*\)/) | ||
|
||
if (!match || !match[1]) { | ||
console.log('Failed to extract defineWalletSetup callback from:', sourceCode) | ||
throw new Error('Could not find defineWalletSetup callback') | ||
} | ||
|
||
// Return just the callback function (second parameter) | ||
return match[1] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
import { createHash } from "node:crypto"; | ||
import { createHash } from 'node:crypto' | ||
|
||
// Same length as the file part (first part before the `-`) of a Playwright Test ID. | ||
export const WALLET_SETUP_FUNC_HASH_LENGTH = 10; | ||
export const WALLET_SETUP_FUNC_HASH_LENGTH = 10 | ||
|
||
export function getWalletSetupFuncHash(walletSetupString: string) { | ||
const hash = createHash("shake256", { | ||
outputLength: WALLET_SETUP_FUNC_HASH_LENGTH, | ||
}); | ||
const hash = createHash('shake256', { | ||
outputLength: WALLET_SETUP_FUNC_HASH_LENGTH | ||
}) | ||
|
||
return hash.update(walletSetupString).digest("hex"); | ||
return hash.update(walletSetupString).digest('hex') | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,48 @@ | ||
import path from "node:path"; | ||
import fs from "fs-extra"; | ||
import { ensureCacheDirExists } from "../ensureCacheDirExists"; | ||
import { createCacheForWalletSetupFunction } from "./createCacheForWalletSetupFunction"; | ||
import { isDirEmpty } from "./isDirEmpty"; | ||
import { getWalletSetupFuncHash } from "./getWalletSetupFuncHash"; | ||
import type { WalletSetupFunction } from "../defineWalletSetup"; | ||
import path from 'node:path' | ||
import fs from 'fs-extra' | ||
import type { WalletSetupFunction } from '../defineWalletSetup' | ||
import { ensureCacheDirExists } from '../ensureCacheDirExists' | ||
import { createCacheForWalletSetupFunction } from './createCacheForWalletSetupFunction' | ||
import { isDirEmpty } from './isDirEmpty' | ||
|
||
export async function triggerCacheCreation( | ||
setupFunctions: Map< | ||
string, | ||
{ fileName: string; setupFunction: WalletSetupFunction } | ||
>, | ||
functionStrings: string[], | ||
setupFunctions: Map<string, { fileName: string; setupFunction: WalletSetupFunction }>, | ||
hashes: string[], | ||
downloadExtension: () => Promise<string>, | ||
force: boolean | ||
) { | ||
const cacheDirPath = ensureCacheDirExists(); | ||
const extensionPath = await downloadExtension(); | ||
const cacheDirPath = ensureCacheDirExists() | ||
const extensionPath = await downloadExtension() | ||
|
||
return Array.from(setupFunctions).map( | ||
async ([_, { fileName, setupFunction }], index) => { | ||
// @ts-ignore | ||
const funcHash = getWalletSetupFuncHash(functionStrings[index]); | ||
return Array.from(setupFunctions).map(async ([_, { fileName, setupFunction }], index) => { | ||
if (!hashes[index]) { | ||
throw new Error(`No hash found for ${fileName}`) | ||
} | ||
|
||
const cachePath = path.join(cacheDirPath, funcHash); | ||
const doesCacheDirExist = await fs.exists(cachePath); | ||
const isCacheDirEmpty = await isDirEmpty(cachePath); | ||
const funcHash = hashes[index] | ||
|
||
if (doesCacheDirExist) { | ||
if (isCacheDirEmpty) { | ||
// In case of incorrect Playwright setup, the cache dir will be empty. For now, we're just deleting it. | ||
await fs.remove(cachePath); | ||
} else { | ||
if (!force) { | ||
console.log(`Cache already exists for ${funcHash}. Skipping...`); | ||
return; | ||
} | ||
const cachePath = path.join(cacheDirPath, funcHash || 'unknown') | ||
const doesCacheDirExist = await fs.exists(cachePath) | ||
const isCacheDirEmpty = await isDirEmpty(cachePath) | ||
|
||
console.log( | ||
`Cache already exists for ${funcHash} but force flag is set. Deleting cache...` | ||
); | ||
await fs.remove(cachePath); | ||
if (doesCacheDirExist) { | ||
if (isCacheDirEmpty) { | ||
// In case of incorrect Playwright setup, the cache dir will be empty. For now, we're just deleting it. | ||
await fs.remove(cachePath) | ||
} else { | ||
if (!force) { | ||
console.log(`Cache already exists for ${funcHash}. Skipping...`) | ||
return | ||
} | ||
} | ||
|
||
const fileNameWithCorrectExtension = fileName.replace( | ||
/\.(ts|js|mjs)$/, | ||
".{ts,js,mjs}" | ||
); | ||
console.log( | ||
`Triggering cache creation for: ${funcHash} (${fileNameWithCorrectExtension})` | ||
); | ||
// We're not inferring the return type here to make sure we don't accidentally await the function. | ||
return createCacheForWalletSetupFunction( | ||
extensionPath, | ||
cachePath, | ||
setupFunction, | ||
fileNameWithCorrectExtension | ||
); | ||
console.log(`Cache already exists for ${funcHash} but force flag is set. Deleting cache...`) | ||
await fs.remove(cachePath) | ||
} | ||
} | ||
); | ||
|
||
const fileNameWithCorrectExtension = fileName.replace(/\.(ts|js|mjs)$/, '.{ts,js,mjs}') | ||
console.log(`Triggering cache creation for: ${funcHash} (${fileNameWithCorrectExtension})`) | ||
// We're not inferring the return type here to make sure we don't accidentally await the function. | ||
return createCacheForWalletSetupFunction(extensionPath, cachePath, setupFunction, fileNameWithCorrectExtension) | ||
}) | ||
} |
Oops, something went wrong.