Skip to content

Commit

Permalink
refactor: split global type module (#63)
Browse files Browse the repository at this point in the history
* refactor: move editor-version type and module

Move editor-version type into corresponding module and move that module into the types folder

* doc: jsdoc for editor-version type

* refactor: move pkg-info type and module

Move pkg-info type into corresponding module. Also move that module into types folder.

* doc: jsdoc for pkg-info

* refactor: rename module

Rename upm-config to upm-config-io. This is in preparation for moving the UpmConfig type and functions which act on it into own module which should be called upm-config

* refactor: move upm-config types to own module

This will be  its own module so that it can also contain helpers related to the type which do not involve io

* doc: jsdoc for upm-config types

* refactor: extract constant

* refactor: split UpmAuth type

Split into multiple types in preparation for further refactors

* refactor: auth classification helpers

* refactor: helpers for encoding/decoding basic auth

* refactor: helper for always-auth

* refactor: base64 helper functions

* fix: incorrect type name

* refactor: move type

Move env type into corresponding module

* fix: missing import

* refactor: extract scoped-registry utilities

Move ScopedRegistry type to own module and add utility functions with tests

* refactor: make type local

* refactor: make type local

* refactor: make type local

* refactor: extract module

Move PkgManifest type to own module and create helper functions with tests. Also rename the manifest file and corresponding test file to pkg-manifest-io since that is what the module is there for

* refactor: move type to own module

Also add type documentation where I knew what to write

* refactor: add prompt utilities

* fix: type warning

* fix: outdated type

* refactor: cmd-option utility type

* refactor: rename file
  • Loading branch information
ComradeVanti authored Dec 12, 2023
1 parent 613168e commit bb1c999
Show file tree
Hide file tree
Showing 37 changed files with 923 additions and 316 deletions.
51 changes: 19 additions & 32 deletions src/cmd-add.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import log from "./logger";
import url from "url";
import { isPackageUrl } from "./types/package-url";
import { GlobalOptions, ScopedRegistry } from "./types/global";
import { tryGetLatestVersion } from "./utils/pkg-info";
import { loadManifest, saveManifest } from "./utils/manifest";
import { tryGetLatestVersion } from "./types/pkg-info";
import { loadManifest, saveManifest } from "./utils/pkg-manifest-io";
import { env, parseEnv } from "./utils/env";
import {
compareEditorVersion,
tryParseEditorVersion,
} from "./utils/editor-version";
} from "./types/editor-version";
import { fetchPackageDependencies, fetchPackageInfo } from "./registry-client";
import { DomainName, isDomainName } from "./types/domain-name";
import { SemanticVersion } from "./types/semantic-version";
Expand All @@ -17,12 +16,19 @@ import {
PackageReference,
splitPackageReference,
} from "./types/package-reference";
import { scopedRegistry } from "./types/scoped-registry";
import {
addDependency,
addScopedRegistry,
addTestable,
tryGetScopedRegistryByUrl,
} from "./types/pkg-manifest";
import { CmdOptions } from "./types/options";

export type AddOptions = {
export type AddOptions = CmdOptions<{
test?: boolean;
force?: boolean;
_global: GlobalOptions;
};
}>;

type ResultCode = 0 | 1;

Expand Down Expand Up @@ -76,10 +82,6 @@ const _add = async function ({
// load manifest
const manifest = loadManifest();
if (manifest === null) return { code: 1, dirty };
// ensure manifest.dependencies
if (!manifest.dependencies) {
manifest.dependencies = {};
}
// packages that added to scope registry
const pkgsInScope: DomainName[] = [];
if (version === undefined || !isPackageUrl(version)) {
Expand Down Expand Up @@ -196,7 +198,7 @@ const _add = async function ({
}
// add to dependencies
const oldVersion = manifest.dependencies[name];
manifest.dependencies[name] = version;
addDependency(manifest, name, version);
if (!oldVersion) {
// Log the added package
log.notice("manifest", `added ${packageReference(name, version)}`);
Expand All @@ -215,22 +217,14 @@ const _add = async function ({
manifest.scopedRegistries = [];
dirty = true;
}
const filterEntry = (x: ScopedRegistry): boolean => {
let addr = x.url || "";
if (addr.endsWith("/")) addr = addr.slice(0, -1);
return addr == env.registry;
};
if (manifest.scopedRegistries.filter(filterEntry).length <= 0) {
let entry = tryGetScopedRegistryByUrl(manifest, env.registry);
if (entry === null) {
const name = url.parse(env.registry).hostname;
if (name === null) throw new Error("Could not resolve registry name");
manifest.scopedRegistries.push({
name,
url: env.registry,
scopes: [],
});
entry = scopedRegistry(name, env.registry);
addScopedRegistry(manifest, entry);
dirty = true;
}
const entry = manifest.scopedRegistries.filter(filterEntry)[0];
// apply pkgsInScope
const scopesSet = new Set(entry.scopes || []);
if (isDomainName(env.namespace)) pkgsInScope.push(env.namespace);
Expand All @@ -242,14 +236,7 @@ const _add = async function ({
});
entry.scopes = Array.from(scopesSet).sort();
}
if (testables) {
if (!manifest.testables) {
manifest.testables = [];
}
if (manifest.testables.indexOf(name) === -1) {
manifest.testables.push(name);
}
}
if (testables) addTestable(manifest, name);
// save manifest
if (dirty) {
if (!saveManifest(manifest)) return { code: 1, dirty };
Expand Down
7 changes: 3 additions & 4 deletions src/cmd-deps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import log from "./logger";
import { GlobalOptions } from "./types/global";
import { parseEnv } from "./utils/env";
import { fetchPackageDependencies } from "./registry-client";
import { DomainName } from "./types/domain-name";
Expand All @@ -10,11 +9,11 @@ import {
splitPackageReference,
VersionReference,
} from "./types/package-reference";
import { CmdOptions } from "./types/options";

export type DepsOptions = {
export type DepsOptions = CmdOptions<{
deep?: boolean;
_global: GlobalOptions;
};
}>;

export const deps = async function (
pkg: PackageReference,
Expand Down
42 changes: 19 additions & 23 deletions src/cmd-login.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
import fs from "fs";
import path from "path";
import _ from "lodash";
import promptly from "promptly";
import { assertIsNpmClientError, getNpmClient } from "./registry-client";

import log from "./logger";

import { GlobalOptions } from "./types/global";
import {
getUpmConfigDir,
loadUpmConfig,
saveUpmConfig,
} from "./utils/upm-config";
} from "./utils/upm-config-io";
import { parseEnv } from "./utils/env";
import { encodeBasicAuth } from "./types/upm-config";
import { Base64 } from "./types/base64";
import { RegistryUrl, removeTrailingSlash } from "./types/registry-url";
import {
RegistryUrl,
registryUrl,
removeTrailingSlash,
} from "./types/registry-url";
promptEmail,
promptPassword,
promptRegistryUrl,
promptUsername,
} from "./utils/prompts";
import { CmdOptions } from "./types/options";

export type LoginOptions = {
export type LoginOptions = CmdOptions<{
username?: string;
password?: string;
email?: string;
basicAuth?: boolean;
alwaysAuth?: boolean;
_global: GlobalOptions;
};
}>;

export const login = async function (options: LoginOptions) {
// parse env
const envOk = await parseEnv(options, { checkPath: false });
if (!envOk) return 1;
// query parameters
if (!options.username) options.username = await promptly.prompt("Username: ");
if (!options.password)
options.password = await promptly.password("Password: ");
if (!options.email) options.email = await promptly.prompt("Email: ");
if (!options.username) options.username = await promptUsername();
if (!options.password) options.password = await promptPassword();
if (!options.email) options.email = await promptEmail();
if (!options._global.registry)
options._global.registry = (await promptly.prompt("Registry: ", {
validator: [registryUrl],
})) as RegistryUrl;
options._global.registry = await promptRegistryUrl();
let token: string | null = null;
let _auth: string | null = null;
let _auth: Base64 | null = null;
if (options.basicAuth) {
// basic auth
const userPass = `${options.username}:${options.password}`;
_auth = Buffer.from(userPass).toString("base64");
_auth = encodeBasicAuth(options.username, options.password);
} else {
// npm login
const result = await npmLogin({
Expand Down Expand Up @@ -205,7 +201,7 @@ const writeUnityToken = async function ({
registry,
token,
}: {
_auth: string | null;
_auth: Base64 | null;
alwaysAuth: boolean;
basicAuth: boolean;
email: string;
Expand Down
53 changes: 22 additions & 31 deletions src/cmd-remove.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import log from "./logger";
import { GlobalOptions, ScopedRegistry } from "./types/global";
import { loadManifest, saveManifest } from "./utils/manifest";
import { loadManifest, saveManifest } from "./utils/pkg-manifest-io";
import { env, parseEnv } from "./utils/env";
import { isDomainName } from "./types/domain-name";
import {
packageReference,
PackageReference,
splitPackageReference,
} from "./types/package-reference";
import { hasScope, removeScope } from "./types/scoped-registry";
import {
removeDependency,
tryGetScopedRegistryByUrl,
} from "./types/pkg-manifest";
import { CmdOptions } from "./types/options";

export type RemoveOptions = {
_global: GlobalOptions;
};
export type RemoveOptions = CmdOptions;

export const remove = async function (
pkgs: PackageReference[] | PackageReference,
Expand Down Expand Up @@ -53,33 +56,21 @@ const _remove = async function (pkg: PackageReference) {
if (manifest === null) return { code: 1, dirty };
// not found array
const pkgsNotFound = [];
// remove from dependencies
if (manifest.dependencies) {
version = manifest.dependencies[name];
if (version) {
log.notice("manifest", `removed ${packageReference(name, version)}`);
delete manifest.dependencies[name];
version = manifest.dependencies[name];
if (version) {
log.notice("manifest", `removed ${packageReference(name, version)}`);
removeDependency(manifest, name);
dirty = true;
} else pkgsNotFound.push(pkg);

const entry = tryGetScopedRegistryByUrl(manifest, env.registry);
if (entry !== null) {
if (hasScope(entry, name)) {
removeScope(entry, name);
const scopesSet = new Set(entry.scopes);
if (isDomainName(env.namespace)) scopesSet.add(env.namespace);
entry.scopes = Array.from(scopesSet).sort();
dirty = true;
} else pkgsNotFound.push(pkg);
}
// remove from scopedRegistries
if (manifest.scopedRegistries) {
const filterEntry = (x: ScopedRegistry) => {
let url = x.url || "";
if (url.endsWith("/")) url = url.slice(0, -1);
return url == env.registry;
};
const entires = manifest.scopedRegistries.filter(filterEntry);
if (entires.length > 0) {
const entry = entires[0];
const index = entry.scopes.indexOf(name);
if (index > -1) {
entry.scopes.splice(index, 1);
const scopesSet = new Set(entry.scopes);
if (isDomainName(env.namespace)) scopesSet.add(env.namespace);
entry.scopes = Array.from(scopesSet).sort();
dirty = true;
}
}
}
// save manifest
Expand Down
8 changes: 3 additions & 5 deletions src/cmd-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ import log from "./logger";
import { is404Error, isHttpError } from "./utils/error-type-guards";
import * as os from "os";
import assert from "assert";
import { GlobalOptions, PkgInfo } from "./types/global";
import { tryGetLatestVersion } from "./utils/pkg-info";
import { PkgInfo, tryGetLatestVersion } from "./types/pkg-info";
import { env, parseEnv } from "./utils/env";
import { DomainName } from "./types/domain-name";
import { SemanticVersion } from "./types/semantic-version";
import { RegistryUrl } from "./types/registry-url";
import { CmdOptions } from "./types/options";

type DateString = string;

type TableRow = [DomainName, SemanticVersion, DateString, ""];

export type SearchOptions = {
_global: GlobalOptions;
};
export type SearchOptions = CmdOptions;

export type SearchedPkgInfo = Omit<PkgInfo, "versions"> & {
versions: Record<SemanticVersion, "latest">;
Expand Down
8 changes: 3 additions & 5 deletions src/cmd-view.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import chalk from "chalk";
import log from "./logger";
import assert from "assert";
import { GlobalOptions, PkgInfo } from "./types/global";
import { tryGetLatestVersion } from "./utils/pkg-info";
import { PkgInfo, tryGetLatestVersion } from "./types/pkg-info";
import { env, parseEnv } from "./utils/env";
import { fetchPackageInfo } from "./registry-client";
import { DomainName } from "./types/domain-name";
Expand All @@ -11,10 +10,9 @@ import {
PackageReference,
splitPackageReference,
} from "./types/package-reference";
import { CmdOptions } from "./types/options";

export type ViewOptions = {
_global: GlobalOptions;
};
export type ViewOptions = CmdOptions;

export const view = async function (
pkg: PackageReference,
Expand Down
19 changes: 17 additions & 2 deletions src/registry-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import RegClient, {
import log from "./logger";
import request from "request";
import assert, { AssertionError } from "assert";
import { Dependency, NameVersionPair, PkgInfo } from "./types/global";
import { env } from "./utils/env";
import _ from "lodash";
import { tryGetLatestVersion } from "./utils/pkg-info";
import { PkgInfo, tryGetLatestVersion } from "./types/pkg-info";
import { DomainName, isInternalPackage } from "./types/domain-name";
import { SemanticVersion } from "./types/semantic-version";
import { packageReference } from "./types/package-reference";
Expand Down Expand Up @@ -44,6 +43,21 @@ export class NpmClientError extends Error {
}
}

export type Dependency = {
name: DomainName;
version?: SemanticVersion;
upstream: boolean;
self: boolean;
internal: boolean;
reason: string | null;
resolved?: boolean;
};

type NameVersionPair = {
name: DomainName;
version: SemanticVersion | "latest" | undefined;
};

export function assertIsNpmClientError(
x: unknown
): asserts x is NpmClientError {
Expand Down Expand Up @@ -103,6 +117,7 @@ export const fetchPackageInfo = async function (
// eslint-disable-next-line no-empty
} catch (err) {}
};

/* Fetch package [valid dependencies, invalid dependencies] with a structure of
[
{
Expand Down
3 changes: 2 additions & 1 deletion src/types/another-npm-registry-client.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Response } from "request";
import { PkgInfo } from "./global";

import { PkgInfo } from "./pkg-info";

declare module "another-npm-registry-client" {
export type NpmAuth =
Expand Down
20 changes: 20 additions & 0 deletions src/types/base64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Brand } from "ts-brand";

export type Base64 = Brand<string, "Base64">;

/**
* Encodes a string using base64
* @param s The string
*/
export function encodeBase64(s: string): Base64 {
return Buffer.from(s).toString("base64") as Base64;
}

/**
* Decodes a base64 string
* @param base64 The string
*/
export function decodeBase64(base64: Base64): string {
const buffer = Buffer.from(base64, "base64");
return buffer.toString("utf-8");
}
Loading

0 comments on commit bb1c999

Please sign in to comment.