From 6bd7fe1154f944d33d8a8ab2ecbf480ec3d496c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dandelion=20Man=C3=A9?= Date: Sun, 21 Jul 2019 16:05:21 +0100 Subject: [PATCH] Replace `Object.freeze` with `deepFreeze` Throughout the codebase, we freeze objects when we want to ensure that their properties are never altered -- e.g. because they are a plugin declaration, or are being re-used for various test cases. We generally use `Object.freeze`. This has the disadvantage that it does not work recursively, so a frozen object's mutable fields and properties can still be mutated. (E.g. if `const obj = Object.freeze({foo: []})`, then `obj.foo.push(1)` will succeed in mutating the 'frozen' object). Sometimes we anticipate this and explicitly freeze the sub-fields (which is tedious); sometimes we forget (which invites errors). This change simply replaces all instances of Object.freeze with [deep-freeze], so we don't need to worry about the issue at all anymore. Test plan: `yarn test` passes (after updating snapshots); `git grep Object.freeze` returns no hits. [deep-freeze]: https://www.npmjs.com/package/deep-freeze --- package.json | 1 + src/analysis/loadGraph.test.js | 16 ++++---- src/analysis/timeline/timelinePagerank.js | 3 +- src/analysis/weightEvaluator.test.js | 19 +++++---- src/analysis/weightsToEdgeEvaluator.test.js | 9 ++-- src/cli/common.js | 3 +- src/core/address.js | 3 +- src/core/graph.js | 3 +- src/core/graphTestUtil.js | 8 ++-- src/core/project.test.js | 13 +++--- src/core/project_io.test.js | 13 +++--- src/core/version.js | 6 ++- .../legacy/pagerankTable/aggregate.js | 7 ++-- .../generateFlowTypes.test.js.snap | 6 ++- src/graphql/generateFlowTypes.js | 5 ++- src/graphql/mirror.js | 3 +- src/plugins/defaultCredConfig.js | 15 +++---- src/plugins/demo/declaration.js | 18 ++++---- src/plugins/demo/graph.js | 5 ++- src/plugins/git/declaration.js | 11 ++--- src/plugins/git/edges.js | 5 ++- src/plugins/git/mergeRepository.test.js | 9 ++-- src/plugins/git/nodes.js | 3 +- src/plugins/git/render.test.js | 5 ++- src/plugins/github/blacklistedObjectIds.js | 3 +- src/plugins/github/declaration.js | 41 ++++++++++--------- src/plugins/github/edges.js | 5 ++- src/plugins/github/graphqlTypes.js | 6 ++- src/plugins/github/nodes.js | 3 +- src/webutil/Colors.js | 11 ++--- yarn.lock | 5 +++ 31 files changed, 150 insertions(+), 113 deletions(-) diff --git a/package.json b/package.json index 3feb0a0..26e245f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "d3-scale-chromatic": "^1.3.3", "d3-time": "^1.0.11", "d3-time-format": "^2.1.3", + "deep-freeze": "^0.0.1", "express": "^4.16.3", "fs-extra": "8.1.0", "history": "^3.0.0", diff --git a/src/analysis/loadGraph.test.js b/src/analysis/loadGraph.test.js index e87886b..b8a80f2 100644 --- a/src/analysis/loadGraph.test.js +++ b/src/analysis/loadGraph.test.js @@ -2,6 +2,7 @@ import tmp from "tmp"; import path from "path"; +import deepFreeze from "deep-freeze"; import { Graph, @@ -18,13 +19,14 @@ import {makeRepoId, type RepoId} from "../core/repoId"; import {loadGraph} from "./loadGraph"; import {node} from "../core/graphTestUtil"; -const declaration = (name) => ({ - name, - nodePrefix: NodeAddress.empty, - edgePrefix: EdgeAddress.empty, - nodeTypes: Object.freeze([]), - edgeTypes: Object.freeze([]), -}); +const declaration = (name) => + deepFreeze({ + name, + nodePrefix: NodeAddress.empty, + edgePrefix: EdgeAddress.empty, + nodeTypes: [], + edgeTypes: [], + }); class MockStaticAdapter implements IBackendAdapterLoader { _resolutionGraph: ?Graph; diff --git a/src/analysis/timeline/timelinePagerank.js b/src/analysis/timeline/timelinePagerank.js index f7a42ca..754bc55 100644 --- a/src/analysis/timeline/timelinePagerank.js +++ b/src/analysis/timeline/timelinePagerank.js @@ -3,6 +3,7 @@ /** * Core logic for computing timeline PageRank on a graph. */ +import deepFreeze from "deep-freeze"; import {sum} from "d3-array"; import * as NullUtil from "../../util/null"; import {Graph, type NodeAddressT, type Edge, type Node} from "../../core/graph"; @@ -183,7 +184,7 @@ export function* _timelineMarkovChain( for (const {address} of edges) { edgeWeights.set(address, edgeEvaluator(address)); } - const defaultEdgeWeight = Object.freeze({forwards: 0, backwards: 0}); + const defaultEdgeWeight = deepFreeze({forwards: 0, backwards: 0}); const currentEdgeWeight = (e: Edge) => { return NullUtil.orElse(edgeWeights.get(e.address), defaultEdgeWeight); }; diff --git a/src/analysis/weightEvaluator.test.js b/src/analysis/weightEvaluator.test.js index 5b3b217..b967c02 100644 --- a/src/analysis/weightEvaluator.test.js +++ b/src/analysis/weightEvaluator.test.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import {NodeAddress, EdgeAddress} from "../core/graph"; import {nodeWeightEvaluator, edgeWeightEvaluator} from "./weightEvaluator"; import {defaultWeights} from "./weights"; @@ -10,7 +11,7 @@ describe("src/analysis/weightEvaluator", () => { const foo = NodeAddress.fromParts(["foo"]); const foobar = NodeAddress.fromParts(["foo", "bar"]); - const fooNodeType = Object.freeze({ + const fooNodeType = deepFreeze({ name: "", pluralName: "", prefix: foo, @@ -18,7 +19,7 @@ describe("src/analysis/weightEvaluator", () => { description: "", }); - const fooBarNodeType = Object.freeze({ + const fooBarNodeType = deepFreeze({ name: "", pluralName: "", prefix: foobar, @@ -26,7 +27,7 @@ describe("src/analysis/weightEvaluator", () => { description: "", }); - const types = Object.freeze([fooNodeType, fooBarNodeType]); + const types = deepFreeze([fooNodeType, fooBarNodeType]); it("gives every node weight 1 with empty types and weights", () => { const evaluator = nodeWeightEvaluator([], defaultWeights()); @@ -69,20 +70,20 @@ describe("src/analysis/weightEvaluator", () => { describe("edgeEvaluator", () => { const foo = EdgeAddress.fromParts(["foo"]); const foobar = EdgeAddress.fromParts(["foo", "bar"]); - const fooType = { + const fooType = deepFreeze({ forwardName: "", backwardName: "", - defaultWeight: Object.freeze({forwards: 2, backwards: 3}), + defaultWeight: {forwards: 2, backwards: 3}, prefix: foo, description: "", - }; - const fooBarType = { + }); + const fooBarType = deepFreeze({ forwardName: "", backwardName: "", - defaultWeight: Object.freeze({forwards: 4, backwards: 5}), + defaultWeight: {forwards: 4, backwards: 5}, prefix: foobar, description: "", - }; + }); it("gives default 1,1 weights if no matching type", () => { const evaluator = edgeWeightEvaluator([], defaultWeights()); expect(evaluator(foo)).toEqual({forwards: 1, backwards: 1}); diff --git a/src/analysis/weightsToEdgeEvaluator.test.js b/src/analysis/weightsToEdgeEvaluator.test.js index dcf0f61..a27feb7 100644 --- a/src/analysis/weightsToEdgeEvaluator.test.js +++ b/src/analysis/weightsToEdgeEvaluator.test.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import {NodeAddress, EdgeAddress} from "../core/graph"; import {type Weights, defaultWeights} from "./weights"; import {weightsToEdgeEvaluator} from "./weightsToEdgeEvaluator"; @@ -14,7 +15,7 @@ describe("analysis/weightsToEdgeEvaluator", () => { timestampMs: 0, }; - const fallbackNodeType = Object.freeze({ + const fallbackNodeType = deepFreeze({ name: "", pluralName: "", prefix: NodeAddress.empty, @@ -22,7 +23,7 @@ describe("analysis/weightsToEdgeEvaluator", () => { description: "", }); - const srcNodeType = Object.freeze({ + const srcNodeType = deepFreeze({ name: "", pluralName: "", prefix: src, @@ -30,10 +31,10 @@ describe("analysis/weightsToEdgeEvaluator", () => { description: "", }); - const fallbackEdgeType = Object.freeze({ + const fallbackEdgeType = deepFreeze({ forwardName: "", backwardName: "", - defaultWeight: Object.freeze({forwards: 1, backwards: 1}), + defaultWeight: {forwards: 1, backwards: 1}, prefix: EdgeAddress.empty, description: "", }); diff --git a/src/cli/common.js b/src/cli/common.js index 0a73229..b81840f 100644 --- a/src/cli/common.js +++ b/src/cli/common.js @@ -3,12 +3,13 @@ import os from "os"; import path from "path"; +import deepFreeze from "deep-freeze"; import * as NullUtil from "../util/null"; export type PluginName = "git" | "github"; -export const defaultPlugins: PluginName[] = Object.freeze(["github"]); +export const defaultPlugins: PluginName[] = deepFreeze(["github"]); export function defaultSourcecredDirectory() { return path.join(os.tmpdir(), "sourcecred"); diff --git a/src/core/address.js b/src/core/address.js index 8171d5f..c80f705 100644 --- a/src/core/address.js +++ b/src/core/address.js @@ -1,6 +1,7 @@ // @flow import stringify from "json-stable-stringify"; +import deepFreeze from "deep-freeze"; import * as MapUtil from "../util/map"; @@ -233,5 +234,5 @@ export function makeAddressModule(options: Options): AddressModule { append, hasPrefix, }; - return Object.freeze(result); + return deepFreeze(result); } diff --git a/src/core/graph.js b/src/core/graph.js index 3ba5b81..fddc611 100644 --- a/src/core/graph.js +++ b/src/core/graph.js @@ -1,6 +1,7 @@ // @flow import deepEqual from "lodash.isequal"; +import deepFreeze from "deep-freeze"; import {makeAddressModule, type AddressModule} from "./address"; import {toCompat, fromCompat, type Compatible} from "../util/compat"; @@ -151,7 +152,7 @@ export const Direction: {| +IN: DirectionT, +OUT: DirectionT, +ANY: DirectionT, -|} = Object.freeze({ +|} = deepFreeze({ IN: Symbol("IN"), OUT: Symbol("OUT"), ANY: Symbol("ANY"), diff --git a/src/core/graphTestUtil.js b/src/core/graphTestUtil.js index cff3b1e..4f1e885 100644 --- a/src/core/graphTestUtil.js +++ b/src/core/graphTestUtil.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import {EdgeAddress, Graph, NodeAddress, type Node, type Edge} from "./graph"; /** @@ -12,11 +13,10 @@ import {EdgeAddress, Graph, NodeAddress, type Node, type Edge} from "./graph"; * the codebase. * * The returned node is frozen; as such, it is safe to re-use this exact - * object across test cases. If any non-primitive field is added to Node, - * please ensure this function freezes that field explicitly. + * object across test cases. */ export function partsNode(parts: string[]): Node { - return Object.freeze({ + return deepFreeze({ address: NodeAddress.fromParts(parts), description: parts.toString(), timestampMs: null, @@ -40,7 +40,7 @@ export function node(name: string): Node { * The returned edge is frozen, so it is safe to use across test cases. */ export function partsEdge(parts: string[], src: Node, dst: Node): Edge { - return Object.freeze({ + return deepFreeze({ address: EdgeAddress.fromParts(parts), src: src.address, dst: dst.address, diff --git a/src/core/project.test.js b/src/core/project.test.js index 982b1d4..4baf6d4 100644 --- a/src/core/project.test.js +++ b/src/core/project.test.js @@ -1,6 +1,7 @@ // @flow import base64url from "base64url"; +import deepFreeze from "deep-freeze"; import { projectToJSON, projectFromJSON, @@ -11,15 +12,15 @@ import { import {makeRepoId} from "./repoId"; describe("core/project", () => { - const foobar = Object.freeze(makeRepoId("foo", "bar")); - const foozod = Object.freeze(makeRepoId("foo", "zod")); - const p1: Project = Object.freeze({ + const foobar = deepFreeze(makeRepoId("foo", "bar")); + const foozod = deepFreeze(makeRepoId("foo", "zod")); + const p1: Project = deepFreeze({ id: "foo/bar", - repoIds: Object.freeze([foobar]), + repoIds: [foobar], }); - const p2: Project = Object.freeze({ + const p2: Project = deepFreeze({ id: "@foo", - repoIds: Object.freeze([foobar, foozod]), + repoIds: [foobar, foozod], }); describe("to/fro JSON", () => { it("round trip is identity", () => { diff --git a/src/core/project_io.test.js b/src/core/project_io.test.js index 5601fe3..1be7655 100644 --- a/src/core/project_io.test.js +++ b/src/core/project_io.test.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import tmp from "tmp"; import path from "path"; import fs from "fs-extra"; @@ -16,15 +17,15 @@ import { import {makeRepoId} from "./repoId"; describe("core/project_io", () => { - const foobar = Object.freeze(makeRepoId("foo", "bar")); - const foozod = Object.freeze(makeRepoId("foo", "zod")); - const p1: Project = Object.freeze({ + const foobar = deepFreeze(makeRepoId("foo", "bar")); + const foozod = deepFreeze(makeRepoId("foo", "zod")); + const p1: Project = deepFreeze({ id: "foo/bar", - repoIds: Object.freeze([foobar]), + repoIds: [foobar], }); - const p2: Project = Object.freeze({ + const p2: Project = deepFreeze({ id: "@foo", - repoIds: Object.freeze([foobar, foozod]), + repoIds: [foobar, foozod], }); it("setupProjectDirectory results in a loadable project", async () => { diff --git a/src/core/version.js b/src/core/version.js index 6bef850..59f024e 100644 --- a/src/core/version.js +++ b/src/core/version.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; export type VersionInfo = {| +major: number, +minor: number, @@ -24,10 +25,11 @@ export function parseGitState(raw: ?string): GitState { if (typeof raw !== "string") { throw new Error("gitState: not a string: " + String(raw)); } - const parsed: mixed = Object.freeze(JSON.parse(raw)); + const parsed: mixed = JSON.parse(raw); if (parsed == null || typeof parsed !== "object") { throw new Error("gitState: not a JSON object: " + String(parsed)); } + deepFreeze(parsed); // This intermediate variable helps out Flow's inference... const gitState: Object = parsed; if ( @@ -56,7 +58,7 @@ export function parseEnvironment(raw: ?string): Environment { } const environment = parseEnvironment(process.env.NODE_ENV); -export const VERSION_INFO: VersionInfo = Object.freeze({ +export const VERSION_INFO: VersionInfo = deepFreeze({ major: 0, minor: 3, patch: 0, diff --git a/src/explorer/legacy/pagerankTable/aggregate.js b/src/explorer/legacy/pagerankTable/aggregate.js index 32ff47b..9fea9e7 100644 --- a/src/explorer/legacy/pagerankTable/aggregate.js +++ b/src/explorer/legacy/pagerankTable/aggregate.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import sortBy from "lodash.sortby"; import stringify from "json-stable-stringify"; import * as MapUtil from "../../../util/map"; @@ -45,7 +46,7 @@ export type FlatAggregation = {| +connections: $ReadOnlyArray, |}; -export const fallbackNodeType: NodeType = Object.freeze({ +export const fallbackNodeType: NodeType = deepFreeze({ name: "node", pluralName: "nodes", prefix: NodeAddress.empty, @@ -53,10 +54,10 @@ export const fallbackNodeType: NodeType = Object.freeze({ description: "", }); -export const fallbackEdgeType: EdgeType = Object.freeze({ +export const fallbackEdgeType: EdgeType = deepFreeze({ forwardName: "has edge to", backwardName: "has edge from", - defaultWeight: Object.freeze({forwards: 1, backwards: 1}), + defaultWeight: {forwards: 1, backwards: 1}, prefix: EdgeAddress.empty, description: "", }); diff --git a/src/graphql/__snapshots__/generateFlowTypes.test.js.snap b/src/graphql/__snapshots__/generateFlowTypes.test.js.snap index cc3d22e..4ef9745 100644 --- a/src/graphql/__snapshots__/generateFlowTypes.test.js.snap +++ b/src/graphql/__snapshots__/generateFlowTypes.test.js.snap @@ -5,6 +5,8 @@ exports[`graphql/generateFlowTypes generateFlowTypes works on a representative s // Autogenerated file. Do not edit. +import deepFreeze from \\"deep-freeze\\"; + export type Actor = Human | TalentedChimpanzee; export type Color = \\"BLUE\\" | \\"GREEN\\" | \\"RED\\"; @@ -13,7 +15,7 @@ export const Color$Values: {| +BLUE: \\"BLUE\\", +GREEN: \\"GREEN\\", +RED: \\"RED\\", -|} = Object.freeze({ BLUE: \\"BLUE\\", GREEN: \\"GREEN\\", RED: \\"RED\\" }); +|} = deepFreeze({ BLUE: \\"BLUE\\", GREEN: \\"GREEN\\", RED: \\"RED\\" }); export type DateTime = string; @@ -21,7 +23,7 @@ export type Dollars = number; export type EmptyEnum = empty; -export const EmptyEnum$Values: {||} = Object.freeze({}); +export const EmptyEnum$Values: {||} = deepFreeze({}); export type EmptyUnion = empty; diff --git a/src/graphql/generateFlowTypes.js b/src/graphql/generateFlowTypes.js index 9381599..5b71d76 100644 --- a/src/graphql/generateFlowTypes.js +++ b/src/graphql/generateFlowTypes.js @@ -77,7 +77,7 @@ export default function generateFlowTypes( const typeRhs = values.length === 0 ? "empty" : values.join(" | "); definitions.push(`export type ${typename} = ${typeRhs};`); - // export const E$Values: {|+A: "A", +B: "B"|} = Object.freeze(...); + // export const E$Values: {|+A: "A", +B: "B"|} = deepFreeze(...); const objectName = `${typename}$Values`; const objectType = [ "{|", @@ -85,7 +85,7 @@ export default function generateFlowTypes( "|}", ].join(""); const objectValue = [ - "Object.freeze({", + "deepFreeze({", values.map((x) => `${x}: ${x}`).join(", "), "})", ].join(""); @@ -127,6 +127,7 @@ export default function generateFlowTypes( const rawSource = [ "// @flow", "// Autogenerated file. Do not edit.", + 'import deepFreeze from "deep-freeze"', ...definitions, ].join("\n\n"); return prettier.format(rawSource, prettierOptions); diff --git a/src/graphql/mirror.js b/src/graphql/mirror.js index a63e02c..ae68a74 100644 --- a/src/graphql/mirror.js +++ b/src/graphql/mirror.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import type Database, {BindingDictionary, Statement} from "better-sqlite3"; import stringify from "json-stable-stringify"; @@ -2038,7 +2039,7 @@ type UpdateResult = { +[string]: OwnDataUpdateResult | NodeConnectionsUpdateResult, }; -export const _FIELD_PREFIXES = Object.freeze({ +export const _FIELD_PREFIXES = deepFreeze({ /** * A key of an `UpdateResult` has this prefix if and only if the * corresponding value represents `OwnDataUpdateResult`s. diff --git a/src/plugins/defaultCredConfig.js b/src/plugins/defaultCredConfig.js index ef0c044..ceb87b7 100644 --- a/src/plugins/defaultCredConfig.js +++ b/src/plugins/defaultCredConfig.js @@ -1,13 +1,14 @@ // @flow +import deepFreeze from "deep-freeze"; import {userNodeType, repoNodeType, declaration} from "./github/declaration"; import type {TimelineCredConfig} from "../analysis/timeline/timelineCred"; -export const DEFAULT_CRED_CONFIG: TimelineCredConfig = { +export const DEFAULT_CRED_CONFIG: TimelineCredConfig = deepFreeze({ scoreNodePrefix: userNodeType.prefix, - filterNodePrefixes: Object.freeze([userNodeType.prefix, repoNodeType.prefix]), - types: Object.freeze({ - nodeTypes: Object.freeze(declaration.nodeTypes.slice()), - edgeTypes: Object.freeze(declaration.edgeTypes.slice()), - }), -}; + filterNodePrefixes: [userNodeType.prefix, repoNodeType.prefix], + types: { + nodeTypes: declaration.nodeTypes.slice(), + edgeTypes: declaration.edgeTypes.slice(), + }, +}); diff --git a/src/plugins/demo/declaration.js b/src/plugins/demo/declaration.js index b441004..1c1abcc 100644 --- a/src/plugins/demo/declaration.js +++ b/src/plugins/demo/declaration.js @@ -1,12 +1,12 @@ // @flow +import deepFreeze from "deep-freeze"; + import {NodeAddress, EdgeAddress} from "../../core/graph"; - import type {PluginDeclaration} from "../../analysis/pluginDeclaration"; - import type {EdgeType, NodeType} from "../../analysis/types"; -export const inserterNodeType: NodeType = Object.freeze({ +export const inserterNodeType: NodeType = deepFreeze({ name: "inserter", pluralName: "inserters", prefix: NodeAddress.fromParts(["factorio", "inserter"]), @@ -14,7 +14,7 @@ export const inserterNodeType: NodeType = Object.freeze({ description: "Nodes for Factorio inserter objects in demo plugin", }); -export const machineNodeType: NodeType = Object.freeze({ +export const machineNodeType: NodeType = deepFreeze({ name: "machine", pluralName: "machines", prefix: NodeAddress.fromParts(["factorio", "machine"]), @@ -22,7 +22,7 @@ export const machineNodeType: NodeType = Object.freeze({ description: "Nodes for Factorio machine objects in demo plugin", }); -export const assemblesEdgeType: EdgeType = Object.freeze({ +export const assemblesEdgeType: EdgeType = deepFreeze({ forwardName: "assembles", backwardName: "is assembled by", defaultWeight: {forwards: 2, backwards: 2 ** -2}, @@ -30,7 +30,7 @@ export const assemblesEdgeType: EdgeType = Object.freeze({ description: "Connects assembly machines to products they assemble.", }); -export const transportsEdgeType: EdgeType = Object.freeze({ +export const transportsEdgeType: EdgeType = deepFreeze({ forwardName: "transports", backwardName: "is transported by", defaultWeight: {forwards: 2, backwards: 2 ** -1}, @@ -38,10 +38,10 @@ export const transportsEdgeType: EdgeType = Object.freeze({ description: "Connects transporter belts to objects they transport.", }); -export const declaration: PluginDeclaration = Object.freeze({ +export const declaration: PluginDeclaration = deepFreeze({ name: "Factorio demo adapter", nodePrefix: NodeAddress.fromParts(["factorio"]), - nodeTypes: Object.freeze([inserterNodeType, machineNodeType]), + nodeTypes: [inserterNodeType, machineNodeType], edgePrefix: EdgeAddress.fromParts(["factorio"]), - edgeTypes: Object.freeze([assemblesEdgeType, transportsEdgeType]), + edgeTypes: [assemblesEdgeType, transportsEdgeType], }); diff --git a/src/plugins/demo/graph.js b/src/plugins/demo/graph.js index 75ed3de..fe8ce75 100644 --- a/src/plugins/demo/graph.js +++ b/src/plugins/demo/graph.js @@ -1,16 +1,17 @@ // @flow +import deepFreeze from "deep-freeze"; import {Graph} from "../../core/graph"; import {partsNode, partsEdge} from "../../core/graphTestUtil"; -export const nodes = Object.freeze({ +export const nodes = deepFreeze({ inserter1: partsNode(["factorio", "inserter", "1"]), machine1: partsNode(["factorio", "machine", "1"]), inserter2: partsNode(["factorio", "inserter", "2"]), machine2: partsNode(["factorio", "machine", "2"]), }); -export const edges = Object.freeze({ +export const edges = deepFreeze({ transports1: partsEdge( ["factorio", "transports", "1"], nodes.inserter1, diff --git a/src/plugins/git/declaration.js b/src/plugins/git/declaration.js index eb26d7a..a944e63 100644 --- a/src/plugins/git/declaration.js +++ b/src/plugins/git/declaration.js @@ -1,11 +1,12 @@ // @flow +import deepFreeze from "deep-freeze"; import type {PluginDeclaration} from "../../analysis/pluginDeclaration"; import type {NodeType} from "../../analysis/types"; import * as N from "./nodes"; import * as E from "./edges"; -const commitNodeType: NodeType = Object.freeze({ +const commitNodeType: NodeType = deepFreeze({ name: "Commit", pluralName: "Commits", prefix: N.Prefix.commit, @@ -13,7 +14,7 @@ const commitNodeType: NodeType = Object.freeze({ description: "NodeType representing a git commit", }); -const hasParentEdgeType = Object.freeze({ +const hasParentEdgeType = deepFreeze({ forwardName: "has parent", backwardName: "is parent of", prefix: E.Prefix.hasParent, @@ -21,10 +22,10 @@ const hasParentEdgeType = Object.freeze({ description: "Connects a Git commit to its parent commit(s).", }); -const nodeTypes = Object.freeze([commitNodeType]); -const edgeTypes = Object.freeze([hasParentEdgeType]); +const nodeTypes = deepFreeze([commitNodeType]); +const edgeTypes = deepFreeze([hasParentEdgeType]); -export const declaration: PluginDeclaration = Object.freeze({ +export const declaration: PluginDeclaration = deepFreeze({ name: "Git", nodePrefix: N.Prefix.base, edgePrefix: E.Prefix.base, diff --git a/src/plugins/git/edges.js b/src/plugins/git/edges.js index 2581b00..fd2a5ab 100644 --- a/src/plugins/git/edges.js +++ b/src/plugins/git/edges.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import { type Edge, type EdgeAddressT, @@ -21,7 +22,7 @@ function gitEdgeAddress(...parts: string[]): RawAddress { return EdgeAddress.append(GIT_PREFIX, ...parts); } -export const Prefix = Object.freeze({ +export const Prefix = deepFreeze({ base: GIT_PREFIX, hasParent: gitEdgeAddress(HAS_PARENT_TYPE), }); @@ -34,7 +35,7 @@ export type HasParentAddress = {| export type StructuredAddress = HasParentAddress; -export const createEdge = Object.freeze({ +export const createEdge = deepFreeze({ hasParent: ( child: GitNode.CommitAddress, parent: GitNode.CommitAddress, diff --git a/src/plugins/git/mergeRepository.test.js b/src/plugins/git/mergeRepository.test.js index d5f5bdf..4bb85c7 100644 --- a/src/plugins/git/mergeRepository.test.js +++ b/src/plugins/git/mergeRepository.test.js @@ -1,15 +1,16 @@ //@flow +import deepFreeze from "deep-freeze"; import {makeRepoId, repoIdToString, type RepoIdString} from "../../core/repoId"; import type {Repository} from "./types"; import {mergeRepository} from "./mergeRepository"; describe("plugins/git/mergeRepository", () => { describe("mergeRepository", () => { - const empty: Repository = Object.freeze({commits: {}, commitToRepoId: {}}); + const empty: Repository = deepFreeze({commits: {}, commitToRepoId: {}}); const repoId1 = repoIdToString(makeRepoId("repo", "1")); const repoId2 = repoIdToString(makeRepoId("repo", "2")); - const repository1: Repository = Object.freeze({ + const repository1: Repository = deepFreeze({ commits: { commit1: { hash: "commit1", @@ -31,7 +32,7 @@ describe("plugins/git/mergeRepository", () => { commit2: {[((repoId1: RepoIdString): any)]: true}, }, }); - const repository2: Repository = Object.freeze({ + const repository2: Repository = deepFreeze({ commits: { commit1: { hash: "commit1", @@ -89,7 +90,7 @@ describe("plugins/git/mergeRepository", () => { expect(mergeRepository([repository1, repository1])).toEqual(repository1); }); it("throws an error if merging a repository with conflicting commits", () => { - const conflictingRepository: Repository = Object.freeze({ + const conflictingRepository: Repository = deepFreeze({ commits: { commit1: { hash: "commit1", diff --git a/src/plugins/git/nodes.js b/src/plugins/git/nodes.js index 374dab1..8ebc6f2 100644 --- a/src/plugins/git/nodes.js +++ b/src/plugins/git/nodes.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import {NodeAddress, type NodeAddressT} from "../../core/graph"; import type {Hash} from "./types"; @@ -12,7 +13,7 @@ export function _gitAddress(...parts: string[]): RawAddress { export const COMMIT_TYPE: "COMMIT" = "COMMIT"; -export const Prefix = Object.freeze({ +export const Prefix = deepFreeze({ base: GIT_PREFIX, commit: _gitAddress(COMMIT_TYPE), }); diff --git a/src/plugins/git/render.test.js b/src/plugins/git/render.test.js index b5abe67..d98f220 100644 --- a/src/plugins/git/render.test.js +++ b/src/plugins/git/render.test.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import * as N from "./nodes"; import {shallow} from "enzyme"; import {description} from "./render"; @@ -48,7 +49,7 @@ describe("plugins/git/render", () => { createdAt: 123456789, parentHashes: [], }; - const exampleRepository: Repository = Object.freeze({ + const exampleRepository: Repository = deepFreeze({ commits: { zeroRepoCommit, singleRepoCommit, @@ -65,7 +66,7 @@ describe("plugins/git/render", () => { }, }); - const exampleGitGateway: GitGateway = Object.freeze({ + const exampleGitGateway: GitGateway = deepFreeze({ commitUrl(repo: RepoId, hash: Hash): URL { return repoIdToString(repo) + "/" + hash; }, diff --git a/src/plugins/github/blacklistedObjectIds.js b/src/plugins/github/blacklistedObjectIds.js index 48a88cf..72c0350 100644 --- a/src/plugins/github/blacklistedObjectIds.js +++ b/src/plugins/github/blacklistedObjectIds.js @@ -1,8 +1,9 @@ // @flow +import deepFreeze from "deep-freeze"; import type {ObjectId} from "../../graphql/schema"; -export const BLACKLISTED_IDS: $ReadOnlyArray = Object.freeze([ +export const BLACKLISTED_IDS: $ReadOnlyArray = deepFreeze([ // These are `Organization` nodes that are sometimes referenced in a // `User` context: in particular, as the author of a reaction. // See: https://gist.github.com/wchargin/a2b8561b81bcc932c84e493d2485ea8a diff --git a/src/plugins/github/declaration.js b/src/plugins/github/declaration.js index 801a9ed..1642e4c 100644 --- a/src/plugins/github/declaration.js +++ b/src/plugins/github/declaration.js @@ -1,11 +1,12 @@ // @flow +import deepFreeze from "deep-freeze"; import type {PluginDeclaration} from "../../analysis/pluginDeclaration"; import * as N from "./nodes"; import * as E from "./edges"; import dedent from "../../util/dedent"; -export const repoNodeType = Object.freeze({ +export const repoNodeType = deepFreeze({ name: "Repository", pluralName: "Repositories", prefix: N.Prefix.repo, @@ -13,7 +14,7 @@ export const repoNodeType = Object.freeze({ description: "NodeType for a GitHub repository", }); -const issueNodeType = Object.freeze({ +const issueNodeType = deepFreeze({ name: "Issue", pluralName: "Issues", prefix: N.Prefix.issue, @@ -21,7 +22,7 @@ const issueNodeType = Object.freeze({ description: "NodeType for a GitHub issue", }); -const pullNodeType = Object.freeze({ +const pullNodeType = deepFreeze({ name: "Pull request", pluralName: "Pull requests", prefix: N.Prefix.pull, @@ -29,7 +30,7 @@ const pullNodeType = Object.freeze({ description: "NodeType for a GitHub pull request", }); -const reviewNodeType = Object.freeze({ +const reviewNodeType = deepFreeze({ name: "Pull request review", pluralName: "Pull request reviews", prefix: N.Prefix.review, @@ -37,7 +38,7 @@ const reviewNodeType = Object.freeze({ description: "NodeType for a GitHub code review", }); -const commentNodeType = Object.freeze({ +const commentNodeType = deepFreeze({ name: "Comment", pluralName: "Comments", prefix: N.Prefix.comment, @@ -45,7 +46,7 @@ const commentNodeType = Object.freeze({ description: "NodeType for a GitHub comment", }); -const commitNodeType = Object.freeze({ +const commitNodeType = deepFreeze({ name: "Commit", pluralName: "Commits", prefix: N.Prefix.commit, @@ -54,7 +55,7 @@ const commitNodeType = Object.freeze({ "Represents a particular Git commit on GitHub, i.e. scoped to a particular repository", }); -export const userNodeType = Object.freeze({ +export const userNodeType = deepFreeze({ name: "User", pluralName: "Users", prefix: N.Prefix.user, @@ -62,7 +63,7 @@ export const userNodeType = Object.freeze({ description: "NodeType for a GitHub user", }); -const botNodeType = Object.freeze({ +const botNodeType = deepFreeze({ name: "Bot", pluralName: "Bots", prefix: N.Prefix.bot, @@ -70,7 +71,7 @@ const botNodeType = Object.freeze({ description: "NodeType for a GitHub bot account", }); -const nodeTypes = Object.freeze([ +const nodeTypes = deepFreeze([ repoNodeType, issueNodeType, pullNodeType, @@ -81,7 +82,7 @@ const nodeTypes = Object.freeze([ botNodeType, ]); -const authorsEdgeType = Object.freeze({ +const authorsEdgeType = deepFreeze({ forwardName: "authors", backwardName: "is authored by", defaultWeight: {forwards: 1 / 2, backwards: 1}, @@ -93,7 +94,7 @@ const authorsEdgeType = Object.freeze({ `, }); -const hasParentEdgeType = Object.freeze({ +const hasParentEdgeType = deepFreeze({ forwardName: "has parent", backwardName: "has child", defaultWeight: {forwards: 1, backwards: 1 / 4}, @@ -106,7 +107,7 @@ const hasParentEdgeType = Object.freeze({ `, }); -const mergedAsEdgeType = Object.freeze({ +const mergedAsEdgeType = deepFreeze({ forwardName: "merges", backwardName: "is merged by", defaultWeight: {forwards: 1 / 2, backwards: 1}, @@ -116,7 +117,7 @@ const mergedAsEdgeType = Object.freeze({ `, }); -const referencesEdgeType = Object.freeze({ +const referencesEdgeType = deepFreeze({ forwardName: "references", backwardName: "is referenced by", defaultWeight: {forwards: 1, backwards: 0}, @@ -130,7 +131,7 @@ const referencesEdgeType = Object.freeze({ `, }); -const reactsHeartEdgeType = Object.freeze({ +const reactsHeartEdgeType = deepFreeze({ forwardName: "reacted ❤️ to", backwardName: "got ❤️ from", defaultWeight: {forwards: 2, backwards: 0}, @@ -140,7 +141,7 @@ const reactsHeartEdgeType = Object.freeze({ `, }); -const reactsThumbsUpEdgeType = Object.freeze({ +const reactsThumbsUpEdgeType = deepFreeze({ forwardName: "reacted 👍 to", backwardName: "got 👍 from", defaultWeight: {forwards: 1, backwards: 0}, @@ -150,7 +151,7 @@ const reactsThumbsUpEdgeType = Object.freeze({ `, }); -const reactsHoorayEdgeType = Object.freeze({ +const reactsHoorayEdgeType = deepFreeze({ forwardName: "reacted 🎉 to", backwardName: "got 🎉 from", defaultWeight: {forwards: 4, backwards: 0}, @@ -160,7 +161,7 @@ const reactsHoorayEdgeType = Object.freeze({ `, }); -const reactsRocketEdgeType = Object.freeze({ +const reactsRocketEdgeType = deepFreeze({ forwardName: "reacted 🚀 to", backwardName: "got 🚀 from", defaultWeight: {forwards: 1, backwards: 0}, @@ -170,7 +171,7 @@ const reactsRocketEdgeType = Object.freeze({ `, }); -const correspondsToCommitEdgeType = Object.freeze({ +const correspondsToCommitEdgeType = deepFreeze({ forwardName: "corresponds to Git commit", backwardName: "merged on GitHub as", defaultWeight: {forwards: 1, backwards: 1}, @@ -180,7 +181,7 @@ const correspondsToCommitEdgeType = Object.freeze({ `, }); -const edgeTypes = Object.freeze([ +const edgeTypes = deepFreeze([ authorsEdgeType, hasParentEdgeType, mergedAsEdgeType, @@ -192,7 +193,7 @@ const edgeTypes = Object.freeze([ correspondsToCommitEdgeType, ]); -export const declaration: PluginDeclaration = Object.freeze({ +export const declaration: PluginDeclaration = deepFreeze({ name: "GitHub", nodePrefix: N.Prefix.base, edgePrefix: E.Prefix.base, diff --git a/src/plugins/github/edges.js b/src/plugins/github/edges.js index 0a7cfbe..6d47b4c 100644 --- a/src/plugins/github/edges.js +++ b/src/plugins/github/edges.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import { type Edge, type EdgeAddressT, @@ -31,7 +32,7 @@ function githubEdgeAddress(...parts: string[]): RawAddress { return EdgeAddress.append(GITHUB_PREFIX, ...parts); } -export const Prefix = Object.freeze({ +export const Prefix = deepFreeze({ base: GITHUB_PREFIX, authors: githubEdgeAddress(AUTHORS_TYPE), mergedAs: githubEdgeAddress(MERGED_AS_TYPE), @@ -82,7 +83,7 @@ export type StructuredAddress = | ReactsAddress | CorrespondsToCommitAddress; -export const createEdge = Object.freeze({ +export const createEdge = deepFreeze({ authors: ( author: GithubNode.UserlikeAddress, content: GithubNode.AuthorableAddress, diff --git a/src/plugins/github/graphqlTypes.js b/src/plugins/github/graphqlTypes.js index b354333..ea3f3f4 100644 --- a/src/plugins/github/graphqlTypes.js +++ b/src/plugins/github/graphqlTypes.js @@ -2,6 +2,8 @@ // Autogenerated file. Do not edit. +import deepFreeze from "deep-freeze"; + export type Actor = Bot | Organization | User; export type Blob = {| @@ -122,7 +124,7 @@ export const PullRequestReviewState$Values: {| +COMMENTED: "COMMENTED", +DISMISSED: "DISMISSED", +PENDING: "PENDING", -|} = Object.freeze({ +|} = deepFreeze({ APPROVED: "APPROVED", CHANGES_REQUESTED: "CHANGES_REQUESTED", COMMENTED: "COMMENTED", @@ -157,7 +159,7 @@ export const ReactionContent$Values: {| +ROCKET: "ROCKET", +THUMBS_DOWN: "THUMBS_DOWN", +THUMBS_UP: "THUMBS_UP", -|} = Object.freeze({ +|} = deepFreeze({ CONFUSED: "CONFUSED", EYES: "EYES", HEART: "HEART", diff --git a/src/plugins/github/nodes.js b/src/plugins/github/nodes.js index 4b77170..fdf9a49 100644 --- a/src/plugins/github/nodes.js +++ b/src/plugins/github/nodes.js @@ -1,5 +1,6 @@ // @flow +import deepFreeze from "deep-freeze"; import {NodeAddress, type NodeAddressT} from "../../core/graph"; export opaque type RawAddress: NodeAddressT = NodeAddressT; @@ -19,7 +20,7 @@ export const USERLIKE_TYPE: "USERLIKE" = "USERLIKE"; export const USER_SUBTYPE: "USER" = "USER"; export const BOT_SUBTYPE: "BOT" = "BOT"; -export const Prefix = Object.freeze({ +export const Prefix = deepFreeze({ base: GITHUB_PREFIX, repo: _githubAddress(REPO_TYPE), issue: _githubAddress(ISSUE_TYPE), diff --git a/src/webutil/Colors.js b/src/webutil/Colors.js index deb3931..abde054 100644 --- a/src/webutil/Colors.js +++ b/src/webutil/Colors.js @@ -1,15 +1,16 @@ // @flow +import deepFreeze from "deep-freeze"; export type HexColor = string; -export default (Object.freeze({ - brand: Object.freeze({ +export default (deepFreeze({ + brand: { medium: "#0872A2", dark: "#3A066A", - }), - accent: Object.freeze({ + }, + accent: { medium: "#FF3201", - }), + }, }): {| +brand: {| +medium: HexColor, diff --git a/yarn.lock b/yarn.lock index 27a0194..85c518c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2703,6 +2703,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-freeze@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/deep-freeze/-/deep-freeze-0.0.1.tgz#3a0b0005de18672819dfd38cd31f91179c893e84" + integrity sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ= + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"