ras-stack 0.10.0 → 0.12.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/README.md +28 -2
- package/dist/database/index.d.ts +12 -1
- package/dist/database/index.js +11 -1
- package/dist/database/index.js.map +1 -1
- package/dist/database/postgres.d.ts +16 -0
- package/dist/database/postgres.js +29 -0
- package/dist/database/postgres.js.map +1 -0
- package/dist/tanstack/server.d.ts +14 -1
- package/dist/tanstack/server.js +18 -1
- package/dist/tanstack/server.js.map +1 -1
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -70,7 +70,13 @@ The optional TanStack entrypoints bind the shared primitives to TanStack Start's
|
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
72
|
import { createStackQueryClient } from 'ras-stack/tanstack/query'
|
|
73
|
-
import {
|
|
73
|
+
import {
|
|
74
|
+
betterAuthHandlers,
|
|
75
|
+
canonicalHostMiddleware,
|
|
76
|
+
createTanStackRpc,
|
|
77
|
+
requireTanStackMutationOrigin,
|
|
78
|
+
tanStackHealthHandler,
|
|
79
|
+
} from 'ras-stack/tanstack/server'
|
|
74
80
|
|
|
75
81
|
export const { rpc, mutationRpc } = createTanStackRpc({
|
|
76
82
|
requireMutation: (request) =>
|
|
@@ -84,9 +90,13 @@ export const { rpc, mutationRpc } = createTanStackRpc({
|
|
|
84
90
|
})
|
|
85
91
|
|
|
86
92
|
export const queryClient = createStackQueryClient()
|
|
93
|
+
|
|
94
|
+
export const authHandlers = betterAuthHandlers(() => app().auth)
|
|
95
|
+
export const healthHandler = tanStackHealthHandler(() => app().database.get(sql`SELECT 1`))
|
|
96
|
+
export const canonicalHost = canonicalHostMiddleware(() => ({ canonicalUrl: process.env.APP_URL }))
|
|
87
97
|
```
|
|
88
98
|
|
|
89
|
-
Applications still own their auth clients, authorization,
|
|
99
|
+
Applications still own their auth clients, authorization, file-route declarations, router, logging, health-check work, and Query configuration. Both integrations remain optional, and their upstream libraries remain directly accessible.
|
|
90
100
|
|
|
91
101
|
Only enable `trustForwardedHeaders` behind a proxy that replaces incoming forwarded headers. Otherwise a client could choose the origin used by the check.
|
|
92
102
|
|
|
@@ -111,6 +121,22 @@ const database = openDrizzleSqlite({
|
|
|
111
121
|
|
|
112
122
|
Applications retain their schema, migrations, database path, repositories, transactions, and driver selection. Dual-database applications can use `openSqliteClient()` and `configureSqlite()` beneath their own wrapper without forcing PostgreSQL through a shared database interface.
|
|
113
123
|
|
|
124
|
+
The PostgreSQL entrypoint applies the same boundary to Postgres.js and Drizzle while returning both native objects:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { databaseTarget } from 'ras-stack/database'
|
|
128
|
+
import { closeDrizzlePostgres, migrateDrizzlePostgres, openDrizzlePostgres } from 'ras-stack/database/postgres'
|
|
129
|
+
|
|
130
|
+
const target = databaseTarget({ databaseUrl: process.env.DATABASE_URL, sqliteFile })
|
|
131
|
+
if (target.provider === 'postgres') {
|
|
132
|
+
const connection = openDrizzlePostgres({ url: target.url, schema })
|
|
133
|
+
await migrateDrizzlePostgres(connection, postgresMigrationsFolder)
|
|
134
|
+
await closeDrizzlePostgres(connection)
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The package does not make SQLite and PostgreSQL queries look identical. Applications keep driver-specific transaction and compatibility behavior while sharing target validation, pool defaults, numeric parsing, migrations, credential-safe display URLs, and shutdown.
|
|
139
|
+
|
|
114
140
|
## Realtime updates
|
|
115
141
|
|
|
116
142
|
Applications choose their channel names, authorize subscriptions, and define payloads. `ras-stack` handles Centrifugo's HTTP publication, signed tokens, and repeated browser lifecycle mechanics:
|
package/dist/database/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { URL } from 'node:url';
|
|
2
2
|
export type BundledDirectoryOptions = {
|
|
3
3
|
developmentUrl: URL;
|
|
4
4
|
production: boolean;
|
|
@@ -6,3 +6,14 @@ export type BundledDirectoryOptions = {
|
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
8
|
export declare function bundledDirectory(options: BundledDirectoryOptions): string;
|
|
9
|
+
export type DatabaseTarget = {
|
|
10
|
+
provider: 'sqlite';
|
|
11
|
+
file: string;
|
|
12
|
+
} | {
|
|
13
|
+
provider: 'postgres';
|
|
14
|
+
url: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function databaseTarget(options: {
|
|
17
|
+
databaseUrl?: string;
|
|
18
|
+
sqliteFile: string;
|
|
19
|
+
}): DatabaseTarget;
|
package/dist/database/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { fileURLToPath, URL } from 'node:url';
|
|
3
3
|
export function bundledDirectory(options) {
|
|
4
4
|
if (!options.production)
|
|
5
5
|
return fileURLToPath(options.developmentUrl);
|
|
@@ -8,4 +8,14 @@ export function bundledDirectory(options) {
|
|
|
8
8
|
throw new Error('production entrypoint is required to resolve a bundled directory');
|
|
9
9
|
return path.join(path.dirname(entry), options.name);
|
|
10
10
|
}
|
|
11
|
+
export function databaseTarget(options) {
|
|
12
|
+
const configured = options.databaseUrl?.trim();
|
|
13
|
+
if (!configured)
|
|
14
|
+
return { provider: 'sqlite', file: options.sqliteFile };
|
|
15
|
+
const url = new URL(configured);
|
|
16
|
+
if (url.protocol !== 'postgres:' && url.protocol !== 'postgresql:') {
|
|
17
|
+
throw new Error('database URL must use a postgres:// or postgresql:// URL');
|
|
18
|
+
}
|
|
19
|
+
return { provider: 'postgres', url: configured };
|
|
20
|
+
}
|
|
11
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAS7C,MAAM,UAAU,gBAAgB,CAAC,OAAgC;IAC/D,IAAI,CAAC,OAAO,CAAC,UAAU;QAAE,OAAO,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACxD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAA;IAC/F,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;AACrD,CAAC;AAID,MAAM,UAAU,cAAc,CAAC,OAAqD;IAClF,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAA;IAC9C,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;IACxE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAA;IAC/B,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAA;AAClD,CAAC","sourcesContent":["import path from 'node:path'\nimport { fileURLToPath, URL } from 'node:url'\n\nexport type BundledDirectoryOptions = {\n developmentUrl: URL\n production: boolean\n productionEntry?: string\n name: string\n}\n\nexport function bundledDirectory(options: BundledDirectoryOptions) {\n if (!options.production) return fileURLToPath(options.developmentUrl)\n const entry = options.productionEntry ?? process.argv[1]\n if (!entry) throw new Error('production entrypoint is required to resolve a bundled directory')\n return path.join(path.dirname(entry), options.name)\n}\n\nexport type DatabaseTarget = { provider: 'sqlite'; file: string } | { provider: 'postgres'; url: string }\n\nexport function databaseTarget(options: { databaseUrl?: string; sqliteFile: string }): DatabaseTarget {\n const configured = options.databaseUrl?.trim()\n if (!configured) return { provider: 'sqlite', file: options.sqliteFile }\n const url = new URL(configured)\n if (url.protocol !== 'postgres:' && url.protocol !== 'postgresql:') {\n throw new Error('database URL must use a postgres:// or postgresql:// URL')\n }\n return { provider: 'postgres', url: configured }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
|
2
|
+
import postgres, { type Sql } from 'postgres';
|
|
3
|
+
export type PostgresClientOptions = NonNullable<Parameters<typeof postgres>[1]>;
|
|
4
|
+
export type OpenDrizzlePostgresOptions<TSchema extends Record<string, unknown>> = {
|
|
5
|
+
url: string;
|
|
6
|
+
schema: TSchema;
|
|
7
|
+
client?: PostgresClientOptions;
|
|
8
|
+
};
|
|
9
|
+
export type DrizzlePostgresConnection<TSchema extends Record<string, unknown>> = {
|
|
10
|
+
database: PostgresJsDatabase<TSchema>;
|
|
11
|
+
client: Sql;
|
|
12
|
+
};
|
|
13
|
+
export declare function openDrizzlePostgres<TSchema extends Record<string, unknown>>(options: OpenDrizzlePostgresOptions<TSchema>): DrizzlePostgresConnection<TSchema>;
|
|
14
|
+
export declare function migrateDrizzlePostgres<TSchema extends Record<string, unknown>>(connection: DrizzlePostgresConnection<TSchema>, migrationsFolder: string): Promise<void>;
|
|
15
|
+
export declare function closeDrizzlePostgres(connection: Pick<DrizzlePostgresConnection<Record<string, unknown>>, 'client'>, timeout?: number): Promise<void>;
|
|
16
|
+
export declare function redactedPostgresUrl(source: string): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { drizzle } from 'drizzle-orm/postgres-js';
|
|
2
|
+
import { migrate } from 'drizzle-orm/postgres-js/migrator';
|
|
3
|
+
import postgres, {} from 'postgres';
|
|
4
|
+
export function openDrizzlePostgres(options) {
|
|
5
|
+
const client = postgres(options.url, {
|
|
6
|
+
max: 10,
|
|
7
|
+
onnotice: () => undefined,
|
|
8
|
+
types: {
|
|
9
|
+
bigint: { to: 20, from: [20], serialize: (value) => String(value), parse: Number },
|
|
10
|
+
numeric: { to: 1700, from: [1700], serialize: (value) => String(value), parse: Number },
|
|
11
|
+
},
|
|
12
|
+
...options.client,
|
|
13
|
+
});
|
|
14
|
+
const database = drizzle(client, { schema: options.schema });
|
|
15
|
+
return { database, client };
|
|
16
|
+
}
|
|
17
|
+
export async function migrateDrizzlePostgres(connection, migrationsFolder) {
|
|
18
|
+
await migrate(connection.database, { migrationsFolder });
|
|
19
|
+
}
|
|
20
|
+
export async function closeDrizzlePostgres(connection, timeout = 5) {
|
|
21
|
+
await connection.client.end({ timeout });
|
|
22
|
+
}
|
|
23
|
+
export function redactedPostgresUrl(source) {
|
|
24
|
+
const url = new URL(source);
|
|
25
|
+
url.username = '';
|
|
26
|
+
url.password = '';
|
|
27
|
+
return url.toString();
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/database/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA2B,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAA;AAC1D,OAAO,QAAQ,EAAE,EAAY,MAAM,UAAU,CAAA;AAe7C,MAAM,UAAU,mBAAmB,CACjC,OAA4C;IAE5C,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,GAAG,EAAE,EAAE;QACP,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;QACzB,KAAK,EAAE;YACL,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;YAC1F,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;SAChG;QACD,GAAG,OAAO,CAAC,MAAM;KAClB,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAA8C,EAC9C,gBAAwB;IAExB,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAA;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,UAA8E,EAAE,OAAO,GAAG,CAAC;IACpI,MAAM,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAA;IACjB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAA;IACjB,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;AACvB,CAAC","sourcesContent":["import { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js'\nimport { migrate } from 'drizzle-orm/postgres-js/migrator'\nimport postgres, { type Sql } from 'postgres'\n\nexport type PostgresClientOptions = NonNullable<Parameters<typeof postgres>[1]>\n\nexport type OpenDrizzlePostgresOptions<TSchema extends Record<string, unknown>> = {\n url: string\n schema: TSchema\n client?: PostgresClientOptions\n}\n\nexport type DrizzlePostgresConnection<TSchema extends Record<string, unknown>> = {\n database: PostgresJsDatabase<TSchema>\n client: Sql\n}\n\nexport function openDrizzlePostgres<TSchema extends Record<string, unknown>>(\n options: OpenDrizzlePostgresOptions<TSchema>,\n): DrizzlePostgresConnection<TSchema> {\n const client = postgres(options.url, {\n max: 10,\n onnotice: () => undefined,\n types: {\n bigint: { to: 20, from: [20], serialize: (value: number) => String(value), parse: Number },\n numeric: { to: 1700, from: [1700], serialize: (value: number) => String(value), parse: Number },\n },\n ...options.client,\n })\n const database = drizzle(client, { schema: options.schema })\n return { database, client }\n}\n\nexport async function migrateDrizzlePostgres<TSchema extends Record<string, unknown>>(\n connection: DrizzlePostgresConnection<TSchema>,\n migrationsFolder: string,\n) {\n await migrate(connection.database, { migrationsFolder })\n}\n\nexport async function closeDrizzlePostgres(connection: Pick<DrizzlePostgresConnection<Record<string, unknown>>, 'client'>, timeout = 5) {\n await connection.client.end({ timeout })\n}\n\nexport function redactedPostgresUrl(source: string) {\n const url = new URL(source)\n url.username = ''\n url.password = ''\n return url.toString()\n}\n"]}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { type OriginOptions } from '../auth/index.js';
|
|
2
|
-
import { type RpcOptions } from '../server/index.js';
|
|
2
|
+
import { type CanonicalRedirectOptions, type HealthResponseOptions, type RpcOptions } from '../server/index.js';
|
|
3
3
|
export type TanStackRpcOptions = Omit<RpcOptions, 'getRequest'> & Pick<RpcOptions, 'getRequest'>;
|
|
4
4
|
export declare function createTanStackRpc(options?: TanStackRpcOptions): {
|
|
5
5
|
rpc: <T>(work: () => Promise<T> | T) => Promise<T>;
|
|
6
6
|
mutationRpc: <T>(work: () => Promise<T> | T, request?: Request | undefined) => Promise<T>;
|
|
7
7
|
};
|
|
8
8
|
export declare function requireTanStackMutationOrigin(options?: OriginOptions, request?: Request): void;
|
|
9
|
+
type RequestContext = {
|
|
10
|
+
request: Request;
|
|
11
|
+
};
|
|
12
|
+
export declare function betterAuthHandlers(resolveAuth: () => {
|
|
13
|
+
handler(request: Request): Response | Promise<Response>;
|
|
14
|
+
}): {
|
|
15
|
+
GET: ({ request }: RequestContext) => Promise<Response> | Response;
|
|
16
|
+
POST: ({ request }: RequestContext) => Promise<Response> | Response;
|
|
17
|
+
};
|
|
18
|
+
export declare function tanStackHealthHandler(check: () => void | Promise<void>, options?: HealthResponseOptions): () => Promise<Response>;
|
|
19
|
+
export declare function canonicalHostRequest<T>(request: Request, next: () => T, options: CanonicalRedirectOptions): Response | T;
|
|
20
|
+
export declare function canonicalHostMiddleware(resolveOptions: () => CanonicalRedirectOptions): import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
21
|
+
export {};
|
package/dist/tanstack/server.js
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { getRequest } from '@tanstack/react-start/server';
|
|
2
|
+
import { createMiddleware } from '@tanstack/react-start';
|
|
2
3
|
import { requireSameOrigin } from '../auth/index.js';
|
|
3
|
-
import { createRpc } from '../server/index.js';
|
|
4
|
+
import { canonicalRedirect, createRpc, healthResponse, } from '../server/index.js';
|
|
4
5
|
export function createTanStackRpc(options = {}) {
|
|
5
6
|
return createRpc({ ...options, getRequest: options.getRequest ?? getRequest });
|
|
6
7
|
}
|
|
7
8
|
export function requireTanStackMutationOrigin(options = {}, request = getRequest()) {
|
|
8
9
|
return requireSameOrigin(request, options);
|
|
9
10
|
}
|
|
11
|
+
export function betterAuthHandlers(resolveAuth) {
|
|
12
|
+
const handle = ({ request }) => resolveAuth().handler(request);
|
|
13
|
+
return { GET: handle, POST: handle };
|
|
14
|
+
}
|
|
15
|
+
export function tanStackHealthHandler(check, options = {}) {
|
|
16
|
+
return () => healthResponse(check, options);
|
|
17
|
+
}
|
|
18
|
+
export function canonicalHostRequest(request, next, options) {
|
|
19
|
+
const redirect = canonicalRedirect(request.url, options);
|
|
20
|
+
return redirect ? Response.redirect(redirect, 301) : next();
|
|
21
|
+
}
|
|
22
|
+
export function canonicalHostMiddleware(resolveOptions) {
|
|
23
|
+
return createMiddleware({ type: 'request' }).server(({ request, next }) => {
|
|
24
|
+
return canonicalHostRequest(request, next, resolveOptions());
|
|
25
|
+
});
|
|
26
|
+
}
|
|
10
27
|
//# sourceMappingURL=server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/tanstack/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAsB,MAAM,kBAAkB,CAAA;AACxE,OAAO,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/tanstack/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAsB,MAAM,kBAAkB,CAAA;AACxE,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,cAAc,GAIf,MAAM,oBAAoB,CAAA;AAI3B,MAAM,UAAU,iBAAiB,CAAC,OAAO,GAAuB,EAAE;IAChE,OAAO,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC,CAAA;AAChF,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,OAAO,GAAkB,EAAE,EAAE,OAAO,GAAG,UAAU,EAAE;IAC/F,OAAO,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC5C,CAAC;AAID,MAAM,UAAU,kBAAkB,CAAC,WAA8E;IAC/G,MAAM,MAAM,GAAG,CAAC,EAAE,OAAO,EAAkB,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9E,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAiC,EAAE,OAAO,GAA0B,EAAE;IAC1G,OAAO,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAI,OAAgB,EAAE,IAAa,EAAE,OAAiC;IACxG,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACxD,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,cAA8C;IACpF,OAAO,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACxE,OAAO,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;IAC9D,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { getRequest } from '@tanstack/react-start/server'\nimport { createMiddleware } from '@tanstack/react-start'\nimport { requireSameOrigin, type OriginOptions } from '../auth/index.js'\nimport {\n canonicalRedirect,\n createRpc,\n healthResponse,\n type CanonicalRedirectOptions,\n type HealthResponseOptions,\n type RpcOptions,\n} from '../server/index.js'\n\nexport type TanStackRpcOptions = Omit<RpcOptions, 'getRequest'> & Pick<RpcOptions, 'getRequest'>\n\nexport function createTanStackRpc(options: TanStackRpcOptions = {}) {\n return createRpc({ ...options, getRequest: options.getRequest ?? getRequest })\n}\n\nexport function requireTanStackMutationOrigin(options: OriginOptions = {}, request = getRequest()) {\n return requireSameOrigin(request, options)\n}\n\ntype RequestContext = { request: Request }\n\nexport function betterAuthHandlers(resolveAuth: () => { handler(request: Request): Response | Promise<Response> }) {\n const handle = ({ request }: RequestContext) => resolveAuth().handler(request)\n return { GET: handle, POST: handle }\n}\n\nexport function tanStackHealthHandler(check: () => void | Promise<void>, options: HealthResponseOptions = {}) {\n return () => healthResponse(check, options)\n}\n\nexport function canonicalHostRequest<T>(request: Request, next: () => T, options: CanonicalRedirectOptions): Response | T {\n const redirect = canonicalRedirect(request.url, options)\n return redirect ? Response.redirect(redirect, 301) : next()\n}\n\nexport function canonicalHostMiddleware(resolveOptions: () => CanonicalRedirectOptions) {\n return createMiddleware({ type: 'request' }).server(({ request, next }) => {\n return canonicalHostRequest(request, next, resolveOptions())\n })\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ras-stack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Composable full-stack primitives shared across Richard Solomou's applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authentication",
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
"types": "./dist/database/sqlite.d.ts",
|
|
43
43
|
"default": "./dist/database/sqlite.js"
|
|
44
44
|
},
|
|
45
|
+
"./database/postgres": {
|
|
46
|
+
"types": "./dist/database/postgres.d.ts",
|
|
47
|
+
"default": "./dist/database/postgres.js"
|
|
48
|
+
},
|
|
45
49
|
"./policy": {
|
|
46
50
|
"types": "./dist/policy/index.d.ts",
|
|
47
51
|
"default": "./dist/policy/index.js"
|
|
@@ -112,6 +116,7 @@
|
|
|
112
116
|
"oxfmt": "^0.61.0",
|
|
113
117
|
"oxlint": "^1.74.0",
|
|
114
118
|
"oxlint-tsgolint": "^7.0.2001",
|
|
119
|
+
"postgres": "3.4.9",
|
|
115
120
|
"tus-js-client": "^4.3.1",
|
|
116
121
|
"typescript": "^7.0.2",
|
|
117
122
|
"vite": "8.2.1",
|
|
@@ -124,6 +129,7 @@
|
|
|
124
129
|
"centrifuge": ">=5 <6",
|
|
125
130
|
"drizzle-orm": ">=0.45 <1",
|
|
126
131
|
"nodemailer": ">=9 <10",
|
|
132
|
+
"postgres": ">=3.4 <4",
|
|
127
133
|
"tus-js-client": ">=4 <5"
|
|
128
134
|
},
|
|
129
135
|
"peerDependenciesMeta": {
|
|
@@ -145,6 +151,9 @@
|
|
|
145
151
|
"nodemailer": {
|
|
146
152
|
"optional": true
|
|
147
153
|
},
|
|
154
|
+
"postgres": {
|
|
155
|
+
"optional": true
|
|
156
|
+
},
|
|
148
157
|
"tus-js-client": {
|
|
149
158
|
"optional": true
|
|
150
159
|
}
|