firebase-admin-edge 3.0.2 → 3.1.0
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 +17 -14
- package/THIRD_PARTY_NOTICES.md +62 -0
- package/dist/firebase-edge-server.d.ts +2 -0
- package/dist/firebase-edge-server.d.ts.map +1 -1
- package/dist/firebase-edge-server.js +7 -0
- package/dist/firebase-edge-server.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/remote-config/condition-evaluator.d.ts +6 -0
- package/dist/remote-config/condition-evaluator.d.ts.map +1 -0
- package/dist/remote-config/condition-evaluator.js +122 -0
- package/dist/remote-config/condition-evaluator.js.map +1 -0
- package/dist/remote-config/remote-config-endpoints.d.ts +22 -0
- package/dist/remote-config/remote-config-endpoints.d.ts.map +1 -0
- package/dist/remote-config/remote-config-endpoints.js +161 -0
- package/dist/remote-config/remote-config-endpoints.js.map +1 -0
- package/dist/remote-config/remote-config-fetch-response.d.ts +8 -0
- package/dist/remote-config/remote-config-fetch-response.d.ts.map +1 -0
- package/dist/remote-config/remote-config-fetch-response.js +26 -0
- package/dist/remote-config/remote-config-fetch-response.js.map +1 -0
- package/dist/remote-config/remote-config-results.d.ts +15 -0
- package/dist/remote-config/remote-config-results.d.ts.map +1 -0
- package/dist/remote-config/remote-config-results.js +26 -0
- package/dist/remote-config/remote-config-results.js.map +1 -0
- package/dist/remote-config/remote-config-template.d.ts +20 -0
- package/dist/remote-config/remote-config-template.d.ts.map +1 -0
- package/dist/remote-config/remote-config-template.js +129 -0
- package/dist/remote-config/remote-config-template.js.map +1 -0
- package/dist/remote-config/remote-config-types.d.ts +807 -0
- package/dist/remote-config/remote-config-types.d.ts.map +1 -0
- package/dist/remote-config/remote-config-types.js +119 -0
- package/dist/remote-config/remote-config-types.js.map +1 -0
- package/dist/remote-config/remote-config.d.ts +34 -0
- package/dist/remote-config/remote-config.d.ts.map +1 -0
- package/dist/remote-config/remote-config.js +112 -0
- package/dist/remote-config/remote-config.js.map +1 -0
- package/dist/remote-config/server-template.d.ts +33 -0
- package/dist/remote-config/server-template.d.ts.map +1 -0
- package/dist/remote-config/server-template.js +145 -0
- package/dist/remote-config/server-template.js.map +1 -0
- package/dist/rest-fetch.d.ts +1 -1
- package/dist/rest-fetch.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { FirebaseEdgeError } from '../auth/errors.js';
|
|
2
|
+
import { restFetch } from '../rest-fetch.js';
|
|
3
|
+
import { invalidRemoteConfig, isRemoteConfigObject } from './remote-config-results.js';
|
|
4
|
+
import { normalizeTemplate, normalizeVersion, validateVersionNumber } from './remote-config-template.js';
|
|
5
|
+
/** @internal Validate list options and convert dates to the REST representation. */
|
|
6
|
+
export function remoteConfigListParams(options = {}) {
|
|
7
|
+
if (!isRemoteConfigObject(options)) {
|
|
8
|
+
invalidRemoteConfig('List options must be an object.');
|
|
9
|
+
}
|
|
10
|
+
const params = {};
|
|
11
|
+
if (options.pageSize !== undefined) {
|
|
12
|
+
if (!Number.isInteger(options.pageSize) ||
|
|
13
|
+
options.pageSize < 1 ||
|
|
14
|
+
options.pageSize > 300) {
|
|
15
|
+
invalidRemoteConfig('pageSize must be an integer between 1 and 300.');
|
|
16
|
+
}
|
|
17
|
+
params.pageSize = String(options.pageSize);
|
|
18
|
+
}
|
|
19
|
+
if (options.pageToken !== undefined) {
|
|
20
|
+
if (typeof options.pageToken !== 'string' ||
|
|
21
|
+
!options.pageToken.trim()) {
|
|
22
|
+
invalidRemoteConfig('pageToken must be a non-empty string.');
|
|
23
|
+
}
|
|
24
|
+
params.pageToken = options.pageToken;
|
|
25
|
+
}
|
|
26
|
+
if (options.endVersionNumber !== undefined) {
|
|
27
|
+
params.endVersionNumber = validateVersionNumber(options.endVersionNumber);
|
|
28
|
+
}
|
|
29
|
+
for (const key of ['startTime', 'endTime']) {
|
|
30
|
+
const value = options[key];
|
|
31
|
+
if (value === undefined) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!(value instanceof Date) &&
|
|
35
|
+
(typeof value !== 'string' || !value.trim())) {
|
|
36
|
+
invalidRemoteConfig(`${key} must be a date or date string.`);
|
|
37
|
+
}
|
|
38
|
+
const date = new Date(value);
|
|
39
|
+
if (!Number.isFinite(date.getTime())) {
|
|
40
|
+
invalidRemoteConfig(`Invalid ${key}.`);
|
|
41
|
+
}
|
|
42
|
+
params[key] = date.toISOString();
|
|
43
|
+
}
|
|
44
|
+
return params;
|
|
45
|
+
}
|
|
46
|
+
/** @internal Owns Remote Config URLs, ETags, request bodies, and API errors. */
|
|
47
|
+
export async function remoteConfigRequest(projectId, accessToken, operation, fetch) {
|
|
48
|
+
let path = 'remoteConfig';
|
|
49
|
+
let method = 'GET';
|
|
50
|
+
let body;
|
|
51
|
+
let params;
|
|
52
|
+
let originalEtag;
|
|
53
|
+
const headers = { 'Accept-Encoding': 'gzip' };
|
|
54
|
+
switch (operation.type) {
|
|
55
|
+
case 'get':
|
|
56
|
+
if ('version' in operation) {
|
|
57
|
+
params = {
|
|
58
|
+
versionNumber: validateVersionNumber(operation.version)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
case 'rollback':
|
|
63
|
+
path += ':rollback';
|
|
64
|
+
method = 'POST';
|
|
65
|
+
body = { versionNumber: validateVersionNumber(operation.version) };
|
|
66
|
+
break;
|
|
67
|
+
case 'list':
|
|
68
|
+
path += ':listVersions';
|
|
69
|
+
params = remoteConfigListParams(operation.options);
|
|
70
|
+
break;
|
|
71
|
+
case 'server':
|
|
72
|
+
path = 'namespaces/firebase-server/serverRemoteConfig';
|
|
73
|
+
break;
|
|
74
|
+
case 'publish':
|
|
75
|
+
case 'validate': {
|
|
76
|
+
if (operation.force !== undefined &&
|
|
77
|
+
typeof operation.force !== 'boolean') {
|
|
78
|
+
invalidRemoteConfig('force must be a boolean.');
|
|
79
|
+
}
|
|
80
|
+
const template = normalizeTemplate(operation.template);
|
|
81
|
+
method = 'PUT';
|
|
82
|
+
headers['If-Match'] = operation.force ? '*' : template.etag;
|
|
83
|
+
body = {
|
|
84
|
+
conditions: template.conditions,
|
|
85
|
+
parameters: template.parameters,
|
|
86
|
+
parameterGroups: template.parameterGroups ?? {},
|
|
87
|
+
...(template.version && {
|
|
88
|
+
version: { description: template.version.description }
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
if (operation.type === 'validate') {
|
|
92
|
+
params = { validate_only: 'true' };
|
|
93
|
+
originalEtag = template.etag;
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
let responseEtag = null;
|
|
99
|
+
let responseStatus = 0;
|
|
100
|
+
const captureFetch = async (input, init) => {
|
|
101
|
+
const response = await fetch(input, init);
|
|
102
|
+
responseEtag = response.headers.get('etag');
|
|
103
|
+
responseStatus = response.status;
|
|
104
|
+
return response;
|
|
105
|
+
};
|
|
106
|
+
const { error, data } = await restFetch(`https://firebaseremoteconfig.googleapis.com/v1/projects/${encodeURIComponent(projectId)}/${path}`, {
|
|
107
|
+
method,
|
|
108
|
+
body,
|
|
109
|
+
params,
|
|
110
|
+
headers,
|
|
111
|
+
bearerToken: accessToken,
|
|
112
|
+
global: { fetch: captureFetch }
|
|
113
|
+
});
|
|
114
|
+
if (error !== null) {
|
|
115
|
+
const codes = {
|
|
116
|
+
INVALID_ARGUMENT: 'invalid-argument',
|
|
117
|
+
NOT_FOUND: 'not-found',
|
|
118
|
+
PERMISSION_DENIED: 'permission-denied',
|
|
119
|
+
UNAUTHENTICATED: 'authentication-error',
|
|
120
|
+
RESOURCE_EXHAUSTED: 'resource-exhausted',
|
|
121
|
+
FAILED_PRECONDITION: 'failed-precondition',
|
|
122
|
+
ABORTED: 'aborted',
|
|
123
|
+
INTERNAL: 'internal-error',
|
|
124
|
+
UNAVAILABLE: 'unavailable',
|
|
125
|
+
UNKNOWN: 'unknown-error'
|
|
126
|
+
};
|
|
127
|
+
const status = typeof error === 'object' ? error?.error?.status : undefined;
|
|
128
|
+
throw new FirebaseEdgeError({
|
|
129
|
+
code: `remote-config/${responseStatus === 412 ? 'etag-mismatch' : (codes[status ?? ''] ?? 'unknown-error')}`,
|
|
130
|
+
message: typeof error === 'string'
|
|
131
|
+
? error
|
|
132
|
+
: (error?.error?.message ?? 'Remote Config request failed.')
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (!isRemoteConfigObject(data)) {
|
|
136
|
+
throw new FirebaseEdgeError({
|
|
137
|
+
code: 'remote-config/internal-error',
|
|
138
|
+
message: 'Invalid Remote Config response.'
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (operation.type === 'list') {
|
|
142
|
+
if (data.versions !== undefined && !Array.isArray(data.versions)) {
|
|
143
|
+
throw new FirebaseEdgeError({
|
|
144
|
+
code: 'remote-config/internal-error',
|
|
145
|
+
message: 'Invalid version list.'
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
versions: (data.versions ?? []).map(normalizeVersion),
|
|
150
|
+
nextPageToken: data.nextPageToken
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (!responseEtag) {
|
|
154
|
+
throw new FirebaseEdgeError({
|
|
155
|
+
code: 'remote-config/internal-error',
|
|
156
|
+
message: 'Remote Config response is missing its ETag.'
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return { ...data, etag: originalEtag ?? responseEtag };
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=remote-config-endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-endpoints.js","sourceRoot":"","sources":["../../src/remote-config/remote-config-endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ServerConfig, FetchResponseData } from './remote-config-types.js';
|
|
2
|
+
/** Produces a client fetch response from evaluated server configuration. */
|
|
3
|
+
export declare class RemoteConfigFetchResponse {
|
|
4
|
+
private readonly response;
|
|
5
|
+
constructor(projectId: string, serverConfig: ServerConfig, requestEtag?: string);
|
|
6
|
+
toJSON(): FetchResponseData;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=remote-config-fetch-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-fetch-response.d.ts","sourceRoot":"","sources":["../../src/remote-config/remote-config-fetch-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEhF,4EAA4E;AAC5E,qBAAa,yBAAyB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;gBAEzC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,MAAM;IAqBxB,MAAM,IAAI,iBAAiB;CAG9B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Produces a client fetch response from evaluated server configuration. */
|
|
2
|
+
export class RemoteConfigFetchResponse {
|
|
3
|
+
response;
|
|
4
|
+
constructor(projectId, serverConfig, requestEtag) {
|
|
5
|
+
const config = Object.fromEntries(Object.entries(serverConfig.getAll()).map(([key, value]) => [
|
|
6
|
+
key,
|
|
7
|
+
value.asString()
|
|
8
|
+
]));
|
|
9
|
+
const json = JSON.stringify(config);
|
|
10
|
+
let hash = 0;
|
|
11
|
+
for (let index = 0; index < json.length; index++) {
|
|
12
|
+
hash = ((hash << 5) - hash + json.charCodeAt(index)) | 0;
|
|
13
|
+
}
|
|
14
|
+
const eTag = ['etag', projectId, 'firebase-server', 'fetch', hash]
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.join('-');
|
|
17
|
+
this.response =
|
|
18
|
+
requestEtag === eTag
|
|
19
|
+
? { status: 304, eTag }
|
|
20
|
+
: { status: 200, eTag, config };
|
|
21
|
+
}
|
|
22
|
+
toJSON() {
|
|
23
|
+
return structuredClone(this.response);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=remote-config-fetch-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-fetch-response.js","sourceRoot":"","sources":["../../src/remote-config/remote-config-fetch-response.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,OAAO,yBAAyB;IACjB,QAAQ,CAAoB;IAC7C,YACI,SAAiB,EACjB,YAA0B,EAC1B,WAAoB;QAEpB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC7B,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACxD,GAAG;YACH,KAAK,CAAC,QAAQ,EAAE;SACnB,CAAC,CACL,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/C,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC;aAC7D,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ;YACT,WAAW,KAAK,IAAI;gBAChB,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE;gBACvB,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM;QACF,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;CACJ"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FirebaseEdgeError } from '../auth/errors.js';
|
|
2
|
+
export type RemoteConfigResult<T> = {
|
|
3
|
+
error: null;
|
|
4
|
+
data: T;
|
|
5
|
+
} | {
|
|
6
|
+
error: FirebaseEdgeError;
|
|
7
|
+
data: null;
|
|
8
|
+
};
|
|
9
|
+
/** @internal */
|
|
10
|
+
export declare function remoteConfigError(cause: unknown): FirebaseEdgeError;
|
|
11
|
+
/** @internal */
|
|
12
|
+
export declare function invalidRemoteConfig(message: string): never;
|
|
13
|
+
/** @internal */
|
|
14
|
+
export declare function isRemoteConfigObject<T>(value: T): value is T & Record<string, unknown>;
|
|
15
|
+
//# sourceMappingURL=remote-config-results.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-results.d.ts","sourceRoot":"","sources":["../../src/remote-config/remote-config-results.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAe,MAAM,mBAAmB,CAAC;AAEnE,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC1B;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAE/C,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAgBnE;AAED,gBAAgB;AAChB,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAK1D;AAED,gBAAgB;AAChB,wBAAgB,oBAAoB,CAAC,CAAC,EAClC,KAAK,EAAE,CAAC,GACT,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FirebaseEdgeError, ensureError } from '../auth/errors.js';
|
|
2
|
+
/** @internal */
|
|
3
|
+
export function remoteConfigError(cause) {
|
|
4
|
+
if (cause instanceof FirebaseEdgeError) {
|
|
5
|
+
return cause;
|
|
6
|
+
}
|
|
7
|
+
const error = ensureError(cause);
|
|
8
|
+
return new FirebaseEdgeError({
|
|
9
|
+
code: cause instanceof SyntaxError
|
|
10
|
+
? 'remote-config/invalid-argument'
|
|
11
|
+
: 'remote-config/unknown-error',
|
|
12
|
+
message: error.message
|
|
13
|
+
}, { cause: error });
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
export function invalidRemoteConfig(message) {
|
|
17
|
+
throw new FirebaseEdgeError({
|
|
18
|
+
code: 'remote-config/invalid-argument',
|
|
19
|
+
message
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/** @internal */
|
|
23
|
+
export function isRemoteConfigObject(value) {
|
|
24
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=remote-config-results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-results.js","sourceRoot":"","sources":["../../src/remote-config/remote-config-results.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMnE,gBAAgB;AAChB,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEjC,OAAO,IAAI,iBAAiB,CACxB;QACI,IAAI,EACA,KAAK,YAAY,WAAW;YACxB,CAAC,CAAC,gCAAgC;YAClC,CAAC,CAAC,6BAA6B;QACvC,OAAO,EAAE,KAAK,CAAC,OAAO;KACzB,EACD,EAAE,KAAK,EAAE,KAAK,EAAE,CACnB,CAAC;AACN,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,mBAAmB,CAAC,OAAe;IAC/C,MAAM,IAAI,iBAAiB,CAAC;QACxB,IAAI,EAAE,gCAAgC;QACtC,OAAO;KACV,CAAC,CAAC;AACP,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,oBAAoB,CAChC,KAAQ;IAER,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RemoteConfigTemplate as TemplateData, ServerTemplateData, Version } from './remote-config-types.js';
|
|
2
|
+
/** @internal Validate and normalize version metadata without losing int64 precision. */
|
|
3
|
+
export declare function normalizeVersion(input: Version): Version & {
|
|
4
|
+
toJSON(): object;
|
|
5
|
+
};
|
|
6
|
+
/** @internal */
|
|
7
|
+
export declare function validateVersionNumber(value: string | number): string;
|
|
8
|
+
/** @internal */
|
|
9
|
+
export declare function normalizeTemplate<T extends TemplateData | ServerTemplateData>(input: T): T;
|
|
10
|
+
/** A mutable client template with a read-only ETag and JSON serialization. */
|
|
11
|
+
export declare class RemoteConfigTemplate implements TemplateData {
|
|
12
|
+
parameters: TemplateData['parameters'];
|
|
13
|
+
parameterGroups: TemplateData['parameterGroups'];
|
|
14
|
+
conditions: TemplateData['conditions'];
|
|
15
|
+
version?: Version;
|
|
16
|
+
readonly etag: string;
|
|
17
|
+
constructor(input: TemplateData);
|
|
18
|
+
toJSON(): TemplateData;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=remote-config-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-template.d.ts","sourceRoot":"","sources":["../../src/remote-config/remote-config-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,oBAAoB,IAAI,YAAY,EACpC,kBAAkB,EAClB,OAAO,EACV,MAAM,0BAA0B,CAAC;AAMlC,wFAAwF;AACxF,wBAAgB,gBAAgB,CAC5B,KAAK,EAAE,OAAO,GACf,OAAO,GAAG;IAAE,MAAM,IAAI,MAAM,CAAA;CAAE,CA8ChC;AAED,gBAAgB;AAChB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAcpE;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,YAAY,GAAG,kBAAkB,EACzE,KAAK,EAAE,CAAC,GACT,CAAC,CAqDH;AAED,8EAA8E;AAC9E,qBAAa,oBAAqB,YAAW,YAAY;IACrD,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACvC,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC,CAAC;IACjD,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,KAAK,EAAE,YAAY;IAS/B,MAAM,IAAI,YAAY;CAWzB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { invalidRemoteConfig, isRemoteConfigObject } from './remote-config-results.js';
|
|
2
|
+
/** @internal Validate and normalize version metadata without losing int64 precision. */
|
|
3
|
+
export function normalizeVersion(input) {
|
|
4
|
+
if (!isRemoteConfigObject(input)) {
|
|
5
|
+
invalidRemoteConfig('Version must be an object.');
|
|
6
|
+
}
|
|
7
|
+
const version = { ...input };
|
|
8
|
+
for (const key of ['versionNumber', 'rollbackSource']) {
|
|
9
|
+
if (version[key] !== undefined) {
|
|
10
|
+
version[key] = validateVersionNumber(version[key]);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (version.updateTime !== undefined) {
|
|
14
|
+
if (typeof version.updateTime !== 'string' ||
|
|
15
|
+
!version.updateTime.trim()) {
|
|
16
|
+
invalidRemoteConfig('Invalid version update time.');
|
|
17
|
+
}
|
|
18
|
+
const date = new Date(version.updateTime);
|
|
19
|
+
if (!Number.isFinite(date.getTime())) {
|
|
20
|
+
invalidRemoteConfig('Invalid version update time.');
|
|
21
|
+
}
|
|
22
|
+
version.updateTime = date.toUTCString();
|
|
23
|
+
}
|
|
24
|
+
if (version.updateUser !== undefined &&
|
|
25
|
+
!isRemoteConfigObject(version.updateUser)) {
|
|
26
|
+
invalidRemoteConfig('Version updateUser must be an object.');
|
|
27
|
+
}
|
|
28
|
+
if (version.isLegacy !== undefined &&
|
|
29
|
+
typeof version.isLegacy !== 'boolean') {
|
|
30
|
+
invalidRemoteConfig('Version isLegacy must be a boolean.');
|
|
31
|
+
}
|
|
32
|
+
for (const key of ['description', 'updateOrigin', 'updateType']) {
|
|
33
|
+
if (version[key] !== undefined && typeof version[key] !== 'string') {
|
|
34
|
+
invalidRemoteConfig(`Version ${key} must be a string.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return Object.assign(version, {
|
|
38
|
+
toJSON() {
|
|
39
|
+
const { toJSON, ...data } = this;
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** @internal */
|
|
45
|
+
export function validateVersionNumber(value) {
|
|
46
|
+
if ((typeof value !== 'string' && typeof value !== 'number') ||
|
|
47
|
+
(typeof value === 'number' && !Number.isSafeInteger(value)) ||
|
|
48
|
+
!/^[1-9]\d*$/.test(String(value))) {
|
|
49
|
+
invalidRemoteConfig('Version number must be a positive integer or int64 string.');
|
|
50
|
+
}
|
|
51
|
+
if (BigInt(value) > 9223372036854775807n) {
|
|
52
|
+
invalidRemoteConfig('Version number exceeds int64 range.');
|
|
53
|
+
}
|
|
54
|
+
return String(value);
|
|
55
|
+
}
|
|
56
|
+
/** @internal */
|
|
57
|
+
export function normalizeTemplate(input) {
|
|
58
|
+
if (!isRemoteConfigObject(input) ||
|
|
59
|
+
typeof input.etag !== 'string' ||
|
|
60
|
+
!input.etag.trim()) {
|
|
61
|
+
invalidRemoteConfig('Template must have a non-empty ETag.');
|
|
62
|
+
}
|
|
63
|
+
for (const key of ['parameters', 'parameterGroups']) {
|
|
64
|
+
if (input[key] !== undefined && !isRemoteConfigObject(input[key])) {
|
|
65
|
+
invalidRemoteConfig(`${key} must be an object.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (input.conditions !== undefined && !Array.isArray(input.conditions)) {
|
|
69
|
+
invalidRemoteConfig('conditions must be an array.');
|
|
70
|
+
}
|
|
71
|
+
const template = JSON.parse(JSON.stringify(input));
|
|
72
|
+
template.parameters ??= {};
|
|
73
|
+
template.conditions ??= [];
|
|
74
|
+
for (const parameter of [
|
|
75
|
+
...Object.values(template.parameters),
|
|
76
|
+
...Object.values(input.parameterGroups ?? {}).flatMap((group) => Object.values(group.parameters ?? {}))
|
|
77
|
+
]) {
|
|
78
|
+
if (!isRemoteConfigObject(parameter)) {
|
|
79
|
+
invalidRemoteConfig('Each parameter must be an object.');
|
|
80
|
+
}
|
|
81
|
+
for (const value of Object.values(parameter.conditionalValues ?? {})) {
|
|
82
|
+
if (!('experimentValue' in value)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const { exposurePercent } = value.experimentValue;
|
|
86
|
+
if (exposurePercent === undefined) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (typeof exposurePercent !== 'number' ||
|
|
90
|
+
!Number.isFinite(exposurePercent) ||
|
|
91
|
+
exposurePercent < 0 ||
|
|
92
|
+
exposurePercent > 100) {
|
|
93
|
+
invalidRemoteConfig('Experiment exposure percent must be between 0 and 100.');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (input.version !== undefined) {
|
|
98
|
+
template.version = normalizeVersion(input.version);
|
|
99
|
+
}
|
|
100
|
+
return template;
|
|
101
|
+
}
|
|
102
|
+
/** A mutable client template with a read-only ETag and JSON serialization. */
|
|
103
|
+
export class RemoteConfigTemplate {
|
|
104
|
+
parameters;
|
|
105
|
+
parameterGroups;
|
|
106
|
+
conditions;
|
|
107
|
+
version;
|
|
108
|
+
etag;
|
|
109
|
+
constructor(input) {
|
|
110
|
+
const template = normalizeTemplate(input);
|
|
111
|
+
this.etag = template.etag;
|
|
112
|
+
this.parameters = template.parameters;
|
|
113
|
+
this.parameterGroups = template.parameterGroups ?? {};
|
|
114
|
+
this.conditions = template.conditions;
|
|
115
|
+
this.version = template.version;
|
|
116
|
+
}
|
|
117
|
+
toJSON() {
|
|
118
|
+
return {
|
|
119
|
+
parameters: this.parameters,
|
|
120
|
+
parameterGroups: this.parameterGroups,
|
|
121
|
+
conditions: this.conditions,
|
|
122
|
+
etag: this.etag,
|
|
123
|
+
version: this.version
|
|
124
|
+
? normalizeVersion(this.version).toJSON()
|
|
125
|
+
: undefined
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=remote-config-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-config-template.js","sourceRoot":"","sources":["../../src/remote-config/remote-config-template.ts"],"names":[],"mappings":"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"}
|