@genesislcap/foundation-utils 14.497.0 → 14.498.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1434,7 +1434,46 @@
1434
1434
  "text": "string"
1435
1435
  }
1436
1436
  }
1437
- ]
1437
+ ],
1438
+ "description": "Returns true when `feature.<name>` is present in the current URL query string.",
1439
+ "privacy": "public"
1440
+ },
1441
+ {
1442
+ "kind": "function",
1443
+ "name": "getActivatedFeatures",
1444
+ "return": {
1445
+ "type": {
1446
+ "text": "string[]"
1447
+ }
1448
+ },
1449
+ "description": "Returns the names of all feature flags currently present in the URL query string.",
1450
+ "privacy": "public"
1451
+ },
1452
+ {
1453
+ "kind": "function",
1454
+ "name": "setActivatedFeatures",
1455
+ "return": {
1456
+ "type": {
1457
+ "text": "void"
1458
+ }
1459
+ },
1460
+ "parameters": [
1461
+ {
1462
+ "name": "features",
1463
+ "type": {
1464
+ "text": "string[]"
1465
+ }
1466
+ },
1467
+ {
1468
+ "name": "options",
1469
+ "default": "{}",
1470
+ "type": {
1471
+ "text": "SetActivatedFeaturesOptions"
1472
+ }
1473
+ }
1474
+ ],
1475
+ "description": "Rewrites URL `feature.*` query params to match the given feature list (presence-only).\nRemoves any existing `feature.*` params, then adds each selected feature as `feature.<name>`.\nReloads by default so boot-time consumers (e.g. AI registration) pick up the change.",
1476
+ "privacy": "public"
1438
1477
  }
1439
1478
  ],
1440
1479
  "exports": [
@@ -1445,6 +1484,22 @@
1445
1484
  "name": "isFeatureActivated",
1446
1485
  "module": "src/feature-flags/featureFlags.ts"
1447
1486
  }
1487
+ },
1488
+ {
1489
+ "kind": "js",
1490
+ "name": "getActivatedFeatures",
1491
+ "declaration": {
1492
+ "name": "getActivatedFeatures",
1493
+ "module": "src/feature-flags/featureFlags.ts"
1494
+ }
1495
+ },
1496
+ {
1497
+ "kind": "js",
1498
+ "name": "setActivatedFeatures",
1499
+ "declaration": {
1500
+ "name": "setActivatedFeatures",
1501
+ "module": "src/feature-flags/featureFlags.ts"
1502
+ }
1448
1503
  }
1449
1504
  ]
1450
1505
  },
@@ -1,2 +1,47 @@
1
+ /**
2
+ * Options for {@link setActivatedFeatures}.
3
+ * @public
4
+ */
5
+ export type SetActivatedFeaturesOptions = {
6
+ /**
7
+ * When true (default), navigates to the updated URL so boot-time consumers re-evaluate.
8
+ * When false, updates the URL via `history.replaceState` without reloading.
9
+ */
10
+ reload?: boolean;
11
+ };
12
+ /**
13
+ * Returns true when `feature.<name>` is present in the given search string.
14
+ * @internal
15
+ */
16
+ export declare const isFeatureActivatedInSearch: (search: string, feature: string) => boolean;
17
+ /**
18
+ * Returns the names of all feature flags present in the given search string.
19
+ * @internal
20
+ */
21
+ export declare const getActivatedFeaturesFromSearch: (search: string) => string[];
22
+ /**
23
+ * Returns a new URL with `feature.*` query params rewritten to match the given feature list.
24
+ * @internal
25
+ */
26
+ export declare const applyActivatedFeaturesToUrl: (url: URL, features: string[]) => URL;
27
+ /**
28
+ * Returns true when `feature.<name>` is present in the current URL query string.
29
+ * @public
30
+ */
1
31
  export declare const isFeatureActivated: (feature: string) => boolean;
32
+ /**
33
+ * Returns the names of all feature flags currently present in the URL query string.
34
+ * @example
35
+ * // URL: ?feature.ai&feature.forceHttp=true
36
+ * getActivatedFeatures(); // ['ai', 'forceHttp']
37
+ * @public
38
+ */
39
+ export declare const getActivatedFeatures: () => string[];
40
+ /**
41
+ * Rewrites URL `feature.*` query params to match the given feature list (presence-only).
42
+ * Removes any existing `feature.*` params, then adds each selected feature as `feature.<name>`.
43
+ * Reloads by default so boot-time consumers (e.g. AI registration) pick up the change.
44
+ * @public
45
+ */
46
+ export declare const setActivatedFeatures: (features: string[], options?: SetActivatedFeaturesOptions) => void;
2
47
  //# sourceMappingURL=featureFlags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"featureFlags.d.ts","sourceRoot":"","sources":["../../../src/feature-flags/featureFlags.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,OAapD,CAAC"}
1
+ {"version":3,"file":"featureFlags.d.ts","sourceRoot":"","sources":["../../../src/feature-flags/featureFlags.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,KAAG,OAe5E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,GAAI,QAAQ,MAAM,KAAG,MAAM,EAcrE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GAAI,KAAK,GAAG,EAAE,UAAU,MAAM,EAAE,KAAG,GAmB1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,OACQ,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAAM,EACU,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,MAAM,EAAE,EAClB,UAAS,2BAAgC,KACxC,IAUF,CAAC"}
@@ -1,8 +1,15 @@
1
- export const isFeatureActivated = (feature) => {
2
- const currentUrl = window.location.href;
3
- const queryString = new URL(currentUrl).search;
4
- const params = new URLSearchParams(queryString);
5
- const featureKey = `feature.${feature}`.toLowerCase();
1
+ const FEATURE_PREFIX = 'feature.';
2
+ const isFeatureParamKey = (key) => key.toLowerCase().startsWith(FEATURE_PREFIX);
3
+ /**
4
+ * Returns true when `feature.<name>` is present in the given search string.
5
+ * @internal
6
+ */
7
+ export const isFeatureActivatedInSearch = (search, feature) => {
8
+ if (!feature) {
9
+ return false;
10
+ }
11
+ const featureKey = `${FEATURE_PREFIX}${feature}`.toLowerCase();
12
+ const params = new URLSearchParams(search);
6
13
  for (const [key] of params.entries()) {
7
14
  if (key.toLowerCase() === featureKey) {
8
15
  return true;
@@ -10,3 +17,69 @@ export const isFeatureActivated = (feature) => {
10
17
  }
11
18
  return false;
12
19
  };
20
+ /**
21
+ * Returns the names of all feature flags present in the given search string.
22
+ * @internal
23
+ */
24
+ export const getActivatedFeaturesFromSearch = (search) => {
25
+ const params = new URLSearchParams(search);
26
+ const features = [];
27
+ for (const [key] of params.entries()) {
28
+ if (isFeatureParamKey(key)) {
29
+ const feature = key.slice(FEATURE_PREFIX.length);
30
+ if (feature) {
31
+ features.push(feature);
32
+ }
33
+ }
34
+ }
35
+ return features;
36
+ };
37
+ /**
38
+ * Returns a new URL with `feature.*` query params rewritten to match the given feature list.
39
+ * @internal
40
+ */
41
+ export const applyActivatedFeaturesToUrl = (url, features) => {
42
+ const next = new URL(url.href);
43
+ const params = next.searchParams;
44
+ for (const key of [...params.keys()]) {
45
+ if (isFeatureParamKey(key)) {
46
+ params.delete(key);
47
+ }
48
+ }
49
+ for (const feature of features) {
50
+ if (feature) {
51
+ // Use an explicit value so routers/normalizers that drop empty query values
52
+ // (e.g. some React Router redirect paths) still preserve the flag.
53
+ params.set(`${FEATURE_PREFIX}${feature}`, 'true');
54
+ }
55
+ }
56
+ return next;
57
+ };
58
+ /**
59
+ * Returns true when `feature.<name>` is present in the current URL query string.
60
+ * @public
61
+ */
62
+ export const isFeatureActivated = (feature) => isFeatureActivatedInSearch(window.location.search, feature);
63
+ /**
64
+ * Returns the names of all feature flags currently present in the URL query string.
65
+ * @example
66
+ * // URL: ?feature.ai&feature.forceHttp=true
67
+ * getActivatedFeatures(); // ['ai', 'forceHttp']
68
+ * @public
69
+ */
70
+ export const getActivatedFeatures = () => getActivatedFeaturesFromSearch(window.location.search);
71
+ /**
72
+ * Rewrites URL `feature.*` query params to match the given feature list (presence-only).
73
+ * Removes any existing `feature.*` params, then adds each selected feature as `feature.<name>`.
74
+ * Reloads by default so boot-time consumers (e.g. AI registration) pick up the change.
75
+ * @public
76
+ */
77
+ export const setActivatedFeatures = (features, options = {}) => {
78
+ const { reload = true } = options;
79
+ const url = applyActivatedFeaturesToUrl(new URL(window.location.href), features);
80
+ if (reload) {
81
+ window.location.assign(url.toString());
82
+ return;
83
+ }
84
+ window.history.replaceState({}, '', url.toString());
85
+ };
@@ -5829,6 +5829,30 @@
5829
5829
  }
5830
5830
  ]
5831
5831
  },
5832
+ {
5833
+ "kind": "Function",
5834
+ "canonicalReference": "@genesislcap/foundation-utils!getActivatedFeatures:function(1)",
5835
+ "docComment": "/**\n * Returns the names of all feature flags currently present in the URL query string.\n *\n * @example\n *\n * // URL: ?feature.ai&feature.forceHttp=true getActivatedFeatures(); // ['ai', 'forceHttp']\n *\n * @public\n */\n",
5836
+ "excerptTokens": [
5837
+ {
5838
+ "kind": "Content",
5839
+ "text": "getActivatedFeatures: () => "
5840
+ },
5841
+ {
5842
+ "kind": "Content",
5843
+ "text": "string[]"
5844
+ }
5845
+ ],
5846
+ "fileUrlPath": "src/feature-flags/featureFlags.ts",
5847
+ "returnTypeTokenRange": {
5848
+ "startIndex": 1,
5849
+ "endIndex": 2
5850
+ },
5851
+ "releaseTag": "Public",
5852
+ "overloadIndex": 1,
5853
+ "parameters": [],
5854
+ "name": "getActivatedFeatures"
5855
+ },
5832
5856
  {
5833
5857
  "kind": "Function",
5834
5858
  "canonicalReference": "@genesislcap/foundation-utils!getAllElements:function(1)",
@@ -8246,7 +8270,7 @@
8246
8270
  {
8247
8271
  "kind": "Function",
8248
8272
  "canonicalReference": "@genesislcap/foundation-utils!isFeatureActivated:function(1)",
8249
- "docComment": "",
8273
+ "docComment": "/**\n * Returns true when `feature.<name>` is present in the current URL query string.\n *\n * @public\n */\n",
8250
8274
  "excerptTokens": [
8251
8275
  {
8252
8276
  "kind": "Content",
@@ -17879,6 +17903,90 @@
17879
17903
  "endIndex": 4
17880
17904
  }
17881
17905
  },
17906
+ {
17907
+ "kind": "Function",
17908
+ "canonicalReference": "@genesislcap/foundation-utils!setActivatedFeatures:function(1)",
17909
+ "docComment": "/**\n * Rewrites URL `feature.*` query params to match the given feature list (presence-only). Removes any existing `feature.*` params, then adds each selected feature as `feature.<name>`. Reloads by default so boot-time consumers (e.g. AI registration) pick up the change.\n *\n * @public\n */\n",
17910
+ "excerptTokens": [
17911
+ {
17912
+ "kind": "Content",
17913
+ "text": "setActivatedFeatures: (features: "
17914
+ },
17915
+ {
17916
+ "kind": "Content",
17917
+ "text": "string[]"
17918
+ },
17919
+ {
17920
+ "kind": "Content",
17921
+ "text": ", options?: "
17922
+ },
17923
+ {
17924
+ "kind": "Reference",
17925
+ "text": "SetActivatedFeaturesOptions",
17926
+ "canonicalReference": "@genesislcap/foundation-utils!SetActivatedFeaturesOptions:type"
17927
+ },
17928
+ {
17929
+ "kind": "Content",
17930
+ "text": ") => "
17931
+ },
17932
+ {
17933
+ "kind": "Content",
17934
+ "text": "void"
17935
+ }
17936
+ ],
17937
+ "fileUrlPath": "src/feature-flags/featureFlags.ts",
17938
+ "returnTypeTokenRange": {
17939
+ "startIndex": 5,
17940
+ "endIndex": 6
17941
+ },
17942
+ "releaseTag": "Public",
17943
+ "overloadIndex": 1,
17944
+ "parameters": [
17945
+ {
17946
+ "parameterName": "features",
17947
+ "parameterTypeTokenRange": {
17948
+ "startIndex": 1,
17949
+ "endIndex": 2
17950
+ },
17951
+ "isOptional": false
17952
+ },
17953
+ {
17954
+ "parameterName": "options",
17955
+ "parameterTypeTokenRange": {
17956
+ "startIndex": 3,
17957
+ "endIndex": 4
17958
+ },
17959
+ "isOptional": true
17960
+ }
17961
+ ],
17962
+ "name": "setActivatedFeatures"
17963
+ },
17964
+ {
17965
+ "kind": "TypeAlias",
17966
+ "canonicalReference": "@genesislcap/foundation-utils!SetActivatedFeaturesOptions:type",
17967
+ "docComment": "/**\n * Options for {@link setActivatedFeatures}.\n *\n * @public\n */\n",
17968
+ "excerptTokens": [
17969
+ {
17970
+ "kind": "Content",
17971
+ "text": "export type SetActivatedFeaturesOptions = "
17972
+ },
17973
+ {
17974
+ "kind": "Content",
17975
+ "text": "{\n reload?: boolean;\n}"
17976
+ },
17977
+ {
17978
+ "kind": "Content",
17979
+ "text": ";"
17980
+ }
17981
+ ],
17982
+ "fileUrlPath": "src/feature-flags/featureFlags.ts",
17983
+ "releaseTag": "Public",
17984
+ "name": "SetActivatedFeaturesOptions",
17985
+ "typeTokenRange": {
17986
+ "startIndex": 1,
17987
+ "endIndex": 2
17988
+ }
17989
+ },
17882
17990
  {
17883
17991
  "kind": "Variable",
17884
17992
  "canonicalReference": "@genesislcap/foundation-utils!SHORTCUT_BLOCKED_DEFAULT_MESSAGE:var",
@@ -38,6 +38,12 @@ export declare const activeColorScheme: CSSDesignToken<string>;
38
38
  */
39
39
  export declare let API_HOST: string;
40
40
 
41
+ /**
42
+ * Returns a new URL with `feature.*` query params rewritten to match the given feature list.
43
+ * @internal
44
+ */
45
+ export declare const applyActivatedFeaturesToUrl: (url: URL, features: string[]) => URL;
46
+
41
47
  /**
42
48
  * assureDesignSystem.
43
49
  *
@@ -682,6 +688,21 @@ export declare namespace Genesis {
682
688
  */
683
689
  export declare const GENESIS_SOCKET_URL: string;
684
690
 
691
+ /**
692
+ * Returns the names of all feature flags currently present in the URL query string.
693
+ * @example
694
+ * // URL: ?feature.ai&feature.forceHttp=true
695
+ * getActivatedFeatures(); // ['ai', 'forceHttp']
696
+ * @public
697
+ */
698
+ export declare const getActivatedFeatures: () => string[];
699
+
700
+ /**
701
+ * Returns the names of all feature flags present in the given search string.
702
+ * @internal
703
+ */
704
+ export declare const getActivatedFeaturesFromSearch: (search: string) => string[];
705
+
685
706
  /**
686
707
  * Recursively gather all elements including those in shadow DOM
687
708
  * @public
@@ -890,8 +911,18 @@ export declare const inSymphonyDesktop: () => boolean;
890
911
  */
891
912
  export declare const isDev: () => boolean;
892
913
 
914
+ /**
915
+ * Returns true when `feature.<name>` is present in the current URL query string.
916
+ * @public
917
+ */
893
918
  export declare const isFeatureActivated: (feature: string) => boolean;
894
919
 
920
+ /**
921
+ * Returns true when `feature.<name>` is present in the given search string.
922
+ * @internal
923
+ */
924
+ export declare const isFeatureActivatedInSearch: (search: string, feature: string) => boolean;
925
+
895
926
  /**
896
927
  * JSON replacer function.
897
928
  * @param key - The object key.
@@ -2264,6 +2295,26 @@ export declare type ServerRowEntity = {
2264
2295
  };
2265
2296
  };
2266
2297
 
2298
+ /**
2299
+ * Rewrites URL `feature.*` query params to match the given feature list (presence-only).
2300
+ * Removes any existing `feature.*` params, then adds each selected feature as `feature.<name>`.
2301
+ * Reloads by default so boot-time consumers (e.g. AI registration) pick up the change.
2302
+ * @public
2303
+ */
2304
+ export declare const setActivatedFeatures: (features: string[], options?: SetActivatedFeaturesOptions) => void;
2305
+
2306
+ /**
2307
+ * Options for {@link setActivatedFeatures}.
2308
+ * @public
2309
+ */
2310
+ export declare type SetActivatedFeaturesOptions = {
2311
+ /**
2312
+ * When true (default), navigates to the updated URL so boot-time consumers re-evaluate.
2313
+ * When false, updates the URL via `history.replaceState` without reloading.
2314
+ */
2315
+ reload?: boolean;
2316
+ };
2317
+
2267
2318
  export declare const SHORTCUT_BLOCKED_DEFAULT_MESSAGE = "This shortcut is currently unavailable in this context.";
2268
2319
 
2269
2320
  export declare const SHORTCUT_BLOCKED_DEFAULT_TITLE = "Shortcut blocked";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/foundation-utils",
3
3
  "description": "Genesis Foundation Utils",
4
- "version": "14.497.0",
4
+ "version": "14.498.0",
5
5
  "sideEffects": false,
6
6
  "license": "SEE LICENSE IN license.txt",
7
7
  "main": "dist/esm/index.js",
@@ -29,18 +29,18 @@
29
29
  }
30
30
  },
31
31
  "devDependencies": {
32
- "@genesislcap/foundation-testing": "14.497.0",
33
- "@genesislcap/genx": "14.497.0",
34
- "@genesislcap/rollup-builder": "14.497.0",
35
- "@genesislcap/ts-builder": "14.497.0",
36
- "@genesislcap/uvu-playwright-builder": "14.497.0",
37
- "@genesislcap/vite-builder": "14.497.0",
38
- "@genesislcap/webpack-builder": "14.497.0",
32
+ "@genesislcap/foundation-testing": "14.498.0",
33
+ "@genesislcap/genx": "14.498.0",
34
+ "@genesislcap/rollup-builder": "14.498.0",
35
+ "@genesislcap/ts-builder": "14.498.0",
36
+ "@genesislcap/uvu-playwright-builder": "14.498.0",
37
+ "@genesislcap/vite-builder": "14.498.0",
38
+ "@genesislcap/webpack-builder": "14.498.0",
39
39
  "@types/json-schema": "^7.0.11"
40
40
  },
41
41
  "dependencies": {
42
- "@genesislcap/expression-builder": "14.497.0",
43
- "@genesislcap/foundation-logger": "14.497.0",
42
+ "@genesislcap/expression-builder": "14.498.0",
43
+ "@genesislcap/foundation-logger": "14.498.0",
44
44
  "@microsoft/fast-components": "2.30.6",
45
45
  "@microsoft/fast-element": "1.14.0",
46
46
  "@microsoft/fast-foundation": "2.50.0",
@@ -58,5 +58,5 @@
58
58
  "access": "public"
59
59
  },
60
60
  "customElements": "dist/custom-elements.json",
61
- "gitHead": "8859a3cd83bd40fc5e5bbff9be5ebe02380fb6ec"
61
+ "gitHead": "88a07e46851fa94efc9399c50975c9eb2c21168c"
62
62
  }