@smooai/config 3.0.0 → 3.1.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.
Files changed (81) hide show
  1. package/dist/browser/chunk-YMNAMX6Y.mjs +55 -0
  2. package/dist/browser/chunk-YMNAMX6Y.mjs.map +1 -0
  3. package/dist/browser/client/index.mjs +14 -0
  4. package/dist/browser/client/index.mjs.map +1 -0
  5. package/dist/browser/feature-flags/index.mjs +4 -24
  6. package/dist/browser/feature-flags/index.mjs.map +1 -1
  7. package/dist/{chunk-2DYBQ6SF.mjs → chunk-43SVVFYE.mjs} +3 -3
  8. package/dist/{chunk-PCXGCPWC.mjs → chunk-6XDO5B2T.mjs} +8 -8
  9. package/dist/{chunk-7CCXEKIK.mjs → chunk-H4YT7JJJ.mjs} +4 -4
  10. package/dist/{chunk-JAEJOSH5.mjs → chunk-NF7JF2UP.mjs} +2 -2
  11. package/dist/{chunk-7GMXNAVA.mjs → chunk-PD2SHA7M.mjs} +11 -11
  12. package/dist/{chunk-2CD4ZQFH.mjs → chunk-R7NMFJFJ.mjs} +2 -2
  13. package/dist/chunk-SAX775JO.mjs +40 -0
  14. package/dist/chunk-SAX775JO.mjs.map +1 -0
  15. package/dist/chunk-UCFP2MA2.mjs +55 -0
  16. package/dist/chunk-UCFP2MA2.mjs.map +1 -0
  17. package/dist/{chunk-4RYDS2HX.mjs → chunk-UEIVAJKL.mjs} +2 -2
  18. package/dist/client/index.d.mts +66 -0
  19. package/dist/client/index.d.ts +66 -0
  20. package/dist/client/index.js +82 -0
  21. package/dist/client/index.js.map +1 -0
  22. package/dist/client/index.mjs +14 -0
  23. package/dist/client/index.mjs.map +1 -0
  24. package/dist/config/config.mjs +2 -2
  25. package/dist/config/findAndProcessEnvConfig.mjs +5 -5
  26. package/dist/config/findAndProcessFileConfig.mjs +6 -6
  27. package/dist/config/index.mjs +6 -6
  28. package/dist/config/parseConfigSchema.mjs +3 -3
  29. package/dist/config/server.mjs +9 -9
  30. package/dist/feature-flags/index.d.mts +1 -59
  31. package/dist/feature-flags/index.d.ts +1 -59
  32. package/dist/feature-flags/index.js +9 -3
  33. package/dist/feature-flags/index.js.map +1 -1
  34. package/dist/feature-flags/index.mjs +4 -24
  35. package/dist/feature-flags/index.mjs.map +1 -1
  36. package/dist/integration-tests/1/smooai-config/config.mjs +3 -3
  37. package/dist/integration-tests/1/smooai-config/default.mjs +3 -3
  38. package/dist/integration-tests/1/smooai-config/development.mjs +3 -3
  39. package/dist/integration-tests/1/smooai-config/production.aws.mjs +3 -3
  40. package/dist/integration-tests/1/smooai-config/production.aws.us-east-1.mjs +3 -3
  41. package/dist/integration-tests/1/smooai-config/production.aws.us-east-2.mjs +3 -3
  42. package/dist/integration-tests/1/smooai-config/production.mjs +3 -3
  43. package/dist/integration-tests/1/smooai-config/staging.mjs +3 -3
  44. package/dist/integration-tests/2/smooai-config/config.mjs +3 -3
  45. package/dist/integration-tests/2/smooai-config/default.mjs +3 -3
  46. package/dist/integration-tests/2/smooai-config/development.mjs +3 -3
  47. package/dist/integration-tests/2/smooai-config/production.aws.mjs +3 -3
  48. package/dist/integration-tests/2/smooai-config/production.aws.us-east-1.mjs +3 -3
  49. package/dist/integration-tests/2/smooai-config/production.mjs +3 -3
  50. package/dist/nextjs/index.mjs +3 -3
  51. package/dist/nextjs/withFeatureFlags.d.mts +41 -0
  52. package/dist/nextjs/withFeatureFlags.d.ts +41 -0
  53. package/dist/nextjs/withFeatureFlags.js +79 -0
  54. package/dist/nextjs/withFeatureFlags.js.map +1 -0
  55. package/dist/nextjs/withFeatureFlags.mjs +20 -0
  56. package/dist/nextjs/withFeatureFlags.mjs.map +1 -0
  57. package/dist/nextjs/withSmooConfig.d.mts +63 -0
  58. package/dist/nextjs/withSmooConfig.d.ts +63 -0
  59. package/dist/nextjs/withSmooConfig.js +64 -0
  60. package/dist/nextjs/withSmooConfig.js.map +1 -0
  61. package/dist/nextjs/withSmooConfig.mjs +8 -0
  62. package/dist/nextjs/withSmooConfig.mjs.map +1 -0
  63. package/dist/platform/server/server.async.mjs +8 -8
  64. package/dist/platform/server/server.featureFlag.sync.mjs +8 -8
  65. package/dist/platform/server/server.publicConfig.sync.mjs +8 -8
  66. package/dist/platform/server/server.secretConfig.sync.mjs +8 -8
  67. package/dist/platform/server.mjs +8 -8
  68. package/dist/vite/smooConfigPlugin.d.mts +47 -0
  69. package/dist/vite/smooConfigPlugin.d.ts +47 -0
  70. package/dist/vite/smooConfigPlugin.js +60 -0
  71. package/dist/vite/smooConfigPlugin.js.map +1 -0
  72. package/dist/vite/smooConfigPlugin.mjs +37 -0
  73. package/dist/vite/smooConfigPlugin.mjs.map +1 -0
  74. package/package.json +25 -1
  75. /package/dist/{chunk-2DYBQ6SF.mjs.map → chunk-43SVVFYE.mjs.map} +0 -0
  76. /package/dist/{chunk-PCXGCPWC.mjs.map → chunk-6XDO5B2T.mjs.map} +0 -0
  77. /package/dist/{chunk-7CCXEKIK.mjs.map → chunk-H4YT7JJJ.mjs.map} +0 -0
  78. /package/dist/{chunk-JAEJOSH5.mjs.map → chunk-NF7JF2UP.mjs.map} +0 -0
  79. /package/dist/{chunk-7GMXNAVA.mjs.map → chunk-PD2SHA7M.mjs.map} +0 -0
  80. /package/dist/{chunk-2CD4ZQFH.mjs.map → chunk-R7NMFJFJ.mjs.map} +0 -0
  81. /package/dist/{chunk-4RYDS2HX.mjs.map → chunk-UEIVAJKL.mjs.map} +0 -0
@@ -0,0 +1,55 @@
1
+ // src/client/index.ts
2
+ function toUpperSnakeCase(key) {
3
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
4
+ }
5
+ function getClientFeatureFlag(key) {
6
+ const envKey = toUpperSnakeCase(key);
7
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : void 0;
8
+ if (nextValue !== void 0) {
9
+ return nextValue === "true" || nextValue === "1";
10
+ }
11
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : void 0;
12
+ if (viteValue !== void 0) {
13
+ return viteValue === "true" || viteValue === "1";
14
+ }
15
+ try {
16
+ const viteEnv = globalThis.__VITE_ENV__;
17
+ const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];
18
+ if (viteEnvValue !== void 0) {
19
+ return viteEnvValue === "true" || viteEnvValue === "1";
20
+ }
21
+ } catch {
22
+ }
23
+ return false;
24
+ }
25
+ function getClientPublicConfig(key) {
26
+ const envKey = toUpperSnakeCase(key);
27
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : void 0;
28
+ if (nextValue !== void 0) {
29
+ return nextValue;
30
+ }
31
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_CONFIG_${envKey}`] : void 0;
32
+ if (viteValue !== void 0) {
33
+ return viteValue;
34
+ }
35
+ try {
36
+ const viteEnv = globalThis.__VITE_ENV__;
37
+ const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];
38
+ if (viteEnvValue !== void 0) {
39
+ return viteEnvValue;
40
+ }
41
+ } catch {
42
+ }
43
+ return void 0;
44
+ }
45
+ function createFeatureFlagChecker() {
46
+ return (key) => getClientFeatureFlag(key);
47
+ }
48
+
49
+ export {
50
+ toUpperSnakeCase,
51
+ getClientFeatureFlag,
52
+ getClientPublicConfig,
53
+ createFeatureFlagChecker
54
+ };
55
+ //# sourceMappingURL=chunk-YMNAMX6Y.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/index.ts"],"sourcesContent":["/**\n * Universal client-safe config readers.\n *\n * Reads from both `NEXT_PUBLIC_` and `VITE_` prefixed env vars,\n * allowing the same code to work in Next.js and Vite environments.\n *\n * @example\n * ```tsx\n * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';\n *\n * if (getClientFeatureFlag('aboutPage')) {\n * // show the feature\n * }\n *\n * const apiUrl = getClientPublicConfig('apiBaseUrl');\n * ```\n */\n\n/**\n * Convert a camelCase key to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" → \"ABOUT_PAGE\"\n */\nexport function 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\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue === 'true' || viteValue === '1';\n }\n\n // Check Vite import.meta.env fallback (available via globalThis in some setups)\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue === 'true' || viteEnvValue === '1';\n }\n } catch {\n // Vite env not available\n }\n\n return false;\n}\n\n/**\n * Get a public config value from build-time environment variables.\n *\n * Checks for:\n * 1. NEXT_PUBLIC_CONFIG_{KEY} (Next.js)\n * 2. VITE_CONFIG_{KEY} (Vite)\n *\n * The key is converted from camelCase to UPPER_SNAKE_CASE.\n * e.g., \"apiBaseUrl\" checks NEXT_PUBLIC_CONFIG_API_BASE_URL\n *\n * @param key - The camelCase config key\n * @returns The config value as a string, or undefined if not set\n */\nexport function getClientPublicConfig(key: string): string | undefined {\n const envKey = toUpperSnakeCase(key);\n\n // Check Next.js env var\n const nextValue = typeof process !== 'undefined' ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : undefined;\n if (nextValue !== undefined) {\n return nextValue;\n }\n\n // Check Vite env var\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_CONFIG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue;\n }\n\n // Check Vite import.meta.env fallback\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue;\n }\n } catch {\n // Vite env not available\n }\n\n return undefined;\n}\n\n/**\n * Create a typed feature flag checker from a config's FeatureFlagKeys.\n *\n * @example\n * ```tsx\n * import { createFeatureFlagChecker } from '@smooai/config/client';\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":";AAsBO,SAAS,iBAAiB,KAAqB;AAClD,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;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,qBAAqB,MAAM,EAAE,IAAI;AAClG,MAAI,cAAc,QAAW;AACzB,WAAO,cAAc,UAAU,cAAc;AAAA,EACjD;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,qBAAqB,MAAM,EAAE;AAC5D,QAAI,iBAAiB,QAAW;AAC5B,aAAO,iBAAiB,UAAU,iBAAiB;AAAA,IACvD;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,sBAAsB,KAAiC;AACnE,QAAM,SAAS,iBAAiB,GAAG;AAGnC,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,sBAAsB,MAAM,EAAE,IAAI;AACnG,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,eAAe,MAAM,EAAE,IAAI;AAC5F,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,eAAe,MAAM,EAAE;AACtD,QAAI,iBAAiB,QAAW;AAC5B,aAAO;AAAA,IACX;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,2BAA2F;AACvG,SAAO,CAAC,QAAoB,qBAAqB,GAAa;AAClE;","names":[]}
@@ -0,0 +1,14 @@
1
+ import {
2
+ createFeatureFlagChecker,
3
+ getClientFeatureFlag,
4
+ getClientPublicConfig,
5
+ toUpperSnakeCase
6
+ } from "../chunk-YMNAMX6Y.mjs";
7
+ import "../chunk-J5LGTIGS.mjs";
8
+ export {
9
+ createFeatureFlagChecker,
10
+ getClientFeatureFlag,
11
+ getClientPublicConfig,
12
+ toUpperSnakeCase
13
+ };
14
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,28 +1,8 @@
1
+ import {
2
+ createFeatureFlagChecker,
3
+ getClientFeatureFlag
4
+ } from "../chunk-YMNAMX6Y.mjs";
1
5
  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
6
  export {
27
7
  createFeatureFlagChecker,
28
8
  getClientFeatureFlag
@@ -1 +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":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  findAndProcessEnvConfig
3
- } from "./chunk-PCXGCPWC.mjs";
3
+ } from "./chunk-6XDO5B2T.mjs";
4
4
  import {
5
5
  findAndProcessFileConfig
6
- } from "./chunk-7GMXNAVA.mjs";
6
+ } from "./chunk-PD2SHA7M.mjs";
7
7
 
8
8
  // src/platform/server/server.async.ts
9
9
  import TTLCache from "@isaacs/ttlcache";
@@ -115,4 +115,4 @@ function buildConfigObject(configSchema) {
115
115
  export {
116
116
  buildConfigObject
117
117
  };
118
- //# sourceMappingURL=chunk-2DYBQ6SF.mjs.map
118
+ //# sourceMappingURL=chunk-43SVVFYE.mjs.map
@@ -1,17 +1,17 @@
1
- import {
2
- generateZodSchemas,
3
- parseConfigKey
4
- } from "./chunk-JAEJOSH5.mjs";
5
- import {
6
- PublicConfigKey
7
- } from "./chunk-CASNDTCH.mjs";
8
1
  import {
9
2
  getCloudRegion
10
3
  } from "./chunk-5J6U77AV.mjs";
4
+ import {
5
+ generateZodSchemas,
6
+ parseConfigKey
7
+ } from "./chunk-NF7JF2UP.mjs";
11
8
  import {
12
9
  envToUse,
13
10
  initEsmUtils
14
11
  } from "./chunk-UWV4ZGVI.mjs";
12
+ import {
13
+ PublicConfigKey
14
+ } from "./chunk-CASNDTCH.mjs";
15
15
 
16
16
  // src/config/findAndProcessEnvConfig.ts
17
17
  import Logger from "@smooai/logger/Logger";
@@ -68,4 +68,4 @@ function setBuiltInConfig(config, {
68
68
  export {
69
69
  findAndProcessEnvConfig
70
70
  };
71
- //# sourceMappingURL=chunk-PCXGCPWC.mjs.map
71
+ //# sourceMappingURL=chunk-6XDO5B2T.mjs.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  standardSchemaToJson
3
3
  } from "./chunk-LPEA3TRJ.mjs";
4
- import {
5
- PublicConfigKey
6
- } from "./chunk-CASNDTCH.mjs";
7
4
  import {
8
5
  SmooaiConfigError,
9
6
  convertKeyToUpperSnakeCase
10
7
  } from "./chunk-UWV4ZGVI.mjs";
8
+ import {
9
+ PublicConfigKey
10
+ } from "./chunk-CASNDTCH.mjs";
11
11
  import {
12
12
  __export
13
13
  } from "./chunk-J5LGTIGS.mjs";
@@ -12191,4 +12191,4 @@ export {
12191
12191
  generateConfigSchema,
12192
12192
  defineConfig
12193
12193
  };
12194
- //# sourceMappingURL=chunk-7CCXEKIK.mjs.map
12194
+ //# sourceMappingURL=chunk-H4YT7JJJ.mjs.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  deserializeConfigSchema,
3
3
  generateConfigSchema
4
- } from "./chunk-7CCXEKIK.mjs";
4
+ } from "./chunk-H4YT7JJJ.mjs";
5
5
 
6
6
  // src/config/parseConfigSchema.ts
7
7
  import { handleSchemaValidationSync } from "@smooai/utils/validation/standardSchema";
@@ -30,4 +30,4 @@ export {
30
30
  parseConfig,
31
31
  parseConfigKey
32
32
  };
33
- //# sourceMappingURL=chunk-JAEJOSH5.mjs.map
33
+ //# sourceMappingURL=chunk-NF7JF2UP.mjs.map
@@ -1,26 +1,26 @@
1
- import {
2
- mergeReplaceArrays
3
- } from "./chunk-VLAIJ4S7.mjs";
4
1
  import {
5
2
  directoryExists,
6
3
  importFile
7
4
  } from "./chunk-XKVOJHYW.mjs";
8
5
  import {
9
- generateZodSchemas,
10
- parseConfig,
11
- parseConfigKey
12
- } from "./chunk-JAEJOSH5.mjs";
13
- import {
14
- PublicConfigKey
15
- } from "./chunk-CASNDTCH.mjs";
6
+ mergeReplaceArrays
7
+ } from "./chunk-VLAIJ4S7.mjs";
16
8
  import {
17
9
  getCloudRegion
18
10
  } from "./chunk-5J6U77AV.mjs";
11
+ import {
12
+ generateZodSchemas,
13
+ parseConfig,
14
+ parseConfigKey
15
+ } from "./chunk-NF7JF2UP.mjs";
19
16
  import {
20
17
  SmooaiConfigError,
21
18
  envToUse,
22
19
  initEsmUtils
23
20
  } from "./chunk-UWV4ZGVI.mjs";
21
+ import {
22
+ PublicConfigKey
23
+ } from "./chunk-CASNDTCH.mjs";
24
24
 
25
25
  // src/config/findAndProcessFileConfig.ts
26
26
  import { join } from "path";
@@ -170,4 +170,4 @@ export {
170
170
  findConfigDirectory,
171
171
  findAndProcessFileConfig
172
172
  };
173
- //# sourceMappingURL=chunk-7GMXNAVA.mjs.map
173
+ //# sourceMappingURL=chunk-PD2SHA7M.mjs.map
@@ -4,7 +4,7 @@ import {
4
4
  StringSchema,
5
5
  defineConfig,
6
6
  external_exports
7
- } from "./chunk-7CCXEKIK.mjs";
7
+ } from "./chunk-H4YT7JJJ.mjs";
8
8
 
9
9
  // src/integration-tests/2/smooai-config/config.ts
10
10
  var config_default = defineConfig({
@@ -34,4 +34,4 @@ var config_default = defineConfig({
34
34
  export {
35
35
  config_default
36
36
  };
37
- //# sourceMappingURL=chunk-2CD4ZQFH.mjs.map
37
+ //# sourceMappingURL=chunk-R7NMFJFJ.mjs.map
@@ -0,0 +1,40 @@
1
+ // src/nextjs/withSmooConfig.ts
2
+ function toUpperSnakeCase(key) {
3
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
4
+ }
5
+ function withSmooConfig(options, nextConfig = {}) {
6
+ const stage = process.env.NEXT_PUBLIC_SST_STAGE ?? (process.env.NODE_ENV === "production" ? "production" : "development");
7
+ const defaultValues = options.default ?? {};
8
+ const stageOverrides = options[stage] ?? {};
9
+ const resolvedFlags = {
10
+ ...defaultValues.featureFlags,
11
+ ...stageOverrides.featureFlags
12
+ };
13
+ const resolvedConfig = {
14
+ ...defaultValues.publicConfig,
15
+ ...stageOverrides.publicConfig
16
+ };
17
+ const env = {};
18
+ for (const [key, value] of Object.entries(resolvedFlags)) {
19
+ const envKey = `NEXT_PUBLIC_FEATURE_FLAG_${toUpperSnakeCase(key)}`;
20
+ env[envKey] = String(value);
21
+ process.env[envKey] = String(value);
22
+ }
23
+ for (const [key, value] of Object.entries(resolvedConfig)) {
24
+ const envKey = `NEXT_PUBLIC_CONFIG_${toUpperSnakeCase(key)}`;
25
+ env[envKey] = String(value);
26
+ process.env[envKey] = String(value);
27
+ }
28
+ return {
29
+ ...nextConfig,
30
+ env: {
31
+ ...nextConfig.env,
32
+ ...env
33
+ }
34
+ };
35
+ }
36
+
37
+ export {
38
+ withSmooConfig
39
+ };
40
+ //# sourceMappingURL=chunk-SAX775JO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/nextjs/withSmooConfig.ts"],"sourcesContent":["/**\n * Next.js config helper that injects feature flags AND public config\n * as NEXT_PUBLIC_ environment variables.\n *\n * This is the unified replacement for `withFeatureFlags`, supporting both\n * feature flags (NEXT_PUBLIC_FEATURE_FLAG_*) and public config values\n * (NEXT_PUBLIC_CONFIG_*).\n *\n * @example\n * ```ts\n * // next.config.ts\n * import { withSmooConfig } from '@smooai/config/nextjs/withSmooConfig';\n *\n * const nextConfig = withSmooConfig({\n * default: {\n * featureFlags: { aboutPage: false, contactPage: true },\n * publicConfig: { apiBaseUrl: 'https://api.smooai.com', maxRetries: 3 },\n * },\n * development: {\n * featureFlags: { aboutPage: true },\n * publicConfig: { apiBaseUrl: 'http://localhost:3000' },\n * },\n * });\n *\n * export default nextConfig;\n * ```\n *\n * This will set environment variables like:\n * - NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE=true (in development)\n * - NEXT_PUBLIC_CONFIG_API_BASE_URL=http://localhost:3000 (in development)\n *\n * Then in any client component:\n * ```tsx\n * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';\n * const isEnabled = getClientFeatureFlag('aboutPage');\n * const apiUrl = getClientPublicConfig('apiBaseUrl');\n * ```\n */\n\ntype NextConfig = Record<string, unknown>;\n\nexport interface SmooConfigValues {\n /** Feature flag values (boolean). */\n featureFlags?: Record<string, boolean>;\n /** Public config values (string, number, or boolean). */\n publicConfig?: Record<string, string | number | boolean>;\n}\n\nexport interface WithSmooConfigOptions {\n /** Default config values (used in production). */\n default: SmooConfigValues;\n /** Development overrides (merged with default). */\n development?: SmooConfigValues;\n /** Additional stage-specific overrides. Key is the stage name. */\n [stage: string]: SmooConfigValues | undefined;\n}\n\n/**\n * Convert a camelCase 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 * Wraps a Next.js config to inject feature flags and public config\n * as NEXT_PUBLIC_ environment variables.\n *\n * Reads `NEXT_PUBLIC_SST_STAGE` (or `NODE_ENV`) to determine which config to use.\n * Falls back to development config if stage is not 'production'.\n */\nexport function withSmooConfig(options: WithSmooConfigOptions, nextConfig: NextConfig = {}): NextConfig {\n const stage = process.env.NEXT_PUBLIC_SST_STAGE ?? (process.env.NODE_ENV === 'production' ? 'production' : 'development');\n\n // Merge default with stage-specific overrides\n const defaultValues = options.default ?? {};\n const stageOverrides = options[stage] ?? {};\n\n const resolvedFlags: Record<string, boolean> = {\n ...defaultValues.featureFlags,\n ...stageOverrides.featureFlags,\n };\n\n const resolvedConfig: Record<string, string | number | boolean> = {\n ...defaultValues.publicConfig,\n ...stageOverrides.publicConfig,\n };\n\n // Inject as NEXT_PUBLIC_ env vars\n const env: Record<string, string> = {};\n\n // Feature flags → NEXT_PUBLIC_FEATURE_FLAG_*\n for (const [key, value] of Object.entries(resolvedFlags)) {\n const envKey = `NEXT_PUBLIC_FEATURE_FLAG_${toUpperSnakeCase(key)}`;\n env[envKey] = String(value);\n // Also set in process.env for SSR\n process.env[envKey] = String(value);\n }\n\n // Public config → NEXT_PUBLIC_CONFIG_*\n for (const [key, value] of Object.entries(resolvedConfig)) {\n const envKey = `NEXT_PUBLIC_CONFIG_${toUpperSnakeCase(key)}`;\n env[envKey] = String(value);\n // Also set in process.env for SSR\n process.env[envKey] = String(value);\n }\n\n return {\n ...nextConfig,\n env: {\n ...(nextConfig.env as Record<string, string> | undefined),\n ...env,\n },\n };\n}\n"],"mappings":";AA6DA,SAAS,iBAAiB,KAAqB;AAC3C,SAAO,IAAI,QAAQ,YAAY,KAAK,EAAE,YAAY;AACtD;AASO,SAAS,eAAe,SAAgC,aAAyB,CAAC,GAAe;AACpG,QAAM,QAAQ,QAAQ,IAAI,0BAA0B,QAAQ,IAAI,aAAa,eAAe,eAAe;AAG3G,QAAM,gBAAgB,QAAQ,WAAW,CAAC;AAC1C,QAAM,iBAAiB,QAAQ,KAAK,KAAK,CAAC;AAE1C,QAAM,gBAAyC;AAAA,IAC3C,GAAG,cAAc;AAAA,IACjB,GAAG,eAAe;AAAA,EACtB;AAEA,QAAM,iBAA4D;AAAA,IAC9D,GAAG,cAAc;AAAA,IACjB,GAAG,eAAe;AAAA,EACtB;AAGA,QAAM,MAA8B,CAAC;AAGrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACtD,UAAM,SAAS,4BAA4B,iBAAiB,GAAG,CAAC;AAChE,QAAI,MAAM,IAAI,OAAO,KAAK;AAE1B,YAAQ,IAAI,MAAM,IAAI,OAAO,KAAK;AAAA,EACtC;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACvD,UAAM,SAAS,sBAAsB,iBAAiB,GAAG,CAAC;AAC1D,QAAI,MAAM,IAAI,OAAO,KAAK;AAE1B,YAAQ,IAAI,MAAM,IAAI,OAAO,KAAK;AAAA,EACtC;AAEA,SAAO;AAAA,IACH,GAAG;AAAA,IACH,KAAK;AAAA,MACD,GAAI,WAAW;AAAA,MACf,GAAG;AAAA,IACP;AAAA,EACJ;AACJ;","names":[]}
@@ -0,0 +1,55 @@
1
+ // src/client/index.ts
2
+ function toUpperSnakeCase(key) {
3
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
4
+ }
5
+ function getClientFeatureFlag(key) {
6
+ const envKey = toUpperSnakeCase(key);
7
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : void 0;
8
+ if (nextValue !== void 0) {
9
+ return nextValue === "true" || nextValue === "1";
10
+ }
11
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : void 0;
12
+ if (viteValue !== void 0) {
13
+ return viteValue === "true" || viteValue === "1";
14
+ }
15
+ try {
16
+ const viteEnv = globalThis.__VITE_ENV__;
17
+ const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];
18
+ if (viteEnvValue !== void 0) {
19
+ return viteEnvValue === "true" || viteEnvValue === "1";
20
+ }
21
+ } catch {
22
+ }
23
+ return false;
24
+ }
25
+ function getClientPublicConfig(key) {
26
+ const envKey = toUpperSnakeCase(key);
27
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : void 0;
28
+ if (nextValue !== void 0) {
29
+ return nextValue;
30
+ }
31
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_CONFIG_${envKey}`] : void 0;
32
+ if (viteValue !== void 0) {
33
+ return viteValue;
34
+ }
35
+ try {
36
+ const viteEnv = globalThis.__VITE_ENV__;
37
+ const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];
38
+ if (viteEnvValue !== void 0) {
39
+ return viteEnvValue;
40
+ }
41
+ } catch {
42
+ }
43
+ return void 0;
44
+ }
45
+ function createFeatureFlagChecker() {
46
+ return (key) => getClientFeatureFlag(key);
47
+ }
48
+
49
+ export {
50
+ toUpperSnakeCase,
51
+ getClientFeatureFlag,
52
+ getClientPublicConfig,
53
+ createFeatureFlagChecker
54
+ };
55
+ //# sourceMappingURL=chunk-UCFP2MA2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/index.ts"],"sourcesContent":["/**\n * Universal client-safe config readers.\n *\n * Reads from both `NEXT_PUBLIC_` and `VITE_` prefixed env vars,\n * allowing the same code to work in Next.js and Vite environments.\n *\n * @example\n * ```tsx\n * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';\n *\n * if (getClientFeatureFlag('aboutPage')) {\n * // show the feature\n * }\n *\n * const apiUrl = getClientPublicConfig('apiBaseUrl');\n * ```\n */\n\n/**\n * Convert a camelCase key to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" → \"ABOUT_PAGE\"\n */\nexport function 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\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue === 'true' || viteValue === '1';\n }\n\n // Check Vite import.meta.env fallback (available via globalThis in some setups)\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue === 'true' || viteEnvValue === '1';\n }\n } catch {\n // Vite env not available\n }\n\n return false;\n}\n\n/**\n * Get a public config value from build-time environment variables.\n *\n * Checks for:\n * 1. NEXT_PUBLIC_CONFIG_{KEY} (Next.js)\n * 2. VITE_CONFIG_{KEY} (Vite)\n *\n * The key is converted from camelCase to UPPER_SNAKE_CASE.\n * e.g., \"apiBaseUrl\" checks NEXT_PUBLIC_CONFIG_API_BASE_URL\n *\n * @param key - The camelCase config key\n * @returns The config value as a string, or undefined if not set\n */\nexport function getClientPublicConfig(key: string): string | undefined {\n const envKey = toUpperSnakeCase(key);\n\n // Check Next.js env var\n const nextValue = typeof process !== 'undefined' ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : undefined;\n if (nextValue !== undefined) {\n return nextValue;\n }\n\n // Check Vite env var\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_CONFIG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue;\n }\n\n // Check Vite import.meta.env fallback\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue;\n }\n } catch {\n // Vite env not available\n }\n\n return undefined;\n}\n\n/**\n * Create a typed feature flag checker from a config's FeatureFlagKeys.\n *\n * @example\n * ```tsx\n * import { createFeatureFlagChecker } from '@smooai/config/client';\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":";AAsBO,SAAS,iBAAiB,KAAqB;AAClD,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;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,qBAAqB,MAAM,EAAE,IAAI;AAClG,MAAI,cAAc,QAAW;AACzB,WAAO,cAAc,UAAU,cAAc;AAAA,EACjD;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,qBAAqB,MAAM,EAAE;AAC5D,QAAI,iBAAiB,QAAW;AAC5B,aAAO,iBAAiB,UAAU,iBAAiB;AAAA,IACvD;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,sBAAsB,KAAiC;AACnE,QAAM,SAAS,iBAAiB,GAAG;AAGnC,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,sBAAsB,MAAM,EAAE,IAAI;AACnG,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,eAAe,MAAM,EAAE,IAAI;AAC5F,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,eAAe,MAAM,EAAE;AACtD,QAAI,iBAAiB,QAAW;AAC5B,aAAO;AAAA,IACX;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,2BAA2F;AACvG,SAAO,CAAC,QAAoB,qBAAqB,GAAa;AAClE;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  StringSchema,
5
5
  defineConfig,
6
6
  external_exports
7
- } from "./chunk-7CCXEKIK.mjs";
7
+ } from "./chunk-H4YT7JJJ.mjs";
8
8
 
9
9
  // src/integration-tests/1/smooai-config/config.ts
10
10
  var config_default = defineConfig({
@@ -86,4 +86,4 @@ var config_default = defineConfig({
86
86
  export {
87
87
  config_default
88
88
  };
89
- //# sourceMappingURL=chunk-4RYDS2HX.mjs.map
89
+ //# sourceMappingURL=chunk-UEIVAJKL.mjs.map
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Universal client-safe config readers.
3
+ *
4
+ * Reads from both `NEXT_PUBLIC_` and `VITE_` prefixed env vars,
5
+ * allowing the same code to work in Next.js and Vite environments.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';
10
+ *
11
+ * if (getClientFeatureFlag('aboutPage')) {
12
+ * // show the feature
13
+ * }
14
+ *
15
+ * const apiUrl = getClientPublicConfig('apiBaseUrl');
16
+ * ```
17
+ */
18
+ /**
19
+ * Convert a camelCase key to UPPER_SNAKE_CASE.
20
+ * e.g., "aboutPage" → "ABOUT_PAGE"
21
+ */
22
+ declare function toUpperSnakeCase(key: string): string;
23
+ /**
24
+ * Get a feature flag value from build-time environment variables.
25
+ *
26
+ * Checks for:
27
+ * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)
28
+ * 2. VITE_FEATURE_FLAG_{KEY} (Vite)
29
+ *
30
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
31
+ * e.g., "aboutPage" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE
32
+ *
33
+ * @param key - The camelCase feature flag key
34
+ * @returns true if the flag is explicitly set to "true", false otherwise
35
+ */
36
+ declare function getClientFeatureFlag(key: string): boolean;
37
+ /**
38
+ * Get a public config value from build-time environment variables.
39
+ *
40
+ * Checks for:
41
+ * 1. NEXT_PUBLIC_CONFIG_{KEY} (Next.js)
42
+ * 2. VITE_CONFIG_{KEY} (Vite)
43
+ *
44
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
45
+ * e.g., "apiBaseUrl" checks NEXT_PUBLIC_CONFIG_API_BASE_URL
46
+ *
47
+ * @param key - The camelCase config key
48
+ * @returns The config value as a string, or undefined if not set
49
+ */
50
+ declare function getClientPublicConfig(key: string): string | undefined;
51
+ /**
52
+ * Create a typed feature flag checker from a config's FeatureFlagKeys.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { createFeatureFlagChecker } from '@smooai/config/client';
57
+ *
58
+ * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();
59
+ *
60
+ * // Usage:
61
+ * getFeatureFlag('aboutPage') // typed to valid keys
62
+ * ```
63
+ */
64
+ declare function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean;
65
+
66
+ export { createFeatureFlagChecker, getClientFeatureFlag, getClientPublicConfig, toUpperSnakeCase };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Universal client-safe config readers.
3
+ *
4
+ * Reads from both `NEXT_PUBLIC_` and `VITE_` prefixed env vars,
5
+ * allowing the same code to work in Next.js and Vite environments.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';
10
+ *
11
+ * if (getClientFeatureFlag('aboutPage')) {
12
+ * // show the feature
13
+ * }
14
+ *
15
+ * const apiUrl = getClientPublicConfig('apiBaseUrl');
16
+ * ```
17
+ */
18
+ /**
19
+ * Convert a camelCase key to UPPER_SNAKE_CASE.
20
+ * e.g., "aboutPage" → "ABOUT_PAGE"
21
+ */
22
+ declare function toUpperSnakeCase(key: string): string;
23
+ /**
24
+ * Get a feature flag value from build-time environment variables.
25
+ *
26
+ * Checks for:
27
+ * 1. NEXT_PUBLIC_FEATURE_FLAG_{KEY} (Next.js)
28
+ * 2. VITE_FEATURE_FLAG_{KEY} (Vite)
29
+ *
30
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
31
+ * e.g., "aboutPage" checks NEXT_PUBLIC_FEATURE_FLAG_ABOUT_PAGE
32
+ *
33
+ * @param key - The camelCase feature flag key
34
+ * @returns true if the flag is explicitly set to "true", false otherwise
35
+ */
36
+ declare function getClientFeatureFlag(key: string): boolean;
37
+ /**
38
+ * Get a public config value from build-time environment variables.
39
+ *
40
+ * Checks for:
41
+ * 1. NEXT_PUBLIC_CONFIG_{KEY} (Next.js)
42
+ * 2. VITE_CONFIG_{KEY} (Vite)
43
+ *
44
+ * The key is converted from camelCase to UPPER_SNAKE_CASE.
45
+ * e.g., "apiBaseUrl" checks NEXT_PUBLIC_CONFIG_API_BASE_URL
46
+ *
47
+ * @param key - The camelCase config key
48
+ * @returns The config value as a string, or undefined if not set
49
+ */
50
+ declare function getClientPublicConfig(key: string): string | undefined;
51
+ /**
52
+ * Create a typed feature flag checker from a config's FeatureFlagKeys.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { createFeatureFlagChecker } from '@smooai/config/client';
57
+ *
58
+ * export const getFeatureFlag = createFeatureFlagChecker<typeof FeatureFlagKeys>();
59
+ *
60
+ * // Usage:
61
+ * getFeatureFlag('aboutPage') // typed to valid keys
62
+ * ```
63
+ */
64
+ declare function createFeatureFlagChecker<T extends Record<string, string>>(): (key: T[keyof T]) => boolean;
65
+
66
+ export { createFeatureFlagChecker, getClientFeatureFlag, getClientPublicConfig, toUpperSnakeCase };
@@ -0,0 +1,82 @@
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/client/index.ts
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ createFeatureFlagChecker: () => createFeatureFlagChecker,
24
+ getClientFeatureFlag: () => getClientFeatureFlag,
25
+ getClientPublicConfig: () => getClientPublicConfig,
26
+ toUpperSnakeCase: () => toUpperSnakeCase
27
+ });
28
+ module.exports = __toCommonJS(client_exports);
29
+ function toUpperSnakeCase(key) {
30
+ return key.replace(/([A-Z])/g, "_$1").toUpperCase();
31
+ }
32
+ function getClientFeatureFlag(key) {
33
+ const envKey = toUpperSnakeCase(key);
34
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_FEATURE_FLAG_${envKey}`] : void 0;
35
+ if (nextValue !== void 0) {
36
+ return nextValue === "true" || nextValue === "1";
37
+ }
38
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : void 0;
39
+ if (viteValue !== void 0) {
40
+ return viteValue === "true" || viteValue === "1";
41
+ }
42
+ try {
43
+ const viteEnv = globalThis.__VITE_ENV__;
44
+ const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];
45
+ if (viteEnvValue !== void 0) {
46
+ return viteEnvValue === "true" || viteEnvValue === "1";
47
+ }
48
+ } catch {
49
+ }
50
+ return false;
51
+ }
52
+ function getClientPublicConfig(key) {
53
+ const envKey = toUpperSnakeCase(key);
54
+ const nextValue = typeof process !== "undefined" ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : void 0;
55
+ if (nextValue !== void 0) {
56
+ return nextValue;
57
+ }
58
+ const viteValue = typeof process !== "undefined" ? process.env?.[`VITE_CONFIG_${envKey}`] : void 0;
59
+ if (viteValue !== void 0) {
60
+ return viteValue;
61
+ }
62
+ try {
63
+ const viteEnv = globalThis.__VITE_ENV__;
64
+ const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];
65
+ if (viteEnvValue !== void 0) {
66
+ return viteEnvValue;
67
+ }
68
+ } catch {
69
+ }
70
+ return void 0;
71
+ }
72
+ function createFeatureFlagChecker() {
73
+ return (key) => getClientFeatureFlag(key);
74
+ }
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ createFeatureFlagChecker,
78
+ getClientFeatureFlag,
79
+ getClientPublicConfig,
80
+ toUpperSnakeCase
81
+ });
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/index.ts"],"sourcesContent":["/**\n * Universal client-safe config readers.\n *\n * Reads from both `NEXT_PUBLIC_` and `VITE_` prefixed env vars,\n * allowing the same code to work in Next.js and Vite environments.\n *\n * @example\n * ```tsx\n * import { getClientFeatureFlag, getClientPublicConfig } from '@smooai/config/client';\n *\n * if (getClientFeatureFlag('aboutPage')) {\n * // show the feature\n * }\n *\n * const apiUrl = getClientPublicConfig('apiBaseUrl');\n * ```\n */\n\n/**\n * Convert a camelCase key to UPPER_SNAKE_CASE.\n * e.g., \"aboutPage\" → \"ABOUT_PAGE\"\n */\nexport function 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\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_FEATURE_FLAG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue === 'true' || viteValue === '1';\n }\n\n // Check Vite import.meta.env fallback (available via globalThis in some setups)\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_FEATURE_FLAG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue === 'true' || viteEnvValue === '1';\n }\n } catch {\n // Vite env not available\n }\n\n return false;\n}\n\n/**\n * Get a public config value from build-time environment variables.\n *\n * Checks for:\n * 1. NEXT_PUBLIC_CONFIG_{KEY} (Next.js)\n * 2. VITE_CONFIG_{KEY} (Vite)\n *\n * The key is converted from camelCase to UPPER_SNAKE_CASE.\n * e.g., \"apiBaseUrl\" checks NEXT_PUBLIC_CONFIG_API_BASE_URL\n *\n * @param key - The camelCase config key\n * @returns The config value as a string, or undefined if not set\n */\nexport function getClientPublicConfig(key: string): string | undefined {\n const envKey = toUpperSnakeCase(key);\n\n // Check Next.js env var\n const nextValue = typeof process !== 'undefined' ? process.env?.[`NEXT_PUBLIC_CONFIG_${envKey}`] : undefined;\n if (nextValue !== undefined) {\n return nextValue;\n }\n\n // Check Vite env var\n const viteValue = typeof process !== 'undefined' ? process.env?.[`VITE_CONFIG_${envKey}`] : undefined;\n if (viteValue !== undefined) {\n return viteValue;\n }\n\n // Check Vite import.meta.env fallback\n try {\n const viteEnv = (globalThis as Record<string, unknown>).__VITE_ENV__ as Record<string, string> | undefined;\n const viteEnvValue = viteEnv?.[`VITE_CONFIG_${envKey}`];\n if (viteEnvValue !== undefined) {\n return viteEnvValue;\n }\n } catch {\n // Vite env not available\n }\n\n return undefined;\n}\n\n/**\n * Create a typed feature flag checker from a config's FeatureFlagKeys.\n *\n * @example\n * ```tsx\n * import { createFeatureFlagChecker } from '@smooai/config/client';\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;AAAA;AAAA;AAsBO,SAAS,iBAAiB,KAAqB;AAClD,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;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,qBAAqB,MAAM,EAAE,IAAI;AAClG,MAAI,cAAc,QAAW;AACzB,WAAO,cAAc,UAAU,cAAc;AAAA,EACjD;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,qBAAqB,MAAM,EAAE;AAC5D,QAAI,iBAAiB,QAAW;AAC5B,aAAO,iBAAiB,UAAU,iBAAiB;AAAA,IACvD;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,sBAAsB,KAAiC;AACnE,QAAM,SAAS,iBAAiB,GAAG;AAGnC,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,sBAAsB,MAAM,EAAE,IAAI;AACnG,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,QAAM,YAAY,OAAO,YAAY,cAAc,QAAQ,MAAM,eAAe,MAAM,EAAE,IAAI;AAC5F,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AAGA,MAAI;AACA,UAAM,UAAW,WAAuC;AACxD,UAAM,eAAe,UAAU,eAAe,MAAM,EAAE;AACtD,QAAI,iBAAiB,QAAW;AAC5B,aAAO;AAAA,IACX;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAeO,SAAS,2BAA2F;AACvG,SAAO,CAAC,QAAoB,qBAAqB,GAAa;AAClE;","names":[]}