Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: split global type module #63

Merged
merged 27 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b6861e2
refactor: move editor-version type and module
ComradeVanti Nov 25, 2023
361a900
doc: jsdoc for editor-version type
ComradeVanti Nov 25, 2023
e8d9c00
refactor: move pkg-info type and module
ComradeVanti Nov 25, 2023
6f5f7a2
doc: jsdoc for pkg-info
ComradeVanti Nov 25, 2023
ccf37e4
refactor: rename module
ComradeVanti Nov 25, 2023
eff5885
refactor: move upm-config types to own module
ComradeVanti Nov 25, 2023
a018176
doc: jsdoc for upm-config types
ComradeVanti Nov 25, 2023
94e82bd
refactor: extract constant
ComradeVanti Nov 25, 2023
b13ca1a
refactor: split UpmAuth type
ComradeVanti Nov 25, 2023
488c0ce
refactor: auth classification helpers
ComradeVanti Nov 25, 2023
6e4cf61
refactor: helpers for encoding/decoding basic auth
ComradeVanti Nov 25, 2023
006462b
refactor: helper for always-auth
ComradeVanti Nov 25, 2023
2d9941f
refactor: base64 helper functions
ComradeVanti Nov 25, 2023
1c753b1
fix: incorrect type name
ComradeVanti Nov 25, 2023
f870669
refactor: move type
ComradeVanti Nov 25, 2023
dc7ce76
fix: missing import
ComradeVanti Nov 25, 2023
65025fd
refactor: extract scoped-registry utilities
ComradeVanti Nov 25, 2023
20ccac6
refactor: make type local
ComradeVanti Nov 25, 2023
aa5b776
refactor: make type local
ComradeVanti Nov 25, 2023
d69ab34
refactor: make type local
ComradeVanti Nov 25, 2023
7d4ffbc
refactor: extract module
ComradeVanti Nov 25, 2023
8572967
refactor: move type to own module
ComradeVanti Nov 26, 2023
ecc5aeb
refactor: add prompt utilities
ComradeVanti Nov 26, 2023
4acba70
fix: type warning
ComradeVanti Nov 26, 2023
a0ab467
fix: outdated type
ComradeVanti Nov 26, 2023
8852071
refactor: cmd-option utility type
ComradeVanti Nov 27, 2023
5c6e64d
refactor: rename file
ComradeVanti Nov 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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