@happyvertical/smrt-features 0.55.5 → 0.55.7

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/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.55.5","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","displayLabelField":"label","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","enum":["global","tenant"]},"scopeId":{"type":"text","required":false},"effect":{"type":"text","required":false,"enum":["inherit","enable","disable"]}},"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"],"stampsConstructors":true}`));
5
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-features","packageVersion":"0.55.7","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","displayLabelField":"label","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","enum":["global","tenant"]},"scopeId":{"type":"text","required":false},"effect":{"type":"text","required":false,"enum":["inherit","enable","disable"]}},"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"],"stampsConstructors":true}`));
6
6
  //#endregion
7
7
  //#region src/utils.ts
8
8
  function createFeatureKey(qualifiedClassName, localId) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/utils.ts","../src/feature-definition.ts","../src/feature-definitions.ts","../src/feature-override.ts","../src/feature-override-service.ts","../src/feature-overrides.ts","../src/list-bounds.ts","../src/feature-resolver.ts","../src/feature-settings.ts","../src/feature-sync.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-features\\\",\\\"packageVersion\\\":\\\"0.55.5\\\",\\\"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\\\",\\\"displayLabelField\\\":\\\"label\\\",\\\"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\\\",\\\"enum\\\":[\\\"global\\\",\\\"tenant\\\"]},\\\"scopeId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"effect\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"enum\\\":[\\\"inherit\\\",\\\"enable\\\",\\\"disable\\\"]}},\\\"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\\\"],\\\"stampsConstructors\\\":true}\"));\n","import {\n createQualifiedName,\n isQualifiedName,\n ObjectRegistry,\n parseQualifiedName,\n type SmartObjectConfig,\n} from '@happyvertical/smrt-core';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '@happyvertical/smrt-core/manifest';\nimport type {\n FeatureDefinitionSeed,\n FeatureMetadata,\n FeatureTargetConstructor,\n} from './types.js';\n\nexport type RegistryEntryLike = {\n name: string;\n qualifiedName?: string;\n packageName?: string;\n config: SmartObjectConfig;\n visibility?: string;\n};\n\nexport function createFeatureKey(\n qualifiedClassName: string,\n localId: string,\n): string {\n if (!isQualifiedName(qualifiedClassName)) {\n throw new Error(\n `Feature keys require a qualified class name. Received \"${qualifiedClassName}\".`,\n );\n }\n\n if (!localId) {\n throw new Error('Feature localId is required.');\n }\n\n if (localId.includes('#')) {\n throw new Error(\n `Feature localId \"${localId}\" cannot contain \"#\". This character is reserved for canonical feature keys.`,\n );\n }\n\n return `${qualifiedClassName}#${localId}`;\n}\n\nexport function parseFeatureKey(featureKey: string): {\n qualifiedClassName: string;\n localId: string;\n} {\n const separatorIndex = featureKey.lastIndexOf('#');\n if (separatorIndex <= 0 || separatorIndex === featureKey.length - 1) {\n throw new Error(\n `Invalid feature key \"${featureKey}\". Expected format \"<qualifiedClassName>#<localId>\".`,\n );\n }\n\n const qualifiedClassName = featureKey.slice(0, separatorIndex);\n const localId = featureKey.slice(separatorIndex + 1);\n\n if (!isQualifiedName(qualifiedClassName)) {\n throw new Error(\n `Invalid feature key \"${featureKey}\". \"${qualifiedClassName}\" is not a qualified class name.`,\n );\n }\n\n return { qualifiedClassName, localId };\n}\n\nexport function serializeFeatureMetadata(\n metadata: FeatureMetadata | string | null | undefined,\n): string {\n if (!metadata) {\n return '';\n }\n\n if (typeof metadata === 'string') {\n const parsed = parseFeatureMetadataString(metadata);\n return JSON.stringify(parsed);\n }\n\n if (!isFeatureMetadataRecord(metadata)) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n );\n }\n\n return JSON.stringify(metadata);\n}\n\nexport function parseFeatureMetadata(\n metadata: string | null | undefined,\n): FeatureMetadata {\n if (!metadata) {\n return {};\n }\n\n try {\n return parseFeatureMetadataString(metadata);\n } catch {\n return {};\n }\n}\n\nfunction parseFeatureMetadataString(metadata: string): FeatureMetadata {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(metadata);\n } catch (error) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n { cause: error },\n );\n }\n\n if (!isFeatureMetadataRecord(parsed)) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n );\n }\n\n return parsed;\n}\n\nfunction isFeatureMetadataRecord(value: unknown): value is FeatureMetadata {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nexport function getQualifiedClassNameFromRegistry(\n registration: RegistryEntryLike,\n): string | null {\n if (\n registration.qualifiedName &&\n isQualifiedName(registration.qualifiedName)\n ) {\n return registration.qualifiedName;\n }\n\n if (registration.packageName) {\n return createQualifiedName(registration.packageName, registration.name);\n }\n\n return null;\n}\n\nexport function getPackageNameFromRegistry(\n registration: RegistryEntryLike,\n): string | null {\n if (registration.packageName) {\n return registration.packageName;\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n return null;\n }\n\n return parseQualifiedName(qualifiedClassName).packageName;\n}\n\nexport function extractFeatureSeedsFromRegistryEntry(\n registration: RegistryEntryLike,\n): FeatureDefinitionSeed[] {\n if (registration.visibility === 'test') {\n return [];\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n return [];\n }\n\n const featureConfig = registration.config.features;\n if (!featureConfig) {\n return [];\n }\n\n const packageName =\n registration.packageName ||\n parseQualifiedName(qualifiedClassName).packageName;\n\n return Object.entries(featureConfig).map(([localId, feature]) => ({\n featureKey: createFeatureKey(qualifiedClassName, localId),\n packageName,\n qualifiedClassName,\n className: registration.name,\n localId,\n defaultEnabled: feature.defaultEnabled,\n label: feature.label,\n description: feature.description,\n metadata: feature.metadata,\n visibility: registration.visibility,\n }));\n}\n\nexport function extractFeatureSeedsFromManifest(\n manifest: SmartObjectManifest,\n): FeatureDefinitionSeed[] {\n const seeds: FeatureDefinitionSeed[] = [];\n\n for (const [objectKey, objectDef] of Object.entries(manifest.objects)) {\n seeds.push(...extractFeatureSeedsFromManifestObject(objectKey, objectDef));\n }\n\n return seeds;\n}\n\nexport function extractTouchedPackagesFromManifest(\n manifest: SmartObjectManifest,\n): Set<string> {\n const packages = new Set<string>();\n\n if (manifest.packageName) {\n packages.add(manifest.packageName);\n }\n\n for (const [objectKey, objectDef] of Object.entries(manifest.objects)) {\n if (objectDef.visibility === 'test') {\n continue;\n }\n\n if (objectDef.packageName) {\n packages.add(objectDef.packageName);\n continue;\n }\n\n const qualifiedClassName = resolveManifestQualifiedClassName(\n objectKey,\n objectDef,\n );\n if (qualifiedClassName) {\n packages.add(parseQualifiedName(qualifiedClassName).packageName);\n }\n }\n\n return packages;\n}\n\nfunction extractFeatureSeedsFromManifestObject(\n objectKey: string,\n objectDef: SmartObjectDefinition,\n): FeatureDefinitionSeed[] {\n if (objectDef.visibility === 'test') {\n return [];\n }\n\n const features = objectDef.decoratorConfig.features;\n if (!features) {\n return [];\n }\n\n const qualifiedClassName = resolveManifestQualifiedClassName(\n objectKey,\n objectDef,\n );\n if (!qualifiedClassName) {\n return [];\n }\n\n const packageName =\n objectDef.packageName || parseQualifiedName(qualifiedClassName).packageName;\n\n return Object.entries(features).map(([localId, feature]) => ({\n featureKey: createFeatureKey(qualifiedClassName, localId),\n packageName,\n qualifiedClassName,\n className: objectDef.className,\n localId,\n defaultEnabled: feature.defaultEnabled,\n label: feature.label,\n description: feature.description,\n metadata:\n feature.metadata && typeof feature.metadata === 'object'\n ? (feature.metadata as FeatureMetadata)\n : undefined,\n visibility: objectDef.visibility,\n }));\n}\n\nfunction resolveManifestQualifiedClassName(\n objectKey: string,\n objectDef: SmartObjectDefinition,\n): string | null {\n if (objectDef.qualifiedName && isQualifiedName(objectDef.qualifiedName)) {\n return objectDef.qualifiedName;\n }\n\n if (isQualifiedName(objectKey)) {\n return objectKey;\n }\n\n if (objectDef.packageName) {\n return createQualifiedName(objectDef.packageName, objectDef.className);\n }\n\n return null;\n}\n\nexport function resolveFeatureKeyForTarget(\n classOrInstance: object | FeatureTargetConstructor,\n localId: string,\n): {\n featureKey: string;\n defaultEnabled: boolean;\n} {\n const ctor: FeatureTargetConstructor =\n typeof classOrInstance === 'function'\n ? (classOrInstance as FeatureTargetConstructor)\n : (classOrInstance.constructor as FeatureTargetConstructor);\n\n const registration = ObjectRegistry.getClassByConstructor(ctor);\n if (!registration) {\n throw new Error(\n `Cannot resolve feature \"${localId}\" because ${ctor?.name || 'the target class'} is not registered with @smrt().`,\n );\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n throw new Error(\n `Cannot resolve feature \"${localId}\" for ${registration.name} because the class has no qualified package identity.`,\n );\n }\n\n const feature = registration.config.features?.[localId];\n if (!feature) {\n throw new Error(\n `Feature \"${localId}\" is not declared on ${qualifiedClassName}.`,\n );\n }\n\n return {\n featureKey: createFeatureKey(qualifiedClassName, localId),\n defaultEnabled: feature.defaultEnabled,\n };\n}\n\nexport function findFeatureDefaultInRegistry(\n featureKey: string,\n): boolean | undefined {\n const { qualifiedClassName, localId } = parseFeatureKey(featureKey);\n const registration =\n ObjectRegistry.getClassByQualifiedName(qualifiedClassName) ||\n ObjectRegistry.getClass(qualifiedClassName);\n\n const feature = registration?.config.features?.[localId];\n return feature?.defaultEnabled;\n}\n","import { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport type { FeatureDefinitionOptions, FeatureMetadata } from './types.js';\nimport { parseFeatureMetadata, serializeFeatureMetadata } from './utils.js';\n\n@smrt({\n tableName: '_smrt_feature_definitions',\n // Closed by default like FeatureOverride (#3013): the catalog is framework\n // state synced from manifests, not a tenant resource.\n api: false,\n cli: false,\n mcp: false,\n conflictColumns: ['feature_key'],\n})\nexport class FeatureDefinition extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-features\";\n featureKey: string = '';\n packageName: string = '';\n qualifiedClassName: string = '';\n className: string = '';\n localId: string = '';\n defaultEnabled: boolean = false;\n label: string = '';\n description: string = '';\n metadata: string = '';\n visibility: string = 'public';\n\n constructor(options: FeatureDefinitionOptions = {}) {\n super(options);\n\n if (options.featureKey !== undefined) this.featureKey = options.featureKey;\n if (options.packageName !== undefined)\n this.packageName = options.packageName;\n if (options.qualifiedClassName !== undefined) {\n this.qualifiedClassName = options.qualifiedClassName;\n }\n if (options.className !== undefined) this.className = options.className;\n if (options.localId !== undefined) this.localId = options.localId;\n if (options.defaultEnabled !== undefined) {\n this.defaultEnabled = options.defaultEnabled;\n }\n if (options.label !== undefined) this.label = options.label;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.visibility !== undefined) this.visibility = options.visibility;\n if (options.metadata !== undefined) {\n this.metadata = serializeFeatureMetadata(options.metadata);\n }\n }\n\n getMetadata(): FeatureMetadata {\n return parseFeatureMetadata(this.metadata);\n }\n\n setMetadata(metadata: FeatureMetadata | null): void {\n this.metadata = serializeFeatureMetadata(metadata);\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { FeatureDefinition } from './feature-definition.js';\nimport type { FeatureDefinitionSeed } from './types.js';\nimport { serializeFeatureMetadata } from './utils.js';\n\nexport class FeatureDefinitionCollection extends SmrtCollection<FeatureDefinition> {\n static readonly _itemClass = FeatureDefinition;\n\n async findByFeatureKey(\n featureKey: string,\n ): Promise<FeatureDefinition | null> {\n const results = await this.list({\n where: { featureKey },\n limit: 1,\n });\n return results[0] ?? null;\n }\n\n async findByPackageName(packageName: string): Promise<FeatureDefinition[]> {\n return this.list({\n where: { packageName },\n });\n }\n\n async upsertDefinition(seed: FeatureDefinitionSeed): Promise<{\n definition: FeatureDefinition;\n status: 'created' | 'updated' | 'unchanged';\n }> {\n const existing = await this.findByFeatureKey(seed.featureKey);\n\n if (!existing) {\n const created = await this.create({\n ...seed,\n metadata: serializeFeatureMetadata(seed.metadata),\n });\n await created.save();\n return { definition: created, status: 'created' };\n }\n\n const nextMetadata = serializeFeatureMetadata(seed.metadata);\n const changed =\n existing.packageName !== seed.packageName ||\n existing.qualifiedClassName !== seed.qualifiedClassName ||\n existing.className !== seed.className ||\n existing.localId !== seed.localId ||\n existing.defaultEnabled !== seed.defaultEnabled ||\n existing.label !== (seed.label ?? '') ||\n existing.description !== (seed.description ?? '') ||\n existing.metadata !== nextMetadata ||\n existing.visibility !== (seed.visibility ?? 'public');\n\n if (!changed) {\n return { definition: existing, status: 'unchanged' };\n }\n\n existing.packageName = seed.packageName;\n existing.qualifiedClassName = seed.qualifiedClassName;\n existing.className = seed.className;\n existing.localId = seed.localId;\n existing.defaultEnabled = seed.defaultEnabled;\n existing.label = seed.label ?? '';\n existing.description = seed.description ?? '';\n existing.metadata = nextMetadata;\n existing.visibility = seed.visibility ?? 'public';\n await existing.save();\n\n return { definition: existing, status: 'updated' };\n }\n}\n","import { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport {\n FeatureOverrideEffect,\n type FeatureOverrideOptions,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\n// Override rows are authorization state: any scope (global, another tenant,\n// another user) can be written, and the object is not tenant-scoped. Generated\n// REST routes and MCP tools only check authentication, so they are closed\n// (#3013). Hosts write overrides server-side through\n// `FeatureOverrideService`, which requires an explicit authorizer for every\n// write (or the collection's `setOverride()` / `removeOverride()` after their\n// own authorization decision). The CLI is closed too: generated CLI commands\n// dispatch through the generated API.\n@smrt({\n tableName: '_smrt_feature_overrides',\n api: false,\n cli: false,\n mcp: false,\n conflictColumns: ['feature_key', 'scope_type', 'scope_id'],\n})\nexport class FeatureOverride extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-features\";\n featureKey: string = '';\n scopeType: FeatureScopeType = 'global';\n scopeId: string = GLOBAL_FEATURE_SCOPE_ID;\n effect: FeatureOverrideEffect = FeatureOverrideEffect.INHERIT;\n\n constructor(options: FeatureOverrideOptions = {}) {\n super(options);\n\n if (options.featureKey !== undefined) this.featureKey = options.featureKey;\n if (options.scopeType !== undefined) this.scopeType = options.scopeType;\n if (options.scopeId !== undefined) this.scopeId = options.scopeId;\n if (options.effect !== undefined) this.effect = options.effect;\n }\n\n isInherit(): boolean {\n return this.effect === FeatureOverrideEffect.INHERIT;\n }\n\n isEnabled(): boolean {\n return this.effect === FeatureOverrideEffect.ENABLE;\n }\n\n isDisabled(): boolean {\n return this.effect === FeatureOverrideEffect.DISABLE;\n }\n}\n","import type { FeatureOverride } from './feature-override.js';\nimport type { FeatureOverrideCollection } from './feature-overrides.js';\nimport type { FeatureOverrideEffect, FeatureScopeType } from './types.js';\n\n/** One override write the host must authorize before it runs (#3013). */\nexport interface FeatureOverrideWriteRequest {\n operation: 'set' | 'remove';\n featureKey: string;\n scopeType: FeatureScopeType;\n scopeId: string;\n /** Present for `set`. */\n effect?: FeatureOverrideEffect;\n}\n\n/**\n * The host's explicit authorization decision for one override write. Return\n * `true` only when the current caller may write that exact scope; anything\n * else denies.\n */\nexport type FeatureOverrideAuthorizer = (\n request: FeatureOverrideWriteRequest,\n) => boolean | Promise<boolean>;\n\n/** Thrown when the authorizer does not return `true`. Nothing is written. */\nexport class FeatureOverrideAuthorizationError extends Error {\n readonly status = 403;\n constructor(readonly request: FeatureOverrideWriteRequest) {\n super(\n `Feature override ${request.operation} denied for ${request.scopeType} scope`,\n );\n this.name = 'FeatureOverrideAuthorizationError';\n }\n}\n\n/**\n * Authorized write path for feature overrides (#3013). Override rows are\n * authorization state for every scope and `FeatureOverride` is not\n * tenant-scoped, so generated surfaces are closed. Hosts that let callers\n * change flags construct this service with an authorizer bound to the\n * current caller and write through it; every write asks the authorizer\n * first and fails closed.\n */\nexport class FeatureOverrideService {\n constructor(\n private readonly overrides: FeatureOverrideCollection,\n private readonly authorize: FeatureOverrideAuthorizer,\n ) {}\n\n async setOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n await this.require({\n operation: 'set',\n featureKey,\n scopeType,\n scopeId,\n effect,\n });\n return this.overrides.setOverride(featureKey, scopeType, scopeId, effect);\n }\n\n async removeOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<boolean> {\n await this.require({ operation: 'remove', featureKey, scopeType, scopeId });\n return this.overrides.removeOverride(featureKey, scopeType, scopeId);\n }\n\n private async require(request: FeatureOverrideWriteRequest): Promise<void> {\n let allowed = false;\n try {\n allowed = (await this.authorize(request)) === true;\n } catch {\n allowed = false;\n }\n if (!allowed) throw new FeatureOverrideAuthorizationError(request);\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { FeatureOverride } from './feature-override.js';\nimport {\n type FeatureOverrideEffect,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\nexport class FeatureOverrideCollection extends SmrtCollection<FeatureOverride> {\n static readonly _itemClass = FeatureOverride;\n\n async findByFeatureKey(featureKey: string): Promise<FeatureOverride[]> {\n return this.list({\n where: { featureKey },\n });\n }\n\n async findByFeatureAndScope(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<FeatureOverride | null> {\n const results = await this.list({\n where: { featureKey, scopeType, scopeId },\n limit: 1,\n });\n return results[0] ?? null;\n }\n\n async getGlobalOverride(featureKey: string): Promise<FeatureOverride | null> {\n return this.findByFeatureAndScope(\n featureKey,\n 'global',\n GLOBAL_FEATURE_SCOPE_ID,\n );\n }\n\n async getTenantOverride(\n featureKey: string,\n tenantId: string,\n ): Promise<FeatureOverride | null> {\n return this.findByFeatureAndScope(featureKey, 'tenant', tenantId);\n }\n\n async getOverrideMap(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeIds: string[],\n ): Promise<Map<string, FeatureOverride>> {\n const result = new Map<string, FeatureOverride>();\n if (scopeIds.length === 0) {\n return result;\n }\n\n const overrides = await this.list({\n where: { featureKey, scopeType, scopeId: scopeIds },\n });\n\n for (const override of overrides) {\n result.set(override.scopeId, override);\n }\n\n return result;\n }\n\n async setOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n const existing = await this.findByFeatureAndScope(\n featureKey,\n scopeType,\n scopeId,\n );\n\n if (existing) {\n existing.effect = effect;\n await existing.save();\n return existing;\n }\n\n const created = await this.create({\n featureKey,\n scopeType,\n scopeId,\n effect,\n });\n await created.save();\n return created;\n }\n\n async setGlobalOverride(\n featureKey: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n return this.setOverride(\n featureKey,\n 'global',\n GLOBAL_FEATURE_SCOPE_ID,\n effect,\n );\n }\n\n async setTenantOverride(\n featureKey: string,\n tenantId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n return this.setOverride(featureKey, 'tenant', tenantId, effect);\n }\n\n async removeOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<boolean> {\n const existing = await this.findByFeatureAndScope(\n featureKey,\n scopeType,\n scopeId,\n );\n\n if (!existing) {\n return false;\n }\n\n await existing.delete();\n return true;\n }\n}\n","/** Collection options for framework-internal, correctness-critical reads. @packageDocumentation */\nimport type {\n SmrtClassOptions,\n SmrtCollectionOptions,\n} from '@happyvertical/smrt-core';\n\n/** Host options this package accepts before stripping internal list bounds. */\nexport type FeatureHostOptions = SmrtClassOptions &\n Pick<SmrtCollectionOptions, 'defaultListLimit' | 'maxListLimit'>;\n\n/**\n * The caller's options with its list bounds removed.\n *\n * `SmrtCollection.create()` forwards `defaultListLimit`/`maxListLimit` from\n * any options bag it is handed (#2367), so a host that configures those\n * application-wide — a perfectly ordinary thing to do — would silently cap\n * every internal enumeration this package runs. Two of those are\n * correctness-critical and neither is a user-facing page of results\n * (`FeatureDefinition`/`FeatureOverride` expose no generated list surface,\n * #3013): a dropped ancestor override changes the flag's *resolved value*\n * (`FeatureResolver.isEnabled()`), and a dropped definition makes a feature\n * invisible to a management screen or a sync prune pass (#3056, same hazard\n * class as #3048). The collections built here are therefore always created\n * from this bag. Only the list bounds are stripped; the database, tenancy\n * context, and every other option still apply.\n *\n * This is a local copy of `@happyvertical/smrt-users`'\n * `authorization-read-options.ts#withoutListBounds` (added for #3048/#3051).\n * `smrt-features` deliberately never imports `smrt-users` (see package\n * AGENTS.md), and no shared `smrt-core` helper exists for this yet, so the\n * two-line implementation is duplicated here rather than adding a\n * cross-package dependency for it.\n */\nexport function withoutListBounds(\n options: SmrtClassOptions | SmrtCollectionOptions,\n): SmrtCollectionOptions {\n return { ...options, defaultListLimit: undefined, maxListLimit: undefined };\n}\n","import type { SmrtClassOptions } from '@happyvertical/smrt-core';\nimport { importWorkspaceModule } from '@happyvertical/smrt-core/utils/import-workspace-module';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport { FeatureOverrideCollection } from './feature-overrides.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport {\n FeatureOverrideEffect,\n type FeatureResolutionContext,\n type FeatureResolverOptions,\n type FeatureTargetConstructor,\n type FeatureTenantHierarchyProvider,\n type FeatureTenantNode,\n type FeatureUsersModule,\n} from './types.js';\nimport {\n findFeatureDefaultInRegistry,\n resolveFeatureKeyForTarget,\n} from './utils.js';\n\nexport class FeatureResolver {\n private readonly options: FeatureHostOptions;\n private readonly resolverOptions: FeatureResolverOptions;\n private featureDefinitions!: FeatureDefinitionCollection;\n private featureOverrides!: FeatureOverrideCollection;\n private initializationPromise: Promise<void> | null = null;\n private tenantHierarchyPromise: Promise<FeatureTenantHierarchyProvider | null> | null =\n null;\n\n constructor(\n options: FeatureHostOptions = {},\n resolverOptions: FeatureResolverOptions = {},\n ) {\n this.options = options;\n this.resolverOptions = resolverOptions;\n }\n\n async isEnabled(\n featureKey: string,\n context: FeatureResolutionContext = {},\n ): Promise<boolean> {\n await this.ensureInitialized();\n\n const baseState = await this.resolveBaseState(featureKey);\n const globalOverride =\n await this.featureOverrides.getGlobalOverride(featureKey);\n const globalState = this.applyOverride(baseState, globalOverride?.effect);\n\n if (!context.tenantId) {\n return globalState;\n }\n\n const tenantHierarchy = await this.getTenantHierarchy();\n if (!tenantHierarchy) {\n const directOverride = await this.featureOverrides.getTenantOverride(\n featureKey,\n context.tenantId,\n );\n return this.applyOverride(globalState, directOverride?.effect);\n }\n\n const chain = await tenantHierarchy.getChain(context.tenantId);\n if (chain.length === 0) {\n const directOverride = await this.featureOverrides.getTenantOverride(\n featureKey,\n context.tenantId,\n );\n return this.applyOverride(globalState, directOverride?.effect);\n }\n\n const overrides = await this.featureOverrides.getOverrideMap(\n featureKey,\n 'tenant',\n chain.map((node) => node.id),\n );\n\n let inheritedState = globalState;\n\n for (let index = 0; index < chain.length; index++) {\n const current = chain[index];\n const previous = index > 0 ? chain[index - 1] : null;\n const shouldInherit =\n index === 0 ||\n (!!previous?.cascadePermissions && current.inheritPermissions);\n\n const baseline = shouldInherit ? inheritedState : globalState;\n const override = overrides.get(current.id);\n inheritedState = this.applyOverride(baseline, override?.effect);\n }\n\n return inheritedState;\n }\n\n async isEnabledFor(\n classOrInstance: object | FeatureTargetConstructor,\n localId: string,\n context: FeatureResolutionContext = {},\n ): Promise<boolean> {\n const { featureKey } = resolveFeatureKeyForTarget(classOrInstance, localId);\n return this.isEnabled(featureKey, context);\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initializationPromise) {\n this.initializationPromise = (async () => {\n // A host-configured `defaultListLimit`/`maxListLimit` must never reach\n // these reads: `getOverrideMap()` walks the tenant ancestor chain, and\n // a dropped ancestor override would change the flag's resolved value\n // silently (#3056, same hazard class as #3048).\n const options = withoutListBounds(this.options);\n this.featureDefinitions =\n await FeatureDefinitionCollection.create(options);\n this.featureOverrides = await FeatureOverrideCollection.create(options);\n })();\n }\n\n await this.initializationPromise;\n }\n\n private async resolveBaseState(featureKey: string): Promise<boolean> {\n const registryDefault = findFeatureDefaultInRegistry(featureKey);\n if (registryDefault !== undefined) {\n return registryDefault;\n }\n\n const definition =\n await this.featureDefinitions.findByFeatureKey(featureKey);\n if (!definition) {\n throw new Error(\n `Feature \"${featureKey}\" is not declared in the registry or synced feature definitions.`,\n );\n }\n\n return definition.defaultEnabled;\n }\n\n private applyOverride(\n currentState: boolean,\n effect: FeatureOverrideEffect | undefined,\n ): boolean {\n switch (effect) {\n case FeatureOverrideEffect.ENABLE:\n return true;\n case FeatureOverrideEffect.DISABLE:\n return false;\n default:\n return currentState;\n }\n }\n\n private async getTenantHierarchy(): Promise<FeatureTenantHierarchyProvider | null> {\n if (!this.tenantHierarchyPromise) {\n const loader =\n this.resolverOptions.tenantHierarchyLoader ||\n defaultTenantHierarchyLoader;\n this.tenantHierarchyPromise = loader(this.options);\n }\n\n return this.tenantHierarchyPromise;\n }\n}\n\nasync function defaultTenantHierarchyLoader(\n options: SmrtClassOptions,\n): Promise<FeatureTenantHierarchyProvider | null> {\n try {\n const usersModule = await importWorkspaceModule<FeatureUsersModule>({\n packageName: '@happyvertical/smrt-users',\n sourceEntry: 'packages/users/src/collections/index.ts',\n purpose: 'tenant-aware feature flag resolution',\n });\n\n const tenantCollection = await usersModule.TenantCollection.create(options);\n return {\n async getChain(tenantId: string): Promise<FeatureTenantNode[]> {\n const tenant = await tenantCollection.get({ id: tenantId });\n if (!tenant) {\n return [];\n }\n\n const ancestors = await tenantCollection.getAncestorsFromRoot(tenantId);\n return [...ancestors, tenant].map((node) => ({\n id: String(node.id),\n inheritPermissions: Boolean(node.inheritPermissions),\n cascadePermissions: Boolean(node.cascadePermissions),\n }));\n },\n };\n } catch (error) {\n if (isMissingUsersDependency(error)) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isMissingUsersDependency(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const causeMessage =\n error.cause instanceof Error ? ` ${error.cause.message}` : '';\n const text = `${error.message}${causeMessage}`;\n\n return (\n text.includes('@happyvertical/smrt-users') &&\n (text.includes('Cannot find module') ||\n text.includes('Failed to load') ||\n text.includes('could not find'))\n );\n}\n","import type { FeatureDefinition } from './feature-definition.js';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport type { FeatureOverride } from './feature-override.js';\nimport {\n type FeatureOverrideAuthorizer,\n FeatureOverrideService,\n} from './feature-override-service.js';\nimport { FeatureOverrideCollection } from './feature-overrides.js';\nimport { FeatureResolver } from './feature-resolver.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport {\n type FeatureMetadata,\n FeatureOverrideEffect,\n type FeatureResolverOptions,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\n/**\n * One feature, rendered for a management screen: the code-owned definition,\n * the value that is actually in effect for the requested tenant, and the raw\n * override row at each scope level so the UI can show *why* it is in effect.\n *\n * Structurally assignable to the presentational `FeatureSettingsView` consumed\n * by `@happyvertical/smrt-features/svelte`, so a server load can hand its rows\n * straight to `FeatureSettingsPanel` without a mapping step.\n */\nexport interface FeatureSettingsRow {\n /**\n * The persisted identifier. Renaming it orphans every existing override —\n * see the warning on {@link FeatureSettingsService}.\n */\n featureKey: string;\n /** Human label from the definition; may be empty. */\n label: string;\n /** Human description from the definition; may be empty. */\n description: string;\n /** Owning package, as synced from the manifest. */\n packageName: string;\n /** Qualified `package:Class` name of the feature's target. */\n qualifiedClassName: string;\n /** Unqualified class name of the feature's target. */\n className: string;\n /** Class-local feature id. */\n localId: string;\n /** Definition visibility marker (`public` unless the seed says otherwise). */\n visibility: string;\n /** Parsed definition metadata. */\n metadata: FeatureMetadata;\n /** The code-owned default, used when no override applies. */\n defaultEnabled: boolean;\n /**\n * What {@link FeatureResolver} resolves for the requested context — the\n * value the application actually behaves by.\n */\n effectiveEnabled: boolean;\n /** Effect of the global override row, or `null` when there is none. */\n globalEffect: FeatureOverrideEffect | null;\n /**\n * Effect of the override row for the requested tenant, or `null` when there\n * is none (or when no `tenantId` was requested).\n */\n tenantEffect: FeatureOverrideEffect | null;\n /**\n * What this feature resolves to for the requested tenant with **no override\n * of its own** — the state that removing the tenant override would produce,\n * which is what a management UI must name on its \"back to Default\" control.\n *\n * `null` when no `tenantId` was requested — nothing tenant-inherited was\n * computed, and the global state is not an answer to a question about a\n * tenant — and `null` when the tenant holds an override of its own, because\n * then the inherited state depends on the levels above this tenant, which a\n * configured `FeatureTenantHierarchyProvider` extends to ancestor tenants'\n * overrides. It is reported only for a requested tenant with no override of\n * its own, where the inherited state *is* the effective state. Rows that\n * leave it `null` get the neutral \"Default (inherited)\" label in the panel,\n * never a claim about a state nothing computed.\n */\n inheritedEnabled: boolean | null;\n}\n\n/** Selection for {@link FeatureSettingsService.listFeatureSettings}. */\nexport interface ListFeatureSettingsOptions {\n /**\n * Tenant whose overrides and effective values to report. Omit for a\n * global-only view.\n */\n tenantId?: string;\n /** Restrict to one owning package (the usual case for an app's own screen). */\n packageName?: string;\n /**\n * Restrict to an explicit allowlist of keys. Keys with no definition are\n * simply absent from the result — this filters, it does not validate.\n */\n featureKeys?: string[];\n}\n\n/** One override write requested through {@link FeatureSettingsService}. */\nexport interface SetFeatureOverrideRequest {\n featureKey: string;\n scopeType: FeatureScopeType;\n scopeId: string;\n /**\n * `INHERIT` removes the override row at that scope, returning the feature to\n * whatever the next level up resolves to.\n */\n effect: FeatureOverrideEffect;\n}\n\n/**\n * Thrown when a write names a `featureKey` that has no {@link FeatureDefinition}\n * row. Nothing is written.\n *\n * This is the generalized form of the per-app \"is this one of my keys?\" guard\n * every consumer would otherwise hand-roll to keep a form post from creating an\n * override for an arbitrary string.\n */\nexport class UnknownFeatureKeyError extends Error {\n readonly status = 400;\n constructor(readonly featureKey: string) {\n super(`Unknown feature key: ${featureKey}`);\n this.name = 'UnknownFeatureKeyError';\n }\n}\n\n/**\n * Thrown when a write names a scope the resolver would never read back: an\n * unknown `scopeType`, a global write under anything but\n * {@link GLOBAL_FEATURE_SCOPE_ID}, or a tenant write with a blank or untrimmed\n * `scopeId`. Nothing is written.\n *\n * `FeatureOverride` rows are looked up by the exact `(featureKey, scopeType,\n * scopeId)` triple, so a row stored under a scope nothing queries is invisible\n * state: it never takes effect, and it silently reappears if the scope naming\n * is ever corrected.\n */\nexport class InvalidFeatureScopeError extends Error {\n readonly status = 400;\n constructor(\n readonly scopeType: string,\n readonly scopeId: string,\n reason: string,\n ) {\n super(`Invalid feature override scope (${scopeType}): ${reason}`);\n this.name = 'InvalidFeatureScopeError';\n }\n}\n\n/** Options for {@link FeatureSettingsService.create}. */\nexport interface FeatureSettingsServiceOptions {\n /**\n * The host's authorization decision for each override write, bound to the\n * current caller. **Omitting it makes the service read-only**: every write\n * then fails closed with `FeatureOverrideAuthorizationError`. This\n * package never decides who may write.\n */\n authorize?: FeatureOverrideAuthorizer;\n /** Forwarded to {@link FeatureResolver} (e.g. the tenant-hierarchy loader). */\n resolver?: FeatureResolverOptions;\n}\n\nconst KNOWN_EFFECTS = new Set<string>(Object.values(FeatureOverrideEffect));\n\n/**\n * Coerce an untrusted value (a form field, a query parameter, a JSON body) to a\n * {@link FeatureOverrideEffect}. Anything unrecognized — including `null` and\n * `undefined` — becomes `INHERIT`, i.e. \"back to the default\", which is the\n * safe reading of a value the host could not parse.\n */\nexport function featureOverrideEffectFromValue(\n value: unknown,\n): FeatureOverrideEffect {\n if (value === FeatureOverrideEffect.ENABLE)\n return FeatureOverrideEffect.ENABLE;\n if (value === FeatureOverrideEffect.DISABLE)\n return FeatureOverrideEffect.DISABLE;\n return FeatureOverrideEffect.INHERIT;\n}\n\n/**\n * Read and write side of a feature-flag management screen, so consumers do not\n * re-derive the row shape or the unknown-key guard.\n *\n * **Authorization stays with the consumer.** This service makes no\n * authorization decision of its own: reads are unfiltered, and every write is\n * delegated to {@link FeatureOverrideService}, which asks the host-supplied\n * {@link FeatureOverrideAuthorizer} first and fails closed. Call it only from\n * server code that has already established who the caller is. See\n * `packages/features/README.md` for the consumer recipe.\n *\n * **Feature keys are persisted identifiers.** Overrides are stored keyed by the\n * exact `featureKey` string and resolved by that string at runtime. Renaming a\n * key orphans every existing override, silently reverting all tenants to the\n * definition default. Treat a key as immutable once shipped; a rename needs a\n * data migration, not an edit.\n */\nexport class FeatureSettingsService {\n private readonly writes: FeatureOverrideService;\n\n constructor(\n private readonly definitions: FeatureDefinitionCollection,\n private readonly overrides: FeatureOverrideCollection,\n private readonly resolver: FeatureResolver,\n authorize?: FeatureOverrideAuthorizer,\n ) {\n this.writes = new FeatureOverrideService(\n overrides,\n authorize ?? (() => false),\n );\n }\n\n /**\n * Build a service over the given database options.\n *\n * @param options - SMRT database options, as passed to any collection.\n * @param serviceOptions - Host authorizer and resolver wiring. Omit\n * `authorize` for a read-only (load-function) service.\n */\n static async create(\n options: FeatureHostOptions = {},\n serviceOptions: FeatureSettingsServiceOptions = {},\n ): Promise<FeatureSettingsService> {\n // The catalog enumeration (`loadDefinitions()`) and every override read\n // this service does are internal, correctness-critical reads — not a\n // user-facing page of results — so a host-configured `defaultListLimit`/\n // `maxListLimit` must never truncate them (#3056, same hazard class as\n // #3048).\n const boundedOptions = withoutListBounds(options);\n const [definitions, overrides] = await Promise.all([\n FeatureDefinitionCollection.create(boundedOptions),\n FeatureOverrideCollection.create(boundedOptions),\n ]);\n return new FeatureSettingsService(\n definitions as FeatureDefinitionCollection,\n overrides as FeatureOverrideCollection,\n new FeatureResolver(options, serviceOptions.resolver ?? {}),\n serviceOptions.authorize,\n );\n }\n\n /**\n * One {@link FeatureSettingsRow} per matching definition, ordered by owning\n * package, then label, then key, so a rendered list is stable across loads.\n *\n * Makes no authorization decision — the caller has already decided that this\n * principal may see this tenant's flags.\n */\n async listFeatureSettings(\n options: ListFeatureSettingsOptions = {},\n ): Promise<FeatureSettingsRow[]> {\n const definitions = await this.loadDefinitions(options);\n\n return Promise.all(\n definitions.map((definition) => this.toRow(definition, options.tenantId)),\n );\n }\n\n /** The single row for one key, or `null` when no definition owns that key. */\n async getFeatureSetting(\n featureKey: string,\n tenantId?: string,\n ): Promise<FeatureSettingsRow | null> {\n const definition = await this.definitions.findByFeatureKey(featureKey);\n return definition ? this.toRow(definition, tenantId) : null;\n }\n\n /**\n * Apply one override change.\n *\n * Refuses any `featureKey` without a {@link FeatureDefinition} row and any\n * scope the resolver would never read back, then delegates to\n * {@link FeatureOverrideService} so the host authorizer decides whether this\n * caller may write this scope. `INHERIT` removes the row.\n *\n * @returns the stored override, or `null` when the row was removed (or was\n * already absent).\n * @throws {UnknownFeatureKeyError} when the key has no definition.\n * @throws {InvalidFeatureScopeError} when the scope is not one the resolver reads.\n * @throws `FeatureOverrideAuthorizationError` when the authorizer declines.\n */\n async setFeatureOverride(\n request: SetFeatureOverrideRequest,\n ): Promise<FeatureOverride | null> {\n const { featureKey, scopeType, scopeId, effect } = request;\n\n if (!KNOWN_EFFECTS.has(effect)) {\n throw new TypeError(`Unknown feature override effect: ${String(effect)}`);\n }\n assertValidFeatureScope(scopeType, scopeId);\n await this.assertKnownFeatureKey(featureKey);\n\n if (effect === FeatureOverrideEffect.INHERIT) {\n await this.writes.removeOverride(featureKey, scopeType, scopeId);\n return null;\n }\n\n return this.writes.setOverride(featureKey, scopeType, scopeId, effect);\n }\n\n /** {@link setFeatureOverride} for the global scope. */\n async setGlobalFeatureOverride(\n featureKey: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride | null> {\n return this.setFeatureOverride({\n featureKey,\n scopeType: 'global',\n scopeId: GLOBAL_FEATURE_SCOPE_ID,\n effect,\n });\n }\n\n /** {@link setFeatureOverride} for one tenant. */\n async setTenantFeatureOverride(\n featureKey: string,\n tenantId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride | null> {\n return this.setFeatureOverride({\n featureKey,\n scopeType: 'tenant',\n scopeId: tenantId,\n effect,\n });\n }\n\n private async assertKnownFeatureKey(featureKey: string): Promise<void> {\n const key = typeof featureKey === 'string' ? featureKey.trim() : '';\n if (!key || key !== featureKey) {\n throw new UnknownFeatureKeyError(String(featureKey));\n }\n const definition = await this.definitions.findByFeatureKey(key);\n if (!definition) {\n throw new UnknownFeatureKeyError(key);\n }\n }\n\n private async loadDefinitions(\n options: ListFeatureSettingsOptions,\n ): Promise<FeatureDefinition[]> {\n const definitions = options.packageName\n ? await this.definitions.findByPackageName(options.packageName)\n : await this.definitions.list({});\n\n const allowed = options.featureKeys ? new Set(options.featureKeys) : null;\n const selected = allowed\n ? definitions.filter((definition) => allowed.has(definition.featureKey))\n : definitions;\n\n return [...selected].sort(compareDefinitions);\n }\n\n private async toRow(\n definition: FeatureDefinition,\n tenantId?: string,\n ): Promise<FeatureSettingsRow> {\n const { featureKey } = definition;\n const [globalOverride, tenantOverride, effectiveEnabled] =\n await Promise.all([\n this.overrides.getGlobalOverride(featureKey),\n tenantId\n ? this.overrides.getTenantOverride(featureKey, tenantId)\n : Promise.resolve(null),\n this.resolver.isEnabled(featureKey, tenantId ? { tenantId } : {}),\n ]);\n\n return {\n featureKey,\n label: definition.label,\n description: definition.description,\n packageName: definition.packageName,\n qualifiedClassName: definition.qualifiedClassName,\n className: definition.className,\n localId: definition.localId,\n visibility: definition.visibility,\n metadata: definition.getMetadata(),\n defaultEnabled: definition.defaultEnabled,\n effectiveEnabled,\n globalEffect: globalOverride?.effect ?? null,\n tenantEffect: tenantOverride?.effect ?? null,\n inheritedEnabled: tenantId && !tenantOverride ? effectiveEnabled : null,\n };\n }\n}\n\n/**\n * Reject a scope the resolver would never read back.\n *\n * `FeatureResolver` looks overrides up by the exact `(featureKey, scopeType,\n * scopeId)` triple: the global scope only ever at {@link GLOBAL_FEATURE_SCOPE_ID},\n * and the tenant scope only at ids it gets from the session or the tenant\n * hierarchy. A row written anywhere else is never read, so it is invisible\n * state rather than a setting — and the host authorizer cannot catch it,\n * because `scopeType: 'global'` with someone else's tenant id looks like an\n * ordinary global write to an authorizer that only gates the global scope.\n */\nfunction assertValidFeatureScope(\n scopeType: FeatureScopeType,\n scopeId: string,\n): void {\n if (scopeType !== 'global' && scopeType !== 'tenant') {\n throw new InvalidFeatureScopeError(\n String(scopeType),\n String(scopeId),\n 'scope type must be \"global\" or \"tenant\"',\n );\n }\n if (typeof scopeId !== 'string') {\n throw new InvalidFeatureScopeError(\n scopeType,\n String(scopeId),\n 'scope id must be a string',\n );\n }\n if (scopeType === 'global' && scopeId !== GLOBAL_FEATURE_SCOPE_ID) {\n throw new InvalidFeatureScopeError(\n scopeType,\n scopeId,\n `the global scope is only ever \"${GLOBAL_FEATURE_SCOPE_ID}\"`,\n );\n }\n if (\n scopeType === 'tenant' &&\n (!scopeId.trim() || scopeId !== scopeId.trim())\n ) {\n throw new InvalidFeatureScopeError(\n scopeType,\n scopeId,\n 'a tenant scope id must be non-blank and already trimmed',\n );\n }\n}\n\nfunction compareDefinitions(\n a: FeatureDefinition,\n b: FeatureDefinition,\n): number {\n return (\n a.packageName.localeCompare(b.packageName) ||\n (a.label || a.featureKey).localeCompare(b.label || b.featureKey) ||\n a.featureKey.localeCompare(b.featureKey)\n );\n}\n","import { ObjectRegistry } from '@happyvertical/smrt-core';\nimport type { SmartObjectManifest } from '@happyvertical/smrt-core/manifest';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport type {\n FeatureDefinitionSeed,\n FeatureSyncResult,\n SyncDefinitionsOptions,\n SyncManifestOptions,\n} from './types.js';\nimport {\n extractFeatureSeedsFromManifest,\n extractFeatureSeedsFromRegistryEntry,\n extractTouchedPackagesFromManifest,\n getPackageNameFromRegistry,\n type RegistryEntryLike,\n} from './utils.js';\n\nexport class FeatureSyncService {\n private readonly options: FeatureHostOptions;\n private featureDefinitions!: FeatureDefinitionCollection;\n private initializationPromise: Promise<void> | null = null;\n\n constructor(options: FeatureHostOptions = {}) {\n this.options = options;\n }\n\n async syncDefinitions(\n options: SyncDefinitionsOptions = {},\n ): Promise<FeatureSyncResult> {\n await this.ensureInitialized();\n const registrations = this.collectRegistrations(options);\n const definitions = this.collectDefinitionsFromRegistrations(registrations);\n const touchedPackages =\n this.collectTouchedPackagesFromRegistrations(registrations);\n const isFilteredSync =\n Boolean(options.classNames?.length) ||\n Boolean(options.constructors?.length);\n const pruneStale = isFilteredSync ? false : (options.pruneStale ?? true);\n\n return this.applyDefinitions(definitions, touchedPackages, pruneStale);\n }\n\n async syncManifest(\n manifest: SmartObjectManifest,\n options: SyncManifestOptions = {},\n ): Promise<FeatureSyncResult> {\n await this.ensureInitialized();\n const definitions = extractFeatureSeedsFromManifest(manifest);\n const touchedPackages = extractTouchedPackagesFromManifest(manifest);\n return this.applyDefinitions(\n definitions,\n touchedPackages,\n options.pruneStale ?? true,\n );\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initializationPromise) {\n this.initializationPromise = (async () => {\n // `applyDefinitions()` enumerates the full catalog per touched package\n // to prune stale rows; a host-configured list bound must not make a\n // prune pass see a partial catalog (#3056, same hazard class as #3048).\n this.featureDefinitions = await FeatureDefinitionCollection.create(\n withoutListBounds(this.options),\n );\n })();\n }\n\n await this.initializationPromise;\n }\n\n private collectDefinitionsFromRegistrations(\n registrations: RegistryEntryLike[],\n ): FeatureDefinitionSeed[] {\n const definitions: FeatureDefinitionSeed[] = [];\n\n for (const registration of registrations) {\n definitions.push(...extractFeatureSeedsFromRegistryEntry(registration));\n }\n\n return definitions;\n }\n\n private collectTouchedPackagesFromRegistrations(\n registrations: RegistryEntryLike[],\n ): Set<string> {\n const packages = new Set<string>();\n\n for (const registration of registrations) {\n if (registration.visibility === 'test') {\n continue;\n }\n\n const packageName = getPackageNameFromRegistry(registration);\n if (packageName) {\n packages.add(packageName);\n }\n }\n\n return packages;\n }\n\n private collectRegistrations(\n options: SyncDefinitionsOptions,\n ): RegistryEntryLike[] {\n if (options.classNames?.length) {\n return options.classNames\n .map((name) => ObjectRegistry.getClass(name))\n .filter((value): value is NonNullable<typeof value> => !!value);\n }\n\n if (options.constructors?.length) {\n return options.constructors\n .map((ctor) => ObjectRegistry.getClassByConstructor(ctor))\n .filter((value): value is NonNullable<typeof value> => !!value);\n }\n\n const registrations: RegistryEntryLike[] = [];\n const seen = new Set<RegistryEntryLike>();\n\n for (const registration of ObjectRegistry.getAllClasses().values()) {\n if (seen.has(registration)) {\n continue;\n }\n seen.add(registration);\n registrations.push(registration);\n }\n\n return registrations;\n }\n\n private async applyDefinitions(\n definitions: FeatureDefinitionSeed[],\n touchedPackages: Set<string>,\n pruneStale: boolean,\n ): Promise<FeatureSyncResult> {\n const deduped = new Map<string, FeatureDefinitionSeed>();\n for (const definition of definitions) {\n deduped.set(definition.featureKey, definition);\n }\n\n let created = 0;\n let updated = 0;\n let unchanged = 0;\n let deleted = 0;\n\n const dedupedDefinitions = Array.from(deduped.values());\n const currentKeys = new Set(\n dedupedDefinitions.map((definition) => definition.featureKey),\n );\n const upsertResults = await Promise.all(\n dedupedDefinitions.map((definition) =>\n this.featureDefinitions.upsertDefinition(definition),\n ),\n );\n for (const result of upsertResults) {\n if (result.status === 'created') created++;\n if (result.status === 'updated') updated++;\n if (result.status === 'unchanged') unchanged++;\n }\n\n if (pruneStale) {\n const existingByPackage = await Promise.all(\n Array.from(touchedPackages, (packageName) =>\n this.featureDefinitions.findByPackageName(packageName),\n ),\n );\n\n const staleDefinitions = existingByPackage.flatMap((existing) =>\n existing.filter(\n (definition) => !currentKeys.has(definition.featureKey),\n ),\n );\n\n await Promise.all(\n staleDefinitions.map((definition) => definition.delete()),\n );\n deleted = staleDefinitions.length;\n }\n\n return {\n total: deduped.size,\n created,\n updated,\n unchanged,\n deleted,\n featureKeys: Array.from(currentKeys).sort(),\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/utils.ts","../src/feature-definition.ts","../src/feature-definitions.ts","../src/feature-override.ts","../src/feature-override-service.ts","../src/feature-overrides.ts","../src/list-bounds.ts","../src/feature-resolver.ts","../src/feature-settings.ts","../src/feature-sync.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-features\\\",\\\"packageVersion\\\":\\\"0.55.7\\\",\\\"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\\\",\\\"displayLabelField\\\":\\\"label\\\",\\\"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\\\",\\\"enum\\\":[\\\"global\\\",\\\"tenant\\\"]},\\\"scopeId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"effect\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"enum\\\":[\\\"inherit\\\",\\\"enable\\\",\\\"disable\\\"]}},\\\"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\\\"],\\\"stampsConstructors\\\":true}\"));\n","import {\n createQualifiedName,\n isQualifiedName,\n ObjectRegistry,\n parseQualifiedName,\n type SmartObjectConfig,\n} from '@happyvertical/smrt-core';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '@happyvertical/smrt-core/manifest';\nimport type {\n FeatureDefinitionSeed,\n FeatureMetadata,\n FeatureTargetConstructor,\n} from './types.js';\n\nexport type RegistryEntryLike = {\n name: string;\n qualifiedName?: string;\n packageName?: string;\n config: SmartObjectConfig;\n visibility?: string;\n};\n\nexport function createFeatureKey(\n qualifiedClassName: string,\n localId: string,\n): string {\n if (!isQualifiedName(qualifiedClassName)) {\n throw new Error(\n `Feature keys require a qualified class name. Received \"${qualifiedClassName}\".`,\n );\n }\n\n if (!localId) {\n throw new Error('Feature localId is required.');\n }\n\n if (localId.includes('#')) {\n throw new Error(\n `Feature localId \"${localId}\" cannot contain \"#\". This character is reserved for canonical feature keys.`,\n );\n }\n\n return `${qualifiedClassName}#${localId}`;\n}\n\nexport function parseFeatureKey(featureKey: string): {\n qualifiedClassName: string;\n localId: string;\n} {\n const separatorIndex = featureKey.lastIndexOf('#');\n if (separatorIndex <= 0 || separatorIndex === featureKey.length - 1) {\n throw new Error(\n `Invalid feature key \"${featureKey}\". Expected format \"<qualifiedClassName>#<localId>\".`,\n );\n }\n\n const qualifiedClassName = featureKey.slice(0, separatorIndex);\n const localId = featureKey.slice(separatorIndex + 1);\n\n if (!isQualifiedName(qualifiedClassName)) {\n throw new Error(\n `Invalid feature key \"${featureKey}\". \"${qualifiedClassName}\" is not a qualified class name.`,\n );\n }\n\n return { qualifiedClassName, localId };\n}\n\nexport function serializeFeatureMetadata(\n metadata: FeatureMetadata | string | null | undefined,\n): string {\n if (!metadata) {\n return '';\n }\n\n if (typeof metadata === 'string') {\n const parsed = parseFeatureMetadataString(metadata);\n return JSON.stringify(parsed);\n }\n\n if (!isFeatureMetadataRecord(metadata)) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n );\n }\n\n return JSON.stringify(metadata);\n}\n\nexport function parseFeatureMetadata(\n metadata: string | null | undefined,\n): FeatureMetadata {\n if (!metadata) {\n return {};\n }\n\n try {\n return parseFeatureMetadataString(metadata);\n } catch {\n return {};\n }\n}\n\nfunction parseFeatureMetadataString(metadata: string): FeatureMetadata {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(metadata);\n } catch (error) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n { cause: error },\n );\n }\n\n if (!isFeatureMetadataRecord(parsed)) {\n throw new Error(\n 'Feature metadata must be a plain object or a JSON string representing a plain object.',\n );\n }\n\n return parsed;\n}\n\nfunction isFeatureMetadataRecord(value: unknown): value is FeatureMetadata {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nexport function getQualifiedClassNameFromRegistry(\n registration: RegistryEntryLike,\n): string | null {\n if (\n registration.qualifiedName &&\n isQualifiedName(registration.qualifiedName)\n ) {\n return registration.qualifiedName;\n }\n\n if (registration.packageName) {\n return createQualifiedName(registration.packageName, registration.name);\n }\n\n return null;\n}\n\nexport function getPackageNameFromRegistry(\n registration: RegistryEntryLike,\n): string | null {\n if (registration.packageName) {\n return registration.packageName;\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n return null;\n }\n\n return parseQualifiedName(qualifiedClassName).packageName;\n}\n\nexport function extractFeatureSeedsFromRegistryEntry(\n registration: RegistryEntryLike,\n): FeatureDefinitionSeed[] {\n if (registration.visibility === 'test') {\n return [];\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n return [];\n }\n\n const featureConfig = registration.config.features;\n if (!featureConfig) {\n return [];\n }\n\n const packageName =\n registration.packageName ||\n parseQualifiedName(qualifiedClassName).packageName;\n\n return Object.entries(featureConfig).map(([localId, feature]) => ({\n featureKey: createFeatureKey(qualifiedClassName, localId),\n packageName,\n qualifiedClassName,\n className: registration.name,\n localId,\n defaultEnabled: feature.defaultEnabled,\n label: feature.label,\n description: feature.description,\n metadata: feature.metadata,\n visibility: registration.visibility,\n }));\n}\n\nexport function extractFeatureSeedsFromManifest(\n manifest: SmartObjectManifest,\n): FeatureDefinitionSeed[] {\n const seeds: FeatureDefinitionSeed[] = [];\n\n for (const [objectKey, objectDef] of Object.entries(manifest.objects)) {\n seeds.push(...extractFeatureSeedsFromManifestObject(objectKey, objectDef));\n }\n\n return seeds;\n}\n\nexport function extractTouchedPackagesFromManifest(\n manifest: SmartObjectManifest,\n): Set<string> {\n const packages = new Set<string>();\n\n if (manifest.packageName) {\n packages.add(manifest.packageName);\n }\n\n for (const [objectKey, objectDef] of Object.entries(manifest.objects)) {\n if (objectDef.visibility === 'test') {\n continue;\n }\n\n if (objectDef.packageName) {\n packages.add(objectDef.packageName);\n continue;\n }\n\n const qualifiedClassName = resolveManifestQualifiedClassName(\n objectKey,\n objectDef,\n );\n if (qualifiedClassName) {\n packages.add(parseQualifiedName(qualifiedClassName).packageName);\n }\n }\n\n return packages;\n}\n\nfunction extractFeatureSeedsFromManifestObject(\n objectKey: string,\n objectDef: SmartObjectDefinition,\n): FeatureDefinitionSeed[] {\n if (objectDef.visibility === 'test') {\n return [];\n }\n\n const features = objectDef.decoratorConfig.features;\n if (!features) {\n return [];\n }\n\n const qualifiedClassName = resolveManifestQualifiedClassName(\n objectKey,\n objectDef,\n );\n if (!qualifiedClassName) {\n return [];\n }\n\n const packageName =\n objectDef.packageName || parseQualifiedName(qualifiedClassName).packageName;\n\n return Object.entries(features).map(([localId, feature]) => ({\n featureKey: createFeatureKey(qualifiedClassName, localId),\n packageName,\n qualifiedClassName,\n className: objectDef.className,\n localId,\n defaultEnabled: feature.defaultEnabled,\n label: feature.label,\n description: feature.description,\n metadata:\n feature.metadata && typeof feature.metadata === 'object'\n ? (feature.metadata as FeatureMetadata)\n : undefined,\n visibility: objectDef.visibility,\n }));\n}\n\nfunction resolveManifestQualifiedClassName(\n objectKey: string,\n objectDef: SmartObjectDefinition,\n): string | null {\n if (objectDef.qualifiedName && isQualifiedName(objectDef.qualifiedName)) {\n return objectDef.qualifiedName;\n }\n\n if (isQualifiedName(objectKey)) {\n return objectKey;\n }\n\n if (objectDef.packageName) {\n return createQualifiedName(objectDef.packageName, objectDef.className);\n }\n\n return null;\n}\n\nexport function resolveFeatureKeyForTarget(\n classOrInstance: object | FeatureTargetConstructor,\n localId: string,\n): {\n featureKey: string;\n defaultEnabled: boolean;\n} {\n const ctor: FeatureTargetConstructor =\n typeof classOrInstance === 'function'\n ? (classOrInstance as FeatureTargetConstructor)\n : (classOrInstance.constructor as FeatureTargetConstructor);\n\n const registration = ObjectRegistry.getClassByConstructor(ctor);\n if (!registration) {\n throw new Error(\n `Cannot resolve feature \"${localId}\" because ${ctor?.name || 'the target class'} is not registered with @smrt().`,\n );\n }\n\n const qualifiedClassName = getQualifiedClassNameFromRegistry(registration);\n if (!qualifiedClassName) {\n throw new Error(\n `Cannot resolve feature \"${localId}\" for ${registration.name} because the class has no qualified package identity.`,\n );\n }\n\n const feature = registration.config.features?.[localId];\n if (!feature) {\n throw new Error(\n `Feature \"${localId}\" is not declared on ${qualifiedClassName}.`,\n );\n }\n\n return {\n featureKey: createFeatureKey(qualifiedClassName, localId),\n defaultEnabled: feature.defaultEnabled,\n };\n}\n\nexport function findFeatureDefaultInRegistry(\n featureKey: string,\n): boolean | undefined {\n const { qualifiedClassName, localId } = parseFeatureKey(featureKey);\n const registration =\n ObjectRegistry.getClassByQualifiedName(qualifiedClassName) ||\n ObjectRegistry.getClass(qualifiedClassName);\n\n const feature = registration?.config.features?.[localId];\n return feature?.defaultEnabled;\n}\n","import { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport type { FeatureDefinitionOptions, FeatureMetadata } from './types.js';\nimport { parseFeatureMetadata, serializeFeatureMetadata } from './utils.js';\n\n@smrt({\n tableName: '_smrt_feature_definitions',\n // Closed by default like FeatureOverride (#3013): the catalog is framework\n // state synced from manifests, not a tenant resource.\n api: false,\n cli: false,\n mcp: false,\n conflictColumns: ['feature_key'],\n})\nexport class FeatureDefinition extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-features\";\n featureKey: string = '';\n packageName: string = '';\n qualifiedClassName: string = '';\n className: string = '';\n localId: string = '';\n defaultEnabled: boolean = false;\n label: string = '';\n description: string = '';\n metadata: string = '';\n visibility: string = 'public';\n\n constructor(options: FeatureDefinitionOptions = {}) {\n super(options);\n\n if (options.featureKey !== undefined) this.featureKey = options.featureKey;\n if (options.packageName !== undefined)\n this.packageName = options.packageName;\n if (options.qualifiedClassName !== undefined) {\n this.qualifiedClassName = options.qualifiedClassName;\n }\n if (options.className !== undefined) this.className = options.className;\n if (options.localId !== undefined) this.localId = options.localId;\n if (options.defaultEnabled !== undefined) {\n this.defaultEnabled = options.defaultEnabled;\n }\n if (options.label !== undefined) this.label = options.label;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.visibility !== undefined) this.visibility = options.visibility;\n if (options.metadata !== undefined) {\n this.metadata = serializeFeatureMetadata(options.metadata);\n }\n }\n\n getMetadata(): FeatureMetadata {\n return parseFeatureMetadata(this.metadata);\n }\n\n setMetadata(metadata: FeatureMetadata | null): void {\n this.metadata = serializeFeatureMetadata(metadata);\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { FeatureDefinition } from './feature-definition.js';\nimport type { FeatureDefinitionSeed } from './types.js';\nimport { serializeFeatureMetadata } from './utils.js';\n\nexport class FeatureDefinitionCollection extends SmrtCollection<FeatureDefinition> {\n static readonly _itemClass = FeatureDefinition;\n\n async findByFeatureKey(\n featureKey: string,\n ): Promise<FeatureDefinition | null> {\n const results = await this.list({\n where: { featureKey },\n limit: 1,\n });\n return results[0] ?? null;\n }\n\n async findByPackageName(packageName: string): Promise<FeatureDefinition[]> {\n return this.list({\n where: { packageName },\n });\n }\n\n async upsertDefinition(seed: FeatureDefinitionSeed): Promise<{\n definition: FeatureDefinition;\n status: 'created' | 'updated' | 'unchanged';\n }> {\n const existing = await this.findByFeatureKey(seed.featureKey);\n\n if (!existing) {\n const created = await this.create({\n ...seed,\n metadata: serializeFeatureMetadata(seed.metadata),\n });\n await created.save();\n return { definition: created, status: 'created' };\n }\n\n const nextMetadata = serializeFeatureMetadata(seed.metadata);\n const changed =\n existing.packageName !== seed.packageName ||\n existing.qualifiedClassName !== seed.qualifiedClassName ||\n existing.className !== seed.className ||\n existing.localId !== seed.localId ||\n existing.defaultEnabled !== seed.defaultEnabled ||\n existing.label !== (seed.label ?? '') ||\n existing.description !== (seed.description ?? '') ||\n existing.metadata !== nextMetadata ||\n existing.visibility !== (seed.visibility ?? 'public');\n\n if (!changed) {\n return { definition: existing, status: 'unchanged' };\n }\n\n existing.packageName = seed.packageName;\n existing.qualifiedClassName = seed.qualifiedClassName;\n existing.className = seed.className;\n existing.localId = seed.localId;\n existing.defaultEnabled = seed.defaultEnabled;\n existing.label = seed.label ?? '';\n existing.description = seed.description ?? '';\n existing.metadata = nextMetadata;\n existing.visibility = seed.visibility ?? 'public';\n await existing.save();\n\n return { definition: existing, status: 'updated' };\n }\n}\n","import { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport {\n FeatureOverrideEffect,\n type FeatureOverrideOptions,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\n// Override rows are authorization state: any scope (global, another tenant,\n// another user) can be written, and the object is not tenant-scoped. Generated\n// REST routes and MCP tools only check authentication, so they are closed\n// (#3013). Hosts write overrides server-side through\n// `FeatureOverrideService`, which requires an explicit authorizer for every\n// write (or the collection's `setOverride()` / `removeOverride()` after their\n// own authorization decision). The CLI is closed too: generated CLI commands\n// dispatch through the generated API.\n@smrt({\n tableName: '_smrt_feature_overrides',\n api: false,\n cli: false,\n mcp: false,\n conflictColumns: ['feature_key', 'scope_type', 'scope_id'],\n})\nexport class FeatureOverride extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-features\";\n featureKey: string = '';\n scopeType: FeatureScopeType = 'global';\n scopeId: string = GLOBAL_FEATURE_SCOPE_ID;\n effect: FeatureOverrideEffect = FeatureOverrideEffect.INHERIT;\n\n constructor(options: FeatureOverrideOptions = {}) {\n super(options);\n\n if (options.featureKey !== undefined) this.featureKey = options.featureKey;\n if (options.scopeType !== undefined) this.scopeType = options.scopeType;\n if (options.scopeId !== undefined) this.scopeId = options.scopeId;\n if (options.effect !== undefined) this.effect = options.effect;\n }\n\n isInherit(): boolean {\n return this.effect === FeatureOverrideEffect.INHERIT;\n }\n\n isEnabled(): boolean {\n return this.effect === FeatureOverrideEffect.ENABLE;\n }\n\n isDisabled(): boolean {\n return this.effect === FeatureOverrideEffect.DISABLE;\n }\n}\n","import type { FeatureOverride } from './feature-override.js';\nimport type { FeatureOverrideCollection } from './feature-overrides.js';\nimport type { FeatureOverrideEffect, FeatureScopeType } from './types.js';\n\n/** One override write the host must authorize before it runs (#3013). */\nexport interface FeatureOverrideWriteRequest {\n operation: 'set' | 'remove';\n featureKey: string;\n scopeType: FeatureScopeType;\n scopeId: string;\n /** Present for `set`. */\n effect?: FeatureOverrideEffect;\n}\n\n/**\n * The host's explicit authorization decision for one override write. Return\n * `true` only when the current caller may write that exact scope; anything\n * else denies.\n */\nexport type FeatureOverrideAuthorizer = (\n request: FeatureOverrideWriteRequest,\n) => boolean | Promise<boolean>;\n\n/** Thrown when the authorizer does not return `true`. Nothing is written. */\nexport class FeatureOverrideAuthorizationError extends Error {\n readonly status = 403;\n constructor(readonly request: FeatureOverrideWriteRequest) {\n super(\n `Feature override ${request.operation} denied for ${request.scopeType} scope`,\n );\n this.name = 'FeatureOverrideAuthorizationError';\n }\n}\n\n/**\n * Authorized write path for feature overrides (#3013). Override rows are\n * authorization state for every scope and `FeatureOverride` is not\n * tenant-scoped, so generated surfaces are closed. Hosts that let callers\n * change flags construct this service with an authorizer bound to the\n * current caller and write through it; every write asks the authorizer\n * first and fails closed.\n */\nexport class FeatureOverrideService {\n constructor(\n private readonly overrides: FeatureOverrideCollection,\n private readonly authorize: FeatureOverrideAuthorizer,\n ) {}\n\n async setOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n await this.require({\n operation: 'set',\n featureKey,\n scopeType,\n scopeId,\n effect,\n });\n return this.overrides.setOverride(featureKey, scopeType, scopeId, effect);\n }\n\n async removeOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<boolean> {\n await this.require({ operation: 'remove', featureKey, scopeType, scopeId });\n return this.overrides.removeOverride(featureKey, scopeType, scopeId);\n }\n\n private async require(request: FeatureOverrideWriteRequest): Promise<void> {\n let allowed = false;\n try {\n allowed = (await this.authorize(request)) === true;\n } catch {\n allowed = false;\n }\n if (!allowed) throw new FeatureOverrideAuthorizationError(request);\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { FeatureOverride } from './feature-override.js';\nimport {\n type FeatureOverrideEffect,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\nexport class FeatureOverrideCollection extends SmrtCollection<FeatureOverride> {\n static readonly _itemClass = FeatureOverride;\n\n async findByFeatureKey(featureKey: string): Promise<FeatureOverride[]> {\n return this.list({\n where: { featureKey },\n });\n }\n\n async findByFeatureAndScope(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<FeatureOverride | null> {\n const results = await this.list({\n where: { featureKey, scopeType, scopeId },\n limit: 1,\n });\n return results[0] ?? null;\n }\n\n async getGlobalOverride(featureKey: string): Promise<FeatureOverride | null> {\n return this.findByFeatureAndScope(\n featureKey,\n 'global',\n GLOBAL_FEATURE_SCOPE_ID,\n );\n }\n\n async getTenantOverride(\n featureKey: string,\n tenantId: string,\n ): Promise<FeatureOverride | null> {\n return this.findByFeatureAndScope(featureKey, 'tenant', tenantId);\n }\n\n async getOverrideMap(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeIds: string[],\n ): Promise<Map<string, FeatureOverride>> {\n const result = new Map<string, FeatureOverride>();\n if (scopeIds.length === 0) {\n return result;\n }\n\n const overrides = await this.list({\n where: { featureKey, scopeType, scopeId: scopeIds },\n });\n\n for (const override of overrides) {\n result.set(override.scopeId, override);\n }\n\n return result;\n }\n\n async setOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n const existing = await this.findByFeatureAndScope(\n featureKey,\n scopeType,\n scopeId,\n );\n\n if (existing) {\n existing.effect = effect;\n await existing.save();\n return existing;\n }\n\n const created = await this.create({\n featureKey,\n scopeType,\n scopeId,\n effect,\n });\n await created.save();\n return created;\n }\n\n async setGlobalOverride(\n featureKey: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n return this.setOverride(\n featureKey,\n 'global',\n GLOBAL_FEATURE_SCOPE_ID,\n effect,\n );\n }\n\n async setTenantOverride(\n featureKey: string,\n tenantId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride> {\n return this.setOverride(featureKey, 'tenant', tenantId, effect);\n }\n\n async removeOverride(\n featureKey: string,\n scopeType: FeatureScopeType,\n scopeId: string,\n ): Promise<boolean> {\n const existing = await this.findByFeatureAndScope(\n featureKey,\n scopeType,\n scopeId,\n );\n\n if (!existing) {\n return false;\n }\n\n await existing.delete();\n return true;\n }\n}\n","/** Collection options for framework-internal, correctness-critical reads. @packageDocumentation */\nimport type {\n SmrtClassOptions,\n SmrtCollectionOptions,\n} from '@happyvertical/smrt-core';\n\n/** Host options this package accepts before stripping internal list bounds. */\nexport type FeatureHostOptions = SmrtClassOptions &\n Pick<SmrtCollectionOptions, 'defaultListLimit' | 'maxListLimit'>;\n\n/**\n * The caller's options with its list bounds removed.\n *\n * `SmrtCollection.create()` forwards `defaultListLimit`/`maxListLimit` from\n * any options bag it is handed (#2367), so a host that configures those\n * application-wide — a perfectly ordinary thing to do — would silently cap\n * every internal enumeration this package runs. Two of those are\n * correctness-critical and neither is a user-facing page of results\n * (`FeatureDefinition`/`FeatureOverride` expose no generated list surface,\n * #3013): a dropped ancestor override changes the flag's *resolved value*\n * (`FeatureResolver.isEnabled()`), and a dropped definition makes a feature\n * invisible to a management screen or a sync prune pass (#3056, same hazard\n * class as #3048). The collections built here are therefore always created\n * from this bag. Only the list bounds are stripped; the database, tenancy\n * context, and every other option still apply.\n *\n * This is a local copy of `@happyvertical/smrt-users`'\n * `authorization-read-options.ts#withoutListBounds` (added for #3048/#3051).\n * `smrt-features` deliberately never imports `smrt-users` (see package\n * AGENTS.md), and no shared `smrt-core` helper exists for this yet, so the\n * two-line implementation is duplicated here rather than adding a\n * cross-package dependency for it.\n */\nexport function withoutListBounds(\n options: SmrtClassOptions | SmrtCollectionOptions,\n): SmrtCollectionOptions {\n return { ...options, defaultListLimit: undefined, maxListLimit: undefined };\n}\n","import type { SmrtClassOptions } from '@happyvertical/smrt-core';\nimport { importWorkspaceModule } from '@happyvertical/smrt-core/utils/import-workspace-module';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport { FeatureOverrideCollection } from './feature-overrides.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport {\n FeatureOverrideEffect,\n type FeatureResolutionContext,\n type FeatureResolverOptions,\n type FeatureTargetConstructor,\n type FeatureTenantHierarchyProvider,\n type FeatureTenantNode,\n type FeatureUsersModule,\n} from './types.js';\nimport {\n findFeatureDefaultInRegistry,\n resolveFeatureKeyForTarget,\n} from './utils.js';\n\nexport class FeatureResolver {\n private readonly options: FeatureHostOptions;\n private readonly resolverOptions: FeatureResolverOptions;\n private featureDefinitions!: FeatureDefinitionCollection;\n private featureOverrides!: FeatureOverrideCollection;\n private initializationPromise: Promise<void> | null = null;\n private tenantHierarchyPromise: Promise<FeatureTenantHierarchyProvider | null> | null =\n null;\n\n constructor(\n options: FeatureHostOptions = {},\n resolverOptions: FeatureResolverOptions = {},\n ) {\n this.options = options;\n this.resolverOptions = resolverOptions;\n }\n\n async isEnabled(\n featureKey: string,\n context: FeatureResolutionContext = {},\n ): Promise<boolean> {\n await this.ensureInitialized();\n\n const baseState = await this.resolveBaseState(featureKey);\n const globalOverride =\n await this.featureOverrides.getGlobalOverride(featureKey);\n const globalState = this.applyOverride(baseState, globalOverride?.effect);\n\n if (!context.tenantId) {\n return globalState;\n }\n\n const tenantHierarchy = await this.getTenantHierarchy();\n if (!tenantHierarchy) {\n const directOverride = await this.featureOverrides.getTenantOverride(\n featureKey,\n context.tenantId,\n );\n return this.applyOverride(globalState, directOverride?.effect);\n }\n\n const chain = await tenantHierarchy.getChain(context.tenantId);\n if (chain.length === 0) {\n const directOverride = await this.featureOverrides.getTenantOverride(\n featureKey,\n context.tenantId,\n );\n return this.applyOverride(globalState, directOverride?.effect);\n }\n\n const overrides = await this.featureOverrides.getOverrideMap(\n featureKey,\n 'tenant',\n chain.map((node) => node.id),\n );\n\n let inheritedState = globalState;\n\n for (let index = 0; index < chain.length; index++) {\n const current = chain[index];\n const previous = index > 0 ? chain[index - 1] : null;\n const shouldInherit =\n index === 0 ||\n (!!previous?.cascadePermissions && current.inheritPermissions);\n\n const baseline = shouldInherit ? inheritedState : globalState;\n const override = overrides.get(current.id);\n inheritedState = this.applyOverride(baseline, override?.effect);\n }\n\n return inheritedState;\n }\n\n async isEnabledFor(\n classOrInstance: object | FeatureTargetConstructor,\n localId: string,\n context: FeatureResolutionContext = {},\n ): Promise<boolean> {\n const { featureKey } = resolveFeatureKeyForTarget(classOrInstance, localId);\n return this.isEnabled(featureKey, context);\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initializationPromise) {\n this.initializationPromise = (async () => {\n // A host-configured `defaultListLimit`/`maxListLimit` must never reach\n // these reads: `getOverrideMap()` walks the tenant ancestor chain, and\n // a dropped ancestor override would change the flag's resolved value\n // silently (#3056, same hazard class as #3048).\n const options = withoutListBounds(this.options);\n this.featureDefinitions =\n await FeatureDefinitionCollection.create(options);\n this.featureOverrides = await FeatureOverrideCollection.create(options);\n })();\n }\n\n await this.initializationPromise;\n }\n\n private async resolveBaseState(featureKey: string): Promise<boolean> {\n const registryDefault = findFeatureDefaultInRegistry(featureKey);\n if (registryDefault !== undefined) {\n return registryDefault;\n }\n\n const definition =\n await this.featureDefinitions.findByFeatureKey(featureKey);\n if (!definition) {\n throw new Error(\n `Feature \"${featureKey}\" is not declared in the registry or synced feature definitions.`,\n );\n }\n\n return definition.defaultEnabled;\n }\n\n private applyOverride(\n currentState: boolean,\n effect: FeatureOverrideEffect | undefined,\n ): boolean {\n switch (effect) {\n case FeatureOverrideEffect.ENABLE:\n return true;\n case FeatureOverrideEffect.DISABLE:\n return false;\n default:\n return currentState;\n }\n }\n\n private async getTenantHierarchy(): Promise<FeatureTenantHierarchyProvider | null> {\n if (!this.tenantHierarchyPromise) {\n const loader =\n this.resolverOptions.tenantHierarchyLoader ||\n defaultTenantHierarchyLoader;\n this.tenantHierarchyPromise = loader(this.options);\n }\n\n return this.tenantHierarchyPromise;\n }\n}\n\nasync function defaultTenantHierarchyLoader(\n options: SmrtClassOptions,\n): Promise<FeatureTenantHierarchyProvider | null> {\n try {\n const usersModule = await importWorkspaceModule<FeatureUsersModule>({\n packageName: '@happyvertical/smrt-users',\n sourceEntry: 'packages/users/src/collections/index.ts',\n purpose: 'tenant-aware feature flag resolution',\n });\n\n const tenantCollection = await usersModule.TenantCollection.create(options);\n return {\n async getChain(tenantId: string): Promise<FeatureTenantNode[]> {\n const tenant = await tenantCollection.get({ id: tenantId });\n if (!tenant) {\n return [];\n }\n\n const ancestors = await tenantCollection.getAncestorsFromRoot(tenantId);\n return [...ancestors, tenant].map((node) => ({\n id: String(node.id),\n inheritPermissions: Boolean(node.inheritPermissions),\n cascadePermissions: Boolean(node.cascadePermissions),\n }));\n },\n };\n } catch (error) {\n if (isMissingUsersDependency(error)) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isMissingUsersDependency(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const causeMessage =\n error.cause instanceof Error ? ` ${error.cause.message}` : '';\n const text = `${error.message}${causeMessage}`;\n\n return (\n text.includes('@happyvertical/smrt-users') &&\n (text.includes('Cannot find module') ||\n text.includes('Failed to load') ||\n text.includes('could not find'))\n );\n}\n","import type { FeatureDefinition } from './feature-definition.js';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport type { FeatureOverride } from './feature-override.js';\nimport {\n type FeatureOverrideAuthorizer,\n FeatureOverrideService,\n} from './feature-override-service.js';\nimport { FeatureOverrideCollection } from './feature-overrides.js';\nimport { FeatureResolver } from './feature-resolver.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport {\n type FeatureMetadata,\n FeatureOverrideEffect,\n type FeatureResolverOptions,\n type FeatureScopeType,\n GLOBAL_FEATURE_SCOPE_ID,\n} from './types.js';\n\n/**\n * One feature, rendered for a management screen: the code-owned definition,\n * the value that is actually in effect for the requested tenant, and the raw\n * override row at each scope level so the UI can show *why* it is in effect.\n *\n * Structurally assignable to the presentational `FeatureSettingsView` consumed\n * by `@happyvertical/smrt-features/svelte`, so a server load can hand its rows\n * straight to `FeatureSettingsPanel` without a mapping step.\n */\nexport interface FeatureSettingsRow {\n /**\n * The persisted identifier. Renaming it orphans every existing override —\n * see the warning on {@link FeatureSettingsService}.\n */\n featureKey: string;\n /** Human label from the definition; may be empty. */\n label: string;\n /** Human description from the definition; may be empty. */\n description: string;\n /** Owning package, as synced from the manifest. */\n packageName: string;\n /** Qualified `package:Class` name of the feature's target. */\n qualifiedClassName: string;\n /** Unqualified class name of the feature's target. */\n className: string;\n /** Class-local feature id. */\n localId: string;\n /** Definition visibility marker (`public` unless the seed says otherwise). */\n visibility: string;\n /** Parsed definition metadata. */\n metadata: FeatureMetadata;\n /** The code-owned default, used when no override applies. */\n defaultEnabled: boolean;\n /**\n * What {@link FeatureResolver} resolves for the requested context — the\n * value the application actually behaves by.\n */\n effectiveEnabled: boolean;\n /** Effect of the global override row, or `null` when there is none. */\n globalEffect: FeatureOverrideEffect | null;\n /**\n * Effect of the override row for the requested tenant, or `null` when there\n * is none (or when no `tenantId` was requested).\n */\n tenantEffect: FeatureOverrideEffect | null;\n /**\n * What this feature resolves to for the requested tenant with **no override\n * of its own** — the state that removing the tenant override would produce,\n * which is what a management UI must name on its \"back to Default\" control.\n *\n * `null` when no `tenantId` was requested — nothing tenant-inherited was\n * computed, and the global state is not an answer to a question about a\n * tenant — and `null` when the tenant holds an override of its own, because\n * then the inherited state depends on the levels above this tenant, which a\n * configured `FeatureTenantHierarchyProvider` extends to ancestor tenants'\n * overrides. It is reported only for a requested tenant with no override of\n * its own, where the inherited state *is* the effective state. Rows that\n * leave it `null` get the neutral \"Default (inherited)\" label in the panel,\n * never a claim about a state nothing computed.\n */\n inheritedEnabled: boolean | null;\n}\n\n/** Selection for {@link FeatureSettingsService.listFeatureSettings}. */\nexport interface ListFeatureSettingsOptions {\n /**\n * Tenant whose overrides and effective values to report. Omit for a\n * global-only view.\n */\n tenantId?: string;\n /** Restrict to one owning package (the usual case for an app's own screen). */\n packageName?: string;\n /**\n * Restrict to an explicit allowlist of keys. Keys with no definition are\n * simply absent from the result — this filters, it does not validate.\n */\n featureKeys?: string[];\n}\n\n/** One override write requested through {@link FeatureSettingsService}. */\nexport interface SetFeatureOverrideRequest {\n featureKey: string;\n scopeType: FeatureScopeType;\n scopeId: string;\n /**\n * `INHERIT` removes the override row at that scope, returning the feature to\n * whatever the next level up resolves to.\n */\n effect: FeatureOverrideEffect;\n}\n\n/**\n * Thrown when a write names a `featureKey` that has no {@link FeatureDefinition}\n * row. Nothing is written.\n *\n * This is the generalized form of the per-app \"is this one of my keys?\" guard\n * every consumer would otherwise hand-roll to keep a form post from creating an\n * override for an arbitrary string.\n */\nexport class UnknownFeatureKeyError extends Error {\n readonly status = 400;\n constructor(readonly featureKey: string) {\n super(`Unknown feature key: ${featureKey}`);\n this.name = 'UnknownFeatureKeyError';\n }\n}\n\n/**\n * Thrown when a write names a scope the resolver would never read back: an\n * unknown `scopeType`, a global write under anything but\n * {@link GLOBAL_FEATURE_SCOPE_ID}, or a tenant write with a blank or untrimmed\n * `scopeId`. Nothing is written.\n *\n * `FeatureOverride` rows are looked up by the exact `(featureKey, scopeType,\n * scopeId)` triple, so a row stored under a scope nothing queries is invisible\n * state: it never takes effect, and it silently reappears if the scope naming\n * is ever corrected.\n */\nexport class InvalidFeatureScopeError extends Error {\n readonly status = 400;\n constructor(\n readonly scopeType: string,\n readonly scopeId: string,\n reason: string,\n ) {\n super(`Invalid feature override scope (${scopeType}): ${reason}`);\n this.name = 'InvalidFeatureScopeError';\n }\n}\n\n/** Options for {@link FeatureSettingsService.create}. */\nexport interface FeatureSettingsServiceOptions {\n /**\n * The host's authorization decision for each override write, bound to the\n * current caller. **Omitting it makes the service read-only**: every write\n * then fails closed with `FeatureOverrideAuthorizationError`. This\n * package never decides who may write.\n */\n authorize?: FeatureOverrideAuthorizer;\n /** Forwarded to {@link FeatureResolver} (e.g. the tenant-hierarchy loader). */\n resolver?: FeatureResolverOptions;\n}\n\nconst KNOWN_EFFECTS = new Set<string>(Object.values(FeatureOverrideEffect));\n\n/**\n * Coerce an untrusted value (a form field, a query parameter, a JSON body) to a\n * {@link FeatureOverrideEffect}. Anything unrecognized — including `null` and\n * `undefined` — becomes `INHERIT`, i.e. \"back to the default\", which is the\n * safe reading of a value the host could not parse.\n */\nexport function featureOverrideEffectFromValue(\n value: unknown,\n): FeatureOverrideEffect {\n if (value === FeatureOverrideEffect.ENABLE)\n return FeatureOverrideEffect.ENABLE;\n if (value === FeatureOverrideEffect.DISABLE)\n return FeatureOverrideEffect.DISABLE;\n return FeatureOverrideEffect.INHERIT;\n}\n\n/**\n * Read and write side of a feature-flag management screen, so consumers do not\n * re-derive the row shape or the unknown-key guard.\n *\n * **Authorization stays with the consumer.** This service makes no\n * authorization decision of its own: reads are unfiltered, and every write is\n * delegated to {@link FeatureOverrideService}, which asks the host-supplied\n * {@link FeatureOverrideAuthorizer} first and fails closed. Call it only from\n * server code that has already established who the caller is. See\n * `packages/features/README.md` for the consumer recipe.\n *\n * **Feature keys are persisted identifiers.** Overrides are stored keyed by the\n * exact `featureKey` string and resolved by that string at runtime. Renaming a\n * key orphans every existing override, silently reverting all tenants to the\n * definition default. Treat a key as immutable once shipped; a rename needs a\n * data migration, not an edit.\n */\nexport class FeatureSettingsService {\n private readonly writes: FeatureOverrideService;\n\n constructor(\n private readonly definitions: FeatureDefinitionCollection,\n private readonly overrides: FeatureOverrideCollection,\n private readonly resolver: FeatureResolver,\n authorize?: FeatureOverrideAuthorizer,\n ) {\n this.writes = new FeatureOverrideService(\n overrides,\n authorize ?? (() => false),\n );\n }\n\n /**\n * Build a service over the given database options.\n *\n * @param options - SMRT database options, as passed to any collection.\n * @param serviceOptions - Host authorizer and resolver wiring. Omit\n * `authorize` for a read-only (load-function) service.\n */\n static async create(\n options: FeatureHostOptions = {},\n serviceOptions: FeatureSettingsServiceOptions = {},\n ): Promise<FeatureSettingsService> {\n // The catalog enumeration (`loadDefinitions()`) and every override read\n // this service does are internal, correctness-critical reads — not a\n // user-facing page of results — so a host-configured `defaultListLimit`/\n // `maxListLimit` must never truncate them (#3056, same hazard class as\n // #3048).\n const boundedOptions = withoutListBounds(options);\n const [definitions, overrides] = await Promise.all([\n FeatureDefinitionCollection.create(boundedOptions),\n FeatureOverrideCollection.create(boundedOptions),\n ]);\n return new FeatureSettingsService(\n definitions as FeatureDefinitionCollection,\n overrides as FeatureOverrideCollection,\n new FeatureResolver(options, serviceOptions.resolver ?? {}),\n serviceOptions.authorize,\n );\n }\n\n /**\n * One {@link FeatureSettingsRow} per matching definition, ordered by owning\n * package, then label, then key, so a rendered list is stable across loads.\n *\n * Makes no authorization decision — the caller has already decided that this\n * principal may see this tenant's flags.\n */\n async listFeatureSettings(\n options: ListFeatureSettingsOptions = {},\n ): Promise<FeatureSettingsRow[]> {\n const definitions = await this.loadDefinitions(options);\n\n return Promise.all(\n definitions.map((definition) => this.toRow(definition, options.tenantId)),\n );\n }\n\n /** The single row for one key, or `null` when no definition owns that key. */\n async getFeatureSetting(\n featureKey: string,\n tenantId?: string,\n ): Promise<FeatureSettingsRow | null> {\n const definition = await this.definitions.findByFeatureKey(featureKey);\n return definition ? this.toRow(definition, tenantId) : null;\n }\n\n /**\n * Apply one override change.\n *\n * Refuses any `featureKey` without a {@link FeatureDefinition} row and any\n * scope the resolver would never read back, then delegates to\n * {@link FeatureOverrideService} so the host authorizer decides whether this\n * caller may write this scope. `INHERIT` removes the row.\n *\n * @returns the stored override, or `null` when the row was removed (or was\n * already absent).\n * @throws {UnknownFeatureKeyError} when the key has no definition.\n * @throws {InvalidFeatureScopeError} when the scope is not one the resolver reads.\n * @throws `FeatureOverrideAuthorizationError` when the authorizer declines.\n */\n async setFeatureOverride(\n request: SetFeatureOverrideRequest,\n ): Promise<FeatureOverride | null> {\n const { featureKey, scopeType, scopeId, effect } = request;\n\n if (!KNOWN_EFFECTS.has(effect)) {\n throw new TypeError(`Unknown feature override effect: ${String(effect)}`);\n }\n assertValidFeatureScope(scopeType, scopeId);\n await this.assertKnownFeatureKey(featureKey);\n\n if (effect === FeatureOverrideEffect.INHERIT) {\n await this.writes.removeOverride(featureKey, scopeType, scopeId);\n return null;\n }\n\n return this.writes.setOverride(featureKey, scopeType, scopeId, effect);\n }\n\n /** {@link setFeatureOverride} for the global scope. */\n async setGlobalFeatureOverride(\n featureKey: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride | null> {\n return this.setFeatureOverride({\n featureKey,\n scopeType: 'global',\n scopeId: GLOBAL_FEATURE_SCOPE_ID,\n effect,\n });\n }\n\n /** {@link setFeatureOverride} for one tenant. */\n async setTenantFeatureOverride(\n featureKey: string,\n tenantId: string,\n effect: FeatureOverrideEffect,\n ): Promise<FeatureOverride | null> {\n return this.setFeatureOverride({\n featureKey,\n scopeType: 'tenant',\n scopeId: tenantId,\n effect,\n });\n }\n\n private async assertKnownFeatureKey(featureKey: string): Promise<void> {\n const key = typeof featureKey === 'string' ? featureKey.trim() : '';\n if (!key || key !== featureKey) {\n throw new UnknownFeatureKeyError(String(featureKey));\n }\n const definition = await this.definitions.findByFeatureKey(key);\n if (!definition) {\n throw new UnknownFeatureKeyError(key);\n }\n }\n\n private async loadDefinitions(\n options: ListFeatureSettingsOptions,\n ): Promise<FeatureDefinition[]> {\n const definitions = options.packageName\n ? await this.definitions.findByPackageName(options.packageName)\n : await this.definitions.list({});\n\n const allowed = options.featureKeys ? new Set(options.featureKeys) : null;\n const selected = allowed\n ? definitions.filter((definition) => allowed.has(definition.featureKey))\n : definitions;\n\n return [...selected].sort(compareDefinitions);\n }\n\n private async toRow(\n definition: FeatureDefinition,\n tenantId?: string,\n ): Promise<FeatureSettingsRow> {\n const { featureKey } = definition;\n const [globalOverride, tenantOverride, effectiveEnabled] =\n await Promise.all([\n this.overrides.getGlobalOverride(featureKey),\n tenantId\n ? this.overrides.getTenantOverride(featureKey, tenantId)\n : Promise.resolve(null),\n this.resolver.isEnabled(featureKey, tenantId ? { tenantId } : {}),\n ]);\n\n return {\n featureKey,\n label: definition.label,\n description: definition.description,\n packageName: definition.packageName,\n qualifiedClassName: definition.qualifiedClassName,\n className: definition.className,\n localId: definition.localId,\n visibility: definition.visibility,\n metadata: definition.getMetadata(),\n defaultEnabled: definition.defaultEnabled,\n effectiveEnabled,\n globalEffect: globalOverride?.effect ?? null,\n tenantEffect: tenantOverride?.effect ?? null,\n inheritedEnabled: tenantId && !tenantOverride ? effectiveEnabled : null,\n };\n }\n}\n\n/**\n * Reject a scope the resolver would never read back.\n *\n * `FeatureResolver` looks overrides up by the exact `(featureKey, scopeType,\n * scopeId)` triple: the global scope only ever at {@link GLOBAL_FEATURE_SCOPE_ID},\n * and the tenant scope only at ids it gets from the session or the tenant\n * hierarchy. A row written anywhere else is never read, so it is invisible\n * state rather than a setting — and the host authorizer cannot catch it,\n * because `scopeType: 'global'` with someone else's tenant id looks like an\n * ordinary global write to an authorizer that only gates the global scope.\n */\nfunction assertValidFeatureScope(\n scopeType: FeatureScopeType,\n scopeId: string,\n): void {\n if (scopeType !== 'global' && scopeType !== 'tenant') {\n throw new InvalidFeatureScopeError(\n String(scopeType),\n String(scopeId),\n 'scope type must be \"global\" or \"tenant\"',\n );\n }\n if (typeof scopeId !== 'string') {\n throw new InvalidFeatureScopeError(\n scopeType,\n String(scopeId),\n 'scope id must be a string',\n );\n }\n if (scopeType === 'global' && scopeId !== GLOBAL_FEATURE_SCOPE_ID) {\n throw new InvalidFeatureScopeError(\n scopeType,\n scopeId,\n `the global scope is only ever \"${GLOBAL_FEATURE_SCOPE_ID}\"`,\n );\n }\n if (\n scopeType === 'tenant' &&\n (!scopeId.trim() || scopeId !== scopeId.trim())\n ) {\n throw new InvalidFeatureScopeError(\n scopeType,\n scopeId,\n 'a tenant scope id must be non-blank and already trimmed',\n );\n }\n}\n\nfunction compareDefinitions(\n a: FeatureDefinition,\n b: FeatureDefinition,\n): number {\n return (\n a.packageName.localeCompare(b.packageName) ||\n (a.label || a.featureKey).localeCompare(b.label || b.featureKey) ||\n a.featureKey.localeCompare(b.featureKey)\n );\n}\n","import { ObjectRegistry } from '@happyvertical/smrt-core';\nimport type { SmartObjectManifest } from '@happyvertical/smrt-core/manifest';\nimport { FeatureDefinitionCollection } from './feature-definitions.js';\nimport { type FeatureHostOptions, withoutListBounds } from './list-bounds.js';\nimport type {\n FeatureDefinitionSeed,\n FeatureSyncResult,\n SyncDefinitionsOptions,\n SyncManifestOptions,\n} from './types.js';\nimport {\n extractFeatureSeedsFromManifest,\n extractFeatureSeedsFromRegistryEntry,\n extractTouchedPackagesFromManifest,\n getPackageNameFromRegistry,\n type RegistryEntryLike,\n} from './utils.js';\n\nexport class FeatureSyncService {\n private readonly options: FeatureHostOptions;\n private featureDefinitions!: FeatureDefinitionCollection;\n private initializationPromise: Promise<void> | null = null;\n\n constructor(options: FeatureHostOptions = {}) {\n this.options = options;\n }\n\n async syncDefinitions(\n options: SyncDefinitionsOptions = {},\n ): Promise<FeatureSyncResult> {\n await this.ensureInitialized();\n const registrations = this.collectRegistrations(options);\n const definitions = this.collectDefinitionsFromRegistrations(registrations);\n const touchedPackages =\n this.collectTouchedPackagesFromRegistrations(registrations);\n const isFilteredSync =\n Boolean(options.classNames?.length) ||\n Boolean(options.constructors?.length);\n const pruneStale = isFilteredSync ? false : (options.pruneStale ?? true);\n\n return this.applyDefinitions(definitions, touchedPackages, pruneStale);\n }\n\n async syncManifest(\n manifest: SmartObjectManifest,\n options: SyncManifestOptions = {},\n ): Promise<FeatureSyncResult> {\n await this.ensureInitialized();\n const definitions = extractFeatureSeedsFromManifest(manifest);\n const touchedPackages = extractTouchedPackagesFromManifest(manifest);\n return this.applyDefinitions(\n definitions,\n touchedPackages,\n options.pruneStale ?? true,\n );\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initializationPromise) {\n this.initializationPromise = (async () => {\n // `applyDefinitions()` enumerates the full catalog per touched package\n // to prune stale rows; a host-configured list bound must not make a\n // prune pass see a partial catalog (#3056, same hazard class as #3048).\n this.featureDefinitions = await FeatureDefinitionCollection.create(\n withoutListBounds(this.options),\n );\n })();\n }\n\n await this.initializationPromise;\n }\n\n private collectDefinitionsFromRegistrations(\n registrations: RegistryEntryLike[],\n ): FeatureDefinitionSeed[] {\n const definitions: FeatureDefinitionSeed[] = [];\n\n for (const registration of registrations) {\n definitions.push(...extractFeatureSeedsFromRegistryEntry(registration));\n }\n\n return definitions;\n }\n\n private collectTouchedPackagesFromRegistrations(\n registrations: RegistryEntryLike[],\n ): Set<string> {\n const packages = new Set<string>();\n\n for (const registration of registrations) {\n if (registration.visibility === 'test') {\n continue;\n }\n\n const packageName = getPackageNameFromRegistry(registration);\n if (packageName) {\n packages.add(packageName);\n }\n }\n\n return packages;\n }\n\n private collectRegistrations(\n options: SyncDefinitionsOptions,\n ): RegistryEntryLike[] {\n if (options.classNames?.length) {\n return options.classNames\n .map((name) => ObjectRegistry.getClass(name))\n .filter((value): value is NonNullable<typeof value> => !!value);\n }\n\n if (options.constructors?.length) {\n return options.constructors\n .map((ctor) => ObjectRegistry.getClassByConstructor(ctor))\n .filter((value): value is NonNullable<typeof value> => !!value);\n }\n\n const registrations: RegistryEntryLike[] = [];\n const seen = new Set<RegistryEntryLike>();\n\n for (const registration of ObjectRegistry.getAllClasses().values()) {\n if (seen.has(registration)) {\n continue;\n }\n seen.add(registration);\n registrations.push(registration);\n }\n\n return registrations;\n }\n\n private async applyDefinitions(\n definitions: FeatureDefinitionSeed[],\n touchedPackages: Set<string>,\n pruneStale: boolean,\n ): Promise<FeatureSyncResult> {\n const deduped = new Map<string, FeatureDefinitionSeed>();\n for (const definition of definitions) {\n deduped.set(definition.featureKey, definition);\n }\n\n let created = 0;\n let updated = 0;\n let unchanged = 0;\n let deleted = 0;\n\n const dedupedDefinitions = Array.from(deduped.values());\n const currentKeys = new Set(\n dedupedDefinitions.map((definition) => definition.featureKey),\n );\n const upsertResults = await Promise.all(\n dedupedDefinitions.map((definition) =>\n this.featureDefinitions.upsertDefinition(definition),\n ),\n );\n for (const result of upsertResults) {\n if (result.status === 'created') created++;\n if (result.status === 'updated') updated++;\n if (result.status === 'unchanged') unchanged++;\n }\n\n if (pruneStale) {\n const existingByPackage = await Promise.all(\n Array.from(touchedPackages, (packageName) =>\n this.featureDefinitions.findByPackageName(packageName),\n ),\n );\n\n const staleDefinitions = existingByPackage.flatMap((existing) =>\n existing.filter(\n (definition) => !currentKeys.has(definition.featureKey),\n ),\n );\n\n await Promise.all(\n staleDefinitions.map((definition) => definition.delete()),\n );\n deleted = staleDefinitions.length;\n }\n\n return {\n total: deduped.size,\n created,\n updated,\n unchanged,\n deleted,\n featureKeys: Array.from(currentKeys).sort(),\n };\n }\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-features",
5
- "packageVersion": "0.55.5",
5
+ "packageVersion": "0.55.7",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-features:FeatureDefinition": {
8
8
  "name": "featuredefinition",
@@ -3,12 +3,12 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-features",
6
- "packageVersion": "0.55.5",
6
+ "packageVersion": "0.55.7",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "0d93002d396f9ad2ce3a4a4f7b6b08b250be72c2fc7ede438eecce2a6dfd7454",
11
- "packageJson": "08f766b244272f094dc9a58b16bbdf1279747b31b32a09936ac5d8b45d49ef46",
10
+ "manifest": "0bc1b1cb8366b9700eec50167c821229f2dd2686d2a529a01ea80befd4d8748d",
11
+ "packageJson": "3b3ac82d04ee40b8aae22fe4c8a2de27310629d186cf510764c5d8d595fd3024",
12
12
  "agents": "9e350e9338ed878227fa9152a33d0fe8a804c6567e51876f6ba3bd56967a4deb"
13
13
  },
14
14
  "exports": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-features",
3
- "version": "0.55.5",
3
+ "version": "0.55.7",
4
4
  "description": "Code-first feature flags and tenant-aware overrides for the SMRT framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,13 +24,13 @@
24
24
  "./manifest.json": "./dist/manifest.json"
25
25
  },
26
26
  "dependencies": {
27
- "@happyvertical/smrt-core": "0.55.5",
28
- "@happyvertical/smrt-ui": "0.55.5"
27
+ "@happyvertical/smrt-core": "0.55.7",
28
+ "@happyvertical/smrt-ui": "0.55.7"
29
29
  },
30
30
  "devDependencies": {
31
- "@happyvertical/smrt-cli": "0.55.5",
32
- "@happyvertical/smrt-users": "0.55.5",
33
- "@happyvertical/smrt-vitest": "0.55.5",
31
+ "@happyvertical/smrt-cli": "0.55.7",
32
+ "@happyvertical/smrt-users": "0.55.7",
33
+ "@happyvertical/smrt-vitest": "0.55.7",
34
34
  "@sveltejs/package": "^2.5.8",
35
35
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
36
36
  "@types/node": "24.13.6",