From ba969ee32a2570742335d7e244b97a23268e5405 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Tue, 15 Oct 2024 09:25:41 -0400 Subject: [PATCH] Feature diff static file out (#2863) --- package.json | 2 +- projects/fastify-capture/package.json | 2 +- projects/json-pointer-helpers/package.json | 2 +- projects/openapi-io/package.json | 2 +- projects/openapi-utilities/package.json | 2 +- projects/optic/package.json | 2 +- projects/optic/src/commands/diff/diff.ts | 32 +++++++++++++++--- projects/optic/web/craco.config.js | 37 +++++++++++++++++--- projects/optic/web/package-lock.json | 39 ++++++++++++++++++++++ projects/optic/web/package.json | 2 ++ projects/optic/web/public/index.html | 15 --------- projects/optic/web/src/index.tsx | 3 +- projects/rulesets-base/package.json | 2 +- projects/standard-rulesets/package.json | 2 +- 14 files changed, 112 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 8b1dcb1191..09a5d5c609 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "openapi-workspaces", "license": "MIT", "private": true, - "version": "1.0.3", + "version": "1.0.4", "workspaces": [ "projects/json-pointer-helpers", "projects/openapi-io", diff --git a/projects/fastify-capture/package.json b/projects/fastify-capture/package.json index 48159c595b..e9868acb48 100644 --- a/projects/fastify-capture/package.json +++ b/projects/fastify-capture/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/fastify-capture", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/json-pointer-helpers/package.json b/projects/json-pointer-helpers/package.json index 02097b7a8b..93394c01c4 100644 --- a/projects/json-pointer-helpers/package.json +++ b/projects/json-pointer-helpers/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/json-pointer-helpers", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/openapi-io/package.json b/projects/openapi-io/package.json index 1e6d4d09fb..03da9787d1 100644 --- a/projects/openapi-io/package.json +++ b/projects/openapi-io/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/openapi-io", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/openapi-utilities/package.json b/projects/openapi-utilities/package.json index 9df9503eb2..15c4bcdb39 100644 --- a/projects/openapi-utilities/package.json +++ b/projects/openapi-utilities/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/openapi-utilities", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/optic/package.json b/projects/optic/package.json index 517ebce9dc..fc99650ea5 100644 --- a/projects/optic/package.json +++ b/projects/optic/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/optic", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/optic/src/commands/diff/diff.ts b/projects/optic/src/commands/diff/diff.ts index ec090724ad..32975c6e8b 100644 --- a/projects/optic/src/commands/diff/diff.ts +++ b/projects/optic/src/commands/diff/diff.ts @@ -46,6 +46,7 @@ type DiffActionOptions = { severity: 'info' | 'warn' | 'error'; lastChange: boolean; generated?: boolean; + out?: string; }; const description = 'Run a diff between two API specs'; @@ -118,6 +119,10 @@ export const registerDiff = ( .option('-c, --check', 'Enable checks', false) .option('-u, --upload', 'Upload run to cloud', false) .option('-w, --web', 'View the diff in the Optic changelog web view', false) + .option( + '-o, --out ', + 'write a self-contained HTML diff. use with --web' + ) .option('--json', 'Output as json', false) .option('--last-change', 'Find the last change for this spec', false) .option( @@ -368,6 +373,8 @@ const getDiffAction = const diffResult = await runDiff(parsedFiles, config, options, file1); let maybeChangelogUrl: string | null = null; + let indexPath: string | null = null; + let compressedData: string | null = null; let specUrl: string | null = null; let [baseParseResult, headParseResult, specDetails] = parsedFiles; @@ -447,7 +454,7 @@ const getDiffAction = base: options.base, }; - const compressedData = compressDataV2( + compressedData = compressDataV2( baseParseResult, headParseResult, diffResult.specResults, @@ -455,7 +462,6 @@ const getDiffAction = diffResult.changelogData ); analyticsData.compressedDataLength = compressedData.length; - logger.info('Opening up diff in web view'); const copyPath = path.join(os.tmpdir(), 'optic-changelog'); @@ -466,13 +472,31 @@ const getDiffAction = { errorOnExist: false, overwrite: false } ); - const baseHtml = path.resolve(path.join(copyPath, 'index.html')); + indexPath = path.join( + path.resolve(path.join(__dirname, '../../../web/build')), + 'index.html' + ); + const baseHtml = path.resolve(indexPath); maybeChangelogUrl = `${baseHtml}#${compressedData}`; await flushEvents(); } trackEvent('optic.diff.view_web', analyticsData); - await openUrl(maybeChangelogUrl); + if (options.out && indexPath) { + const indexContents = (await fs.readFile(indexPath)).toString(); + const newContents = indexContents.replace( + `
`, + `
` + ); + + const out = path.resolve(process.cwd(), options.out); + logger.info('Diff HTML written to ' + out); + + await fs.writeFile(out, newContents); + } else { + logger.info('Opening up diff in web view'); + await openUrl(maybeChangelogUrl); + } } } diff --git a/projects/optic/web/craco.config.js b/projects/optic/web/craco.config.js index 014b86e636..07f5b89fae 100644 --- a/projects/optic/web/craco.config.js +++ b/projects/optic/web/craco.config.js @@ -1,12 +1,12 @@ const webpack = require('webpack'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlInlineScriptPlugin = require('html-inline-script-webpack-plugin'); module.exports = { webpack: { alias: { fs: false, path: false, - // Alias fallbacks for node files with `node:` prefix removed - // In the future, we should split out our dependencies into node + browser 'fs/promises': false, zlib: false, os: false, @@ -24,12 +24,41 @@ module.exports = { }, plugins: { add: [ - // https://github.com/webpack/webpack/issues/13290#issuecomment-1188760779 - // in combination with the fallbacks above + // Replace node prefix new webpack.NormalModuleReplacementPlugin(/^node:/, (resource) => { resource.request = resource.request.replace(/^node:/, ''); }), + // HtmlWebpackPlugin to generate HTML output + new HtmlWebpackPlugin({ + inject: 'body', // Inject scripts at the end of the body + template: './public/index.html', + filename: 'index.html', // Ensure a single output HTML file + }), + // Inline JavaScript into the HTML + new HtmlInlineScriptPlugin(), ], }, + configure: (webpackConfig) => { + // Remove any existing HtmlWebpackPlugin instances to prevent conflicts + webpackConfig.plugins = webpackConfig.plugins.filter( + (plugin) => + !( + plugin.constructor && + plugin.constructor.name === 'HtmlWebpackPlugin' + ) + ); + + // Add HtmlWebpackPlugin after removing any existing instances + webpackConfig.plugins.push( + new HtmlWebpackPlugin({ + inject: 'body', + template: './public/index.html', + filename: 'index.html', + }), + new HtmlInlineScriptPlugin() + ); + + return webpackConfig; + }, }, }; diff --git a/projects/optic/web/package-lock.json b/projects/optic/web/package-lock.json index bdcb53bfc3..e66ca07a5b 100644 --- a/projects/optic/web/package-lock.json +++ b/projects/optic/web/package-lock.json @@ -25,6 +25,8 @@ "brotli": "^1.3.3", "buffer": "^6.0.3", "diff": "5.2.0", + "html-inline-script-webpack-plugin": "^3.2.1", + "html-webpack-inline-source-plugin": "^0.0.10", "markdown-to-jsx": "^7.2.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -9569,6 +9571,19 @@ "resolved": "https://packages.atlassian.com/api/npm/npm-remote/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, + "node_modules/html-inline-script-webpack-plugin": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/html-inline-script-webpack-plugin/-/html-inline-script-webpack-plugin-3.2.1.tgz", + "integrity": "sha512-PEj9Ve31BE0dva6eTD6wHMOztgIdPxF6gx3wad7ohBkCn7MXpuUvPC9t5ThMJ2NrVi1jWGBYU76DfoS+8dabRw==", + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + }, + "peerDependencies": { + "html-webpack-plugin": "^5.0.0", + "webpack": "^5.0.0" + } + }, "node_modules/html-minifier-terser": { "version": "6.1.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -9589,6 +9604,24 @@ "node": ">=12" } }, + "node_modules/html-webpack-inline-source-plugin": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/html-webpack-inline-source-plugin/-/html-webpack-inline-source-plugin-0.0.10.tgz", + "integrity": "sha512-0ZNU57u7283vrXSF5a4VDnVOMWiSwypKIp1z/XfXWoVHLA1r3Xmyxx5+Lz+mnthz/UvxL1OAf41w5UIF68Jngw==", + "dependencies": { + "escape-string-regexp": "^1.0.5", + "slash": "^1.0.0", + "source-map-url": "^0.4.0" + } + }, + "node_modules/html-webpack-inline-source-plugin/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/html-webpack-plugin": { "version": "5.6.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", @@ -16414,6 +16447,12 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" + }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", diff --git a/projects/optic/web/package.json b/projects/optic/web/package.json index 693f6c4853..53254ac18d 100644 --- a/projects/optic/web/package.json +++ b/projects/optic/web/package.json @@ -14,6 +14,8 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "html-webpack-inline-source-plugin": "^0.0.10", + "html-inline-script-webpack-plugin": "^3.2.1", "@types/jest": "^27.5.2", "@types/node": "^16.18.104", "@types/react": "^18.3.3", diff --git a/projects/optic/web/public/index.html b/projects/optic/web/public/index.html index c52d3b5a90..31eb70df64 100644 --- a/projects/optic/web/public/index.html +++ b/projects/optic/web/public/index.html @@ -2,28 +2,13 @@ - - - - - Optic Changelog diff --git a/projects/optic/web/src/index.tsx b/projects/optic/web/src/index.tsx index 674e95af59..0c8452977a 100644 --- a/projects/optic/web/src/index.tsx +++ b/projects/optic/web/src/index.tsx @@ -16,7 +16,8 @@ const decodeHash = (data: string): any => { const App = () => { const transformed = useMemo(() => { - const decoded = decodeHash(window.location.hash); + // @ts-ignore + const decoded = decodeHash(window.diffData || window.location.hash); return { ...decoded, base: { diff --git a/projects/rulesets-base/package.json b/projects/rulesets-base/package.json index 2fac47f688..67c8284e6c 100644 --- a/projects/rulesets-base/package.json +++ b/projects/rulesets-base/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/rulesets-base", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/standard-rulesets/package.json b/projects/standard-rulesets/package.json index 61d1b7393b..88d718924a 100644 --- a/projects/standard-rulesets/package.json +++ b/projects/standard-rulesets/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/standard-rulesets", "license": "MIT", "packageManager": "yarn@4.1.1", - "version": "1.0.3", + "version": "1.0.4", "main": "build/index.js", "types": "build/index.d.ts", "files": [