/
ext-configure.ts
162 lines (145 loc) · 5.14 KB
/
ext-configure.ts
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const { marked } = require("marked");
import TerminalRenderer = require("marked-terminal");
import { checkMinRequiredVersion } from "../checkMinRequiredVersion";
import { Command } from "../command";
import { FirebaseError } from "../error";
import { needProjectId, getProjectId } from "../projectUtils";
import * as extensionsApi from "../extensions/extensionsApi";
import {
logPrefix,
diagnoseAndFixProject,
createSourceFromLocation,
isLocalPath,
} from "../extensions/extensionsHelper";
import * as paramHelper from "../extensions/paramHelper";
import { requirePermissions } from "../requirePermissions";
import * as utils from "../utils";
import { logger } from "../logger";
import * as refs from "../extensions/refs";
import * as manifest from "../extensions/manifest";
import { Options } from "../options";
import { partition } from "../functional";
import { buildBindingOptionsWithBaseValue, getBaseParamBindings } from "../extensions/paramHelper";
import * as askUserForEventsConfig from "../extensions/askUserForEventsConfig";
marked.setOptions({
renderer: new TerminalRenderer(),
});
/**
* Command for configuring an existing extension instance
*/
export default new Command("ext:configure <extensionInstanceId>")
.description("configure an existing extension instance")
.withForce()
.option("--local", "deprecated")
.before(requirePermissions, [
"firebaseextensions.instances.update",
"firebaseextensions.instances.get",
])
.before(checkMinRequiredVersion, "extMinVersion")
.before(diagnoseAndFixProject)
.action(async (instanceId: string, options: Options) => {
const projectId = getProjectId(options);
if (options.nonInteractive) {
throw new FirebaseError(
`Command not supported in non-interactive mode, edit ./extensions/${instanceId}.env directly instead. ` +
`See https://firebase.google.com/docs/extensions/manifest for more details.`
);
}
if (options.local) {
utils.logLabeledWarning(
logPrefix,
"As of firebase-tools@11.0.0, the `--local` flag is no longer required, as it is the default behavior."
);
}
const config = manifest.loadConfig(options);
const refOrPath = manifest.getInstanceTarget(instanceId, config);
const isLocalSource = isLocalPath(refOrPath);
let spec: extensionsApi.ExtensionSpec;
if (isLocalSource) {
const source = await createSourceFromLocation(needProjectId({ projectId }), refOrPath);
spec = source.spec;
} else {
const extensionVersion = await extensionsApi.getExtensionVersion(refOrPath);
spec = extensionVersion.spec;
}
const oldParamValues = manifest.readInstanceParam({
instanceId,
projectDir: config.projectDir,
});
const [immutableParams, tbdParams] = partition(
spec.params,
(param) => param.immutable ?? false
);
infoImmutableParams(immutableParams, oldParamValues);
// Ask for mutable param values from user.
paramHelper.setNewDefaults(tbdParams, oldParamValues);
const mutableParamsBindingOptions = await paramHelper.getParams({
projectId,
paramSpecs: tbdParams,
nonInteractive: false,
// TODO(b/230598656): Clean up paramsEnvPath after v11 launch.
paramsEnvPath: "",
instanceId,
reconfiguring: true,
});
// Ask for events config
const eventsConfig = spec.events
? await askUserForEventsConfig.askForEventsConfig(
spec.events,
"${param:PROJECT_ID}",
instanceId
)
: undefined;
if (eventsConfig) {
mutableParamsBindingOptions.EVENTARC_CHANNEL = { baseValue: eventsConfig.channel };
mutableParamsBindingOptions.ALLOWED_EVENT_TYPES = {
baseValue: eventsConfig.allowedEventTypes.join(","),
};
}
// Merge with old immutable params.
const newParamOptions = {
...buildBindingOptionsWithBaseValue(oldParamValues),
...mutableParamsBindingOptions,
};
await manifest.writeToManifest(
[
{
instanceId,
ref: !isLocalSource ? refs.parse(refOrPath) : undefined,
localPath: isLocalSource ? refOrPath : undefined,
params: newParamOptions,
extensionSpec: spec,
},
],
config,
{
nonInteractive: false,
force: true, // Skip asking for permission again
}
);
manifest.showPostDeprecationNotice();
return;
});
function infoImmutableParams(
immutableParams: extensionsApi.Param[],
paramValues: { [key: string]: string }
) {
if (!immutableParams.length) {
return;
}
const plural = immutableParams.length > 1;
utils.logLabeledWarning(
logPrefix,
marked(`The following param${plural ? "s are" : " is"} immutable and won't be changed:`)
);
for (const { param } of immutableParams) {
logger.info(`param: ${param}, value: ${paramValues[param]}`);
}
logger.info(
(plural
? "To set different values for these params"
: "To set a different value for this param") +
", uninstall the extension, then install a new instance of this extension."
);
}