Skip to content

Commit

Permalink
Feature diff static file out (#2863)
Browse files Browse the repository at this point in the history
  • Loading branch information
acunniffe authored Oct 15, 2024
1 parent 646db75 commit ba969ee
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion projects/fastify-capture/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion projects/json-pointer-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion projects/openapi-io/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion projects/openapi-utilities/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion projects/optic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
32 changes: 28 additions & 4 deletions projects/optic/src/commands/diff/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 <file>',
'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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -447,15 +454,14 @@ const getDiffAction =
base: options.base,
};

const compressedData = compressDataV2(
compressedData = compressDataV2(
baseParseResult,
headParseResult,
diffResult.specResults,
meta,
diffResult.changelogData
);
analyticsData.compressedDataLength = compressedData.length;
logger.info('Opening up diff in web view');

const copyPath = path.join(os.tmpdir(), 'optic-changelog');

Expand All @@ -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(
`<div id="root"></div>`,
`<div id="root"></div><script>window.diffData ='${compressedData}'</script>`
);

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);
}
}
}

Expand Down
37 changes: 33 additions & 4 deletions projects/optic/web/craco.config.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
},
},
};
39 changes: 39 additions & 0 deletions projects/optic/web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions projects/optic/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
15 changes: 0 additions & 15 deletions projects/optic/web/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,13 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Optic Changelog</title>
</head>
<body>
Expand Down
3 changes: 2 additions & 1 deletion projects/optic/web/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
2 changes: 1 addition & 1 deletion projects/rulesets-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion projects/standard-rulesets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down

0 comments on commit ba969ee

Please sign in to comment.