futonic 0.0.0-canary.03da5f8
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/README.md +219 -0
- package/dist/chunk-eqeddyek.js +130 -0
- package/dist/chunk-nj3a3jzm.js +26 -0
- package/dist/chunk-s3j6ndfy.js +96 -0
- package/dist/chunk-s9sdjw1m.js +181 -0
- package/dist/chunk-v0bahtg2.js +4 -0
- package/dist/cli/generators/drizzle.d.ts +11 -0
- package/dist/cli/generators/drizzle.d.ts.map +1 -0
- package/dist/cli/generators/kysely.d.ts +17 -0
- package/dist/cli/generators/kysely.d.ts.map +1 -0
- package/dist/cli/generators/prisma.d.ts +10 -0
- package/dist/cli/generators/prisma.d.ts.map +1 -0
- package/dist/cli/generators/types.d.ts +24 -0
- package/dist/cli/generators/types.d.ts.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +100 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/core/context.d.ts +23 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/host.d.ts +14 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/core/service.d.ts +25 -0
- package/dist/core/service.d.ts.map +1 -0
- package/dist/db/internal-adapter.d.ts +63 -0
- package/dist/db/internal-adapter.d.ts.map +1 -0
- package/dist/db/kysely-factory.d.ts +34 -0
- package/dist/db/kysely-factory.d.ts.map +1 -0
- package/dist/db/schema.d.ts +36 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +337 -0
- package/dist/router/endpoint.d.ts +105 -0
- package/dist/router/endpoint.d.ts.map +1 -0
- package/dist/router/middleware.d.ts +10 -0
- package/dist/router/middleware.d.ts.map +1 -0
- package/dist/test-utils.d.ts +25 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely.d.ts","sourceRoot":"","sources":["../../../src/cli/generators/kysely.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEjE,eAAO,MAAM,oBAAoB,EAAE,eAmBlC,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,aAAa,EACpB,QAAQ,GAAE,gBAAuB,GAC/B,MAAM,CAqBR"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma schema generator.
|
|
3
|
+
*
|
|
4
|
+
* Forked from better-auth `packages/cli/src/generators/prisma.ts` (MIT).
|
|
5
|
+
* Adapted to read from futonic's PrefixedTable IR instead of getAuthTables().
|
|
6
|
+
* Uses @mrleebo/prisma-ast for AST-based schema patching.
|
|
7
|
+
*/
|
|
8
|
+
import type { SchemaGenerator } from "./types";
|
|
9
|
+
export declare const generatePrismaSchema: SchemaGenerator;
|
|
10
|
+
//# sourceMappingURL=prisma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../../src/cli/generators/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,eAAO,MAAM,oBAAoB,EAAE,eAgIlC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator types for CLI schema generation.
|
|
3
|
+
*
|
|
4
|
+
* Forked from better-auth `packages/cli/src/generators/types.ts` (MIT).
|
|
5
|
+
* Adapted to use futonic's ServiceDBSchema IR instead of BetterAuthOptions.
|
|
6
|
+
*/
|
|
7
|
+
import type { PrefixedTable } from "../../db/schema";
|
|
8
|
+
export interface SchemaGeneratorResult {
|
|
9
|
+
code?: string;
|
|
10
|
+
fileName: string;
|
|
11
|
+
overwrite?: boolean;
|
|
12
|
+
append?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type DatabaseProvider = "pg" | "mysql" | "sqlite";
|
|
15
|
+
export interface GeneratorOptions {
|
|
16
|
+
/** All prefixed tables collected from mounted services */
|
|
17
|
+
tables: Map<string, PrefixedTable>;
|
|
18
|
+
/** Target database provider */
|
|
19
|
+
provider: DatabaseProvider;
|
|
20
|
+
/** Output file path override */
|
|
21
|
+
file?: string;
|
|
22
|
+
}
|
|
23
|
+
export type SchemaGenerator = (opts: GeneratorOptions) => Promise<SchemaGeneratorResult>;
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/generators/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAChC,0DAA0D;IAC1D,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACnC,+BAA+B;IAC/B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,CAC7B,IAAI,EAAE,gBAAgB,KAClB,OAAO,CAAC,qBAAqB,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI factory for service authors.
|
|
3
|
+
*
|
|
4
|
+
* Service packages wrap this to provide their own CLI:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* // packages/acme-billing/src/cli.ts
|
|
8
|
+
* #!/usr/bin/env node
|
|
9
|
+
* import { createCLI } from "futonic/cli";
|
|
10
|
+
* import { billingService } from "./service";
|
|
11
|
+
*
|
|
12
|
+
* createCLI({ service: billingService });
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* The host developer then runs:
|
|
16
|
+
* npx acme-billing generate --orm=drizzle --provider=pg
|
|
17
|
+
*
|
|
18
|
+
* And gets migration files for just that service's tables.
|
|
19
|
+
*/
|
|
20
|
+
import type { EmbeddableService } from "../core/service";
|
|
21
|
+
export interface CLIOptions {
|
|
22
|
+
/** The service definition (pre-mount, has dbSchema) */
|
|
23
|
+
service: EmbeddableService;
|
|
24
|
+
/** Optional name override for CLI output (defaults to service.id) */
|
|
25
|
+
name?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function createCLI(options: CLIOptions): void;
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAIzD,MAAM,WAAW,UAAU;IAC1B,uDAAuD;IACvD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAgBnD"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getServiceTables
|
|
3
|
+
} from "../chunk-nj3a3jzm.js";
|
|
4
|
+
import {
|
|
5
|
+
__require
|
|
6
|
+
} from "../chunk-v0bahtg2.js";
|
|
7
|
+
|
|
8
|
+
// src/cli/index.ts
|
|
9
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
function createCLI(options) {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const command = args[0];
|
|
14
|
+
const serviceName = options.name ?? options.service.id;
|
|
15
|
+
switch (command) {
|
|
16
|
+
case "generate":
|
|
17
|
+
runGenerate(args.slice(1), options).catch((err) => {
|
|
18
|
+
console.error(err);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
printUsage(serviceName);
|
|
24
|
+
process.exit(command ? 1 : 0);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function printUsage(name) {
|
|
28
|
+
console.log(`
|
|
29
|
+
${name} CLI (powered by futonic)
|
|
30
|
+
|
|
31
|
+
Usage:
|
|
32
|
+
${name} generate --orm=<drizzle|prisma|kysely> [options]
|
|
33
|
+
|
|
34
|
+
Commands:
|
|
35
|
+
generate Generate database schema files for the host application
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
--orm Target ORM (required): drizzle, prisma, kysely
|
|
39
|
+
--provider Database provider: pg, mysql, sqlite (default: pg)
|
|
40
|
+
--out Output file path (optional, defaults vary by ORM)
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
function parseFlag(flags, name) {
|
|
44
|
+
const flag = flags.find((a) => a.startsWith(`--${name}=`));
|
|
45
|
+
return flag?.split("=")[1];
|
|
46
|
+
}
|
|
47
|
+
async function runGenerate(flags, options) {
|
|
48
|
+
const { service } = options;
|
|
49
|
+
const serviceName = options.name ?? service.id;
|
|
50
|
+
const orm = parseFlag(flags, "orm");
|
|
51
|
+
if (!orm) {
|
|
52
|
+
console.error("Error: --orm flag is required");
|
|
53
|
+
console.error(` ${serviceName} generate --orm=drizzle|prisma|kysely`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const provider = parseFlag(flags, "provider") ?? "pg";
|
|
57
|
+
if (!["pg", "mysql", "sqlite"].includes(provider)) {
|
|
58
|
+
console.error(`Invalid provider: ${provider}. Must be pg, mysql, or sqlite`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const outPath = parseFlag(flags, "out");
|
|
62
|
+
const tables = getServiceTables([
|
|
63
|
+
{
|
|
64
|
+
...service,
|
|
65
|
+
mountConfig: { mount: "" }
|
|
66
|
+
}
|
|
67
|
+
]);
|
|
68
|
+
const generator = await loadGenerator(orm);
|
|
69
|
+
const result = await generator({ tables, provider, file: outPath });
|
|
70
|
+
if (!result.code) {
|
|
71
|
+
console.log(`[${serviceName}] No schema changes detected.`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const dir = path.dirname(result.fileName);
|
|
75
|
+
await mkdir(dir, { recursive: true });
|
|
76
|
+
await writeFile(result.fileName, result.code, "utf-8");
|
|
77
|
+
console.log(`[${serviceName}] Generated ${orm} schema → ${result.fileName}`);
|
|
78
|
+
}
|
|
79
|
+
async function loadGenerator(orm) {
|
|
80
|
+
switch (orm) {
|
|
81
|
+
case "drizzle": {
|
|
82
|
+
const { generateDrizzleSchema } = await import("../chunk-s9sdjw1m.js");
|
|
83
|
+
return generateDrizzleSchema;
|
|
84
|
+
}
|
|
85
|
+
case "prisma": {
|
|
86
|
+
const { generatePrismaSchema } = await import("../chunk-eqeddyek.js");
|
|
87
|
+
return generatePrismaSchema;
|
|
88
|
+
}
|
|
89
|
+
case "kysely": {
|
|
90
|
+
const { generateKyselySchema } = await import("../chunk-s3j6ndfy.js");
|
|
91
|
+
return generateKyselySchema;
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
console.error(`Unknown ORM: ${orm}. Supported: drizzle, prisma, kysely`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
createCLI
|
|
100
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports better-call's client utilities for type-safe API consumption.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { createClient } from "futonic/client";
|
|
7
|
+
* import type { billingRouter } from "@acme/billing";
|
|
8
|
+
*
|
|
9
|
+
* const client = createClient<typeof billingRouter>({
|
|
10
|
+
* baseURL: "/api/billing",
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export { createClient } from "better-call/client";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { InternalAdapter } from "../db/internal-adapter";
|
|
2
|
+
import type { ServiceDBSchema } from "../db/schema";
|
|
3
|
+
export interface Logger {
|
|
4
|
+
info(message: string, ...args: unknown[]): void;
|
|
5
|
+
warn(message: string, ...args: unknown[]): void;
|
|
6
|
+
error(message: string, ...args: unknown[]): void;
|
|
7
|
+
debug(message: string, ...args: unknown[]): void;
|
|
8
|
+
}
|
|
9
|
+
export interface HostInfo {
|
|
10
|
+
baseURL: string;
|
|
11
|
+
mountPath: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolvedConfig {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface ServiceContext<TSchema extends ServiceDBSchema = ServiceDBSchema> {
|
|
17
|
+
db: InternalAdapter<TSchema>;
|
|
18
|
+
config: ResolvedConfig;
|
|
19
|
+
logger: Logger;
|
|
20
|
+
hostInfo: HostInfo;
|
|
21
|
+
}
|
|
22
|
+
export declare function createLogger(serviceId: string): Logger;
|
|
23
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,MAAM;IACtB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,QAAQ;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc,CAC9B,OAAO,SAAS,eAAe,GAAG,eAAe;IAEjD,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQtD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type DatabaseConnection } from "../db/kysely-factory";
|
|
2
|
+
import type { MountedService } from "./service";
|
|
3
|
+
export interface HostConfig {
|
|
4
|
+
database?: DatabaseConnection;
|
|
5
|
+
services: MountedService[];
|
|
6
|
+
baseURL?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Host {
|
|
9
|
+
services: Map<string, MountedService>;
|
|
10
|
+
init(): Promise<void>;
|
|
11
|
+
shutdown(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createHost(config: HostConfig): Host;
|
|
14
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/core/host.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,kBAAkB,EAEvB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACtC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAgFnD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ServiceDBSchema } from "../db/schema";
|
|
2
|
+
import type { ServiceContext } from "./context";
|
|
3
|
+
export interface ServiceConfig<TConfig = unknown> {
|
|
4
|
+
mount: string;
|
|
5
|
+
middleware?: unknown[];
|
|
6
|
+
config?: TConfig;
|
|
7
|
+
}
|
|
8
|
+
export interface EmbeddableService<TConfig = unknown, TSchema extends ServiceDBSchema = ServiceDBSchema, TEndpoints extends Record<string, unknown> = Record<string, unknown>> {
|
|
9
|
+
id: string;
|
|
10
|
+
version: string;
|
|
11
|
+
dependencies: {
|
|
12
|
+
database: boolean;
|
|
13
|
+
};
|
|
14
|
+
dbSchema?: TSchema;
|
|
15
|
+
endpoints: TEndpoints;
|
|
16
|
+
onInit?: (ctx: ServiceContext<TSchema>) => Promise<void>;
|
|
17
|
+
onReady?: (ctx: ServiceContext<TSchema>) => Promise<void>;
|
|
18
|
+
onShutdown?: () => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface MountedService<TConfig = unknown, TSchema extends ServiceDBSchema = ServiceDBSchema, TEndpoints extends Record<string, unknown> = Record<string, unknown>> extends EmbeddableService<TConfig, TSchema, TEndpoints> {
|
|
21
|
+
mountConfig: ServiceConfig<TConfig>;
|
|
22
|
+
serviceContext?: ServiceContext<TSchema>;
|
|
23
|
+
}
|
|
24
|
+
export declare function createService<TConfig, TSchema extends ServiceDBSchema, TEndpoints extends Record<string, unknown>>(definition: EmbeddableService<TConfig, TSchema, TEndpoints>): (config: ServiceConfig<TConfig>) => MountedService<TConfig, TSchema, TEndpoints>;
|
|
25
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/core/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,OAAO;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB,CACjC,OAAO,GAAG,OAAO,EACjB,OAAO,SAAS,eAAe,GAAG,eAAe,EACjD,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEpE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc,CAC9B,OAAO,GAAG,OAAO,EACjB,OAAO,SAAS,eAAe,GAAG,eAAe,EACjD,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACnE,SAAQ,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;IACxD,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACzC;AAED,wBAAgB,aAAa,CAC5B,OAAO,EACP,OAAO,SAAS,eAAe,EAC/B,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAE1C,UAAU,EAAE,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,GACzD,CACF,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,KAC1B,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAKhD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal database adapter that scopes all queries to a service's prefixed tables.
|
|
3
|
+
*
|
|
4
|
+
* Follows the same 8-method interface as better-auth's Kysely adapter
|
|
5
|
+
* (`create`, `findOne`, `findMany`, `count`, `update`, `updateMany`, `delete`, `deleteMany`).
|
|
6
|
+
*
|
|
7
|
+
* Access tables via property name: `db.invoices.create({ ... })`.
|
|
8
|
+
*/
|
|
9
|
+
import type { Kysely } from "kysely";
|
|
10
|
+
import { type ServiceDBSchema } from "./schema";
|
|
11
|
+
export interface Where {
|
|
12
|
+
field: string;
|
|
13
|
+
value: unknown;
|
|
14
|
+
operator?: "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "not_in";
|
|
15
|
+
connector?: "AND" | "OR";
|
|
16
|
+
}
|
|
17
|
+
export type FilterOp = "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "not_in" | "contains" | "startsWith" | "endsWith" | "isNull" | "isNotNull";
|
|
18
|
+
export type FilterNode = {
|
|
19
|
+
type: "and" | "or";
|
|
20
|
+
nodes: FilterNode[];
|
|
21
|
+
} | {
|
|
22
|
+
type: "not";
|
|
23
|
+
node: FilterNode;
|
|
24
|
+
} | {
|
|
25
|
+
type: "cond";
|
|
26
|
+
field: string;
|
|
27
|
+
op: FilterOp;
|
|
28
|
+
value?: unknown;
|
|
29
|
+
};
|
|
30
|
+
export interface FindManyOptions {
|
|
31
|
+
where?: Where[];
|
|
32
|
+
/** Boolean expression tree (supports and/or/not + contains/like); combined with `where`. */
|
|
33
|
+
filter?: FilterNode;
|
|
34
|
+
/** Column projection; when omitted selects all columns. */
|
|
35
|
+
select?: string[];
|
|
36
|
+
limit?: number;
|
|
37
|
+
offset?: number;
|
|
38
|
+
sortBy?: {
|
|
39
|
+
field: string;
|
|
40
|
+
direction: "asc" | "desc";
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface TableAdapter {
|
|
44
|
+
create(data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
45
|
+
findOne(where: Where[]): Promise<Record<string, unknown> | null>;
|
|
46
|
+
findMany(options?: FindManyOptions): Promise<Record<string, unknown>[]>;
|
|
47
|
+
count(where?: Where[] | {
|
|
48
|
+
where?: Where[];
|
|
49
|
+
filter?: FilterNode;
|
|
50
|
+
}): Promise<number>;
|
|
51
|
+
update(where: Where[], data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
52
|
+
updateMany(where: Where[], data: Record<string, unknown>): Promise<number>;
|
|
53
|
+
delete(where: Where[]): Promise<void>;
|
|
54
|
+
deleteMany(where: Where[]): Promise<number>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Proxy-based adapter that scopes all queries to a service's prefixed tables.
|
|
58
|
+
*/
|
|
59
|
+
export type InternalAdapter<TSchema extends ServiceDBSchema = ServiceDBSchema> = {
|
|
60
|
+
[K in keyof TSchema["tables"]]: TableAdapter;
|
|
61
|
+
};
|
|
62
|
+
export declare function createInternalAdapter<TSchema extends ServiceDBSchema>(kysely: Kysely<Record<string, unknown>>, serviceId: string, schema?: TSchema): InternalAdapter<TSchema>;
|
|
63
|
+
//# sourceMappingURL=internal-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-adapter.d.ts","sourceRoot":"","sources":["../../src/db/internal-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kysely instance factory with dialect auto-detection.
|
|
3
|
+
*
|
|
4
|
+
* Forked from better-auth's `packages/kysely-adapter/src/dialect.ts` (MIT).
|
|
5
|
+
* Adapted to work standalone without BetterAuthOptions — accepts raw driver
|
|
6
|
+
* instances or Kysely Dialect objects directly.
|
|
7
|
+
*/
|
|
8
|
+
import { Kysely } from "kysely";
|
|
9
|
+
export type KyselyDatabaseType = "sqlite" | "mysql" | "postgres";
|
|
10
|
+
/**
|
|
11
|
+
* The host passes one of these to `createHost({ database: ... })`.
|
|
12
|
+
*
|
|
13
|
+
* Accepted forms:
|
|
14
|
+
* - A Kysely `Dialect` instance (most explicit)
|
|
15
|
+
* - A `pg.Pool` (detected via `"connect"` property)
|
|
16
|
+
* - A `mysql2` pool (detected via `"getConnection"` property)
|
|
17
|
+
* - A `better-sqlite3` instance (detected via `"aggregate"` property)
|
|
18
|
+
* - A Bun SQLite instance (detected via `"fileControl"` property)
|
|
19
|
+
*/
|
|
20
|
+
export type DatabaseConnection = any;
|
|
21
|
+
/**
|
|
22
|
+
* Detects the database type from a driver instance using property sniffing.
|
|
23
|
+
*
|
|
24
|
+
* Forked from better-auth `getKyselyDatabaseType()`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectDatabaseType(db: DatabaseConnection): KyselyDatabaseType | null;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a Kysely instance from the host's database connection.
|
|
29
|
+
*
|
|
30
|
+
* Forked from better-auth `createKyselyAdapter()`.
|
|
31
|
+
* Auto-detects the dialect from the driver instance shape.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createKyselyInstance(connection: DatabaseConnection): Kysely<Record<string, unknown>>;
|
|
34
|
+
//# sourceMappingURL=kysely-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-factory.d.ts","sourceRoot":"","sources":["../../src/db/kysely-factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,MAAM,EAAgD,MAAM,QAAQ,CAAC;AAE9E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjE;;;;;;;;;GASG;AAEH,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAErC;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,EAAE,EAAE,kBAAkB,GACpB,kBAAkB,GAAG,IAAI,CA6B3B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,kBAAkB,GAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAkDjC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { MountedService } from "../core/service";
|
|
2
|
+
export interface FieldDefinition {
|
|
3
|
+
type: "string" | "number" | "boolean" | "date" | "json" | "binary";
|
|
4
|
+
required?: boolean;
|
|
5
|
+
unique?: boolean;
|
|
6
|
+
primaryKey?: boolean;
|
|
7
|
+
defaultValue?: unknown;
|
|
8
|
+
enum?: string[];
|
|
9
|
+
references?: {
|
|
10
|
+
model: string;
|
|
11
|
+
field: string;
|
|
12
|
+
onDelete?: "cascade" | "restrict" | "set-null";
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface TableDefinition {
|
|
16
|
+
fields: Record<string, FieldDefinition>;
|
|
17
|
+
}
|
|
18
|
+
export interface ServiceDBSchema {
|
|
19
|
+
tables: Record<string, TableDefinition>;
|
|
20
|
+
}
|
|
21
|
+
export interface PrefixedTable {
|
|
22
|
+
originalName: string;
|
|
23
|
+
prefixedName: string;
|
|
24
|
+
serviceId: string;
|
|
25
|
+
fields: Record<string, FieldDefinition>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Collects all mounted services' dbSchema values, applies `{serviceId}_` prefix,
|
|
29
|
+
* and returns a unified map of prefixed table name → table definition.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getServiceTables(services: MountedService[]): Map<string, PrefixedTable>;
|
|
32
|
+
/**
|
|
33
|
+
* Maps a logical (unprefixed) table name to its prefixed counterpart.
|
|
34
|
+
*/
|
|
35
|
+
export declare function prefixTableName(serviceId: string, tableName: string): string;
|
|
36
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;KAC/C,CAAC;CACF;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,cAAc,EAAE,GACxB,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CA2B5B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { createService } from "./core/service";
|
|
2
|
+
export type { EmbeddableService, MountedService, ServiceConfig, } from "./core/service";
|
|
3
|
+
export { createHost } from "./core/host";
|
|
4
|
+
export type { HostConfig, Host } from "./core/host";
|
|
5
|
+
export type { ServiceContext, Logger, HostInfo, ResolvedConfig, } from "./core/context";
|
|
6
|
+
export type { ServiceDBSchema, TableDefinition, FieldDefinition, PrefixedTable, } from "./db/schema";
|
|
7
|
+
export { getServiceTables, prefixTableName } from "./db/schema";
|
|
8
|
+
export type { InternalAdapter, TableAdapter, FindManyOptions, Where, } from "./db/internal-adapter";
|
|
9
|
+
export { createServiceEndpoint } from "./router/endpoint";
|
|
10
|
+
export { createServiceMiddleware } from "./router/middleware";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EACX,iBAAiB,EACjB,cAAc,EACd,aAAa,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EACX,cAAc,EACd,MAAM,EACN,QAAQ,EACR,cAAc,GACd,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACX,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EACX,eAAe,EACf,YAAY,EACZ,eAAe,EACf,KAAK,GACL,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
|