@clisma/config 0.2.1 → 0.3.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/dist/config.d.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  export type MigrationConfig = {
2
2
  dir: string;
3
- table_name?: string;
4
- replication_path?: string;
3
+ table?: {
4
+ name: string;
5
+ is_replicated: boolean;
6
+ cluster_name?: string;
7
+ replication_path?: string;
8
+ };
5
9
  vars?: Record<string, unknown>;
6
10
  };
7
11
  export type TlsConfig = {
@@ -12,7 +16,6 @@ export type TlsConfig = {
12
16
  export type EnvConfig = {
13
17
  url: string;
14
18
  exclude?: string[];
15
- cluster_name?: string;
16
19
  tls?: TlsConfig;
17
20
  migrations: MigrationConfig;
18
21
  };
@@ -1 +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,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,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,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,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;AAgCF;;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,CAiJnB,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"}
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,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,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;AAmCF;;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,CAuJnB,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 CHANGED
@@ -52,22 +52,26 @@ export const parseConfig = async (content, env = {}, vars = {}, envName, sourceN
52
52
  resolvedVars[key] = value;
53
53
  }
54
54
  }
55
- // Parse optional table_name
56
- const tableName = migrationBlock.table_name
57
- ? extractValue(migrationBlock.table_name, "schema_migrations")
55
+ const tableBlock = migrationBlock.table?.[0];
56
+ const tableName = tableBlock?.name
57
+ ? extractValue(tableBlock.name, "schema_migrations")
58
58
  : "schema_migrations";
59
- const replicationPath = migrationBlock.replication_path
60
- ? resolveValue(extractValue(migrationBlock.replication_path, ""), env, variables) || undefined
59
+ const clusterName = tableBlock?.cluster_name
60
+ ? resolveValue(extractValue(tableBlock.cluster_name, ""), env, variables) ||
61
+ undefined
61
62
  : undefined;
63
+ const replicationPath = tableBlock?.replication_path
64
+ ? resolveValue(extractValue(tableBlock.replication_path, ""), env, variables) || undefined
65
+ : undefined;
66
+ const hasIsReplicated = tableBlock?.is_replicated !== undefined;
67
+ const isReplicated = hasIsReplicated
68
+ ? extractValue(tableBlock?.is_replicated, false)
69
+ : Boolean(replicationPath || clusterName);
62
70
  // Parse URL
63
71
  const url = extractValue(envBlock.url, "");
64
72
  if (!url) {
65
73
  throw new Error(`Database URL not specified for environment "${targetEnv}"`);
66
74
  }
67
- const clusterNameValue = envBlock.cluster_name
68
- ? resolveValue(extractValue(envBlock.cluster_name, ""), env, variables)
69
- : "";
70
- const clusterName = clusterNameValue || undefined;
71
75
  const tlsBlock = envBlock.tls?.[0];
72
76
  let tls;
73
77
  if (tlsBlock) {
@@ -97,12 +101,15 @@ export const parseConfig = async (content, env = {}, vars = {}, envName, sourceN
97
101
  return {
98
102
  url: resolveValue(url, env, variables),
99
103
  exclude: excludePatterns,
100
- cluster_name: clusterName,
101
104
  tls,
102
105
  migrations: {
103
106
  dir: resolveValue(migrationDir, env, variables),
104
- table_name: tableName,
105
- replication_path: replicationPath,
107
+ table: {
108
+ name: tableName,
109
+ is_replicated: isReplicated,
110
+ cluster_name: clusterName,
111
+ replication_path: replicationPath,
112
+ },
106
113
  vars: resolvedVars,
107
114
  },
108
115
  };
@@ -33,10 +33,6 @@ export declare const clismaSchema: {
33
33
  readonly type: "string";
34
34
  readonly description: "ClickHouse connection string.";
35
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
36
  readonly exclude: {
41
37
  readonly type: "array";
42
38
  readonly items: {
@@ -68,13 +64,12 @@ export declare const clismaSchema: {
68
64
  readonly type: "string";
69
65
  readonly description: "Path to migrations directory.";
70
66
  };
71
- readonly table_name: {
72
- readonly type: "string";
73
- readonly description: "Custom table name for migration tracking.";
74
- };
75
- readonly replication_path: {
76
- readonly type: "string";
77
- readonly description: "Optional replication path for the migrations table in clustered setups.";
67
+ readonly table: {
68
+ readonly type: "array";
69
+ readonly items: {
70
+ readonly $ref: "#/$defs/tableBlock";
71
+ };
72
+ readonly description: "Migrations tracking table configuration.";
78
73
  };
79
74
  readonly vars: {
80
75
  readonly type: "object";
@@ -85,6 +80,28 @@ export declare const clismaSchema: {
85
80
  };
86
81
  };
87
82
  };
83
+ readonly tableBlock: {
84
+ readonly type: "object";
85
+ readonly additionalProperties: false;
86
+ readonly properties: {
87
+ readonly name: {
88
+ readonly type: "string";
89
+ readonly description: "Custom table name for migration tracking.";
90
+ };
91
+ readonly is_replicated: {
92
+ readonly type: "boolean";
93
+ readonly description: "Whether tracking table should use ReplicatedReplacingMergeTree and ON CLUSTER.";
94
+ };
95
+ readonly cluster_name: {
96
+ readonly type: "string";
97
+ readonly description: "Optional cluster name override for ON CLUSTER when replicated mode is enabled.";
98
+ };
99
+ readonly replication_path: {
100
+ readonly type: "string";
101
+ readonly description: "Optional replication path for the migrations table in replicated setups.";
102
+ };
103
+ };
104
+ };
88
105
  readonly tlsBlock: {
89
106
  readonly type: "object";
90
107
  readonly additionalProperties: false;
@@ -1 +1 @@
1
- {"version":3,"file":"hcl-schema.d.ts","sourceRoot":"","sources":["../src/hcl-schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqIf,CAAC;AAEX,eAAO,MAAM,cAAc,QAAO,OAAO,YAExC,CAAC"}
1
+ {"version":3,"file":"hcl-schema.d.ts","sourceRoot":"","sources":["../src/hcl-schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuJf,CAAC;AAEX,eAAO,MAAM,cAAc,QAAO,OAAO,YAExC,CAAC"}
@@ -33,10 +33,6 @@ export const clismaSchema = {
33
33
  type: "string",
34
34
  description: "ClickHouse connection string.",
35
35
  },
36
- cluster_name: {
37
- type: "string",
38
- description: "Optional cluster name. When set, migrations use replicated tracking and templating.",
39
- },
40
36
  exclude: {
41
37
  type: "array",
42
38
  items: {
@@ -68,13 +64,12 @@ export const clismaSchema = {
68
64
  type: "string",
69
65
  description: "Path to migrations directory.",
70
66
  },
71
- table_name: {
72
- type: "string",
73
- description: "Custom table name for migration tracking.",
74
- },
75
- replication_path: {
76
- type: "string",
77
- description: "Optional replication path for the migrations table in clustered setups.",
67
+ table: {
68
+ type: "array",
69
+ items: {
70
+ $ref: "#/$defs/tableBlock",
71
+ },
72
+ description: "Migrations tracking table configuration.",
78
73
  },
79
74
  vars: {
80
75
  type: "object",
@@ -85,6 +80,28 @@ export const clismaSchema = {
85
80
  },
86
81
  },
87
82
  },
83
+ tableBlock: {
84
+ type: "object",
85
+ additionalProperties: false,
86
+ properties: {
87
+ name: {
88
+ type: "string",
89
+ description: "Custom table name for migration tracking.",
90
+ },
91
+ is_replicated: {
92
+ type: "boolean",
93
+ description: "Whether tracking table should use ReplicatedReplacingMergeTree and ON CLUSTER.",
94
+ },
95
+ cluster_name: {
96
+ type: "string",
97
+ description: "Optional cluster name override for ON CLUSTER when replicated mode is enabled.",
98
+ },
99
+ replication_path: {
100
+ type: "string",
101
+ description: "Optional replication path for the migrations table in replicated setups.",
102
+ },
103
+ },
104
+ },
88
105
  tlsBlock: {
89
106
  type: "object",
90
107
  additionalProperties: false,
@@ -36,6 +36,47 @@ env "prod" {
36
36
  }
37
37
  }
38
38
  `;
39
+ const SAMPLE_HCL_WITH_TABLE = `
40
+ env "prod" {
41
+ url = "http://default:password@localhost:8123/default"
42
+
43
+ migrations {
44
+ dir = "migrations"
45
+
46
+ table {
47
+ name = "custom_migrations"
48
+ is_replicated = true
49
+ replication_path = "/clickhouse/some/path"
50
+ }
51
+ }
52
+ }
53
+ `;
54
+ const SAMPLE_HCL_WITH_ONLY_REPLICATION_PATH = `
55
+ env "prod" {
56
+ url = "http://default:password@localhost:8123/default"
57
+
58
+ migrations {
59
+ dir = "migrations"
60
+
61
+ table {
62
+ replication_path = "/clickhouse/some/path"
63
+ }
64
+ }
65
+ }
66
+ `;
67
+ const SAMPLE_HCL_WITH_CLUSTER_NAME = `
68
+ env "prod" {
69
+ url = "http://default:password@localhost:8123/default"
70
+
71
+ migrations {
72
+ dir = "migrations"
73
+
74
+ table {
75
+ cluster_name = "prod-cluster"
76
+ }
77
+ }
78
+ }
79
+ `;
39
80
  test("parseConfig resolves env() and var.* values", async () => {
40
81
  const config = await parseConfig(SAMPLE_HCL, {
41
82
  CLICKHOUSE_URL: "lol",
@@ -54,6 +95,22 @@ test("parseConfig resolves TLS block and validates mTLS fields", async () => {
54
95
  assert.equal(config.tls?.cert_file, "certs/client.pem");
55
96
  assert.equal(config.tls?.key_file, "certs/client.key");
56
97
  });
98
+ test("parseConfig parses migrations.table block", async () => {
99
+ const config = await parseConfig(SAMPLE_HCL_WITH_TABLE, {}, {}, "prod");
100
+ assert.equal(config.migrations.table?.name, "custom_migrations");
101
+ assert.equal(config.migrations.table?.is_replicated, true);
102
+ assert.equal(config.migrations.table?.replication_path, "/clickhouse/some/path");
103
+ });
104
+ test("parseConfig enables replication when replication_path is set", async () => {
105
+ const config = await parseConfig(SAMPLE_HCL_WITH_ONLY_REPLICATION_PATH, {}, {}, "prod");
106
+ assert.equal(config.migrations.table?.is_replicated, true);
107
+ assert.equal(config.migrations.table?.replication_path, "/clickhouse/some/path");
108
+ });
109
+ test("parseConfig enables replication when cluster_name is set", async () => {
110
+ const config = await parseConfig(SAMPLE_HCL_WITH_CLUSTER_NAME, {}, {}, "prod");
111
+ assert.equal(config.migrations.table?.is_replicated, true);
112
+ assert.equal(config.migrations.table?.cluster_name, "prod-cluster");
113
+ });
57
114
  test("parseConfig throws when only one mTLS file is provided", async () => {
58
115
  await assert.rejects(() => parseConfig(`
59
116
  env "prod" {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clisma/config",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Configuration parsing and schema generation for clisma",
5
5
  "type": "module",
6
6
  "main": "dist/config.js",