diff --git a/src/plugins/identity/alias.js b/src/plugins/identity/alias.js index 846d6ee..f383a5f 100644 --- a/src/plugins/identity/alias.js +++ b/src/plugins/identity/alias.js @@ -3,11 +3,15 @@ import {type NodeAddressT} from "../../core/graph"; import {githubOwnerPattern} from "../github/repoId"; import {loginAddress as githubAddress} from "../github/nodes"; +import {userNodeType as githubUserType} from "../github/declaration"; import {userAddress as discourseAddress} from "../discourse/address"; +import {userNodeType as discourseUserType} from "../discourse/declaration"; +import {identityType} from "./declaration"; import { identityAddress, USERNAME_PATTERN as _VALID_IDENTITY_PATTERN, } from "./identity"; +import {NodeAddress} from "../../core/graph"; /** An Alias is a string specification of an identity within another plugin. * @@ -64,3 +68,29 @@ export function resolveAlias( throw new Error(`Unknown type for alias: ${alias}`); } } + +/** + * Attempt to convert a NodeAddressT to an Alias. + * + * If the provided node address corresponds to a known aliasing scheme, an + * alias will be returned. Otherwise, null is returned. Since it's possible + * that the node address is a valid user node address provided by a plugin that + * didn't update this alias registry, clients should endeavor to accomodate + * those addresses rather than erroring. + */ +export function toAlias(n: NodeAddressT): Alias | null { + const parts = NodeAddress.toParts(n); + const terminator = parts[parts.length - 1]; + const prefixes: Map = new Map([ + ["github", githubUserType.prefix], + ["discourse", discourseUserType.prefix], + ["sourcecred", identityType.prefix], + ]); + + for (const [prefix, nodePrefix] of prefixes.entries()) { + if (NodeAddress.hasPrefix(n, nodePrefix)) { + return `${prefix}/${terminator}`; + } + } + return null; +} diff --git a/src/plugins/identity/alias.test.js b/src/plugins/identity/alias.test.js index 8e37604..0ec2154 100644 --- a/src/plugins/identity/alias.test.js +++ b/src/plugins/identity/alias.test.js @@ -1,9 +1,10 @@ // @flow -import {resolveAlias} from "./alias"; +import {resolveAlias, toAlias} from "./alias"; import {loginAddress as githubAddress} from "../github/nodes"; import {userAddress as discourseAddress} from "../discourse/address"; import {identityAddress} from "./identity"; +import {NodeAddress} from "../../core/graph"; describe("src/plugins/identity/alias", () => { describe("resolveAlias", () => { @@ -90,4 +91,23 @@ describe("src/plugins/identity/alias", () => { }); }); }); + describe("toAlias", () => { + function checkRoundTrip(alias) { + const addr = resolveAlias(alias, "https://example.com"); + expect(toAlias(addr)).toEqual(alias); + } + it("works for a GitHub node address", () => { + checkRoundTrip("github/example"); + }); + it("works for a Discourse node address", () => { + checkRoundTrip("discourse/example"); + }); + it("works for a identity node address", () => { + checkRoundTrip("sourcecred/example"); + }); + it("returns null for an address without an aliasing scheme", () => { + const address = NodeAddress.fromParts(["sourcecred", "plugin", "foo"]); + expect(toAlias(address)).toEqual(null); + }); + }); });