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
This commit is contained in:
Dandelion Mané 2019-07-21 16:05:21 +01:00
parent e4c96f3a18
commit 6bd7fe1154
31 changed files with 150 additions and 113 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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);
};

View File

@ -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});

View File

@ -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: "",
});

View File

@ -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");

View File

@ -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<string> {
append,
hasPrefix,
};
return Object.freeze(result);
return deepFreeze(result);
}

View File

@ -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"),

View File

@ -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,

View File

@ -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", () => {

View File

@ -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 () => {

View File

@ -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,

View File

@ -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<ScoredConnection>,
|};
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: "",
});

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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(),
},
});

View File

@ -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],
});

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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",

View File

@ -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),
});

View File

@ -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;
},

View File

@ -1,8 +1,9 @@
// @flow
import deepFreeze from "deep-freeze";
import type {ObjectId} from "../../graphql/schema";
export const BLACKLISTED_IDS: $ReadOnlyArray<ObjectId> = Object.freeze([
export const BLACKLISTED_IDS: $ReadOnlyArray<ObjectId> = 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

View File

@ -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,

View File

@ -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,

View File

@ -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",

View File

@ -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),

View File

@ -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,

View File

@ -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"