Skip to content

Commit 1984f1f

Browse files
authored
Allow security-rules to auto-generate typings, separate internal vs external APIs (#974)
1 parent 42fac27 commit 1984f1f

7 files changed

+109
-29
lines changed

gulpfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ var paths = {
5555
curatedTypings: [
5656
'src/*.d.ts',
5757
'!src/instance-id.d.ts',
58+
'!src/security-rules.d.ts',
5859
'!src/project-management.d.ts'
5960
],
6061
};
@@ -70,7 +71,6 @@ const TEMPORARY_TYPING_EXCLUDES = [
7071
'!lib/machine-learning/*.d.ts',
7172
'!lib/messaging/*.d.ts',
7273
'!lib/remote-config/*.d.ts',
73-
'!lib/security-rules/*.d.ts',
7474
'!lib/storage/*.d.ts',
7575
'!lib/utils/*.d.ts'
7676
];

src/security-rules/index.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*!
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { FirebaseApp } from '../firebase-app';
18+
import * as securityRulesApi from './security-rules';
19+
import * as firebaseAdmin from '../index';
20+
21+
export function securityRules(app?: FirebaseApp): securityRulesApi.SecurityRules {
22+
if (typeof(app) === 'undefined') {
23+
app = firebaseAdmin.app();
24+
}
25+
return app.securityRules();
26+
}
27+
28+
/**
29+
* We must define a namespace to make the typings work correctly. Otherwise
30+
* `admin.securityRules()` cannot be called like a function. Temporarily,
31+
* admin.securityRules is used as the namespace name because we cannot barrel
32+
* re-export the contents from security-rules, and we want it to
33+
* match the namespacing in the re-export inside src/index.d.ts
34+
*/
35+
/* eslint-disable @typescript-eslint/no-namespace */
36+
export namespace admin.securityRules {
37+
// See https://github.com/microsoft/TypeScript/issues/4336
38+
/* eslint-disable @typescript-eslint/no-unused-vars */
39+
// See https://github.com/typescript-eslint/typescript-eslint/issues/363
40+
export import RulesFile = securityRulesApi.RulesFile;
41+
export import RulesetMetadata = securityRulesApi.RulesetMetadata;
42+
export import RulesetMetadataList = securityRulesApi.RulesetMetadataList;
43+
44+
/* eslint-disable @typescript-eslint/no-empty-interface */
45+
export interface Ruleset extends securityRulesApi.Ruleset {}
46+
export interface SecurityRules extends securityRulesApi.SecurityRules {}
47+
}

src/security-rules/security-rules-api-client.ts renamed to src/security-rules/security-rules-api-client-internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient } from '../utils/api-request';
1818
import { PrefixedFirebaseError } from '../utils/error';
19-
import { FirebaseSecurityRulesError, SecurityRulesErrorCode } from './security-rules-utils';
19+
import { FirebaseSecurityRulesError, SecurityRulesErrorCode } from './security-rules-internal';
2020
import * as utils from '../utils/index';
2121
import * as validator from '../utils/validator';
2222
import { FirebaseApp } from '../firebase-app';

src/security-rules/security-rules.ts

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,47 @@ import { FirebaseApp } from '../firebase-app';
1919
import * as validator from '../utils/validator';
2020
import {
2121
SecurityRulesApiClient, RulesetResponse, RulesetContent, ListRulesetsResponse,
22-
} from './security-rules-api-client';
23-
import { FirebaseSecurityRulesError } from './security-rules-utils';
22+
} from './security-rules-api-client-internal';
23+
import { FirebaseSecurityRulesError } from './security-rules-internal';
2424

2525
/**
26-
* A source file containing some Firebase security rules.
26+
* A source file containing some Firebase security rules. The content includes raw
27+
* source code including text formatting, indentation and comments. Use the
28+
* [`securityRules.createRulesFileFromSource()`](admin.securityRules.SecurityRules#createRulesFileFromSource)
29+
* method to create new instances of this type.
2730
*/
2831
export interface RulesFile {
2932
readonly name: string;
3033
readonly content: string;
3134
}
3235

3336
/**
34-
* Additional metadata associated with a Ruleset.
37+
* Required metadata associated with a ruleset.
3538
*/
3639
export interface RulesetMetadata {
40+
/**
41+
* Name of the `Ruleset` as a short string. This can be directly passed into APIs
42+
* like [`securityRules.getRuleset()`](admin.securityRules.SecurityRules#getRuleset)
43+
* and [`securityRules.deleteRuleset()`](admin.securityRules.SecurityRules#deleteRuleset).
44+
*/
3745
readonly name: string;
46+
/**
47+
* Creation time of the `Ruleset` as a UTC timestamp string.
48+
*/
3849
readonly createTime: string;
3950
}
4051

4152
/**
4253
* A page of ruleset metadata.
4354
*/
4455
export interface RulesetMetadataList {
56+
/**
57+
* A batch of ruleset metadata.
58+
*/
4559
readonly rulesets: RulesetMetadata[];
60+
/**
61+
* The next page token if available. This is needed to retrieve the next batch.
62+
*/
4663
readonly nextPageToken?: string;
4764
}
4865

@@ -97,7 +114,10 @@ export class Ruleset implements RulesetMetadata {
97114
}
98115

99116
/**
100-
* SecurityRules service bound to the provided app.
117+
* The Firebase `SecurityRules` service interface.
118+
*
119+
* Do not call this constructor directly. Instead, use
120+
* [`admin.securityRules()`](admin.securityRules#securityRules).
101121
*/
102122
export class SecurityRules implements FirebaseServiceInterface {
103123

@@ -235,12 +255,21 @@ export class SecurityRules implements FirebaseServiceInterface {
235255
}
236256

237257
/**
238-
* Creates a `RulesFile` with the given name and source. Throws if any of the arguments are invalid. This is a
239-
* local operation, and does not involve any network API calls.
258+
* Creates a {@link admin.securityRules.RulesFile `RuleFile`} with the given name
259+
* and source. Throws an error if any of the arguments are invalid. This is a local
260+
* operation, and does not involve any network API calls.
240261
*
241-
* @param {string} name Name to assign to the rules file.
242-
* @param {string|Buffer} source Contents of the rules file.
243-
* @returns {RulesFile} A new rules file instance.
262+
* @example
263+
* ```javascript
264+
* const source = '// Some rules source';
265+
* const rulesFile = admin.securityRules().createRulesFileFromSource(
266+
* 'firestore.rules', source);
267+
* ```
268+
*
269+
* @param name Name to assign to the rules file. This is usually a short file name that
270+
* helps identify the file in a ruleset.
271+
* @param source Contents of the rules file.
272+
* @return A new rules file instance.
244273
*/
245274
public createRulesFileFromSource(name: string, source: string | Buffer): RulesFile {
246275
if (!validator.isNonEmptyString(name)) {
@@ -265,10 +294,11 @@ export class SecurityRules implements FirebaseServiceInterface {
265294
}
266295

267296
/**
268-
* Creates a new `Ruleset` from the given `RulesFile`.
297+
* Creates a new {@link admin.securityRules.Ruleset `Ruleset`} from the given
298+
* {@link admin.securityRules.RulesFile `RuleFile`}.
269299
*
270-
* @param {RulesFile} file Rules file to include in the new Ruleset.
271-
* @returns {Promise<Ruleset>} A promise that fulfills with the newly created Ruleset.
300+
* @param file Rules file to include in the new `Ruleset`.
301+
* @returns A promise that fulfills with the newly created `Ruleset`.
272302
*/
273303
public createRuleset(file: RulesFile): Promise<Ruleset> {
274304
const ruleset: RulesetContent = {
@@ -284,24 +314,27 @@ export class SecurityRules implements FirebaseServiceInterface {
284314
}
285315

286316
/**
287-
* Deletes the Ruleset identified by the given name. The input name should be the short name string without
288-
* the project ID prefix. For example, to delete the `projects/project-id/rulesets/my-ruleset`, pass the
289-
* short name "my-ruleset". Rejects with a `not-found` error if the specified Ruleset cannot be found.
317+
* Deletes the {@link admin.securityRules.Ruleset `Ruleset`} identified by the given
318+
* name. The input name should be the short name string without the project ID
319+
* prefix. For example, to delete the `projects/project-id/rulesets/my-ruleset`,
320+
* pass the short name "my-ruleset". Rejects with a `not-found` error if the
321+
* specified `Ruleset` cannot be found.
290322
*
291-
* @param {string} name Name of the Ruleset to delete.
292-
* @returns {Promise<Ruleset>} A promise that fulfills when the Ruleset is deleted.
323+
* @param name Name of the `Ruleset` to delete.
324+
* @return A promise that fulfills when the `Ruleset` is deleted.
293325
*/
294326
public deleteRuleset(name: string): Promise<void> {
295327
return this.client.deleteRuleset(name);
296328
}
297329

298330
/**
299-
* Retrieves a page of rulesets.
331+
* Retrieves a page of ruleset metadata.
300332
*
301-
* @param {number=} pageSize The page size, 100 if undefined. This is also the maximum allowed limit.
302-
* @param {string=} nextPageToken The next page token. If not specified, returns rulesets starting
303-
* without any offset.
304-
* @returns {Promise<RulesetMetadataList>} A promise that fulfills a page of rulesets.
333+
* @param pageSize The page size, 100 if undefined. This is also the maximum allowed
334+
* limit.
335+
* @param nextPageToken The next page token. If not specified, returns rulesets
336+
* starting without any offset.
337+
* @return A promise that fulfills with a page of rulesets.
305338
*/
306339
public listRulesetMetadata(pageSize = 100, nextPageToken?: string): Promise<RulesetMetadataList> {
307340
return this.client.listRulesets(pageSize, nextPageToken)

test/unit/security-rules/security-rules-api-client.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
import * as _ from 'lodash';
2020
import * as chai from 'chai';
2121
import * as sinon from 'sinon';
22-
import { SecurityRulesApiClient, RulesetContent } from '../../../src/security-rules/security-rules-api-client';
23-
import { FirebaseSecurityRulesError } from '../../../src/security-rules/security-rules-utils';
22+
import { SecurityRulesApiClient, RulesetContent } from '../../../src/security-rules/security-rules-api-client-internal';
23+
import { FirebaseSecurityRulesError } from '../../../src/security-rules/security-rules-internal';
2424
import { HttpClient } from '../../../src/utils/api-request';
2525
import * as utils from '../utils';
2626
import * as mocks from '../../resources/mocks';

test/unit/security-rules/security-rules.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import * as sinon from 'sinon';
2222
import { SecurityRules } from '../../../src/security-rules/security-rules';
2323
import { FirebaseApp } from '../../../src/firebase-app';
2424
import * as mocks from '../../resources/mocks';
25-
import { SecurityRulesApiClient, RulesetContent } from '../../../src/security-rules/security-rules-api-client';
26-
import { FirebaseSecurityRulesError } from '../../../src/security-rules/security-rules-utils';
25+
import { SecurityRulesApiClient, RulesetContent } from '../../../src/security-rules/security-rules-api-client-internal';
26+
import { FirebaseSecurityRulesError } from '../../../src/security-rules/security-rules-internal';
2727
import { deepCopy } from '../../../src/utils/deep-copy';
2828

2929
const expect = chai.expect;

0 commit comments

Comments
 (0)