@fjall/schema-gate 10.1.1
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 +50 -0
- package/dist/.build-source-hash +24 -0
- package/dist/.minified +1 -0
- package/dist/bin.d.ts +9 -0
- package/dist/bin.js +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/runSchemaGate.d.ts +29 -0
- package/dist/runSchemaGate.js +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.js +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Fjall Proprietary Software Licence
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fjall. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software, including all source, object, bundled, and minified forms
|
|
6
|
+
("the Software"), is the proprietary and confidential property of Fjall.
|
|
7
|
+
|
|
8
|
+
1. Permitted Use. Subject to the terms of this Licence, Fjall grants you
|
|
9
|
+
a non-exclusive, non-transferable, revocable licence to install the
|
|
10
|
+
Software via the npm registry and to execute it solely for the purpose
|
|
11
|
+
of deploying, operating, and managing your own applications and
|
|
12
|
+
infrastructure on cloud providers.
|
|
13
|
+
|
|
14
|
+
2. Restrictions. You may NOT, and may not permit any third party to:
|
|
15
|
+
(a) copy, redistribute, sublicense, sell, rent, lease, or otherwise
|
|
16
|
+
transfer the Software;
|
|
17
|
+
(b) modify, adapt, translate, or create derivative works of the Software;
|
|
18
|
+
(c) reverse engineer, decompile, disassemble, deminify, or otherwise
|
|
19
|
+
attempt to derive the source code, structure, or organisation of
|
|
20
|
+
the Software, except to the minimum extent expressly permitted by
|
|
21
|
+
applicable mandatory law;
|
|
22
|
+
(d) use the Software, or any portion of it, to develop, train, or
|
|
23
|
+
improve any product or service that competes with Fjall;
|
|
24
|
+
(e) remove, alter, or obscure any proprietary notices contained in
|
|
25
|
+
the Software;
|
|
26
|
+
(f) publish, share, or otherwise disclose the Software or its contents
|
|
27
|
+
to any third party.
|
|
28
|
+
|
|
29
|
+
3. Ownership. All right, title, and interest in and to the Software,
|
|
30
|
+
including all intellectual property rights, remain with Fjall. No
|
|
31
|
+
rights are granted except as expressly set out in this Licence.
|
|
32
|
+
|
|
33
|
+
4. Termination. This Licence terminates automatically if you breach any
|
|
34
|
+
of its terms. Upon termination you must cease all use of the Software
|
|
35
|
+
and destroy all copies in your possession.
|
|
36
|
+
|
|
37
|
+
5. Disclaimer of Warranty. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT
|
|
38
|
+
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
|
39
|
+
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
|
40
|
+
AND NON-INFRINGEMENT.
|
|
41
|
+
|
|
42
|
+
6. Limitation of Liability. IN NO EVENT SHALL FJALL BE LIABLE FOR ANY
|
|
43
|
+
INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
|
|
44
|
+
ARISING OUT OF OR RELATED TO THE SOFTWARE, EVEN IF ADVISED OF THE
|
|
45
|
+
POSSIBILITY OF SUCH DAMAGES.
|
|
46
|
+
|
|
47
|
+
7. Governing Law. This Licence is governed by the laws of England and
|
|
48
|
+
Wales, without regard to conflict of laws principles.
|
|
49
|
+
|
|
50
|
+
For commercial licensing enquiries, contact: contact@fjall.io
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"algorithm": "sha256",
|
|
4
|
+
"sources": [
|
|
5
|
+
"src"
|
|
6
|
+
],
|
|
7
|
+
"extraFiles": [
|
|
8
|
+
"../scripts/minify-dist.mjs",
|
|
9
|
+
"package.json",
|
|
10
|
+
"tsconfig.json"
|
|
11
|
+
],
|
|
12
|
+
"hash": "505139b3e780af0997b693326624892b3c01dd78547001cfcfb3901dbc749aa4",
|
|
13
|
+
"files": {
|
|
14
|
+
"src/bin.ts": "3acde81b3b914cc4",
|
|
15
|
+
"src/index.ts": "ab1151c1b7f1bc38",
|
|
16
|
+
"src/runSchemaGate.ts": "f0a4b0fec6a095de",
|
|
17
|
+
"src/types.ts": "67a71f4a53cc1e83",
|
|
18
|
+
"../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
|
|
19
|
+
"package.json": "abbd127fa295a73e",
|
|
20
|
+
"tsconfig.json": "8a11f0e3fce6a36a"
|
|
21
|
+
},
|
|
22
|
+
"outputHash": "283ec27ac60724f090ed3d911a0bd9f4e15b8be9e195d25d490a75b9b225c9ad",
|
|
23
|
+
"outputFileCount": 9
|
|
24
|
+
}
|
package/dist/.minified
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4 files minified at 2026-08-11T22:22:01.205Z
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Container entrypoint for the synthetic `fjall-schema-gate` container.
|
|
4
|
+
* Wires the real drivers into `runSchemaGate` and exits with the taxonomy
|
|
5
|
+
* code — the dependent app containers' `dependsOn: SUCCESS` turns any
|
|
6
|
+
* non-zero exit into a pre-RUNNING task stop the deployment circuit breaker
|
|
7
|
+
* can count.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var m=Object.defineProperty;var o=(e,t)=>m(e,"name",{value:t,configurable:!0});import{createFjallClickHouseClient as p}from"@fjall/clickhouse";import{getErrorMessage as s,maskSensitiveOutput as a}from"@fjall/util";import d from"pg";import{runSchemaGate as f}from"./runSchemaGate.js";import{SCHEMA_GATE_EXIT as S}from"./types.js";const{Client:g}=d,w="FjallSchemaGate",i=1e4;function r(e,t,n={}){process.stdout.write(`${JSON.stringify({timestamp:new Date().toISOString(),level:e,namespace:w,message:t,...n})}
|
|
3
|
+
`)}o(r,"log");function u(e,t){return new g({connectionString:e,connectionTimeoutMillis:i,query_timeout:i,statement_timeout:i,...t?{ssl:{rejectUnauthorized:!1}}:{}})}o(u,"buildPgClient");const C={async connectPg(e){const t=u(e,!0);try{return await t.connect(),t}catch(n){if(!/does not support SSL/i.test(s(n)))throw n;await t.end().catch(l=>{r("warn","Postgres TLS probe cleanup failed",{error:a(s(l))})}),r("info","Server does not support TLS \u2014 connecting in plaintext");const c=u(e,!1);return await c.connect(),c}},createChClient(e){return p({url:e.url,username:e.username,password:e.password,...e.caCert!==void 0?{caCert:e.caCert}:{},request_timeout:i})},sleep:o(e=>new Promise(t=>setTimeout(t,e)),"sleep"),log:r};for(const[e,t]of[["SIGTERM",143],["SIGINT",130]])process.on(e,()=>{r("warn",`Received ${e} \u2014 exiting without a verdict`),process.exit(t)});f(process.env,C).then(e=>{process.exit(e)}).catch(e=>{r("error","Gate crashed",{error:a(s(e))}),process.exit(S.configError)});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { CONNECTION_ATTEMPTS, RETRY_DELAY_MS, runSchemaGate, } from "./runSchemaGate.js";
|
|
2
|
+
export { SCHEMA_GATE_EXIT, type SchemaGateChClientOpts, type SchemaGateChHandle, type SchemaGateDeps, type SchemaGateExitCode, type SchemaGateLogLevel, type SchemaGateLogger, type SchemaGatePgHandle, } from "./types.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CONNECTION_ATTEMPTS as r,RETRY_DELAY_MS as _,runSchemaGate as e}from"./runSchemaGate.js";import{SCHEMA_GATE_EXIT as A}from"./types.js";export{r as CONNECTION_ATTEMPTS,_ as RETRY_DELAY_MS,A as SCHEMA_GATE_EXIT,e as runSchemaGate};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core gate logic for the synthetic `fjall-schema-gate` container.
|
|
3
|
+
*
|
|
4
|
+
* Reads the env contract injected by `EcsCompute` (names shared via
|
|
5
|
+
* `@fjall/util/migration` — coupled values across the construct↔runner
|
|
6
|
+
* boundary), verifies each configured target against the live database with
|
|
7
|
+
* the tolerant comparator (`actual >= expected`; rollbacks after expand-only
|
|
8
|
+
* migrations must boot), and returns an exit code from the taxonomy in
|
|
9
|
+
* `types.ts`.
|
|
10
|
+
*
|
|
11
|
+
* Connection attempts are bounded: `CONNECTION_ATTEMPTS` tries,
|
|
12
|
+
* `RETRY_DELAY_MS` apart, per target. Targets verify in parallel so the
|
|
13
|
+
* worst-case wall clock stays inside the dependent containers'
|
|
14
|
+
* `startTimeout` (120s) with headroom.
|
|
15
|
+
*/
|
|
16
|
+
import { type SchemaGateDeps, type SchemaGateExitCode } from "./types.js";
|
|
17
|
+
export declare const CONNECTION_ATTEMPTS = 3;
|
|
18
|
+
export declare const RETRY_DELAY_MS = 5000;
|
|
19
|
+
/**
|
|
20
|
+
* Bound on how long a post-verdict client close may hold up the exit path.
|
|
21
|
+
* The verdict is already in hand — a close that outlives this is abandoned
|
|
22
|
+
* (the process exits immediately after, dropping the socket).
|
|
23
|
+
*/
|
|
24
|
+
export declare const CLIENT_CLOSE_TIMEOUT_MS = 2000;
|
|
25
|
+
/**
|
|
26
|
+
* Run every configured verification target and reduce to one exit code.
|
|
27
|
+
* See `SCHEMA_GATE_EXIT` for the taxonomy and its precedence rules.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runSchemaGate(env: Record<string, string | undefined>, deps: SchemaGateDeps): Promise<SchemaGateExitCode>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var R=Object.defineProperty;var i=(e,t)=>R(e,"name",{value:t,configurable:!0});import{verifyExpectedClickHouseSchemaVersion as k}from"@fjall/clickhouse";import{maskSensitiveOutput as H}from"@fjall/util";import{EXPECTED_CH_SCHEMA_VERSION_ENV as m,EXPECTED_SCHEMA_VERSION_ENV as p,EXPECTED_SCHEMA_VERSION_TOOL_ENV as C,SCHEMA_ADMIN_PASSWORD_ENV as M,SCHEMA_ADMIN_USER_ENV as b,SCHEMA_GATE_CH_CA_CERT_ENV as P,SCHEMA_GATE_CH_DATABASE_ENV as V,SCHEMA_GATE_CH_URL_ENV as D,SCHEMA_GATE_DB_PASSWORD_ENV as G,SCHEMA_GATE_DB_URL_BASE_ENV as S,SCHEMA_GATE_DB_USER_ENV as O,verifyExpectedSchemaVersion as U}from"@fjall/util/migration";import{SCHEMA_GATE_EXIT as f}from"./types.js";const g=3,x=5e3,w=500,v="42P01",I=new Set(["60","81"]),$=2e3,L=new Set(["postgresql:","postgres:"]);class _ extends Error{static{i(this,"GateConfigError")}}function d(e){const t=e instanceof Error?e.message:String(e),a=H(t);return a.length>w?`${a.slice(0,w)}...`:a}i(d,"maskedError");function E(e,t,a){const r=e[t];if(r===void 0||r==="")throw new _(`${a}, but ${t} is missing or empty. The construct injects both together \u2014 an incomplete set points at an author override or a framework bug.`);return r}i(E,"requireEnv");function B(e,t,a){let r;try{r=new URL(e)}catch{throw new _(`${S} is not a parseable URL`)}if(!L.has(r.protocol))throw new _(`${S} has scheme '${r.protocol}' \u2014 the materialised gate supports the postgres engine family only. Set schemaGate: { materialise: false } for this service.`);return r.username=encodeURIComponent(t),r.password=encodeURIComponent(a),r.searchParams.delete("sslmode"),r.toString()}i(B,"composePgUrl");function y(e){return typeof e=="object"&&e!==null&&"code"in e&&e.code===v}i(y,"isUndefinedTableError");function A(e){if(typeof e!="object"||e===null)return!1;const t=e.code;return typeof t=="string"&&I.has(t)}i(A,"isChNeverMigratedError");async function T(e,t,a){await Promise.race([a().catch(r=>{e.log("warn",`${t} client close failed`,{error:d(r)})}),e.sleep($)])}i(T,"closeWithTimeout");async function N(e,t,a){let r;for(let n=1;n<=g;n++)try{return await a()}catch(s){if(r=s,y(s)||A(s))throw s;e.log("warn","Verification attempt failed",{target:t,attempt:n,of:g,error:d(s)}),n<g&&await e.sleep(x)}throw r}i(N,"withRetry");async function X(e,t,a){const r=`${p} is set`,n=E(e,C,r);if(n!=="prisma")throw new _(`${C}='${n}' \u2014 the materialised gate supports tool "prisma" only (a custom tool's metadata query cannot be expressed through the env contract). Set schemaGate: { materialise: false } for this service.`);const s=E(e,S,r),u=E(e,O,r),l=E(e,G,r),o=B(s,u,l);try{const c=await N(t,"postgres",async()=>{const h=await t.connectPg(o);try{return await U({tool:"prisma",expected:a,client:h})}finally{await T(t,"Postgres",()=>h.end())}});return{target:"postgres",kind:c.matches?"pass":"refused",expected:a,actual:c.actual}}catch(c){return y(c)?{target:"postgres",kind:"refused",expected:a,actual:null,detail:"migrations table absent \u2014 the database has never been migrated while the deployed image expects a schema version"}:{target:"postgres",kind:"connection-error",expected:a,detail:d(c)}}}i(X,"verifyPostgres");async function j(e,t,a){const r=`${m} is set`,n=E(e,D,r),s=E(e,b,r),u=E(e,M,r),l=e[P],o=e[V];try{const c=await N(t,"clickhouse",async()=>{const h=t.createChClient({url:n,username:s,password:u,...l!==void 0&&l!==""?{caCert:l}:{}});try{return await k({client:h,expected:a,...o!==void 0&&o!==""?{database:o}:{}})}finally{await T(t,"ClickHouse",()=>h.close())}});return{target:"clickhouse",kind:c.matches?"pass":"refused",expected:a,actual:c.actual}}catch(c){return A(c)?{target:"clickhouse",kind:"refused",expected:a,actual:null,detail:"migrations audit table absent \u2014 the ClickHouse database has never been migrated while the deployed image expects a schema version"}:{target:"clickhouse",kind:"connection-error",expected:a,detail:d(c)}}}i(j,"verifyClickHouse");async function J(e,t){const a=e[p],r=e[m],n=a!==void 0&&a!=="",s=r!==void 0&&r!=="";if(!n&&!s)return t.log("error","Nothing to verify \u2014 no expected-version env present",{hint:`neither ${p} nor ${m} is set; the construct should never materialise a gate container without one`}),f.configError;const u=[];n&&u.push(X(e,t,a)),s&&u.push(j(e,t,r));let l;try{l=await Promise.all(u)}catch(o){return o instanceof _?(t.log("error","Gate configuration invalid",{error:d(o)}),f.configError):(t.log("error","Gate failed unexpectedly",{error:d(o)}),f.configError)}for(const o of l)o.kind==="pass"?t.log("info","Schema version satisfied",{target:o.target,expected:o.expected,actual:o.actual??null}):o.kind==="refused"?t.log("error","REFUSED \u2014 schema version not satisfied",{target:o.target,expected:o.expected,actual:o.actual??null,...o.detail!==void 0?{detail:o.detail}:{}}):t.log("error","Verification target unreachable after retries",{target:o.target,expected:o.expected,attempts:g,...o.detail!==void 0?{error:o.detail}:{}});return l.some(o=>o.kind==="refused")?f.refused:l.some(o=>o.kind==="connection-error")?f.connectionError:f.pass}i(J,"runSchemaGate");export{$ as CLIENT_CLOSE_TIMEOUT_MS,g as CONNECTION_ATTEMPTS,x as RETRY_DELAY_MS,J as runSchemaGate};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit taxonomy for the materialised gate container. The dependent app
|
|
3
|
+
* containers declare `dependsOn: [{ container: "fjall-schema-gate",
|
|
4
|
+
* condition: "SUCCESS" }]`, so ANY non-zero exit stops the task pre-RUNNING
|
|
5
|
+
* and counts toward the deployment circuit breaker's stage-1 arithmetic —
|
|
6
|
+
* the codes exist for the forensic log and the deploy-time ECS tail, not for
|
|
7
|
+
* ECS itself.
|
|
8
|
+
*
|
|
9
|
+
* - `pass` (0) — every configured target verified; app containers start.
|
|
10
|
+
* - `refused` (1) — a target's live schema does not satisfy the expected
|
|
11
|
+
* version (forward skew, or a never-migrated database). The gate did its
|
|
12
|
+
* job; the deploy must roll back or the migration must land first.
|
|
13
|
+
* - `configError` (2) — the gate could not even attempt verification:
|
|
14
|
+
* missing/empty env, unsupported tool or engine family, or an internal
|
|
15
|
+
* error. Points at a construct bug or an author override.
|
|
16
|
+
* - `connectionError` (3) — a target was unreachable after the bounded
|
|
17
|
+
* retry budget. Indeterminate: the schema may be fine.
|
|
18
|
+
*
|
|
19
|
+
* Precedence when targets disagree: `configError` is detected before any
|
|
20
|
+
* connection is attempted; a verified `refused` outranks `connectionError`
|
|
21
|
+
* (a refusal is definitive evidence, an unreachable sibling is not).
|
|
22
|
+
*/
|
|
23
|
+
export declare const SCHEMA_GATE_EXIT: {
|
|
24
|
+
readonly pass: 0;
|
|
25
|
+
readonly refused: 1;
|
|
26
|
+
readonly configError: 2;
|
|
27
|
+
readonly connectionError: 3;
|
|
28
|
+
};
|
|
29
|
+
export type SchemaGateExitCode = (typeof SCHEMA_GATE_EXIT)[keyof typeof SCHEMA_GATE_EXIT];
|
|
30
|
+
export type SchemaGateLogLevel = "info" | "warn" | "error";
|
|
31
|
+
/**
|
|
32
|
+
* Structured one-line JSON log sink. The container's stdout lands in the
|
|
33
|
+
* service's CloudWatch log group (and, on abnormal stop, in the task-stop
|
|
34
|
+
* watchdog's forensic log via `stoppedReason`), so every line must be
|
|
35
|
+
* self-contained and pre-masked.
|
|
36
|
+
*/
|
|
37
|
+
export type SchemaGateLogger = (level: SchemaGateLogLevel, message: string, context?: Record<string, unknown>) => void;
|
|
38
|
+
/** Minimal Postgres handle the runner needs — `pg.Client` satisfies it. */
|
|
39
|
+
export interface SchemaGatePgHandle {
|
|
40
|
+
query(sql: string): Promise<{
|
|
41
|
+
rows: Array<Record<string, unknown>>;
|
|
42
|
+
}>;
|
|
43
|
+
end(): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/** Minimal ClickHouse handle — `@clickhouse/client` satisfies it. */
|
|
46
|
+
export interface SchemaGateChHandle {
|
|
47
|
+
query(params: {
|
|
48
|
+
query: string;
|
|
49
|
+
format: "JSONEachRow";
|
|
50
|
+
}): Promise<{
|
|
51
|
+
json(): Promise<unknown>;
|
|
52
|
+
}>;
|
|
53
|
+
close(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export interface SchemaGateChClientOpts {
|
|
56
|
+
url: string;
|
|
57
|
+
username: string;
|
|
58
|
+
password: string;
|
|
59
|
+
caCert?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Injectable seams. `bin.ts` supplies the real drivers; tests supply fakes
|
|
63
|
+
* that can express every failure shape (refusal, missing table, connect
|
|
64
|
+
* timeout) — a fake that cannot express the bug shape cannot catch it.
|
|
65
|
+
*/
|
|
66
|
+
export interface SchemaGateDeps {
|
|
67
|
+
connectPg(connectionUrl: string): Promise<SchemaGatePgHandle>;
|
|
68
|
+
createChClient(opts: SchemaGateChClientOpts): SchemaGateChHandle;
|
|
69
|
+
sleep(ms: number): Promise<void>;
|
|
70
|
+
log: SchemaGateLogger;
|
|
71
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r={pass:0,refused:1,configError:2,connectionError:3};export{r as SCHEMA_GATE_EXIT};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fjall/schema-gate",
|
|
3
|
+
"version": "10.1.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
7
|
+
"directory": "schema-gate"
|
|
8
|
+
},
|
|
9
|
+
"description": "Schema-version gate runner for the synthetic fjall-schema-gate ECS container. Verifies the deployed image's expected schema version against the live database (Postgres + ClickHouse) and exits with a structured taxonomy so a refusing task stops pre-RUNNING and trips the deployment circuit breaker.",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"bin": {
|
|
14
|
+
"fjall-schema-gate": "dist/bin.js"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"clean": "rm -rf ./dist ./sourcemaps",
|
|
30
|
+
"clean:node": "rm -rf ./node_modules",
|
|
31
|
+
"build": "npm run clean && npx tsc && node ../scripts/minify-dist.mjs dist && node ../scripts/stamp-build.mjs",
|
|
32
|
+
"prepack": "node ../scripts/check-dist-freshness.mjs",
|
|
33
|
+
"watch": "npm run build && npx tsc-watch",
|
|
34
|
+
"watch:only": "npx tsc-watch",
|
|
35
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"",
|
|
36
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\"",
|
|
37
|
+
"lint": "eslint src/",
|
|
38
|
+
"lint:fix": "eslint src/ --fix",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"typecheck": "npx tsc --noEmit"
|
|
41
|
+
},
|
|
42
|
+
"author": "",
|
|
43
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^26.1.2",
|
|
46
|
+
"@types/pg": "^8.16.0",
|
|
47
|
+
"prettier": "^3.9.6",
|
|
48
|
+
"tsc-watch": "^7.2.1",
|
|
49
|
+
"typescript": "^6.0.3",
|
|
50
|
+
"vitest": "^4.1.10"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@clickhouse/client": "^1.23.1",
|
|
54
|
+
"@fjall/clickhouse": "^10.1.1",
|
|
55
|
+
"@fjall/util": "^10.1.1",
|
|
56
|
+
"pg": "^8.16.3"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=22.0.0"
|
|
60
|
+
}
|
|
61
|
+
}
|