@gadgetinc/ggt 0.4.7 → 0.4.8
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 +1 -1
- package/bin/dev.js +2 -1
- package/bin/run.js +3 -1
- package/lib/commands/deploy.js +11 -15
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/list.js +7 -11
- package/lib/commands/list.js.map +1 -1
- package/lib/commands/login.js +8 -12
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/logout.js +3 -7
- package/lib/commands/logout.js.map +1 -1
- package/lib/commands/root.js +17 -44
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/sync.js +8 -27
- package/lib/commands/sync.js.map +1 -1
- package/lib/commands/version.js +2 -6
- package/lib/commands/version.js.map +1 -1
- package/lib/commands/whoami.js +5 -9
- package/lib/commands/whoami.js.map +1 -1
- package/lib/ggt.js +40 -0
- package/lib/ggt.js.map +1 -0
- package/lib/services/app/app.js +8 -6
- package/lib/services/app/app.js.map +1 -1
- package/lib/services/app/edit/client.js +176 -0
- package/lib/services/app/edit/client.js.map +1 -0
- package/lib/services/app/edit/edit.js +155 -0
- package/lib/services/app/edit/edit.js.map +1 -0
- package/lib/services/app/edit/error.js +65 -0
- package/lib/services/app/edit/error.js.map +1 -0
- package/lib/services/app/edit/operation.js +87 -0
- package/lib/services/app/edit/operation.js.map +1 -0
- package/lib/services/command/arg.js +5 -5
- package/lib/services/command/arg.js.map +1 -1
- package/lib/services/command/command.js +21 -7
- package/lib/services/command/command.js.map +1 -1
- package/lib/services/command/context.js +108 -56
- package/lib/services/command/context.js.map +1 -1
- package/lib/services/filesync/changes.js +7 -9
- package/lib/services/filesync/changes.js.map +1 -1
- package/lib/services/filesync/conflicts.js +11 -9
- package/lib/services/filesync/conflicts.js.map +1 -1
- package/lib/services/filesync/directory.js +2 -2
- package/lib/services/filesync/directory.js.map +1 -1
- package/lib/services/filesync/filesync.js +70 -42
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/filesync/hashes.js +18 -15
- package/lib/services/filesync/hashes.js.map +1 -1
- package/lib/services/http/auth.js +4 -4
- package/lib/services/http/auth.js.map +1 -1
- package/lib/services/http/http.js +43 -23
- package/lib/services/http/http.js.map +1 -1
- package/lib/services/output/log/logger.js +11 -6
- package/lib/services/output/log/logger.js.map +1 -1
- package/lib/services/output/log/printer.js.map +1 -1
- package/lib/services/output/log/structured.js +2 -2
- package/lib/services/output/log/structured.js.map +1 -1
- package/lib/services/output/notify.js +3 -7
- package/lib/services/output/notify.js.map +1 -1
- package/lib/services/output/prompt.js +11 -11
- package/lib/services/output/prompt.js.map +1 -1
- package/lib/services/output/report.js +51 -67
- package/lib/services/output/report.js.map +1 -1
- package/lib/services/output/update.js +9 -10
- package/lib/services/output/update.js.map +1 -1
- package/lib/services/user/user.js +19 -25
- package/lib/services/user/user.js.map +1 -1
- package/lib/services/util/collection.js +1 -1
- package/lib/services/util/collection.js.map +1 -1
- package/lib/services/util/function.js +29 -11
- package/lib/services/util/function.js.map +1 -1
- package/lib/services/util/number.js +3 -3
- package/lib/services/util/number.js.map +1 -1
- package/lib/services/util/object.js +4 -4
- package/lib/services/util/object.js.map +1 -1
- package/lib/services/util/paths.js +4 -4
- package/lib/services/util/paths.js.map +1 -1
- package/lib/services/util/types.js +3 -1
- package/lib/services/util/types.js.map +1 -1
- package/npm-shrinkwrap.json +579 -411
- package/package.json +15 -14
- package/lib/main.js +0 -8
- package/lib/main.js.map +0 -1
- package/lib/services/app/edit-graphql.js +0 -392
- package/lib/services/app/edit-graphql.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/edit/edit.ts"],"sourcesContent":["import type { Promisable } from \"type-fest\";\nimport type { Context } from \"../../command/context.js\";\nimport { type HttpOptions } from \"../../http/http.js\";\nimport { unthunk, type Thunk } from \"../../util/function.js\";\nimport { Client } from \"./client.js\";\nimport { EditError } from \"./error.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./operation.js\";\n\nexport class Edit {\n readonly ctx: Context;\n #client: Client;\n\n constructor(ctx: Context) {\n this.ctx = ctx.child({ name: \"edit\" });\n this.#client = new Client(this.ctx);\n }\n\n /**\n * Execute a GraphQL query.\n *\n * @param request - The query and variables to send to the server.\n * @param request.query - The GraphQL query to execute.\n * @param request.variables - The variables to send to the server.\n * @param request.http - {@linkcode HttpOptions} to pass to http.\n * @returns The data returned by the server.\n */\n async query<Query extends GraphQLQuery>({\n query,\n variables,\n ...options\n }: {\n query: Query;\n variables?: Thunk<Query[\"Variables\"]> | null;\n http?: HttpOptions;\n }): Promise<Query[\"Data\"]> {\n const name = query.split(/ |\\(/, 2)[1];\n const ctx = this.ctx.child({\n fields: { edit: { query: name } },\n devFields: { edit: { query: name, variables: unthunk(variables) } },\n });\n\n ctx.log.info(\"executing graphql query\");\n const response = await this.#client.execute(ctx, {\n operation: query,\n variables,\n ...options,\n http: {\n retry: {\n // queries _should_ be idempotent, so automatically retry them\n methods: [\"POST\"],\n },\n ...options.http,\n },\n });\n\n if (response.errors) {\n throw new EditError(query, response.errors);\n }\n\n if (!response.data) {\n throw new EditError(query, \"Query response did not contain data\");\n }\n\n return response.data;\n }\n\n /**\n * Execute a GraphQL mutation.\n *\n * @param request - The query and variables to send to the server.\n * @param request.mutation - The GraphQL query to execute.\n * @param request.variables - The variables to send to the server.\n * @param request.http - {@linkcode HttpOptions} to pass to http.\n * @returns The data returned by the server.\n */\n async mutate<Mutation extends GraphQLMutation>({\n mutation,\n variables,\n ...options\n }: {\n mutation: Mutation;\n variables?: Thunk<Mutation[\"Variables\"]> | null;\n http?: HttpOptions;\n }): Promise<Mutation[\"Data\"]> {\n const name = mutation.split(/ |\\(/, 2)[1];\n const ctx = this.ctx.child({\n fields: { edit: { mutation: name } },\n devFields: { edit: { mutation: name, variables: unthunk(variables) } },\n });\n\n ctx.log.info(\"executing graphql mutation\");\n const response = await this.#client.execute(ctx, { operation: mutation, variables, ...options });\n\n if (response.errors) {\n throw new EditError(mutation, response.errors);\n }\n\n if (!response.data) {\n throw new EditError(mutation, \"Mutation response did not contain data\");\n }\n\n return response.data;\n }\n\n /**\n * Subscribe to a GraphQL subscription.\n *\n * @param options - The query and variables to send to the server.\n * @param options.subscription - The GraphQL subscription to subscribe to.\n * @param options.variables - The variables to send to the server.\n * @param options.onData - A callback that will be called with the data returned by the server.\n * @param options.onError - A callback that will be called with any errors returned by the server.\n * @param options.onComplete - A callback that will be called when the subscription is complete.\n * @returns A function to unsubscribe from the subscription.\n */\n subscribe<Subscription extends GraphQLSubscription>({\n onData,\n ...options\n }: {\n subscription: Subscription;\n variables?: Thunk<Subscription[\"Variables\"]> | null;\n onData: (data: Subscription[\"Data\"]) => Promisable<void>;\n onError: (error: EditError) => Promisable<void>;\n onComplete?: () => Promisable<void>;\n }): () => void {\n const name = options.subscription.split(/ |\\(/, 2)[1];\n const ctx = this.ctx.child({\n fields: { edit: { subscription: name } },\n devFields: { edit: { subscription: name, variables: unthunk(options.variables) } },\n });\n\n ctx.log.info(\"subscribing to graphql subscription\");\n const unsubscribe = this.#client.subscribe(ctx, {\n ...options,\n onResponse: async (response) => {\n if (response.errors) {\n unsubscribe();\n await options.onError(new EditError(options.subscription, response.errors));\n return;\n }\n\n if (!response.data) {\n unsubscribe();\n await options.onError(new EditError(options.subscription, \"Subscription response did not contain data\"));\n return;\n }\n\n await onData(response.data);\n },\n });\n\n return unsubscribe;\n }\n\n /**\n * Close the client.\n */\n async dispose(): Promise<void> {\n await this.#client.dispose();\n }\n}\n"],"names":["unthunk","Client","EditError","Edit","query","variables","options","name","split","ctx","child","fields","edit","devFields","log","info","response","client","execute","operation","http","retry","methods","errors","data","mutate","mutation","subscribe","onData","subscription","unsubscribe","onResponse","onError","dispose","constructor"],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import pluralize from "pluralize";
|
|
4
|
+
import { CLIError, IsBug } from "../../output/report.js";
|
|
5
|
+
import { sprint } from "../../output/sprint.js";
|
|
6
|
+
import { uniq } from "../../util/collection.js";
|
|
7
|
+
import { isCloseEvent, isError, isErrorEvent, isGraphQLErrors, isString } from "../../util/is.js";
|
|
8
|
+
import { serializeError } from "../../util/object.js";
|
|
9
|
+
export class EditError extends CLIError {
|
|
10
|
+
render() {
|
|
11
|
+
let body = "";
|
|
12
|
+
switch(true){
|
|
13
|
+
case isGraphQLErrors(this.cause):
|
|
14
|
+
{
|
|
15
|
+
const errors = uniq(this.cause.map((x)=>x.message));
|
|
16
|
+
body = sprint`
|
|
17
|
+
Gadget responded with the following ${pluralize("error", errors.length, false)}:
|
|
18
|
+
|
|
19
|
+
• ${errors.join("\n • ")}
|
|
20
|
+
`;
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case isCloseEvent(this.cause):
|
|
24
|
+
body = "The connection to Gadget closed unexpectedly.";
|
|
25
|
+
break;
|
|
26
|
+
case isErrorEvent(this.cause) || isError(this.cause):
|
|
27
|
+
body = this.cause.message;
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
body = this.cause;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
return this.message + "\n\n" + body;
|
|
34
|
+
}
|
|
35
|
+
constructor(request, cause){
|
|
36
|
+
super("An error occurred while communicating with Gadget");
|
|
37
|
+
_define_property(this, "request", void 0);
|
|
38
|
+
_define_property(this, "isBug", void 0);
|
|
39
|
+
_define_property(this, "cause", void 0);
|
|
40
|
+
this.request = request;
|
|
41
|
+
this.isBug = IsBug.MAYBE;
|
|
42
|
+
// ErrorEvent and CloseEvent aren't serializable, so we reconstruct
|
|
43
|
+
// them into an object. We discard the `target` property because
|
|
44
|
+
// it's large and not that useful
|
|
45
|
+
if (isErrorEvent(cause)) {
|
|
46
|
+
this.cause = {
|
|
47
|
+
type: cause.type,
|
|
48
|
+
message: cause.message,
|
|
49
|
+
error: serializeError(cause.error)
|
|
50
|
+
};
|
|
51
|
+
} else if (isCloseEvent(cause)) {
|
|
52
|
+
this.cause = {
|
|
53
|
+
type: cause.type,
|
|
54
|
+
code: cause.code,
|
|
55
|
+
reason: cause.reason,
|
|
56
|
+
wasClean: cause.wasClean
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
assert(isString(cause) || isError(cause) || isGraphQLErrors(cause), "cause must be a string, Error, GraphQLError[], CloseEvent, or ErrorEvent");
|
|
60
|
+
this.cause = cause;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/edit/error.ts"],"sourcesContent":["import type { GraphQLError } from \"graphql\";\nimport assert from \"node:assert\";\nimport pluralize from \"pluralize\";\nimport type { CloseEvent, ErrorEvent } from \"ws\";\nimport { CLIError, IsBug } from \"../../output/report.js\";\nimport { sprint } from \"../../output/sprint.js\";\nimport { uniq } from \"../../util/collection.js\";\nimport { isCloseEvent, isError, isErrorEvent, isGraphQLErrors, isString } from \"../../util/is.js\";\nimport { serializeError } from \"../../util/object.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./operation.js\";\n\nexport class EditError extends CLIError {\n isBug = IsBug.MAYBE;\n\n override cause: string | Error | readonly GraphQLError[] | CloseEvent | ErrorEvent;\n\n constructor(\n readonly request: GraphQLQuery | GraphQLMutation | GraphQLSubscription,\n cause: unknown,\n ) {\n super(\"An error occurred while communicating with Gadget\");\n\n // ErrorEvent and CloseEvent aren't serializable, so we reconstruct\n // them into an object. We discard the `target` property because\n // it's large and not that useful\n if (isErrorEvent(cause)) {\n this.cause = {\n type: cause.type,\n message: cause.message,\n error: serializeError(cause.error),\n } as ErrorEvent;\n } else if (isCloseEvent(cause)) {\n this.cause = {\n type: cause.type,\n code: cause.code,\n reason: cause.reason,\n wasClean: cause.wasClean,\n } as CloseEvent;\n } else {\n assert(\n isString(cause) || isError(cause) || isGraphQLErrors(cause),\n \"cause must be a string, Error, GraphQLError[], CloseEvent, or ErrorEvent\",\n );\n this.cause = cause;\n }\n }\n\n override render(): string {\n let body = \"\";\n\n switch (true) {\n case isGraphQLErrors(this.cause): {\n const errors = uniq(this.cause.map((x) => x.message));\n body = sprint`\n Gadget responded with the following ${pluralize(\"error\", errors.length, false)}:\n\n • ${errors.join(\"\\n • \")}\n `;\n break;\n }\n case isCloseEvent(this.cause):\n body = \"The connection to Gadget closed unexpectedly.\";\n break;\n case isErrorEvent(this.cause) || isError(this.cause):\n body = this.cause.message;\n break;\n default:\n body = this.cause;\n break;\n }\n\n return this.message + \"\\n\\n\" + body;\n }\n}\n"],"names":["assert","pluralize","CLIError","IsBug","sprint","uniq","isCloseEvent","isError","isErrorEvent","isGraphQLErrors","isString","serializeError","EditError","render","body","cause","errors","map","x","message","length","join","constructor","request","isBug","MAYBE","type","error","code","reason","wasClean"],"mappings":";AACA,OAAOA,YAAY,cAAc;AACjC,OAAOC,eAAe,YAAY;AAElC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,yBAAyB;AACzD,SAASC,MAAM,QAAQ,yBAAyB;AAChD,SAASC,IAAI,QAAQ,2BAA2B;AAChD,SAASC,YAAY,EAAEC,OAAO,EAAEC,YAAY,EAAEC,eAAe,EAAEC,QAAQ,QAAQ,mBAAmB;AAClG,SAASC,cAAc,QAAQ,uBAAuB;AAGtD,OAAO,MAAMC,kBAAkBV;IAoCpBW,SAAiB;QACxB,IAAIC,OAAO;QAEX,OAAQ;YACN,KAAKL,gBAAgB,IAAI,CAACM,KAAK;gBAAG;oBAChC,MAAMC,SAASX,KAAK,IAAI,CAACU,KAAK,CAACE,GAAG,CAAC,CAACC,IAAMA,EAAEC,OAAO;oBACnDL,OAAOV,MAAM,CAAC;8CACwB,EAAEH,UAAU,SAASe,OAAOI,MAAM,EAAE,OAAO;;cAE3E,EAAEJ,OAAOK,IAAI,CAAC,oBAAoB;QACxC,CAAC;oBACD;gBACF;YACA,KAAKf,aAAa,IAAI,CAACS,KAAK;gBAC1BD,OAAO;gBACP;YACF,KAAKN,aAAa,IAAI,CAACO,KAAK,KAAKR,QAAQ,IAAI,CAACQ,KAAK;gBACjDD,OAAO,IAAI,CAACC,KAAK,CAACI,OAAO;gBACzB;YACF;gBACEL,OAAO,IAAI,CAACC,KAAK;gBACjB;QACJ;QAEA,OAAO,IAAI,CAACI,OAAO,GAAG,SAASL;IACjC;IAxDAQ,YACE,AAASC,OAA6D,EACtER,KAAc,CACd;QACA,KAAK,CAAC;;QARRS,uBAAAA,SAAAA,KAAAA;QAEA,uBAAST,SAAT,KAAA;aAGWQ,UAAAA;aALXC,QAAQrB,MAAMsB,KAAK;QAUjB,mEAAmE;QACnE,gEAAgE;QAChE,iCAAiC;QACjC,IAAIjB,aAAaO,QAAQ;YACvB,IAAI,CAACA,KAAK,GAAG;gBACXW,MAAMX,MAAMW,IAAI;gBAChBP,SAASJ,MAAMI,OAAO;gBACtBQ,OAAOhB,eAAeI,MAAMY,KAAK;YACnC;QACF,OAAO,IAAIrB,aAAaS,QAAQ;YAC9B,IAAI,CAACA,KAAK,GAAG;gBACXW,MAAMX,MAAMW,IAAI;gBAChBE,MAAMb,MAAMa,IAAI;gBAChBC,QAAQd,MAAMc,MAAM;gBACpBC,UAAUf,MAAMe,QAAQ;YAC1B;QACF,OAAO;YACL9B,OACEU,SAASK,UAAUR,QAAQQ,UAAUN,gBAAgBM,QACrD;YAEF,IAAI,CAACA,KAAK,GAAGA;QACf;IACF;AA4BF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { sprint } from "../../output/sprint.js";
|
|
2
|
+
export const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `
|
|
3
|
+
subscription RemoteFileSyncEvents($localFilesVersion: String!) {
|
|
4
|
+
remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {
|
|
5
|
+
remoteFilesVersion
|
|
6
|
+
changed {
|
|
7
|
+
path
|
|
8
|
+
mode
|
|
9
|
+
content
|
|
10
|
+
encoding
|
|
11
|
+
}
|
|
12
|
+
deleted {
|
|
13
|
+
path
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`);
|
|
18
|
+
export const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `
|
|
19
|
+
query RemoteFilesVersion {
|
|
20
|
+
remoteFilesVersion
|
|
21
|
+
}
|
|
22
|
+
`);
|
|
23
|
+
export const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `
|
|
24
|
+
mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {
|
|
25
|
+
publishFileSyncEvents(input: $input) {
|
|
26
|
+
remoteFilesVersion
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`);
|
|
30
|
+
export const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `
|
|
31
|
+
query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {
|
|
32
|
+
fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {
|
|
33
|
+
filesVersion
|
|
34
|
+
files {
|
|
35
|
+
path
|
|
36
|
+
mode
|
|
37
|
+
content
|
|
38
|
+
encoding
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`);
|
|
43
|
+
export const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `
|
|
44
|
+
query FileSyncHashes($filesVersion: String) {
|
|
45
|
+
fileSyncHashes(filesVersion: $filesVersion) {
|
|
46
|
+
filesVersion
|
|
47
|
+
hashes
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`);
|
|
51
|
+
export const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `
|
|
52
|
+
query FileSyncComparisonHashes($filesVersion: String!) {
|
|
53
|
+
fileSyncComparisonHashes(filesVersion: $filesVersion) {
|
|
54
|
+
filesVersionHashes {
|
|
55
|
+
filesVersion
|
|
56
|
+
hashes
|
|
57
|
+
}
|
|
58
|
+
latestFilesVersionHashes {
|
|
59
|
+
filesVersion
|
|
60
|
+
hashes
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`);
|
|
65
|
+
export const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
|
|
66
|
+
subscription publishStatus($localFilesVersion: String!, $force: Boolean) {
|
|
67
|
+
publishStatus(localFilesVersion: $localFilesVersion, force: $force) {
|
|
68
|
+
remoteFilesVersion
|
|
69
|
+
progress
|
|
70
|
+
issues {
|
|
71
|
+
severity
|
|
72
|
+
message
|
|
73
|
+
node {
|
|
74
|
+
type
|
|
75
|
+
key
|
|
76
|
+
apiIdentifier
|
|
77
|
+
name
|
|
78
|
+
fieldType
|
|
79
|
+
parentKey
|
|
80
|
+
parentApiIdentifier
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`);
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/edit/operation.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport type { JsonObject } from \"type-fest\";\nimport type {\n FileSyncComparisonHashesQuery,\n FileSyncComparisonHashesQueryVariables,\n FileSyncFilesQuery,\n FileSyncFilesQueryVariables,\n FileSyncHashesQuery,\n FileSyncHashesQueryVariables,\n PublishFileSyncEventsMutation,\n PublishFileSyncEventsMutationVariables,\n PublishStatusSubscription,\n PublishStatusSubscriptionVariables,\n RemoteFileSyncEventsSubscription,\n RemoteFileSyncEventsSubscriptionVariables,\n RemoteFilesVersionQuery,\n RemoteFilesVersionQueryVariables,\n} from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\n\n/**\n * A GraphQL query with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLQuery<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"query\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL mutation with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLMutation<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"mutation\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL subscription with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLSubscription<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"subscription\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\nexport const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription RemoteFileSyncEvents($localFilesVersion: String!) {\n remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {\n remoteFilesVersion\n changed {\n path\n mode\n content\n encoding\n }\n deleted {\n path\n }\n }\n }\n`) as GraphQLSubscription<RemoteFileSyncEventsSubscription, RemoteFileSyncEventsSubscriptionVariables>;\n\nexport type REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = typeof REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION;\n\nexport const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `\n query RemoteFilesVersion {\n remoteFilesVersion\n }\n`) as GraphQLQuery<RemoteFilesVersionQuery, RemoteFilesVersionQueryVariables>;\n\nexport type REMOTE_FILES_VERSION_QUERY = typeof REMOTE_FILES_VERSION_QUERY;\n\nexport const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `\n mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {\n publishFileSyncEvents(input: $input) {\n remoteFilesVersion\n }\n }\n`) as GraphQLMutation<PublishFileSyncEventsMutation, PublishFileSyncEventsMutationVariables>;\n\nexport type PUBLISH_FILE_SYNC_EVENTS_MUTATION = typeof PUBLISH_FILE_SYNC_EVENTS_MUTATION;\n\nexport const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `\n query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {\n fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {\n filesVersion\n files {\n path\n mode\n content\n encoding\n }\n }\n }\n`) as GraphQLQuery<FileSyncFilesQuery, FileSyncFilesQueryVariables>;\n\nexport type FILE_SYNC_FILES_QUERY = typeof FILE_SYNC_FILES_QUERY;\n\nexport const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncHashes($filesVersion: String) {\n fileSyncHashes(filesVersion: $filesVersion) {\n filesVersion\n hashes\n }\n }\n`) as GraphQLQuery<FileSyncHashesQuery, FileSyncHashesQueryVariables>;\n\nexport type FILE_SYNC_HASHES_QUERY = typeof FILE_SYNC_HASHES_QUERY;\n\nexport const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncComparisonHashes($filesVersion: String!) {\n fileSyncComparisonHashes(filesVersion: $filesVersion) {\n filesVersionHashes {\n filesVersion\n hashes\n }\n latestFilesVersionHashes {\n filesVersion\n hashes\n }\n }\n }\n`) as GraphQLQuery<FileSyncComparisonHashesQuery, FileSyncComparisonHashesQueryVariables>;\n\nexport type FILE_SYNC_COMPARISON_HASHES_QUERY = typeof FILE_SYNC_COMPARISON_HASHES_QUERY;\n\nexport const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription publishStatus($localFilesVersion: String!, $force: Boolean) {\n publishStatus(localFilesVersion: $localFilesVersion, force: $force) {\n remoteFilesVersion\n progress\n issues {\n severity\n message\n node {\n type\n key\n apiIdentifier\n name\n fieldType\n parentKey\n parentApiIdentifier\n }\n }\n }\n }\n`) as GraphQLSubscription<PublishStatusSubscription, PublishStatusSubscriptionVariables>;\n\nexport type REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = typeof REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION;\n"],"names":["sprint","REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION","REMOTE_FILES_VERSION_QUERY","PUBLISH_FILE_SYNC_EVENTS_MUTATION","FILE_SYNC_FILES_QUERY","FILE_SYNC_HASHES_QUERY","FILE_SYNC_COMPARISON_HASHES_QUERY","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION"],"mappings":"AAkBA,SAASA,MAAM,QAAQ,yBAAyB;AAwDhD,OAAO,MAAMC,uCAAuCD,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;AAe1E,CAAC,EAAsG;AAIvG,OAAO,MAAME,6BAA6BF,OAAO,WAAW,GAAG,CAAC;;;;AAIhE,CAAC,EAA6E;AAI9E,OAAO,MAAMG,oCAAoCH,OAAO,WAAW,GAAG,CAAC;;;;;;AAMvE,CAAC,EAA4F;AAI7F,OAAO,MAAMI,wBAAwBJ,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAY3D,CAAC,EAAmE;AAIpE,OAAO,MAAMK,yBAAyBL,OAAO,WAAW,GAAG,CAAC;;;;;;;AAO5D,CAAC,EAAqE;AAItE,OAAO,MAAMM,oCAAoCN,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;AAavE,CAAC,EAAyF;AAI1F,OAAO,MAAMO,6CAA6CP,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;AAoBhF,CAAC,EAAwF"}
|
|
@@ -3,25 +3,25 @@ import arg from "arg";
|
|
|
3
3
|
import { CLIError, IsBug, UnexpectedError } from "../output/report.js";
|
|
4
4
|
import { isNil } from "../util/is.js";
|
|
5
5
|
export const parseArgs = (args, options)=>{
|
|
6
|
-
const
|
|
6
|
+
const spec = {};
|
|
7
7
|
const defaultValues = {};
|
|
8
8
|
for (const [key, value] of Object.entries(args)){
|
|
9
9
|
if (!("type" in value)) {
|
|
10
|
-
|
|
10
|
+
spec[key] = value;
|
|
11
11
|
continue;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
spec[key] = value.type;
|
|
14
14
|
defaultValues[key] = value.default;
|
|
15
15
|
if (value.alias) {
|
|
16
16
|
for (const alias of Array.isArray(value.alias) ? value.alias : [
|
|
17
17
|
value.alias
|
|
18
18
|
]){
|
|
19
|
-
|
|
19
|
+
spec[alias] = key;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
try {
|
|
24
|
-
const parsed = arg(
|
|
24
|
+
const parsed = arg(spec, options);
|
|
25
25
|
for (const [key, value] of Object.entries(defaultValues)){
|
|
26
26
|
if (isNil(parsed[key])) {
|
|
27
27
|
parsed[key] = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/command/arg.ts"],"sourcesContent":["import arg from \"arg\";\nimport type { Simplify } from \"type-fest\";\nimport { CLIError, IsBug, UnexpectedError } from \"../output/report.js\";\nimport { isNil } from \"../util/is.js\";\n\nexport type
|
|
1
|
+
{"version":3,"sources":["../../../src/services/command/arg.ts"],"sourcesContent":["import arg from \"arg\";\nimport type { Simplify } from \"type-fest\";\nimport { CLIError, IsBug, UnexpectedError } from \"../output/report.js\";\nimport { isNil } from \"../util/is.js\";\n\nexport type ArgsDefinition = Record<string, ArgDefinition>;\n\ntype ArgDefinition<Handler extends arg.Handler = arg.Handler> =\n | Handler\n | {\n type: Handler;\n alias?: string | string[];\n default?: ReturnType<Handler>;\n };\n\nexport type ParseArgsOptions = {\n /**\n * A list of arguments to parse.\n */\n argv?: string[];\n\n /**\n * When permissive set to `true`, arg will push any unknown arguments\n * onto the \"extra\" argument array (`ctx.args._`) instead of throwing\n * an error about an unknown flag.\n *\n * @default false\n */\n permissive?: boolean;\n\n /**\n * When stopAtPositional is set to true, context will stop parsing at\n * the first positional argument.\n *\n * @default false\n */\n stopAtPositional?: boolean;\n};\n\nexport const parseArgs = <Args extends ArgsDefinition>(args: Args, options?: arg.Options): ArgsDefinitionResult<Args> => {\n const spec: arg.Spec = {};\n const defaultValues: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(args)) {\n if (!(\"type\" in value)) {\n spec[key] = value;\n continue;\n }\n\n spec[key] = value.type;\n defaultValues[key] = value.default;\n\n if (value.alias) {\n for (const alias of Array.isArray(value.alias) ? value.alias : [value.alias]) {\n spec[alias] = key;\n }\n }\n }\n\n try {\n const parsed = arg(spec, options);\n for (const [key, value] of Object.entries(defaultValues)) {\n if (isNil(parsed[key])) {\n parsed[key] = value as never;\n }\n }\n return parsed as ArgsDefinitionResult<Args>;\n } catch (error: unknown) {\n if (error instanceof arg.ArgError) {\n // convert arg.ArgError to CLIError\n // eslint-disable-next-line no-ex-assign\n error = new ArgError(error.message);\n }\n if (error instanceof CLIError) {\n throw error;\n }\n throw new UnexpectedError(error);\n }\n};\n\nexport class ArgError extends CLIError {\n isBug = IsBug.NO;\n\n protected override render(): string {\n return this.message;\n }\n}\n\n/**\n * Turns this:\n * ```ts\n * type Args = {\n * \"--string\": { type: String; alias: \"s\" };\n * \"--number\": { type: Number; default: 42 };\n * };\n * ```\n *\n * Into this:\n * ```ts\n * type Result = {\n * \"--string\": string | undefined;\n * \"--number\": number;\n * };\n * ```\n */\nexport type ArgsDefinitionResult<Args extends ArgsDefinition, Keys extends keyof Args = keyof Args> = Simplify<{\n [Key in Keys]: Args[Key] extends ArgDefinition<infer Handler>\n ? Args[Key] extends { default: unknown }\n ? NonNullable<ReturnType<Handler>>\n : ReturnType<Handler> | undefined\n : never;\n}> & { _: string[] };\n"],"names":["arg","CLIError","IsBug","UnexpectedError","isNil","parseArgs","args","options","spec","defaultValues","key","value","Object","entries","type","default","alias","Array","isArray","parsed","error","ArgError","message","render","isBug","NO"],"mappings":";AAAA,OAAOA,SAAS,MAAM;AAEtB,SAASC,QAAQ,EAAEC,KAAK,EAAEC,eAAe,QAAQ,sBAAsB;AACvE,SAASC,KAAK,QAAQ,gBAAgB;AAoCtC,OAAO,MAAMC,YAAY,CAA8BC,MAAYC;IACjE,MAAMC,OAAiB,CAAC;IACxB,MAAMC,gBAAyC,CAAC;IAEhD,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACP,MAAO;QAC/C,IAAI,CAAE,CAAA,UAAUK,KAAI,GAAI;YACtBH,IAAI,CAACE,IAAI,GAAGC;YACZ;QACF;QAEAH,IAAI,CAACE,IAAI,GAAGC,MAAMG,IAAI;QACtBL,aAAa,CAACC,IAAI,GAAGC,MAAMI,OAAO;QAElC,IAAIJ,MAAMK,KAAK,EAAE;YACf,KAAK,MAAMA,SAASC,MAAMC,OAAO,CAACP,MAAMK,KAAK,IAAIL,MAAMK,KAAK,GAAG;gBAACL,MAAMK,KAAK;aAAC,CAAE;gBAC5ER,IAAI,CAACQ,MAAM,GAAGN;YAChB;QACF;IACF;IAEA,IAAI;QACF,MAAMS,SAASnB,IAAIQ,MAAMD;QACzB,KAAK,MAAM,CAACG,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACJ,eAAgB;YACxD,IAAIL,MAAMe,MAAM,CAACT,IAAI,GAAG;gBACtBS,MAAM,CAACT,IAAI,GAAGC;YAChB;QACF;QACA,OAAOQ;IACT,EAAE,OAAOC,OAAgB;QACvB,IAAIA,iBAAiBpB,IAAIqB,QAAQ,EAAE;YACjC,mCAAmC;YACnC,wCAAwC;YACxCD,QAAQ,IAAIC,SAASD,MAAME,OAAO;QACpC;QACA,IAAIF,iBAAiBnB,UAAU;YAC7B,MAAMmB;QACR;QACA,MAAM,IAAIjB,gBAAgBiB;IAC5B;AACF,EAAE;AAEF,OAAO,MAAMC,iBAAiBpB;IAGTsB,SAAiB;QAClC,OAAO,IAAI,CAACD,OAAO;IACrB;;;QAJAE,uBAAAA,SAAQtB,MAAMuB,EAAE;;AAKlB"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import assert from "node:assert";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import { config } from "../config/config.js";
|
|
4
4
|
import { relativeToThisFile } from "../util/paths.js";
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The list of available commands.
|
|
7
|
+
* - Each command is a separate file in src/commands.
|
|
8
|
+
* - The order determines the order of commands in the README.
|
|
9
|
+
*/ export const Commands = [
|
|
6
10
|
"sync",
|
|
7
11
|
"list",
|
|
8
12
|
"login",
|
|
@@ -10,14 +14,24 @@ export const AvailableCommands = [
|
|
|
10
14
|
"whoami",
|
|
11
15
|
"version"
|
|
12
16
|
];
|
|
13
|
-
//
|
|
17
|
+
// deploy is still in preview
|
|
14
18
|
if (process.env["GGT_DEPLOY_PREVIEW"]) {
|
|
15
|
-
|
|
19
|
+
Commands.push("deploy");
|
|
16
20
|
}
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Checks if a string is a valid command.
|
|
23
|
+
*
|
|
24
|
+
* @param command - The string to check
|
|
25
|
+
* @returns Whether the string is a valid command
|
|
26
|
+
*/ export const isAvailableCommand = (command)=>{
|
|
27
|
+
return Commands.includes(command);
|
|
19
28
|
};
|
|
20
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Imports a command module.
|
|
31
|
+
*
|
|
32
|
+
* @param cmd - The command to import
|
|
33
|
+
* @see {@linkcode CommandModule}
|
|
34
|
+
*/ export const importCommand = async (cmd)=>{
|
|
21
35
|
assert(isAvailableCommand(cmd), `invalid command: ${cmd}`);
|
|
22
36
|
let commandPath = relativeToThisFile(`../../commands/${cmd}.js`);
|
|
23
37
|
if (config.windows) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/command/command.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../src/services/command/command.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport { pathToFileURL } from \"node:url\";\nimport type { EmptyObject, Promisable } from \"type-fest\";\nimport type { RootArgs } from \"../../commands/root.js\";\nimport { config } from \"../config/config.js\";\nimport { relativeToThisFile } from \"../util/paths.js\";\nimport type { ArgsDefinition } from \"./arg.js\";\nimport type { Context } from \"./context.js\";\n\n/**\n * The list of available commands.\n * - Each command is a separate file in src/commands.\n * - The order determines the order of commands in the README.\n */\nexport const Commands = [\"sync\", \"list\", \"login\", \"logout\", \"whoami\", \"version\"] as const;\n\n// deploy is still in preview\nif (process.env[\"GGT_DEPLOY_PREVIEW\"]) {\n (Commands as unknown as string[]).push(\"deploy\");\n}\n\n/**\n * One of the commands in {@link Commands}.\n */\nexport type AvailableCommand = (typeof Commands)[number];\n\n/**\n * Checks if a string is a valid command.\n *\n * @param command - The string to check\n * @returns Whether the string is a valid command\n */\nexport const isAvailableCommand = (command: string): command is AvailableCommand => {\n return Commands.includes(command as AvailableCommand);\n};\n\n/**\n * A command module is a file in the src/commands directory.\n */\nexport type CommandModule<Args extends ArgsDefinition = EmptyObject, ParentArgs extends ArgsDefinition = RootArgs> = {\n /**\n * The command's {@link ArgsDefinition}.\n */\n args?: Args;\n\n /**\n * The command's {@link Usage}.\n */\n usage: Usage;\n\n /**\n * The command's {@link Command}.\n */\n command: Command<Args, ParentArgs>;\n};\n\n/**\n * A command's usage is a string that describes how to use the command.\n */\nexport type Usage = () => string;\n\n/**\n * The function that is run when the command is invoked.\n *\n * @param ctx - A {@linkcode Context} with the command's {@linkcode Args} and {@linkcode ParentArgs}.\n */\nexport type Command<Args extends ArgsDefinition = EmptyObject, ParentArgs extends ArgsDefinition = RootArgs> = (\n ctx: Context<Args, ParentArgs>,\n) => Promisable<void>;\n\n/**\n * Imports a command module.\n *\n * @param cmd - The command to import\n * @see {@linkcode CommandModule}\n */\nexport const importCommand = async (cmd: AvailableCommand): Promise<CommandModule> => {\n assert(isAvailableCommand(cmd), `invalid command: ${cmd}`);\n let commandPath = relativeToThisFile(`../../commands/${cmd}.js`);\n if (config.windows) {\n // https://github.com/nodejs/node/issues/31710\n commandPath = pathToFileURL(commandPath).toString();\n }\n return (await import(commandPath)) as CommandModule;\n};\n"],"names":["assert","pathToFileURL","config","relativeToThisFile","Commands","process","env","push","isAvailableCommand","command","includes","importCommand","cmd","commandPath","windows","toString"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAASC,aAAa,QAAQ,WAAW;AAGzC,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,kBAAkB,QAAQ,mBAAmB;AAItD;;;;CAIC,GACD,OAAO,MAAMC,WAAW;IAAC;IAAQ;IAAQ;IAAS;IAAU;IAAU;CAAU,CAAU;AAE1F,6BAA6B;AAC7B,IAAIC,QAAQC,GAAG,CAAC,qBAAqB,EAAE;IACpCF,SAAiCG,IAAI,CAAC;AACzC;AAOA;;;;;CAKC,GACD,OAAO,MAAMC,qBAAqB,CAACC;IACjC,OAAOL,SAASM,QAAQ,CAACD;AAC3B,EAAE;AAoCF;;;;;CAKC,GACD,OAAO,MAAME,gBAAgB,OAAOC;IAClCZ,OAAOQ,mBAAmBI,MAAM,CAAC,iBAAiB,EAAEA,IAAI,CAAC;IACzD,IAAIC,cAAcV,mBAAmB,CAAC,eAAe,EAAES,IAAI,GAAG,CAAC;IAC/D,IAAIV,OAAOY,OAAO,EAAE;QAClB,8CAA8C;QAC9CD,cAAcZ,cAAcY,aAAaE,QAAQ;IACnD;IACA,OAAQ,MAAM,MAAM,CAACF;AACvB,EAAE"}
|
|
@@ -1,63 +1,105 @@
|
|
|
1
|
+
import { _ as _class_private_field_get } from "@swc/helpers/_/_class_private_field_get";
|
|
2
|
+
import { _ as _class_private_field_init } from "@swc/helpers/_/_class_private_field_init";
|
|
3
|
+
import { _ as _class_private_field_set } from "@swc/helpers/_/_class_private_field_set";
|
|
1
4
|
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
2
5
|
import assert from "node:assert";
|
|
3
6
|
import { createLogger } from "../output/log/logger.js";
|
|
4
|
-
import {
|
|
7
|
+
import { defaults, pick } from "../util/object.js";
|
|
5
8
|
import { parseArgs } from "./arg.js";
|
|
9
|
+
var _log = /*#__PURE__*/ new WeakMap(), _parent = /*#__PURE__*/ new WeakMap(), _user = /*#__PURE__*/ new WeakMap(), _app = /*#__PURE__*/ new WeakMap();
|
|
6
10
|
/**
|
|
7
11
|
* Represents the context of a command-line operation.
|
|
8
12
|
*/ export class Context extends AbortController {
|
|
9
13
|
/**
|
|
14
|
+
* A {@linkcode Logger} that can print to stdout and log structured
|
|
15
|
+
* messages to stderr.
|
|
16
|
+
*/ get log() {
|
|
17
|
+
return _class_private_field_get(this, _log);
|
|
18
|
+
}
|
|
19
|
+
get user() {
|
|
20
|
+
return _class_private_field_get(this, _user) ?? _class_private_field_get(this, _parent)?.user;
|
|
21
|
+
}
|
|
22
|
+
set user(user) {
|
|
23
|
+
_class_private_field_set(this, _user, user);
|
|
24
|
+
if (_class_private_field_get(this, _parent)) {
|
|
25
|
+
_class_private_field_get(this, _parent).user = user;
|
|
26
|
+
}
|
|
27
|
+
_class_private_field_set(this, _log, _class_private_field_get(this, _log).child({
|
|
28
|
+
fields: {
|
|
29
|
+
user: pick(user, [
|
|
30
|
+
"id",
|
|
31
|
+
"name",
|
|
32
|
+
"email"
|
|
33
|
+
])
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
38
|
+
get app() {
|
|
39
|
+
return _class_private_field_get(this, _app) ?? _class_private_field_get(this, _parent)?.app;
|
|
40
|
+
}
|
|
41
|
+
set app(app) {
|
|
42
|
+
_class_private_field_set(this, _app, app);
|
|
43
|
+
if (_class_private_field_get(this, _parent)) {
|
|
44
|
+
_class_private_field_get(this, _parent).app = app;
|
|
45
|
+
}
|
|
46
|
+
_class_private_field_set(this, _log, _class_private_field_get(this, _log).child({
|
|
47
|
+
fields: {
|
|
48
|
+
app
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
10
53
|
* Initializes a new context.
|
|
11
|
-
|
|
12
|
-
|
|
54
|
+
*
|
|
55
|
+
* @see {@linkcode ContextInit}
|
|
56
|
+
*/ static init({ parse: spec, ...options }) {
|
|
13
57
|
return new Context({
|
|
14
|
-
args,
|
|
15
|
-
|
|
58
|
+
args: spec ? parseArgs(spec, pick(options, [
|
|
59
|
+
"argv",
|
|
60
|
+
"permissive",
|
|
61
|
+
"stopAtPositional"
|
|
62
|
+
])) : {},
|
|
63
|
+
log: createLogger(pick(options, [
|
|
64
|
+
"name",
|
|
65
|
+
"fields",
|
|
66
|
+
"devFields"
|
|
67
|
+
]))
|
|
16
68
|
});
|
|
17
69
|
}
|
|
18
70
|
/**
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...parseArgs(spec, {
|
|
24
|
-
argv: this.args._,
|
|
25
|
-
...options
|
|
26
|
-
})
|
|
27
|
-
};
|
|
28
|
-
const ctx = new Context({
|
|
29
|
-
args,
|
|
30
|
-
name
|
|
31
|
-
});
|
|
32
|
-
this.onAbort(()=>ctx.abort());
|
|
33
|
-
return ctx;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Clones the current context and optionally overrides its name and
|
|
37
|
-
* arguments.
|
|
38
|
-
*/ clone({ args, name }) {
|
|
71
|
+
* Returns a new context that is a child of the current context.
|
|
72
|
+
*
|
|
73
|
+
* @see {@linkcode ChildContextInit}
|
|
74
|
+
*/ child({ parse: spec, ...options }) {
|
|
39
75
|
const ctx = new Context({
|
|
76
|
+
parent: this,
|
|
40
77
|
args: {
|
|
41
|
-
...args,
|
|
42
|
-
...
|
|
78
|
+
...this.args,
|
|
79
|
+
...options.overwrite,
|
|
80
|
+
...spec ? parseArgs(spec, defaults(pick(options, [
|
|
81
|
+
"argv",
|
|
82
|
+
"permissive",
|
|
83
|
+
"stopAtPositional"
|
|
84
|
+
]), {
|
|
85
|
+
argv: this.args._
|
|
86
|
+
})) : {}
|
|
43
87
|
},
|
|
44
|
-
|
|
88
|
+
log: this.log.child(pick(options, [
|
|
89
|
+
"name",
|
|
90
|
+
"fields",
|
|
91
|
+
"devFields"
|
|
92
|
+
]))
|
|
45
93
|
});
|
|
46
94
|
this.onAbort(()=>ctx.abort());
|
|
47
95
|
return ctx;
|
|
48
96
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} else {
|
|
56
|
-
options = {
|
|
57
|
-
...options,
|
|
58
|
-
...callbackOrOptions
|
|
59
|
-
};
|
|
60
|
-
}
|
|
97
|
+
/**
|
|
98
|
+
* Registers a callback that will be called when the context is
|
|
99
|
+
* aborted (e.g. when the user presses Ctrl+C).
|
|
100
|
+
*
|
|
101
|
+
* @param callback - The callback to call when the context is aborted.
|
|
102
|
+
*/ onAbort(callback) {
|
|
61
103
|
this.signal.addEventListener("abort", // eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
62
104
|
async ()=>{
|
|
63
105
|
try {
|
|
@@ -68,27 +110,37 @@ import { parseArgs } from "./arg.js";
|
|
|
68
110
|
error
|
|
69
111
|
});
|
|
70
112
|
}
|
|
71
|
-
}
|
|
113
|
+
});
|
|
72
114
|
}
|
|
73
|
-
constructor({ args,
|
|
115
|
+
constructor({ args, log, parent }){
|
|
74
116
|
super();
|
|
75
117
|
/**
|
|
76
|
-
* The parsed command-line arguments for the current
|
|
77
|
-
*
|
|
118
|
+
* The parsed command-line arguments for the current context and any
|
|
119
|
+
* parent contexts.
|
|
78
120
|
*/ _define_property(this, "args", void 0);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
* This logger's name is set the name of the command that is being
|
|
83
|
-
* executed.
|
|
84
|
-
*/ _define_property(this, "log", void 0);
|
|
85
|
-
this.args = args;
|
|
86
|
-
this.log = createLogger({
|
|
87
|
-
name,
|
|
88
|
-
fields: {
|
|
89
|
-
args: this.args
|
|
90
|
-
}
|
|
121
|
+
_class_private_field_init(this, _log, {
|
|
122
|
+
writable: true,
|
|
123
|
+
value: void 0
|
|
91
124
|
});
|
|
125
|
+
_class_private_field_init(this, _parent, {
|
|
126
|
+
writable: true,
|
|
127
|
+
value: void 0
|
|
128
|
+
});
|
|
129
|
+
_class_private_field_init(this, _user, {
|
|
130
|
+
writable: true,
|
|
131
|
+
value: void 0
|
|
132
|
+
});
|
|
133
|
+
_class_private_field_init(this, _app, {
|
|
134
|
+
writable: true,
|
|
135
|
+
value: void 0
|
|
136
|
+
});
|
|
137
|
+
this.args = args;
|
|
138
|
+
_class_private_field_set(this, _log, log);
|
|
139
|
+
_class_private_field_set(this, _parent, parent);
|
|
140
|
+
// in case this context is ...spread into another object
|
|
141
|
+
this.abort = this.abort.bind(this);
|
|
142
|
+
this.child = this.child.bind(this);
|
|
143
|
+
this.onAbort = this.onAbort.bind(this);
|
|
92
144
|
}
|
|
93
145
|
}
|
|
94
146
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/command/context.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/services/command/context.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport type { EmptyObject } from \"type-fest\";\nimport type { RootArgs } from \"../../commands/root.js\";\nimport type { App } from \"../app/app.js\";\nimport { createLogger, type Logger } from \"../output/log/logger.js\";\nimport type { StructuredLoggerOptions } from \"../output/log/structured.js\";\nimport type { User } from \"../user/user.js\";\nimport { defaults, pick } from \"../util/object.js\";\nimport type { AnyVoid } from \"../util/types.js\";\nimport { parseArgs, type ArgsDefinition, type ArgsDefinitionResult, type ParseArgsOptions } from \"./arg.js\";\n\n/**\n * Represents the options that can be passed to {@linkcode Context.init}.\n */\nexport type ContextInit<Args extends ArgsDefinition> = ParseArgsOptions &\n StructuredLoggerOptions & {\n /**\n * The {@linkcode ArgsDefinition} to use to parse the arguments (`argv`).\n */\n parse?: Args;\n };\n\n/**\n * Represents the options that can be passed to {@linkcode Context.child}.\n *\n * @see {@linkcode Context.child}\n * @see {@linkcode ContextInit}\n */\nexport type ChildContextInit<Args extends ArgsDefinition, Parsed extends ArgsDefinitionResult<ArgsDefinition>> = Partial<\n ContextInit<Args>\n> & {\n /**\n * Replaces the parsed arguments of the parent context.\n */\n overwrite?: Partial<Omit<Parsed, \"_\">>;\n};\n\n/**\n * Represents the context of a command-line operation.\n */\nexport class Context<\n Args extends ArgsDefinition = EmptyObject,\n ParentArgs extends ArgsDefinition = RootArgs,\n ThisArgs extends ArgsDefinition = ParentArgs & Args,\n> extends AbortController {\n /**\n * The parsed command-line arguments for the current context and any\n * parent contexts.\n */\n readonly args: ArgsDefinitionResult<ThisArgs>;\n\n #log: Logger;\n #parent?: Context<ArgsDefinition, ParentArgs>;\n #user?: User;\n #app?: App;\n\n private constructor({\n args,\n log,\n parent,\n }: {\n parent?: Context<ArgsDefinition, ParentArgs>;\n args: ArgsDefinitionResult<ThisArgs>;\n log: Logger;\n }) {\n super();\n this.args = args;\n this.#log = log;\n this.#parent = parent;\n\n // in case this context is ...spread into another object\n this.abort = this.abort.bind(this);\n this.child = this.child.bind(this);\n this.onAbort = this.onAbort.bind(this);\n }\n\n /**\n * A {@linkcode Logger} that can print to stdout and log structured\n * messages to stderr.\n */\n get log(): Logger {\n return this.#log;\n }\n\n get user(): User | undefined {\n return this.#user ?? this.#parent?.user;\n }\n\n set user(user: User) {\n this.#user = user;\n if (this.#parent) {\n this.#parent.user = user;\n }\n\n this.#log = this.#log.child({ fields: { user: pick(user, [\"id\", \"name\", \"email\"]) } });\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n get app(): App | undefined {\n return this.#app ?? this.#parent?.app;\n }\n\n set app(app: App) {\n this.#app = app;\n if (this.#parent) {\n this.#parent.app = app;\n }\n\n this.#log = this.#log.child({ fields: { app } });\n }\n\n /**\n * Initializes a new context.\n *\n * @see {@linkcode ContextInit}\n */\n static init<Args extends ArgsDefinition = EmptyObject>({ parse: spec, ...options }: ContextInit<Args>): Context<Args> {\n return new Context({\n args: spec ? parseArgs(spec, pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"])) : ({} as ArgsDefinitionResult<Args>),\n log: createLogger(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n }\n\n /**\n * Returns a new context that is a child of the current context.\n *\n * @see {@linkcode ChildContextInit}\n */\n child<ChildArgs extends ArgsDefinition = EmptyObject>({\n parse: spec,\n ...options\n }: ChildContextInit<ChildArgs, ArgsDefinitionResult<ThisArgs>>): Context<ChildArgs, ThisArgs> {\n const ctx = new Context<ChildArgs, ThisArgs>({\n parent: this,\n args: {\n ...this.args,\n ...options.overwrite,\n ...(spec\n ? parseArgs(spec, defaults(pick(options, [\"argv\", \"permissive\", \"stopAtPositional\"]), { argv: this.args._ }))\n : ({} as ArgsDefinitionResult<ChildArgs>)),\n },\n log: this.log.child(pick(options, [\"name\", \"fields\", \"devFields\"])),\n });\n\n this.onAbort(() => ctx.abort());\n\n return ctx;\n }\n\n /**\n * Registers a callback that will be called when the context is\n * aborted (e.g. when the user presses Ctrl+C).\n *\n * @param callback - The callback to call when the context is aborted.\n */\n onAbort(callback: OnAbort): void {\n this.signal.addEventListener(\n \"abort\",\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async () => {\n try {\n assert(callback, \"callback must have been provided\");\n await callback(this.signal.reason);\n } catch (error: unknown) {\n this.log.error(\"error during abort\", { error });\n }\n },\n );\n }\n}\n\n/**\n * A callback that will be called when the context is aborted.\n */\nexport type OnAbort = (reason: unknown) => AnyVoid;\n"],"names":["assert","createLogger","defaults","pick","parseArgs","Context","AbortController","log","user","parent","child","fields","app","init","parse","spec","options","args","ctx","overwrite","argv","_","onAbort","abort","callback","signal","addEventListener","reason","error","bind"],"mappings":"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"}
|
|
@@ -2,12 +2,8 @@ import chalk from "chalk";
|
|
|
2
2
|
import pluralize from "pluralize";
|
|
3
3
|
import { config } from "../config/config.js";
|
|
4
4
|
import { Level } from "../output/log/level.js";
|
|
5
|
-
import { createLogger } from "../output/log/logger.js";
|
|
6
5
|
import { sprint } from "../output/sprint.js";
|
|
7
6
|
import { isNever, isString } from "../util/is.js";
|
|
8
|
-
const log = createLogger({
|
|
9
|
-
name: "changes"
|
|
10
|
-
});
|
|
11
7
|
export class Changes extends Map {
|
|
12
8
|
created() {
|
|
13
9
|
return Array.from(this.entries()).filter(([, change])=>change.type === "create").map(([path])=>path);
|
|
@@ -22,10 +18,12 @@ export class Changes extends Map {
|
|
|
22
18
|
/**
|
|
23
19
|
* Prints the changes to the console.
|
|
24
20
|
*
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
|
|
21
|
+
* @param ctx - The current context.
|
|
22
|
+
* @param options - The options to use.
|
|
23
|
+
* @param options.changes - The changes to print.
|
|
24
|
+
* @param options.tense - The tense to use for the change type.
|
|
25
|
+
* @param options.limit - The maximum number of changes to print.
|
|
26
|
+
*/ export const printChanges = (ctx, { changes, tense, limit = Infinity, ...tableOptions })=>{
|
|
29
27
|
if (config.logLevel <= Level.TRACE) {
|
|
30
28
|
// print all changes when tracing
|
|
31
29
|
limit = Infinity;
|
|
@@ -87,7 +85,7 @@ export class Changes extends Map {
|
|
|
87
85
|
footer += breakdown.join(", ");
|
|
88
86
|
footer += ".";
|
|
89
87
|
}
|
|
90
|
-
log.printTable({
|
|
88
|
+
ctx.log.printTable({
|
|
91
89
|
rows,
|
|
92
90
|
footer,
|
|
93
91
|
...tableOptions
|