diff --git a/.editorconfig b/.editorconfig index 73afb2c..101910a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,10 +10,10 @@ trim_trailing_whitespace = true indent_style = space indent_size = 2 -[*.{css,js,json,jsx,md,mdx,scss,ts,tsx,vue}] +[*.{css,js,json,jsx,md,mdx,mts,scss,ts,tsx,vue}] indent_style = space indent_size = 2 -[.{babelrc,eslintrc}] +[.{babelrc,eslintrc,prettierrc}] indent_style = space indent_size = 2 diff --git a/package-lock.json b/package-lock.json index 50361d6..081e080 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,8 @@ "@docusaurus/module-type-aliases": "3.6.3", "@docusaurus/tsconfig": "3.6.3", "@docusaurus/types": "3.6.3", + "@types/semver": "7.5.8", + "semver": "7.6.3", "typescript": "5.7.2" }, "engines": { @@ -6001,6 +6003,13 @@ "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", diff --git a/package.json b/package.json index 35ffdcc..be78ec6 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", + "version": "docusaurus docs:version", + "version:fix": "node --experimental-strip-types ./publish-utils.mts", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "typecheck": "tsc" @@ -33,6 +35,8 @@ "@docusaurus/module-type-aliases": "3.6.3", "@docusaurus/tsconfig": "3.6.3", "@docusaurus/types": "3.6.3", + "@types/semver": "7.5.8", + "semver": "7.6.3", "typescript": "5.7.2" }, "browserslist": { diff --git a/publish-utils.mts b/publish-utils.mts new file mode 100644 index 0000000..3ee5721 --- /dev/null +++ b/publish-utils.mts @@ -0,0 +1,79 @@ +// This script updates all path references to use the right directory +import { + existsSync, + readdirSync, + readFileSync, + statSync, + writeFileSync +} from 'fs'; +import { join } from 'path'; +import { valid } from 'semver'; + +const SPEC_DIR = 'spec'; +const VERSIONED_DOCS_DIR = 'versioned_docs'; + +try { + const args = process.argv.slice(2); + if (!args.length) throw new Error('Missing arguments.'); + + const version = args[0]; + if (!valid(version)) throw new Error(`Argument '${version}' is not semver.`); + + const working_dir = `${VERSIONED_DOCS_DIR}/version-${version}/${SPEC_DIR}`; + if (!existsSync(working_dir)) + throw new Error(`Directory ${working_dir} does not exist.`); + + const files = walk(working_dir); + patch(files, '.mdx', '@site/docs/spec', `@site/${working_dir}`); + patch(files, '.schema.json', 'docs/spec', `${working_dir}`); +} catch (err) { + console.error(err); + process.exit(1); +} + +// +// Task Functions +// + +/** + * @function patch + * @description Patches a set of files matching a certain extension and pattern + * @param {Array} files The set of file paths + * @param {string} ext The file extension to filter on + * @param {string} from The pattern to look for + * @param {string} to The pattern to replace with + * @throws + */ +function patch(files: Array, ext: string, from: string, to: string) { + const schemas = files.filter((f) => f.endsWith(ext)); + + schemas.forEach((file) => { + const oldSchema = readFileSync(file, { encoding: 'utf-8' }); + const newSchema = oldSchema.replaceAll(from, to); + writeFileSync(file, newSchema, { encoding: 'utf-8' }); + console.log(`Patched file ${file}`); + }); +} + +/** + * @function walk + * @description Recursively walks a directory and yields a set of files + * @param {string} dir The directory to walk through + * @returns {Array} A complete set of file paths within the directory + * @throws + */ +function walk(dir: string): Array { + const list = readdirSync(dir); + + let results = []; + list.forEach((file) => { + file = join(dir, file); + const stat = statSync(file); + if (stat && stat.isDirectory()) { + results = [...results, ...walk(file)]; + } else { + results.push(file); + } + }); + return results; +}