@flowblade/sqlduck 0.10.0 → 0.12.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,80 @@
1
+ import * as z from "zod";
2
+
3
+ //#region src/validation/zod/duck-connection-params-zod-schema.d.ts
4
+ declare const duckAllConnectionOptionsZodSchema: z.ZodObject<{
5
+ accessMode: z.ZodOptional<z.ZodEnum<{
6
+ READ_ONLY: "READ_ONLY";
7
+ READ_WRITE: "READ_WRITE";
8
+ }>>;
9
+ compress: z.ZodOptional<z.ZodBoolean>;
10
+ type: z.ZodOptional<z.ZodEnum<{
11
+ DUCKDB: "DUCKDB";
12
+ SQLITE: "SQLITE";
13
+ }>>;
14
+ blockSize: z.ZodOptional<z.ZodInt32>;
15
+ rowGroupSize: z.ZodOptional<z.ZodInt32>;
16
+ storageVersion: z.ZodOptional<z.ZodString>;
17
+ encryptionKey: z.ZodOptional<z.ZodString>;
18
+ encryptionCipher: z.ZodOptional<z.ZodEnum<{
19
+ CBC: "CBC";
20
+ CTR: "CTR";
21
+ GCM: "GCM";
22
+ }>>;
23
+ }, z.core.$strict>;
24
+ declare const duckConnectionParamsZodSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
25
+ type: z.ZodLiteral<"memory">;
26
+ alias: z.ZodString;
27
+ options: z.ZodOptional<z.ZodObject<{
28
+ accessMode: z.ZodOptional<z.ZodEnum<{
29
+ READ_ONLY: "READ_ONLY";
30
+ READ_WRITE: "READ_WRITE";
31
+ }>>;
32
+ compress: z.ZodOptional<z.ZodBoolean>;
33
+ type: z.ZodOptional<z.ZodEnum<{
34
+ DUCKDB: "DUCKDB";
35
+ SQLITE: "SQLITE";
36
+ }>>;
37
+ blockSize: z.ZodOptional<z.ZodInt32>;
38
+ rowGroupSize: z.ZodOptional<z.ZodInt32>;
39
+ storageVersion: z.ZodOptional<z.ZodString>;
40
+ encryptionKey: z.ZodOptional<z.ZodString>;
41
+ encryptionCipher: z.ZodOptional<z.ZodEnum<{
42
+ CBC: "CBC";
43
+ CTR: "CTR";
44
+ GCM: "GCM";
45
+ }>>;
46
+ }, z.core.$strict>>;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ type: z.ZodLiteral<"duckdb">;
49
+ path: z.ZodString;
50
+ alias: z.ZodString;
51
+ options: z.ZodOptional<z.ZodObject<{
52
+ accessMode: z.ZodOptional<z.ZodEnum<{
53
+ READ_ONLY: "READ_ONLY";
54
+ READ_WRITE: "READ_WRITE";
55
+ }>>;
56
+ compress: z.ZodOptional<z.ZodBoolean>;
57
+ type: z.ZodOptional<z.ZodEnum<{
58
+ DUCKDB: "DUCKDB";
59
+ SQLITE: "SQLITE";
60
+ }>>;
61
+ blockSize: z.ZodOptional<z.ZodInt32>;
62
+ rowGroupSize: z.ZodOptional<z.ZodInt32>;
63
+ storageVersion: z.ZodOptional<z.ZodString>;
64
+ encryptionKey: z.ZodOptional<z.ZodString>;
65
+ encryptionCipher: z.ZodOptional<z.ZodEnum<{
66
+ CBC: "CBC";
67
+ CTR: "CTR";
68
+ GCM: "GCM";
69
+ }>>;
70
+ }, z.core.$strict>>;
71
+ }, z.core.$strict>], "type">;
72
+ type DuckConnectionParamsZodSchema = z.infer<typeof duckConnectionParamsZodSchema>;
73
+ //#endregion
74
+ //#region src/validation/core/types.d.ts
75
+ type DuckAliasName = string;
76
+ type DuckTableName = string;
77
+ type DuckSchemaName = string;
78
+ type DuckConnectionParams = DuckConnectionParamsZodSchema;
79
+ //#endregion
80
+ export { duckAllConnectionOptionsZodSchema as a, DuckTableName as i, DuckConnectionParams as n, duckConnectionParamsZodSchema as o, DuckSchemaName as r, DuckAliasName as t };
@@ -0,0 +1,37 @@
1
+ import { a as duckAllConnectionOptionsZodSchema, i as DuckTableName, n as DuckConnectionParams, o as duckConnectionParamsZodSchema, r as DuckSchemaName, t as DuckAliasName } from "../../types-DCqYqEsa.mjs";
2
+ import * as _$zod from "zod";
3
+
4
+ //#region src/validation/zod/duck-asserts-zod.d.ts
5
+ declare function assertValidAliasName(aliasName: string): asserts aliasName is DuckAliasName;
6
+ declare function assertValidSchemaName(schemaName: string): asserts schemaName is DuckSchemaName;
7
+ declare function assertValidTableName(tableName: string): asserts tableName is DuckTableName;
8
+ //#endregion
9
+ //#region src/validation/zod/duck-validators-zod.d.ts
10
+ /**
11
+ * Common validators for duckdb parameters, tables...
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { duckValidatorsZod } from '@flowblade/sqlduck/zod';
16
+ *
17
+ * duckValidatorsZod.tableName.parse('my_table'); // valid
18
+ * duckValidatorsZod.tableName.parse('my table'); // invalid
19
+ * ```
20
+ */
21
+ declare const duckValidatorsZod: {
22
+ /**
23
+ * Validate duckdb objects names like table, alias, and schemas
24
+ * for validity.
25
+ */
26
+ readonly aliasName: _$zod.ZodString;
27
+ readonly schemaName: _$zod.ZodString;
28
+ readonly tableName: _$zod.ZodString;
29
+ };
30
+ //#endregion
31
+ //#region src/validation/zod/is-parsable-duck-dsn-zod.d.ts
32
+ declare const isParsableDuckDsnZod: (dsn: unknown) => boolean;
33
+ //#endregion
34
+ //#region src/validation/zod/parse-duck-dsn-zod.d.ts
35
+ declare const parseDuckDSNZod: (dsn: string) => DuckConnectionParams;
36
+ //#endregion
37
+ export { assertValidAliasName, assertValidSchemaName, assertValidTableName, duckAllConnectionOptionsZodSchema, duckConnectionParamsZodSchema, duckValidatorsZod, isParsableDuckDsnZod, parseDuckDSNZod };
@@ -0,0 +1,2 @@
1
+ import { a as assertValidAliasName, c as duckValidatorsZod, i as duckConnectionParamsZodSchema, n as parseDuckDSNZod, o as assertValidSchemaName, r as duckAllConnectionOptionsZodSchema, s as assertValidTableName, t as isParsableDuckDsnZod } from "../../zod-CwR_oehs.mjs";
2
+ export { assertValidAliasName, assertValidSchemaName, assertValidTableName, duckAllConnectionOptionsZodSchema, duckConnectionParamsZodSchema, duckValidatorsZod, isParsableDuckDsnZod, parseDuckDSNZod };
@@ -0,0 +1,207 @@
1
+ import * as z from "zod";
2
+ import { parseDsn } from "@httpx/dsn-parser";
3
+ //#region src/validation/core/create-assert-error.ts
4
+ const createAssertError = (msgOrErrorFactory, fallbackMsg) => {
5
+ if (typeof msgOrErrorFactory === "string" || msgOrErrorFactory === void 0) return new TypeError(msgOrErrorFactory ?? fallbackMsg ?? "Assertion did not pass.");
6
+ return msgOrErrorFactory();
7
+ };
8
+ //#endregion
9
+ //#region src/validation/core/base-validators.ts
10
+ const duckIdentifierNameRegex = /^[a-z_]\w*$/i;
11
+ const duckStorageVersionRegexp = /^v?\d{1,4}\.\d{1,4}\.\d{1,4}$/;
12
+ //#endregion
13
+ //#region src/validation/core/duck-reserved-keywords.ts
14
+ /**
15
+ * DuckDB reserved keywords that cannot be used as unquoted identifiers.
16
+ * @see https://duckdb.org/docs/sql/keywords-and-identifiers.html
17
+ */
18
+ const duckReservedKeywords = [
19
+ "ALL",
20
+ "ANALYSE",
21
+ "ANALYZE",
22
+ "AND",
23
+ "ANY",
24
+ "ARRAY",
25
+ "AS",
26
+ "ASC",
27
+ "ASYMMETRIC",
28
+ "BOTH",
29
+ "CASE",
30
+ "CAST",
31
+ "CHECK",
32
+ "COLLATE",
33
+ "COLUMN",
34
+ "CONSTRAINT",
35
+ "CREATE",
36
+ "CROSS",
37
+ "CURRENT_CATALOG",
38
+ "CURRENT_DATE",
39
+ "CURRENT_ROLE",
40
+ "CURRENT_SCHEMA",
41
+ "CURRENT_TIME",
42
+ "CURRENT_TIMESTAMP",
43
+ "CURRENT_USER",
44
+ "DEFAULT",
45
+ "DEFERRABLE",
46
+ "DESC",
47
+ "DISTINCT",
48
+ "DO",
49
+ "ELSE",
50
+ "END",
51
+ "EXCEPT",
52
+ "EXISTS",
53
+ "EXTRACT",
54
+ "FALSE",
55
+ "FETCH",
56
+ "FOR",
57
+ "FOREIGN",
58
+ "FROM",
59
+ "GRANT",
60
+ "GROUP",
61
+ "HAVING",
62
+ "IF",
63
+ "ILIKE",
64
+ "IN",
65
+ "INITIALLY",
66
+ "INNER",
67
+ "INTERSECT",
68
+ "INTO",
69
+ "IS",
70
+ "ISNULL",
71
+ "JOIN",
72
+ "LATERAL",
73
+ "LEADING",
74
+ "LEFT",
75
+ "LIKE",
76
+ "LIMIT",
77
+ "LOCALTIME",
78
+ "LOCALTIMESTAMP",
79
+ "NATURAL",
80
+ "NOT",
81
+ "NOTNULL",
82
+ "NULL",
83
+ "OFFSET",
84
+ "ON",
85
+ "ONLY",
86
+ "OR",
87
+ "ORDER",
88
+ "OUTER",
89
+ "OVERLAPS",
90
+ "PLACING",
91
+ "PRIMARY",
92
+ "REFERENCES",
93
+ "RETURNING",
94
+ "RIGHT",
95
+ "ROW",
96
+ "SELECT",
97
+ "SESSION_USER",
98
+ "SIMILAR",
99
+ "SOME",
100
+ "SYMMETRIC",
101
+ "TABLE",
102
+ "THEN",
103
+ "TO",
104
+ "TRAILING",
105
+ "TRUE",
106
+ "UNION",
107
+ "UNIQUE",
108
+ "USING",
109
+ "VARIADIC",
110
+ "VERBOSE",
111
+ "WHEN",
112
+ "WHERE",
113
+ "WINDOW",
114
+ "WITH"
115
+ ];
116
+ //#endregion
117
+ //#region src/validation/zod/duck-identifier-zod-schema.ts
118
+ const duckdbReservedKeywordsSet = new Set(duckReservedKeywords.map((k) => k.toUpperCase()));
119
+ /**
120
+ * Check whether a table name identifier is valid
121
+ */
122
+ const duckIdentifierZodSchema = z.string().min(1).max(120).regex(duckIdentifierNameRegex, "Identifier must start with a letter or underscore, and contain only letters, numbers and underscores").refine((value) => !duckdbReservedKeywordsSet.has(value.toUpperCase()), { message: `Identifier value is a DuckDB reserved keyword and cannot be used as an identifier` });
123
+ //#endregion
124
+ //#region src/validation/zod/duck-validators-zod.ts
125
+ /**
126
+ * Common validators for duckdb parameters, tables...
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * import { duckValidatorsZod } from '@flowblade/sqlduck/zod';
131
+ *
132
+ * duckValidatorsZod.tableName.parse('my_table'); // valid
133
+ * duckValidatorsZod.tableName.parse('my table'); // invalid
134
+ * ```
135
+ */
136
+ const duckValidatorsZod = {
137
+ aliasName: duckIdentifierZodSchema,
138
+ schemaName: duckIdentifierZodSchema,
139
+ tableName: duckIdentifierZodSchema
140
+ };
141
+ //#endregion
142
+ //#region src/validation/zod/duck-asserts-zod.ts
143
+ function assertValidAliasName(aliasName) {
144
+ const parsed = z.safeParse(duckValidatorsZod.aliasName, aliasName);
145
+ if (parsed.error) throw createAssertError(`'${aliasName}' is not a valid alias name: ${parsed.error.message}`);
146
+ }
147
+ function assertValidSchemaName(schemaName) {
148
+ const parsed = z.safeParse(duckValidatorsZod.schemaName, schemaName);
149
+ if (parsed.error) throw createAssertError(`'${schemaName}' is not a valid schema name: ${parsed.error.message}`);
150
+ }
151
+ function assertValidTableName(tableName) {
152
+ const parsed = z.safeParse(duckValidatorsZod.tableName, tableName);
153
+ if (parsed.error) throw createAssertError(`'${tableName}' is not a valid table name: ${parsed.error.message}`);
154
+ }
155
+ //#endregion
156
+ //#region src/validation/zod/duck-connection-params-zod-schema.ts
157
+ const duckAllConnectionOptionsZodSchema = z.strictObject({
158
+ accessMode: z.optional(z.enum(["READ_ONLY", "READ_WRITE"])),
159
+ compress: z.optional(z.boolean()),
160
+ type: z.optional(z.enum(["DUCKDB", "SQLITE"])),
161
+ blockSize: z.optional(z.int32().min(16384).max(262144)),
162
+ rowGroupSize: z.optional(z.int32().positive()),
163
+ storageVersion: z.optional(z.string().startsWith("v").regex(duckStorageVersionRegexp)),
164
+ encryptionKey: z.optional(z.string().min(8)),
165
+ encryptionCipher: z.optional(z.enum([
166
+ "CBC",
167
+ "CTR",
168
+ "GCM"
169
+ ]))
170
+ });
171
+ const duckConnectionParamsZodSchema = z.discriminatedUnion("type", [z.strictObject({
172
+ type: z.literal("memory"),
173
+ alias: duckValidatorsZod.aliasName,
174
+ options: z.optional(duckAllConnectionOptionsZodSchema)
175
+ }), z.strictObject({
176
+ type: z.literal("duckdb"),
177
+ path: z.string().min(4).endsWith(".db"),
178
+ alias: duckValidatorsZod.aliasName,
179
+ options: z.optional(duckAllConnectionOptionsZodSchema)
180
+ })]);
181
+ //#endregion
182
+ //#region src/validation/zod/parse-duck-dsn-zod.ts
183
+ const parseDuckDSNZod = (dsn) => {
184
+ const result = parseDsn(dsn);
185
+ if (!result.success) throw new Error(`Invalid DuckDB DSN - ${result.message}`);
186
+ const parsed = result.value;
187
+ const { path, ...options } = parsed.params ?? {};
188
+ return duckConnectionParamsZodSchema.parse({
189
+ type: parsed.host,
190
+ alias: parsed.db,
191
+ ...path ? { path } : {},
192
+ options: { ...options }
193
+ });
194
+ };
195
+ //#endregion
196
+ //#region src/validation/zod/is-parsable-duck-dsn-zod.ts
197
+ const isParsableDuckDsnZod = (dsn) => {
198
+ if (typeof dsn !== "string") return false;
199
+ try {
200
+ parseDuckDSNZod(dsn);
201
+ return true;
202
+ } catch {
203
+ return false;
204
+ }
205
+ };
206
+ //#endregion
207
+ export { assertValidAliasName as a, duckValidatorsZod as c, duckConnectionParamsZodSchema as i, duckReservedKeywords as l, parseDuckDSNZod as n, assertValidSchemaName as o, duckAllConnectionOptionsZodSchema as r, assertValidTableName as s, isParsableDuckDsnZod as t };
package/package.json CHANGED
@@ -1,18 +1,16 @@
1
1
  {
2
2
  "name": "@flowblade/sqlduck",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
7
7
  ".": {
8
- "import": {
9
- "types": "./dist/index.d.mts",
10
- "default": "./dist/index.mjs"
11
- },
12
- "require": {
13
- "types": "./dist/index.d.cts",
14
- "default": "./dist/index.cjs"
15
- }
8
+ "types": "./dist/index.d.mts",
9
+ "default": "./dist/index.mjs"
10
+ },
11
+ "./zod": {
12
+ "types": "./dist/validation/zod/index.d.mts",
13
+ "default": "./dist/validation/zod/index.mjs"
16
14
  },
17
15
  "./package.json": "./package.json"
18
16
  },
@@ -57,10 +55,12 @@
57
55
  "@flowblade/core": "^0.2.26",
58
56
  "@flowblade/source-duckdb": "^0.20.1",
59
57
  "@flowblade/sql-tag": "^0.3.2",
60
- "@logtape/logtape": "2.0.4",
58
+ "@httpx/assert": "^0.16.8",
59
+ "@httpx/dsn-parser": "^1.9.9",
60
+ "@httpx/plain-object": "^2.1.8",
61
+ "@logtape/logtape": "^2.0.5",
61
62
  "@standard-schema/spec": "^1.1.0",
62
- "p-mutex": "^1.0.0",
63
- "valibot": "^1.3.1",
63
+ "p-queue": "9.1.0",
64
64
  "zod": "^4.3.6"
65
65
  },
66
66
  "peerDependencies": {
@@ -68,9 +68,9 @@
68
68
  },
69
69
  "devDependencies": {
70
70
  "@belgattitude/eslint-config-bases": "8.10.0",
71
- "@dotenvx/dotenvx": "1.57.2",
71
+ "@dotenvx/dotenvx": "1.59.1",
72
72
  "@duckdb/node-api": "1.5.1-r.1",
73
- "@faker-js/faker": "10.3.0",
73
+ "@faker-js/faker": "10.4.0",
74
74
  "@flowblade/source-kysely": "^1.3.0",
75
75
  "@httpx/assert": "0.16.8",
76
76
  "@mitata/counters": "0.0.8",
@@ -78,23 +78,23 @@
78
78
  "@size-limit/file": "12.0.1",
79
79
  "@testcontainers/mssqlserver": "11.13.0",
80
80
  "@total-typescript/ts-reset": "0.6.1",
81
- "@traversable/zod": "0.0.57",
82
81
  "@types/node": "25.5.0",
83
- "@typescript-eslint/eslint-plugin": "8.57.2",
84
- "@typescript-eslint/parser": "8.57.2",
85
- "@typescript/native-preview": "7.0.0-dev.20260316.1",
86
- "@vitest/coverage-v8": "4.1.1",
87
- "@vitest/ui": "4.1.1",
82
+ "@typescript-eslint/eslint-plugin": "8.58.0",
83
+ "@typescript-eslint/parser": "8.58.0",
84
+ "@typescript/native-preview": "7.0.0-dev.20260324.1",
85
+ "@vitest/coverage-v8": "4.1.2",
86
+ "@vitest/ui": "4.1.2",
88
87
  "ansis": "4.2.0",
89
88
  "browserslist-to-esbuild": "2.1.1",
90
89
  "core-js": "3.49.0",
91
90
  "cross-env": "10.1.0",
92
91
  "es-check": "9.6.3",
92
+ "es-toolkit": "1.45.1",
93
93
  "esbuild": "0.27.4",
94
94
  "eslint": "8.57.1",
95
95
  "execa": "9.6.1",
96
96
  "is-in-ci": "2.0.0",
97
- "kysely": "0.28.14",
97
+ "kysely": "0.28.15",
98
98
  "mitata": "1.0.34",
99
99
  "npm-run-all2": "8.0.4",
100
100
  "prettier": "3.8.1",
@@ -102,16 +102,16 @@
102
102
  "regexp.escape": "2.0.1",
103
103
  "rimraf": "6.1.3",
104
104
  "size-limit": "12.0.1",
105
- "sql-formatter": "15.7.2",
105
+ "sql-formatter": "15.7.3",
106
106
  "tarn": "3.0.2",
107
107
  "tedious": "19.2.1",
108
108
  "testcontainers": "11.13.0",
109
- "tsdown": "0.21.4",
109
+ "tsdown": "0.21.7",
110
110
  "tsx": "4.21.0",
111
- "typedoc": "0.28.17",
111
+ "typedoc": "0.28.18",
112
112
  "typedoc-plugin-markdown": "4.11.0",
113
- "typescript": "5.9.3",
114
- "vitest": "4.1.1"
113
+ "typescript": "6.0.2",
114
+ "vitest": "4.1.2"
115
115
  },
116
116
  "files": [
117
117
  "dist"