@smooai/config 2.1.4 → 2.1.5

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.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Client-safe feature flag utilities.
3
+ *
4
+ * These functions read feature flags from build-time environment variables
5
+ * (NEXT_PUBLIC_FEATURE_FLAG_* or VITE_FEATURE_FLAG_*) and can be used
6
+ * in both server and client components.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // In your .smooai-config/config.ts:
11
+ * const config = defineConfig({
12
+ * featureFlagSchema: {
13
+ * aboutPage: BooleanSchema,
14
+ * contactPage: BooleanSchema,
15
+ * },
16
+ * });
17
+ *
18
+ * // In your next.config.js, inject flags as env vars:
19
+ * // NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE=true
20
+ *
21
+ * // In any component (server or client):
22
+ * import { getClientFeatureFlag } from '@smooai/config/feature-flags';
23
+ *
24
+ * if (getClientFeatureFlag('aboutPage')) {
25
+ * // show the feature
26
+ * }
27
+ * ```
28
+ */
29
+ /**
30
+ * Get a feature flag value from build-time environment variables.
31
+ *
32
+ * Checks for:
33
+ * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)
34
+ * 2. VITE_FEATURE_FLAG_{KEY} (Vite)
35
+ *
36
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
37
+ * e.g., "aboutPage" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE
38
+ *
39
+ * @param key - The camelCase feature flag key
40
+ * @returns true if the flag is explicitly set to "true", false otherwise
41
+ */
42
+ declare function getClientFeatureFlag(key: string): boolean;
43
+ /**
44
+ * Create a typed feature flag checker from a config's FeatureFlagKeys.
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import config, { FeatureFlagKeys } from '../.smooai-config/config';
49
+ * import { createFeatureFlagChecker } from '@smooai/config/feature-flags';
50
+ *
51
+ * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();
52
+ *
53
+ * // Usage:
54
+ * getFeatureFlag('aboutPage') // typed to valid keys
55
+ * ```
56
+ */
57
+ declare function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean;
58
+
59
+ export { createFeatureFlagChecker, getClientFeatureFlag };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Client-safe feature flag utilities.
3
+ *
4
+ * These functions read feature flags from build-time environment variables
5
+ * (NEXT_PUBLIC_FEATURE_FLAG_* or VITE_FEATURE_FLAG_*) and can be used
6
+ * in both server and client components.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // In your .smooai-config/config.ts:
11
+ * const config = defineConfig({
12
+ * featureFlagSchema: {
13
+ * aboutPage: BooleanSchema,
14
+ * contactPage: BooleanSchema,
15
+ * },
16
+ * });
17
+ *
18
+ * // In your next.config.js, inject flags as env vars:
19
+ * // NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE=true
20
+ *
21
+ * // In any component (server or client):
22
+ * import { getClientFeatureFlag } from '@smooai/config/feature-flags';
23
+ *
24
+ * if (getClientFeatureFlag('aboutPage')) {
25
+ * // show the feature
26
+ * }
27
+ * ```
28
+ */
29
+ /**
30
+ * Get a feature flag value from build-time environment variables.
31
+ *
32
+ * Checks for:
33
+ * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)
34
+ * 2. VITE_FEATURE_FLAG_{KEY} (Vite)
35
+ *
36
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
37
+ * e.g., "aboutPage" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE
38
+ *
39
+ * @param key - The camelCase feature flag key
40
+ * @returns true if the flag is explicitly set to "true", false otherwise
41
+ */
42
+ declare function getClientFeatureFlag(key: string): boolean;
43
+ /**
44
+ * Create a typed feature flag checker from a config's FeatureFlagKeys.
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import config, { FeatureFlagKeys } from '../.smooai-config/config';
49
+ * import { createFeatureFlagChecker } from '@smooai/config/feature-flags';
50
+ *
51
+ * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();
52
+ *
53
+ * // Usage:
54
+ * getFeatureFlag('aboutPage') // typed to valid keys
55
+ * ```
56
+ */
57
+ declare function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean;
58
+
59
+ export { createFeatureFlagChecker, getClientFeatureFlag };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/feature-flags/index.ts
21
+ var feature_flags_exports = {};
22
+ __export(feature_flags_exports, {
23
+ createFeatureFlagChecker: () => createFeatureFlagChecker,
24
+ getClientFeatureFlag: () => getClientFeatureFlag
25
+ });
26
+ module.exports = __toCommonJS(feature_flags_exports);
27
+ function toUpperSnakeCase(key) {
28
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
29
+ }
30
+ function getClientFeatureFlag(key) {
31
+ const envKey = toUpperSnakeCase(key);
32
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : void 0;
33
+ if (nextValue !== void 0) {
34
+ return nextValue === "true" || nextValue === "1";
35
+ }
36
+ try {
37
+ const viteEnv = globalThis.__VITE_ENV__;
38
+ const viteValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];
39
+ if (viteValue !== void 0) {
40
+ return viteValue === "true" || viteValue === "1";
41
+ }
42
+ } catch {
43
+ }
44
+ return false;
45
+ }
46
+ function createFeatureFlagChecker() {
47
+ return (key) => getClientFeatureFlag(key);
48
+ }
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ createFeatureFlagChecker,
52
+ getClientFeatureFlag
53
+ });
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/feature-flags/index.ts"],"sourcesContent":["/**\n * Client-safe feature flag utilities.\n *\n * These functions read feature flags from build-time environment variables\n * (NEXT_PUBLIC_FEATURE_FLAG_* or VITE_FEATURE_FLAG_*) and can be used\n * in both server and client components.\n *\n * @example\n * ```tsx\n * // In your .smooai-config/config.ts:\n * const config = defineConfig({\n * featureFlagSchema: {\n * aboutPage: BooleanSchema,\n * contactPage: BooleanSchema,\n * },\n * });\n *\n * // In your next.config.js, inject flags as env vars:\n * // NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE=true\n *\n * // In any component (server or client):\n * import { getClientFeatureFlag } from '@smooai/config/feature-flags';\n *\n * if (getClientFeatureFlag('aboutPage')) {\n * // show the feature\n * }\n * ```\n */\n\n/**\n * Convert a camelCase feature flag key to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" → \"ABOUT_PAGE\"\n */\nfunction toUpperSnakeCase(key: string): string {\n return key.replace(/([A-Z])/g, '_$1').toUpperCase();\n}\n\n/**\n * Get a feature flag value from build-time environment variables.\n *\n * Checks for:\n * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)\n * 2. VITE_FEATURE_FLAG_{KEY} (Vite)\n *\n * The key is converted from camelCase to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE\n *\n * @param key - The camelCase feature flag key\n * @returns true if the flag is explicitly set to \"true\", false otherwise\n */\nexport function getClientFeatureFlag(key: string): boolean {\n const envKey = toUpperSnakeCase(key);\n\n // Check Next.js env var\n const nextValue = typeof process !== 'undefined' ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : undefined;\n if (nextValue !== undefined) {\n return nextValue === 'true' || nextValue === '1';\n }\n\n // Check Vite env var (available via import.meta.env in Vite)\n // At build time, Vite replaces import.meta.env.VITE_* with literal values\n // We use a dynamic approach for runtime compatibility\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];\n if (viteValue !== undefined) {\n return viteValue === 'true' || viteValue === '1';\n }\n } catch {\n // Vite env not available\n }\n\n return false;\n}\n\n/**\n * Create a typed feature flag checker from a config's FeatureFlagKeys.\n *\n * @example\n * ```tsx\n * import config, { FeatureFlagKeys } from '../.smooai-config/config';\n * import { createFeatureFlagChecker } from '@smooai/config/feature-flags';\n *\n * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();\n *\n * // Usage:\n * getFeatureFlag('aboutPage') // typed to valid keys\n * ```\n */\nexport function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean {\n return (key: T[keyof T]) => getClientFeatureFlag(key as string);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,SAAS,iBAAiB,KAAqB;AAC3C,SAAO,IAAI,QAAQ,YAAY,KAAK,EAAE,YAAY;AACtD;AAeO,SAAS,qBAAqB,KAAsB;AACvD,QAAM,SAAS,iBAAiB,GAAG;AAGnC,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,4BAA4B,MAAM,EAAE,IAAI;AACzG,MAAI,cAAc,QAAW;AACzB,WAAO,cAAc,UAAU,cAAc;AAAA,EACjD;AAKA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,YAAY,UAAU,qBAAqB,MAAM,EAAE;AACzD,QAAI,cAAc,QAAW;AACzB,aAAO,cAAc,UAAU,cAAc;AAAA,IACjD;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAgBO,SAAS,2BAA2F;AACvG,SAAO,CAAC,QAAoB,qBAAqB,GAAa;AAClE;","names":[]}
@@ -0,0 +1,30 @@
1
+ import "../chunk-J5LGTIGS.mjs";
2
+
3
+ // src/feature-flags/index.ts
4
+ function toUpperSnakeCase(key) {
5
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
6
+ }
7
+ function getClientFeatureFlag(key) {
8
+ const envKey = toUpperSnakeCase(key);
9
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : void 0;
10
+ if (nextValue !== void 0) {
11
+ return nextValue === "true" || nextValue === "1";
12
+ }
13
+ try {
14
+ const viteEnv = globalThis.__VITE_ENV__;
15
+ const viteValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];
16
+ if (viteValue !== void 0) {
17
+ return viteValue === "true" || viteValue === "1";
18
+ }
19
+ } catch {
20
+ }
21
+ return false;
22
+ }
23
+ function createFeatureFlagChecker() {
24
+ return (key) => getClientFeatureFlag(key);
25
+ }
26
+ export {
27
+ createFeatureFlagChecker,
28
+ getClientFeatureFlag
29
+ };
30
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/feature-flags/index.ts"],"sourcesContent":["/**\n * Client-safe feature flag utilities.\n *\n * These functions read feature flags from build-time environment variables\n * (NEXT_PUBLIC_FEATURE_FLAG_* or VITE_FEATURE_FLAG_*) and can be used\n * in both server and client components.\n *\n * @example\n * ```tsx\n * // In your .smooai-config/config.ts:\n * const config = defineConfig({\n * featureFlagSchema: {\n * aboutPage: BooleanSchema,\n * contactPage: BooleanSchema,\n * },\n * });\n *\n * // In your next.config.js, inject flags as env vars:\n * // NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE=true\n *\n * // In any component (server or client):\n * import { getClientFeatureFlag } from '@smooai/config/feature-flags';\n *\n * if (getClientFeatureFlag('aboutPage')) {\n * // show the feature\n * }\n * ```\n */\n\n/**\n * Convert a camelCase feature flag key to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" → \"ABOUT_PAGE\"\n */\nfunction toUpperSnakeCase(key: string): string {\n return key.replace(/([A-Z])/g, '_$1').toUpperCase();\n}\n\n/**\n * Get a feature flag value from build-time environment variables.\n *\n * Checks for:\n * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)\n * 2. VITE_FEATURE_FLAG_{KEY} (Vite)\n *\n * The key is converted from camelCase to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE\n *\n * @param key - The camelCase feature flag key\n * @returns true if the flag is explicitly set to \"true\", false otherwise\n */\nexport function getClientFeatureFlag(key: string): boolean {\n const envKey = toUpperSnakeCase(key);\n\n // Check Next.js env var\n const nextValue = typeof process !== 'undefined' ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : undefined;\n if (nextValue !== undefined) {\n return nextValue === 'true' || nextValue === '1';\n }\n\n // Check Vite env var (available via import.meta.env in Vite)\n // At build time, Vite replaces import.meta.env.VITE_* with literal values\n // We use a dynamic approach for runtime compatibility\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];\n if (viteValue !== undefined) {\n return viteValue === 'true' || viteValue === '1';\n }\n } catch {\n // Vite env not available\n }\n\n return false;\n}\n\n/**\n * Create a typed feature flag checker from a config's FeatureFlagKeys.\n *\n * @example\n * ```tsx\n * import config, { FeatureFlagKeys } from '../.smooai-config/config';\n * import { createFeatureFlagChecker } from '@smooai/config/feature-flags';\n *\n * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();\n *\n * // Usage:\n * getFeatureFlag('aboutPage') // typed to valid keys\n * ```\n */\nexport function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean {\n return (key: T[keyof T]) => getClientFeatureFlag(key as string);\n}\n"],"mappings":";;;AAiCA,SAAS,iBAAiB,KAAqB;AAC3C,SAAO,IAAI,QAAQ,YAAY,KAAK,EAAE,YAAY;AACtD;AAeO,SAAS,qBAAqB,KAAsB;AACvD,QAAM,SAAS,iBAAiB,GAAG;AAGnC,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,4BAA4B,MAAM,EAAE,IAAI;AACzG,MAAI,cAAc,QAAW;AACzB,WAAO,cAAc,UAAU,cAAc;AAAA,EACjD;AAKA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,YAAY,UAAU,qBAAqB,MAAM,EAAE;AACzD,QAAI,cAAc,QAAW;AACzB,aAAO,cAAc,UAAU,cAAc;AAAA,IACjD;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAgBO,SAAS,2BAA2F;AACvG,SAAO,CAAC,QAAoB,qBAAqB,GAAa;AAClE;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smooai/config",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "Type-safe multi-language configuration management with schema validation, three-tier config (public, secret, feature flags), and runtime client support for TypeScript, Python, Rust, and Go.",
5
5
  "homepage": "https://github.com/SmooAI/config#readme",
6
6
  "bugs": {
@@ -47,6 +47,11 @@
47
47
  "import": "./dist/nextjs/getConfig.mjs",
48
48
  "require": "./dist/nextjs/getConfig.js"
49
49
  },
50
+ "./feature-flags": {
51
+ "types": "./dist/feature-flags/index.d.ts",
52
+ "import": "./dist/feature-flags/index.mjs",
53
+ "require": "./dist/feature-flags/index.js"
54
+ },
50
55
  "./react": {
51
56
  "types": "./dist/react/index.d.ts",
52
57
  "import": "./dist/react/index.mjs",