From 6c8d9573a471864258ad7b3564438e3e464c6aaf Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Sun, 26 May 2024 21:52:12 +0100 Subject: [PATCH] feat: export version constant --- eslint.config.mjs | 2 +- lib/svgo-node.js | 4 +++- lib/svgo.d.ts | 3 +++ lib/svgo.js | 3 +++ lib/version.js | 2 ++ package.json | 16 ++++++++-------- scripts/sync-version.js | 12 ++++++++++++ test/browser.js | 20 +++++++++++++++++--- test/svgo.cjs | 4 +++- test/svgo/_index.test.js | 12 +++++++++--- 10 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 lib/version.js create mode 100644 scripts/sync-version.js diff --git a/eslint.config.mjs b/eslint.config.mjs index 86b26911d..61073b2bb 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -20,7 +20,7 @@ export default [ }, { languageOptions: { - ecmaVersion: 2021, + ecmaVersion: 'latest', globals: { ...globals.nodeBuiltin, }, diff --git a/lib/svgo-node.js b/lib/svgo-node.js index 05ca2bc7d..24911b2df 100644 --- a/lib/svgo-node.js +++ b/lib/svgo-node.js @@ -2,7 +2,7 @@ import os from 'os'; import fs from 'fs'; import { pathToFileURL } from 'url'; import path from 'path'; -import { optimize as optimizeAgnostic } from './svgo.js'; +import { VERSION, optimize as optimizeAgnostic } from './svgo.js'; const importConfig = async (configFile) => { // dynamic import expects file url instead of path and may fail @@ -25,6 +25,8 @@ const isFile = async (file) => { } }; +export { VERSION }; + export const loadConfig = async (configFile, cwd = process.cwd()) => { if (configFile != null) { if (path.isAbsolute(configFile)) { diff --git a/lib/svgo.d.ts b/lib/svgo.d.ts index a9693f4a6..f1151184c 100644 --- a/lib/svgo.d.ts +++ b/lib/svgo.d.ts @@ -52,5 +52,8 @@ type Output = { data: string; }; +/** Installed version of SVGO. */ +export declare const VERSION: string; + /** The core of SVGO */ export declare function optimize(input: string, config?: Config): Output; diff --git a/lib/svgo.js b/lib/svgo.js index e57fb2e1e..14028895f 100644 --- a/lib/svgo.js +++ b/lib/svgo.js @@ -3,6 +3,7 @@ import { stringifySvg } from './stringifier.js'; import { builtin } from './builtin.js'; import { invokePlugins } from './svgo/plugins.js'; import { encodeSVGDatauri } from './svgo/tools.js'; +import { VERSION } from './version.js'; const pluginsMap = {}; for (const plugin of builtin) { @@ -45,6 +46,8 @@ const resolvePluginConfig = (plugin) => { return null; }; +export { VERSION }; + export const optimize = (input, config) => { if (config == null) { config = {}; diff --git a/lib/version.js b/lib/version.js new file mode 100644 index 000000000..0953766a7 --- /dev/null +++ b/lib/version.js @@ -0,0 +1,2 @@ +/** Version of SVGO. */ +export const VERSION = '4.0.0'; diff --git a/package.json b/package.json index 2394c9c39..fd8ed3327 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "packageManager": "yarn@3.8.2", "name": "svgo", - "version": "3.3.1", + "version": "4.0.0", "description": "SVGO is a Node.js library and command-line application for optimizing vector images.", "license": "MIT", "type": "module", @@ -85,15 +85,15 @@ "node": ">=14.0.0" }, "scripts": { - "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --maxWorkers=4 --coverage", + "build": "node scripts/sync-version.js && rollup -c", + "typecheck": "tsc", "lint": "eslint . && prettier --check .", "fix": "eslint --fix . && prettier --write .", - "typecheck": "tsc", - "generate-bundles": "rollup -c", - "test-bundles": "yarn generate-bundles && node ./test/svgo.cjs && node ./test/browser.js", - "test-regression": "node ./test/regression-extract.js && cross-env NO_DIFF=1 node ./test/regression.js", - "prepublishOnly": "rimraf dist && yarn generate-bundles", - "qa": "yarn lint && yarn typecheck && yarn test && yarn test-bundles && yarn test-regression" + "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --maxWorkers=4 --coverage", + "test:bundles": "yarn build && node ./test/svgo.cjs && node ./test/browser.js", + "test:regression": "node ./test/regression-extract.js && cross-env NO_DIFF=1 node ./test/regression.js", + "qa": "yarn typecheck && yarn lint && yarn test && yarn test:bundles && yarn test:regression", + "prepublishOnly": "rimraf dist && yarn build" }, "jest": { "coveragePathIgnorePatterns": [ diff --git a/scripts/sync-version.js b/scripts/sync-version.js new file mode 100644 index 000000000..6d9136609 --- /dev/null +++ b/scripts/sync-version.js @@ -0,0 +1,12 @@ +import fs from 'node:fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const pkgPath = path.join(__dirname, '../package.json'); +const { version } = JSON.parse(await fs.readFile(pkgPath, 'utf-8')); + +await fs.writeFile( + './lib/version.js', + `/** Version of SVGO. */\nexport const VERSION = '${version}';\n`, +); diff --git a/test/browser.js b/test/browser.js index 3f9cfc444..c35b392ac 100644 --- a/test/browser.js +++ b/test/browser.js @@ -1,8 +1,14 @@ import assert from 'assert'; import fs from 'node:fs/promises'; import http from 'http'; +import path from 'path'; +import { fileURLToPath } from 'url'; import { chromium } from 'playwright'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const pkgPath = path.join(__dirname, '../package.json'); +const { version } = JSON.parse(await fs.readFile(pkgPath, 'utf-8')); + const fixture = ` @@ -24,11 +30,12 @@ const expected = ` const content = ` `; @@ -50,8 +57,15 @@ const runTest = async () => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto('http://localhost:5000'); - const actual = await page.evaluate(() => globalThis.result); - assert.equal(actual, expected); + + const actual = await page.evaluate(() => ({ + version: globalThis.version, + result: globalThis.result, + })); + + assert.strictEqual(actual.version, version); + assert.equal(actual.result, expected); + await browser.close(); }; diff --git a/test/svgo.cjs b/test/svgo.cjs index 7adc1b733..2c9d6fdb9 100644 --- a/test/svgo.cjs +++ b/test/svgo.cjs @@ -1,5 +1,6 @@ -const { loadConfig, optimize } = require('../dist/svgo-node.cjs'); const assert = require('assert'); +const { VERSION, optimize, loadConfig } = require('../dist/svgo-node.cjs'); +const PKG = require('../package.json'); const fixture = ` @@ -27,6 +28,7 @@ const runTest = () => { }); const actual = result.data; + assert.strictEqual(VERSION, PKG.version); assert.equal(actual, expected); assert.notEqual(loadConfig, undefined); }; diff --git a/test/svgo/_index.test.js b/test/svgo/_index.test.js index 15275b10c..5bde71787 100644 --- a/test/svgo/_index.test.js +++ b/test/svgo/_index.test.js @@ -1,8 +1,8 @@ -import fs from 'fs'; +import fs from 'node:fs/promises'; import path from 'path'; import { EOL } from 'os'; import { fileURLToPath } from 'url'; -import { optimize } from '../../lib/svgo.js'; +import { VERSION, optimize } from '../../lib/svgo.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -14,11 +14,17 @@ const normalize = (file) => { const parseFixture = async (file) => { const filepath = path.resolve(__dirname, file); - const content = await fs.promises.readFile(filepath, 'utf-8'); + const content = await fs.readFile(filepath, 'utf-8'); return normalize(content).split(/\s*@@@\s*/); }; describe('svgo', () => { + it('version should match package.json', async () => { + const pkgPath = path.resolve(__dirname, '../../package.json'); + const { version } = JSON.parse(await fs.readFile(pkgPath, 'utf-8')); + expect(VERSION).toStrictEqual(version); + }); + it('should create indent with 2 spaces', async () => { const [original, expected] = await parseFixture('test.svg.txt'); const result = optimize(original, {