@terreno/feature-flags 0.12.0 → 0.12.1
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/dist/featureFlagsApp.js +7 -4
- package/dist/types.d.ts +14 -1
- package/package.json +2 -2
- package/src/featureFlagsApp.ts +6 -3
- package/src/types.ts +14 -1
package/dist/featureFlagsApp.js
CHANGED
|
@@ -77,9 +77,9 @@ var FeatureFlagsApp = /** @class */ (function () {
|
|
|
77
77
|
}
|
|
78
78
|
FeatureFlagsApp.prototype.register = function (app, openApi) {
|
|
79
79
|
var _this = this;
|
|
80
|
-
var _a;
|
|
80
|
+
var _a, _b;
|
|
81
81
|
var basePath = (_a = this.options.basePath) !== null && _a !== void 0 ? _a : "/feature-flags";
|
|
82
|
-
var routerOptions = __assign(__assign({}, (openApi ? { openApi: openApi } : {})), { permissions: {
|
|
82
|
+
var routerOptions = __assign(__assign({}, (openApi ? { openApi: openApi } : {})), { permissions: (_b = this.options.permissions) !== null && _b !== void 0 ? _b : {
|
|
83
83
|
create: [api_1.Permissions.IsAdmin],
|
|
84
84
|
delete: [api_1.Permissions.IsAdmin],
|
|
85
85
|
list: [api_1.Permissions.IsAdmin],
|
|
@@ -109,10 +109,13 @@ var FeatureFlagsApp = /** @class */ (function () {
|
|
|
109
109
|
}); }));
|
|
110
110
|
// GET /feature-flags/segments — list registered segment names (admin only)
|
|
111
111
|
app.get("".concat(basePath, "/segments"), (0, api_1.authenticateMiddleware)(), (0, api_1.asyncHandler)(function (req, res) { return __awaiter(_this, void 0, void 0, function () {
|
|
112
|
-
var user;
|
|
112
|
+
var user, allowed;
|
|
113
113
|
return __generator(this, function (_a) {
|
|
114
114
|
user = req.user;
|
|
115
|
-
|
|
115
|
+
allowed = this.options.segmentsPermission
|
|
116
|
+
? this.options.segmentsPermission(user)
|
|
117
|
+
: Boolean(user === null || user === void 0 ? void 0 : user.admin);
|
|
118
|
+
if (!allowed) {
|
|
116
119
|
throw new api_1.APIError({ status: 403, title: "Only admins can view segments" });
|
|
117
120
|
}
|
|
118
121
|
return [2 /*return*/, res.json({ data: Object.keys(this.segments) })];
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FindExactlyOnePlugin, FindOneOrNonePlugin } from "@terreno/api";
|
|
1
|
+
import type { FindExactlyOnePlugin, FindOneOrNonePlugin, ModelRouterOptions } from "@terreno/api";
|
|
2
2
|
import type mongoose from "mongoose";
|
|
3
3
|
export interface FeatureFlagVariant {
|
|
4
4
|
key: string;
|
|
@@ -32,5 +32,18 @@ export type SegmentFunction = (user: unknown) => boolean;
|
|
|
32
32
|
export interface FeatureFlagsOptions {
|
|
33
33
|
basePath?: string;
|
|
34
34
|
segments?: Record<string, SegmentFunction>;
|
|
35
|
+
/**
|
|
36
|
+
* Permission predicates that gate the admin CRUD routes for flags. When
|
|
37
|
+
* omitted, defaults to requiring `Permissions.IsAdmin` (i.e. `user.admin === true`)
|
|
38
|
+
* on every method. Provide this when consumers need role-based gating
|
|
39
|
+
* other than the boolean `admin` flag.
|
|
40
|
+
*/
|
|
41
|
+
permissions?: ModelRouterOptions<FeatureFlagDocument>["permissions"];
|
|
42
|
+
/**
|
|
43
|
+
* Predicate used to gate the `/segments` admin endpoint. Receives the
|
|
44
|
+
* authenticated user and should return true to allow the request. Defaults
|
|
45
|
+
* to checking `user.admin === true` when not provided.
|
|
46
|
+
*/
|
|
47
|
+
segmentsPermission?: (user: unknown) => boolean;
|
|
35
48
|
}
|
|
36
49
|
export type EvaluationResult = Record<string, boolean | string | null>;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"url": "https://github.com/FlourishHealth/terreno/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@terreno/api": "0.12.
|
|
7
|
+
"@terreno/api": "0.12.1",
|
|
8
8
|
"express": "^5.2.1",
|
|
9
9
|
"lodash": "^4.17.23"
|
|
10
10
|
},
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"test:coverage": "bun run ../scripts/check-coverage.ts"
|
|
52
52
|
},
|
|
53
53
|
"types": "dist/index.d.ts",
|
|
54
|
-
"version": "0.12.
|
|
54
|
+
"version": "0.12.1"
|
|
55
55
|
}
|
package/src/featureFlagsApp.ts
CHANGED
|
@@ -45,7 +45,7 @@ export class FeatureFlagsApp implements TerrenoPlugin {
|
|
|
45
45
|
const basePath = this.options.basePath ?? "/feature-flags";
|
|
46
46
|
const routerOptions: ModelRouterOptions<FeatureFlagDocument> = {
|
|
47
47
|
...(openApi ? {openApi: openApi as OpenApiMiddleware} : {}),
|
|
48
|
-
permissions: {
|
|
48
|
+
permissions: this.options.permissions ?? {
|
|
49
49
|
create: [Permissions.IsAdmin],
|
|
50
50
|
delete: [Permissions.IsAdmin],
|
|
51
51
|
list: [Permissions.IsAdmin],
|
|
@@ -83,8 +83,11 @@ export class FeatureFlagsApp implements TerrenoPlugin {
|
|
|
83
83
|
`${basePath}/segments`,
|
|
84
84
|
authenticateMiddleware(),
|
|
85
85
|
asyncHandler(async (req: express.Request, res: express.Response) => {
|
|
86
|
-
const user = req.user
|
|
87
|
-
|
|
86
|
+
const user = req.user;
|
|
87
|
+
const allowed = this.options.segmentsPermission
|
|
88
|
+
? this.options.segmentsPermission(user)
|
|
89
|
+
: Boolean((user as {admin?: boolean} | undefined)?.admin);
|
|
90
|
+
if (!allowed) {
|
|
88
91
|
throw new APIError({status: 403, title: "Only admins can view segments"});
|
|
89
92
|
}
|
|
90
93
|
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {FindExactlyOnePlugin, FindOneOrNonePlugin} from "@terreno/api";
|
|
1
|
+
import type {FindExactlyOnePlugin, FindOneOrNonePlugin, ModelRouterOptions} from "@terreno/api";
|
|
2
2
|
import type mongoose from "mongoose";
|
|
3
3
|
|
|
4
4
|
export interface FeatureFlagVariant {
|
|
@@ -41,6 +41,19 @@ export type SegmentFunction = (user: unknown) => boolean;
|
|
|
41
41
|
export interface FeatureFlagsOptions {
|
|
42
42
|
basePath?: string;
|
|
43
43
|
segments?: Record<string, SegmentFunction>;
|
|
44
|
+
/**
|
|
45
|
+
* Permission predicates that gate the admin CRUD routes for flags. When
|
|
46
|
+
* omitted, defaults to requiring `Permissions.IsAdmin` (i.e. `user.admin === true`)
|
|
47
|
+
* on every method. Provide this when consumers need role-based gating
|
|
48
|
+
* other than the boolean `admin` flag.
|
|
49
|
+
*/
|
|
50
|
+
permissions?: ModelRouterOptions<FeatureFlagDocument>["permissions"];
|
|
51
|
+
/**
|
|
52
|
+
* Predicate used to gate the `/segments` admin endpoint. Receives the
|
|
53
|
+
* authenticated user and should return true to allow the request. Defaults
|
|
54
|
+
* to checking `user.admin === true` when not provided.
|
|
55
|
+
*/
|
|
56
|
+
segmentsPermission?: (user: unknown) => boolean;
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
export type EvaluationResult = Record<string, boolean | string | null>;
|