@happyvertical/smrt-features 0.51.19 → 0.51.21
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/AGENTS.md +17 -0
- package/README.md +152 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/feature-definition.d.ts +18 -0
- package/dist/feature-definition.d.ts.map +1 -0
- package/dist/feature-definitions.d.ts +13 -0
- package/dist/feature-definitions.d.ts.map +1 -0
- package/dist/feature-override-service.d.ts +41 -0
- package/dist/feature-override-service.d.ts.map +1 -0
- package/dist/feature-override.d.ts +13 -0
- package/dist/feature-override.d.ts.map +1 -0
- package/dist/feature-overrides.d.ts +16 -0
- package/dist/feature-overrides.d.ts.map +1 -0
- package/dist/feature-resolver.d.ts +18 -0
- package/dist/feature-resolver.d.ts.map +1 -0
- package/dist/feature-settings.d.ts +209 -0
- package/dist/feature-settings.d.ts.map +1 -0
- package/dist/feature-sync.d.ts +17 -0
- package/dist/feature-sync.d.ts.map +1 -0
- package/dist/index.d.ts +11 -263
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +155 -2
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/smrt-knowledge.json +14 -6
- package/dist/svelte/components/FeatureSettingsPanel.svelte +338 -0
- package/dist/svelte/components/FeatureSettingsPanel.svelte.d.ts +52 -0
- package/dist/svelte/components/FeatureSettingsPanel.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +14 -0
- package/dist/svelte/types.d.ts +76 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +37 -0
- package/dist/types.d.ts +107 -131
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +26 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,263 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
className: string;
|
|
13
|
-
localId: string;
|
|
14
|
-
defaultEnabled: boolean;
|
|
15
|
-
label: string;
|
|
16
|
-
description: string;
|
|
17
|
-
metadata: string;
|
|
18
|
-
visibility: string;
|
|
19
|
-
constructor(options?: FeatureDefinitionOptions);
|
|
20
|
-
getMetadata(): FeatureMetadata;
|
|
21
|
-
setMetadata(metadata: FeatureMetadata | null): void;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export declare class FeatureDefinitionCollection extends SmrtCollection<FeatureDefinition> {
|
|
25
|
-
static readonly _itemClass: typeof FeatureDefinition;
|
|
26
|
-
findByFeatureKey(featureKey: string): Promise<FeatureDefinition | null>;
|
|
27
|
-
findByPackageName(packageName: string): Promise<FeatureDefinition[]>;
|
|
28
|
-
upsertDefinition(seed: FeatureDefinitionSeed): Promise<{
|
|
29
|
-
definition: FeatureDefinition;
|
|
30
|
-
status: 'created' | 'updated' | 'unchanged';
|
|
31
|
-
}>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export declare interface FeatureDefinitionOptions {
|
|
35
|
-
id?: string;
|
|
36
|
-
featureKey?: string;
|
|
37
|
-
packageName?: string;
|
|
38
|
-
qualifiedClassName?: string;
|
|
39
|
-
className?: string;
|
|
40
|
-
localId?: string;
|
|
41
|
-
defaultEnabled?: boolean;
|
|
42
|
-
label?: string;
|
|
43
|
-
description?: string;
|
|
44
|
-
metadata?: FeatureMetadata | string | null;
|
|
45
|
-
visibility?: string;
|
|
46
|
-
createdAt?: Date;
|
|
47
|
-
updatedAt?: Date;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export declare interface FeatureDefinitionSeed {
|
|
51
|
-
featureKey: string;
|
|
52
|
-
packageName: string;
|
|
53
|
-
qualifiedClassName: string;
|
|
54
|
-
className: string;
|
|
55
|
-
localId: string;
|
|
56
|
-
defaultEnabled: boolean;
|
|
57
|
-
label?: string;
|
|
58
|
-
description?: string;
|
|
59
|
-
metadata?: FeatureMetadata;
|
|
60
|
-
visibility?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export declare interface FeatureMetadata {
|
|
64
|
-
[key: string]: unknown;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export declare class FeatureOverride extends SmrtObject {
|
|
68
|
-
featureKey: string;
|
|
69
|
-
scopeType: FeatureScopeType;
|
|
70
|
-
scopeId: string;
|
|
71
|
-
effect: FeatureOverrideEffect;
|
|
72
|
-
constructor(options?: FeatureOverrideOptions);
|
|
73
|
-
isInherit(): boolean;
|
|
74
|
-
isEnabled(): boolean;
|
|
75
|
-
isDisabled(): boolean;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Thrown when the authorizer does not return `true`. Nothing is written. */
|
|
79
|
-
export declare class FeatureOverrideAuthorizationError extends Error {
|
|
80
|
-
readonly request: FeatureOverrideWriteRequest;
|
|
81
|
-
readonly status = 403;
|
|
82
|
-
constructor(request: FeatureOverrideWriteRequest);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The host's explicit authorization decision for one override write. Return
|
|
87
|
-
* `true` only when the current caller may write that exact scope; anything
|
|
88
|
-
* else denies.
|
|
89
|
-
*/
|
|
90
|
-
export declare type FeatureOverrideAuthorizer = (request: FeatureOverrideWriteRequest) => boolean | Promise<boolean>;
|
|
91
|
-
|
|
92
|
-
export declare class FeatureOverrideCollection extends SmrtCollection<FeatureOverride> {
|
|
93
|
-
static readonly _itemClass: typeof FeatureOverride;
|
|
94
|
-
findByFeatureKey(featureKey: string): Promise<FeatureOverride[]>;
|
|
95
|
-
findByFeatureAndScope(featureKey: string, scopeType: FeatureScopeType, scopeId: string): Promise<FeatureOverride | null>;
|
|
96
|
-
getGlobalOverride(featureKey: string): Promise<FeatureOverride | null>;
|
|
97
|
-
getTenantOverride(featureKey: string, tenantId: string): Promise<FeatureOverride | null>;
|
|
98
|
-
getOverrideMap(featureKey: string, scopeType: FeatureScopeType, scopeIds: string[]): Promise<Map<string, FeatureOverride>>;
|
|
99
|
-
setOverride(featureKey: string, scopeType: FeatureScopeType, scopeId: string, effect: FeatureOverrideEffect): Promise<FeatureOverride>;
|
|
100
|
-
setGlobalOverride(featureKey: string, effect: FeatureOverrideEffect): Promise<FeatureOverride>;
|
|
101
|
-
setTenantOverride(featureKey: string, tenantId: string, effect: FeatureOverrideEffect): Promise<FeatureOverride>;
|
|
102
|
-
removeOverride(featureKey: string, scopeType: FeatureScopeType, scopeId: string): Promise<boolean>;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export declare enum FeatureOverrideEffect {
|
|
106
|
-
INHERIT = "inherit",
|
|
107
|
-
ENABLE = "enable",
|
|
108
|
-
DISABLE = "disable"
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export declare interface FeatureOverrideOptions {
|
|
112
|
-
id?: string;
|
|
113
|
-
featureKey?: string;
|
|
114
|
-
scopeType?: FeatureScopeType;
|
|
115
|
-
scopeId?: string;
|
|
116
|
-
effect?: FeatureOverrideEffect;
|
|
117
|
-
createdAt?: Date;
|
|
118
|
-
updatedAt?: Date;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Authorized write path for feature overrides (#3013). Override rows are
|
|
123
|
-
* authorization state for every scope and `FeatureOverride` is not
|
|
124
|
-
* tenant-scoped, so generated surfaces are closed. Hosts that let callers
|
|
125
|
-
* change flags construct this service with an authorizer bound to the
|
|
126
|
-
* current caller and write through it; every write asks the authorizer
|
|
127
|
-
* first and fails closed.
|
|
128
|
-
*/
|
|
129
|
-
export declare class FeatureOverrideService {
|
|
130
|
-
private readonly overrides;
|
|
131
|
-
private readonly authorize;
|
|
132
|
-
constructor(overrides: FeatureOverrideCollection, authorize: FeatureOverrideAuthorizer);
|
|
133
|
-
setOverride(featureKey: string, scopeType: FeatureScopeType, scopeId: string, effect: FeatureOverrideEffect): Promise<FeatureOverride>;
|
|
134
|
-
removeOverride(featureKey: string, scopeType: FeatureScopeType, scopeId: string): Promise<boolean>;
|
|
135
|
-
private require;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** One override write the host must authorize before it runs (#3013). */
|
|
139
|
-
export declare interface FeatureOverrideWriteRequest {
|
|
140
|
-
operation: 'set' | 'remove';
|
|
141
|
-
featureKey: string;
|
|
142
|
-
scopeType: FeatureScopeType;
|
|
143
|
-
scopeId: string;
|
|
144
|
-
/** Present for `set`. */
|
|
145
|
-
effect?: FeatureOverrideEffect;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export declare interface FeatureResolutionContext {
|
|
149
|
-
tenantId?: string;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export declare class FeatureResolver {
|
|
153
|
-
private readonly options;
|
|
154
|
-
private readonly resolverOptions;
|
|
155
|
-
private featureDefinitions;
|
|
156
|
-
private featureOverrides;
|
|
157
|
-
private initializationPromise;
|
|
158
|
-
private tenantHierarchyPromise;
|
|
159
|
-
constructor(options?: SmrtClassOptions, resolverOptions?: FeatureResolverOptions);
|
|
160
|
-
isEnabled(featureKey: string, context?: FeatureResolutionContext): Promise<boolean>;
|
|
161
|
-
isEnabledFor(classOrInstance: object | FeatureTargetConstructor, localId: string, context?: FeatureResolutionContext): Promise<boolean>;
|
|
162
|
-
private ensureInitialized;
|
|
163
|
-
private resolveBaseState;
|
|
164
|
-
private applyOverride;
|
|
165
|
-
private getTenantHierarchy;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export declare interface FeatureResolverOptions {
|
|
169
|
-
tenantHierarchyLoader?: FeatureTenantHierarchyLoader;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export declare type FeatureScopeType = 'global' | 'tenant';
|
|
173
|
-
|
|
174
|
-
export declare interface FeatureSyncResult {
|
|
175
|
-
total: number;
|
|
176
|
-
created: number;
|
|
177
|
-
updated: number;
|
|
178
|
-
unchanged: number;
|
|
179
|
-
deleted: number;
|
|
180
|
-
featureKeys: string[];
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export declare class FeatureSyncService {
|
|
184
|
-
private readonly options;
|
|
185
|
-
private featureDefinitions;
|
|
186
|
-
private initializationPromise;
|
|
187
|
-
constructor(options?: SmrtClassOptions);
|
|
188
|
-
syncDefinitions(options?: SyncDefinitionsOptions): Promise<FeatureSyncResult>;
|
|
189
|
-
syncManifest(manifest: SmartObjectManifest, options?: SyncManifestOptions): Promise<FeatureSyncResult>;
|
|
190
|
-
private ensureInitialized;
|
|
191
|
-
private collectDefinitionsFromRegistrations;
|
|
192
|
-
private collectTouchedPackagesFromRegistrations;
|
|
193
|
-
private collectRegistrations;
|
|
194
|
-
private applyDefinitions;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Constructor type for any `@smrt()`-decorated class that may declare feature
|
|
199
|
-
* toggles. Feature targets always extend `SmrtObject`, so this mirrors
|
|
200
|
-
* `@happyvertical/smrt-core`'s internal (non-exported) `SmrtObjectConstructor`
|
|
201
|
-
* and remains assignable to it for `ObjectRegistry.getClassByConstructor`.
|
|
202
|
-
*/
|
|
203
|
-
declare type FeatureTargetConstructor = new (...args: unknown[]) => SmrtObject;
|
|
204
|
-
|
|
205
|
-
export declare type FeatureTenantHierarchyLoader = (options: SmrtClassOptions) => Promise<FeatureTenantHierarchyProvider | null>;
|
|
206
|
-
|
|
207
|
-
export declare interface FeatureTenantHierarchyProvider {
|
|
208
|
-
getChain(tenantId: string): Promise<FeatureTenantNode[]>;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export declare interface FeatureTenantNode {
|
|
212
|
-
id: string;
|
|
213
|
-
inheritPermissions: boolean;
|
|
214
|
-
cascadePermissions: boolean;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export declare interface FeatureUsersModule {
|
|
218
|
-
TenantCollection: {
|
|
219
|
-
create(options: SmrtClassOptions): Promise<{
|
|
220
|
-
get(criteria: {
|
|
221
|
-
id: string;
|
|
222
|
-
}): Promise<FeatureUsersTenantRecord | null>;
|
|
223
|
-
getAncestorsFromRoot(tenantId: string): Promise<FeatureUsersTenantRecord[]>;
|
|
224
|
-
}>;
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Minimal structural shape of a tenant record returned by
|
|
230
|
-
* `@happyvertical/smrt-users`. Only the permission-cascade fields consumed by
|
|
231
|
-
* feature resolution are modeled; everything else is left unconstrained.
|
|
232
|
-
*/
|
|
233
|
-
declare interface FeatureUsersTenantRecord {
|
|
234
|
-
id: string;
|
|
235
|
-
inheritPermissions?: boolean;
|
|
236
|
-
cascadePermissions?: boolean;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export declare function findFeatureDefaultInRegistry(featureKey: string): boolean | undefined;
|
|
240
|
-
|
|
241
|
-
export declare const GLOBAL_FEATURE_SCOPE_ID = "*";
|
|
242
|
-
|
|
243
|
-
export declare function parseFeatureKey(featureKey: string): {
|
|
244
|
-
qualifiedClassName: string;
|
|
245
|
-
localId: string;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
export declare function resolveFeatureKeyForTarget(classOrInstance: object | FeatureTargetConstructor, localId: string): {
|
|
249
|
-
featureKey: string;
|
|
250
|
-
defaultEnabled: boolean;
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
export declare interface SyncDefinitionsOptions {
|
|
254
|
-
classNames?: string[];
|
|
255
|
-
constructors?: FeatureTargetConstructor[];
|
|
256
|
-
pruneStale?: boolean;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export declare interface SyncManifestOptions {
|
|
260
|
-
pruneStale?: boolean;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
export { }
|
|
1
|
+
export { FeatureDefinition } from './feature-definition.js';
|
|
2
|
+
export { FeatureDefinitionCollection } from './feature-definitions.js';
|
|
3
|
+
export { FeatureOverride } from './feature-override.js';
|
|
4
|
+
export { FeatureOverrideAuthorizationError, type FeatureOverrideAuthorizer, FeatureOverrideService, type FeatureOverrideWriteRequest, } from './feature-override-service.js';
|
|
5
|
+
export { FeatureOverrideCollection } from './feature-overrides.js';
|
|
6
|
+
export { FeatureResolver } from './feature-resolver.js';
|
|
7
|
+
export { type FeatureSettingsRow, FeatureSettingsService, type FeatureSettingsServiceOptions, featureOverrideEffectFromValue, InvalidFeatureScopeError, type ListFeatureSettingsOptions, type SetFeatureOverrideRequest, UnknownFeatureKeyError, } from './feature-settings.js';
|
|
8
|
+
export { FeatureSyncService } from './feature-sync.js';
|
|
9
|
+
export { type FeatureDefinitionOptions, type FeatureDefinitionSeed, type FeatureMetadata, FeatureOverrideEffect, type FeatureOverrideOptions, type FeatureResolutionContext, type FeatureResolverOptions, type FeatureScopeType, type FeatureSyncResult, type FeatureTenantHierarchyLoader, type FeatureTenantHierarchyProvider, type FeatureTenantNode, type FeatureUsersModule, GLOBAL_FEATURE_SCOPE_ID, type SyncDefinitionsOptions, type SyncManifestOptions, } from './types.js';
|
|
10
|
+
export { createFeatureKey, findFeatureDefaultInRegistry, parseFeatureKey, resolveFeatureKeyForTarget, } from './utils.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,wBAAwB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,iCAAiC,EACjC,KAAK,yBAAyB,EAC9B,sBAAsB,EACtB,KAAK,2BAA2B,GACjC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,8BAA8B,EAC9B,wBAAwB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACnC,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,eAAe,EACf,0BAA0B,GAC3B,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { FeatureOverrideEffect, GLOBAL_FEATURE_SCOPE_ID } from "./types.js";
|
|
|
2
2
|
import { ObjectRegistry, SmrtCollection, SmrtObject, createQualifiedName, isQualifiedName, parseQualifiedName, smrt } from "@happyvertical/smrt-core";
|
|
3
3
|
import { importWorkspaceModule } from "@happyvertical/smrt-core/utils/import-workspace-module";
|
|
4
4
|
//#region src/__smrt-register__.ts
|
|
5
|
-
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-features\",\"packageVersion\":\"0.51.19\",\"objects\":{\"@happyvertical/smrt-features:FeatureDefinition\":{\"name\":\"featuredefinition\",\"className\":\"FeatureDefinition\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureDefinition\",\"collection\":\"featuredefinitions\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-definition.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{\"featureKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"packageName\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"qualifiedClassName\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"className\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"localId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"defaultEnabled\":{\"type\":\"boolean\",\"required\":false,\"default\":false},\"label\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"description\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"visibility\":{\"type\":\"text\",\"required\":false,\"default\":\"public\"}},\"methods\":{\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"FeatureMetadata\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"FeatureMetadata | null\",\"optional\":false,\"unionBranches\":[{\"type\":\"FeatureMetadata\"},{\"type\":\"null\"}]}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_definitions\",\"api\":false,\"cli\":false,\"mcp\":false,\"conflictColumns\":[\"feature_key\"]},\"extends\":\"SmrtObject\",\"exportName\":\"FeatureDefinition\",\"collectionExportName\":\"FeatureDefinitionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_definitions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_definitions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"package_name\\\" TEXT DEFAULT '',\\n \\\"qualified_class_name\\\" TEXT DEFAULT '',\\n \\\"class_name\\\" TEXT DEFAULT '',\\n \\\"local_id\\\" TEXT DEFAULT '',\\n \\\"default_enabled\\\" BOOLEAN DEFAULT FALSE,\\n \\\"label\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '',\\n \\\"visibility\\\" TEXT DEFAULT 'public'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"package_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"qualified_class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"local_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"default_enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"label\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"visibility\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"public\"}},\"indexes\":[{\"name\":\"_smrt_feature_definitions_feature_key_idx\",\"columns\":[\"feature_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_definitions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_definitions_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"8813204c\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureDefinitionCollection\":{\"name\":\"featuredefinitioncollection\",\"className\":\"FeatureDefinitionCollection\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureDefinitionCollection\",\"collection\":\"featuredefinitions\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-definitions.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{},\"methods\":{\"findByFeatureKey\":{\"name\":\"findByFeatureKey\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureDefinition | null>\",\"isStatic\":false,\"isPublic\":true},\"findByPackageName\":{\"name\":\"findByPackageName\",\"async\":true,\"parameters\":[{\"name\":\"packageName\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureDefinition[]>\",\"isStatic\":false,\"isPublic\":true},\"upsertDefinition\":{\"name\":\"upsertDefinition\",\"async\":true,\"parameters\":[{\"name\":\"seed\",\"type\":\"FeatureDefinitionSeed\",\"optional\":false}],\"returnType\":\"Promise<object>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_definitions\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"FeatureDefinition\",\"exportName\":\"FeatureDefinitionCollection\",\"collectionExportName\":\"FeatureDefinitionCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_definitions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_definitions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"package_name\\\" TEXT DEFAULT '',\\n \\\"qualified_class_name\\\" TEXT DEFAULT '',\\n \\\"class_name\\\" TEXT DEFAULT '',\\n \\\"local_id\\\" TEXT DEFAULT '',\\n \\\"default_enabled\\\" BOOLEAN DEFAULT FALSE,\\n \\\"label\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '',\\n \\\"visibility\\\" TEXT DEFAULT 'public'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"package_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"qualified_class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"local_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"default_enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"label\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"visibility\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"public\"}},\"indexes\":[{\"name\":\"_smrt_feature_definitions_feature_key_idx\",\"columns\":[\"feature_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_definitions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_definitions_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"8813204c\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureOverride\":{\"name\":\"featureoverride\",\"className\":\"FeatureOverride\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureOverride\",\"collection\":\"featureoverrides\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-override.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{\"featureKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"scopeType\":{\"type\":\"text\",\"required\":false,\"default\":\"global\"},\"scopeId\":{\"type\":\"text\",\"required\":false},\"effect\":{\"type\":\"text\",\"required\":false}},\"methods\":{\"isInherit\":{\"name\":\"isInherit\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"isEnabled\":{\"name\":\"isEnabled\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"isDisabled\":{\"name\":\"isDisabled\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_overrides\",\"api\":false,\"cli\":false,\"mcp\":false,\"conflictColumns\":[\"feature_key\",\"scope_type\",\"scope_id\"]},\"extends\":\"SmrtObject\",\"exportName\":\"FeatureOverride\",\"collectionExportName\":\"FeatureOverrideCollection\",\"schema\":{\"tableName\":\"_smrt_feature_overrides\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_overrides\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"scope_type\\\" TEXT DEFAULT 'global',\\n \\\"scope_id\\\" TEXT,\\n \\\"effect\\\" TEXT\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"scope_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"global\"},\"scope_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"effect\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_feature_overrides_feature_key_scope_type_idx\",\"columns\":[\"feature_key\",\"scope_type\",\"scope_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_overrides_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_overrides_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"d61cf901\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureOverrideCollection\":{\"name\":\"featureoverridecollection\",\"className\":\"FeatureOverrideCollection\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureOverrideCollection\",\"collection\":\"featureoverrides\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-overrides.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{},\"methods\":{\"findByFeatureKey\":{\"name\":\"findByFeatureKey\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride[]>\",\"isStatic\":false,\"isPublic\":true},\"findByFeatureAndScope\":{\"name\":\"findByFeatureAndScope\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getGlobalOverride\":{\"name\":\"getGlobalOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getTenantOverride\":{\"name\":\"getTenantOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getOverrideMap\":{\"name\":\"getOverrideMap\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeIds\",\"type\":\"string[]\",\"optional\":false}],\"returnType\":\"Promise<Map<string, FeatureOverride>>\",\"isStatic\":false,\"isPublic\":true},\"setOverride\":{\"name\":\"setOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"setGlobalOverride\":{\"name\":\"setGlobalOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"setTenantOverride\":{\"name\":\"setTenantOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"removeOverride\":{\"name\":\"removeOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<boolean>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_overrides\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"FeatureOverride\",\"exportName\":\"FeatureOverrideCollection\",\"collectionExportName\":\"FeatureOverrideCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_overrides\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_overrides\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"scope_type\\\" TEXT DEFAULT 'global',\\n \\\"scope_id\\\" TEXT,\\n \\\"effect\\\" TEXT\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"scope_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"global\"},\"scope_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"effect\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_feature_overrides_feature_key_scope_type_idx\",\"columns\":[\"feature_key\",\"scope_type\",\"scope_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_overrides_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_overrides_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"d61cf901\"},\"importPath\":\"@happyvertical/smrt-features\"}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-users\"]}"));
|
|
5
|
+
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-features\",\"packageVersion\":\"0.51.21\",\"objects\":{\"@happyvertical/smrt-features:FeatureDefinition\":{\"name\":\"featuredefinition\",\"className\":\"FeatureDefinition\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureDefinition\",\"collection\":\"featuredefinitions\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-definition.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{\"featureKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"packageName\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"qualifiedClassName\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"className\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"localId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"defaultEnabled\":{\"type\":\"boolean\",\"required\":false,\"default\":false},\"label\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"description\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"visibility\":{\"type\":\"text\",\"required\":false,\"default\":\"public\"}},\"methods\":{\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"FeatureMetadata\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"FeatureMetadata | null\",\"optional\":false,\"unionBranches\":[{\"type\":\"FeatureMetadata\"},{\"type\":\"null\"}]}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_definitions\",\"api\":false,\"cli\":false,\"mcp\":false,\"conflictColumns\":[\"feature_key\"]},\"extends\":\"SmrtObject\",\"exportName\":\"FeatureDefinition\",\"collectionExportName\":\"FeatureDefinitionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_definitions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_definitions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"package_name\\\" TEXT DEFAULT '',\\n \\\"qualified_class_name\\\" TEXT DEFAULT '',\\n \\\"class_name\\\" TEXT DEFAULT '',\\n \\\"local_id\\\" TEXT DEFAULT '',\\n \\\"default_enabled\\\" BOOLEAN DEFAULT FALSE,\\n \\\"label\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '',\\n \\\"visibility\\\" TEXT DEFAULT 'public'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"package_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"qualified_class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"local_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"default_enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"label\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"visibility\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"public\"}},\"indexes\":[{\"name\":\"_smrt_feature_definitions_feature_key_idx\",\"columns\":[\"feature_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_definitions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_definitions_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"8813204c\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureDefinitionCollection\":{\"name\":\"featuredefinitioncollection\",\"className\":\"FeatureDefinitionCollection\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureDefinitionCollection\",\"collection\":\"featuredefinitions\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-definitions.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{},\"methods\":{\"findByFeatureKey\":{\"name\":\"findByFeatureKey\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureDefinition | null>\",\"isStatic\":false,\"isPublic\":true},\"findByPackageName\":{\"name\":\"findByPackageName\",\"async\":true,\"parameters\":[{\"name\":\"packageName\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureDefinition[]>\",\"isStatic\":false,\"isPublic\":true},\"upsertDefinition\":{\"name\":\"upsertDefinition\",\"async\":true,\"parameters\":[{\"name\":\"seed\",\"type\":\"FeatureDefinitionSeed\",\"optional\":false}],\"returnType\":\"Promise<object>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_definitions\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"FeatureDefinition\",\"exportName\":\"FeatureDefinitionCollection\",\"collectionExportName\":\"FeatureDefinitionCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_definitions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_definitions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"package_name\\\" TEXT DEFAULT '',\\n \\\"qualified_class_name\\\" TEXT DEFAULT '',\\n \\\"class_name\\\" TEXT DEFAULT '',\\n \\\"local_id\\\" TEXT DEFAULT '',\\n \\\"default_enabled\\\" BOOLEAN DEFAULT FALSE,\\n \\\"label\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '',\\n \\\"visibility\\\" TEXT DEFAULT 'public'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"package_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"qualified_class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"class_name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"local_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"default_enabled\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"label\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"visibility\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"public\"}},\"indexes\":[{\"name\":\"_smrt_feature_definitions_feature_key_idx\",\"columns\":[\"feature_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_definitions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_definitions_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"8813204c\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureOverride\":{\"name\":\"featureoverride\",\"className\":\"FeatureOverride\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureOverride\",\"collection\":\"featureoverrides\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-override.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{\"featureKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"scopeType\":{\"type\":\"text\",\"required\":false,\"default\":\"global\"},\"scopeId\":{\"type\":\"text\",\"required\":false},\"effect\":{\"type\":\"text\",\"required\":false}},\"methods\":{\"isInherit\":{\"name\":\"isInherit\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"isEnabled\":{\"name\":\"isEnabled\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"isDisabled\":{\"name\":\"isDisabled\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_overrides\",\"api\":false,\"cli\":false,\"mcp\":false,\"conflictColumns\":[\"feature_key\",\"scope_type\",\"scope_id\"]},\"extends\":\"SmrtObject\",\"exportName\":\"FeatureOverride\",\"collectionExportName\":\"FeatureOverrideCollection\",\"schema\":{\"tableName\":\"_smrt_feature_overrides\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_overrides\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"scope_type\\\" TEXT DEFAULT 'global',\\n \\\"scope_id\\\" TEXT,\\n \\\"effect\\\" TEXT\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"scope_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"global\"},\"scope_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"effect\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_feature_overrides_feature_key_scope_type_idx\",\"columns\":[\"feature_key\",\"scope_type\",\"scope_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_overrides_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_overrides_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"d61cf901\"},\"importPath\":\"@happyvertical/smrt-features\"},\"@happyvertical/smrt-features:FeatureOverrideCollection\":{\"name\":\"featureoverridecollection\",\"className\":\"FeatureOverrideCollection\",\"qualifiedName\":\"@happyvertical/smrt-features:FeatureOverrideCollection\",\"collection\":\"featureoverrides\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/features/src/feature-overrides.ts\",\"packageName\":\"@happyvertical/smrt-features\",\"fields\":{},\"methods\":{\"findByFeatureKey\":{\"name\":\"findByFeatureKey\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride[]>\",\"isStatic\":false,\"isPublic\":true},\"findByFeatureAndScope\":{\"name\":\"findByFeatureAndScope\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getGlobalOverride\":{\"name\":\"getGlobalOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getTenantOverride\":{\"name\":\"getTenantOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride | null>\",\"isStatic\":false,\"isPublic\":true},\"getOverrideMap\":{\"name\":\"getOverrideMap\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeIds\",\"type\":\"string[]\",\"optional\":false}],\"returnType\":\"Promise<Map<string, FeatureOverride>>\",\"isStatic\":false,\"isPublic\":true},\"setOverride\":{\"name\":\"setOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"setGlobalOverride\":{\"name\":\"setGlobalOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"setTenantOverride\":{\"name\":\"setTenantOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"effect\",\"type\":\"FeatureOverrideEffect\",\"optional\":false}],\"returnType\":\"Promise<FeatureOverride>\",\"isStatic\":false,\"isPublic\":true},\"removeOverride\":{\"name\":\"removeOverride\",\"async\":true,\"parameters\":[{\"name\":\"featureKey\",\"type\":\"string\",\"optional\":false},{\"name\":\"scopeType\",\"type\":\"FeatureScopeType\",\"optional\":false},{\"name\":\"scopeId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<boolean>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_feature_overrides\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"FeatureOverride\",\"exportName\":\"FeatureOverrideCollection\",\"collectionExportName\":\"FeatureOverrideCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_feature_overrides\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_feature_overrides\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"feature_key\\\" TEXT DEFAULT '',\\n \\\"scope_type\\\" TEXT DEFAULT 'global',\\n \\\"scope_id\\\" TEXT,\\n \\\"effect\\\" TEXT\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"feature_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"scope_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"global\"},\"scope_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false},\"effect\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_feature_overrides_feature_key_scope_type_idx\",\"columns\":[\"feature_key\",\"scope_type\",\"scope_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_feature_overrides_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_feature_overrides_created_at_idx\",\"columns\":[\"created_at\"]}],\"version\":\"d61cf901\"},\"importPath\":\"@happyvertical/smrt-features\"}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-users\"]}"));
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/utils.ts
|
|
8
8
|
function createFeatureKey(qualifiedClassName, localId) {
|
|
@@ -496,6 +496,159 @@ function isMissingUsersDependency(error) {
|
|
|
496
496
|
return text.includes("@happyvertical/smrt-users") && (text.includes("Cannot find module") || text.includes("Failed to load") || text.includes("could not find"));
|
|
497
497
|
}
|
|
498
498
|
//#endregion
|
|
499
|
+
//#region src/feature-settings.ts
|
|
500
|
+
var UnknownFeatureKeyError = class extends Error {
|
|
501
|
+
constructor(featureKey) {
|
|
502
|
+
super(`Unknown feature key: ${featureKey}`);
|
|
503
|
+
this.featureKey = featureKey;
|
|
504
|
+
this.name = "UnknownFeatureKeyError";
|
|
505
|
+
}
|
|
506
|
+
featureKey;
|
|
507
|
+
status = 400;
|
|
508
|
+
};
|
|
509
|
+
var InvalidFeatureScopeError = class extends Error {
|
|
510
|
+
constructor(scopeType, scopeId, reason) {
|
|
511
|
+
super(`Invalid feature override scope (${scopeType}): ${reason}`);
|
|
512
|
+
this.scopeType = scopeType;
|
|
513
|
+
this.scopeId = scopeId;
|
|
514
|
+
this.name = "InvalidFeatureScopeError";
|
|
515
|
+
}
|
|
516
|
+
scopeType;
|
|
517
|
+
scopeId;
|
|
518
|
+
status = 400;
|
|
519
|
+
};
|
|
520
|
+
var KNOWN_EFFECTS = new Set(Object.values(FeatureOverrideEffect));
|
|
521
|
+
function featureOverrideEffectFromValue(value) {
|
|
522
|
+
if (value === FeatureOverrideEffect.ENABLE) return FeatureOverrideEffect.ENABLE;
|
|
523
|
+
if (value === FeatureOverrideEffect.DISABLE) return FeatureOverrideEffect.DISABLE;
|
|
524
|
+
return FeatureOverrideEffect.INHERIT;
|
|
525
|
+
}
|
|
526
|
+
var FeatureSettingsService = class FeatureSettingsService {
|
|
527
|
+
constructor(definitions, overrides, resolver, authorize) {
|
|
528
|
+
this.definitions = definitions;
|
|
529
|
+
this.overrides = overrides;
|
|
530
|
+
this.resolver = resolver;
|
|
531
|
+
this.writes = new FeatureOverrideService(overrides, authorize ?? (() => false));
|
|
532
|
+
}
|
|
533
|
+
definitions;
|
|
534
|
+
overrides;
|
|
535
|
+
resolver;
|
|
536
|
+
writes;
|
|
537
|
+
/**
|
|
538
|
+
* Build a service over the given database options.
|
|
539
|
+
*
|
|
540
|
+
* @param options - SMRT database options, as passed to any collection.
|
|
541
|
+
* @param serviceOptions - Host authorizer and resolver wiring. Omit
|
|
542
|
+
* `authorize` for a read-only (load-function) service.
|
|
543
|
+
*/
|
|
544
|
+
static async create(options = {}, serviceOptions = {}) {
|
|
545
|
+
const [definitions, overrides] = await Promise.all([FeatureDefinitionCollection.create(options), FeatureOverrideCollection.create(options)]);
|
|
546
|
+
return new FeatureSettingsService(definitions, overrides, new FeatureResolver(options, serviceOptions.resolver ?? {}), serviceOptions.authorize);
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* One {@link FeatureSettingsRow} per matching definition, ordered by owning
|
|
550
|
+
* package, then label, then key, so a rendered list is stable across loads.
|
|
551
|
+
*
|
|
552
|
+
* Makes no authorization decision — the caller has already decided that this
|
|
553
|
+
* principal may see this tenant's flags.
|
|
554
|
+
*/
|
|
555
|
+
async listFeatureSettings(options = {}) {
|
|
556
|
+
const definitions = await this.loadDefinitions(options);
|
|
557
|
+
return Promise.all(definitions.map((definition) => this.toRow(definition, options.tenantId)));
|
|
558
|
+
}
|
|
559
|
+
/** The single row for one key, or `null` when no definition owns that key. */
|
|
560
|
+
async getFeatureSetting(featureKey, tenantId) {
|
|
561
|
+
const definition = await this.definitions.findByFeatureKey(featureKey);
|
|
562
|
+
return definition ? this.toRow(definition, tenantId) : null;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Apply one override change.
|
|
566
|
+
*
|
|
567
|
+
* Refuses any `featureKey` without a {@link FeatureDefinition} row and any
|
|
568
|
+
* scope the resolver would never read back, then delegates to
|
|
569
|
+
* {@link FeatureOverrideService} so the host authorizer decides whether this
|
|
570
|
+
* caller may write this scope. `INHERIT` removes the row.
|
|
571
|
+
*
|
|
572
|
+
* @returns the stored override, or `null` when the row was removed (or was
|
|
573
|
+
* already absent).
|
|
574
|
+
* @throws {UnknownFeatureKeyError} when the key has no definition.
|
|
575
|
+
* @throws {InvalidFeatureScopeError} when the scope is not one the resolver reads.
|
|
576
|
+
* @throws `FeatureOverrideAuthorizationError` when the authorizer declines.
|
|
577
|
+
*/
|
|
578
|
+
async setFeatureOverride(request) {
|
|
579
|
+
const { featureKey, scopeType, scopeId, effect } = request;
|
|
580
|
+
if (!KNOWN_EFFECTS.has(effect)) throw new TypeError(`Unknown feature override effect: ${String(effect)}`);
|
|
581
|
+
assertValidFeatureScope(scopeType, scopeId);
|
|
582
|
+
await this.assertKnownFeatureKey(featureKey);
|
|
583
|
+
if (effect === FeatureOverrideEffect.INHERIT) {
|
|
584
|
+
await this.writes.removeOverride(featureKey, scopeType, scopeId);
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
return this.writes.setOverride(featureKey, scopeType, scopeId, effect);
|
|
588
|
+
}
|
|
589
|
+
/** {@link setFeatureOverride} for the global scope. */
|
|
590
|
+
async setGlobalFeatureOverride(featureKey, effect) {
|
|
591
|
+
return this.setFeatureOverride({
|
|
592
|
+
featureKey,
|
|
593
|
+
scopeType: "global",
|
|
594
|
+
scopeId: "*",
|
|
595
|
+
effect
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
/** {@link setFeatureOverride} for one tenant. */
|
|
599
|
+
async setTenantFeatureOverride(featureKey, tenantId, effect) {
|
|
600
|
+
return this.setFeatureOverride({
|
|
601
|
+
featureKey,
|
|
602
|
+
scopeType: "tenant",
|
|
603
|
+
scopeId: tenantId,
|
|
604
|
+
effect
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
async assertKnownFeatureKey(featureKey) {
|
|
608
|
+
const key = typeof featureKey === "string" ? featureKey.trim() : "";
|
|
609
|
+
if (!key || key !== featureKey) throw new UnknownFeatureKeyError(String(featureKey));
|
|
610
|
+
if (!await this.definitions.findByFeatureKey(key)) throw new UnknownFeatureKeyError(key);
|
|
611
|
+
}
|
|
612
|
+
async loadDefinitions(options) {
|
|
613
|
+
const definitions = options.packageName ? await this.definitions.findByPackageName(options.packageName) : await this.definitions.list({});
|
|
614
|
+
const allowed = options.featureKeys ? new Set(options.featureKeys) : null;
|
|
615
|
+
return [...allowed ? definitions.filter((definition) => allowed.has(definition.featureKey)) : definitions].sort(compareDefinitions);
|
|
616
|
+
}
|
|
617
|
+
async toRow(definition, tenantId) {
|
|
618
|
+
const { featureKey } = definition;
|
|
619
|
+
const [globalOverride, tenantOverride, effectiveEnabled] = await Promise.all([
|
|
620
|
+
this.overrides.getGlobalOverride(featureKey),
|
|
621
|
+
tenantId ? this.overrides.getTenantOverride(featureKey, tenantId) : Promise.resolve(null),
|
|
622
|
+
this.resolver.isEnabled(featureKey, tenantId ? { tenantId } : {})
|
|
623
|
+
]);
|
|
624
|
+
return {
|
|
625
|
+
featureKey,
|
|
626
|
+
label: definition.label,
|
|
627
|
+
description: definition.description,
|
|
628
|
+
packageName: definition.packageName,
|
|
629
|
+
qualifiedClassName: definition.qualifiedClassName,
|
|
630
|
+
className: definition.className,
|
|
631
|
+
localId: definition.localId,
|
|
632
|
+
visibility: definition.visibility,
|
|
633
|
+
metadata: definition.getMetadata(),
|
|
634
|
+
defaultEnabled: definition.defaultEnabled,
|
|
635
|
+
effectiveEnabled,
|
|
636
|
+
globalEffect: globalOverride?.effect ?? null,
|
|
637
|
+
tenantEffect: tenantOverride?.effect ?? null,
|
|
638
|
+
inheritedEnabled: tenantId && !tenantOverride ? effectiveEnabled : null
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
function assertValidFeatureScope(scopeType, scopeId) {
|
|
643
|
+
if (scopeType !== "global" && scopeType !== "tenant") throw new InvalidFeatureScopeError(String(scopeType), String(scopeId), "scope type must be \"global\" or \"tenant\"");
|
|
644
|
+
if (typeof scopeId !== "string") throw new InvalidFeatureScopeError(scopeType, String(scopeId), "scope id must be a string");
|
|
645
|
+
if (scopeType === "global" && scopeId !== "*") throw new InvalidFeatureScopeError(scopeType, scopeId, `the global scope is only ever "*"`);
|
|
646
|
+
if (scopeType === "tenant" && (!scopeId.trim() || scopeId !== scopeId.trim())) throw new InvalidFeatureScopeError(scopeType, scopeId, "a tenant scope id must be non-blank and already trimmed");
|
|
647
|
+
}
|
|
648
|
+
function compareDefinitions(a, b) {
|
|
649
|
+
return a.packageName.localeCompare(b.packageName) || (a.label || a.featureKey).localeCompare(b.label || b.featureKey) || a.featureKey.localeCompare(b.featureKey);
|
|
650
|
+
}
|
|
651
|
+
//#endregion
|
|
499
652
|
//#region src/feature-sync.ts
|
|
500
653
|
var FeatureSyncService = class {
|
|
501
654
|
options;
|
|
@@ -581,6 +734,6 @@ var FeatureSyncService = class {
|
|
|
581
734
|
}
|
|
582
735
|
};
|
|
583
736
|
//#endregion
|
|
584
|
-
export { FeatureDefinition, FeatureDefinitionCollection, FeatureOverride, FeatureOverrideAuthorizationError, FeatureOverrideCollection, FeatureOverrideEffect, FeatureOverrideService, FeatureResolver, FeatureSyncService, GLOBAL_FEATURE_SCOPE_ID, createFeatureKey, findFeatureDefaultInRegistry, parseFeatureKey, resolveFeatureKeyForTarget };
|
|
737
|
+
export { FeatureDefinition, FeatureDefinitionCollection, FeatureOverride, FeatureOverrideAuthorizationError, FeatureOverrideCollection, FeatureOverrideEffect, FeatureOverrideService, FeatureResolver, FeatureSettingsService, FeatureSyncService, GLOBAL_FEATURE_SCOPE_ID, InvalidFeatureScopeError, UnknownFeatureKeyError, createFeatureKey, featureOverrideEffectFromValue, findFeatureDefaultInRegistry, parseFeatureKey, resolveFeatureKeyForTarget };
|
|
585
738
|
|
|
586
739
|
//# sourceMappingURL=index.js.map
|