@astrojs/db 0.0.0-10646-20240402132948
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 +59 -0
- package/README.md +38 -0
- package/dist/_internal/core/integration/error-map.d.ts +6 -0
- package/dist/_internal/core/schemas.d.ts +4034 -0
- package/dist/_internal/core/types.d.ts +59 -0
- package/dist/_internal/core/utils.d.ts +20 -0
- package/dist/_internal/runtime/config.d.ts +154 -0
- package/dist/_internal/runtime/types.d.ts +69 -0
- package/dist/core/cli/commands/execute/index.d.ts +8 -0
- package/dist/core/cli/commands/execute/index.js +66 -0
- package/dist/core/cli/commands/link/index.d.ts +20 -0
- package/dist/core/cli/commands/link/index.js +252 -0
- package/dist/core/cli/commands/login/index.d.ts +8 -0
- package/dist/core/cli/commands/login/index.js +55 -0
- package/dist/core/cli/commands/logout/index.d.ts +1 -0
- package/dist/core/cli/commands/logout/index.js +9 -0
- package/dist/core/cli/commands/push/index.d.ts +8 -0
- package/dist/core/cli/commands/push/index.js +93 -0
- package/dist/core/cli/commands/shell/index.d.ts +8 -0
- package/dist/core/cli/commands/shell/index.js +33 -0
- package/dist/core/cli/commands/verify/index.d.ts +8 -0
- package/dist/core/cli/commands/verify/index.js +46 -0
- package/dist/core/cli/index.d.ts +6 -0
- package/dist/core/cli/index.js +76 -0
- package/dist/core/cli/migration-queries.d.ts +23 -0
- package/dist/core/cli/migration-queries.js +386 -0
- package/dist/core/cli/print-help.d.ts +11 -0
- package/dist/core/cli/print-help.js +55 -0
- package/dist/core/consts.d.ts +8 -0
- package/dist/core/consts.js +21 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.js +56 -0
- package/dist/core/integration/error-map.d.ts +6 -0
- package/dist/core/integration/error-map.js +79 -0
- package/dist/core/integration/file-url.d.ts +2 -0
- package/dist/core/integration/file-url.js +81 -0
- package/dist/core/integration/index.d.ts +2 -0
- package/dist/core/integration/index.js +160 -0
- package/dist/core/integration/typegen.d.ts +7 -0
- package/dist/core/integration/typegen.js +33 -0
- package/dist/core/integration/vite-plugin-db.d.ts +39 -0
- package/dist/core/integration/vite-plugin-db.js +134 -0
- package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +11 -0
- package/dist/core/integration/vite-plugin-inject-env-ts.js +53 -0
- package/dist/core/load-file.d.ts +253 -0
- package/dist/core/load-file.js +170 -0
- package/dist/core/schemas.d.ts +4034 -0
- package/dist/core/schemas.js +186 -0
- package/dist/core/tokens.d.ts +11 -0
- package/dist/core/tokens.js +181 -0
- package/dist/core/types.d.ts +59 -0
- package/dist/core/types.js +0 -0
- package/dist/core/utils.d.ts +20 -0
- package/dist/core/utils.js +32 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +8 -0
- package/dist/runtime/config.js +111 -0
- package/dist/runtime/db-client.d.ts +6 -0
- package/dist/runtime/db-client.js +148 -0
- package/dist/runtime/drizzle.d.ts +1 -0
- package/dist/runtime/drizzle.js +48 -0
- package/dist/runtime/errors.d.ts +5 -0
- package/dist/runtime/errors.js +31 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.js +131 -0
- package/dist/runtime/queries.d.ts +71 -0
- package/dist/runtime/queries.js +169 -0
- package/dist/runtime/seed-local.d.ts +10 -0
- package/dist/runtime/seed-local.js +55 -0
- package/dist/runtime/types.d.ts +69 -0
- package/dist/runtime/types.js +8 -0
- package/dist/runtime/utils.d.ts +8 -0
- package/dist/runtime/utils.js +17 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +6 -0
- package/index.d.ts +3 -0
- package/package.json +95 -0
- package/virtual.d.ts +45 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
async function copyFile(toDir, fromUrl, toUrl) {
|
|
5
|
+
await fs.promises.mkdir(toDir, { recursive: true });
|
|
6
|
+
await fs.promises.rename(fromUrl, toUrl);
|
|
7
|
+
}
|
|
8
|
+
function fileURLIntegration() {
|
|
9
|
+
const fileNames = [];
|
|
10
|
+
function createVitePlugin(command) {
|
|
11
|
+
let referenceIds = [];
|
|
12
|
+
return {
|
|
13
|
+
name: "@astrojs/db/file-url",
|
|
14
|
+
enforce: "pre",
|
|
15
|
+
async load(id) {
|
|
16
|
+
if (id.endsWith("?fileurl")) {
|
|
17
|
+
const filePath = id.slice(0, id.indexOf("?"));
|
|
18
|
+
if (command === "build") {
|
|
19
|
+
const data = await fs.promises.readFile(filePath);
|
|
20
|
+
const name = path.basename(filePath);
|
|
21
|
+
const referenceId = this.emitFile({
|
|
22
|
+
name,
|
|
23
|
+
source: data,
|
|
24
|
+
type: "asset"
|
|
25
|
+
});
|
|
26
|
+
referenceIds.push(referenceId);
|
|
27
|
+
return `export default import.meta.ROLLUP_FILE_URL_${referenceId};`;
|
|
28
|
+
} else {
|
|
29
|
+
return `export default new URL(${JSON.stringify(pathToFileURL(filePath).toString())})`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
generateBundle() {
|
|
34
|
+
for (const referenceId of referenceIds) {
|
|
35
|
+
fileNames.push(this.getFileName(referenceId));
|
|
36
|
+
}
|
|
37
|
+
referenceIds = [];
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
let config;
|
|
42
|
+
return {
|
|
43
|
+
name: "@astrojs/db/file-url",
|
|
44
|
+
hooks: {
|
|
45
|
+
"astro:config:setup"({ updateConfig, command }) {
|
|
46
|
+
updateConfig({
|
|
47
|
+
vite: {
|
|
48
|
+
plugins: [createVitePlugin(command)]
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
"astro:config:done": ({ config: _config }) => {
|
|
53
|
+
config = _config;
|
|
54
|
+
},
|
|
55
|
+
async "astro:build:done"() {
|
|
56
|
+
if (config.output === "static") {
|
|
57
|
+
const unlinks = [];
|
|
58
|
+
for (const fileName of fileNames) {
|
|
59
|
+
const url = new URL(fileName, config.outDir);
|
|
60
|
+
unlinks.push(fs.promises.unlink(url));
|
|
61
|
+
}
|
|
62
|
+
await Promise.all(unlinks);
|
|
63
|
+
const assetDir = new URL(config.build.assets, config.outDir);
|
|
64
|
+
await fs.promises.rmdir(assetDir).catch(() => []);
|
|
65
|
+
} else {
|
|
66
|
+
const moves = [];
|
|
67
|
+
for (const fileName of fileNames) {
|
|
68
|
+
const fromUrl = new URL(fileName, config.build.client);
|
|
69
|
+
const toUrl = new URL(fileName, config.build.server);
|
|
70
|
+
const toDir = new URL("./", toUrl);
|
|
71
|
+
moves.push(copyFile(toDir, fromUrl, toUrl));
|
|
72
|
+
}
|
|
73
|
+
await Promise.all(moves);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
fileURLIntegration
|
|
81
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
5
|
+
import { blue, yellow } from "kleur/colors";
|
|
6
|
+
import { loadEnv } from "vite";
|
|
7
|
+
import parseArgs from "yargs-parser";
|
|
8
|
+
import { SEED_DEV_FILE_NAME } from "../../runtime/queries.js";
|
|
9
|
+
import { AstroDbError } from "../../runtime/utils.js";
|
|
10
|
+
import { CONFIG_FILE_NAMES, DB_PATH } from "../consts.js";
|
|
11
|
+
import { resolveDbConfig } from "../load-file.js";
|
|
12
|
+
import { getManagedAppTokenOrExit } from "../tokens.js";
|
|
13
|
+
import { getDbDirectoryUrl } from "../utils.js";
|
|
14
|
+
import { fileURLIntegration } from "./file-url.js";
|
|
15
|
+
import { typegenInternal } from "./typegen.js";
|
|
16
|
+
import { resolved, vitePluginDb } from "./vite-plugin-db.js";
|
|
17
|
+
import { vitePluginInjectEnvTs } from "./vite-plugin-inject-env-ts.js";
|
|
18
|
+
function astroDBIntegration() {
|
|
19
|
+
let connectToStudio = false;
|
|
20
|
+
let configFileDependencies = [];
|
|
21
|
+
let root;
|
|
22
|
+
let appToken;
|
|
23
|
+
let tables = {
|
|
24
|
+
get() {
|
|
25
|
+
throw new Error("[astro:db] INTERNAL Tables not loaded yet");
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
let seedFiles = {
|
|
29
|
+
get() {
|
|
30
|
+
throw new Error("[astro:db] INTERNAL Seed files not loaded yet");
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
let command;
|
|
34
|
+
let output = "server";
|
|
35
|
+
return {
|
|
36
|
+
name: "astro:db",
|
|
37
|
+
hooks: {
|
|
38
|
+
"astro:config:setup": async ({ updateConfig, config, command: _command, logger }) => {
|
|
39
|
+
command = _command;
|
|
40
|
+
root = config.root;
|
|
41
|
+
output = config.output;
|
|
42
|
+
if (command === "preview")
|
|
43
|
+
return;
|
|
44
|
+
let dbPlugin = void 0;
|
|
45
|
+
const args = parseArgs(process.argv.slice(3));
|
|
46
|
+
connectToStudio = process.env.ASTRO_INTERNAL_TEST_REMOTE || args["remote"];
|
|
47
|
+
if (connectToStudio) {
|
|
48
|
+
appToken = await getManagedAppTokenOrExit();
|
|
49
|
+
dbPlugin = vitePluginDb({
|
|
50
|
+
connectToStudio,
|
|
51
|
+
appToken: appToken.token,
|
|
52
|
+
tables,
|
|
53
|
+
root: config.root,
|
|
54
|
+
srcDir: config.srcDir
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
dbPlugin = vitePluginDb({
|
|
58
|
+
connectToStudio: false,
|
|
59
|
+
tables,
|
|
60
|
+
seedFiles,
|
|
61
|
+
root: config.root,
|
|
62
|
+
srcDir: config.srcDir
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
updateConfig({
|
|
66
|
+
vite: {
|
|
67
|
+
assetsInclude: [DB_PATH],
|
|
68
|
+
plugins: [dbPlugin, vitePluginInjectEnvTs(config, logger)]
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
"astro:config:done": async ({ config }) => {
|
|
73
|
+
if (command === "preview")
|
|
74
|
+
return;
|
|
75
|
+
const { dbConfig, dependencies, integrationSeedPaths } = await resolveDbConfig(config);
|
|
76
|
+
tables.get = () => dbConfig.tables;
|
|
77
|
+
seedFiles.get = () => integrationSeedPaths;
|
|
78
|
+
configFileDependencies = dependencies;
|
|
79
|
+
const localDbUrl = new URL(DB_PATH, config.root);
|
|
80
|
+
if (!connectToStudio && !existsSync(localDbUrl)) {
|
|
81
|
+
await mkdir(dirname(fileURLToPath(localDbUrl)), { recursive: true });
|
|
82
|
+
await writeFile(localDbUrl, "");
|
|
83
|
+
}
|
|
84
|
+
await typegenInternal({ tables: tables.get() ?? {}, root: config.root });
|
|
85
|
+
},
|
|
86
|
+
"astro:server:setup": async ({ server, logger }) => {
|
|
87
|
+
const filesToWatch = [
|
|
88
|
+
...CONFIG_FILE_NAMES.map((c) => new URL(c, getDbDirectoryUrl(root))),
|
|
89
|
+
...configFileDependencies.map((c) => new URL(c, root))
|
|
90
|
+
];
|
|
91
|
+
server.watcher.on("all", (event, relativeEntry) => {
|
|
92
|
+
const entry = new URL(relativeEntry, root);
|
|
93
|
+
if (filesToWatch.some((f) => entry.href === f.href)) {
|
|
94
|
+
server.restart();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
logger.info(
|
|
99
|
+
connectToStudio ? "Connected to remote database." : "New local database created."
|
|
100
|
+
);
|
|
101
|
+
if (connectToStudio)
|
|
102
|
+
return;
|
|
103
|
+
const localSeedPaths = SEED_DEV_FILE_NAME.map(
|
|
104
|
+
(name) => new URL(name, getDbDirectoryUrl(root))
|
|
105
|
+
);
|
|
106
|
+
let seedInFlight = false;
|
|
107
|
+
if (seedFiles.get().length || localSeedPaths.find((path) => existsSync(path))) {
|
|
108
|
+
loadSeedModule();
|
|
109
|
+
}
|
|
110
|
+
const eagerReloadIntegrationSeedPaths = seedFiles.get().map((s) => typeof s === "string" && s.startsWith(".") ? new URL(s, root) : s).filter((s) => s instanceof URL);
|
|
111
|
+
const eagerReloadSeedPaths = [...eagerReloadIntegrationSeedPaths, ...localSeedPaths];
|
|
112
|
+
server.watcher.on("all", (event, relativeEntry) => {
|
|
113
|
+
if (event === "unlink" || event === "unlinkDir")
|
|
114
|
+
return;
|
|
115
|
+
const entry = new URL(relativeEntry, root);
|
|
116
|
+
if (eagerReloadSeedPaths.find((path) => entry.href === path.href)) {
|
|
117
|
+
loadSeedModule();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
function loadSeedModule() {
|
|
121
|
+
if (seedInFlight)
|
|
122
|
+
return;
|
|
123
|
+
seedInFlight = true;
|
|
124
|
+
const mod = server.moduleGraph.getModuleById(resolved.seedVirtual);
|
|
125
|
+
if (mod)
|
|
126
|
+
server.moduleGraph.invalidateModule(mod);
|
|
127
|
+
server.ssrLoadModule(resolved.seedVirtual).then(() => {
|
|
128
|
+
logger.info("Seeded database.");
|
|
129
|
+
}).catch((e) => {
|
|
130
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
131
|
+
}).finally(() => {
|
|
132
|
+
seedInFlight = false;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}, 100);
|
|
136
|
+
},
|
|
137
|
+
"astro:build:start": async ({ logger }) => {
|
|
138
|
+
if (!connectToStudio && !databaseFileEnvDefined() && (output === "server" || output === "hybrid")) {
|
|
139
|
+
const message = `Attempting to build without the --remote flag or the ASTRO_DATABASE_FILE environment variable defined. You probably want to pass --remote to astro build.`;
|
|
140
|
+
const hint = "Learn more connecting to Studio: https://docs.astro.build/en/guides/astro-db/#connect-to-astro-studio";
|
|
141
|
+
throw new AstroDbError(message, hint);
|
|
142
|
+
}
|
|
143
|
+
logger.info("database: " + (connectToStudio ? yellow("remote") : blue("local database.")));
|
|
144
|
+
},
|
|
145
|
+
"astro:build:done": async ({}) => {
|
|
146
|
+
await appToken?.destroy();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function databaseFileEnvDefined() {
|
|
152
|
+
const env = loadEnv("", process.cwd());
|
|
153
|
+
return env.ASTRO_DATABASE_FILE != null || process.env.ASTRO_DATABASE_FILE != null;
|
|
154
|
+
}
|
|
155
|
+
function integration() {
|
|
156
|
+
return [astroDBIntegration(), fileURLIntegration()];
|
|
157
|
+
}
|
|
158
|
+
export {
|
|
159
|
+
integration
|
|
160
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AstroConfig } from 'astro';
|
|
2
|
+
import type { DBTables } from '../types.js';
|
|
3
|
+
export declare function typegen(astroConfig: Pick<AstroConfig, 'root' | 'integrations'>): Promise<void>;
|
|
4
|
+
export declare function typegenInternal({ tables, root }: {
|
|
5
|
+
tables: DBTables;
|
|
6
|
+
root: URL;
|
|
7
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { DB_TYPES_FILE, RUNTIME_IMPORT } from "../consts.js";
|
|
4
|
+
import { resolveDbConfig } from "../load-file.js";
|
|
5
|
+
async function typegen(astroConfig) {
|
|
6
|
+
const { dbConfig } = await resolveDbConfig(astroConfig);
|
|
7
|
+
await typegenInternal({ tables: dbConfig.tables, root: astroConfig.root });
|
|
8
|
+
}
|
|
9
|
+
async function typegenInternal({ tables, root }) {
|
|
10
|
+
const content = `// This file is generated by Astro DB
|
|
11
|
+
declare module 'astro:db' {
|
|
12
|
+
${Object.entries(tables).map(([name, table]) => generateTableType(name, table)).join("\n")}
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
const dotAstroDir = new URL(".astro/", root);
|
|
16
|
+
if (!existsSync(dotAstroDir)) {
|
|
17
|
+
await mkdir(dotAstroDir);
|
|
18
|
+
}
|
|
19
|
+
await writeFile(new URL(DB_TYPES_FILE, dotAstroDir), content);
|
|
20
|
+
}
|
|
21
|
+
function generateTableType(name, table) {
|
|
22
|
+
const sanitizedColumnsList = Object.entries(table.columns).filter(([, val]) => !val.schema.deprecated);
|
|
23
|
+
const sanitizedColumns = Object.fromEntries(sanitizedColumnsList);
|
|
24
|
+
let tableType = ` export const ${name}: import(${RUNTIME_IMPORT}).Table<
|
|
25
|
+
${JSON.stringify(name)},
|
|
26
|
+
${JSON.stringify(sanitizedColumns)}
|
|
27
|
+
>;`;
|
|
28
|
+
return tableType;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
typegen,
|
|
32
|
+
typegenInternal
|
|
33
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { DBTables } from '../types.js';
|
|
2
|
+
import { type VitePlugin } from '../utils.js';
|
|
3
|
+
export declare const resolved: {
|
|
4
|
+
virtual: string;
|
|
5
|
+
seedVirtual: string;
|
|
6
|
+
};
|
|
7
|
+
export type LateTables = {
|
|
8
|
+
get: () => DBTables;
|
|
9
|
+
};
|
|
10
|
+
export type LateSeedFiles = {
|
|
11
|
+
get: () => Array<string | URL>;
|
|
12
|
+
};
|
|
13
|
+
type VitePluginDBParams = {
|
|
14
|
+
connectToStudio: false;
|
|
15
|
+
tables: LateTables;
|
|
16
|
+
seedFiles: LateSeedFiles;
|
|
17
|
+
srcDir: URL;
|
|
18
|
+
root: URL;
|
|
19
|
+
} | {
|
|
20
|
+
connectToStudio: true;
|
|
21
|
+
tables: LateTables;
|
|
22
|
+
appToken: string;
|
|
23
|
+
srcDir: URL;
|
|
24
|
+
root: URL;
|
|
25
|
+
};
|
|
26
|
+
export declare function vitePluginDb(params: VitePluginDBParams): VitePlugin;
|
|
27
|
+
export declare function getConfigVirtualModContents(): string;
|
|
28
|
+
export declare function getLocalVirtualModContents({ tables, root, seedFiles, shouldSeed, }: {
|
|
29
|
+
tables: DBTables;
|
|
30
|
+
seedFiles: Array<string | URL>;
|
|
31
|
+
root: URL;
|
|
32
|
+
shouldSeed: boolean;
|
|
33
|
+
}): string;
|
|
34
|
+
export declare function getStudioVirtualModContents({ tables, appToken, isBuild, }: {
|
|
35
|
+
tables: DBTables;
|
|
36
|
+
appToken: string;
|
|
37
|
+
isBuild: boolean;
|
|
38
|
+
}): string;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import { SEED_DEV_FILE_NAME } from "../../runtime/queries.js";
|
|
4
|
+
import { DB_PATH, RUNTIME_CONFIG_IMPORT, RUNTIME_IMPORT, VIRTUAL_MODULE_ID } from "../consts.js";
|
|
5
|
+
import { getDbDirectoryUrl, getRemoteDatabaseUrl } from "../utils.js";
|
|
6
|
+
const WITH_SEED_VIRTUAL_MODULE_ID = "astro:db:seed";
|
|
7
|
+
const resolved = {
|
|
8
|
+
virtual: "\0" + VIRTUAL_MODULE_ID,
|
|
9
|
+
seedVirtual: "\0" + WITH_SEED_VIRTUAL_MODULE_ID
|
|
10
|
+
};
|
|
11
|
+
function vitePluginDb(params) {
|
|
12
|
+
const srcDirPath = normalizePath(fileURLToPath(params.srcDir));
|
|
13
|
+
let command = "build";
|
|
14
|
+
return {
|
|
15
|
+
name: "astro:db",
|
|
16
|
+
enforce: "pre",
|
|
17
|
+
configResolved(resolvedConfig) {
|
|
18
|
+
command = resolvedConfig.command;
|
|
19
|
+
},
|
|
20
|
+
async resolveId(id, rawImporter) {
|
|
21
|
+
if (id !== VIRTUAL_MODULE_ID)
|
|
22
|
+
return;
|
|
23
|
+
if (params.connectToStudio)
|
|
24
|
+
return resolved.virtual;
|
|
25
|
+
const importer = rawImporter ? await this.resolve(rawImporter) : null;
|
|
26
|
+
if (!importer)
|
|
27
|
+
return resolved.virtual;
|
|
28
|
+
if (importer.id.startsWith(srcDirPath)) {
|
|
29
|
+
return resolved.seedVirtual;
|
|
30
|
+
}
|
|
31
|
+
return resolved.virtual;
|
|
32
|
+
},
|
|
33
|
+
async load(id) {
|
|
34
|
+
if (id !== resolved.virtual && id !== resolved.seedVirtual)
|
|
35
|
+
return;
|
|
36
|
+
if (params.connectToStudio) {
|
|
37
|
+
return getStudioVirtualModContents({
|
|
38
|
+
appToken: params.appToken,
|
|
39
|
+
tables: params.tables.get(),
|
|
40
|
+
isBuild: command === "build"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return getLocalVirtualModContents({
|
|
44
|
+
root: params.root,
|
|
45
|
+
tables: params.tables.get(),
|
|
46
|
+
seedFiles: params.seedFiles.get(),
|
|
47
|
+
shouldSeed: id === resolved.seedVirtual
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function getConfigVirtualModContents() {
|
|
53
|
+
return `export * from ${RUNTIME_CONFIG_IMPORT}`;
|
|
54
|
+
}
|
|
55
|
+
function getLocalVirtualModContents({
|
|
56
|
+
tables,
|
|
57
|
+
root,
|
|
58
|
+
seedFiles,
|
|
59
|
+
shouldSeed
|
|
60
|
+
}) {
|
|
61
|
+
const userSeedFilePaths = SEED_DEV_FILE_NAME.map(
|
|
62
|
+
// Format as /db/[name].ts
|
|
63
|
+
// for Vite import.meta.glob
|
|
64
|
+
(name) => new URL(name, getDbDirectoryUrl("file:///")).pathname
|
|
65
|
+
);
|
|
66
|
+
const resolveId = (id) => id.startsWith(".") ? normalizePath(fileURLToPath(new URL(id, root))) : id;
|
|
67
|
+
const integrationSeedImportStatements = [];
|
|
68
|
+
const integrationSeedImportNames = [];
|
|
69
|
+
seedFiles.forEach((pathOrUrl, index) => {
|
|
70
|
+
const path = typeof pathOrUrl === "string" ? resolveId(pathOrUrl) : pathOrUrl.pathname;
|
|
71
|
+
const importName = "integration_seed_" + index;
|
|
72
|
+
integrationSeedImportStatements.push(`import ${importName} from ${JSON.stringify(path)};`);
|
|
73
|
+
integrationSeedImportNames.push(importName);
|
|
74
|
+
});
|
|
75
|
+
const dbUrl = new URL(DB_PATH, root);
|
|
76
|
+
return `
|
|
77
|
+
import { asDrizzleTable, createLocalDatabaseClient, normalizeDatabaseUrl } from ${RUNTIME_IMPORT};
|
|
78
|
+
${shouldSeed ? `import { seedLocal } from ${RUNTIME_IMPORT};` : ""}
|
|
79
|
+
${shouldSeed ? integrationSeedImportStatements.join("\n") : ""}
|
|
80
|
+
|
|
81
|
+
const dbUrl = normalizeDatabaseUrl(import.meta.env.ASTRO_DATABASE_FILE, ${JSON.stringify(dbUrl)});
|
|
82
|
+
export const db = createLocalDatabaseClient({ dbUrl });
|
|
83
|
+
|
|
84
|
+
${shouldSeed ? `await seedLocal({
|
|
85
|
+
db,
|
|
86
|
+
tables: ${JSON.stringify(tables)},
|
|
87
|
+
userSeedGlob: import.meta.glob(${JSON.stringify(userSeedFilePaths)}, { eager: true }),
|
|
88
|
+
integrationSeedFunctions: [${integrationSeedImportNames.join(",")}],
|
|
89
|
+
});` : ""}
|
|
90
|
+
|
|
91
|
+
export * from ${RUNTIME_CONFIG_IMPORT};
|
|
92
|
+
|
|
93
|
+
${getStringifiedTableExports(tables)}`;
|
|
94
|
+
}
|
|
95
|
+
function getStudioVirtualModContents({
|
|
96
|
+
tables,
|
|
97
|
+
appToken,
|
|
98
|
+
isBuild
|
|
99
|
+
}) {
|
|
100
|
+
function appTokenArg() {
|
|
101
|
+
if (isBuild) {
|
|
102
|
+
return "process.env.ASTRO_STUDIO_APP_TOKEN";
|
|
103
|
+
} else {
|
|
104
|
+
return JSON.stringify(appToken);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function dbUrlArg() {
|
|
108
|
+
const dbStr = JSON.stringify(getRemoteDatabaseUrl());
|
|
109
|
+
return `import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL ?? ${dbStr}`;
|
|
110
|
+
}
|
|
111
|
+
return `
|
|
112
|
+
import {asDrizzleTable, createRemoteDatabaseClient} from ${RUNTIME_IMPORT};
|
|
113
|
+
|
|
114
|
+
export const db = await createRemoteDatabaseClient(${appTokenArg()}, ${dbUrlArg()});
|
|
115
|
+
|
|
116
|
+
export * from ${RUNTIME_CONFIG_IMPORT};
|
|
117
|
+
|
|
118
|
+
${getStringifiedTableExports(tables)}
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
function getStringifiedTableExports(tables) {
|
|
122
|
+
return Object.entries(tables).map(
|
|
123
|
+
([name, table]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
|
|
124
|
+
table
|
|
125
|
+
)}, false)`
|
|
126
|
+
).join("\n");
|
|
127
|
+
}
|
|
128
|
+
export {
|
|
129
|
+
getConfigVirtualModContents,
|
|
130
|
+
getLocalVirtualModContents,
|
|
131
|
+
getStudioVirtualModContents,
|
|
132
|
+
resolved,
|
|
133
|
+
vitePluginDb
|
|
134
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AstroIntegrationLogger } from 'astro';
|
|
2
|
+
import type { VitePlugin } from '../utils.js';
|
|
3
|
+
export declare function vitePluginInjectEnvTs({ srcDir, root }: {
|
|
4
|
+
srcDir: URL;
|
|
5
|
+
root: URL;
|
|
6
|
+
}, logger: AstroIntegrationLogger): VitePlugin;
|
|
7
|
+
export declare function setUpEnvTs({ srcDir, root, logger, }: {
|
|
8
|
+
srcDir: URL;
|
|
9
|
+
root: URL;
|
|
10
|
+
logger: AstroIntegrationLogger;
|
|
11
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { bold } from "kleur/colors";
|
|
6
|
+
import { normalizePath } from "vite";
|
|
7
|
+
import { DB_TYPES_FILE } from "../consts.js";
|
|
8
|
+
function vitePluginInjectEnvTs({ srcDir, root }, logger) {
|
|
9
|
+
return {
|
|
10
|
+
name: "db-inject-env-ts",
|
|
11
|
+
enforce: "post",
|
|
12
|
+
async config() {
|
|
13
|
+
await setUpEnvTs({ srcDir, root, logger });
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async function setUpEnvTs({
|
|
18
|
+
srcDir,
|
|
19
|
+
root,
|
|
20
|
+
logger
|
|
21
|
+
}) {
|
|
22
|
+
const envTsPath = getEnvTsPath({ srcDir });
|
|
23
|
+
const envTsPathRelativetoRoot = normalizePath(
|
|
24
|
+
path.relative(fileURLToPath(root), fileURLToPath(envTsPath))
|
|
25
|
+
);
|
|
26
|
+
if (existsSync(envTsPath)) {
|
|
27
|
+
let typesEnvContents = await readFile(envTsPath, "utf-8");
|
|
28
|
+
const dotAstroDir = new URL(".astro/", root);
|
|
29
|
+
if (!existsSync(dotAstroDir))
|
|
30
|
+
return;
|
|
31
|
+
const dbTypeReference = getDBTypeReference({ srcDir, dotAstroDir });
|
|
32
|
+
if (!typesEnvContents.includes(dbTypeReference)) {
|
|
33
|
+
typesEnvContents = `${dbTypeReference}
|
|
34
|
+
${typesEnvContents}`;
|
|
35
|
+
await writeFile(envTsPath, typesEnvContents, "utf-8");
|
|
36
|
+
logger.info(`Added ${bold(envTsPathRelativetoRoot)} types`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function getDBTypeReference({ srcDir, dotAstroDir }) {
|
|
41
|
+
const dbTypesFile = new URL(DB_TYPES_FILE, dotAstroDir);
|
|
42
|
+
const contentTypesRelativeToSrcDir = normalizePath(
|
|
43
|
+
path.relative(fileURLToPath(srcDir), fileURLToPath(dbTypesFile))
|
|
44
|
+
);
|
|
45
|
+
return `/// <reference path=${JSON.stringify(contentTypesRelativeToSrcDir)} />`;
|
|
46
|
+
}
|
|
47
|
+
function getEnvTsPath({ srcDir }) {
|
|
48
|
+
return new URL("env.d.ts", srcDir);
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
setUpEnvTs,
|
|
52
|
+
vitePluginInjectEnvTs
|
|
53
|
+
};
|