From f4fbf93411f4dc50c2ab51aa2493ba767a684aa7 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Wed, 24 May 2023 15:37:00 +0200 Subject: [PATCH] fix(cli): do not rely on x.nest.land --- cli/deps.ts | 6 ++++ cli/flow.ts | 2 +- cli/login.ts | 3 +- cli/main.ts | 2 +- cli/script.ts | 4 +-- cli/sync.ts | 12 ++++---- cli/types.ts | 10 ++----- cli/utils.ts | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 cli/utils.ts diff --git a/cli/deps.ts b/cli/deps.ts index 118178c370..8be49d7e84 100644 --- a/cli/deps.ts +++ b/cli/deps.ts @@ -25,6 +25,7 @@ export { } from "https://deno.land/std@0.176.0/streams/mod.ts"; export { DelimiterStream } from "https://deno.land/std@0.176.0/streams/mod.ts"; export { iterateReader } from "https://deno.land/std@0.176.0/streams/iterate_reader.ts"; +export { writeAllSync } from "https://deno.land/std@0.176.0/streams/mod.ts"; // other export { getAvailablePort } from "https://deno.land/x/port@1.0.0/mod.ts"; @@ -38,3 +39,8 @@ export { default as objectHash } from "https://deno.land/x/object_hash@2.0.3.1/m export { default as gitignore_parser } from "npm:gitignore-parser"; export { default as JSZip } from "npm:jszip@3.7.1"; export * as log from "https://deno.land/std@0.186.0/log/mod.ts"; +export { + stringify as yamlStringify, + parse as yamlParse, +} from "https://deno.land/std@0.184.0/yaml/mod.ts"; +export { open } from "https://deno.land/x/open@v0.0.5/index.ts"; diff --git a/cli/flow.ts b/cli/flow.ts index 0358a36fec..42c81b9aff 100644 --- a/cli/flow.ts +++ b/cli/flow.ts @@ -1,6 +1,5 @@ // deno-lint-ignore-file no-explicit-any import { GlobalOptions, isSuperset } from "./types.ts"; -import { parse as yamlParse } from "https://deno.land/std@0.184.0/yaml/mod.ts"; import { colors, @@ -10,6 +9,7 @@ import { FlowService, JobService, Table, + yamlParse, } from "./deps.ts"; import { requireLogin, resolveWorkspace, validatePath } from "./context.ts"; import { resolve, track_job } from "./script.ts"; diff --git a/cli/login.ts b/cli/login.ts index 97e283a455..6665fd3f7a 100644 --- a/cli/login.ts +++ b/cli/login.ts @@ -1,6 +1,5 @@ import { GlobalOptions } from "./types.ts"; -import { colors, getAvailablePort, log, Secret, Select } from "./deps.ts"; -import { open } from "https://deno.land/x/open/index.ts"; +import { colors, getAvailablePort, log, open, Secret, Select } from "./deps.ts"; export async function loginInteractive(remote: string) { let token: string | undefined; diff --git a/cli/main.ts b/cli/main.ts index 4bc059fd1f..7a86eb4138 100644 --- a/cli/main.ts +++ b/cli/main.ts @@ -3,6 +3,7 @@ import { CompletionsCommand, DenoLandProvider, UpgradeCommand, + log, } from "./deps.ts"; import flow from "./flow.ts"; import app from "./apps.ts"; @@ -18,7 +19,6 @@ import folder from "./folder.ts"; import sync from "./sync.ts"; import { tryResolveVersion } from "./context.ts"; import { GlobalOptions } from "./types.ts"; -import * as log from "https://deno.land/std@0.186.0/log/mod.ts"; addEventListener("error", (event) => { if (event.error) { diff --git a/cli/script.ts b/cli/script.ts index 117180f9c6..1a786d4d89 100644 --- a/cli/script.ts +++ b/cli/script.ts @@ -11,9 +11,9 @@ import { Script, ScriptService, Table, + writeAllSync, + yamlParse, } from "./deps.ts"; -import { writeAllSync } from "https://deno.land/std@0.176.0/streams/mod.ts"; -import { parse as yamlParse } from "https://deno.land/std@0.184.0/yaml/mod.ts"; export interface ScriptFile { parent_hash?: string; diff --git a/cli/sync.ts b/cli/sync.ts index 853137b8e9..358c9abdbf 100644 --- a/cli/sync.ts +++ b/cli/sync.ts @@ -17,6 +17,8 @@ import { FlowModule, RawScript, log, + yamlStringify, + yamlParse, } from "./deps.ts"; import { getTypeStrFromPath, @@ -31,11 +33,7 @@ import { downloadZip } from "./pull.ts"; import { handleScriptMetadata } from "./script.ts"; import { handleFile } from "./script.ts"; -import { equal } from "https://deno.land/x/equal@v1.5.0/mod.ts"; -import { - stringify as yamlStringify, - parse as yamlParse, -} from "https://deno.land/std@0.184.0/yaml/mod.ts"; +import { deepEqual } from "./utils.ts"; type DynFSElement = { isDirectory: boolean; @@ -325,8 +323,8 @@ async function compareDynFSElement( changes.push({ name: "added", path: k, content: v }); } else if ( m2[k] != v && - (!k.endsWith(".json") || !equal(JSON.parse(v), JSON.parse(m2[k]))) && - (!k.endsWith(".yaml") || !equal(yamlParse(v), yamlParse(m2[k]))) + (!k.endsWith(".json") || !deepEqual(JSON.parse(v), JSON.parse(m2[k]))) && + (!k.endsWith(".yaml") || !deepEqual(yamlParse(v), yamlParse(m2[k]))) ) { changes.push({ name: "edited", path: k, after: v, before: m2[k] }); } diff --git a/cli/types.ts b/cli/types.ts index ca59a289ce..4db16408ed 100644 --- a/cli/types.ts +++ b/cli/types.ts @@ -1,12 +1,7 @@ // deno-lint-ignore-file no-explicit-any -import { colors, log, path } from "./deps.ts"; +import { colors, log, path, yamlParse, yamlStringify } from "./deps.ts"; import { pushApp } from "./apps.ts"; -import { - parse as yamlParse, - stringify as yamlStringify, -} from "https://deno.land/std@0.184.0/yaml/mod.ts"; -import { equal } from "https://deno.land/x/equal@v1.5.0/equal.ts"; import { pushFolder } from "./folder.ts"; import { pushFlow } from "./flow.ts"; import { pushResource } from "./resource.ts"; @@ -15,6 +10,7 @@ import { pushVariable } from "./variable.ts"; import * as Diff from "npm:diff"; import { yamlOptions } from "./sync.ts"; import { showDiffs } from "./main.ts"; +import { deepEqual } from "./utils.ts"; export interface DifferenceCreate { type: "CREATE"; @@ -47,7 +43,7 @@ export function isSuperset( superset: Record ): boolean { return Object.keys(subset).every((key) => { - const eq = equal(subset[key], superset[key]); + const eq = deepEqual(subset[key], superset[key]); if (!eq && showDiffs) { const sub = subset[key]; const supers = superset[key]; diff --git a/cli/utils.ts b/cli/utils.ts new file mode 100644 index 0000000000..fe6ca02215 --- /dev/null +++ b/cli/utils.ts @@ -0,0 +1,76 @@ +// Modified from: https://raw.githubusercontent.com/epoberezkin/fast-deep-equal/master/src/index.jst +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-nocheck This file is copied from a JS project, so it's not type-safe. +export function deepEqual(a: T, b: T): boolean { + if (a === b) return true; + + if (a && b && typeof a === "object" && typeof b === "object") { + if (a.constructor !== b.constructor) return false; + + let length, i; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0; ) { + if (!deepEqual(a[i], b[i])) return false; + } + return true; + } + + if (a instanceof Map && b instanceof Map) { + if (a.size !== b.size) return false; + for (i of a.entries()) { + if (!b.has(i[0])) return false; + } + for (i of a.entries()) { + if (!deepEqual(i[1], b.get(i[0]))) return false; + } + return true; + } + + if (a instanceof Set && b instanceof Set) { + if (a.size !== b.size) return false; + for (i of a.entries()) { + if (!b.has(i[0])) return false; + } + return true; + } + + if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0; ) { + if (a[i] !== b[i]) return false; + } + return true; + } + + if (a.constructor === RegExp) { + return a.source === b.source && a.flags === b.flags; + } + if (a.valueOf !== Object.prototype.valueOf) { + return a.valueOf() === b.valueOf(); + } + if (a.toString !== Object.prototype.toString) { + return a.toString() === b.toString(); + } + + const keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0; ) { + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + } + + for (i = length; i-- !== 0; ) { + const key = keys[i]; + if (!deepEqual(a[key], b[key])) return false; + } + + return true; + } + + // true if both NaN, false otherwise + return a !== a && b !== b; +}