@danceroutine/tango-config 0.1.0 → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Pedro Del Moral Lopez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # @danceroutine/tango-config
2
+
3
+ `@danceroutine/tango-config` provides typed, validated application configuration for server-side TypeScript projects.
4
+
5
+ Tango applications use this package to work with your project's `tango.config.ts`, which serves a similar function to the Django settings module in Django, giving application runtime code one place to read database and migration settings, and gives the `tango` CLI the same source of truth when it infers migration defaults.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @danceroutine/tango-config
11
+ ```
12
+
13
+ `defineConfig()` declares and validates the configuration contract. `loadConfig()` resolves the active environment, loads `.env`, and merges supported Tango environment overrides into the selected environment. The separation keeps configuration declaration and runtime resolution distinct, which makes startup behavior easier to reason about.
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { defineConfig, loadConfig } from '@danceroutine/tango-config';
19
+
20
+ const config = defineConfig({
21
+ current: 'development',
22
+ environments: {
23
+ development: {
24
+ name: 'development',
25
+ db: { adapter: 'sqlite', filename: 'dev.sqlite' },
26
+ migrations: { dir: 'migrations', online: false },
27
+ },
28
+ test: {
29
+ name: 'test',
30
+ db: { adapter: 'sqlite', filename: ':memory:' },
31
+ migrations: { dir: 'migrations', online: false },
32
+ },
33
+ production: {
34
+ name: 'production',
35
+ db: { adapter: 'postgres', url: process.env.DATABASE_URL },
36
+ migrations: { dir: 'migrations', online: true },
37
+ },
38
+ },
39
+ });
40
+
41
+ const loaded = loadConfig(() => config);
42
+ ```
43
+
44
+ The loaded result is ready for application startup. `loadConfig()` returns the selected environment as `loaded.current`, so application code usually reads `loaded.current.db` and `loaded.current.migrations` directly when it creates database clients or wires migration commands.
45
+
46
+ ## `tango.config.ts`
47
+
48
+ The usual place to use this package is a project-root `tango.config.ts` file:
49
+
50
+ ```ts
51
+ import { defineConfig } from '@danceroutine/tango-config';
52
+
53
+ export default defineConfig({
54
+ current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',
55
+ environments: {
56
+ development: {
57
+ name: 'development',
58
+ db: {
59
+ adapter: 'sqlite',
60
+ filename: './.data/app.sqlite',
61
+ maxConnections: 1,
62
+ },
63
+ migrations: { dir: './migrations', online: false },
64
+ },
65
+ test: {
66
+ name: 'test',
67
+ db: {
68
+ adapter: 'sqlite',
69
+ filename: ':memory:',
70
+ maxConnections: 1,
71
+ },
72
+ migrations: { dir: './migrations', online: false },
73
+ },
74
+ production: {
75
+ name: 'production',
76
+ db: {
77
+ adapter: 'postgres',
78
+ url: process.env.TANGO_DATABASE_URL,
79
+ maxConnections: 20,
80
+ },
81
+ migrations: { dir: './migrations', online: true },
82
+ },
83
+ },
84
+ });
85
+ ```
86
+
87
+ Application code can then resolve the active environment like this:
88
+
89
+ ```ts
90
+ import { loadConfig } from '@danceroutine/tango-config';
91
+ import tangoConfig from '../tango.config';
92
+
93
+ const loadedConfig = loadConfig(() => tangoConfig);
94
+ const db = loadedConfig.current.db;
95
+ ```
96
+
97
+ ## Environment overrides
98
+
99
+ `loadConfig()` supports environment-driven overrides for Tango database and migration settings, including values such as:
100
+
101
+ - `TANGO_DB_ADAPTER`
102
+ - `TANGO_DATABASE_URL`
103
+ - `TANGO_DB_HOST`, `TANGO_DB_PORT`, `TANGO_DB_NAME`, `TANGO_DB_USER`, `TANGO_DB_PASSWORD`
104
+ - `TANGO_SQLITE_FILENAME`
105
+ - `TANGO_MIGRATIONS_DIR`
106
+ - `TANGO_MIGRATIONS_ONLINE`
107
+
108
+ These overrides are useful when the same application configuration needs to run in local development, CI, and production with different infrastructure values.
109
+
110
+ ## Public API
111
+
112
+ The root export includes `defineConfig()`, `loadConfig()`, `LoadedConfig`, the core configuration types, and the Zod schemas for Tango config, environments, databases, and migrations.
113
+
114
+ The root export is enough for most applications. The `schema` and `loader` subpaths are available when you want a narrower import boundary in application code or tooling.
115
+
116
+ ## Documentation
117
+
118
+ - Official documentation: <https://tangowebframework.dev>
119
+ - Config API: <https://tangowebframework.dev/reference/config-api>
120
+ - Installation guide: <https://tangowebframework.dev/guide/installation>
121
+ - Configure databases: <https://tangowebframework.dev/how-to/databases>
122
+
123
+ ## Development
124
+
125
+ ```bash
126
+ pnpm --filter @danceroutine/tango-config build
127
+ pnpm --filter @danceroutine/tango-config typecheck
128
+ pnpm --filter @danceroutine/tango-config test
129
+ ```
130
+
131
+ For the wider contributor workflow, use:
132
+
133
+ - <https://tangowebframework.dev/contributing>
134
+
135
+ ## License
136
+
137
+ MIT
package/dist/index.d.ts CHANGED
@@ -4,6 +4,6 @@
4
4
  */
5
5
  export * as schema from './schema/index';
6
6
  export * as loader from './loader/index';
7
- export { defineConfig, loadConfig, type LoadedConfig } from './loader/index';
7
+ export { defineConfig, loadConfig, loadConfigFromProjectRoot, type LoadedConfig, type ProjectConfigLoadOptions, } from './loader/index';
8
8
  export type { AdapterName, DbConfig, EnvConfig, EnvName, MigrationsConfig, TangoConfig } from './schema/index';
9
9
  export { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, } from './schema/index';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, schema_exports } from "./schema-D6LCZS5E.js";
2
- import { defineConfig, loadConfig, loader_exports } from "./loader-De9vxa5D.js";
1
+ import { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, schema_exports } from "./schema-VrnHv-I7.js";
2
+ import { defineConfig, loadConfig, loadConfigFromProjectRoot, loader_exports } from "./loader-D5ezTVNH.js";
3
3
 
4
- export { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, defineConfig, loadConfig, loader_exports as loader, schema_exports as schema };
4
+ export { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, defineConfig, loadConfig, loadConfigFromProjectRoot, loader_exports as loader, schema_exports as schema };
@@ -1,4 +1,7 @@
1
1
  import type { EnvConfig, EnvName, TangoConfig } from '../schema/index';
2
+ /**
3
+ * Fully resolved Tango configuration for a specific runtime environment.
4
+ */
2
5
  export interface LoadedConfig {
3
6
  cfg: TangoConfig;
4
7
  env: EnvName;
@@ -1,2 +1,5 @@
1
1
  import { type TangoConfig } from '../schema/index';
2
+ /**
3
+ * Define and validate Tango configuration at declaration time.
4
+ */
2
5
  export declare function defineConfig(cfg: unknown): TangoConfig;
@@ -4,3 +4,5 @@
4
4
  export type { LoadedConfig } from './LoadedConfig';
5
5
  export { defineConfig } from './defineConfig';
6
6
  export { loadConfig } from './loadConfig';
7
+ export { loadConfigFromProjectRoot } from './loadConfigFromProjectRoot';
8
+ export type { ProjectConfigLoadOptions } from './loadConfigFromProjectRoot';
@@ -1,4 +1,4 @@
1
- import "../schema-D6LCZS5E.js";
2
- import { defineConfig, loadConfig } from "../loader-De9vxa5D.js";
1
+ import "../schema-VrnHv-I7.js";
2
+ import { defineConfig, loadConfig, loadConfigFromProjectRoot } from "../loader-D5ezTVNH.js";
3
3
 
4
- export { defineConfig, loadConfig };
4
+ export { defineConfig, loadConfig, loadConfigFromProjectRoot };
@@ -1,2 +1,5 @@
1
1
  import type { LoadedConfig } from './LoadedConfig';
2
+ /**
3
+ * Load, validate, and environment-resolve Tango configuration.
4
+ */
2
5
  export declare function loadConfig(fromFile: () => unknown): LoadedConfig;
@@ -0,0 +1,9 @@
1
+ import type { LoadedConfig } from './LoadedConfig';
2
+ export interface ProjectConfigLoadOptions {
3
+ projectRoot?: string;
4
+ configPath?: string;
5
+ }
6
+ /**
7
+ * Resolve, load, and validate `tango.config.*` from a project root.
8
+ */
9
+ export declare function loadConfigFromProjectRoot(options?: ProjectConfigLoadOptions): LoadedConfig;
@@ -0,0 +1,88 @@
1
+ import { TangoConfigSchema, __export } from "./schema-VrnHv-I7.js";
2
+ import { config as loadDotEnv } from "dotenv";
3
+ import { existsSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import { createJiti } from "jiti";
6
+
7
+ //#region src/loader/defineConfig.ts
8
+ function defineConfig(cfg) {
9
+ return TangoConfigSchema.parse(cfg);
10
+ }
11
+
12
+ //#endregion
13
+ //#region src/loader/loadConfig.ts
14
+ function loadConfig(fromFile) {
15
+ loadDotEnv();
16
+ const cfg = TangoConfigSchema.parse(fromFile());
17
+ const env = cfg.current;
18
+ const current = mergeEnvOverrides(cfg.environments[env]);
19
+ return {
20
+ cfg,
21
+ env,
22
+ current
23
+ };
24
+ }
25
+ /**
26
+ * Merge process environment overrides into a base environment config.
27
+ */
28
+ function mergeEnvOverrides(envCfg) {
29
+ const result = structuredClone(envCfg);
30
+ const env = process.env;
31
+ if (env.TANGO_DB_ADAPTER) result.db.adapter = env.TANGO_DB_ADAPTER;
32
+ if (env.DATABASE_URL || env.TANGO_DATABASE_URL) result.db.url = env.TANGO_DATABASE_URL || env.DATABASE_URL;
33
+ if (env.TANGO_DB_HOST) result.db.host = env.TANGO_DB_HOST;
34
+ if (env.TANGO_DB_PORT) result.db.port = Number(env.TANGO_DB_PORT);
35
+ if (env.TANGO_DB_NAME) result.db.database = env.TANGO_DB_NAME;
36
+ if (env.TANGO_DB_USER) result.db.user = env.TANGO_DB_USER;
37
+ if (env.TANGO_DB_PASSWORD) result.db.password = env.TANGO_DB_PASSWORD;
38
+ if (env.TANGO_SQLITE_FILENAME) result.db.filename = env.TANGO_SQLITE_FILENAME;
39
+ if (env.TANGO_MIGRATIONS_DIR) result.migrations.dir = env.TANGO_MIGRATIONS_DIR;
40
+ if (env.TANGO_MIGRATIONS_ONLINE) result.migrations.online = env.TANGO_MIGRATIONS_ONLINE === "true";
41
+ return result;
42
+ }
43
+
44
+ //#endregion
45
+ //#region src/loader/loadConfigFromProjectRoot.ts
46
+ const DEFAULT_CONFIG_FILENAMES = [
47
+ "tango.config.ts",
48
+ "tango.config.mts",
49
+ "tango.config.cts",
50
+ "tango.config.js",
51
+ "tango.config.mjs",
52
+ "tango.config.cjs"
53
+ ];
54
+ function resolveConfigPath(projectRoot, explicitPath) {
55
+ if (explicitPath) {
56
+ const absolutePath = resolve(projectRoot, explicitPath);
57
+ if (!existsSync(absolutePath)) throw new Error(`Unable to find Tango config at '${absolutePath}'.`);
58
+ return absolutePath;
59
+ }
60
+ for (const filename of DEFAULT_CONFIG_FILENAMES) {
61
+ const absolutePath = resolve(projectRoot, filename);
62
+ if (existsSync(absolutePath)) return absolutePath;
63
+ }
64
+ throw new Error(`Unable to find Tango config in '${projectRoot}'. Expected one of: ${DEFAULT_CONFIG_FILENAMES.join(", ")}.`);
65
+ }
66
+ function loadConfigFromProjectRoot(options = {}) {
67
+ const projectRoot = options.projectRoot ?? process.cwd();
68
+ const configPath = resolveConfigPath(projectRoot, options.configPath);
69
+ const jiti = createJiti(resolve(projectRoot, "package.json"), {
70
+ interopDefault: true,
71
+ moduleCache: true
72
+ });
73
+ const loaded = jiti(configPath);
74
+ return loadConfig(() => loaded);
75
+ }
76
+
77
+ //#endregion
78
+ //#region src/loader/index.ts
79
+ var loader_exports = {};
80
+ __export(loader_exports, {
81
+ defineConfig: () => defineConfig,
82
+ loadConfig: () => loadConfig,
83
+ loadConfigFromProjectRoot: () => loadConfigFromProjectRoot
84
+ });
85
+
86
+ //#endregion
87
+ export { defineConfig, loadConfig, loadConfigFromProjectRoot, loader_exports };
88
+ //# sourceMappingURL=loader-D5ezTVNH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-D5ezTVNH.js","names":["cfg: unknown","fromFile: () => unknown","envCfg: EnvConfig","projectRoot: string","explicitPath?: string","options: ProjectConfigLoadOptions"],"sources":["../src/loader/defineConfig.ts","../src/loader/loadConfig.ts","../src/loader/loadConfigFromProjectRoot.ts","../src/loader/index.ts"],"sourcesContent":["import { TangoConfigSchema, type TangoConfig } from '../schema/index';\n\n/**\n * Define and validate Tango configuration at declaration time.\n */\nexport function defineConfig(cfg: unknown): TangoConfig {\n return TangoConfigSchema.parse(cfg) as TangoConfig;\n}\n","import { config as loadDotEnv } from 'dotenv';\nimport { TangoConfigSchema, type EnvConfig, type TangoConfig } from '../schema/index';\nimport type { LoadedConfig } from './LoadedConfig';\n\n/**\n * Load, validate, and environment-resolve Tango configuration.\n */\nexport function loadConfig(fromFile: () => unknown): LoadedConfig {\n loadDotEnv();\n\n const cfg = TangoConfigSchema.parse(fromFile()) as TangoConfig;\n const env = cfg.current;\n const current = mergeEnvOverrides(cfg.environments[env]);\n\n return { cfg, env, current };\n}\n\n/**\n * Merge process environment overrides into a base environment config.\n */\nfunction mergeEnvOverrides(envCfg: EnvConfig): EnvConfig {\n const result = structuredClone(envCfg);\n const env = process.env;\n\n if (env.TANGO_DB_ADAPTER) {\n result.db.adapter = env.TANGO_DB_ADAPTER as 'postgres' | 'sqlite';\n }\n\n if (env.DATABASE_URL || env.TANGO_DATABASE_URL) {\n result.db.url = env.TANGO_DATABASE_URL || env.DATABASE_URL;\n }\n\n if (env.TANGO_DB_HOST) result.db.host = env.TANGO_DB_HOST;\n if (env.TANGO_DB_PORT) result.db.port = Number(env.TANGO_DB_PORT);\n if (env.TANGO_DB_NAME) result.db.database = env.TANGO_DB_NAME;\n if (env.TANGO_DB_USER) result.db.user = env.TANGO_DB_USER;\n if (env.TANGO_DB_PASSWORD) result.db.password = env.TANGO_DB_PASSWORD;\n if (env.TANGO_SQLITE_FILENAME) result.db.filename = env.TANGO_SQLITE_FILENAME;\n\n if (env.TANGO_MIGRATIONS_DIR) result.migrations.dir = env.TANGO_MIGRATIONS_DIR;\n if (env.TANGO_MIGRATIONS_ONLINE) {\n result.migrations.online = env.TANGO_MIGRATIONS_ONLINE === 'true';\n }\n\n return result;\n}\n","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { createJiti } from 'jiti';\nimport type { LoadedConfig } from './LoadedConfig';\nimport { loadConfig } from './loadConfig';\n\nconst DEFAULT_CONFIG_FILENAMES = [\n 'tango.config.ts',\n 'tango.config.mts',\n 'tango.config.cts',\n 'tango.config.js',\n 'tango.config.mjs',\n 'tango.config.cjs',\n] as const;\n\nexport interface ProjectConfigLoadOptions {\n projectRoot?: string;\n configPath?: string;\n}\n\nfunction resolveConfigPath(projectRoot: string, explicitPath?: string): string {\n if (explicitPath) {\n const absolutePath = resolve(projectRoot, explicitPath);\n if (!existsSync(absolutePath)) {\n throw new Error(`Unable to find Tango config at '${absolutePath}'.`);\n }\n return absolutePath;\n }\n\n for (const filename of DEFAULT_CONFIG_FILENAMES) {\n const absolutePath = resolve(projectRoot, filename);\n if (existsSync(absolutePath)) {\n return absolutePath;\n }\n }\n\n throw new Error(\n `Unable to find Tango config in '${projectRoot}'. Expected one of: ${DEFAULT_CONFIG_FILENAMES.join(', ')}.`\n );\n}\n\n/**\n * Resolve, load, and validate `tango.config.*` from a project root.\n */\nexport function loadConfigFromProjectRoot(options: ProjectConfigLoadOptions = {}): LoadedConfig {\n const projectRoot = options.projectRoot ?? process.cwd();\n const configPath = resolveConfigPath(projectRoot, options.configPath);\n const jiti = createJiti(resolve(projectRoot, 'package.json'), {\n interopDefault: true,\n moduleCache: true,\n });\n const loaded = jiti(configPath);\n\n return loadConfig(() => loaded);\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type { LoadedConfig } from './LoadedConfig';\nexport { defineConfig } from './defineConfig';\nexport { loadConfig } from './loadConfig';\nexport { loadConfigFromProjectRoot } from './loadConfigFromProjectRoot';\nexport type { ProjectConfigLoadOptions } from './loadConfigFromProjectRoot';\n"],"mappings":";;;;;;;AAKO,SAAS,aAAaA,KAA2B;AACpD,QAAO,kBAAkB,MAAM,IAAI;AACtC;;;;ACAM,SAAS,WAAWC,UAAuC;AAC9D,aAAY;CAEZ,MAAM,MAAM,kBAAkB,MAAM,UAAU,CAAC;CAC/C,MAAM,MAAM,IAAI;CAChB,MAAM,UAAU,kBAAkB,IAAI,aAAa,KAAK;AAExD,QAAO;EAAE;EAAK;EAAK;CAAS;AAC/B;;;;AAKD,SAAS,kBAAkBC,QAA8B;CACrD,MAAM,SAAS,gBAAgB,OAAO;CACtC,MAAM,MAAM,QAAQ;AAEpB,KAAI,IAAI,iBACJ,QAAO,GAAG,UAAU,IAAI;AAG5B,KAAI,IAAI,gBAAgB,IAAI,mBACxB,QAAO,GAAG,MAAM,IAAI,sBAAsB,IAAI;AAGlD,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,IAAI;AAC5C,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,OAAO,IAAI,cAAc;AACjE,KAAI,IAAI,cAAe,QAAO,GAAG,WAAW,IAAI;AAChD,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,IAAI;AAC5C,KAAI,IAAI,kBAAmB,QAAO,GAAG,WAAW,IAAI;AACpD,KAAI,IAAI,sBAAuB,QAAO,GAAG,WAAW,IAAI;AAExD,KAAI,IAAI,qBAAsB,QAAO,WAAW,MAAM,IAAI;AAC1D,KAAI,IAAI,wBACJ,QAAO,WAAW,SAAS,IAAI,4BAA4B;AAG/D,QAAO;AACV;;;;ACvCD,MAAM,2BAA2B;CAC7B;CACA;CACA;CACA;CACA;CACA;AACH;AAOD,SAAS,kBAAkBC,aAAqBC,cAA+B;AAC3E,KAAI,cAAc;EACd,MAAM,eAAe,QAAQ,aAAa,aAAa;AACvD,OAAK,WAAW,aAAa,CACzB,OAAM,IAAI,OAAO,kCAAkC,aAAa;AAEpE,SAAO;CACV;AAED,MAAK,MAAM,YAAY,0BAA0B;EAC7C,MAAM,eAAe,QAAQ,aAAa,SAAS;AACnD,MAAI,WAAW,aAAa,CACxB,QAAO;CAEd;AAED,OAAM,IAAI,OACL,kCAAkC,YAAY,sBAAsB,yBAAyB,KAAK,KAAK,CAAC;AAEhH;AAKM,SAAS,0BAA0BC,UAAoC,CAAE,GAAgB;CAC5F,MAAM,cAAc,QAAQ,eAAe,QAAQ,KAAK;CACxD,MAAM,aAAa,kBAAkB,aAAa,QAAQ,WAAW;CACrE,MAAM,OAAO,WAAW,QAAQ,aAAa,eAAe,EAAE;EAC1D,gBAAgB;EAChB,aAAa;CAChB,EAAC;CACF,MAAM,SAAS,KAAK,WAAW;AAE/B,QAAO,WAAW,MAAM,OAAO;AAClC"}
@@ -1,3 +1,4 @@
1
1
  import { z } from 'zod';
2
- export type AdapterName = 'postgres' | 'sqlite';
2
+ import { InternalAdapterName } from './internal/InternalAdapterName';
3
+ export type AdapterName = (typeof InternalAdapterName)[keyof typeof InternalAdapterName];
3
4
  export declare const AdapterNameSchema: z.ZodTypeAny;
@@ -1,7 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { type DbConfig } from './DbConfig';
3
3
  import { type MigrationsConfig } from './MigrationsConfig';
4
- export type EnvName = 'development' | 'test' | 'production';
4
+ import { InternalEnvName } from './internal/InternalEnvName';
5
+ export type EnvName = (typeof InternalEnvName)[keyof typeof InternalEnvName];
5
6
  export type EnvConfig = {
6
7
  name: EnvName;
7
8
  db: DbConfig;
@@ -2,5 +2,7 @@ import { z } from 'zod';
2
2
  export type MigrationsConfig = {
3
3
  dir: string;
4
4
  online: boolean;
5
+ /** When false, `tango migrate` exits without applying. Default `true`. */
6
+ autoApply: boolean;
5
7
  };
6
8
  export declare const MigrationsConfigSchema: z.ZodTypeAny;
@@ -1,5 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { type EnvConfig, type EnvName } from './EnvConfig';
3
+ /**
4
+ * Root Tango framework configuration across deployment environments.
5
+ */
3
6
  export type TangoConfig = {
4
7
  current: EnvName;
5
8
  environments: {
@@ -8,4 +11,7 @@ export type TangoConfig = {
8
11
  production: EnvConfig;
9
12
  };
10
13
  };
14
+ /**
15
+ * Runtime schema for validating Tango config files.
16
+ */
11
17
  export declare const TangoConfigSchema: z.ZodTypeAny;
@@ -1,3 +1,3 @@
1
- import { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema } from "../schema-D6LCZS5E.js";
1
+ import { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema } from "../schema-VrnHv-I7.js";
2
2
 
3
3
  export { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema };
@@ -0,0 +1,4 @@
1
+ export declare const InternalAdapterName: {
2
+ readonly POSTGRES: "postgres";
3
+ readonly SQLITE: "sqlite";
4
+ };
@@ -0,0 +1,5 @@
1
+ export declare const InternalEnvName: {
2
+ readonly DEVELOPMENT: "development";
3
+ readonly TEST: "test";
4
+ readonly PRODUCTION: "production";
5
+ };
@@ -9,9 +9,16 @@ var __export = (target, all) => {
9
9
  });
10
10
  };
11
11
 
12
+ //#endregion
13
+ //#region src/schema/internal/InternalAdapterName.ts
14
+ const InternalAdapterName = {
15
+ POSTGRES: "postgres",
16
+ SQLITE: "sqlite"
17
+ };
18
+
12
19
  //#endregion
13
20
  //#region src/schema/AdapterName.ts
14
- const AdapterNameSchema = z$4.enum(["postgres", "sqlite"]);
21
+ const AdapterNameSchema = z$4.enum(Object.values(InternalAdapterName));
15
22
 
16
23
  //#endregion
17
24
  //#region src/schema/DbConfig.ts
@@ -31,17 +38,22 @@ const DbConfigSchema = z$3.object({
31
38
  //#region src/schema/MigrationsConfig.ts
32
39
  const MigrationsConfigSchema = z$2.object({
33
40
  dir: z$2.string().default("migrations"),
34
- online: z$2.boolean().default(false)
41
+ online: z$2.boolean().default(false),
42
+ autoApply: z$2.boolean().default(true)
35
43
  });
36
44
 
45
+ //#endregion
46
+ //#region src/schema/internal/InternalEnvName.ts
47
+ const InternalEnvName = {
48
+ DEVELOPMENT: "development",
49
+ TEST: "test",
50
+ PRODUCTION: "production"
51
+ };
52
+
37
53
  //#endregion
38
54
  //#region src/schema/EnvConfig.ts
39
55
  const EnvConfigSchema = z$1.object({
40
- name: z$1.enum([
41
- "development",
42
- "test",
43
- "production"
44
- ]),
56
+ name: z$1.enum(Object.values(InternalEnvName)),
45
57
  db: DbConfigSchema,
46
58
  migrations: MigrationsConfigSchema.default({
47
59
  dir: "migrations",
@@ -52,11 +64,7 @@ const EnvConfigSchema = z$1.object({
52
64
  //#endregion
53
65
  //#region src/schema/TangoConfig.ts
54
66
  const TangoConfigSchema = z.object({
55
- current: z.enum([
56
- "development",
57
- "test",
58
- "production"
59
- ]).default("development"),
67
+ current: z.enum(Object.values(InternalEnvName)).default(InternalEnvName.DEVELOPMENT),
60
68
  environments: z.object({
61
69
  development: EnvConfigSchema,
62
70
  test: EnvConfigSchema,
@@ -77,4 +85,4 @@ __export(schema_exports, {
77
85
 
78
86
  //#endregion
79
87
  export { AdapterNameSchema, DbConfigSchema, EnvConfigSchema, MigrationsConfigSchema, TangoConfigSchema, __export, schema_exports };
80
- //# sourceMappingURL=schema-D6LCZS5E.js.map
88
+ //# sourceMappingURL=schema-VrnHv-I7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-VrnHv-I7.js","names":["AdapterNameSchema: z.ZodTypeAny","DbConfigSchema: z.ZodTypeAny","MigrationsConfigSchema: z.ZodTypeAny","EnvConfigSchema: z.ZodTypeAny","TangoConfigSchema: z.ZodTypeAny"],"sources":["../src/schema/internal/InternalAdapterName.ts","../src/schema/AdapterName.ts","../src/schema/DbConfig.ts","../src/schema/MigrationsConfig.ts","../src/schema/internal/InternalEnvName.ts","../src/schema/EnvConfig.ts","../src/schema/TangoConfig.ts","../src/schema/index.ts"],"sourcesContent":["export const InternalAdapterName = {\n POSTGRES: 'postgres',\n SQLITE: 'sqlite',\n} as const;\n","import { z } from 'zod';\nimport { InternalAdapterName } from './internal/InternalAdapterName';\n\nexport type AdapterName = (typeof InternalAdapterName)[keyof typeof InternalAdapterName];\n\nexport const AdapterNameSchema: z.ZodTypeAny = z.enum(Object.values(InternalAdapterName));\n","import { z } from 'zod';\nimport { AdapterNameSchema, type AdapterName } from './AdapterName';\n\nexport type DbConfig = {\n adapter: AdapterName;\n url?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n filename?: string;\n maxConnections: number;\n};\n\nexport const DbConfigSchema: z.ZodTypeAny = z.object({\n adapter: AdapterNameSchema,\n url: z.string().optional(),\n host: z.string().optional(),\n port: z.coerce.number().optional(),\n database: z.string().optional(),\n user: z.string().optional(),\n password: z.string().optional(),\n filename: z.string().optional(),\n maxConnections: z.coerce.number().default(10),\n});\n","import { z } from 'zod';\n\nexport type MigrationsConfig = {\n dir: string;\n online: boolean;\n /** When false, `tango migrate` exits without applying. Default `true`. */\n autoApply: boolean;\n};\n\nexport const MigrationsConfigSchema: z.ZodTypeAny = z.object({\n dir: z.string().default('migrations'),\n online: z.boolean().default(false),\n autoApply: z.boolean().default(true),\n});\n","export const InternalEnvName = {\n DEVELOPMENT: 'development',\n TEST: 'test',\n PRODUCTION: 'production',\n} as const;\n","import { z } from 'zod';\nimport { DbConfigSchema, type DbConfig } from './DbConfig';\nimport { MigrationsConfigSchema, type MigrationsConfig } from './MigrationsConfig';\nimport { InternalEnvName } from './internal/InternalEnvName';\n\nexport type EnvName = (typeof InternalEnvName)[keyof typeof InternalEnvName];\n\nexport type EnvConfig = {\n name: EnvName;\n db: DbConfig;\n migrations: MigrationsConfig;\n};\n\nexport const EnvConfigSchema: z.ZodTypeAny = z.object({\n name: z.enum(Object.values(InternalEnvName)),\n db: DbConfigSchema,\n migrations: MigrationsConfigSchema.default({\n dir: 'migrations',\n online: false,\n }),\n});\n","import { z } from 'zod';\nimport { EnvConfigSchema, type EnvConfig, type EnvName } from './EnvConfig';\nimport { InternalEnvName } from './internal/InternalEnvName';\n\n/**\n * Root Tango framework configuration across deployment environments.\n */\nexport type TangoConfig = {\n current: EnvName;\n environments: {\n development: EnvConfig;\n test: EnvConfig;\n production: EnvConfig;\n };\n};\n\n/**\n * Runtime schema for validating Tango config files.\n */\nexport const TangoConfigSchema: z.ZodTypeAny = z.object({\n current: z.enum(Object.values(InternalEnvName)).default(InternalEnvName.DEVELOPMENT),\n environments: z.object({\n development: EnvConfigSchema,\n test: EnvConfigSchema,\n production: EnvConfigSchema,\n }),\n});\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type { AdapterName } from './AdapterName';\nexport { AdapterNameSchema } from './AdapterName';\n\nexport type { DbConfig } from './DbConfig';\nexport { DbConfigSchema } from './DbConfig';\n\nexport type { MigrationsConfig } from './MigrationsConfig';\nexport { MigrationsConfigSchema } from './MigrationsConfig';\n\nexport type { EnvConfig, EnvName } from './EnvConfig';\nexport { EnvConfigSchema } from './EnvConfig';\n\nexport type { TangoConfig } from './TangoConfig';\nexport { TangoConfigSchema } from './TangoConfig';\n"],"mappings":";;;;;;;;;;;;;MAAa,sBAAsB;CAC/B,UAAU;CACV,QAAQ;AACX;;;;MCEYA,oBAAkC,IAAE,KAAK,OAAO,OAAO,oBAAoB,CAAC;;;;MCU5EC,iBAA+B,IAAE,OAAO;CACjD,SAAS;CACT,KAAK,IAAE,QAAQ,CAAC,UAAU;CAC1B,MAAM,IAAE,QAAQ,CAAC,UAAU;CAC3B,MAAM,IAAE,OAAO,QAAQ,CAAC,UAAU;CAClC,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,MAAM,IAAE,QAAQ,CAAC,UAAU;CAC3B,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,gBAAgB,IAAE,OAAO,QAAQ,CAAC,QAAQ,GAAG;AAChD,EAAC;;;;MChBWC,yBAAuC,IAAE,OAAO;CACzD,KAAK,IAAE,QAAQ,CAAC,QAAQ,aAAa;CACrC,QAAQ,IAAE,SAAS,CAAC,QAAQ,MAAM;CAClC,WAAW,IAAE,SAAS,CAAC,QAAQ,KAAK;AACvC,EAAC;;;;MCbW,kBAAkB;CAC3B,aAAa;CACb,MAAM;CACN,YAAY;AACf;;;;MCSYC,kBAAgC,IAAE,OAAO;CAClD,MAAM,IAAE,KAAK,OAAO,OAAO,gBAAgB,CAAC;CAC5C,IAAI;CACJ,YAAY,uBAAuB,QAAQ;EACvC,KAAK;EACL,QAAQ;CACX,EAAC;AACL,EAAC;;;;MCDWC,oBAAkC,EAAE,OAAO;CACpD,SAAS,EAAE,KAAK,OAAO,OAAO,gBAAgB,CAAC,CAAC,QAAQ,gBAAgB,YAAY;CACpF,cAAc,EAAE,OAAO;EACnB,aAAa;EACb,MAAM;EACN,YAAY;CACf,EAAC;AACL,EAAC"}
package/package.json CHANGED
@@ -1,54 +1,57 @@
1
1
  {
2
- "name": "@danceroutine/tango-config",
3
- "version": "0.1.0",
4
- "description": "Configuration loader with environment profiles for Tango",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- },
13
- "./schema": {
14
- "types": "./dist/schema/index.d.ts",
15
- "import": "./dist/schema/index.js"
16
- },
17
- "./loader": {
18
- "types": "./dist/loader/index.d.ts",
19
- "import": "./dist/loader/index.js"
20
- }
2
+ "name": "@danceroutine/tango-config",
3
+ "version": "1.0.0",
4
+ "description": "Configuration loader with environment profiles for Tango",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
21
12
  },
22
- "files": [
23
- "dist"
24
- ],
25
- "scripts": {
26
- "build": "tsdown",
27
- "test": "vitest run --coverage",
28
- "test:watch": "vitest",
29
- "typecheck": "tsc --noEmit"
13
+ "./schema": {
14
+ "types": "./dist/schema/index.d.ts",
15
+ "import": "./dist/schema/index.js"
30
16
  },
31
- "keywords": [
32
- "tango",
33
- "config",
34
- "environment",
35
- "database"
36
- ],
37
- "author": "Pedro Del Moral Lopez",
38
- "license": "MIT",
39
- "repository": {
40
- "type": "git",
41
- "url": "https://github.com/danceroutine/tango.git",
42
- "directory": "packages/config"
43
- },
44
- "dependencies": {
45
- "dotenv": "^16.4.7",
46
- "zod": "^4.0.0"
47
- },
48
- "devDependencies": {
49
- "@types/node": "^22.9.0",
50
- "tsdown": "^0.4.0",
51
- "typescript": "^5.6.3",
52
- "vitest": "^4.0.6"
17
+ "./loader": {
18
+ "types": "./dist/loader/index.d.ts",
19
+ "import": "./dist/loader/index.js"
53
20
  }
54
- }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "keywords": [
26
+ "tango",
27
+ "config",
28
+ "environment",
29
+ "database"
30
+ ],
31
+ "author": "Pedro Del Moral Lopez",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/danceroutine/tango.git",
36
+ "directory": "packages/config"
37
+ },
38
+ "dependencies": {
39
+ "dotenv": "^16.4.7",
40
+ "jiti": "^2.6.1",
41
+ "zod": "^4.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.9.0",
45
+ "tsdown": "^0.4.0",
46
+ "typescript": "^5.6.3",
47
+ "vitest": "^4.0.6"
48
+ },
49
+ "scripts": {
50
+ "build": "tsdown",
51
+ "test": "vitest run --coverage",
52
+ "test:watch": "vitest",
53
+ "typecheck": "pnpm run typecheck:prod && pnpm run typecheck:test",
54
+ "typecheck:prod": "tsc --noEmit -p tsconfig.json",
55
+ "typecheck:test": "tsc --noEmit -p tsconfig.tests.json"
56
+ }
57
+ }
@@ -1,48 +0,0 @@
1
- import { TangoConfigSchema, __export } from "./schema-D6LCZS5E.js";
2
- import { config as loadDotEnv } from "dotenv";
3
-
4
- //#region src/loader/defineConfig.ts
5
- function defineConfig(cfg) {
6
- return TangoConfigSchema.parse(cfg);
7
- }
8
-
9
- //#endregion
10
- //#region src/loader/loadConfig.ts
11
- function loadConfig(fromFile) {
12
- loadDotEnv();
13
- const cfg = TangoConfigSchema.parse(fromFile());
14
- const env = cfg.current;
15
- const current = mergeEnvOverrides(cfg.environments[env]);
16
- return {
17
- cfg,
18
- env,
19
- current
20
- };
21
- }
22
- function mergeEnvOverrides(envCfg) {
23
- const result = structuredClone(envCfg);
24
- const env = process.env;
25
- if (env.TANGO_DB_ADAPTER) result.db.adapter = env.TANGO_DB_ADAPTER;
26
- if (env.DATABASE_URL || env.TANGO_DATABASE_URL) result.db.url = env.TANGO_DATABASE_URL || env.DATABASE_URL;
27
- if (env.TANGO_DB_HOST) result.db.host = env.TANGO_DB_HOST;
28
- if (env.TANGO_DB_PORT) result.db.port = Number(env.TANGO_DB_PORT);
29
- if (env.TANGO_DB_NAME) result.db.database = env.TANGO_DB_NAME;
30
- if (env.TANGO_DB_USER) result.db.user = env.TANGO_DB_USER;
31
- if (env.TANGO_DB_PASSWORD) result.db.password = env.TANGO_DB_PASSWORD;
32
- if (env.TANGO_SQLITE_FILENAME) result.db.filename = env.TANGO_SQLITE_FILENAME;
33
- if (env.TANGO_MIGRATIONS_DIR) result.migrations.dir = env.TANGO_MIGRATIONS_DIR;
34
- if (env.TANGO_MIGRATIONS_ONLINE) result.migrations.online = env.TANGO_MIGRATIONS_ONLINE === "true";
35
- return result;
36
- }
37
-
38
- //#endregion
39
- //#region src/loader/index.ts
40
- var loader_exports = {};
41
- __export(loader_exports, {
42
- defineConfig: () => defineConfig,
43
- loadConfig: () => loadConfig
44
- });
45
-
46
- //#endregion
47
- export { defineConfig, loadConfig, loader_exports };
48
- //# sourceMappingURL=loader-De9vxa5D.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loader-De9vxa5D.js","names":["cfg: unknown","fromFile: () => unknown","envCfg: EnvConfig"],"sources":["../src/loader/defineConfig.ts","../src/loader/loadConfig.ts","../src/loader/index.ts"],"sourcesContent":["import { TangoConfigSchema, type TangoConfig } from '../schema/index';\n\nexport function defineConfig(cfg: unknown): TangoConfig {\n return TangoConfigSchema.parse(cfg) as TangoConfig;\n}\n","import { config as loadDotEnv } from 'dotenv';\nimport { TangoConfigSchema, type EnvConfig, type TangoConfig } from '../schema/index';\nimport type { LoadedConfig } from './LoadedConfig';\n\nexport function loadConfig(fromFile: () => unknown): LoadedConfig {\n loadDotEnv();\n\n const cfg = TangoConfigSchema.parse(fromFile()) as TangoConfig;\n const env = cfg.current;\n const current = mergeEnvOverrides(cfg.environments[env]);\n\n return { cfg, env, current };\n}\n\nfunction mergeEnvOverrides(envCfg: EnvConfig): EnvConfig {\n const result = structuredClone(envCfg);\n const env = process.env;\n\n if (env.TANGO_DB_ADAPTER) {\n result.db.adapter = env.TANGO_DB_ADAPTER as 'postgres' | 'sqlite';\n }\n\n if (env.DATABASE_URL || env.TANGO_DATABASE_URL) {\n result.db.url = env.TANGO_DATABASE_URL || env.DATABASE_URL;\n }\n\n if (env.TANGO_DB_HOST) result.db.host = env.TANGO_DB_HOST;\n if (env.TANGO_DB_PORT) result.db.port = Number(env.TANGO_DB_PORT);\n if (env.TANGO_DB_NAME) result.db.database = env.TANGO_DB_NAME;\n if (env.TANGO_DB_USER) result.db.user = env.TANGO_DB_USER;\n if (env.TANGO_DB_PASSWORD) result.db.password = env.TANGO_DB_PASSWORD;\n if (env.TANGO_SQLITE_FILENAME) result.db.filename = env.TANGO_SQLITE_FILENAME;\n\n if (env.TANGO_MIGRATIONS_DIR) result.migrations.dir = env.TANGO_MIGRATIONS_DIR;\n if (env.TANGO_MIGRATIONS_ONLINE) {\n result.migrations.online = env.TANGO_MIGRATIONS_ONLINE === 'true';\n }\n\n return result;\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type { LoadedConfig } from './LoadedConfig';\nexport { defineConfig } from './defineConfig';\nexport { loadConfig } from './loadConfig';\n"],"mappings":";;;;AAEO,SAAS,aAAaA,KAA2B;AACpD,QAAO,kBAAkB,MAAM,IAAI;AACtC;;;;ACAM,SAAS,WAAWC,UAAuC;AAC9D,aAAY;CAEZ,MAAM,MAAM,kBAAkB,MAAM,UAAU,CAAC;CAC/C,MAAM,MAAM,IAAI;CAChB,MAAM,UAAU,kBAAkB,IAAI,aAAa,KAAK;AAExD,QAAO;EAAE;EAAK;EAAK;CAAS;AAC/B;AAED,SAAS,kBAAkBC,QAA8B;CACrD,MAAM,SAAS,gBAAgB,OAAO;CACtC,MAAM,MAAM,QAAQ;AAEpB,KAAI,IAAI,iBACJ,QAAO,GAAG,UAAU,IAAI;AAG5B,KAAI,IAAI,gBAAgB,IAAI,mBACxB,QAAO,GAAG,MAAM,IAAI,sBAAsB,IAAI;AAGlD,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,IAAI;AAC5C,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,OAAO,IAAI,cAAc;AACjE,KAAI,IAAI,cAAe,QAAO,GAAG,WAAW,IAAI;AAChD,KAAI,IAAI,cAAe,QAAO,GAAG,OAAO,IAAI;AAC5C,KAAI,IAAI,kBAAmB,QAAO,GAAG,WAAW,IAAI;AACpD,KAAI,IAAI,sBAAuB,QAAO,GAAG,WAAW,IAAI;AAExD,KAAI,IAAI,qBAAsB,QAAO,WAAW,MAAM,IAAI;AAC1D,KAAI,IAAI,wBACJ,QAAO,WAAW,SAAS,IAAI,4BAA4B;AAG/D,QAAO;AACV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-D6LCZS5E.js","names":["AdapterNameSchema: z.ZodTypeAny","DbConfigSchema: z.ZodTypeAny","MigrationsConfigSchema: z.ZodTypeAny","EnvConfigSchema: z.ZodTypeAny","TangoConfigSchema: z.ZodTypeAny"],"sources":["../src/schema/AdapterName.ts","../src/schema/DbConfig.ts","../src/schema/MigrationsConfig.ts","../src/schema/EnvConfig.ts","../src/schema/TangoConfig.ts","../src/schema/index.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport type AdapterName = 'postgres' | 'sqlite';\n\nexport const AdapterNameSchema: z.ZodTypeAny = z.enum(['postgres', 'sqlite']);\n","import { z } from 'zod';\nimport { AdapterNameSchema, type AdapterName } from './AdapterName';\n\nexport type DbConfig = {\n adapter: AdapterName;\n url?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n filename?: string;\n maxConnections: number;\n};\n\nexport const DbConfigSchema: z.ZodTypeAny = z.object({\n adapter: AdapterNameSchema,\n url: z.string().optional(),\n host: z.string().optional(),\n port: z.coerce.number().optional(),\n database: z.string().optional(),\n user: z.string().optional(),\n password: z.string().optional(),\n filename: z.string().optional(),\n maxConnections: z.coerce.number().default(10),\n});\n","import { z } from 'zod';\n\nexport type MigrationsConfig = {\n dir: string;\n online: boolean;\n};\n\nexport const MigrationsConfigSchema: z.ZodTypeAny = z.object({\n dir: z.string().default('migrations'),\n online: z.boolean().default(false),\n});\n","import { z } from 'zod';\nimport { DbConfigSchema, type DbConfig } from './DbConfig';\nimport { MigrationsConfigSchema, type MigrationsConfig } from './MigrationsConfig';\n\nexport type EnvName = 'development' | 'test' | 'production';\n\nexport type EnvConfig = {\n name: EnvName;\n db: DbConfig;\n migrations: MigrationsConfig;\n};\n\nexport const EnvConfigSchema: z.ZodTypeAny = z.object({\n name: z.enum(['development', 'test', 'production']),\n db: DbConfigSchema,\n migrations: MigrationsConfigSchema.default({\n dir: 'migrations',\n online: false,\n }),\n});\n","import { z } from 'zod';\nimport { EnvConfigSchema, type EnvConfig, type EnvName } from './EnvConfig';\n\nexport type TangoConfig = {\n current: EnvName;\n environments: {\n development: EnvConfig;\n test: EnvConfig;\n production: EnvConfig;\n };\n};\n\nexport const TangoConfigSchema: z.ZodTypeAny = z.object({\n current: z.enum(['development', 'test', 'production']).default('development'),\n environments: z.object({\n development: EnvConfigSchema,\n test: EnvConfigSchema,\n production: EnvConfigSchema,\n }),\n});\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type { AdapterName } from './AdapterName';\nexport { AdapterNameSchema } from './AdapterName';\n\nexport type { DbConfig } from './DbConfig';\nexport { DbConfigSchema } from './DbConfig';\n\nexport type { MigrationsConfig } from './MigrationsConfig';\nexport { MigrationsConfigSchema } from './MigrationsConfig';\n\nexport type { EnvConfig, EnvName } from './EnvConfig';\nexport { EnvConfigSchema } from './EnvConfig';\n\nexport type { TangoConfig } from './TangoConfig';\nexport { TangoConfigSchema } from './TangoConfig';\n"],"mappings":";;;;;;;;;;;;;MAIaA,oBAAkC,IAAE,KAAK,CAAC,YAAY,QAAS,EAAC;;;;MCWhEC,iBAA+B,IAAE,OAAO;CACjD,SAAS;CACT,KAAK,IAAE,QAAQ,CAAC,UAAU;CAC1B,MAAM,IAAE,QAAQ,CAAC,UAAU;CAC3B,MAAM,IAAE,OAAO,QAAQ,CAAC,UAAU;CAClC,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,MAAM,IAAE,QAAQ,CAAC,UAAU;CAC3B,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,UAAU,IAAE,QAAQ,CAAC,UAAU;CAC/B,gBAAgB,IAAE,OAAO,QAAQ,CAAC,QAAQ,GAAG;AAChD,EAAC;;;;MClBWC,yBAAuC,IAAE,OAAO;CACzD,KAAK,IAAE,QAAQ,CAAC,QAAQ,aAAa;CACrC,QAAQ,IAAE,SAAS,CAAC,QAAQ,MAAM;AACrC,EAAC;;;;MCEWC,kBAAgC,IAAE,OAAO;CAClD,MAAM,IAAE,KAAK;EAAC;EAAe;EAAQ;CAAa,EAAC;CACnD,IAAI;CACJ,YAAY,uBAAuB,QAAQ;EACvC,KAAK;EACL,QAAQ;CACX,EAAC;AACL,EAAC;;;;MCPWC,oBAAkC,EAAE,OAAO;CACpD,SAAS,EAAE,KAAK;EAAC;EAAe;EAAQ;CAAa,EAAC,CAAC,QAAQ,cAAc;CAC7E,cAAc,EAAE,OAAO;EACnB,aAAa;EACb,MAAM;EACN,YAAY;CACf,EAAC;AACL,EAAC"}