1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | Object.defineProperty(exports, "__esModule", { value: true });
|
24 | exports.ListParam = exports.BooleanParam = exports.FloatParam = exports.IntParam = exports.InternalExpression = exports.StringParam = exports.SecretParam = exports.Param = exports.BUCKET_PICKER = exports.multiSelect = exports.select = exports.CompareExpression = exports.TernaryExpression = exports.Expression = void 0;
|
25 | const logger = require("../logger");
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | class Expression {
|
32 |
|
33 | value() {
|
34 | if (process.env.FUNCTIONS_CONTROL_API === "true") {
|
35 | logger.warn(`${this.toString()}.value() invoked during function deployment, instead of during runtime.`);
|
36 | logger.warn(`This is usually a mistake. In configs, use Params directly without calling .value().`);
|
37 | logger.warn(`example: { memory: memoryParam } not { memory: memoryParam.value() }`);
|
38 | }
|
39 | return this.runtimeValue();
|
40 | }
|
41 |
|
42 | runtimeValue() {
|
43 | throw new Error("Not implemented");
|
44 | }
|
45 |
|
46 | toCEL() {
|
47 | return `{{ ${this.toString()} }}`;
|
48 | }
|
49 |
|
50 | toJSON() {
|
51 | return this.toString();
|
52 | }
|
53 | }
|
54 | exports.Expression = Expression;
|
55 | function valueOf(arg) {
|
56 | return arg instanceof Expression ? arg.runtimeValue() : arg;
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | function refOf(arg) {
|
66 | if (arg instanceof Expression) {
|
67 | return arg.toString();
|
68 | }
|
69 | else if (typeof arg === "string") {
|
70 | return `"${arg}"`;
|
71 | }
|
72 | else if (Array.isArray(arg)) {
|
73 | return JSON.stringify(arg);
|
74 | }
|
75 | else {
|
76 | return arg.toString();
|
77 | }
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 | class TernaryExpression extends Expression {
|
83 | constructor(test, ifTrue, ifFalse) {
|
84 | super();
|
85 | this.test = test;
|
86 | this.ifTrue = ifTrue;
|
87 | this.ifFalse = ifFalse;
|
88 | this.ifTrue = ifTrue;
|
89 | this.ifFalse = ifFalse;
|
90 | }
|
91 |
|
92 | runtimeValue() {
|
93 | return this.test.runtimeValue() ? valueOf(this.ifTrue) : valueOf(this.ifFalse);
|
94 | }
|
95 | toString() {
|
96 | return `${this.test} ? ${refOf(this.ifTrue)} : ${refOf(this.ifFalse)}`;
|
97 | }
|
98 | }
|
99 | exports.TernaryExpression = TernaryExpression;
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | class CompareExpression extends Expression {
|
105 | constructor(cmp, lhs, rhs) {
|
106 | super();
|
107 | this.cmp = cmp;
|
108 | this.lhs = lhs;
|
109 | this.rhs = rhs;
|
110 | }
|
111 |
|
112 | runtimeValue() {
|
113 | const left = this.lhs.runtimeValue();
|
114 | const right = valueOf(this.rhs);
|
115 | switch (this.cmp) {
|
116 | case "==":
|
117 | return Array.isArray(left) ? this.arrayEquals(left, right) : left === right;
|
118 | case "!=":
|
119 | return Array.isArray(left) ? !this.arrayEquals(left, right) : left !== right;
|
120 | case ">":
|
121 | return left > right;
|
122 | case ">=":
|
123 | return left >= right;
|
124 | case "<":
|
125 | return left < right;
|
126 | case "<=":
|
127 | return left <= right;
|
128 | default:
|
129 | throw new Error(`Unknown comparator ${this.cmp}`);
|
130 | }
|
131 | }
|
132 |
|
133 | arrayEquals(a, b) {
|
134 | return a.every((item) => b.includes(item)) && b.every((item) => a.includes(item));
|
135 | }
|
136 | toString() {
|
137 | const rhsStr = refOf(this.rhs);
|
138 | return `${this.lhs} ${this.cmp} ${rhsStr}`;
|
139 | }
|
140 |
|
141 | thenElse(ifTrue, ifFalse) {
|
142 | return new TernaryExpression(this, ifTrue, ifFalse);
|
143 | }
|
144 | }
|
145 | exports.CompareExpression = CompareExpression;
|
146 |
|
147 | function select(options) {
|
148 | let wireOpts;
|
149 | if (Array.isArray(options)) {
|
150 | wireOpts = options.map((opt) => ({ value: opt }));
|
151 | }
|
152 | else {
|
153 | wireOpts = Object.entries(options).map(([label, value]) => ({ label, value }));
|
154 | }
|
155 | return {
|
156 | select: {
|
157 | options: wireOpts,
|
158 | },
|
159 | };
|
160 | }
|
161 | exports.select = select;
|
162 |
|
163 | function multiSelect(options) {
|
164 | let wireOpts;
|
165 | if (Array.isArray(options)) {
|
166 | wireOpts = options.map((opt) => ({ value: opt }));
|
167 | }
|
168 | else {
|
169 | wireOpts = Object.entries(options).map(([label, value]) => ({ label, value }));
|
170 | }
|
171 | return {
|
172 | multiSelect: {
|
173 | options: wireOpts,
|
174 | },
|
175 | };
|
176 | }
|
177 | exports.multiSelect = multiSelect;
|
178 |
|
179 |
|
180 |
|
181 | exports.BUCKET_PICKER = {
|
182 | resource: {
|
183 | type: "storage.googleapis.com/Bucket",
|
184 | },
|
185 | };
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | class Param extends Expression {
|
192 | constructor(name, options = {}) {
|
193 | super();
|
194 | this.name = name;
|
195 | this.options = options;
|
196 | }
|
197 |
|
198 | runtimeValue() {
|
199 | throw new Error("Not implemented");
|
200 | }
|
201 |
|
202 | cmp(cmp, rhs) {
|
203 | return new CompareExpression(cmp, this, rhs);
|
204 | }
|
205 |
|
206 | equals(rhs) {
|
207 | return this.cmp("==", rhs);
|
208 | }
|
209 |
|
210 | notEquals(rhs) {
|
211 | return this.cmp("!=", rhs);
|
212 | }
|
213 |
|
214 | greaterThan(rhs) {
|
215 | return this.cmp(">", rhs);
|
216 | }
|
217 |
|
218 | greaterThanOrEqualTo(rhs) {
|
219 | return this.cmp(">=", rhs);
|
220 | }
|
221 |
|
222 | lessThan(rhs) {
|
223 | return this.cmp("<", rhs);
|
224 | }
|
225 |
|
226 | lessThanOrEqualTo(rhs) {
|
227 | return this.cmp("<=", rhs);
|
228 | }
|
229 | |
230 |
|
231 |
|
232 |
|
233 | lessThanorEqualTo(rhs) {
|
234 | return this.lessThanOrEqualTo(rhs);
|
235 | }
|
236 | toString() {
|
237 | return `params.${this.name}`;
|
238 | }
|
239 |
|
240 | toSpec() {
|
241 | const { default: paramDefault, ...otherOptions } = this.options;
|
242 | const out = {
|
243 | name: this.name,
|
244 | ...otherOptions,
|
245 | type: this.constructor.type,
|
246 | };
|
247 | if (paramDefault instanceof Expression) {
|
248 | out.default = paramDefault.toCEL();
|
249 | }
|
250 | else if (paramDefault !== undefined) {
|
251 | out.default = paramDefault;
|
252 | }
|
253 | if (out.input && "text" in out.input && out.input.text.validationRegex instanceof RegExp) {
|
254 | out.input.text.validationRegex = out.input.text.validationRegex.source;
|
255 | }
|
256 | return out;
|
257 | }
|
258 | }
|
259 | exports.Param = Param;
|
260 | Param.type = "string";
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 | class SecretParam {
|
268 | constructor(name) {
|
269 | this.name = name;
|
270 | }
|
271 |
|
272 | runtimeValue() {
|
273 | const val = process.env[this.name];
|
274 | if (val === undefined) {
|
275 | logger.warn(`No value found for secret parameter "${this.name}". A function can only access a secret if you include the secret in the function's dependency array.`);
|
276 | }
|
277 | return val || "";
|
278 | }
|
279 |
|
280 | toSpec() {
|
281 | return {
|
282 | type: "secret",
|
283 | name: this.name,
|
284 | };
|
285 | }
|
286 |
|
287 | value() {
|
288 | if (process.env.FUNCTIONS_CONTROL_API === "true") {
|
289 | throw new Error(`Cannot access the value of secret "${this.name}" during function deployment. Secret values are only available at runtime.`);
|
290 | }
|
291 | return this.runtimeValue();
|
292 | }
|
293 | }
|
294 | exports.SecretParam = SecretParam;
|
295 | SecretParam.type = "secret";
|
296 |
|
297 |
|
298 |
|
299 |
|
300 | class StringParam extends Param {
|
301 |
|
302 | runtimeValue() {
|
303 | return process.env[this.name] || "";
|
304 | }
|
305 | }
|
306 | exports.StringParam = StringParam;
|
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 | class InternalExpression extends Param {
|
315 | constructor(name, getter) {
|
316 | super(name);
|
317 | this.getter = getter;
|
318 | }
|
319 |
|
320 | runtimeValue() {
|
321 | return this.getter(process.env) || "";
|
322 | }
|
323 | toSpec() {
|
324 | throw new Error("An InternalExpression should never be marshalled for wire transmission.");
|
325 | }
|
326 | }
|
327 | exports.InternalExpression = InternalExpression;
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | class IntParam extends Param {
|
333 |
|
334 | runtimeValue() {
|
335 | return parseInt(process.env[this.name] || "0", 10) || 0;
|
336 | }
|
337 | }
|
338 | exports.IntParam = IntParam;
|
339 | IntParam.type = "int";
|
340 |
|
341 |
|
342 |
|
343 |
|
344 | class FloatParam extends Param {
|
345 |
|
346 | runtimeValue() {
|
347 | return parseFloat(process.env[this.name] || "0") || 0;
|
348 | }
|
349 | }
|
350 | exports.FloatParam = FloatParam;
|
351 | FloatParam.type = "float";
|
352 |
|
353 |
|
354 |
|
355 |
|
356 | class BooleanParam extends Param {
|
357 |
|
358 | runtimeValue() {
|
359 | return !!process.env[this.name] && process.env[this.name] === "true";
|
360 | }
|
361 |
|
362 | then(ifTrue, ifFalse) {
|
363 | return this.thenElse(ifTrue, ifFalse);
|
364 | }
|
365 | thenElse(ifTrue, ifFalse) {
|
366 | return new TernaryExpression(this, ifTrue, ifFalse);
|
367 | }
|
368 | }
|
369 | exports.BooleanParam = BooleanParam;
|
370 | BooleanParam.type = "boolean";
|
371 |
|
372 |
|
373 |
|
374 |
|
375 | class ListParam extends Param {
|
376 |
|
377 | runtimeValue() {
|
378 | const val = JSON.parse(process.env[this.name]);
|
379 | if (!Array.isArray(val) || !val.every((v) => typeof v === "string")) {
|
380 | return [];
|
381 | }
|
382 | return val;
|
383 | }
|
384 |
|
385 |
|
386 | greaterThan(rhs) {
|
387 | throw new Error(">/< comparison operators not supported on params of type List");
|
388 | }
|
389 |
|
390 |
|
391 | greaterThanOrEqualTo(rhs) {
|
392 | throw new Error(">/< comparison operators not supported on params of type List");
|
393 | }
|
394 |
|
395 |
|
396 | lessThan(rhs) {
|
397 | throw new Error(">/< comparison operators not supported on params of type List");
|
398 | }
|
399 |
|
400 |
|
401 | lessThanorEqualTo(rhs) {
|
402 | throw new Error(">/< comparison operators not supported on params of type List");
|
403 | }
|
404 | }
|
405 | exports.ListParam = ListParam;
|
406 | ListParam.type = "list";
|