aboutsummaryrefslogtreecommitdiff
path: root/scripts/apidocs/diff.ts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/apidocs/diff.ts')
-rw-r--r--scripts/apidocs/diff.ts97
1 files changed, 97 insertions, 0 deletions
diff --git a/scripts/apidocs/diff.ts b/scripts/apidocs/diff.ts
new file mode 100644
index 00000000..0ccdad6e
--- /dev/null
+++ b/scripts/apidocs/diff.ts
@@ -0,0 +1,97 @@
+import type { ApiDiffHashes } from './output/diff-index';
+import {
+ FILE_NAME_DOCS_DIFF_INDEX,
+ FILE_PATH_DOCS_DIFF_INDEX,
+} from './output/diff-index';
+
+/**
+ * Loads the diff index from the given source url.
+ *
+ * @param url The url to load the diff index from.
+ */
+async function loadRemote(url: string): Promise<ApiDiffHashes> {
+ return fetch(url).then((res) => {
+ if (!res.ok) {
+ throw new Error(
+ `Failed to load remote diff index from ${url}: ${res.statusText}`
+ );
+ }
+
+ return res.json() as Promise<ApiDiffHashes>;
+ });
+}
+
+/**
+ * Loads the diff index from the given local path.
+ *
+ * @param path The path to load the diff index from. Should start with `file://` for cross platform compatibility.
+ */
+async function loadLocal(path: string): Promise<ApiDiffHashes> {
+ return import(path).then((imp) => imp.default as ApiDiffHashes);
+}
+
+/**
+ * Loads the diff index from the given source.
+ * If the source starts with `https://` it will be loaded from the remote url.
+ * Otherwise it will be loaded from the local path.
+ *
+ * @param source The source to load the diff index from.
+ */
+async function load(source: string): Promise<ApiDiffHashes> {
+ return source.startsWith('https://') ? loadRemote(source) : loadLocal(source);
+}
+
+/**
+ * Returns a set of all keys from the given entries.
+ *
+ * @param entries The entries to get the keys from.
+ */
+function allKeys(
+ ...entries: ReadonlyArray<Record<string, unknown>>
+): Set<string> {
+ return new Set(entries.flatMap(Object.keys));
+}
+
+/**
+ * Compares the target (reference) and source (changed) diff index and returns the differences.
+ * The returned object contains the module names as keys and the method names as values.
+ * If the module name is `ADDED` or `REMOVED` it means that the module was added or removed in the local diff index.
+ *
+ * @param targetDiffIndex The url to the target (reference) diff index. Defaults to the next.fakerjs.dev diff index.
+ * @param sourceDiffIndex The path to the source (changed) index. Defaults to the local diff index.
+ */
+export async function diff(
+ targetDiffIndex = `https://next.fakerjs.dev/${FILE_NAME_DOCS_DIFF_INDEX}`,
+ sourceDiffIndex = `file://${FILE_PATH_DOCS_DIFF_INDEX}`
+): Promise<Record<string, ['ADDED'] | ['REMOVED'] | string[]>> {
+ const target = await load(targetDiffIndex);
+ const source = await load(sourceDiffIndex);
+
+ const diff: Record<string, string[]> = {};
+
+ for (const moduleName of allKeys(target, source)) {
+ const remoteModule = target[moduleName];
+ const localModule = source[moduleName];
+
+ if (!remoteModule) {
+ diff[moduleName] = ['ADDED'];
+ continue;
+ }
+
+ if (!localModule) {
+ diff[moduleName] = ['REMOVED'];
+ continue;
+ }
+
+ for (const methodName of allKeys(remoteModule, localModule)) {
+ const remoteMethod = remoteModule[methodName];
+ const localMethod = localModule[methodName];
+
+ if (remoteMethod !== localMethod) {
+ (diff[moduleName] ??= []).push(methodName);
+ }
+ }
+ }
+
+ return diff;
+}