@bezoar/nuxt 0.0.0-stage → 0.0.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/_chunks/constant.d.ts +31 -0
- package/.dist/config.d.ts +62 -0
- package/.dist/config.js +2 -0
- package/.dist/constant.d.ts +2 -0
- package/.dist/constant.js +19 -0
- package/.dist/module.d.ts +22 -0
- package/.dist/module.js +108 -0
- package/.dist/runtime/server/plugin.d.ts +7 -0
- package/.dist/runtime/server/plugin.js +10 -0
- package/.dist/runtime/server/service.d.ts +23 -0
- package/.dist/runtime/server/service.js +34 -0
- package/.dist/runtime/server/startup.d.ts +21 -0
- package/.dist/runtime/server/startup.js +9 -0
- package/.dist/runtime/server/types.d.ts +6 -0
- package/.dist/runtime/server/types.js +1 -0
- package/LICENSE +21 -0
- package/README.md +88 -2
- package/package.json +48 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The virtual modules the module adds to the server build: the build of the
|
|
3
|
+
* app, and its service. A virtual module is bundled in dev and in production
|
|
4
|
+
* alike, so the plugin of the runtime, which imports both, is too.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VIRTUAL: {
|
|
7
|
+
readonly build: "#bezoar/build";
|
|
8
|
+
readonly service: "#bezoar/service";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The declaration of the service, in the build directory. It declares the
|
|
12
|
+
* virtual service module, so the server is typed by the build.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DECLARATION = "types/bezoar.d.ts";
|
|
15
|
+
/**
|
|
16
|
+
* The modules of a kit build the module adopts.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ENTRIES: readonly ["index", "queries", "migrations", "seeds"];
|
|
19
|
+
/**
|
|
20
|
+
* The export of each module of a kit build, re-exported by the virtual
|
|
21
|
+
* build. Named, not `export *`: the modules are external to the server
|
|
22
|
+
* bundle in dev, and a bundler cannot tell which of several external modules
|
|
23
|
+
* a star re-export provides a name from.
|
|
24
|
+
*/
|
|
25
|
+
export declare const EXPORTS: Record<(typeof ENTRIES)[number], string>;
|
|
26
|
+
/**
|
|
27
|
+
* The drivers the module can connect with. `pg` connects to a server with
|
|
28
|
+
* the connection string of the runtime config. `pglite` runs Postgres in the
|
|
29
|
+
* process, on the data directory of the runtime config, or in memory.
|
|
30
|
+
*/
|
|
31
|
+
export declare const DRIVERS: readonly ["pg", "pglite"];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { DRIVERS } from "./_chunks/constant.js";
|
|
2
|
+
/**
|
|
3
|
+
* A driver the module can connect with.
|
|
4
|
+
*/
|
|
5
|
+
export type Driver = (typeof DRIVERS)[number];
|
|
6
|
+
/**
|
|
7
|
+
* The module's configuration.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* export default defineNuxtConfig({
|
|
11
|
+
* modules: ["@bezoar/nuxt"],
|
|
12
|
+
* bezoar: { build: "@acme/database", migrate: true },
|
|
13
|
+
* });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface NuxtBezoarConfig {
|
|
17
|
+
/**
|
|
18
|
+
* A kit build: the output directory `bezoar build` wrote. A path,
|
|
19
|
+
* relative to the project root or absolute, to the directory or its
|
|
20
|
+
* `index.mjs`, or a package whose main entry is that `index.mjs`.
|
|
21
|
+
*/
|
|
22
|
+
build: string;
|
|
23
|
+
/**
|
|
24
|
+
* The driver. `pg` connects to a Postgres server with the connection
|
|
25
|
+
* string of the runtime config. `pglite` runs Postgres in the process.
|
|
26
|
+
* Defaults to `pg`.
|
|
27
|
+
*/
|
|
28
|
+
driver?: Driver;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the server applies the migrations of the build when it starts.
|
|
31
|
+
* Defaults to `false`.
|
|
32
|
+
*/
|
|
33
|
+
migrate?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the server runs the seeds of the build when it starts, after
|
|
36
|
+
* the migrations. Defaults to `false`.
|
|
37
|
+
*/
|
|
38
|
+
seed?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The runtime config of the module, under `runtimeConfig.bezoar`. An
|
|
42
|
+
* environment variable sets each member: `NUXT_BEZOAR_URL` sets `url`.
|
|
43
|
+
*/
|
|
44
|
+
export interface BezoarRuntimeConfig {
|
|
45
|
+
/** The connection string, for the `pg` driver. */
|
|
46
|
+
url: string;
|
|
47
|
+
/** The data directory, for the `pglite` driver. Empty for memory. */
|
|
48
|
+
dataDir: string;
|
|
49
|
+
/** The driver. */
|
|
50
|
+
driver: Driver;
|
|
51
|
+
/** Whether the server applies the migrations when it starts. */
|
|
52
|
+
migrate: boolean;
|
|
53
|
+
/** Whether the server runs the seeds when it starts. */
|
|
54
|
+
seed: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Identity helper that types a Nuxt bezoar configuration.
|
|
58
|
+
*
|
|
59
|
+
* @param config - The Nuxt bezoar configuration.
|
|
60
|
+
* @returns The same config.
|
|
61
|
+
*/
|
|
62
|
+
export declare const defineBezoarConfig: (config: NuxtBezoarConfig) => NuxtBezoarConfig;
|
package/.dist/config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const VIRTUAL = {
|
|
2
|
+
build: "#bezoar/build",
|
|
3
|
+
service: "#bezoar/service"
|
|
4
|
+
};
|
|
5
|
+
const DECLARATION = "types/bezoar.d.ts";
|
|
6
|
+
const ENTRIES = [
|
|
7
|
+
"index",
|
|
8
|
+
"queries",
|
|
9
|
+
"migrations",
|
|
10
|
+
"seeds"
|
|
11
|
+
];
|
|
12
|
+
const EXPORTS = {
|
|
13
|
+
index: "contract",
|
|
14
|
+
queries: "queries",
|
|
15
|
+
migrations: "migrations",
|
|
16
|
+
seeds: "seeds"
|
|
17
|
+
};
|
|
18
|
+
const DRIVERS = ["pg", "pglite"];
|
|
19
|
+
export { DECLARATION, DRIVERS, ENTRIES, EXPORTS, VIRTUAL };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NuxtBezoarConfig } from "./config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Nuxt module for bezoar.
|
|
4
|
+
*
|
|
5
|
+
* The module takes a kit build, the output of `bezoar build` in a
|
|
6
|
+
* database package, and adds two virtual modules to the server build: the
|
|
7
|
+
* build of the app, which re-exports the modules of the kit build, and the
|
|
8
|
+
* service of the app, over the contract and the SQL of that build. A
|
|
9
|
+
* declaration in the build directory types the service by the contract. The
|
|
10
|
+
* module provides `useBezoar()` to the server from the virtual service: a
|
|
11
|
+
* service over the contract of the build, typed by it, connected through
|
|
12
|
+
* the driver and the connection string of the runtime config. The plugin of
|
|
13
|
+
* the runtime makes the service when the server starts, applies the
|
|
14
|
+
* migrations and runs the seeds of the virtual build when the config asks,
|
|
15
|
+
* and closes the connection when the server stops.
|
|
16
|
+
*
|
|
17
|
+
* The modules are virtual, not written, so Nitro bundles them in dev as in
|
|
18
|
+
* production. Nitro loads a written file through Node in dev, where neither
|
|
19
|
+
* `#imports` nor a virtual module exists.
|
|
20
|
+
*/
|
|
21
|
+
declare const _default: import("@nuxt/schema").NuxtModule<NuxtBezoarConfig, NuxtBezoarConfig, false>;
|
|
22
|
+
export { _default as default };
|
package/.dist/module.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { DECLARATION, ENTRIES, EXPORTS, VIRTUAL } from "./constant.js";
|
|
2
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { addServerImports, addServerPlugin, addServerTemplate, addTypeTemplate, createResolver, defineNuxtModule, directoryToURL, tryResolveModule } from "@nuxt/kit";
|
|
4
|
+
import { record } from "objectively";
|
|
5
|
+
import { existsSync, statSync } from "node:fs";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
const locate = async (build, root) => {
|
|
8
|
+
let path;
|
|
9
|
+
if (build.startsWith(".") || isAbsolute(build)) path = resolve(root, build);
|
|
10
|
+
else {
|
|
11
|
+
const resolved = await tryResolveModule(build, directoryToURL(root));
|
|
12
|
+
path = resolved?.startsWith("file:") ? fileURLToPath(resolved) : resolved;
|
|
13
|
+
}
|
|
14
|
+
if (path === void 0 || !existsSync(path)) throw new Error(`bezoar: \`build\` ${JSON.stringify(build)} could not be found from ${root}`);
|
|
15
|
+
const directory = statSync(path).isFile() ? dirname(path) : path;
|
|
16
|
+
for (const entry of ENTRIES) if (!existsSync(join(directory, `${entry}.mjs`))) throw new Error(`bezoar: ${directory} is not a kit build; it has no ${entry}.mjs (run \`bezoar build\` there first)`);
|
|
17
|
+
return directory;
|
|
18
|
+
};
|
|
19
|
+
const from = (directory, file) => JSON.stringify(join(directory, file));
|
|
20
|
+
const build = ({ build: directory }) => [...ENTRIES.map((entry) => `export { ${EXPORTS[entry]} } from ${from(directory, `${entry}.mjs`)};`), ""].join("\n");
|
|
21
|
+
const service = ({ runtime }) => [
|
|
22
|
+
`import { contract, queries } from ${JSON.stringify(VIRTUAL.build)};`,
|
|
23
|
+
`import { defineService } from ${from(runtime, "service.js")};`,
|
|
24
|
+
"",
|
|
25
|
+
"export const { useBezoar, closeBezoar } = defineService(contract, queries);",
|
|
26
|
+
""
|
|
27
|
+
].join("\n");
|
|
28
|
+
const declaration = ({ build, runtime }) => {
|
|
29
|
+
const contract = `typeof import(${from(build, "index.mjs")}).contract`;
|
|
30
|
+
const service = `import(${from(runtime, "service.js")})`;
|
|
31
|
+
return [
|
|
32
|
+
`declare module ${JSON.stringify(VIRTUAL.service)} {`,
|
|
33
|
+
` export type AppBezoarContract = ${contract};`,
|
|
34
|
+
` export const useBezoar: ${service}.Defined<AppBezoarContract>["useBezoar"];`,
|
|
35
|
+
` export const closeBezoar: ${service}.Defined<AppBezoarContract>["closeBezoar"];`,
|
|
36
|
+
" export type AppBezoar = ReturnType<typeof useBezoar>;",
|
|
37
|
+
` export type AppBezoarQuery = ${service}.Query<AppBezoarContract>;`,
|
|
38
|
+
` export type AppBezoarArguments<Q extends AppBezoarQuery> = ${service}.Arguments<AppBezoarContract, Q>;`,
|
|
39
|
+
` export type AppBezoarRow<Q extends AppBezoarQuery> = ${service}.Row<AppBezoarContract, Q>;`,
|
|
40
|
+
"}",
|
|
41
|
+
""
|
|
42
|
+
].join("\n");
|
|
43
|
+
};
|
|
44
|
+
var module_default = defineNuxtModule({
|
|
45
|
+
meta: {
|
|
46
|
+
name: "bezoar",
|
|
47
|
+
configKey: "bezoar"
|
|
48
|
+
},
|
|
49
|
+
setup: async (options, nuxt) => {
|
|
50
|
+
if (typeof options.build !== "string" || options.build === "") throw new Error("bezoar: `build` must name a kit build, as a package or a path");
|
|
51
|
+
const resolver = createResolver(import.meta.url);
|
|
52
|
+
const sources = {
|
|
53
|
+
build: await locate(options.build, nuxt.options.rootDir),
|
|
54
|
+
runtime: dirname(await resolver.resolvePath("./runtime/server/service"))
|
|
55
|
+
};
|
|
56
|
+
nuxt.options.build.transpile.push(sources.runtime);
|
|
57
|
+
addServerTemplate({
|
|
58
|
+
filename: VIRTUAL.build,
|
|
59
|
+
getContents: () => build(sources)
|
|
60
|
+
});
|
|
61
|
+
addServerTemplate({
|
|
62
|
+
filename: VIRTUAL.service,
|
|
63
|
+
getContents: () => service(sources)
|
|
64
|
+
});
|
|
65
|
+
addTypeTemplate({
|
|
66
|
+
filename: DECLARATION,
|
|
67
|
+
getContents: () => declaration(sources)
|
|
68
|
+
}, {
|
|
69
|
+
nitro: true,
|
|
70
|
+
nuxt: true
|
|
71
|
+
});
|
|
72
|
+
const defaults = {
|
|
73
|
+
url: "",
|
|
74
|
+
dataDir: "",
|
|
75
|
+
driver: options.driver ?? "pg",
|
|
76
|
+
migrate: options.migrate ?? false,
|
|
77
|
+
seed: options.seed ?? false
|
|
78
|
+
};
|
|
79
|
+
const given = nuxt.options.runtimeConfig.bezoar;
|
|
80
|
+
nuxt.options.runtimeConfig.bezoar = {
|
|
81
|
+
...defaults,
|
|
82
|
+
...record(given) ? given : {}
|
|
83
|
+
};
|
|
84
|
+
addServerPlugin(await resolver.resolvePath("./runtime/server/plugin"));
|
|
85
|
+
addServerImports([
|
|
86
|
+
{
|
|
87
|
+
from: VIRTUAL.service,
|
|
88
|
+
name: "useBezoar"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
from: VIRTUAL.service,
|
|
92
|
+
name: "closeBezoar"
|
|
93
|
+
},
|
|
94
|
+
...[
|
|
95
|
+
"AppBezoar",
|
|
96
|
+
"AppBezoarContract",
|
|
97
|
+
"AppBezoarQuery",
|
|
98
|
+
"AppBezoarArguments",
|
|
99
|
+
"AppBezoarRow"
|
|
100
|
+
].map((name) => ({
|
|
101
|
+
from: VIRTUAL.service,
|
|
102
|
+
name,
|
|
103
|
+
type: true
|
|
104
|
+
}))
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
export { module_default as default };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plugin of the app. Nitro resolves a plugin by path, so the plugin is a
|
|
3
|
+
* file of the runtime; what differs by app, the service and the build, comes
|
|
4
|
+
* from the virtual modules the module adds to the server build.
|
|
5
|
+
*/
|
|
6
|
+
declare const _default: (nitroApp: import("#imports").NitroApp) => Promise<void>;
|
|
7
|
+
export { _default as default };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { definePlugin } from "./startup.js";
|
|
2
|
+
import { migrations, seeds } from "#bezoar/build";
|
|
3
|
+
import { closeBezoar, useBezoar } from "#bezoar/service";
|
|
4
|
+
var plugin_default = definePlugin({
|
|
5
|
+
useBezoar,
|
|
6
|
+
closeBezoar,
|
|
7
|
+
migrations,
|
|
8
|
+
seeds
|
|
9
|
+
});
|
|
10
|
+
export { plugin_default as default };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Arguments, Bezoar, Bundle, Definition, Query, Row } from "bezoar";
|
|
2
|
+
/**
|
|
3
|
+
* The service of an app: `useBezoar` for the service, `closeBezoar`
|
|
4
|
+
* to close its connection.
|
|
5
|
+
*/
|
|
6
|
+
export interface Defined<D extends Definition> {
|
|
7
|
+
useBezoar: () => Bezoar<D>;
|
|
8
|
+
closeBezoar: () => Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Defines the service of an app over a contract and its SQL. The written
|
|
12
|
+
* service of the build directory calls this with the modules of the build.
|
|
13
|
+
*
|
|
14
|
+
* `useBezoar` connects on its first call, with the driver of the runtime
|
|
15
|
+
* config, and makes the service. Every call after returns the same service.
|
|
16
|
+
* `closeBezoar` closes the connection. The next `useBezoar` connects
|
|
17
|
+
* again.
|
|
18
|
+
*
|
|
19
|
+
* @param contract - The contract of the build.
|
|
20
|
+
* @param queries - The SQL of the build.
|
|
21
|
+
*/
|
|
22
|
+
export declare const defineService: <const D extends Definition>(contract: D, queries: Bundle<D>) => Defined<D>;
|
|
23
|
+
export type { Arguments, Query, Row };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "#imports";
|
|
2
|
+
import { pg } from "@bezoar/pg";
|
|
3
|
+
import { pglite } from "@bezoar/pglite";
|
|
4
|
+
import { makeBezoar } from "bezoar";
|
|
5
|
+
const connect = (config) => {
|
|
6
|
+
if (config.driver === "pglite") return pglite(config.dataDir === "" ? {} : config.dataDir);
|
|
7
|
+
if (config.url === "") throw new Error("bezoar: no connection string; set NUXT_BEZOAR_URL, or runtimeConfig.bezoar.url");
|
|
8
|
+
return pg(config.url);
|
|
9
|
+
};
|
|
10
|
+
const defineService = (contract, queries) => {
|
|
11
|
+
let connection;
|
|
12
|
+
let service;
|
|
13
|
+
const useBezoar = () => {
|
|
14
|
+
if (service === void 0) {
|
|
15
|
+
connection = connect(useRuntimeConfig().bezoar);
|
|
16
|
+
service = makeBezoar(contract, {
|
|
17
|
+
executor: connection,
|
|
18
|
+
queries
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return service;
|
|
22
|
+
};
|
|
23
|
+
const closeBezoar = async () => {
|
|
24
|
+
const open = connection;
|
|
25
|
+
connection = void 0;
|
|
26
|
+
service = void 0;
|
|
27
|
+
await open?.close();
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
useBezoar,
|
|
31
|
+
closeBezoar
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export { defineService };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Defined } from "./service.js";
|
|
2
|
+
import { Definition, Migration, Seed } from "bezoar";
|
|
3
|
+
/**
|
|
4
|
+
* What the plugin of an app runs with: its service, and the migrations and
|
|
5
|
+
* the seeds of its build.
|
|
6
|
+
*/
|
|
7
|
+
export interface Startup<D extends Definition> extends Defined<D> {
|
|
8
|
+
migrations: readonly Migration[];
|
|
9
|
+
seeds: readonly Seed[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Defines the plugin of an app. The plugin of the runtime calls this with
|
|
13
|
+
* the virtual service and the virtual build of the app.
|
|
14
|
+
*
|
|
15
|
+
* The plugin makes the service when the server starts. When the runtime
|
|
16
|
+
* config asks, it applies the migrations of the build and runs its seeds.
|
|
17
|
+
* It closes the connection when the server stops.
|
|
18
|
+
*
|
|
19
|
+
* @param startup - The service, the migrations, and the seeds.
|
|
20
|
+
*/
|
|
21
|
+
export declare const definePlugin: <D extends Definition>(startup: Startup<D>) => (nitroApp: import("#imports").NitroApp) => Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { defineNitroPlugin, useRuntimeConfig } from "#imports";
|
|
2
|
+
const definePlugin = (startup) => defineNitroPlugin(async (nitroApp) => {
|
|
3
|
+
const { migrate, seed } = useRuntimeConfig().bezoar;
|
|
4
|
+
const db = startup.useBezoar();
|
|
5
|
+
if (migrate) await db.migrate(startup.migrations);
|
|
6
|
+
if (seed) await db.seed(startup.seeds);
|
|
7
|
+
nitroApp.hooks.hook("close", startup.closeBezoar);
|
|
8
|
+
});
|
|
9
|
+
export { definePlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexander Thorwaldson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,89 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bezoar/nuxt
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Nuxt module for bezoar. The module takes a kit build and gives the server
|
|
4
|
+
a typed database service.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm add @bezoar/nuxt
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// nuxt.config.ts
|
|
16
|
+
export default defineNuxtConfig({
|
|
17
|
+
modules: ["@bezoar/nuxt"],
|
|
18
|
+
bezoar: { build: "@acme/database", migrate: true },
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`build` names a kit build: a package whose main entry is the `index.mjs`
|
|
23
|
+
that `bezoar build` wrote, or a path to that directory. The module adds
|
|
24
|
+
two virtual modules to the server build: `#bezoar/build`, which
|
|
25
|
+
re-exports the modules of the kit build, and `#bezoar/service`, the
|
|
26
|
+
service over its contract and its SQL. It writes a declaration of the
|
|
27
|
+
service into the build directory. `useBezoar()` and its types come from
|
|
28
|
+
the virtual service, so they are typed by the build. The modules are virtual
|
|
29
|
+
so that Nitro bundles them in dev as in production; the server plugin of
|
|
30
|
+
the module imports both.
|
|
31
|
+
|
|
32
|
+
## Connection
|
|
33
|
+
|
|
34
|
+
The module reads `runtimeConfig.bezoar`. An environment variable sets
|
|
35
|
+
each member.
|
|
36
|
+
|
|
37
|
+
| Member | Variable | Meaning |
|
|
38
|
+
| --------- | ---------------------- | ------------------------------------------- |
|
|
39
|
+
| `url` | `NUXT_BEZOAR_URL` | The connection string, for the `pg` driver |
|
|
40
|
+
| `dataDir` | `NUXT_BEZOAR_DATA_DIR` | The data directory, for the `pglite` driver |
|
|
41
|
+
| `driver` | `NUXT_BEZOAR_DRIVER` | `pg` or `pglite`. Defaults to `pg` |
|
|
42
|
+
| `migrate` | `NUXT_BEZOAR_MIGRATE` | Apply the migrations when the server starts |
|
|
43
|
+
| `seed` | `NUXT_BEZOAR_SEED` | Run the seeds when the server starts |
|
|
44
|
+
|
|
45
|
+
`driver`, `migrate`, and `seed` can also be set in the module options. A
|
|
46
|
+
value in the runtime config wins.
|
|
47
|
+
|
|
48
|
+
The `pg` driver connects to a Postgres server and needs `url`. The `pglite`
|
|
49
|
+
driver runs Postgres in the process, on `dataDir`, or in memory when it is
|
|
50
|
+
empty. A server with the `pg` driver and no `url` fails to start.
|
|
51
|
+
|
|
52
|
+
## In a server route
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
export default defineEventHandler(async (event) => {
|
|
56
|
+
const db = useBezoar();
|
|
57
|
+
const { day } = await getValidatedQuery(
|
|
58
|
+
event,
|
|
59
|
+
db.schema.validators.queries["events.list"].arguments.parse,
|
|
60
|
+
);
|
|
61
|
+
return db.events.list({ day });
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`useBezoar()` is auto-imported on the server. It returns the same service
|
|
66
|
+
on every call, typed by the contract of the build, so `db.events.list`
|
|
67
|
+
completes, and its arguments and rows check. `AppBezoar`,
|
|
68
|
+
`AppBezoarContract`, `AppBezoarQuery`, `AppBezoarArguments<Q>`, and
|
|
69
|
+
`AppBezoarRow<Q>` are the types, also auto-imported.
|
|
70
|
+
|
|
71
|
+
## Startup and shutdown
|
|
72
|
+
|
|
73
|
+
A server plugin makes the service when the server starts. With `migrate`,
|
|
74
|
+
it applies the migrations of the build first, through `migrate` of
|
|
75
|
+
`@bezoar/core`, under an advisory lock, so instances that start together
|
|
76
|
+
apply each migration once. With `seed`, it runs the seeds after. When the
|
|
77
|
+
server stops, the plugin closes the connection. `closeBezoar()` closes it
|
|
78
|
+
by hand.
|
|
79
|
+
|
|
80
|
+
## Runtime
|
|
81
|
+
|
|
82
|
+
The `pg` driver needs a Node runtime, which the Node server presets of Nuxt
|
|
83
|
+
and the functions of Vercel are.
|
|
84
|
+
|
|
85
|
+
## Related
|
|
86
|
+
|
|
87
|
+
- [`bezoar`](../../packages/bezoar): the runtime.
|
|
88
|
+
- [`@bezoar/kit`](../../packages/kit): builds the contract the module
|
|
89
|
+
adopts.
|
package/package.json
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bezoar/nuxt",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Nuxt module for bezoar: a typed database service for server routes, from a kit build",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/zoobzio/bezoar.git",
|
|
9
|
+
"directory": "integrations/nuxt"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./.dist/module.js",
|
|
13
|
+
"types": "./.dist/module.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./.dist/module.d.ts",
|
|
17
|
+
"import": "./.dist/module.js"
|
|
18
|
+
},
|
|
19
|
+
"./config": {
|
|
20
|
+
"types": "./.dist/config.d.ts",
|
|
21
|
+
"import": "./.dist/config.js"
|
|
22
|
+
},
|
|
23
|
+
"./constant": {
|
|
24
|
+
"types": "./.dist/constant.d.ts",
|
|
25
|
+
"import": "./.dist/constant.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
".dist"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@nuxt/kit": "^4.5.0",
|
|
33
|
+
"objectively": "^0.3.0",
|
|
34
|
+
"@bezoar/pg": "0.0.2",
|
|
35
|
+
"@bezoar/pglite": "0.0.2",
|
|
36
|
+
"bezoar": "0.0.2"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@nuxt/nitro-server": "^4.5.0",
|
|
40
|
+
"@nuxt/schema": "^4.5.0",
|
|
41
|
+
"@types/node": "^25.9.9",
|
|
42
|
+
"nuxt": "^4.5.0"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "obuild",
|
|
46
|
+
"stub": "obuild --stub",
|
|
47
|
+
"lint": "oxlint",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest run"
|
|
50
|
+
}
|
|
6
51
|
}
|