@gadgetinc/ggt 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -76
- package/bin/dev.js +4 -7
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/deploy.js +227 -0
- package/lib/commands/deploy.js.map +1 -0
- package/lib/commands/list.js +20 -16
- package/lib/commands/list.js.map +1 -1
- package/lib/commands/login.js +22 -20
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/logout.js +13 -9
- package/lib/commands/logout.js.map +1 -1
- package/lib/commands/root.js +89 -56
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/sync.js +253 -496
- package/lib/commands/sync.js.map +1 -1
- package/lib/commands/version.js +21 -0
- package/lib/commands/version.js.map +1 -0
- package/lib/commands/whoami.js +15 -11
- package/lib/commands/whoami.js.map +1 -1
- package/lib/main.js +4 -10
- package/lib/main.js.map +1 -1
- package/lib/services/{app.js → app/app.js} +8 -3
- package/lib/services/app/app.js.map +1 -0
- package/lib/services/app/arg.js +28 -0
- package/lib/services/app/arg.js.map +1 -0
- package/lib/services/app/edit-graphql.js +389 -0
- package/lib/services/app/edit-graphql.js.map +1 -0
- package/lib/services/command/arg.js +53 -0
- package/lib/services/command/arg.js.map +1 -0
- package/lib/services/command/command.js +27 -0
- package/lib/services/command/command.js.map +1 -0
- package/lib/services/command/context.js +60 -0
- package/lib/services/command/context.js.map +1 -0
- package/lib/services/{config.js → config/config.js} +29 -31
- package/lib/services/config/config.js.map +1 -0
- package/lib/services/config/env.js +22 -0
- package/lib/services/config/env.js.map +1 -0
- package/lib/services/config/package-json.js +9 -0
- package/lib/services/config/package-json.js.map +1 -0
- package/lib/services/filesync/changes.js +97 -0
- package/lib/services/filesync/changes.js.map +1 -0
- package/lib/services/filesync/conflicts.js +137 -0
- package/lib/services/filesync/conflicts.js.map +1 -0
- package/lib/services/filesync/directory.js +253 -0
- package/lib/services/filesync/directory.js.map +1 -0
- package/lib/services/filesync/error.js +67 -0
- package/lib/services/filesync/error.js.map +1 -0
- package/lib/services/filesync/file.js +3 -0
- package/lib/services/filesync/file.js.map +1 -0
- package/lib/services/filesync/filesync.js +675 -0
- package/lib/services/filesync/filesync.js.map +1 -0
- package/lib/services/filesync/hashes.js +150 -0
- package/lib/services/filesync/hashes.js.map +1 -0
- package/lib/services/http/auth.js +41 -0
- package/lib/services/http/auth.js.map +1 -0
- package/lib/services/http/http.js +64 -0
- package/lib/services/http/http.js.map +1 -0
- package/lib/services/output/log/field.js +3 -0
- package/lib/services/output/log/field.js.map +1 -0
- package/lib/services/output/log/format/format.js +8 -0
- package/lib/services/output/log/format/format.js.map +1 -0
- package/lib/services/output/log/format/json.js +45 -0
- package/lib/services/output/log/format/json.js.map +1 -0
- package/lib/services/output/log/format/pretty.js +147 -0
- package/lib/services/output/log/format/pretty.js.map +1 -0
- package/lib/services/output/log/level.js +41 -0
- package/lib/services/output/log/level.js.map +1 -0
- package/lib/services/output/log/logger.js +40 -0
- package/lib/services/output/log/logger.js.map +1 -0
- package/lib/services/output/log/printer.js +120 -0
- package/lib/services/output/log/printer.js.map +1 -0
- package/lib/services/output/log/structured.js +52 -0
- package/lib/services/output/log/structured.js.map +1 -0
- package/lib/services/{notify.js → output/notify.js} +7 -6
- package/lib/services/output/notify.js.map +1 -0
- package/lib/services/output/prompt.js +52 -0
- package/lib/services/output/prompt.js.map +1 -0
- package/lib/services/output/report.js +162 -0
- package/lib/services/output/report.js.map +1 -0
- package/lib/services/output/sprint.js +21 -0
- package/lib/services/output/sprint.js.map +1 -0
- package/lib/services/output/stream.js +54 -0
- package/lib/services/output/stream.js.map +1 -0
- package/lib/services/{version.js → output/update.js} +24 -16
- package/lib/services/output/update.js.map +1 -0
- package/lib/services/user/session.js +50 -0
- package/lib/services/user/session.js.map +1 -0
- package/lib/services/{user.js → user/user.js} +23 -14
- package/lib/services/user/user.js.map +1 -0
- package/lib/services/util/boolean.js +15 -0
- package/lib/services/util/boolean.js.map +1 -0
- package/lib/services/util/collection.js +38 -0
- package/lib/services/util/collection.js.map +1 -0
- package/lib/services/util/function.js +97 -0
- package/lib/services/util/function.js.map +1 -0
- package/lib/services/{is.js → util/is.js} +7 -0
- package/lib/services/util/is.js.map +1 -0
- package/lib/services/util/number.js +27 -0
- package/lib/services/util/number.js.map +1 -0
- package/lib/services/util/object.js +101 -0
- package/lib/services/util/object.js.map +1 -0
- package/lib/services/util/paths.js +36 -0
- package/lib/services/util/paths.js.map +1 -0
- package/lib/services/{promise.js → util/promise.js} +5 -7
- package/lib/services/util/promise.js.map +1 -0
- package/npm-shrinkwrap.json +2143 -1304
- package/package.json +50 -42
- package/lib/commands/index.js +0 -9
- package/lib/commands/index.js.map +0 -1
- package/lib/services/app.js.map +0 -1
- package/lib/services/args.js +0 -28
- package/lib/services/args.js.map +0 -1
- package/lib/services/collections.js +0 -17
- package/lib/services/collections.js.map +0 -1
- package/lib/services/config.js.map +0 -1
- package/lib/services/debounce.js +0 -21
- package/lib/services/debounce.js.map +0 -1
- package/lib/services/defaults.js +0 -8
- package/lib/services/defaults.js.map +0 -1
- package/lib/services/edit-graphql.js +0 -202
- package/lib/services/edit-graphql.js.map +0 -1
- package/lib/services/errors.js +0 -277
- package/lib/services/errors.js.map +0 -1
- package/lib/services/filesync.js +0 -404
- package/lib/services/filesync.js.map +0 -1
- package/lib/services/fs.js +0 -35
- package/lib/services/fs.js.map +0 -1
- package/lib/services/http.js +0 -53
- package/lib/services/http.js.map +0 -1
- package/lib/services/is.js.map +0 -1
- package/lib/services/log.js +0 -45
- package/lib/services/log.js.map +0 -1
- package/lib/services/noop.js +0 -4
- package/lib/services/noop.js.map +0 -1
- package/lib/services/notify.js.map +0 -1
- package/lib/services/output.js +0 -74
- package/lib/services/output.js.map +0 -1
- package/lib/services/promise.js.map +0 -1
- package/lib/services/prompt.js +0 -22
- package/lib/services/prompt.js.map +0 -1
- package/lib/services/session.js +0 -31
- package/lib/services/session.js.map +0 -1
- package/lib/services/sleep.js +0 -21
- package/lib/services/sleep.js.map +0 -1
- package/lib/services/timeout.js +0 -8
- package/lib/services/timeout.js.map +0 -1
- package/lib/services/user.js.map +0 -1
- package/lib/services/version.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { env } from "../config/env.js";
|
|
4
|
+
import { isObject } from "../util/is.js";
|
|
5
|
+
/**
|
|
6
|
+
* A wrapper around process.stdout and process.stderr that allows us to mock out the streams for testing.
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/oclif/core/blob/16139fe8a7f991b4b446a1599ab63f15d9809b8e/src/cli-ux/stream.ts
|
|
9
|
+
*/ export class Stream {
|
|
10
|
+
get isTTY() {
|
|
11
|
+
return process[this.channel].isTTY;
|
|
12
|
+
}
|
|
13
|
+
getWindowSize() {
|
|
14
|
+
return process[this.channel].getWindowSize();
|
|
15
|
+
}
|
|
16
|
+
write(data) {
|
|
17
|
+
if (env.testLike) {
|
|
18
|
+
// use console.log/error in tests since vitest doesn't display
|
|
19
|
+
// process.stdout/stderr correctly; also, remove trailing newline
|
|
20
|
+
// since console.log/error adds one.
|
|
21
|
+
data = data.replace(/\n$/, "");
|
|
22
|
+
if (this.channel === "stdout") {
|
|
23
|
+
console.log(data);
|
|
24
|
+
} else {
|
|
25
|
+
console.error(data);
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
} else {
|
|
29
|
+
return process[this.channel].write(data);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
on(event, listener) {
|
|
33
|
+
process[this.channel].on(event, listener);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
once(event, listener) {
|
|
37
|
+
process[this.channel].once(event, listener);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
constructor(channel){
|
|
41
|
+
_define_property(this, "channel", void 0);
|
|
42
|
+
this.channel = channel;
|
|
43
|
+
process[this.channel].on("error", (err)=>{
|
|
44
|
+
if (isObject(err) && "code" in err && err.code === "EPIPE") {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
throw err;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const stdout = new Stream("stdout");
|
|
52
|
+
export const stderr = new Stream("stderr");
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/stream.ts"],"sourcesContent":["import process from \"node:process\";\nimport { env } from \"../config/env.js\";\nimport { isObject } from \"../util/is.js\";\n\n/**\n * A wrapper around process.stdout and process.stderr that allows us to mock out the streams for testing.\n *\n * @see https://github.com/oclif/core/blob/16139fe8a7f991b4b446a1599ab63f15d9809b8e/src/cli-ux/stream.ts\n */\nexport class Stream {\n public constructor(public channel: \"stdout\" | \"stderr\") {\n process[this.channel].on(\"error\", (err: unknown) => {\n if (isObject(err) && \"code\" in err && err.code === \"EPIPE\") {\n return;\n }\n throw err;\n });\n }\n\n public get isTTY(): boolean {\n return process[this.channel].isTTY;\n }\n\n public getWindowSize(): number[] {\n return process[this.channel].getWindowSize();\n }\n\n public write(data: string): boolean {\n if (env.testLike) {\n // use console.log/error in tests since vitest doesn't display\n // process.stdout/stderr correctly; also, remove trailing newline\n // since console.log/error adds one.\n data = data.replace(/\\n$/, \"\");\n if (this.channel === \"stdout\") {\n console.log(data);\n } else {\n console.error(data);\n }\n return true;\n } else {\n return process[this.channel].write(data);\n }\n }\n\n public on(event: string, listener: (...args: unknown[]) => void): this {\n process[this.channel].on(event, listener);\n return this;\n }\n\n public once(event: string, listener: (...args: unknown[]) => void): this {\n process[this.channel].once(event, listener);\n return this;\n }\n}\n\nexport const stdout = new Stream(\"stdout\");\nexport const stderr = new Stream(\"stderr\");\n"],"names":["process","env","isObject","Stream","isTTY","channel","getWindowSize","write","data","testLike","replace","console","log","error","on","event","listener","once","err","code","stdout","stderr"],"mappings":";AAAA,OAAOA,aAAa,eAAe;AACnC,SAASC,GAAG,QAAQ,mBAAmB;AACvC,SAASC,QAAQ,QAAQ,gBAAgB;AAEzC;;;;CAIC,GACD,OAAO,MAAMC;IAUX,IAAWC,QAAiB;QAC1B,OAAOJ,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACD,KAAK;IACpC;IAEOE,gBAA0B;QAC/B,OAAON,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACC,aAAa;IAC5C;IAEOC,MAAMC,IAAY,EAAW;QAClC,IAAIP,IAAIQ,QAAQ,EAAE;YAChB,8DAA8D;YAC9D,iEAAiE;YACjE,oCAAoC;YACpCD,OAAOA,KAAKE,OAAO,CAAC,OAAO;YAC3B,IAAI,IAAI,CAACL,OAAO,KAAK,UAAU;gBAC7BM,QAAQC,GAAG,CAACJ;YACd,OAAO;gBACLG,QAAQE,KAAK,CAACL;YAChB;YACA,OAAO;QACT,OAAO;YACL,OAAOR,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACE,KAAK,CAACC;QACrC;IACF;IAEOM,GAAGC,KAAa,EAAEC,QAAsC,EAAQ;QACrEhB,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACS,EAAE,CAACC,OAAOC;QAChC,OAAO,IAAI;IACb;IAEOC,KAAKF,KAAa,EAAEC,QAAsC,EAAQ;QACvEhB,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACY,IAAI,CAACF,OAAOC;QAClC,OAAO,IAAI;IACb;IA1CA,YAAmB,AAAOX,OAA4B,CAAE;;aAA9BA,UAAAA;QACxBL,OAAO,CAAC,IAAI,CAACK,OAAO,CAAC,CAACS,EAAE,CAAC,SAAS,CAACI;YACjC,IAAIhB,SAASgB,QAAQ,UAAUA,OAAOA,IAAIC,IAAI,KAAK,SAAS;gBAC1D;YACF;YACA,MAAMD;QACR;IACF;AAoCF;AAEA,OAAO,MAAME,SAAS,IAAIjB,OAAO,UAAU;AAC3C,OAAO,MAAMkB,SAAS,IAAIlB,OAAO,UAAU"}
|
|
@@ -6,12 +6,20 @@ import assert from "node:assert";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import semver from "semver";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
-
import { config } from "
|
|
10
|
-
import { http } from "
|
|
11
|
-
import { createLogger } from "./log.js";
|
|
12
|
-
import {
|
|
13
|
-
const log = createLogger(
|
|
9
|
+
import { config } from "../config/config.js";
|
|
10
|
+
import { http } from "../http/http.js";
|
|
11
|
+
import { createLogger } from "./log/logger.js";
|
|
12
|
+
import { sprint } from "./sprint.js";
|
|
13
|
+
const log = createLogger({
|
|
14
|
+
name: "update"
|
|
15
|
+
});
|
|
14
16
|
const UPDATE_CHECK_FREQUENCY = ms("12 hours");
|
|
17
|
+
const Registry = z.object({
|
|
18
|
+
name: z.literal("ggt"),
|
|
19
|
+
"dist-tags": z.object({
|
|
20
|
+
latest: z.string()
|
|
21
|
+
})
|
|
22
|
+
});
|
|
15
23
|
export const getDistTags = async ()=>{
|
|
16
24
|
const json = await http({
|
|
17
25
|
method: "GET",
|
|
@@ -22,24 +30,24 @@ export const getDistTags = async ()=>{
|
|
|
22
30
|
request: ms("5s")
|
|
23
31
|
}
|
|
24
32
|
});
|
|
25
|
-
|
|
26
|
-
name: z.literal("ggt"),
|
|
27
|
-
"dist-tags": z.object({
|
|
28
|
-
latest: z.string()
|
|
29
|
-
})
|
|
30
|
-
}).parse(json);
|
|
31
|
-
return parsed["dist-tags"];
|
|
33
|
+
return Registry.parse(json)["dist-tags"];
|
|
32
34
|
};
|
|
33
35
|
export const shouldCheckForUpdate = async ()=>{
|
|
34
36
|
try {
|
|
35
|
-
const lastCheck = Number(await fs.readFile(path.join(config.cacheDir, "last-update-check"), "
|
|
37
|
+
const lastCheck = Number(await fs.readFile(path.join(config.cacheDir, "last-update-check"), "utf8"));
|
|
36
38
|
assert(!Number.isNaN(lastCheck));
|
|
37
39
|
return dayjs().isAfter(lastCheck + UPDATE_CHECK_FREQUENCY);
|
|
38
40
|
} catch (error) {
|
|
39
41
|
return true;
|
|
40
42
|
}
|
|
41
43
|
};
|
|
42
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Checks for updates to the `ggt` npm package and logs a warning
|
|
46
|
+
* message if an update is available.
|
|
47
|
+
*
|
|
48
|
+
* @returns A Promise that resolves with void when the check is
|
|
49
|
+
* complete.
|
|
50
|
+
*/ export const warnIfUpdateAvailable = async ()=>{
|
|
43
51
|
try {
|
|
44
52
|
const shouldCheck = await shouldCheckForUpdate();
|
|
45
53
|
if (!shouldCheck) {
|
|
@@ -52,7 +60,7 @@ export const warnIfUpdateAvailable = async ()=>{
|
|
|
52
60
|
current: config.version,
|
|
53
61
|
latest: tags.latest
|
|
54
62
|
});
|
|
55
|
-
println(boxen(sprint`
|
|
63
|
+
log.println(boxen(sprint`
|
|
56
64
|
Update available! {red ${config.version}} -> {green ${tags.latest}}.
|
|
57
65
|
Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${tags.latest}
|
|
58
66
|
Run "npm install -g ${config.name}" to update.
|
|
@@ -69,4 +77,4 @@ export const warnIfUpdateAvailable = async ()=>{
|
|
|
69
77
|
}
|
|
70
78
|
};
|
|
71
79
|
|
|
72
|
-
//# sourceMappingURL=
|
|
80
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/update.ts"],"sourcesContent":["import boxen from \"boxen\";\nimport dayjs from \"dayjs\";\nimport fs from \"fs-extra\";\nimport ms from \"ms\";\nimport assert from \"node:assert\";\nimport path from \"node:path\";\nimport semver from \"semver\";\nimport { z } from \"zod\";\nimport { config } from \"../config/config.js\";\nimport { http } from \"../http/http.js\";\nimport { createLogger } from \"./log/logger.js\";\nimport { sprint } from \"./sprint.js\";\n\nconst log = createLogger({ name: \"update\" });\n\nconst UPDATE_CHECK_FREQUENCY = ms(\"12 hours\");\n\nconst Registry = z.object({\n name: z.literal(\"ggt\"),\n \"dist-tags\": z.object({\n latest: z.string(),\n }),\n});\n\ntype Registry = z.infer<typeof Registry>;\n\nexport const getDistTags = async (): Promise<Registry[\"dist-tags\"]> => {\n const json = await http({\n method: \"GET\",\n url: \"https://registry.npmjs.org/ggt\",\n responseType: \"json\",\n resolveBodyOnly: true,\n timeout: {\n request: ms(\"5s\"),\n },\n });\n\n return Registry.parse(json)[\"dist-tags\"];\n};\n\nexport const shouldCheckForUpdate = async (): Promise<boolean> => {\n try {\n const lastCheck = Number(await fs.readFile(path.join(config.cacheDir, \"last-update-check\"), \"utf8\"));\n assert(!Number.isNaN(lastCheck));\n return dayjs().isAfter(lastCheck + UPDATE_CHECK_FREQUENCY);\n } catch (error) {\n return true;\n }\n};\n\n/**\n * Checks for updates to the `ggt` npm package and logs a warning\n * message if an update is available.\n *\n * @returns A Promise that resolves with void when the check is\n * complete.\n */\nexport const warnIfUpdateAvailable = async (): Promise<void> => {\n try {\n const shouldCheck = await shouldCheckForUpdate();\n if (!shouldCheck) {\n return;\n }\n\n await fs.outputFile(path.join(config.cacheDir, \"last-update-check\"), String(Date.now()));\n\n const tags = await getDistTags();\n\n if (semver.lt(config.version, tags.latest)) {\n log.info(\"update available\", { current: config.version, latest: tags.latest });\n log.println(\n boxen(\n sprint`\n Update available! {red ${config.version}} -> {green ${tags.latest}}.\n Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${tags.latest}\n Run \"npm install -g ${config.name}\" to update.\n `,\n {\n padding: 1,\n borderStyle: \"round\",\n textAlignment: \"center\",\n },\n ),\n );\n }\n } catch (error) {\n log.error(\"failed to check for updates\", { error });\n }\n};\n"],"names":["boxen","dayjs","fs","ms","assert","path","semver","z","config","http","createLogger","sprint","log","name","UPDATE_CHECK_FREQUENCY","Registry","object","literal","latest","string","getDistTags","json","method","url","responseType","resolveBodyOnly","timeout","request","parse","shouldCheckForUpdate","lastCheck","Number","readFile","join","cacheDir","isNaN","isAfter","error","warnIfUpdateAvailable","shouldCheck","outputFile","String","Date","now","tags","lt","version","info","current","println","padding","borderStyle","textAlignment"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAAU,YAAY;AAC7B,OAAOC,YAAY,SAAS;AAC5B,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,YAAY,QAAQ,kBAAkB;AAC/C,SAASC,MAAM,QAAQ,cAAc;AAErC,MAAMC,MAAMF,aAAa;IAAEG,MAAM;AAAS;AAE1C,MAAMC,yBAAyBX,GAAG;AAElC,MAAMY,WAAWR,EAAES,MAAM,CAAC;IACxBH,MAAMN,EAAEU,OAAO,CAAC;IAChB,aAAaV,EAAES,MAAM,CAAC;QACpBE,QAAQX,EAAEY,MAAM;IAClB;AACF;AAIA,OAAO,MAAMC,cAAc;IACzB,MAAMC,OAAO,MAAMZ,KAAK;QACtBa,QAAQ;QACRC,KAAK;QACLC,cAAc;QACdC,iBAAiB;QACjBC,SAAS;YACPC,SAASxB,GAAG;QACd;IACF;IAEA,OAAOY,SAASa,KAAK,CAACP,KAAK,CAAC,YAAY;AAC1C,EAAE;AAEF,OAAO,MAAMQ,uBAAuB;IAClC,IAAI;QACF,MAAMC,YAAYC,OAAO,MAAM7B,GAAG8B,QAAQ,CAAC3B,KAAK4B,IAAI,CAACzB,OAAO0B,QAAQ,EAAE,sBAAsB;QAC5F9B,OAAO,CAAC2B,OAAOI,KAAK,CAACL;QACrB,OAAO7B,QAAQmC,OAAO,CAACN,YAAYhB;IACrC,EAAE,OAAOuB,OAAO;QACd,OAAO;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMC,wBAAwB;IACnC,IAAI;QACF,MAAMC,cAAc,MAAMV;QAC1B,IAAI,CAACU,aAAa;YAChB;QACF;QAEA,MAAMrC,GAAGsC,UAAU,CAACnC,KAAK4B,IAAI,CAACzB,OAAO0B,QAAQ,EAAE,sBAAsBO,OAAOC,KAAKC,GAAG;QAEpF,MAAMC,OAAO,MAAMxB;QAEnB,IAAId,OAAOuC,EAAE,CAACrC,OAAOsC,OAAO,EAAEF,KAAK1B,MAAM,GAAG;YAC1CN,IAAImC,IAAI,CAAC,oBAAoB;gBAAEC,SAASxC,OAAOsC,OAAO;gBAAE5B,QAAQ0B,KAAK1B,MAAM;YAAC;YAC5EN,IAAIqC,OAAO,CACTjD,MACEW,MAAM,CAAC;mCACkB,EAAEH,OAAOsC,OAAO,CAAC,YAAY,EAAEF,KAAK1B,MAAM,CAAC;uEACP,EAAE0B,KAAK1B,MAAM,CAAC;gCACrD,EAAEV,OAAOK,IAAI,CAAC;UACpC,CAAC,EACD;gBACEqC,SAAS;gBACTC,aAAa;gBACbC,eAAe;YACjB;QAGN;IACF,EAAE,OAAOf,OAAO;QACdzB,IAAIyB,KAAK,CAAC,+BAA+B;YAAEA;QAAM;IACnD;AACF,EAAE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import { configPath } from "../config/config.js";
|
|
3
|
+
import { swallowEnoent } from "../filesync/directory.js";
|
|
4
|
+
import { createLogger } from "../output/log/logger.js";
|
|
5
|
+
import { memo } from "../util/function.js";
|
|
6
|
+
const log = createLogger({
|
|
7
|
+
name: "session"
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* Reads the session from either the environment variable `GGT_SESSION`
|
|
11
|
+
* or from the `session.txt` file in the config directory.
|
|
12
|
+
*
|
|
13
|
+
* @returns The session string if found, otherwise undefined.
|
|
14
|
+
*/ export const readSession = memo(()=>{
|
|
15
|
+
if (process.env["GGT_SESSION"]) {
|
|
16
|
+
log.debug("reading session from env");
|
|
17
|
+
return process.env["GGT_SESSION"];
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
log.debug("reading session from disk");
|
|
21
|
+
return fs.readFileSync(configPath("session.txt"), "utf8");
|
|
22
|
+
} catch (error) {
|
|
23
|
+
swallowEnoent(error);
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Writes the session to disk in the `session.txt` file in the config.
|
|
29
|
+
*
|
|
30
|
+
* @param session - The session to write to disk.
|
|
31
|
+
*/ export const writeSession = (session)=>{
|
|
32
|
+
readSession.clear();
|
|
33
|
+
if (process.env["GGT_SESSION"]) {
|
|
34
|
+
log.debug("writing session to env", {
|
|
35
|
+
session: Boolean(session)
|
|
36
|
+
});
|
|
37
|
+
process.env["GGT_SESSION"] = session;
|
|
38
|
+
}
|
|
39
|
+
log.debug("writing session to disk", {
|
|
40
|
+
session: Boolean(session),
|
|
41
|
+
path: configPath("session.txt")
|
|
42
|
+
});
|
|
43
|
+
if (session) {
|
|
44
|
+
fs.outputFileSync(configPath("session.txt"), session);
|
|
45
|
+
} else {
|
|
46
|
+
fs.removeSync(configPath("session.txt"));
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/user/session.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { configPath } from \"../config/config.js\";\nimport { swallowEnoent } from \"../filesync/directory.js\";\nimport { createLogger } from \"../output/log/logger.js\";\nimport { memo } from \"../util/function.js\";\n\nconst log = createLogger({ name: \"session\" });\n\n/**\n * Reads the session from either the environment variable `GGT_SESSION`\n * or from the `session.txt` file in the config directory.\n *\n * @returns The session string if found, otherwise undefined.\n */\nexport const readSession = memo((): string | undefined => {\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"reading session from env\");\n return process.env[\"GGT_SESSION\"];\n }\n\n try {\n log.debug(\"reading session from disk\");\n return fs.readFileSync(configPath(\"session.txt\"), \"utf8\");\n } catch (error) {\n swallowEnoent(error);\n return undefined;\n }\n});\n\n/**\n * Writes the session to disk in the `session.txt` file in the config.\n *\n * @param session - The session to write to disk.\n */\nexport const writeSession = (session: string | undefined): void => {\n readSession.clear();\n\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"writing session to env\", { session: Boolean(session) });\n process.env[\"GGT_SESSION\"] = session;\n }\n\n log.debug(\"writing session to disk\", { session: Boolean(session), path: configPath(\"session.txt\") });\n\n if (session) {\n fs.outputFileSync(configPath(\"session.txt\"), session);\n } else {\n fs.removeSync(configPath(\"session.txt\"));\n }\n};\n"],"names":["fs","configPath","swallowEnoent","createLogger","memo","log","name","readSession","process","env","debug","readFileSync","error","undefined","writeSession","session","clear","Boolean","path","outputFileSync","removeSync"],"mappings":"AAAA,OAAOA,QAAQ,WAAW;AAC1B,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,YAAY,QAAQ,0BAA0B;AACvD,SAASC,IAAI,QAAQ,sBAAsB;AAE3C,MAAMC,MAAMF,aAAa;IAAEG,MAAM;AAAU;AAE3C;;;;;CAKC,GACD,OAAO,MAAMC,cAAcH,KAAK;IAC9B,IAAII,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC;QACV,OAAOF,QAAQC,GAAG,CAAC,cAAc;IACnC;IAEA,IAAI;QACFJ,IAAIK,KAAK,CAAC;QACV,OAAOV,GAAGW,YAAY,CAACV,WAAW,gBAAgB;IACpD,EAAE,OAAOW,OAAO;QACdV,cAAcU;QACd,OAAOC;IACT;AACF,GAAG;AAEH;;;;CAIC,GACD,OAAO,MAAMC,eAAe,CAACC;IAC3BR,YAAYS,KAAK;IAEjB,IAAIR,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC,0BAA0B;YAAEK,SAASE,QAAQF;QAAS;QAChEP,QAAQC,GAAG,CAAC,cAAc,GAAGM;IAC/B;IAEAV,IAAIK,KAAK,CAAC,2BAA2B;QAAEK,SAASE,QAAQF;QAAUG,MAAMjB,WAAW;IAAe;IAElG,IAAIc,SAAS;QACXf,GAAGmB,cAAc,CAAClB,WAAW,gBAAgBc;IAC/C,OAAO;QACLf,GAAGoB,UAAU,CAACnB,WAAW;IAC3B;AACF,EAAE"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import z from "zod";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
3
|
+
import { login } from "../../commands/login.js";
|
|
4
|
+
import { config } from "../config/config.js";
|
|
5
|
+
import { loadCookie, swallowUnauthorized } from "../http/auth.js";
|
|
6
|
+
import { http } from "../http/http.js";
|
|
7
|
+
import { createLogger } from "../output/log/logger.js";
|
|
8
|
+
import { confirm } from "../output/prompt.js";
|
|
9
|
+
import { setUser } from "../output/report.js";
|
|
10
|
+
import { pick } from "../util/object.js";
|
|
11
|
+
const log = createLogger({
|
|
12
|
+
name: "user"
|
|
13
|
+
});
|
|
11
14
|
const User = z.object({
|
|
12
15
|
id: z.union([
|
|
13
16
|
z.string(),
|
|
@@ -17,7 +20,10 @@ const User = z.object({
|
|
|
17
20
|
email: z.string()
|
|
18
21
|
});
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
23
|
+
* Retrieves the currently logged in user from Gadgets API.
|
|
24
|
+
*
|
|
25
|
+
* @returns A Promise that resolves to a User object representing the
|
|
26
|
+
* current user, or undefined if the user is not authenticated.
|
|
21
27
|
*/ export const getUser = async ()=>{
|
|
22
28
|
const cookie = loadCookie();
|
|
23
29
|
if (!cookie) {
|
|
@@ -47,18 +53,21 @@ const User = z.object({
|
|
|
47
53
|
return undefined;
|
|
48
54
|
}
|
|
49
55
|
};
|
|
50
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves the current user or prompts the user to log in if not
|
|
58
|
+
* already logged in.
|
|
59
|
+
*
|
|
60
|
+
* @param message The message to display when prompting the user to log in.
|
|
61
|
+
* @returns A Promise that resolves to the current user.
|
|
62
|
+
*/ export const getUserOrLogin = async (message = "You must be logged in to use this command. Would you like to log in?")=>{
|
|
51
63
|
let user = await getUser();
|
|
52
64
|
if (user) {
|
|
53
65
|
return user;
|
|
54
66
|
}
|
|
55
67
|
log.info("prompting user to log in");
|
|
56
|
-
|
|
68
|
+
await confirm({
|
|
57
69
|
message
|
|
58
70
|
});
|
|
59
|
-
if (!yes) {
|
|
60
|
-
process.exit(0);
|
|
61
|
-
}
|
|
62
71
|
await login();
|
|
63
72
|
user = await getUser();
|
|
64
73
|
assert(user, "missing user after successful login");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/user/user.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport z from \"zod\";\nimport { login } from \"../../commands/login.js\";\nimport { config } from \"../config/config.js\";\nimport { loadCookie, swallowUnauthorized } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\nimport { createLogger } from \"../output/log/logger.js\";\nimport { confirm } from \"../output/prompt.js\";\nimport { setUser } from \"../output/report.js\";\nimport { pick } from \"../util/object.js\";\n\nconst log = createLogger({ name: \"user\" });\n\nconst User = z.object({\n id: z.union([z.string(), z.number()]).transform(Number),\n name: z.string().nullish(),\n email: z.string(),\n});\n\nexport type User = z.infer<typeof User>;\n\n/**\n * Retrieves the currently logged in user from Gadgets API.\n *\n * @returns A Promise that resolves to a User object representing the\n * current user, or undefined if the user is not authenticated.\n */\nexport const getUser = async (): Promise<User | undefined> => {\n const cookie = loadCookie();\n if (!cookie) {\n return undefined;\n }\n\n try {\n const json = await http({\n url: `https://${config.domains.services}/auth/api/current-user`,\n headers: { cookie },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n const user = User.parse(json);\n setUser(user);\n log.info(\"loaded current user\", { user: pick(user, [\"id\", \"name\", \"email\"]) });\n\n return user;\n } catch (error) {\n swallowUnauthorized(error);\n return undefined;\n }\n};\n\n/**\n * Retrieves the current user or prompts the user to log in if not\n * already logged in.\n *\n * @param message The message to display when prompting the user to log in.\n * @returns A Promise that resolves to the current user.\n */\nexport const getUserOrLogin = async (message = \"You must be logged in to use this command. Would you like to log in?\"): Promise<User> => {\n let user = await getUser();\n if (user) {\n return user;\n }\n\n log.info(\"prompting user to log in\");\n await confirm({ message });\n\n await login();\n\n user = await getUser();\n assert(user, \"missing user after successful login\");\n\n return user;\n};\n"],"names":["assert","z","login","config","loadCookie","swallowUnauthorized","http","createLogger","confirm","setUser","pick","log","name","User","object","id","union","string","number","transform","Number","nullish","email","getUser","cookie","undefined","json","url","domains","services","headers","responseType","resolveBodyOnly","user","parse","info","error","getUserOrLogin","message"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,OAAOC,OAAO,MAAM;AACpB,SAASC,KAAK,QAAQ,0BAA0B;AAChD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,UAAU,EAAEC,mBAAmB,QAAQ,kBAAkB;AAClE,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,YAAY,QAAQ,0BAA0B;AACvD,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,IAAI,QAAQ,oBAAoB;AAEzC,MAAMC,MAAMJ,aAAa;IAAEK,MAAM;AAAO;AAExC,MAAMC,OAAOZ,EAAEa,MAAM,CAAC;IACpBC,IAAId,EAAEe,KAAK,CAAC;QAACf,EAAEgB,MAAM;QAAIhB,EAAEiB,MAAM;KAAG,EAAEC,SAAS,CAACC;IAChDR,MAAMX,EAAEgB,MAAM,GAAGI,OAAO;IACxBC,OAAOrB,EAAEgB,MAAM;AACjB;AAIA;;;;;CAKC,GACD,OAAO,MAAMM,UAAU;IACrB,MAAMC,SAASpB;IACf,IAAI,CAACoB,QAAQ;QACX,OAAOC;IACT;IAEA,IAAI;QACF,MAAMC,OAAO,MAAMpB,KAAK;YACtBqB,KAAK,CAAC,QAAQ,EAAExB,OAAOyB,OAAO,CAACC,QAAQ,CAAC,sBAAsB,CAAC;YAC/DC,SAAS;gBAAEN;YAAO;YAClBO,cAAc;YACdC,iBAAiB;QACnB;QAEA,MAAMC,OAAOpB,KAAKqB,KAAK,CAACR;QACxBjB,QAAQwB;QACRtB,IAAIwB,IAAI,CAAC,uBAAuB;YAAEF,MAAMvB,KAAKuB,MAAM;gBAAC;gBAAM;gBAAQ;aAAQ;QAAE;QAE5E,OAAOA;IACT,EAAE,OAAOG,OAAO;QACd/B,oBAAoB+B;QACpB,OAAOX;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMY,iBAAiB,OAAOC,UAAU,sEAAsE;IACnH,IAAIL,OAAO,MAAMV;IACjB,IAAIU,MAAM;QACR,OAAOA;IACT;IAEAtB,IAAIwB,IAAI,CAAC;IACT,MAAM3B,QAAQ;QAAE8B;IAAQ;IAExB,MAAMpC;IAEN+B,OAAO,MAAMV;IACbvB,OAAOiC,MAAM;IAEb,OAAOA;AACT,EAAE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { memo } from "./function.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parses a string value and returns a boolean value.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The string value to parse.
|
|
6
|
+
* @returns A boolean value representing the parsed value.
|
|
7
|
+
*/ export const parseBoolean = memo((value)=>{
|
|
8
|
+
value ??= "";
|
|
9
|
+
return [
|
|
10
|
+
"true",
|
|
11
|
+
"1"
|
|
12
|
+
].includes(value.trim().toLowerCase());
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=boolean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/boolean.ts"],"sourcesContent":["import { memo } from \"./function.js\";\n\n/**\n * Parses a string value and returns a boolean value.\n *\n * @param value - The string value to parse.\n * @returns A boolean value representing the parsed value.\n */\nexport const parseBoolean = memo((value: string | null | undefined): boolean => {\n value ??= \"\";\n return [\"true\", \"1\"].includes(value.trim().toLowerCase());\n});\n"],"names":["memo","parseBoolean","value","includes","trim","toLowerCase"],"mappings":"AAAA,SAASA,IAAI,QAAQ,gBAAgB;AAErC;;;;;CAKC,GACD,OAAO,MAAMC,eAAeD,KAAK,CAACE;IAChCA,UAAU;IACV,OAAO;QAAC;QAAQ;KAAI,CAACC,QAAQ,CAACD,MAAME,IAAI,GAAGC,WAAW;AACxD,GAAG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import levenshtein from "fast-levenshtein";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
/**
|
|
4
|
+
* Returns a new array with all falsy values removed. The values
|
|
5
|
+
* `false`, `null`, `0`, `""`, `undefined`, and `NaN` are falsy.
|
|
6
|
+
*
|
|
7
|
+
* @param array - The array to compact.
|
|
8
|
+
* @returns A new array with all falsy values removed.
|
|
9
|
+
*/ export const compact = (array)=>{
|
|
10
|
+
return array.filter((value)=>Boolean(value));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Returns a new array with all duplicate elements removed.
|
|
14
|
+
*
|
|
15
|
+
* @param array The array to remove duplicates from.
|
|
16
|
+
* @returns A new array with all duplicate elements removed.
|
|
17
|
+
*/ export const uniq = (array)=>{
|
|
18
|
+
return [
|
|
19
|
+
...new Set(array)
|
|
20
|
+
];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Sorts an array of strings based on their similarity to a given input
|
|
24
|
+
* string. The closest match is returned as the first element, followed
|
|
25
|
+
* by the sorted array.
|
|
26
|
+
*
|
|
27
|
+
* @param input - The input string to compare against.
|
|
28
|
+
* @param options - The array of strings to be sorted.
|
|
29
|
+
* @returns An array with the closest match as the first element,
|
|
30
|
+
* followed by the sorted array.
|
|
31
|
+
*/ export const sortBySimilar = (input, options)=>{
|
|
32
|
+
assert(options.length > 0, "options must not be empty");
|
|
33
|
+
return [
|
|
34
|
+
...options
|
|
35
|
+
].sort((a, b)=>levenshtein.get(a, input) - levenshtein.get(b, input));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/collection.ts"],"sourcesContent":["import levenshtein from \"fast-levenshtein\";\nimport assert from \"node:assert\";\n\n/**\n * Returns a new array with all falsy values removed. The values\n * `false`, `null`, `0`, `\"\"`, `undefined`, and `NaN` are falsy.\n *\n * @param array - The array to compact.\n * @returns A new array with all falsy values removed.\n */\nexport const compact = <T>(array: T[]): NonNullable<T>[] => {\n return array.filter((value): value is NonNullable<T> => Boolean(value));\n};\n\n/**\n * Returns a new array with all duplicate elements removed.\n *\n * @param array The array to remove duplicates from.\n * @returns A new array with all duplicate elements removed.\n */\nexport const uniq = <T>(array: T[]): T[] => {\n return [...new Set(array)];\n};\n\n/**\n * Sorts an array of strings based on their similarity to a given input\n * string. The closest match is returned as the first element, followed\n * by the sorted array.\n *\n * @param input - The input string to compare against.\n * @param options - The array of strings to be sorted.\n * @returns An array with the closest match as the first element,\n * followed by the sorted array.\n */\nexport const sortBySimilar = (input: string, options: readonly string[]): [closest: string, ...sorted: string[]] => {\n assert(options.length > 0, \"options must not be empty\");\n return [...options].sort((a, b) => levenshtein.get(a, input) - levenshtein.get(b, input)) as [string, ...string[]];\n};\n"],"names":["levenshtein","assert","compact","array","filter","value","Boolean","uniq","Set","sortBySimilar","input","options","length","sort","a","b","get"],"mappings":"AAAA,OAAOA,iBAAiB,mBAAmB;AAC3C,OAAOC,YAAY,cAAc;AAEjC;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,CAAIC;IACzB,OAAOA,MAAMC,MAAM,CAAC,CAACC,QAAmCC,QAAQD;AAClE,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAME,OAAO,CAAIJ;IACtB,OAAO;WAAI,IAAIK,IAAIL;KAAO;AAC5B,EAAE;AAEF;;;;;;;;;CASC,GACD,OAAO,MAAMM,gBAAgB,CAACC,OAAeC;IAC3CV,OAAOU,QAAQC,MAAM,GAAG,GAAG;IAC3B,OAAO;WAAID;KAAQ,CAACE,IAAI,CAAC,CAACC,GAAGC,IAAMf,YAAYgB,GAAG,CAACF,GAAGJ,SAASV,YAAYgB,GAAG,CAACD,GAAGL;AACpF,EAAE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable func-style */ import mimicFunction from "mimic-fn";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { isFunction } from "./is.js";
|
|
4
|
+
const memoizedFns = new Set();
|
|
5
|
+
export const MemoFirstArg = (...args)=>String(args[0]);
|
|
6
|
+
export const MemoAllArgs = (...args)=>args.map(String).join(":");
|
|
7
|
+
export function memo(fnOrKeyFn, fn) {
|
|
8
|
+
let keyFn;
|
|
9
|
+
if (fn) {
|
|
10
|
+
keyFn = fnOrKeyFn;
|
|
11
|
+
} else {
|
|
12
|
+
fn = fnOrKeyFn;
|
|
13
|
+
keyFn = MemoFirstArg;
|
|
14
|
+
}
|
|
15
|
+
const cache = new Map();
|
|
16
|
+
const memoized = (...args)=>{
|
|
17
|
+
const key = keyFn(...args);
|
|
18
|
+
if (cache.has(key)) {
|
|
19
|
+
return cache.get(key);
|
|
20
|
+
}
|
|
21
|
+
assert(fn, "fn shouldn't be undefined");
|
|
22
|
+
const result = fn(...args);
|
|
23
|
+
cache.set(key, result);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
memoized.clear = cache.clear.bind(cache);
|
|
27
|
+
memoizedFns.add(memoized);
|
|
28
|
+
mimicFunction(memoized, fn);
|
|
29
|
+
return memoized;
|
|
30
|
+
}
|
|
31
|
+
export const clearMemoized = ()=>{
|
|
32
|
+
for (const memoized of memoizedFns){
|
|
33
|
+
memoized.clear();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Creates a debounced function that delays invoking the provided
|
|
38
|
+
* function until after `delayMS` milliseconds have elapsed since the
|
|
39
|
+
* last time it was invoked.
|
|
40
|
+
*
|
|
41
|
+
* @param delayMS The number of milliseconds to delay.
|
|
42
|
+
* @param f The function to be debounced.
|
|
43
|
+
* @returns A debounced version of the provided function.
|
|
44
|
+
*/ export const debounce = (delayMS, f)=>{
|
|
45
|
+
let timerId;
|
|
46
|
+
let upcomingCall;
|
|
47
|
+
const debounced = (...args)=>{
|
|
48
|
+
upcomingCall = ()=>{
|
|
49
|
+
upcomingCall = undefined;
|
|
50
|
+
timerId = undefined;
|
|
51
|
+
f(...args);
|
|
52
|
+
};
|
|
53
|
+
clearTimeout(timerId);
|
|
54
|
+
timerId = setTimeout(upcomingCall, delayMS);
|
|
55
|
+
};
|
|
56
|
+
debounced.flush = ()=>{
|
|
57
|
+
if (upcomingCall) {
|
|
58
|
+
upcomingCall();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
return debounced;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Wraps a value in a thunk (a function that returns a value). If the
|
|
65
|
+
* value is already a function, it is returned as is.
|
|
66
|
+
*
|
|
67
|
+
* @param val The value or function to wrap.
|
|
68
|
+
* @returns A function that returns the value.
|
|
69
|
+
*/ export const thunk = (val)=>{
|
|
70
|
+
if (isFunction(val)) {
|
|
71
|
+
return val;
|
|
72
|
+
}
|
|
73
|
+
return ()=>val;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Unwraps a value from a thunk (a function that returns a value). If the
|
|
77
|
+
* value is not a function, it is returned as is.
|
|
78
|
+
*
|
|
79
|
+
* @param val The value or thunk to unwrap.
|
|
80
|
+
* @returns The unwrapped value.
|
|
81
|
+
*/ export const unthunk = (val)=>{
|
|
82
|
+
if (isFunction(val)) {
|
|
83
|
+
return val();
|
|
84
|
+
}
|
|
85
|
+
return val;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* A function that does nothing and returns nothing.
|
|
89
|
+
*/ // eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
90
|
+
export const noop = ()=>{};
|
|
91
|
+
/**
|
|
92
|
+
* A function that does nothing and returns `this`.
|
|
93
|
+
*/ export const noopThis = function() {
|
|
94
|
+
return this;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=function.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/function.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable func-style */\nimport mimicFunction from \"mimic-fn\";\nimport assert from \"node:assert\";\nimport type { Promisable } from \"type-fest\";\nimport { isFunction } from \"./is.js\";\n\nexport type AnyFunction = (...args: never[]) => unknown;\n\nexport type AnyVoid = Promisable<void>;\n\nconst memoizedFns = new Set<MemoizedFn>();\n\nexport type MemoizedFn<Fn extends AnyFunction = AnyFunction> = Fn & {\n /**\n * Clears the cache.\n */\n clear: () => void;\n};\n\nexport const MemoFirstArg = (...args: any[]): string => String(args[0]);\nexport const MemoAllArgs = (...args: any[]): string => args.map(String).join(\":\");\n\nexport function memo<Fn extends AnyFunction>(fn: Fn): MemoizedFn<Fn>;\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(keyFn: KeyFn, fn: Fn): MemoizedFn<Fn>;\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(\n fnOrKeyFn: Fn | KeyFn,\n fn?: Fn,\n): MemoizedFn<Fn> {\n let keyFn: KeyFn;\n if (fn) {\n keyFn = fnOrKeyFn as KeyFn;\n } else {\n fn = fnOrKeyFn as Fn;\n keyFn = MemoFirstArg as unknown as KeyFn;\n }\n\n const cache = new Map<string, unknown>();\n\n const memoized = ((...args) => {\n const key = keyFn(...(args as Parameters<Fn>));\n if (cache.has(key)) {\n return cache.get(key);\n }\n\n assert(fn, \"fn shouldn't be undefined\");\n const result = fn(...args);\n cache.set(key, result);\n\n return result;\n }) as MemoizedFn<Fn>;\n\n memoized.clear = cache.clear.bind(cache);\n\n memoizedFns.add(memoized);\n\n mimicFunction(memoized, fn);\n\n return memoized;\n}\n\nexport const clearMemoized = (): void => {\n for (const memoized of memoizedFns) {\n memoized.clear();\n }\n};\n\nexport type DebouncedFunc<Fn extends (...args: unknown[]) => void> = Fn & {\n /**\n * Invokes the function if it is waiting to stop being called.\n */\n flush: () => void;\n};\n\n/**\n * Creates a debounced function that delays invoking the provided\n * function until after `delayMS` milliseconds have elapsed since the\n * last time it was invoked.\n *\n * @param delayMS The number of milliseconds to delay.\n * @param f The function to be debounced.\n * @returns A debounced version of the provided function.\n */\nexport const debounce = <F extends (...args: unknown[]) => void>(delayMS: number, f: F): DebouncedFunc<F> => {\n let timerId: NodeJS.Timeout | undefined;\n let upcomingCall: (() => void) | undefined;\n\n const debounced = ((...args) => {\n upcomingCall = () => {\n upcomingCall = undefined;\n timerId = undefined;\n f(...args);\n };\n\n clearTimeout(timerId);\n timerId = setTimeout(upcomingCall, delayMS);\n }) as DebouncedFunc<F>;\n\n debounced.flush = () => {\n if (upcomingCall) {\n upcomingCall();\n }\n };\n\n return debounced;\n};\n\nexport type Thunk<T> = T | (() => T);\n\n/**\n * Wraps a value in a thunk (a function that returns a value). If the\n * value is already a function, it is returned as is.\n *\n * @param val The value or function to wrap.\n * @returns A function that returns the value.\n */\nexport const thunk = <T>(val: T | (() => T)): (() => T) => {\n if (isFunction(val)) {\n return val;\n }\n return () => val;\n};\n\n/**\n * Unwraps a value from a thunk (a function that returns a value). If the\n * value is not a function, it is returned as is.\n *\n * @param val The value or thunk to unwrap.\n * @returns The unwrapped value.\n */\nexport const unthunk = <T>(val: T | (() => T)): T => {\n if (isFunction(val)) {\n return val();\n }\n return val;\n};\n\n/**\n * A function that does nothing and returns nothing.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport const noop = (): void => {};\n\n/**\n * A function that does nothing and returns `this`.\n */\nexport const noopThis = function <T>(this: T): T {\n return this;\n};\n"],"names":["mimicFunction","assert","isFunction","memoizedFns","Set","MemoFirstArg","args","String","MemoAllArgs","map","join","memo","fnOrKeyFn","fn","keyFn","cache","Map","memoized","key","has","get","result","set","clear","bind","add","clearMemoized","debounce","delayMS","f","timerId","upcomingCall","debounced","undefined","clearTimeout","setTimeout","flush","thunk","val","unthunk","noop","noopThis"],"mappings":"AAAA,qDAAqD,GACrD,6BAA6B,GAC7B,OAAOA,mBAAmB,WAAW;AACrC,OAAOC,YAAY,cAAc;AAEjC,SAASC,UAAU,QAAQ,UAAU;AAMrC,MAAMC,cAAc,IAAIC;AASxB,OAAO,MAAMC,eAAe,CAAC,GAAGC,OAAwBC,OAAOD,IAAI,CAAC,EAAE,EAAE;AACxE,OAAO,MAAME,cAAc,CAAC,GAAGF,OAAwBA,KAAKG,GAAG,CAACF,QAAQG,IAAI,CAAC,KAAK;AAIlF,OAAO,SAASC,KACdC,SAAqB,EACrBC,EAAO;IAEP,IAAIC;IACJ,IAAID,IAAI;QACNC,QAAQF;IACV,OAAO;QACLC,KAAKD;QACLE,QAAQT;IACV;IAEA,MAAMU,QAAQ,IAAIC;IAElB,MAAMC,WAAY,CAAC,GAAGX;QACpB,MAAMY,MAAMJ,SAAUR;QACtB,IAAIS,MAAMI,GAAG,CAACD,MAAM;YAClB,OAAOH,MAAMK,GAAG,CAACF;QACnB;QAEAjB,OAAOY,IAAI;QACX,MAAMQ,SAASR,MAAMP;QACrBS,MAAMO,GAAG,CAACJ,KAAKG;QAEf,OAAOA;IACT;IAEAJ,SAASM,KAAK,GAAGR,MAAMQ,KAAK,CAACC,IAAI,CAACT;IAElCZ,YAAYsB,GAAG,CAACR;IAEhBjB,cAAciB,UAAUJ;IAExB,OAAOI;AACT;AAEA,OAAO,MAAMS,gBAAgB;IAC3B,KAAK,MAAMT,YAAYd,YAAa;QAClCc,SAASM,KAAK;IAChB;AACF,EAAE;AASF;;;;;;;;CAQC,GACD,OAAO,MAAMI,WAAW,CAAyCC,SAAiBC;IAChF,IAAIC;IACJ,IAAIC;IAEJ,MAAMC,YAAa,CAAC,GAAG1B;QACrByB,eAAe;YACbA,eAAeE;YACfH,UAAUG;YACVJ,KAAKvB;QACP;QAEA4B,aAAaJ;QACbA,UAAUK,WAAWJ,cAAcH;IACrC;IAEAI,UAAUI,KAAK,GAAG;QAChB,IAAIL,cAAc;YAChBA;QACF;IACF;IAEA,OAAOC;AACT,EAAE;AAIF;;;;;;CAMC,GACD,OAAO,MAAMK,QAAQ,CAAIC;IACvB,IAAIpC,WAAWoC,MAAM;QACnB,OAAOA;IACT;IACA,OAAO,IAAMA;AACf,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,CAAID;IACzB,IAAIpC,WAAWoC,MAAM;QACnB,OAAOA;IACT;IACA,OAAOA;AACT,EAAE;AAEF;;CAEC,GACD,gEAAgE;AAChE,OAAO,MAAME,OAAO,KAAa,EAAE;AAEnC;;CAEC,GACD,OAAO,MAAMC,WAAW;IACtB,OAAO,IAAI;AACb,EAAE"}
|
|
@@ -35,5 +35,12 @@ export const isGraphQLErrors = (e)=>{
|
|
|
35
35
|
message: z.string()
|
|
36
36
|
})).safeParse(e).success;
|
|
37
37
|
};
|
|
38
|
+
export const isNever = (value)=>{
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
40
|
+
throw new Error(`Unexpected value: ${value}`);
|
|
41
|
+
};
|
|
42
|
+
export const isAbortError = (error)=>{
|
|
43
|
+
return error instanceof Error && error.name === "AbortError" || error instanceof Event && error.type === "abort";
|
|
44
|
+
};
|
|
38
45
|
|
|
39
46
|
//# sourceMappingURL=is.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/is.ts"],"sourcesContent":["import type { GraphQLError } from \"graphql\";\nimport type { SetOptional } from \"type-fest\";\nimport type { CloseEvent, ErrorEvent } from \"ws\";\nimport { z } from \"zod\";\n\nexport const isNil = (val: unknown): val is null | undefined => {\n return val === null || val === undefined;\n};\n\nexport const isString = (val: unknown): val is string => {\n return typeof val === \"string\";\n};\n\nexport const isObject = (val: unknown): val is object => {\n return val instanceof Object;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isFunction = (val: unknown): val is Function => {\n return typeof val === \"function\";\n};\n\nexport const isError = (val: unknown): val is Error => {\n return val instanceof Error;\n};\n\nexport const isCloseEvent = (e: unknown): e is SetOptional<CloseEvent, \"target\"> => {\n return z.object({ type: z.string(), code: z.number(), reason: z.string(), wasClean: z.boolean() }).safeParse(e).success;\n};\n\nexport const isErrorEvent = (e: unknown): e is SetOptional<ErrorEvent, \"target\"> => {\n return z.object({ type: z.string(), message: z.string(), error: z.any() }).safeParse(e).success;\n};\n\nexport const isGraphQLErrors = (e: unknown): e is readonly GraphQLError[] => {\n return z.array(z.object({ message: z.string() })).safeParse(e).success;\n};\n\nexport const isNever = (value: never): never => {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unexpected value: ${value}`);\n};\n\nexport const isAbortError = (error: unknown): error is Error | Event => {\n return (error instanceof Error && error.name === \"AbortError\") || (error instanceof Event && error.type === \"abort\");\n};\n"],"names":["z","isNil","val","undefined","isString","isObject","Object","isFunction","isError","Error","isCloseEvent","e","object","type","string","code","number","reason","wasClean","boolean","safeParse","success","isErrorEvent","message","error","any","isGraphQLErrors","array","isNever","value","isAbortError","name","Event"],"mappings":"AAGA,SAASA,CAAC,QAAQ,MAAM;AAExB,OAAO,MAAMC,QAAQ,CAACC;IACpB,OAAOA,QAAQ,QAAQA,QAAQC;AACjC,EAAE;AAEF,OAAO,MAAMC,WAAW,CAACF;IACvB,OAAO,OAAOA,QAAQ;AACxB,EAAE;AAEF,OAAO,MAAMG,WAAW,CAACH;IACvB,OAAOA,eAAeI;AACxB,EAAE;AAEF,wDAAwD;AACxD,OAAO,MAAMC,aAAa,CAACL;IACzB,OAAO,OAAOA,QAAQ;AACxB,EAAE;AAEF,OAAO,MAAMM,UAAU,CAACN;IACtB,OAAOA,eAAeO;AACxB,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACC;IAC3B,OAAOX,EAAEY,MAAM,CAAC;QAAEC,MAAMb,EAAEc,MAAM;QAAIC,MAAMf,EAAEgB,MAAM;QAAIC,QAAQjB,EAAEc,MAAM;QAAII,UAAUlB,EAAEmB,OAAO;IAAG,GAAGC,SAAS,CAACT,GAAGU,OAAO;AACzH,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACX;IAC3B,OAAOX,EAAEY,MAAM,CAAC;QAAEC,MAAMb,EAAEc,MAAM;QAAIS,SAASvB,EAAEc,MAAM;QAAIU,OAAOxB,EAAEyB,GAAG;IAAG,GAAGL,SAAS,CAACT,GAAGU,OAAO;AACjG,EAAE;AAEF,OAAO,MAAMK,kBAAkB,CAACf;IAC9B,OAAOX,EAAE2B,KAAK,CAAC3B,EAAEY,MAAM,CAAC;QAAEW,SAASvB,EAAEc,MAAM;IAAG,IAAIM,SAAS,CAACT,GAAGU,OAAO;AACxE,EAAE;AAEF,OAAO,MAAMO,UAAU,CAACC;IACtB,4EAA4E;IAC5E,MAAM,IAAIpB,MAAM,CAAC,kBAAkB,EAAEoB,MAAM,CAAC;AAC9C,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACN;IAC3B,OAAO,AAACA,iBAAiBf,SAASe,MAAMO,IAAI,KAAK,gBAAkBP,iBAAiBQ,SAASR,MAAMX,IAAI,KAAK;AAC9G,EAAE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a string value into a number. If the value is an invalid
|
|
3
|
+
* number it returns {@linkcode defaultValue}.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The string value to parse.
|
|
6
|
+
* @returns The parsed number.
|
|
7
|
+
*/ export const parseNumber = (value, defaultValue = 0)=>{
|
|
8
|
+
value ??= "";
|
|
9
|
+
const parsed = Number.parseFloat(value);
|
|
10
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Ensures that a number is within a given range.
|
|
14
|
+
*
|
|
15
|
+
* If the number is less than the minimum value, the minimum value is returned.
|
|
16
|
+
* If the number is greater than the maximum value, the maximum value is returned.
|
|
17
|
+
* Otherwise, the number is returned as is.
|
|
18
|
+
*
|
|
19
|
+
* @param value The value to be clamped.
|
|
20
|
+
* @param min The minimum value of the range.
|
|
21
|
+
* @param max The maximum value of the range.
|
|
22
|
+
* @returns The clamped value.
|
|
23
|
+
*/ export const clamp = (value, min, max)=>{
|
|
24
|
+
return Math.max(min, Math.min(max, value));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=number.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/number.ts"],"sourcesContent":["/**\n * Parses a string value into a number. If the value is an invalid\n * number it returns {@linkcode defaultValue}.\n *\n * @param value - The string value to parse.\n * @returns The parsed number.\n */\nexport const parseNumber = (value: string | null | undefined, defaultValue = 0): number => {\n value ??= \"\";\n const parsed = Number.parseFloat(value);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n};\n\n/**\n * Ensures that a number is within a given range.\n *\n * If the number is less than the minimum value, the minimum value is returned.\n * If the number is greater than the maximum value, the maximum value is returned.\n * Otherwise, the number is returned as is.\n *\n * @param value The value to be clamped.\n * @param min The minimum value of the range.\n * @param max The maximum value of the range.\n * @returns The clamped value.\n */\nexport const clamp = (value: number, min: number, max: number): number => {\n return Math.max(min, Math.min(max, value));\n};\n"],"names":["parseNumber","value","defaultValue","parsed","Number","parseFloat","isNaN","clamp","min","max","Math"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,MAAMA,cAAc,CAACC,OAAkCC,eAAe,CAAC;IAC5ED,UAAU;IACV,MAAME,SAASC,OAAOC,UAAU,CAACJ;IACjC,OAAOG,OAAOE,KAAK,CAACH,UAAUD,eAAeC;AAC/C,EAAE;AAEF;;;;;;;;;;;CAWC,GACD,OAAO,MAAMI,QAAQ,CAACN,OAAeO,KAAaC;IAChD,OAAOC,KAAKD,GAAG,CAACD,KAAKE,KAAKF,GAAG,CAACC,KAAKR;AACrC,EAAE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import cleanStack from "clean-stack";
|
|
2
|
+
import { RequestError } from "got";
|
|
3
|
+
import { inspect } from "node:util";
|
|
4
|
+
import { serializeError as baseSerializeError } from "serialize-error";
|
|
5
|
+
import { workspaceRoot } from "./paths.js";
|
|
6
|
+
/**
|
|
7
|
+
* Returns a new object with the properties of the input object merged
|
|
8
|
+
* with the properties of the defaults object. If a property exists in
|
|
9
|
+
* both objects, the property of the input object will be used.
|
|
10
|
+
*
|
|
11
|
+
* @param input - The input object to merge with the defaults object.
|
|
12
|
+
* @param defaults - The defaults object to merge with the input object.
|
|
13
|
+
* @returns A new object with the properties of the input object merged
|
|
14
|
+
* with the properties of the defaults object.
|
|
15
|
+
*/ export const defaults = (input, defaults)=>{
|
|
16
|
+
const result = {
|
|
17
|
+
...input
|
|
18
|
+
};
|
|
19
|
+
for (const [key, defaultValue] of Object.entries(defaults)){
|
|
20
|
+
if (!result[key]) {
|
|
21
|
+
result[key] = defaultValue;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new object with only the specified properties of the
|
|
28
|
+
* original object.
|
|
29
|
+
*
|
|
30
|
+
* @param object - The original object to pick properties from.
|
|
31
|
+
* @param keys - The keys of the properties to pick.
|
|
32
|
+
* @returns A new object with only the specified properties of the
|
|
33
|
+
* original object.
|
|
34
|
+
*/ export const pick = (object, keys)=>{
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const key of keys){
|
|
37
|
+
result[key] = object[key];
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Returns a new object with the specified keys omitted.
|
|
43
|
+
*
|
|
44
|
+
* @param record The input object.
|
|
45
|
+
* @param keys The keys to omit.
|
|
46
|
+
* @returns A new object with the specified keys omitted.
|
|
47
|
+
*/ export const omit = (record, keys)=>{
|
|
48
|
+
const result = {
|
|
49
|
+
...record
|
|
50
|
+
};
|
|
51
|
+
for (const key of keys){
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
53
|
+
delete result[key];
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Maps the values of an object to a new set of values using the
|
|
59
|
+
* provided function.
|
|
60
|
+
*
|
|
61
|
+
* @param obj The input object to map.
|
|
62
|
+
* @param fn The function to apply to each value in the input object.
|
|
63
|
+
* @returns A new object with the same keys as the input object, but
|
|
64
|
+
* with the values mapped to new values using the provided function.
|
|
65
|
+
*/ export const mapValues = (obj, fn)=>{
|
|
66
|
+
const result = {};
|
|
67
|
+
for (const [key, value] of Object.entries(obj)){
|
|
68
|
+
result[key] = fn(value);
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Universal Error object to json blob serializer.
|
|
74
|
+
*
|
|
75
|
+
* Wraps `serialize-error` with some handy stuff, like special support
|
|
76
|
+
* for Got HTTP errors
|
|
77
|
+
*/ export const serializeError = (error)=>{
|
|
78
|
+
let serialized = baseSerializeError(Array.isArray(error) ? new AggregateError(error) : error);
|
|
79
|
+
if (typeof serialized == "string") {
|
|
80
|
+
serialized = {
|
|
81
|
+
message: serialized
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (serialized.stack) {
|
|
85
|
+
serialized.stack = cleanStack(serialized.stack, {
|
|
86
|
+
pretty: true,
|
|
87
|
+
basePath: workspaceRoot
|
|
88
|
+
}).replaceAll(/file:\/\/\//g, "");
|
|
89
|
+
}
|
|
90
|
+
if (error instanceof RequestError) {
|
|
91
|
+
serialized["timings"] = undefined;
|
|
92
|
+
serialized["options"] = {
|
|
93
|
+
method: error.options.method,
|
|
94
|
+
url: error.options.url instanceof URL ? error.options.url.toJSON() : error.options.url
|
|
95
|
+
};
|
|
96
|
+
serialized["responseBody"] = inspect(error.response?.body);
|
|
97
|
+
}
|
|
98
|
+
return serialized;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/util/object.ts"],"sourcesContent":["import cleanStack from \"clean-stack\";\nimport { RequestError } from \"got\";\nimport { inspect } from \"node:util\";\nimport { serializeError as baseSerializeError, type ErrorObject } from \"serialize-error\";\nimport type { Simplify } from \"type-fest\";\nimport { workspaceRoot } from \"./paths.js\";\n\n/**\n * Returns a new object with the properties of the input object merged\n * with the properties of the defaults object. If a property exists in\n * both objects, the property of the input object will be used.\n *\n * @param input - The input object to merge with the defaults object.\n * @param defaults - The defaults object to merge with the input object.\n * @returns A new object with the properties of the input object merged\n * with the properties of the defaults object.\n */\nexport const defaults = <Input extends Record<string, unknown>, Defaults extends Partial<Input>>(\n input: Input | null | undefined,\n defaults: Defaults,\n): Simplify<Defaults & Input> => {\n const result = { ...input };\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (!result[key]) {\n result[key] = defaultValue;\n }\n }\n return result as Simplify<Defaults & Input>;\n};\n\n/**\n * Creates a new object with only the specified properties of the\n * original object.\n *\n * @param object - The original object to pick properties from.\n * @param keys - The keys of the properties to pick.\n * @returns A new object with only the specified properties of the\n * original object.\n */\nexport const pick = <T extends Record<string, unknown>, K extends keyof T>(object: T, keys: readonly K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n result[key] = object[key];\n }\n return result;\n};\n\n/**\n * Returns a new object with the specified keys omitted.\n *\n * @param record The input object.\n * @param keys The keys to omit.\n * @returns A new object with the specified keys omitted.\n */\nexport const omit = <T extends Record<string, unknown>, K extends keyof T>(record: T, keys: readonly K[]): Omit<T, K> => {\n const result = { ...record };\n for (const key of keys) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[key];\n }\n return result;\n};\n\n/**\n * Maps the values of an object to a new set of values using the\n * provided function.\n *\n * @param obj The input object to map.\n * @param fn The function to apply to each value in the input object.\n * @returns A new object with the same keys as the input object, but\n * with the values mapped to new values using the provided function.\n */\nexport const mapValues = <Key extends string | number | symbol, Value, MappedValue>(\n obj: Record<Key, Value>,\n fn: (value: Value) => MappedValue,\n): Record<Key, MappedValue> => {\n const result = {} as Record<Key, MappedValue>;\n for (const [key, value] of Object.entries(obj)) {\n result[key as Key] = fn(value as Value);\n }\n return result;\n};\n\n/**\n * Universal Error object to json blob serializer.\n *\n * Wraps `serialize-error` with some handy stuff, like special support\n * for Got HTTP errors\n */\nexport const serializeError = (error: unknown): ErrorObject => {\n let serialized = baseSerializeError(Array.isArray(error) ? new AggregateError(error) : error);\n if (typeof serialized == \"string\") {\n serialized = { message: serialized };\n }\n\n if (serialized.stack) {\n serialized.stack = cleanStack(serialized.stack, { pretty: true, basePath: workspaceRoot }).replaceAll(/file:\\/\\/\\//g, \"\");\n }\n\n if (error instanceof RequestError) {\n serialized[\"timings\"] = undefined;\n serialized[\"options\"] = {\n method: error.options.method,\n url: error.options.url instanceof URL ? error.options.url.toJSON() : error.options.url,\n };\n serialized[\"responseBody\"] = inspect(error.response?.body);\n }\n\n return serialized;\n};\n"],"names":["cleanStack","RequestError","inspect","serializeError","baseSerializeError","workspaceRoot","defaults","input","result","key","defaultValue","Object","entries","pick","object","keys","omit","record","mapValues","obj","fn","value","error","serialized","Array","isArray","AggregateError","message","stack","pretty","basePath","replaceAll","undefined","method","options","url","URL","toJSON","response","body"],"mappings":"AAAA,OAAOA,gBAAgB,cAAc;AACrC,SAASC,YAAY,QAAQ,MAAM;AACnC,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,kBAAkBC,kBAAkB,QAA0B,kBAAkB;AAEzF,SAASC,aAAa,QAAQ,aAAa;AAE3C;;;;;;;;;CASC,GACD,OAAO,MAAMC,WAAW,CACtBC,OACAD;IAEA,MAAME,SAAS;QAAE,GAAGD,KAAK;IAAC;IAC1B,KAAK,MAAM,CAACE,KAAKC,aAAa,IAAIC,OAAOC,OAAO,CAACN,UAAW;QAC1D,IAAI,CAACE,MAAM,CAACC,IAAI,EAAE;YAChBD,MAAM,CAACC,IAAI,GAAGC;QAChB;IACF;IACA,OAAOF;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMK,OAAO,CAAuDC,QAAWC;IACpF,MAAMP,SAAS,CAAC;IAChB,KAAK,MAAMC,OAAOM,KAAM;QACtBP,MAAM,CAACC,IAAI,GAAGK,MAAM,CAACL,IAAI;IAC3B;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMQ,OAAO,CAAuDC,QAAWF;IACpF,MAAMP,SAAS;QAAE,GAAGS,MAAM;IAAC;IAC3B,KAAK,MAAMR,OAAOM,KAAM;QACtB,gEAAgE;QAChE,OAAOP,MAAM,CAACC,IAAI;IACpB;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMU,YAAY,CACvBC,KACAC;IAEA,MAAMZ,SAAS,CAAC;IAChB,KAAK,MAAM,CAACC,KAAKY,MAAM,IAAIV,OAAOC,OAAO,CAACO,KAAM;QAC9CX,MAAM,CAACC,IAAW,GAAGW,GAAGC;IAC1B;IACA,OAAOb;AACT,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAML,iBAAiB,CAACmB;IAC7B,IAAIC,aAAanB,mBAAmBoB,MAAMC,OAAO,CAACH,SAAS,IAAII,eAAeJ,SAASA;IACvF,IAAI,OAAOC,cAAc,UAAU;QACjCA,aAAa;YAAEI,SAASJ;QAAW;IACrC;IAEA,IAAIA,WAAWK,KAAK,EAAE;QACpBL,WAAWK,KAAK,GAAG5B,WAAWuB,WAAWK,KAAK,EAAE;YAAEC,QAAQ;YAAMC,UAAUzB;QAAc,GAAG0B,UAAU,CAAC,gBAAgB;IACxH;IAEA,IAAIT,iBAAiBrB,cAAc;QACjCsB,UAAU,CAAC,UAAU,GAAGS;QACxBT,UAAU,CAAC,UAAU,GAAG;YACtBU,QAAQX,MAAMY,OAAO,CAACD,MAAM;YAC5BE,KAAKb,MAAMY,OAAO,CAACC,GAAG,YAAYC,MAAMd,MAAMY,OAAO,CAACC,GAAG,CAACE,MAAM,KAAKf,MAAMY,OAAO,CAACC,GAAG;QACxF;QACAZ,UAAU,CAAC,eAAe,GAAGrB,QAAQoB,MAAMgB,QAAQ,EAAEC;IACvD;IAEA,OAAOhB;AACT,EAAE"}
|