@astrojs/db 0.8.0 → 0.8.2
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/_internal/core/errors.d.ts +14 -0
- package/dist/_internal/core/integration/error-map.d.ts +6 -0
- package/dist/_internal/core/schemas.d.ts +3856 -0
- package/dist/_internal/core/types.d.ts +55 -0
- package/dist/_internal/core/utils.d.ts +19 -0
- package/dist/_internal/runtime/config.d.ts +148 -0
- package/dist/_internal/runtime/db-client.d.ts +5 -0
- package/dist/_internal/runtime/index.d.ts +31 -0
- package/dist/_internal/runtime/queries.d.ts +71 -0
- package/dist/_internal/runtime/seed-local.d.ts +10 -0
- package/dist/_internal/runtime/types.d.ts +69 -0
- package/dist/core/cli/commands/link/index.js +61 -52
- package/dist/core/cli/commands/push/index.js +16 -13
- package/dist/core/cli/migration-queries.js +15 -12
- package/dist/core/cli/print-help.js +1 -1
- package/dist/core/integration/typegen.js +1 -2
- package/dist/core/schemas.d.ts +5 -5
- package/dist/core/schemas.js +1 -1
- package/dist/core/tokens.js +36 -15
- package/dist/core/utils.d.ts +11 -0
- package/dist/core/utils.js +11 -1
- package/dist/runtime/db-client.js +33 -26
- package/package.json +5 -4
- package/virtual.d.ts +31 -7
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
-
import { DB_TYPES_FILE,
|
|
3
|
+
import { DB_TYPES_FILE, RUNTIME_IMPORT } from "../consts.js";
|
|
4
4
|
async function typegen({ tables, root }) {
|
|
5
5
|
const content = `// This file is generated by \`studio sync\`
|
|
6
6
|
declare module 'astro:db' {
|
|
7
7
|
export const db: import(${RUNTIME_IMPORT}).SqliteDB;
|
|
8
8
|
export const dbUrl: string;
|
|
9
|
-
export * from ${RUNTIME_CONFIG_IMPORT};
|
|
10
9
|
|
|
11
10
|
${Object.entries(tables).map(([name, collection]) => generateTableType(name, collection)).join("\n")}
|
|
12
11
|
}
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -578,7 +578,7 @@ export declare const jsonColumnSchema: z.ZodObject<{
|
|
|
578
578
|
default?: unknown;
|
|
579
579
|
};
|
|
580
580
|
}>;
|
|
581
|
-
export declare const columnSchema: z.
|
|
581
|
+
export declare const columnSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
582
582
|
type: z.ZodLiteral<"boolean">;
|
|
583
583
|
schema: z.ZodObject<{
|
|
584
584
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -1379,7 +1379,7 @@ export declare const referenceableColumnSchema: z.ZodUnion<[z.ZodObject<{
|
|
|
1379
1379
|
references?: (() => z.input<typeof numberColumnSchema>) | undefined;
|
|
1380
1380
|
});
|
|
1381
1381
|
}>]>;
|
|
1382
|
-
export declare const columnsSchema: z.ZodRecord<z.ZodString, z.
|
|
1382
|
+
export declare const columnsSchema: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
1383
1383
|
type: z.ZodLiteral<"boolean">;
|
|
1384
1384
|
schema: z.ZodObject<{
|
|
1385
1385
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -1871,7 +1871,7 @@ type ForeignKeysOutput = Omit<ForeignKeysInput, 'references'> & {
|
|
|
1871
1871
|
references: MaybeArray<Omit<z.output<typeof referenceableColumnSchema>, 'references'>>;
|
|
1872
1872
|
};
|
|
1873
1873
|
export declare const tableSchema: z.ZodObject<{
|
|
1874
|
-
columns: z.ZodRecord<z.ZodString, z.
|
|
1874
|
+
columns: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
1875
1875
|
type: z.ZodLiteral<"boolean">;
|
|
1876
1876
|
schema: z.ZodObject<{
|
|
1877
1877
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -2441,7 +2441,7 @@ export declare const tableSchema: z.ZodObject<{
|
|
|
2441
2441
|
deprecated?: boolean | undefined;
|
|
2442
2442
|
}>;
|
|
2443
2443
|
export declare const tablesSchema: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
2444
|
-
columns: z.ZodRecord<z.ZodString, z.
|
|
2444
|
+
columns: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
2445
2445
|
type: z.ZodLiteral<"boolean">;
|
|
2446
2446
|
schema: z.ZodObject<{
|
|
2447
2447
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -3101,7 +3101,7 @@ export declare const tablesSchema: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodOb
|
|
|
3101
3101
|
}>, unknown>;
|
|
3102
3102
|
export declare const dbConfigSchema: z.ZodObject<{
|
|
3103
3103
|
tables: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
3104
|
-
columns: z.ZodRecord<z.ZodString, z.
|
|
3104
|
+
columns: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
3105
3105
|
type: z.ZodLiteral<"boolean">;
|
|
3106
3106
|
schema: z.ZodObject<{
|
|
3107
3107
|
name: z.ZodOptional<z.ZodString>;
|
package/dist/core/schemas.js
CHANGED
package/dist/core/tokens.js
CHANGED
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { MISSING_PROJECT_ID_ERROR, MISSING_SESSION_ID_ERROR } from "./errors.js";
|
|
6
|
-
import { getAstroStudioEnv, getAstroStudioUrl } from "./utils.js";
|
|
6
|
+
import { getAstroStudioEnv, getAstroStudioUrl, getRemoteDatabaseUrl, safeFetch } from "./utils.js";
|
|
7
7
|
const SESSION_LOGIN_FILE = pathToFileURL(join(homedir(), ".astro", "session-token"));
|
|
8
8
|
const PROJECT_ID_FILE = pathToFileURL(join(process.cwd(), ".astro", "link"));
|
|
9
9
|
class ManagedLocalAppToken {
|
|
@@ -19,21 +19,35 @@ class ManagedLocalAppToken {
|
|
|
19
19
|
class ManagedRemoteAppToken {
|
|
20
20
|
token;
|
|
21
21
|
session;
|
|
22
|
+
region;
|
|
22
23
|
projectId;
|
|
23
24
|
ttl;
|
|
24
25
|
renewTimer;
|
|
26
|
+
static async getRegionCode() {
|
|
27
|
+
const pingResponse = await safeFetch(new URL(`${getRemoteDatabaseUrl()}/ping`));
|
|
28
|
+
const pingResult = await pingResponse.json();
|
|
29
|
+
return pingResult.data.region;
|
|
30
|
+
}
|
|
25
31
|
static async create(sessionToken, projectId) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const region = await ManagedRemoteAppToken.getRegionCode();
|
|
33
|
+
const response = await safeFetch(
|
|
34
|
+
new URL(`${getAstroStudioUrl()}/auth/cli/token-create`),
|
|
35
|
+
{
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: new Headers({
|
|
38
|
+
Authorization: `Bearer ${sessionToken}`
|
|
39
|
+
}),
|
|
40
|
+
body: JSON.stringify({ projectId, region })
|
|
41
|
+
},
|
|
42
|
+
(res) => {
|
|
43
|
+
throw new Error(`Failed to create token: ${res.status} ${res.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
33
46
|
const { token: shortLivedAppToken, ttl } = await response.json();
|
|
34
47
|
return new ManagedRemoteAppToken({
|
|
35
48
|
token: shortLivedAppToken,
|
|
36
49
|
session: sessionToken,
|
|
50
|
+
region,
|
|
37
51
|
projectId,
|
|
38
52
|
ttl
|
|
39
53
|
});
|
|
@@ -41,19 +55,26 @@ class ManagedRemoteAppToken {
|
|
|
41
55
|
constructor(options) {
|
|
42
56
|
this.token = options.token;
|
|
43
57
|
this.session = options.session;
|
|
58
|
+
this.region = options.region;
|
|
44
59
|
this.projectId = options.projectId;
|
|
45
60
|
this.ttl = options.ttl;
|
|
46
61
|
this.renewTimer = setTimeout(() => this.renew(), 1e3 * 60 * 5 / 2);
|
|
47
62
|
}
|
|
48
63
|
async fetch(url, body) {
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
return safeFetch(
|
|
65
|
+
`${getAstroStudioUrl()}${url}`,
|
|
66
|
+
{
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${this.session}`,
|
|
70
|
+
"Content-Type": "application/json"
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({ ...body, region: this.region })
|
|
54
73
|
},
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
() => {
|
|
75
|
+
throw new Error(`Failed to fetch ${url}.`);
|
|
76
|
+
}
|
|
77
|
+
);
|
|
57
78
|
}
|
|
58
79
|
async renew() {
|
|
59
80
|
clearTimeout(this.renewTimer);
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -6,3 +6,14 @@ export declare function getRemoteDatabaseUrl(): string;
|
|
|
6
6
|
export declare function getAstroStudioUrl(): string;
|
|
7
7
|
export declare function getDbDirectoryUrl(root: URL | string): URL;
|
|
8
8
|
export declare function defineDbIntegration(integration: AstroDbIntegration): AstroIntegration;
|
|
9
|
+
/**
|
|
10
|
+
* Small wrapper around fetch that throws an error if the response is not OK. Allows for custom error handling as well through the onNotOK callback.
|
|
11
|
+
*/
|
|
12
|
+
export declare function safeFetch(url: Parameters<typeof fetch>[0], options?: Parameters<typeof fetch>[1], onNotOK?: (response: Response) => void | Promise<void>): Promise<Response>;
|
|
13
|
+
export type Result<T> = {
|
|
14
|
+
success: true;
|
|
15
|
+
data: T;
|
|
16
|
+
} | {
|
|
17
|
+
success: false;
|
|
18
|
+
data: unknown;
|
|
19
|
+
};
|
package/dist/core/utils.js
CHANGED
|
@@ -17,10 +17,20 @@ function getDbDirectoryUrl(root) {
|
|
|
17
17
|
function defineDbIntegration(integration) {
|
|
18
18
|
return integration;
|
|
19
19
|
}
|
|
20
|
+
async function safeFetch(url, options = {}, onNotOK = () => {
|
|
21
|
+
throw new Error(`Request to ${url} returned a non-OK status code.`);
|
|
22
|
+
}) {
|
|
23
|
+
const response = await fetch(url, options);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
await onNotOK(response);
|
|
26
|
+
}
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
20
29
|
export {
|
|
21
30
|
defineDbIntegration,
|
|
22
31
|
getAstroStudioEnv,
|
|
23
32
|
getAstroStudioUrl,
|
|
24
33
|
getDbDirectoryUrl,
|
|
25
|
-
getRemoteDatabaseUrl
|
|
34
|
+
getRemoteDatabaseUrl,
|
|
35
|
+
safeFetch
|
|
26
36
|
};
|
|
@@ -2,6 +2,7 @@ import { createClient } from "@libsql/client";
|
|
|
2
2
|
import { drizzle as drizzleLibsql } from "drizzle-orm/libsql";
|
|
3
3
|
import { drizzle as drizzleProxy } from "drizzle-orm/sqlite-proxy";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { safeFetch } from "../core/utils.js";
|
|
5
6
|
const isWebContainer = !!process.versions?.webcontainer;
|
|
6
7
|
function createLocalDatabaseClient({ dbUrl }) {
|
|
7
8
|
const url = isWebContainer ? "file:content.db" : dbUrl;
|
|
@@ -21,21 +22,24 @@ function createRemoteDatabaseClient(appToken, remoteDbURL) {
|
|
|
21
22
|
const db = drizzleProxy(
|
|
22
23
|
async (sql, parameters, method) => {
|
|
23
24
|
const requestBody = { sql, args: parameters };
|
|
24
|
-
const res = await
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const res = await safeFetch(
|
|
26
|
+
url,
|
|
27
|
+
{
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: `Bearer ${appToken}`,
|
|
31
|
+
"Content-Type": "application/json"
|
|
32
|
+
},
|
|
33
|
+
body: JSON.stringify(requestBody)
|
|
29
34
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
throw new Error(
|
|
34
|
-
`Failed to execute query.
|
|
35
|
+
(response) => {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Failed to execute query.
|
|
35
38
|
Query: ${sql}
|
|
36
|
-
Full error: ${
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
Full error: ${response.status} ${response.statusText}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
);
|
|
39
43
|
let remoteResult;
|
|
40
44
|
try {
|
|
41
45
|
const json = await res.json();
|
|
@@ -62,20 +66,23 @@ Full error: Unexpected JSON response. ${e instanceof Error ? e.message : String(
|
|
|
62
66
|
},
|
|
63
67
|
async (queries) => {
|
|
64
68
|
const stmts = queries.map(({ sql, params }) => ({ sql, args: params }));
|
|
65
|
-
const res = await
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
const res = await safeFetch(
|
|
70
|
+
url,
|
|
71
|
+
{
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
Authorization: `Bearer ${appToken}`,
|
|
75
|
+
"Content-Type": "application/json"
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify(stmts)
|
|
70
78
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
+
(response) => {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Failed to execute batch queries.
|
|
82
|
+
Full error: ${response.status} ${response.statusText}}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
);
|
|
79
86
|
let remoteResults;
|
|
80
87
|
try {
|
|
81
88
|
const json = await res.json();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/db",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -80,11 +80,12 @@
|
|
|
80
80
|
"mocha": "^10.2.0",
|
|
81
81
|
"typescript": "^5.2.2",
|
|
82
82
|
"vite": "^5.1.4",
|
|
83
|
-
"astro
|
|
84
|
-
"astro": "
|
|
83
|
+
"astro": "4.5.3",
|
|
84
|
+
"astro-scripts": "0.0.14"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
|
-
"
|
|
87
|
+
"types:config": "tsc -p ./tsconfig.config-types.json",
|
|
88
|
+
"build": "astro-scripts build \"src/**/*.ts\" && tsc && pnpm types:config",
|
|
88
89
|
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
|
89
90
|
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
|
90
91
|
"test": "mocha --exit --timeout 20000 \"test/*.js\" \"test/unit/**/*.js\"",
|
package/virtual.d.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
declare module 'astro:db' {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const
|
|
5
|
-
export const
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
2
|
+
type RuntimeConfig = typeof import('./dist/_internal/runtime/config.js');
|
|
3
|
+
|
|
4
|
+
export const sql: RuntimeConfig['sql'];
|
|
5
|
+
export const NOW: RuntimeConfig['NOW'];
|
|
6
|
+
export const TRUE: RuntimeConfig['TRUE'];
|
|
7
|
+
export const FALSE: RuntimeConfig['FALSE'];
|
|
8
|
+
export const column: RuntimeConfig['column'];
|
|
9
|
+
export const defineDb: RuntimeConfig['defineDb'];
|
|
10
|
+
export const defineTable: RuntimeConfig['defineTable'];
|
|
11
|
+
|
|
12
|
+
export const eq: RuntimeConfig['eq'];
|
|
13
|
+
export const gt: RuntimeConfig['gt'];
|
|
14
|
+
export const gte: RuntimeConfig['gte'];
|
|
15
|
+
export const lt: RuntimeConfig['lt'];
|
|
16
|
+
export const lte: RuntimeConfig['lte'];
|
|
17
|
+
export const ne: RuntimeConfig['ne'];
|
|
18
|
+
export const isNull: RuntimeConfig['isNull'];
|
|
19
|
+
export const isNotNull: RuntimeConfig['isNotNull'];
|
|
20
|
+
export const inArray: RuntimeConfig['inArray'];
|
|
21
|
+
export const notInArray: RuntimeConfig['notInArray'];
|
|
22
|
+
export const exists: RuntimeConfig['exists'];
|
|
23
|
+
export const notExists: RuntimeConfig['notExists'];
|
|
24
|
+
export const between: RuntimeConfig['between'];
|
|
25
|
+
export const notBetween: RuntimeConfig['notBetween'];
|
|
26
|
+
export const like: RuntimeConfig['like'];
|
|
27
|
+
export const notIlike: RuntimeConfig['notIlike'];
|
|
28
|
+
export const not: RuntimeConfig['not'];
|
|
29
|
+
export const asc: RuntimeConfig['asc'];
|
|
30
|
+
export const desc: RuntimeConfig['desc'];
|
|
31
|
+
export const and: RuntimeConfig['and'];
|
|
32
|
+
export const or: RuntimeConfig['or'];
|
|
9
33
|
}
|