-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpush.ts
More file actions
139 lines (118 loc) · 4.16 KB
/
push.ts
File metadata and controls
139 lines (118 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { Args, Flags } from "@oclif/core";
import BaseCommand from "@/lib/base-command";
import { formatCommandScope } from "@/lib/helpers/command";
import { KnockEnv } from "@/lib/helpers/const";
import { formatError, formatErrors, SourceError } from "@/lib/helpers/error";
import * as CustomFlags from "@/lib/helpers/flag";
import { merge } from "@/lib/helpers/object.isomorphic";
import { formatErrorRespMessage, isSuccessResp } from "@/lib/helpers/request";
import { indentString } from "@/lib/helpers/string";
import { spinner } from "@/lib/helpers/ux";
import * as MessageType from "@/lib/marshal/message-type";
import { WithAnnotation } from "@/lib/marshal/shared/types";
import MessageTypeValidate from "./validate";
export default class MessageTypePush extends BaseCommand<
typeof MessageTypePush
> {
static summary =
"Push one or more message types from a local file system to Knock.";
static flags = {
environment: Flags.string({
summary:
"Pushing a message type is only allowed in the development environment",
default: KnockEnv.Development,
options: [KnockEnv.Development],
}),
branch: CustomFlags.branch,
all: Flags.boolean({
summary: "Whether to push all message types from the target directory.",
}),
"message-types-dir": CustomFlags.dirPath({
summary: "The target directory path to find all message types to push.",
dependsOn: ["all"],
}),
commit: Flags.boolean({
summary: "Push and commit the message type(s) at the same time",
}),
"commit-message": Flags.string({
summary: "Use the given value as the commit message",
char: "m",
dependsOn: ["commit"],
}),
};
static args = {
messageTypeKey: Args.string({
required: false,
}),
};
async run(): Promise<void> {
const { flags } = this.props;
// 1. First read all message type directories found for the given command.
const target = await MessageType.ensureValidCommandTarget(
this.props,
this.runContext,
this.projectConfig,
);
const [messageTypes, readErrors] =
await MessageType.readAllForCommandTarget(target, {
withExtractedFiles: true,
});
if (readErrors.length > 0) {
this.error(formatErrors(readErrors, { prependBy: "\n\n" }));
}
if (messageTypes.length === 0) {
this.error(
`No message type directories found in ${target.context.abspath}`,
);
}
// 2. Then validate them all ahead of pushing them.
spinner.start(`‣ Validating`);
const apiErrors = await MessageTypeValidate.validateAll(
this.apiV1,
this.props,
messageTypes,
);
if (apiErrors.length > 0) {
this.error(formatErrors(apiErrors, { prependBy: "\n\n" }));
}
spinner.stop();
// 3. Finally push up each message type, abort on the first error.
spinner.start(`‣ Pushing`);
for (const messageType of messageTypes) {
const props = merge(this.props, {
flags: { annotate: true },
});
// eslint-disable-next-line no-await-in-loop
const resp = await this.apiV1.upsertMessageType<WithAnnotation>(props, {
...messageType.content,
key: messageType.key,
});
if (isSuccessResp(resp)) {
// Update the message type directory with the successfully pushed message
// type payload from the server.
// eslint-disable-next-line no-await-in-loop
await MessageType.writeMessageTypeDirFromData(
messageType,
resp.data.message_type!,
{ withSchema: true },
);
continue;
}
const error = new SourceError(
formatErrorRespMessage(resp),
MessageType.messageTypeJsonPath(messageType),
"ApiError",
);
this.error(formatError(error));
}
spinner.stop();
// 4. Display a success message.
const messageTypeKeys = messageTypes.map((w) => w.key);
const actioned = flags.commit ? "pushed and committed" : "pushed";
const scope = formatCommandScope(flags);
this.log(
`‣ Successfully ${actioned} ${messageTypes.length} message type(s) to ${scope}:\n` +
indentString(messageTypeKeys.join("\n"), 4),
);
}
}