UNPKG

14.2 kBJavaScriptView Raw
1/*! firebase-admin v10.0.0 */
2"use strict";
3/*!
4 * Copyright 2020 Google Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18Object.defineProperty(exports, "__esModule", { value: true });
19exports.RemoteConfig = void 0;
20var validator = require("../utils/validator");
21var remote_config_api_client_internal_1 = require("./remote-config-api-client-internal");
22/**
23 * The Firebase `RemoteConfig` service interface.
24 */
25var RemoteConfig = /** @class */ (function () {
26 /**
27 * @param app - The app for this RemoteConfig service.
28 * @constructor
29 * @internal
30 */
31 function RemoteConfig(app) {
32 this.app = app;
33 this.client = new remote_config_api_client_internal_1.RemoteConfigApiClient(app);
34 }
35 /**
36 * Gets the current active version of the {@link RemoteConfigTemplate} of the project.
37 *
38 * @returns A promise that fulfills with a `RemoteConfigTemplate`.
39 */
40 RemoteConfig.prototype.getTemplate = function () {
41 return this.client.getTemplate()
42 .then(function (templateResponse) {
43 return new RemoteConfigTemplateImpl(templateResponse);
44 });
45 };
46 /**
47 * Gets the requested version of the {@link RemoteConfigTemplate} of the project.
48 *
49 * @param versionNumber - Version number of the Remote Config template to look up.
50 *
51 * @returns A promise that fulfills with a `RemoteConfigTemplate`.
52 */
53 RemoteConfig.prototype.getTemplateAtVersion = function (versionNumber) {
54 return this.client.getTemplateAtVersion(versionNumber)
55 .then(function (templateResponse) {
56 return new RemoteConfigTemplateImpl(templateResponse);
57 });
58 };
59 /**
60 * Validates a {@link RemoteConfigTemplate}.
61 *
62 * @param template - The Remote Config template to be validated.
63 * @returns A promise that fulfills with the validated `RemoteConfigTemplate`.
64 */
65 RemoteConfig.prototype.validateTemplate = function (template) {
66 return this.client.validateTemplate(template)
67 .then(function (templateResponse) {
68 return new RemoteConfigTemplateImpl(templateResponse);
69 });
70 };
71 /**
72 * Publishes a Remote Config template.
73 *
74 * @param template - The Remote Config template to be published.
75 * @param options - Optional options object when publishing a Remote Config template:
76 * - `force`: Setting this to `true` forces the Remote Config template to
77 * be updated and circumvent the ETag. This approach is not recommended
78 * because it risks causing the loss of updates to your Remote Config
79 * template if multiple clients are updating the Remote Config template.
80 * See {@link https://firebase.google.com/docs/remote-config/use-config-rest#etag_usage_and_forced_updates |
81 * ETag usage and forced updates}.
82 *
83 * @returns A Promise that fulfills with the published `RemoteConfigTemplate`.
84 */
85 RemoteConfig.prototype.publishTemplate = function (template, options) {
86 return this.client.publishTemplate(template, options)
87 .then(function (templateResponse) {
88 return new RemoteConfigTemplateImpl(templateResponse);
89 });
90 };
91 /**
92 * Rolls back a project's published Remote Config template to the specified version.
93 * A rollback is equivalent to getting a previously published Remote Config
94 * template and re-publishing it using a force update.
95 *
96 * @param versionNumber - The version number of the Remote Config template to roll back to.
97 * The specified version number must be lower than the current version number, and not have
98 * been deleted due to staleness. Only the last 300 versions are stored.
99 * All versions that correspond to non-active Remote Config templates (that is, all except the
100 * template that is being fetched by clients) are also deleted if they are more than 90 days old.
101 * @returns A promise that fulfills with the published `RemoteConfigTemplate`.
102 */
103 RemoteConfig.prototype.rollback = function (versionNumber) {
104 return this.client.rollback(versionNumber)
105 .then(function (templateResponse) {
106 return new RemoteConfigTemplateImpl(templateResponse);
107 });
108 };
109 /**
110 * Gets a list of Remote Config template versions that have been published, sorted in reverse
111 * chronological order. Only the last 300 versions are stored.
112 * All versions that correspond to non-active Remote Config templates (i.e., all except the
113 * template that is being fetched by clients) are also deleted if they are older than 90 days.
114 *
115 * @param options - Optional options object for getting a list of versions.
116 * @returns A promise that fulfills with a `ListVersionsResult`.
117 */
118 RemoteConfig.prototype.listVersions = function (options) {
119 return this.client.listVersions(options)
120 .then(function (listVersionsResponse) {
121 var _a, _b;
122 return {
123 versions: (_b = (_a = listVersionsResponse.versions) === null || _a === void 0 ? void 0 : _a.map(function (version) { return new VersionImpl(version); })) !== null && _b !== void 0 ? _b : [],
124 nextPageToken: listVersionsResponse.nextPageToken,
125 };
126 });
127 };
128 /**
129 * Creates and returns a new Remote Config template from a JSON string.
130 *
131 * @param json - The JSON string to populate a Remote Config template.
132 *
133 * @returns A new template instance.
134 */
135 RemoteConfig.prototype.createTemplateFromJSON = function (json) {
136 if (!validator.isNonEmptyString(json)) {
137 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'JSON string must be a valid non-empty string');
138 }
139 var template;
140 try {
141 template = JSON.parse(json);
142 }
143 catch (e) {
144 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', "Failed to parse the JSON string: " + json + ". " + e);
145 }
146 return new RemoteConfigTemplateImpl(template);
147 };
148 return RemoteConfig;
149}());
150exports.RemoteConfig = RemoteConfig;
151/**
152 * Remote Config template internal implementation.
153 */
154var RemoteConfigTemplateImpl = /** @class */ (function () {
155 function RemoteConfigTemplateImpl(config) {
156 if (!validator.isNonNullObject(config) ||
157 !validator.isNonEmptyString(config.etag)) {
158 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', "Invalid Remote Config template: " + JSON.stringify(config));
159 }
160 this.etagInternal = config.etag;
161 if (typeof config.parameters !== 'undefined') {
162 if (!validator.isNonNullObject(config.parameters)) {
163 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Remote Config parameters must be a non-null object');
164 }
165 this.parameters = config.parameters;
166 }
167 else {
168 this.parameters = {};
169 }
170 if (typeof config.parameterGroups !== 'undefined') {
171 if (!validator.isNonNullObject(config.parameterGroups)) {
172 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Remote Config parameter groups must be a non-null object');
173 }
174 this.parameterGroups = config.parameterGroups;
175 }
176 else {
177 this.parameterGroups = {};
178 }
179 if (typeof config.conditions !== 'undefined') {
180 if (!validator.isArray(config.conditions)) {
181 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Remote Config conditions must be an array');
182 }
183 this.conditions = config.conditions;
184 }
185 else {
186 this.conditions = [];
187 }
188 if (typeof config.version !== 'undefined') {
189 this.version = new VersionImpl(config.version);
190 }
191 }
192 Object.defineProperty(RemoteConfigTemplateImpl.prototype, "etag", {
193 /**
194 * Gets the ETag of the template.
195 *
196 * @returns The ETag of the Remote Config template.
197 */
198 get: function () {
199 return this.etagInternal;
200 },
201 enumerable: false,
202 configurable: true
203 });
204 /**
205 * Returns a JSON-serializable representation of this object.
206 *
207 * @returns A JSON-serializable representation of this object.
208 */
209 RemoteConfigTemplateImpl.prototype.toJSON = function () {
210 return {
211 conditions: this.conditions,
212 parameters: this.parameters,
213 parameterGroups: this.parameterGroups,
214 etag: this.etag,
215 version: this.version,
216 };
217 };
218 return RemoteConfigTemplateImpl;
219}());
220/**
221* Remote Config Version internal implementation.
222*/
223var VersionImpl = /** @class */ (function () {
224 function VersionImpl(version) {
225 if (!validator.isNonNullObject(version)) {
226 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', "Invalid Remote Config version instance: " + JSON.stringify(version));
227 }
228 if (typeof version.versionNumber !== 'undefined') {
229 if (!validator.isNonEmptyString(version.versionNumber) &&
230 !validator.isNumber(version.versionNumber)) {
231 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version number must be a non-empty string in int64 format or a number');
232 }
233 if (!Number.isInteger(Number(version.versionNumber))) {
234 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version number must be an integer or a string in int64 format');
235 }
236 this.versionNumber = version.versionNumber;
237 }
238 if (typeof version.updateOrigin !== 'undefined') {
239 if (!validator.isNonEmptyString(version.updateOrigin)) {
240 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version update origin must be a non-empty string');
241 }
242 this.updateOrigin = version.updateOrigin;
243 }
244 if (typeof version.updateType !== 'undefined') {
245 if (!validator.isNonEmptyString(version.updateType)) {
246 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version update type must be a non-empty string');
247 }
248 this.updateType = version.updateType;
249 }
250 if (typeof version.updateUser !== 'undefined') {
251 if (!validator.isNonNullObject(version.updateUser)) {
252 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version update user must be a non-null object');
253 }
254 this.updateUser = version.updateUser;
255 }
256 if (typeof version.description !== 'undefined') {
257 if (!validator.isNonEmptyString(version.description)) {
258 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version description must be a non-empty string');
259 }
260 this.description = version.description;
261 }
262 if (typeof version.rollbackSource !== 'undefined') {
263 if (!validator.isNonEmptyString(version.rollbackSource)) {
264 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version rollback source must be a non-empty string');
265 }
266 this.rollbackSource = version.rollbackSource;
267 }
268 if (typeof version.isLegacy !== 'undefined') {
269 if (!validator.isBoolean(version.isLegacy)) {
270 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version.isLegacy must be a boolean');
271 }
272 this.isLegacy = version.isLegacy;
273 }
274 // The backend API provides timestamps in ISO date strings. The Admin SDK exposes timestamps
275 // in UTC date strings. If a developer uses a previously obtained template with UTC timestamps
276 // we could still validate it below.
277 if (typeof version.updateTime !== 'undefined') {
278 if (!this.isValidTimestamp(version.updateTime)) {
279 throw new remote_config_api_client_internal_1.FirebaseRemoteConfigError('invalid-argument', 'Version update time must be a valid date string');
280 }
281 this.updateTime = new Date(version.updateTime).toUTCString();
282 }
283 }
284 /**
285 * @returns A JSON-serializable representation of this object.
286 */
287 VersionImpl.prototype.toJSON = function () {
288 return {
289 versionNumber: this.versionNumber,
290 updateOrigin: this.updateOrigin,
291 updateType: this.updateType,
292 updateUser: this.updateUser,
293 description: this.description,
294 rollbackSource: this.rollbackSource,
295 isLegacy: this.isLegacy,
296 updateTime: this.updateTime,
297 };
298 };
299 VersionImpl.prototype.isValidTimestamp = function (timestamp) {
300 // This validation fails for timestamps earlier than January 1, 1970 and considers strings
301 // such as "1.2" as valid timestamps.
302 return validator.isNonEmptyString(timestamp) && (new Date(timestamp)).getTime() > 0;
303 };
304 return VersionImpl;
305}());