@clisma/config 0.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.
@@ -0,0 +1,33 @@
1
+ export type MigrationConfig = {
2
+ dir: string;
3
+ table_name?: string;
4
+ replication_path?: string;
5
+ vars?: Record<string, unknown>;
6
+ };
7
+ export type EnvConfig = {
8
+ url: string;
9
+ exclude?: string[];
10
+ cluster_name?: string;
11
+ migrations: MigrationConfig;
12
+ };
13
+ export type VariableConfig = {
14
+ type: string;
15
+ default?: unknown;
16
+ description?: string;
17
+ };
18
+ export type ClismaConfig = {
19
+ env: Record<string, EnvConfig>;
20
+ variable?: Record<string, VariableConfig>;
21
+ };
22
+ /**
23
+ * Parses HCL config file and returns normalized configuration
24
+ */
25
+ export declare const parseConfig: (content: string, env?: Record<string, string | undefined>, vars?: Record<string, string>, envName?: string, sourceName?: string) => Promise<EnvConfig>;
26
+ export declare const parseConfigFile: (configPath: string, envName?: string, vars?: Record<string, string>, env?: Record<string, string | undefined>) => Promise<EnvConfig>;
27
+ export declare const listEnvironments: (content: string, sourceName?: string) => Promise<string[]>;
28
+ export declare const listEnvironmentsFile: (configPath: string) => Promise<string[]>;
29
+ /**
30
+ * Finds config file in current directory or parent directories
31
+ */
32
+ export declare const findConfigFile: (startDir?: string, fileName?: string) => Promise<string | null>;
33
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C,CAAC;AA2BF;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,MAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,EAC5C,OAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACjC,UAAU,MAAM,EAChB,aAAY,MAAqB,KAChC,OAAO,CAAC,SAAS,CA4GnB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,YAAY,MAAM,EAClB,UAAU,MAAM,EAChB,OAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACjC,MAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,KACpD,OAAO,CAAC,SAAS,CAInB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,aAAY,MAAqB,KAChC,OAAO,CAAC,MAAM,EAAE,CAMlB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,KACjB,OAAO,CAAC,MAAM,EAAE,CAGlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,WAAU,MAAsB,EAChC,WAAU,MAAqB,KAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAmBvB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,118 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse } from "@cdktf/hcl2json";
4
+ import { extractList, extractObject, extractValue, resolveValue, } from "./utils.js";
5
+ // Helpers live in ./utils.ts to keep parsing logic focused.
6
+ /**
7
+ * Parses HCL config file and returns normalized configuration
8
+ */
9
+ export const parseConfig = async (content, env = {}, vars = {}, envName, sourceName = "clisma.hcl") => {
10
+ const parsed = (await parse(sourceName, content));
11
+ if (!parsed.env) {
12
+ throw new Error("No environments defined in config file");
13
+ }
14
+ // Parse variables
15
+ const variables = { ...vars };
16
+ if (parsed.variable) {
17
+ for (const [varName, varBlocks] of Object.entries(parsed.variable)) {
18
+ const varBlock = varBlocks[0];
19
+ if (varBlock?.default && !variables[varName]) {
20
+ const defaultValue = extractValue(varBlock.default, "");
21
+ variables[varName] = String(defaultValue);
22
+ }
23
+ }
24
+ }
25
+ // Determine which environment to use
26
+ const targetEnv = envName || Object.keys(parsed.env)[0];
27
+ if (!targetEnv) {
28
+ throw new Error("No environment specified and no default environment found");
29
+ }
30
+ const envBlocks = parsed.env[targetEnv];
31
+ if (!envBlocks || envBlocks.length === 0) {
32
+ throw new Error(`Environment "${targetEnv}" not found in config file`);
33
+ }
34
+ const envBlock = envBlocks[0];
35
+ // Parse migrations config
36
+ const migrationBlock = envBlock.migrations?.[0];
37
+ if (!migrationBlock) {
38
+ throw new Error(`No migrations configuration found for environment "${targetEnv}"`);
39
+ }
40
+ const migrationDir = extractValue(migrationBlock.dir, "");
41
+ if (!migrationDir) {
42
+ throw new Error(`Migrations directory not specified for environment "${targetEnv}"`);
43
+ }
44
+ // Parse migration vars and resolve them
45
+ const rawVars = extractObject(migrationBlock.vars, {});
46
+ const resolvedVars = {};
47
+ for (const [key, value] of Object.entries(rawVars)) {
48
+ if (typeof value === "string") {
49
+ resolvedVars[key] = resolveValue(value, env, variables);
50
+ }
51
+ else {
52
+ resolvedVars[key] = value;
53
+ }
54
+ }
55
+ // Parse optional table_name
56
+ const tableName = migrationBlock.table_name
57
+ ? extractValue(migrationBlock.table_name, "schema_migrations")
58
+ : "schema_migrations";
59
+ const replicationPath = migrationBlock.replication_path
60
+ ? resolveValue(extractValue(migrationBlock.replication_path, ""), env, variables) || undefined
61
+ : undefined;
62
+ // Parse URL
63
+ const url = extractValue(envBlock.url, "");
64
+ if (!url) {
65
+ throw new Error(`Database URL not specified for environment "${targetEnv}"`);
66
+ }
67
+ const clusterNameValue = envBlock.cluster_name
68
+ ? resolveValue(extractValue(envBlock.cluster_name, ""), env, variables)
69
+ : "";
70
+ const clusterName = clusterNameValue || undefined;
71
+ // Parse exclude patterns (optional)
72
+ const excludePatterns = extractList(envBlock.exclude, []);
73
+ return {
74
+ url: resolveValue(url, env, variables),
75
+ exclude: excludePatterns,
76
+ cluster_name: clusterName,
77
+ migrations: {
78
+ dir: resolveValue(migrationDir, env, variables),
79
+ table_name: tableName,
80
+ replication_path: replicationPath,
81
+ vars: resolvedVars,
82
+ },
83
+ };
84
+ };
85
+ export const parseConfigFile = async (configPath, envName, vars = {}, env = process.env) => {
86
+ const content = await fs.readFile(configPath, "utf8");
87
+ return parseConfig(content, env, vars, envName, configPath);
88
+ };
89
+ export const listEnvironments = async (content, sourceName = "clisma.hcl") => {
90
+ const parsed = (await parse(sourceName, content));
91
+ if (!parsed.env) {
92
+ return [];
93
+ }
94
+ return Object.keys(parsed.env);
95
+ };
96
+ export const listEnvironmentsFile = async (configPath) => {
97
+ const content = await fs.readFile(configPath, "utf8");
98
+ return listEnvironments(content, configPath);
99
+ };
100
+ /**
101
+ * Finds config file in current directory or parent directories
102
+ */
103
+ export const findConfigFile = async (startDir = process.cwd(), fileName = "clisma.hcl") => {
104
+ let currentDir = startDir;
105
+ const root = path.parse(currentDir).root;
106
+ while (currentDir !== root) {
107
+ const configPath = path.join(currentDir, fileName);
108
+ try {
109
+ await fs.access(configPath);
110
+ return configPath;
111
+ }
112
+ catch {
113
+ // File not found, continue searching
114
+ }
115
+ currentDir = path.dirname(currentDir);
116
+ }
117
+ return null;
118
+ };
@@ -0,0 +1,105 @@
1
+ export declare const clismaSchema: {
2
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
3
+ readonly title: "clisma.hcl";
4
+ readonly type: "object";
5
+ readonly additionalProperties: false;
6
+ readonly properties: {
7
+ readonly env: {
8
+ readonly type: "object";
9
+ readonly additionalProperties: {
10
+ readonly type: "array";
11
+ readonly items: {
12
+ readonly $ref: "#/$defs/envBlock";
13
+ };
14
+ };
15
+ };
16
+ readonly variable: {
17
+ readonly type: "object";
18
+ readonly additionalProperties: {
19
+ readonly type: "array";
20
+ readonly items: {
21
+ readonly $ref: "#/$defs/variableBlock";
22
+ };
23
+ };
24
+ };
25
+ };
26
+ readonly $defs: {
27
+ readonly envBlock: {
28
+ readonly type: "object";
29
+ readonly additionalProperties: false;
30
+ readonly required: readonly ["url", "migrations"];
31
+ readonly properties: {
32
+ readonly url: {
33
+ readonly type: "string";
34
+ readonly description: "ClickHouse connection string.";
35
+ };
36
+ readonly cluster_name: {
37
+ readonly type: "string";
38
+ readonly description: "Optional cluster name. When set, migrations use replicated tracking and templating.";
39
+ };
40
+ readonly exclude: {
41
+ readonly type: "array";
42
+ readonly items: {
43
+ readonly type: "string";
44
+ };
45
+ readonly description: "Optional glob patterns to exclude tables.";
46
+ };
47
+ readonly migrations: {
48
+ readonly type: "array";
49
+ readonly items: {
50
+ readonly $ref: "#/$defs/migrationsBlock";
51
+ };
52
+ };
53
+ };
54
+ };
55
+ readonly migrationsBlock: {
56
+ readonly type: "object";
57
+ readonly additionalProperties: false;
58
+ readonly required: readonly ["dir"];
59
+ readonly properties: {
60
+ readonly dir: {
61
+ readonly type: "string";
62
+ readonly description: "Path to migrations directory.";
63
+ };
64
+ readonly table_name: {
65
+ readonly type: "string";
66
+ readonly description: "Custom table name for migration tracking.";
67
+ };
68
+ readonly replication_path: {
69
+ readonly type: "string";
70
+ readonly description: "Optional replication path for the migrations table in clustered setups.";
71
+ };
72
+ readonly vars: {
73
+ readonly type: "object";
74
+ readonly description: "Variables for Handlebars templates.";
75
+ readonly additionalProperties: {
76
+ readonly $ref: "#/$defs/variableValue";
77
+ };
78
+ };
79
+ };
80
+ };
81
+ readonly variableBlock: {
82
+ readonly type: "object";
83
+ readonly additionalProperties: false;
84
+ readonly required: readonly ["type"];
85
+ readonly properties: {
86
+ readonly type: {
87
+ readonly type: "string";
88
+ readonly description: "Variable type.";
89
+ readonly enum: readonly ["string", "number", "bool", "any"];
90
+ };
91
+ readonly default: {
92
+ readonly $ref: "#/$defs/variableValue";
93
+ };
94
+ readonly description: {
95
+ readonly type: "string";
96
+ };
97
+ };
98
+ };
99
+ readonly variableValue: {
100
+ readonly type: readonly ["string", "number", "boolean", "object", "array", "null"];
101
+ };
102
+ };
103
+ };
104
+ export declare const generateSchema: () => typeof clismaSchema;
105
+ //# sourceMappingURL=hcl-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hcl-schema.d.ts","sourceRoot":"","sources":["../src/hcl-schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwGf,CAAC;AAEX,eAAO,MAAM,cAAc,QAAO,OAAO,YAExC,CAAC"}
@@ -0,0 +1,106 @@
1
+ export const clismaSchema = {
2
+ $schema: "https://json-schema.org/draft/2020-12/schema",
3
+ title: "clisma.hcl",
4
+ type: "object",
5
+ additionalProperties: false,
6
+ properties: {
7
+ env: {
8
+ type: "object",
9
+ additionalProperties: {
10
+ type: "array",
11
+ items: {
12
+ $ref: "#/$defs/envBlock",
13
+ },
14
+ },
15
+ },
16
+ variable: {
17
+ type: "object",
18
+ additionalProperties: {
19
+ type: "array",
20
+ items: {
21
+ $ref: "#/$defs/variableBlock",
22
+ },
23
+ },
24
+ },
25
+ },
26
+ $defs: {
27
+ envBlock: {
28
+ type: "object",
29
+ additionalProperties: false,
30
+ required: ["url", "migrations"],
31
+ properties: {
32
+ url: {
33
+ type: "string",
34
+ description: "ClickHouse connection string.",
35
+ },
36
+ cluster_name: {
37
+ type: "string",
38
+ description: "Optional cluster name. When set, migrations use replicated tracking and templating.",
39
+ },
40
+ exclude: {
41
+ type: "array",
42
+ items: {
43
+ type: "string",
44
+ },
45
+ description: "Optional glob patterns to exclude tables.",
46
+ },
47
+ migrations: {
48
+ type: "array",
49
+ items: {
50
+ $ref: "#/$defs/migrationsBlock",
51
+ },
52
+ },
53
+ },
54
+ },
55
+ migrationsBlock: {
56
+ type: "object",
57
+ additionalProperties: false,
58
+ required: ["dir"],
59
+ properties: {
60
+ dir: {
61
+ type: "string",
62
+ description: "Path to migrations directory.",
63
+ },
64
+ table_name: {
65
+ type: "string",
66
+ description: "Custom table name for migration tracking.",
67
+ },
68
+ replication_path: {
69
+ type: "string",
70
+ description: "Optional replication path for the migrations table in clustered setups.",
71
+ },
72
+ vars: {
73
+ type: "object",
74
+ description: "Variables for Handlebars templates.",
75
+ additionalProperties: {
76
+ $ref: "#/$defs/variableValue",
77
+ },
78
+ },
79
+ },
80
+ },
81
+ variableBlock: {
82
+ type: "object",
83
+ additionalProperties: false,
84
+ required: ["type"],
85
+ properties: {
86
+ type: {
87
+ type: "string",
88
+ description: "Variable type.",
89
+ enum: ["string", "number", "bool", "any"],
90
+ },
91
+ default: {
92
+ $ref: "#/$defs/variableValue",
93
+ },
94
+ description: {
95
+ type: "string",
96
+ },
97
+ },
98
+ },
99
+ variableValue: {
100
+ type: ["string", "number", "boolean", "object", "array", "null"],
101
+ },
102
+ },
103
+ };
104
+ export const generateSchema = () => {
105
+ return clismaSchema;
106
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./config.js";
2
+ export { clismaSchema, generateSchema } from "./hcl-schema.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./config.js";
2
+ export { clismaSchema, generateSchema } from "./hcl-schema.js";
@@ -0,0 +1,96 @@
1
+ export declare const clismaSchema: {
2
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
3
+ readonly title: "clisma.hcl";
4
+ readonly type: "object";
5
+ readonly additionalProperties: false;
6
+ readonly properties: {
7
+ readonly env: {
8
+ readonly type: "object";
9
+ readonly additionalProperties: {
10
+ readonly type: "array";
11
+ readonly items: {
12
+ readonly $ref: "#/$defs/envBlock";
13
+ };
14
+ };
15
+ };
16
+ readonly variable: {
17
+ readonly type: "object";
18
+ readonly additionalProperties: {
19
+ readonly type: "array";
20
+ readonly items: {
21
+ readonly $ref: "#/$defs/variableBlock";
22
+ };
23
+ };
24
+ };
25
+ };
26
+ readonly $defs: {
27
+ readonly envBlock: {
28
+ readonly type: "object";
29
+ readonly additionalProperties: false;
30
+ readonly required: readonly ["url", "migration"];
31
+ readonly properties: {
32
+ readonly url: {
33
+ readonly type: "string";
34
+ readonly description: "ClickHouse connection string.";
35
+ };
36
+ readonly exclude: {
37
+ readonly type: "array";
38
+ readonly items: {
39
+ readonly type: "string";
40
+ };
41
+ readonly description: "Optional glob patterns to exclude tables.";
42
+ };
43
+ readonly migration: {
44
+ readonly type: "array";
45
+ readonly items: {
46
+ readonly $ref: "#/$defs/migrationBlock";
47
+ };
48
+ };
49
+ };
50
+ };
51
+ readonly migrationBlock: {
52
+ readonly type: "object";
53
+ readonly additionalProperties: false;
54
+ readonly required: readonly ["dir"];
55
+ readonly properties: {
56
+ readonly dir: {
57
+ readonly type: "string";
58
+ readonly description: "Path to migrations directory.";
59
+ };
60
+ readonly table_name: {
61
+ readonly type: "string";
62
+ readonly description: "Custom table name for migration tracking.";
63
+ };
64
+ readonly vars: {
65
+ readonly type: "object";
66
+ readonly description: "Variables for Handlebars templates.";
67
+ readonly additionalProperties: {
68
+ readonly $ref: "#/$defs/variableValue";
69
+ };
70
+ };
71
+ };
72
+ };
73
+ readonly variableBlock: {
74
+ readonly type: "object";
75
+ readonly additionalProperties: false;
76
+ readonly required: readonly ["type"];
77
+ readonly properties: {
78
+ readonly type: {
79
+ readonly type: "string";
80
+ readonly description: "Variable type.";
81
+ readonly enum: readonly ["string", "number", "bool", "any"];
82
+ };
83
+ readonly default: {
84
+ readonly $ref: "#/$defs/variableValue";
85
+ };
86
+ readonly description: {
87
+ readonly type: "string";
88
+ };
89
+ };
90
+ };
91
+ readonly variableValue: {
92
+ readonly type: readonly ["string", "number", "boolean", "object", "array", "null"];
93
+ };
94
+ };
95
+ };
96
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8Ff,CAAC"}
package/dist/schema.js ADDED
@@ -0,0 +1,95 @@
1
+ export const clismaSchema = {
2
+ $schema: "https://json-schema.org/draft/2020-12/schema",
3
+ title: "clisma.hcl",
4
+ type: "object",
5
+ additionalProperties: false,
6
+ properties: {
7
+ env: {
8
+ type: "object",
9
+ additionalProperties: {
10
+ type: "array",
11
+ items: {
12
+ $ref: "#/$defs/envBlock",
13
+ },
14
+ },
15
+ },
16
+ variable: {
17
+ type: "object",
18
+ additionalProperties: {
19
+ type: "array",
20
+ items: {
21
+ $ref: "#/$defs/variableBlock",
22
+ },
23
+ },
24
+ },
25
+ },
26
+ $defs: {
27
+ envBlock: {
28
+ type: "object",
29
+ additionalProperties: false,
30
+ required: ["url", "migration"],
31
+ properties: {
32
+ url: {
33
+ type: "string",
34
+ description: "ClickHouse connection string.",
35
+ },
36
+ exclude: {
37
+ type: "array",
38
+ items: {
39
+ type: "string",
40
+ },
41
+ description: "Optional glob patterns to exclude tables.",
42
+ },
43
+ migration: {
44
+ type: "array",
45
+ items: {
46
+ $ref: "#/$defs/migrationBlock",
47
+ },
48
+ },
49
+ },
50
+ },
51
+ migrationBlock: {
52
+ type: "object",
53
+ additionalProperties: false,
54
+ required: ["dir"],
55
+ properties: {
56
+ dir: {
57
+ type: "string",
58
+ description: "Path to migrations directory.",
59
+ },
60
+ table_name: {
61
+ type: "string",
62
+ description: "Custom table name for migration tracking.",
63
+ },
64
+ vars: {
65
+ type: "object",
66
+ description: "Variables for Handlebars templates.",
67
+ additionalProperties: {
68
+ $ref: "#/$defs/variableValue",
69
+ },
70
+ },
71
+ },
72
+ },
73
+ variableBlock: {
74
+ type: "object",
75
+ additionalProperties: false,
76
+ required: ["type"],
77
+ properties: {
78
+ type: {
79
+ type: "string",
80
+ description: "Variable type.",
81
+ enum: ["string", "number", "bool", "any"],
82
+ },
83
+ default: {
84
+ $ref: "#/$defs/variableValue",
85
+ },
86
+ description: {
87
+ type: "string",
88
+ },
89
+ },
90
+ },
91
+ variableValue: {
92
+ type: ["string", "number", "boolean", "object", "array", "null"],
93
+ },
94
+ },
95
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parse-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-config.test.d.ts","sourceRoot":"","sources":["../../src/tests/parse-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { parseConfig } from "../config.js";
4
+ const SAMPLE_HCL = `
5
+ env "local" {
6
+ url = env("CLICKHOUSE_URL")
7
+
8
+ migrations {
9
+ dir = "migrations/\${var.ttl_days}"
10
+
11
+ vars = {
12
+ ttl = var.ttl_days
13
+ ttl_static = "var.ttl_days"
14
+ ttl_unexisting = var.non_existing_var
15
+ }
16
+ }
17
+ }
18
+
19
+ variable "ttl_days" {
20
+ type = string
21
+ default = "30"
22
+ }
23
+ `;
24
+ test("parseConfig resolves env() and var.* values", async () => {
25
+ const config = await parseConfig(SAMPLE_HCL, {
26
+ CLICKHOUSE_URL: "lol",
27
+ }, {}, "local");
28
+ assert.equal(config.url, "lol");
29
+ assert.equal(config.migrations.dir, "migrations/30");
30
+ assert.equal(config.migrations.vars?.ttl, "30");
31
+ assert.equal(config.migrations.vars?.ttl_static, "var.ttl_days");
32
+ assert.equal(config.migrations.vars?.ttl_unexisting, "");
33
+ });
@@ -0,0 +1,5 @@
1
+ export declare const resolveValue: (value: string, env?: Record<string, string | undefined>, vars?: Record<string, string>) => string;
2
+ export declare const extractValue: <T>(value: T[] | T | undefined, defaultValue: T) => T;
3
+ export declare const extractObject: <T extends Record<string, unknown>>(value: T[] | T | undefined, defaultValue: T) => T;
4
+ export declare const extractList: <T>(value: T[] | T[][] | undefined, defaultValue: T[]) => T[];
5
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,GACvB,OAAO,MAAM,EACb,MAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,EAC5C,OAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,KAChC,MAoBF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,EAC5B,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,EAC1B,cAAc,CAAC,KACd,CAKF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,EAC1B,cAAc,CAAC,KACd,CAKF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,SAAS,EAC9B,cAAc,CAAC,EAAE,KAChB,CAAC,EAYH,CAAC"}
package/dist/utils.js ADDED
@@ -0,0 +1,42 @@
1
+ export const resolveValue = (value, env = {}, vars = {}) => {
2
+ const envCallRegex = /^env\("([^"]+)"\)$/;
3
+ const varRefRegex = /^var\.(\w+)$/;
4
+ const interpolationRegex = /\$\{([^}]+)\}/g;
5
+ const resolved = value.replace(interpolationRegex, (match, expr) => {
6
+ const envExprMatch = expr.match(envCallRegex);
7
+ if (envExprMatch) {
8
+ return env[envExprMatch[1]] || "";
9
+ }
10
+ const varExprMatch = expr.match(varRefRegex);
11
+ if (varExprMatch) {
12
+ return vars[varExprMatch[1]] || "";
13
+ }
14
+ return match;
15
+ });
16
+ return resolved;
17
+ };
18
+ export const extractValue = (value, defaultValue) => {
19
+ if (Array.isArray(value) && value.length > 0) {
20
+ return value[0];
21
+ }
22
+ return value !== undefined ? value : defaultValue;
23
+ };
24
+ export const extractObject = (value, defaultValue) => {
25
+ if (Array.isArray(value)) {
26
+ return value[0] || defaultValue;
27
+ }
28
+ return value !== undefined ? value : defaultValue;
29
+ };
30
+ export const extractList = (value, defaultValue) => {
31
+ if (Array.isArray(value)) {
32
+ if (value.length === 0) {
33
+ return defaultValue;
34
+ }
35
+ const first = value[0];
36
+ if (Array.isArray(first)) {
37
+ return first;
38
+ }
39
+ return value;
40
+ }
41
+ return defaultValue;
42
+ };
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@clisma/config",
3
+ "version": "0.1.0",
4
+ "description": "Configuration parsing and schema generation for clisma",
5
+ "type": "module",
6
+ "main": "dist/config.js",
7
+ "types": "dist/config.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "dependencies": {
12
+ "@cdktf/hcl2json": "^0.21.0"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc -b tsconfig.json",
16
+ "test": "node --import tsx --test src/tests/*.test.ts",
17
+ "lint": "oxlint src",
18
+ "lint:fix": "oxlint --fix src",
19
+ "format": "oxfmt --check src",
20
+ "format:fix": "oxfmt src"
21
+ },
22
+ "devDependencies": {
23
+ "oxfmt": "^0.4.0",
24
+ "oxlint": "^0.12.0"
25
+ }
26
+ }