@astrojs/db 0.6.4 → 0.7.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/core/cli/commands/execute/index.js +30 -8
- package/dist/core/cli/commands/push/index.js +2 -2
- package/dist/core/cli/commands/shell/index.d.ts +1 -1
- package/dist/core/cli/commands/shell/index.js +23 -7
- package/dist/core/cli/index.js +2 -4
- package/dist/core/cli/migration-queries.js +3 -2
- package/dist/core/consts.d.ts +2 -2
- package/dist/core/consts.js +4 -3
- package/dist/core/errors.d.ts +3 -0
- package/dist/core/errors.js +19 -2
- package/dist/core/integration/index.js +16 -11
- package/dist/core/integration/typegen.js +2 -2
- package/dist/core/integration/vite-plugin-db.d.ts +6 -1
- package/dist/core/integration/vite-plugin-db.js +63 -36
- package/dist/core/load-file.d.ts +226 -4
- package/dist/core/load-file.js +73 -5
- package/dist/core/types.d.ts +12 -5
- package/dist/core/utils.d.ts +3 -1
- package/dist/core/utils.js +4 -0
- package/dist/runtime/config.d.ts +3 -2
- package/dist/runtime/config.js +48 -3
- package/dist/runtime/db-client.js +90 -40
- package/dist/runtime/index.d.ts +8 -1
- package/dist/runtime/index.js +32 -1
- package/dist/runtime/queries.d.ts +1 -11
- package/dist/runtime/queries.js +3 -40
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +3 -1
- package/package.json +4 -10
- package/virtual.d.ts +9 -0
package/dist/core/load-file.d.ts
CHANGED
|
@@ -1,8 +1,230 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { AstroConfig } from 'astro';
|
|
2
|
+
/**
|
|
3
|
+
* Load a user’s `astro:db` configuration file and additional configuration files provided by integrations.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolveDbConfig({ root, integrations }: AstroConfig): Promise<{
|
|
6
|
+
/** Resolved `astro:db` config, including tables added by integrations. */
|
|
7
|
+
dbConfig: {
|
|
8
|
+
tables: Record<string, {
|
|
9
|
+
deprecated: boolean;
|
|
10
|
+
columns: Record<string, {
|
|
11
|
+
type: "boolean";
|
|
12
|
+
schema: {
|
|
13
|
+
optional: boolean;
|
|
14
|
+
unique: boolean;
|
|
15
|
+
deprecated: boolean;
|
|
16
|
+
name?: string | undefined;
|
|
17
|
+
label?: string | undefined;
|
|
18
|
+
collection?: string | undefined;
|
|
19
|
+
default?: boolean | import("../runtime/types.js").SerializedSQL | undefined;
|
|
20
|
+
};
|
|
21
|
+
} | {
|
|
22
|
+
type: "number";
|
|
23
|
+
schema: ({
|
|
24
|
+
unique: boolean;
|
|
25
|
+
deprecated: boolean;
|
|
26
|
+
name?: string | undefined;
|
|
27
|
+
label?: string | undefined;
|
|
28
|
+
collection?: string | undefined;
|
|
29
|
+
} & {
|
|
30
|
+
optional: boolean;
|
|
31
|
+
primaryKey: false;
|
|
32
|
+
default?: number | import("../runtime/types.js").SerializedSQL | undefined;
|
|
33
|
+
} & {
|
|
34
|
+
references?: any | undefined;
|
|
35
|
+
}) | ({
|
|
36
|
+
unique: boolean;
|
|
37
|
+
deprecated: boolean;
|
|
38
|
+
name?: string | undefined;
|
|
39
|
+
label?: string | undefined;
|
|
40
|
+
collection?: string | undefined;
|
|
41
|
+
} & {
|
|
42
|
+
primaryKey: true;
|
|
43
|
+
optional?: false | undefined;
|
|
44
|
+
default?: undefined;
|
|
45
|
+
} & {
|
|
46
|
+
references?: any | undefined;
|
|
47
|
+
});
|
|
48
|
+
} | {
|
|
49
|
+
type: "text";
|
|
50
|
+
schema: ({
|
|
51
|
+
unique: boolean;
|
|
52
|
+
deprecated: boolean;
|
|
53
|
+
name?: string | undefined;
|
|
54
|
+
label?: string | undefined;
|
|
55
|
+
collection?: string | undefined;
|
|
56
|
+
default?: string | import("../runtime/types.js").SerializedSQL | undefined;
|
|
57
|
+
multiline?: boolean | undefined;
|
|
58
|
+
} & {
|
|
59
|
+
optional: boolean;
|
|
60
|
+
primaryKey: false;
|
|
61
|
+
} & {
|
|
62
|
+
references?: any | undefined;
|
|
63
|
+
}) | ({
|
|
64
|
+
unique: boolean;
|
|
65
|
+
deprecated: boolean;
|
|
66
|
+
name?: string | undefined;
|
|
67
|
+
label?: string | undefined;
|
|
68
|
+
collection?: string | undefined;
|
|
69
|
+
default?: string | import("../runtime/types.js").SerializedSQL | undefined;
|
|
70
|
+
multiline?: boolean | undefined;
|
|
71
|
+
} & {
|
|
72
|
+
primaryKey: true;
|
|
73
|
+
optional?: false | undefined;
|
|
74
|
+
} & {
|
|
75
|
+
references?: any | undefined;
|
|
76
|
+
});
|
|
77
|
+
} | {
|
|
78
|
+
type: "date";
|
|
79
|
+
schema: {
|
|
80
|
+
optional: boolean;
|
|
81
|
+
unique: boolean;
|
|
82
|
+
deprecated: boolean;
|
|
83
|
+
name?: string | undefined;
|
|
84
|
+
label?: string | undefined;
|
|
85
|
+
collection?: string | undefined;
|
|
86
|
+
default?: string | import("../runtime/types.js").SerializedSQL | undefined;
|
|
87
|
+
};
|
|
88
|
+
} | {
|
|
89
|
+
type: "json";
|
|
90
|
+
schema: {
|
|
91
|
+
optional: boolean;
|
|
92
|
+
unique: boolean;
|
|
93
|
+
deprecated: boolean;
|
|
94
|
+
name?: string | undefined;
|
|
95
|
+
label?: string | undefined;
|
|
96
|
+
collection?: string | undefined;
|
|
97
|
+
default?: unknown;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
indexes?: Record<string, {
|
|
101
|
+
on: (string | string[]) & (string | string[] | undefined);
|
|
102
|
+
unique?: boolean | undefined;
|
|
103
|
+
}> | undefined;
|
|
104
|
+
foreignKeys?: (Omit<{
|
|
105
|
+
columns: import("./types.js").MaybeArray<string>;
|
|
106
|
+
references: () => import("./types.js").MaybeArray<Omit<{
|
|
107
|
+
type: "number";
|
|
108
|
+
schema: ({
|
|
109
|
+
name?: string | undefined;
|
|
110
|
+
label?: string | undefined;
|
|
111
|
+
unique?: boolean | undefined;
|
|
112
|
+
deprecated?: boolean | undefined;
|
|
113
|
+
collection?: string | undefined;
|
|
114
|
+
} & {
|
|
115
|
+
primaryKey?: false | undefined;
|
|
116
|
+
optional?: boolean | undefined;
|
|
117
|
+
default?: number | import("drizzle-orm").SQL<any> | undefined;
|
|
118
|
+
} & {
|
|
119
|
+
references?: (() => any) | undefined;
|
|
120
|
+
}) | ({
|
|
121
|
+
name?: string | undefined;
|
|
122
|
+
label?: string | undefined;
|
|
123
|
+
unique?: boolean | undefined;
|
|
124
|
+
deprecated?: boolean | undefined;
|
|
125
|
+
collection?: string | undefined;
|
|
126
|
+
} & {
|
|
127
|
+
primaryKey: true;
|
|
128
|
+
optional?: false | undefined;
|
|
129
|
+
default?: undefined;
|
|
130
|
+
} & {
|
|
131
|
+
references?: (() => any) | undefined;
|
|
132
|
+
});
|
|
133
|
+
} | {
|
|
134
|
+
type: "text";
|
|
135
|
+
schema: ({
|
|
136
|
+
name?: string | undefined;
|
|
137
|
+
label?: string | undefined;
|
|
138
|
+
unique?: boolean | undefined;
|
|
139
|
+
deprecated?: boolean | undefined;
|
|
140
|
+
collection?: string | undefined;
|
|
141
|
+
default?: string | import("drizzle-orm").SQL<any> | undefined;
|
|
142
|
+
multiline?: boolean | undefined;
|
|
143
|
+
} & {
|
|
144
|
+
primaryKey?: false | undefined;
|
|
145
|
+
optional?: boolean | undefined;
|
|
146
|
+
} & {
|
|
147
|
+
references?: (() => any) | undefined;
|
|
148
|
+
}) | ({
|
|
149
|
+
name?: string | undefined;
|
|
150
|
+
label?: string | undefined;
|
|
151
|
+
unique?: boolean | undefined;
|
|
152
|
+
deprecated?: boolean | undefined;
|
|
153
|
+
collection?: string | undefined;
|
|
154
|
+
default?: string | import("drizzle-orm").SQL<any> | undefined;
|
|
155
|
+
multiline?: boolean | undefined;
|
|
156
|
+
} & {
|
|
157
|
+
primaryKey: true;
|
|
158
|
+
optional?: false | undefined;
|
|
159
|
+
} & {
|
|
160
|
+
references?: (() => any) | undefined;
|
|
161
|
+
});
|
|
162
|
+
}, "references">>;
|
|
163
|
+
}, "references"> & {
|
|
164
|
+
references: import("./types.js").MaybeArray<Omit<{
|
|
165
|
+
type: "number";
|
|
166
|
+
schema: ({
|
|
167
|
+
unique: boolean;
|
|
168
|
+
deprecated: boolean;
|
|
169
|
+
name?: string | undefined;
|
|
170
|
+
label?: string | undefined;
|
|
171
|
+
collection?: string | undefined;
|
|
172
|
+
} & {
|
|
173
|
+
optional: boolean;
|
|
174
|
+
primaryKey: false;
|
|
175
|
+
default?: number | import("../runtime/types.js").SerializedSQL | undefined;
|
|
176
|
+
} & {
|
|
177
|
+
references?: any | undefined;
|
|
178
|
+
}) | ({
|
|
179
|
+
unique: boolean;
|
|
180
|
+
deprecated: boolean;
|
|
181
|
+
name?: string | undefined;
|
|
182
|
+
label?: string | undefined;
|
|
183
|
+
collection?: string | undefined;
|
|
184
|
+
} & {
|
|
185
|
+
primaryKey: true;
|
|
186
|
+
optional?: false | undefined;
|
|
187
|
+
default?: undefined;
|
|
188
|
+
} & {
|
|
189
|
+
references?: any | undefined;
|
|
190
|
+
});
|
|
191
|
+
} | {
|
|
192
|
+
type: "text";
|
|
193
|
+
schema: ({
|
|
194
|
+
unique: boolean;
|
|
195
|
+
deprecated: boolean;
|
|
196
|
+
name?: string | undefined;
|
|
197
|
+
label?: string | undefined;
|
|
198
|
+
collection?: string | undefined;
|
|
199
|
+
default?: string | import("../runtime/types.js").SerializedSQL | undefined;
|
|
200
|
+
multiline?: boolean | undefined;
|
|
201
|
+
} & {
|
|
202
|
+
optional: boolean;
|
|
203
|
+
primaryKey: false;
|
|
204
|
+
} & {
|
|
205
|
+
references?: any | undefined;
|
|
206
|
+
}) | ({
|
|
207
|
+
unique: boolean;
|
|
208
|
+
deprecated: boolean;
|
|
209
|
+
name?: string | undefined;
|
|
210
|
+
label?: string | undefined;
|
|
211
|
+
collection?: string | undefined;
|
|
212
|
+
default?: string | import("../runtime/types.js").SerializedSQL | undefined;
|
|
213
|
+
multiline?: boolean | undefined;
|
|
214
|
+
} & {
|
|
215
|
+
primaryKey: true;
|
|
216
|
+
optional?: false | undefined;
|
|
217
|
+
} & {
|
|
218
|
+
references?: any | undefined;
|
|
219
|
+
});
|
|
220
|
+
}, "references">>;
|
|
221
|
+
})[] | undefined;
|
|
222
|
+
}>;
|
|
223
|
+
};
|
|
224
|
+
/** Dependencies imported into the user config file. */
|
|
5
225
|
dependencies: string[];
|
|
226
|
+
/** Additional `astro:db` seed file paths provided by integrations. */
|
|
227
|
+
integrationSeedPaths: (string | URL)[];
|
|
6
228
|
}>;
|
|
7
229
|
/**
|
|
8
230
|
* Bundle arbitrary `mjs` or `ts` file.
|
package/dist/core/load-file.js
CHANGED
|
@@ -1,11 +1,62 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { unlink, writeFile } from "node:fs/promises";
|
|
3
|
-
import {
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
5
|
import { build as esbuild } from "esbuild";
|
|
5
6
|
import { CONFIG_FILE_NAMES, VIRTUAL_MODULE_ID } from "./consts.js";
|
|
7
|
+
import { INTEGRATION_TABLE_CONFLICT_ERROR } from "./errors.js";
|
|
8
|
+
import { errorMap } from "./integration/error-map.js";
|
|
6
9
|
import { getConfigVirtualModContents } from "./integration/vite-plugin-db.js";
|
|
10
|
+
import { dbConfigSchema } from "./types.js";
|
|
7
11
|
import { getDbDirectoryUrl } from "./utils.js";
|
|
8
|
-
|
|
12
|
+
const isDbIntegration = (integration) => "astro:db:setup" in integration.hooks;
|
|
13
|
+
async function resolveDbConfig({ root, integrations }) {
|
|
14
|
+
const { mod, dependencies } = await loadUserConfigFile(root);
|
|
15
|
+
const userDbConfig = dbConfigSchema.parse(mod?.default ?? {}, { errorMap });
|
|
16
|
+
const dbConfig = { tables: userDbConfig.tables ?? {} };
|
|
17
|
+
const integrationDbConfigPaths = [];
|
|
18
|
+
const integrationSeedPaths = [];
|
|
19
|
+
for (const integration of integrations) {
|
|
20
|
+
if (!isDbIntegration(integration))
|
|
21
|
+
continue;
|
|
22
|
+
const { name, hooks } = integration;
|
|
23
|
+
if (hooks["astro:db:setup"]) {
|
|
24
|
+
hooks["astro:db:setup"]({
|
|
25
|
+
extendDb({ configEntrypoint, seedEntrypoint }) {
|
|
26
|
+
if (configEntrypoint) {
|
|
27
|
+
integrationDbConfigPaths.push({ name, configEntrypoint });
|
|
28
|
+
}
|
|
29
|
+
if (seedEntrypoint) {
|
|
30
|
+
integrationSeedPaths.push(seedEntrypoint);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const { name, configEntrypoint } of integrationDbConfigPaths) {
|
|
37
|
+
const loadedConfig = await loadIntegrationConfigFile(root, configEntrypoint);
|
|
38
|
+
const integrationDbConfig = dbConfigSchema.parse(loadedConfig.mod?.default ?? {}, {
|
|
39
|
+
errorMap
|
|
40
|
+
});
|
|
41
|
+
for (const key in integrationDbConfig.tables) {
|
|
42
|
+
if (key in dbConfig.tables) {
|
|
43
|
+
const isUserConflict = key in (userDbConfig.tables ?? {});
|
|
44
|
+
throw new Error(INTEGRATION_TABLE_CONFLICT_ERROR(name, key, isUserConflict));
|
|
45
|
+
} else {
|
|
46
|
+
dbConfig.tables[key] = integrationDbConfig.tables[key];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
/** Resolved `astro:db` config, including tables added by integrations. */
|
|
52
|
+
dbConfig,
|
|
53
|
+
/** Dependencies imported into the user config file. */
|
|
54
|
+
dependencies,
|
|
55
|
+
/** Additional `astro:db` seed file paths provided by integrations. */
|
|
56
|
+
integrationSeedPaths
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function loadUserConfigFile(root) {
|
|
9
60
|
let configFileUrl;
|
|
10
61
|
for (const fileName of CONFIG_FILE_NAMES) {
|
|
11
62
|
const fileUrl = new URL(fileName, getDbDirectoryUrl(root));
|
|
@@ -13,13 +64,30 @@ async function loadDbConfigFile(root) {
|
|
|
13
64
|
configFileUrl = fileUrl;
|
|
14
65
|
}
|
|
15
66
|
}
|
|
16
|
-
|
|
67
|
+
return await loadAndBundleDbConfigFile({ root, fileUrl: configFileUrl });
|
|
68
|
+
}
|
|
69
|
+
async function loadIntegrationConfigFile(root, filePathOrUrl) {
|
|
70
|
+
let fileUrl;
|
|
71
|
+
if (typeof filePathOrUrl === "string") {
|
|
72
|
+
const { resolve } = createRequire(root);
|
|
73
|
+
const resolvedFilePath = resolve(filePathOrUrl);
|
|
74
|
+
fileUrl = pathToFileURL(resolvedFilePath);
|
|
75
|
+
} else {
|
|
76
|
+
fileUrl = filePathOrUrl;
|
|
77
|
+
}
|
|
78
|
+
return await loadAndBundleDbConfigFile({ root, fileUrl });
|
|
79
|
+
}
|
|
80
|
+
async function loadAndBundleDbConfigFile({
|
|
81
|
+
root,
|
|
82
|
+
fileUrl
|
|
83
|
+
}) {
|
|
84
|
+
if (!fileUrl) {
|
|
17
85
|
return { mod: void 0, dependencies: [] };
|
|
18
86
|
}
|
|
19
87
|
const { code, dependencies } = await bundleFile({
|
|
20
88
|
virtualModContents: getConfigVirtualModContents(),
|
|
21
89
|
root,
|
|
22
|
-
fileUrl
|
|
90
|
+
fileUrl
|
|
23
91
|
});
|
|
24
92
|
return {
|
|
25
93
|
mod: await importBundledFile({ code, root }),
|
|
@@ -94,5 +162,5 @@ async function importBundledFile({
|
|
|
94
162
|
export {
|
|
95
163
|
bundleFile,
|
|
96
164
|
importBundledFile,
|
|
97
|
-
|
|
165
|
+
resolveDbConfig
|
|
98
166
|
};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
1
2
|
import { SQL } from 'drizzle-orm';
|
|
2
3
|
import { type ZodTypeDef, z } from 'zod';
|
|
3
4
|
import { type SerializedSQL } from '../runtime/types.js';
|
|
@@ -3118,11 +3119,7 @@ export type DBTable = z.infer<typeof tableSchema>;
|
|
|
3118
3119
|
export type DBTables = Record<string, DBTable>;
|
|
3119
3120
|
export type DBSnapshot = {
|
|
3120
3121
|
schema: Record<string, DBTable>;
|
|
3121
|
-
|
|
3122
|
-
* Snapshot version. Breaking changes to the snapshot format increment this number.
|
|
3123
|
-
* @todo Rename to "version" once closer to release.
|
|
3124
|
-
*/
|
|
3125
|
-
experimentalVersion: number;
|
|
3122
|
+
version: string;
|
|
3126
3123
|
};
|
|
3127
3124
|
export declare const dbConfigSchema: z.ZodObject<{
|
|
3128
3125
|
tables: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -3898,4 +3895,14 @@ interface IndexConfig<TColumns extends ColumnsConfig> extends z.input<typeof ind
|
|
|
3898
3895
|
export type ResolvedCollectionConfig<TColumns extends ColumnsConfig = ColumnsConfig> = TableConfig<TColumns>;
|
|
3899
3896
|
export type NumberColumnOpts = z.input<typeof numberColumnOptsSchema>;
|
|
3900
3897
|
export type TextColumnOpts = z.input<typeof textColumnOptsSchema>;
|
|
3898
|
+
export type AstroDbIntegration = AstroIntegration & {
|
|
3899
|
+
hooks: {
|
|
3900
|
+
'astro:db:setup'?: (options: {
|
|
3901
|
+
extendDb: (options: {
|
|
3902
|
+
configEntrypoint?: URL | string;
|
|
3903
|
+
seedEntrypoint?: URL | string;
|
|
3904
|
+
}) => void;
|
|
3905
|
+
}) => void | Promise<void>;
|
|
3906
|
+
};
|
|
3907
|
+
};
|
|
3901
3908
|
export {};
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { AstroConfig } from 'astro';
|
|
1
|
+
import type { AstroConfig, AstroIntegration } from 'astro';
|
|
2
|
+
import type { AstroDbIntegration } from './types.js';
|
|
2
3
|
export type VitePlugin = Required<AstroConfig['vite']>['plugins'][number];
|
|
3
4
|
export declare function getAstroStudioEnv(envMode?: string): Record<`ASTRO_STUDIO_${string}`, string>;
|
|
4
5
|
export declare function getRemoteDatabaseUrl(): string;
|
|
5
6
|
export declare function getAstroStudioUrl(): string;
|
|
6
7
|
export declare function getDbDirectoryUrl(root: URL | string): URL;
|
|
8
|
+
export declare function defineDbIntegration(integration: AstroDbIntegration): AstroIntegration;
|
package/dist/core/utils.js
CHANGED
|
@@ -14,7 +14,11 @@ function getAstroStudioUrl() {
|
|
|
14
14
|
function getDbDirectoryUrl(root) {
|
|
15
15
|
return new URL("db/", root);
|
|
16
16
|
}
|
|
17
|
+
function defineDbIntegration(integration) {
|
|
18
|
+
return integration;
|
|
19
|
+
}
|
|
17
20
|
export {
|
|
21
|
+
defineDbIntegration,
|
|
18
22
|
getAstroStudioEnv,
|
|
19
23
|
getAstroStudioUrl,
|
|
20
24
|
getDbDirectoryUrl,
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -141,7 +141,8 @@ export declare const column: {
|
|
|
141
141
|
};
|
|
142
142
|
};
|
|
143
143
|
export declare function defineTable<TColumns extends ColumnsConfig>(userConfig: TableConfig<TColumns>): TableConfig<TColumns>;
|
|
144
|
-
export declare function
|
|
144
|
+
export declare function defineDb(userConfig: DBConfigInput): {
|
|
145
145
|
tables?: unknown;
|
|
146
146
|
};
|
|
147
|
-
export {
|
|
147
|
+
export { NOW, TRUE, FALSE } from './index.js';
|
|
148
|
+
export { sql, eq, gt, gte, lt, lte, ne, isNull, isNotNull, inArray, notInArray, exists, notExists, between, notBetween, like, notIlike, not, asc, desc, and, or, } from 'drizzle-orm';
|
package/dist/runtime/config.js
CHANGED
|
@@ -27,16 +27,61 @@ const column = {
|
|
|
27
27
|
function defineTable(userConfig) {
|
|
28
28
|
return userConfig;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function defineDb(userConfig) {
|
|
31
31
|
return userConfig;
|
|
32
32
|
}
|
|
33
|
-
import {
|
|
33
|
+
import { NOW, TRUE, FALSE } from "./index.js";
|
|
34
|
+
import {
|
|
35
|
+
sql,
|
|
36
|
+
eq,
|
|
37
|
+
gt,
|
|
38
|
+
gte,
|
|
39
|
+
lt,
|
|
40
|
+
lte,
|
|
41
|
+
ne,
|
|
42
|
+
isNull,
|
|
43
|
+
isNotNull,
|
|
44
|
+
inArray,
|
|
45
|
+
notInArray,
|
|
46
|
+
exists,
|
|
47
|
+
notExists,
|
|
48
|
+
between,
|
|
49
|
+
notBetween,
|
|
50
|
+
like,
|
|
51
|
+
notIlike,
|
|
52
|
+
not,
|
|
53
|
+
asc,
|
|
54
|
+
desc,
|
|
55
|
+
and,
|
|
56
|
+
or
|
|
57
|
+
} from "drizzle-orm";
|
|
34
58
|
export {
|
|
35
59
|
FALSE,
|
|
36
60
|
NOW,
|
|
37
61
|
TRUE,
|
|
62
|
+
and,
|
|
63
|
+
asc,
|
|
64
|
+
between,
|
|
38
65
|
column,
|
|
39
|
-
|
|
66
|
+
defineDb,
|
|
40
67
|
defineTable,
|
|
68
|
+
desc,
|
|
69
|
+
eq,
|
|
70
|
+
exists,
|
|
71
|
+
gt,
|
|
72
|
+
gte,
|
|
73
|
+
inArray,
|
|
74
|
+
isNotNull,
|
|
75
|
+
isNull,
|
|
76
|
+
like,
|
|
77
|
+
lt,
|
|
78
|
+
lte,
|
|
79
|
+
ne,
|
|
80
|
+
not,
|
|
81
|
+
notBetween,
|
|
82
|
+
notExists,
|
|
83
|
+
notIlike,
|
|
84
|
+
notInArray,
|
|
85
|
+
or,
|
|
41
86
|
sql
|
|
42
87
|
};
|
|
@@ -5,57 +5,107 @@ import { z } from "zod";
|
|
|
5
5
|
const isWebContainer = !!process.versions?.webcontainer;
|
|
6
6
|
function createLocalDatabaseClient({ dbUrl }) {
|
|
7
7
|
const url = isWebContainer ? "file:content.db" : dbUrl;
|
|
8
|
-
const client = createClient({ url
|
|
8
|
+
const client = createClient({ url });
|
|
9
9
|
const db = drizzleLibsql(client);
|
|
10
10
|
return db;
|
|
11
11
|
}
|
|
12
|
+
const remoteResultSchema = z.object({
|
|
13
|
+
columns: z.array(z.string()),
|
|
14
|
+
columnTypes: z.array(z.string()),
|
|
15
|
+
rows: z.array(z.array(z.unknown())),
|
|
16
|
+
rowsAffected: z.number(),
|
|
17
|
+
lastInsertRowid: z.unknown().optional()
|
|
18
|
+
});
|
|
12
19
|
function createRemoteDatabaseClient(appToken, remoteDbURL) {
|
|
13
20
|
const url = new URL("/db/query", remoteDbURL);
|
|
14
|
-
const db = drizzleProxy(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const db = drizzleProxy(
|
|
22
|
+
async (sql, parameters, method) => {
|
|
23
|
+
const requestBody = { sql, args: parameters };
|
|
24
|
+
const res = await fetch(url, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${appToken}`,
|
|
28
|
+
"Content-Type": "application/json"
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify(requestBody)
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Failed to execute query.
|
|
27
35
|
Query: ${sql}
|
|
28
36
|
Full error: ${res.status} ${await res.text()}}`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
} catch (e) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
`Failed to execute query.
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
let remoteResult;
|
|
40
|
+
try {
|
|
41
|
+
const json = await res.json();
|
|
42
|
+
remoteResult = remoteResultSchema.parse(json);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Failed to execute query.
|
|
41
46
|
Query: ${sql}
|
|
42
47
|
Full error: Unexpected JSON response. ${e instanceof Error ? e.message : String(e)}`
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
const rowValues = [];
|
|
46
|
-
for (const row of rows) {
|
|
47
|
-
if (row != null && typeof row === "object") {
|
|
48
|
-
rowValues.push(Object.values(row));
|
|
48
|
+
);
|
|
49
49
|
}
|
|
50
|
+
if (method === "run")
|
|
51
|
+
return remoteResult;
|
|
52
|
+
const rowValues = [];
|
|
53
|
+
for (const row of remoteResult.rows) {
|
|
54
|
+
if (row != null && typeof row === "object") {
|
|
55
|
+
rowValues.push(Object.values(row));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (method === "get") {
|
|
59
|
+
return { rows: rowValues[0] };
|
|
60
|
+
}
|
|
61
|
+
return { rows: rowValues };
|
|
62
|
+
},
|
|
63
|
+
async (queries) => {
|
|
64
|
+
const stmts = queries.map(({ sql, params }) => ({ sql, args: params }));
|
|
65
|
+
const res = await fetch(url, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
Authorization: `Bearer ${appToken}`,
|
|
69
|
+
"Content-Type": "application/json"
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(stmts)
|
|
72
|
+
});
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Failed to execute batch queries.
|
|
76
|
+
Full error: ${res.status} ${await res.text()}}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
let remoteResults;
|
|
80
|
+
try {
|
|
81
|
+
const json = await res.json();
|
|
82
|
+
remoteResults = z.array(remoteResultSchema).parse(json);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Failed to execute batch queries.
|
|
86
|
+
Full error: Unexpected JSON response. ${e instanceof Error ? e.message : String(e)}`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
let results = [];
|
|
90
|
+
for (const [idx, rawResult] of remoteResults.entries()) {
|
|
91
|
+
if (queries[idx]?.method === "run") {
|
|
92
|
+
results.push(rawResult);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const rowValues = [];
|
|
96
|
+
for (const row of rawResult.rows) {
|
|
97
|
+
if (row != null && typeof row === "object") {
|
|
98
|
+
rowValues.push(Object.values(row));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (queries[idx]?.method === "get") {
|
|
102
|
+
results.push({ rows: rowValues[0] });
|
|
103
|
+
}
|
|
104
|
+
results.push({ rows: rowValues });
|
|
105
|
+
}
|
|
106
|
+
return results;
|
|
50
107
|
}
|
|
51
|
-
|
|
52
|
-
return { rows: rowValues[0] };
|
|
53
|
-
}
|
|
54
|
-
return { rows: rowValues };
|
|
55
|
-
});
|
|
56
|
-
db.batch = (_drizzleQueries) => {
|
|
57
|
-
throw new Error("db.batch() is not currently supported.");
|
|
58
|
-
};
|
|
108
|
+
);
|
|
59
109
|
return db;
|
|
60
110
|
}
|
|
61
111
|
export {
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -5,7 +5,14 @@ export { sql };
|
|
|
5
5
|
export type SqliteDB = LibSQLDatabase;
|
|
6
6
|
export type { Table } from './types.js';
|
|
7
7
|
export { createRemoteDatabaseClient, createLocalDatabaseClient } from './db-client.js';
|
|
8
|
-
export
|
|
8
|
+
export declare function seedLocal({ userSeedGlob, integrationSeedImports, }: {
|
|
9
|
+
userSeedGlob: Record<string, {
|
|
10
|
+
default?: () => Promise<void>;
|
|
11
|
+
}>;
|
|
12
|
+
integrationSeedImports: Array<() => Promise<{
|
|
13
|
+
default: () => Promise<void>;
|
|
14
|
+
}>>;
|
|
15
|
+
}): Promise<void>;
|
|
9
16
|
export declare function hasPrimaryKey(column: DBColumn): boolean;
|
|
10
17
|
export declare const NOW: import("drizzle-orm").SQL<unknown>;
|
|
11
18
|
export declare const TRUE: import("drizzle-orm").SQL<unknown>;
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LibsqlError } from "@libsql/client";
|
|
1
2
|
import { sql } from "drizzle-orm";
|
|
2
3
|
import {
|
|
3
4
|
customType,
|
|
@@ -6,10 +7,40 @@ import {
|
|
|
6
7
|
sqliteTable,
|
|
7
8
|
text
|
|
8
9
|
} from "drizzle-orm/sqlite-core";
|
|
10
|
+
import { SEED_DEFAULT_EXPORT_ERROR, SEED_ERROR } from "../core/errors.js";
|
|
9
11
|
import {} from "../core/types.js";
|
|
10
12
|
import { isSerializedSQL } from "./types.js";
|
|
11
13
|
import { createRemoteDatabaseClient, createLocalDatabaseClient } from "./db-client.js";
|
|
12
|
-
|
|
14
|
+
async function seedLocal({
|
|
15
|
+
// Glob all potential seed files to catch renames and deletions.
|
|
16
|
+
userSeedGlob,
|
|
17
|
+
integrationSeedImports
|
|
18
|
+
}) {
|
|
19
|
+
const seedFilePath = Object.keys(userSeedGlob)[0];
|
|
20
|
+
if (seedFilePath) {
|
|
21
|
+
const mod = userSeedGlob[seedFilePath];
|
|
22
|
+
if (!mod.default) {
|
|
23
|
+
throw new Error(SEED_DEFAULT_EXPORT_ERROR(seedFilePath));
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
await mod.default();
|
|
27
|
+
} catch (e) {
|
|
28
|
+
if (e instanceof LibsqlError) {
|
|
29
|
+
throw new Error(SEED_ERROR(e.message));
|
|
30
|
+
}
|
|
31
|
+
throw e;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const importModule of integrationSeedImports) {
|
|
35
|
+
const mod = await importModule();
|
|
36
|
+
await mod.default().catch((e) => {
|
|
37
|
+
if (e instanceof LibsqlError) {
|
|
38
|
+
throw new Error(SEED_ERROR(e.message));
|
|
39
|
+
}
|
|
40
|
+
throw e;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
13
44
|
function hasPrimaryKey(column) {
|
|
14
45
|
return "primaryKey" in column.schema && !!column.schema.primaryKey;
|
|
15
46
|
}
|