@fjall/util 0.100.0 → 0.102.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/.minified CHANGED
@@ -1 +1 @@
1
- 55 files minified at 2026-05-23T06:07:02.579Z
1
+ 57 files minified at 2026-05-23T08:39:30.171Z
package/dist/index.d.ts CHANGED
@@ -16,4 +16,4 @@ export { findInfrastructurePaths, findBoundaryPath, isInfrastructureFile, type M
16
16
  export { inferContainerFromCandidates } from "./inferContainerFromCandidates.js";
17
17
  export { RESERVED_APP_NAMES, type ReservedAppName, isReservedAppName } from "./reservedAppNames.js";
18
18
  export { deriveContentHashTag } from "./deriveContentHashTag.js";
19
- export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, PRISMA_MIGRATION_DIR_RE } from "./migration/constants.js";
19
+ export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, EXPECTED_CH_SCHEMA_VERSION_ENV, PRISMA_MIGRATION_DIR_RE, CLICKHOUSE_MIGRATION_SKIP_RE } from "./migration/constants.js";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{DNS_APEX as o,getDomainExportNames as t}from"./domainExports.js";import{toPascalCase as E,toKebab as i,toValidDatabaseName as n,toScreamingSnake as m,capitalise as s,getSafeZoneName as p}from"./caseConversion.js";import{normaliseError as S,getErrorMessage as N,hasErrorCode as R,getErrorCode as g,getErrorStack as _,formatErrorString as A}from"./errorUtils.js";import{singleton as T}from"./singleton.js";import{DANGEROUS_ENV_VARS as l,filterDangerousEnvVars as C,maskSensitiveOutput as O,parseShellArgs as I}from"./securityHelpers.js";import{sleep as P}from"./sleep.js";import{STANDARD_ENVIRONMENTS as D,STRUCTURAL_ENVIRONMENTS as M,isValidEnvironment as c,ENVIRONMENT_LABELS as v,getEnvironmentLabel as b}from"./environments.js";import{RESOURCE_CATEGORIES as L,categoriseResource as U,getExpectedDuration as F,getFriendlyResourceType as G}from"./resourceCategorisation.js";import{parseGitRemoteUrl as X}from"./gitRemoteParser.js";import{abbreviateRegion as y}from"./regions.js";import{SCOPE_VALUES as K}from"./tokenScopes.js";import{deriveRegionsFromOrgConfig as j,deriveTargets as q,deriveAllTargets as w,findTarget as z,generateTargetName as J}from"./targets.js";import{buildAppConfigPath as W}from"./appPath.js";import{findInfrastructurePaths as $,findBoundaryPath as ee,isInfrastructureFile as re}from"./findInfrastructurePaths.js";import{inferContainerFromCandidates as te}from"./inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as Ee,isReservedAppName as ie}from"./reservedAppNames.js";import{deriveContentHashTag as me}from"./deriveContentHashTag.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as pe,EXPECTED_SCHEMA_VERSION_ENV as fe,EXPECTED_SCHEMA_VERSION_TOOL_ENV as Se,PRISMA_MIGRATION_DIR_RE as Ne}from"./migration/constants.js";export{l as DANGEROUS_ENV_VARS,o as DNS_APEX,v as ENVIRONMENT_LABELS,fe as EXPECTED_SCHEMA_VERSION_ENV,Se as EXPECTED_SCHEMA_VERSION_TOOL_ENV,pe as MIGRATION_SNAPSHOT_NAME_PREFIX,Ne as PRISMA_MIGRATION_DIR_RE,Ee as RESERVED_APP_NAMES,L as RESOURCE_CATEGORIES,K as SCOPE_VALUES,D as STANDARD_ENVIRONMENTS,M as STRUCTURAL_ENVIRONMENTS,y as abbreviateRegion,W as buildAppConfigPath,s as capitalise,U as categoriseResource,w as deriveAllTargets,me as deriveContentHashTag,j as deriveRegionsFromOrgConfig,q as deriveTargets,C as filterDangerousEnvVars,ee as findBoundaryPath,$ as findInfrastructurePaths,z as findTarget,A as formatErrorString,J as generateTargetName,t as getDomainExportNames,b as getEnvironmentLabel,g as getErrorCode,N as getErrorMessage,_ as getErrorStack,F as getExpectedDuration,G as getFriendlyResourceType,p as getSafeZoneName,R as hasErrorCode,te as inferContainerFromCandidates,re as isInfrastructureFile,ie as isReservedAppName,c as isValidEnvironment,O as maskSensitiveOutput,S as normaliseError,X as parseGitRemoteUrl,I as parseShellArgs,T as singleton,P as sleep,i as toKebab,E as toPascalCase,m as toScreamingSnake,n as toValidDatabaseName};
1
+ import{DNS_APEX as o,getDomainExportNames as t}from"./domainExports.js";import{toPascalCase as a,toKebab as i,toValidDatabaseName as n,toScreamingSnake as m,capitalise as s,getSafeZoneName as S}from"./caseConversion.js";import{normaliseError as N,getErrorMessage as R,hasErrorCode as _,getErrorCode as f,getErrorStack as g,formatErrorString as A}from"./errorUtils.js";import{singleton as T}from"./singleton.js";import{DANGEROUS_ENV_VARS as I,filterDangerousEnvVars as O,maskSensitiveOutput as d,parseShellArgs as l}from"./securityHelpers.js";import{sleep as P}from"./sleep.js";import{STANDARD_ENVIRONMENTS as M,STRUCTURAL_ENVIRONMENTS as u,isValidEnvironment as c,ENVIRONMENT_LABELS as v,getEnvironmentLabel as b}from"./environments.js";import{RESOURCE_CATEGORIES as L,categoriseResource as U,getExpectedDuration as h,getFriendlyResourceType as G}from"./resourceCategorisation.js";import{parseGitRemoteUrl as X}from"./gitRemoteParser.js";import{abbreviateRegion as y}from"./regions.js";import{SCOPE_VALUES as B}from"./tokenScopes.js";import{deriveRegionsFromOrgConfig as j,deriveTargets as q,deriveAllTargets as w,findTarget as z,generateTargetName as J}from"./targets.js";import{buildAppConfigPath as W}from"./appPath.js";import{findInfrastructurePaths as $,findBoundaryPath as ee,isInfrastructureFile as re}from"./findInfrastructurePaths.js";import{inferContainerFromCandidates as te}from"./inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as ae,isReservedAppName as ie}from"./reservedAppNames.js";import{deriveContentHashTag as me}from"./deriveContentHashTag.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Se,EXPECTED_SCHEMA_VERSION_ENV as pe,EXPECTED_SCHEMA_VERSION_TOOL_ENV as Ne,EXPECTED_CH_SCHEMA_VERSION_ENV as Re,PRISMA_MIGRATION_DIR_RE as _e,CLICKHOUSE_MIGRATION_SKIP_RE as fe}from"./migration/constants.js";export{fe as CLICKHOUSE_MIGRATION_SKIP_RE,I as DANGEROUS_ENV_VARS,o as DNS_APEX,v as ENVIRONMENT_LABELS,Re as EXPECTED_CH_SCHEMA_VERSION_ENV,pe as EXPECTED_SCHEMA_VERSION_ENV,Ne as EXPECTED_SCHEMA_VERSION_TOOL_ENV,Se as MIGRATION_SNAPSHOT_NAME_PREFIX,_e as PRISMA_MIGRATION_DIR_RE,ae as RESERVED_APP_NAMES,L as RESOURCE_CATEGORIES,B as SCOPE_VALUES,M as STANDARD_ENVIRONMENTS,u as STRUCTURAL_ENVIRONMENTS,y as abbreviateRegion,W as buildAppConfigPath,s as capitalise,U as categoriseResource,w as deriveAllTargets,me as deriveContentHashTag,j as deriveRegionsFromOrgConfig,q as deriveTargets,O as filterDangerousEnvVars,ee as findBoundaryPath,$ as findInfrastructurePaths,z as findTarget,A as formatErrorString,J as generateTargetName,t as getDomainExportNames,b as getEnvironmentLabel,f as getErrorCode,R as getErrorMessage,g as getErrorStack,h as getExpectedDuration,G as getFriendlyResourceType,S as getSafeZoneName,_ as hasErrorCode,te as inferContainerFromCandidates,re as isInfrastructureFile,ie as isReservedAppName,c as isValidEnvironment,d as maskSensitiveOutput,N as normaliseError,X as parseGitRemoteUrl,l as parseShellArgs,T as singleton,P as sleep,i as toKebab,a as toPascalCase,m as toScreamingSnake,n as toValidDatabaseName};
@@ -27,8 +27,23 @@ export declare const EXPECTED_SCHEMA_VERSION_ENV: "EXPECTED_SCHEMA_VERSION";
27
27
  * runtime gate can dispatch to the matching consumer-side resolver.
28
28
  */
29
29
  export declare const EXPECTED_SCHEMA_VERSION_TOOL_ENV: "EXPECTED_SCHEMA_VERSION_TOOL";
30
+ /**
31
+ * Container env var name for the ClickHouse schema-version fail-fast gate.
32
+ * Sibling to `EXPECTED_SCHEMA_VERSION` (Postgres). Both gates can fire on
33
+ * one service when its `connections:` spans a relational DB AND a CH DB
34
+ * each declaring `migrations:`.
35
+ */
36
+ export declare const EXPECTED_CH_SCHEMA_VERSION_ENV: "EXPECTED_CH_SCHEMA_VERSION";
30
37
  /**
31
38
  * Prisma migration directory pattern: 14-digit timestamp + underscore prefix.
32
39
  * Sortable alphanumerically because the timestamp is fixed-width.
33
40
  */
34
41
  export declare const PRISMA_MIGRATION_DIR_RE: RegExp;
42
+ /**
43
+ * Files in a ClickHouse migrations dir that `runSqlMigrations` skips by
44
+ * default (dev-only SQL). Shared with `pickLatestClickHouseMigration` so the
45
+ * synth-time gate and the runtime applier agree on which file is "latest" —
46
+ * drift would inject an `EXPECTED_CH_SCHEMA_VERSION` the runner can never
47
+ * record, hard-failing every boot.
48
+ */
49
+ export declare const CLICKHOUSE_MIGRATION_SKIP_RE: RegExp;
@@ -1 +1 @@
1
- const E="fjall-premigrate",_="EXPECTED_SCHEMA_VERSION",I="EXPECTED_SCHEMA_VERSION_TOOL",O=/^\d{14}_/;export{_ as EXPECTED_SCHEMA_VERSION_ENV,I as EXPECTED_SCHEMA_VERSION_TOOL_ENV,E as MIGRATION_SNAPSHOT_NAME_PREFIX,O as PRISMA_MIGRATION_DIR_RE};
1
+ const E="fjall-premigrate",_="EXPECTED_SCHEMA_VERSION",I="EXPECTED_SCHEMA_VERSION_TOOL",S="EXPECTED_CH_SCHEMA_VERSION",C=/^\d{14}_/,O=/\.dev\.sql$/;export{O as CLICKHOUSE_MIGRATION_SKIP_RE,S as EXPECTED_CH_SCHEMA_VERSION_ENV,_ as EXPECTED_SCHEMA_VERSION_ENV,I as EXPECTED_SCHEMA_VERSION_TOOL_ENV,E as MIGRATION_SNAPSHOT_NAME_PREFIX,C as PRISMA_MIGRATION_DIR_RE};
@@ -1,4 +1,5 @@
1
- export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, PRISMA_MIGRATION_DIR_RE } from "./constants.js";
1
+ export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, EXPECTED_CH_SCHEMA_VERSION_ENV, PRISMA_MIGRATION_DIR_RE, CLICKHOUSE_MIGRATION_SKIP_RE } from "./constants.js";
2
2
  export { pickLatestPrismaMigration } from "./pickLatestPrismaMigration.js";
3
+ export { pickLatestClickHouseMigration } from "./pickLatestClickHouseMigration.js";
3
4
  export { type MigrationsSqlClient, type VerifyExpectedSchemaVersionOpts, type VerifyExpectedSchemaVersionResult, verifyExpectedSchemaVersion } from "./verifyExpectedSchemaVersion.js";
4
5
  export { CLICKHOUSE_MANAGED_USERS_ENV, MANAGED_USER_NAME_PATTERN, userPasswordEnvName, ManagedUserNameSchema, ManagedUserNamesSchema, type ManagedUserName, type ManagedUserNames } from "./clickhouseSqlUsers.js";
@@ -1 +1 @@
1
- import{MIGRATION_SNAPSHOT_NAME_PREFIX as _,EXPECTED_SCHEMA_VERSION_ENV as r,EXPECTED_SCHEMA_VERSION_TOOL_ENV as N,PRISMA_MIGRATION_DIR_RE as a}from"./constants.js";import{pickLatestPrismaMigration as A}from"./pickLatestPrismaMigration.js";import{verifyExpectedSchemaVersion as m}from"./verifyExpectedSchemaVersion.js";import{CLICKHOUSE_MANAGED_USERS_ENV as R,MANAGED_USER_NAME_PATTERN as I,userPasswordEnvName as s,ManagedUserNameSchema as t,ManagedUserNamesSchema as O}from"./clickhouseSqlUsers.js";export{R as CLICKHOUSE_MANAGED_USERS_ENV,r as EXPECTED_SCHEMA_VERSION_ENV,N as EXPECTED_SCHEMA_VERSION_TOOL_ENV,I as MANAGED_USER_NAME_PATTERN,_ as MIGRATION_SNAPSHOT_NAME_PREFIX,t as ManagedUserNameSchema,O as ManagedUserNamesSchema,a as PRISMA_MIGRATION_DIR_RE,A as pickLatestPrismaMigration,s as userPasswordEnvName,m as verifyExpectedSchemaVersion};
1
+ import{MIGRATION_SNAPSHOT_NAME_PREFIX as e,EXPECTED_SCHEMA_VERSION_ENV as r,EXPECTED_SCHEMA_VERSION_TOOL_ENV as N,EXPECTED_CH_SCHEMA_VERSION_ENV as S,PRISMA_MIGRATION_DIR_RE as a,CLICKHOUSE_MIGRATION_SKIP_RE as o}from"./constants.js";import{pickLatestPrismaMigration as I}from"./pickLatestPrismaMigration.js";import{pickLatestClickHouseMigration as R}from"./pickLatestClickHouseMigration.js";import{verifyExpectedSchemaVersion as t}from"./verifyExpectedSchemaVersion.js";import{CLICKHOUSE_MANAGED_USERS_ENV as s,MANAGED_USER_NAME_PATTERN as O,userPasswordEnvName as i,ManagedUserNameSchema as P,ManagedUserNamesSchema as T}from"./clickhouseSqlUsers.js";export{s as CLICKHOUSE_MANAGED_USERS_ENV,o as CLICKHOUSE_MIGRATION_SKIP_RE,S as EXPECTED_CH_SCHEMA_VERSION_ENV,r as EXPECTED_SCHEMA_VERSION_ENV,N as EXPECTED_SCHEMA_VERSION_TOOL_ENV,O as MANAGED_USER_NAME_PATTERN,e as MIGRATION_SNAPSHOT_NAME_PREFIX,P as ManagedUserNameSchema,T as ManagedUserNamesSchema,a as PRISMA_MIGRATION_DIR_RE,R as pickLatestClickHouseMigration,I as pickLatestPrismaMigration,i as userPasswordEnvName,t as verifyExpectedSchemaVersion};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns the lexicographically-latest ClickHouse migration filename under
3
+ * `dir` (e.g. `"011-issue-brief-citations.sql"`). Matches the file selection
4
+ * `runSqlMigrations` performs at runtime so the synth-time gate value equals
5
+ * the value the runner records in `_schema_migrations.ch_version`.
6
+ *
7
+ * Synchronous I/O — safe at both CDK synth time (the new use site) and inside
8
+ * the migration runner script (the existing applier). Throws when the
9
+ * directory contains no `.sql` files (after stripping `.dev.sql`).
10
+ */
11
+ export declare function pickLatestClickHouseMigration(dir: string): string;
@@ -0,0 +1 @@
1
+ import{readdirSync as o}from"node:fs";import{CLICKHOUSE_MIGRATION_SKIP_RE as n}from"./constants.js";function f(t){const i=o(t,{withFileTypes:!0}).filter(e=>e.isFile()).map(e=>e.name).filter(e=>e.endsWith(".sql")).filter(e=>!n.test(e)).sort(),r=i[i.length-1];if(r===void 0)throw new Error(`No ClickHouse migration files found under ${t} (looked for *.sql excluding *.dev.sql)`);return r}export{f as pickLatestClickHouseMigration};
@@ -0,0 +1 @@
1
+ import{mkdtempSync as c,mkdirSync as a,rmSync as m,writeFileSync as i}from"node:fs";import{tmpdir as f}from"node:os";import{join as s}from"node:path";import{afterEach as h,beforeEach as p,describe as n,expect as t,it as o}from"vitest";import{CLICKHOUSE_MIGRATION_SKIP_RE as l}from"./constants.js";import{pickLatestClickHouseMigration as r}from"./pickLatestClickHouseMigration.js";n("pickLatestClickHouseMigration",()=>{let e;p(()=>{e=c(s(f(),"fjall-ch-test-"))}),h(()=>{m(e,{recursive:!0,force:!0})}),o("returns the lexicographically-latest *.sql filename",()=>{i(s(e,"001-schema.sql"),""),i(s(e,"010-issue-briefs.sql"),""),i(s(e,"005-optimisation-mvs.sql"),""),t(r(e)).toBe("010-issue-briefs.sql")}),o("skips *.dev.sql so synth and runner agree on 'latest'",()=>{i(s(e,"001-schema.sql"),""),i(s(e,"002-permissions.sql"),""),i(s(e,"999-local-only.dev.sql"),""),t(r(e)).toBe("002-permissions.sql")}),o("ignores non-SQL files (shell backfills, configs)",()=>{i(s(e,"001-schema.sql"),""),i(s(e,"009-mv-ttl-backfill.sh"),""),i(s(e,"users.xml"),""),i(s(e,"config.xml"),""),t(r(e)).toBe("001-schema.sql")}),o("ignores subdirectories that look like SQL",()=>{i(s(e,"001-schema.sql"),""),a(s(e,"999-not-a-file.sql")),t(r(e)).toBe("001-schema.sql")}),o("throws when the directory contains no eligible SQL files",()=>{i(s(e,"999-only.dev.sql"),""),i(s(e,"config.xml"),""),t(()=>r(e)).toThrow(/No ClickHouse migration files found/)}),o("throws on an empty directory",()=>{t(()=>r(e)).toThrow(/No ClickHouse migration files found/)})}),n("CLICKHOUSE_MIGRATION_SKIP_RE",()=>{o("matches *.dev.sql",()=>{t(l.test("001-users.dev.sql")).toBe(!0)}),o("rejects bare *.sql",()=>{t(l.test("001-schema.sql")).toBe(!1)}),o("regex identity pin \u2014 drift here decouples synth gate from runner applier",()=>{t(l.source).toBe(String.raw`\.dev\.sql$`)})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/util",
3
- "version": "0.100.0",
3
+ "version": "0.102.0",
4
4
  "description": "Common utility methods",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -117,5 +117,5 @@
117
117
  "engines": {
118
118
  "node": ">=22.0.0"
119
119
  },
120
- "gitHead": "9eb16c56de49e6757cfd6352ad860dd125c6c21e"
120
+ "gitHead": "04a4f13181c261cc063786eae527fa82c90a610e"
121
121
  }