@gettersethya/mira-client 0.1.0-alpha.10
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 +21 -0
- package/README.md +140 -0
- package/dist/src/client/auth.d.ts +73 -0
- package/dist/src/client/auth.d.ts.map +1 -0
- package/dist/src/client/auth.js +72 -0
- package/dist/src/client/auth.js.map +1 -0
- package/dist/src/client/collection.d.ts +239 -0
- package/dist/src/client/collection.d.ts.map +1 -0
- package/dist/src/client/collection.js +137 -0
- package/dist/src/client/collection.js.map +1 -0
- package/dist/src/client/errors.d.ts +46 -0
- package/dist/src/client/errors.d.ts.map +1 -0
- package/dist/src/client/errors.js +40 -0
- package/dist/src/client/errors.js.map +1 -0
- package/dist/src/client/factory.d.ts +78 -0
- package/dist/src/client/factory.d.ts.map +1 -0
- package/dist/src/client/factory.js +108 -0
- package/dist/src/client/factory.js.map +1 -0
- package/dist/src/client/file.d.ts +116 -0
- package/dist/src/client/file.d.ts.map +1 -0
- package/dist/src/client/file.js +99 -0
- package/dist/src/client/file.js.map +1 -0
- package/dist/src/client/handler.d.ts +92 -0
- package/dist/src/client/handler.d.ts.map +1 -0
- package/dist/src/client/handler.js +62 -0
- package/dist/src/client/handler.js.map +1 -0
- package/dist/src/client/index.d.ts +13 -0
- package/dist/src/client/index.d.ts.map +1 -0
- package/dist/src/client/index.js +7 -0
- package/dist/src/client/index.js.map +1 -0
- package/dist/src/client/telemetry.d.ts +50 -0
- package/dist/src/client/telemetry.d.ts.map +1 -0
- package/dist/src/client/telemetry.js +32 -0
- package/dist/src/client/telemetry.js.map +1 -0
- package/dist/src/client/types.d.ts +137 -0
- package/dist/src/client/types.d.ts.map +1 -0
- package/dist/src/client/types.js +2 -0
- package/dist/src/client/types.js.map +1 -0
- package/dist/src/collection/auth.d.ts +79 -0
- package/dist/src/collection/auth.d.ts.map +1 -0
- package/dist/src/collection/auth.js +50 -0
- package/dist/src/collection/auth.js.map +1 -0
- package/dist/src/collection/base.d.ts +64 -0
- package/dist/src/collection/base.d.ts.map +1 -0
- package/dist/src/collection/base.js +40 -0
- package/dist/src/collection/base.js.map +1 -0
- package/dist/src/collection/bytes.d.ts +51 -0
- package/dist/src/collection/bytes.d.ts.map +1 -0
- package/dist/src/collection/bytes.js +51 -0
- package/dist/src/collection/bytes.js.map +1 -0
- package/dist/src/collection/errors.d.ts +29 -0
- package/dist/src/collection/errors.d.ts.map +1 -0
- package/dist/src/collection/errors.js +23 -0
- package/dist/src/collection/errors.js.map +1 -0
- package/dist/src/collection/field.d.ts +300 -0
- package/dist/src/collection/field.d.ts.map +1 -0
- package/dist/src/collection/field.js +175 -0
- package/dist/src/collection/field.js.map +1 -0
- package/dist/src/collection/index-builder.d.ts +59 -0
- package/dist/src/collection/index-builder.d.ts.map +1 -0
- package/dist/src/collection/index-builder.js +43 -0
- package/dist/src/collection/index-builder.js.map +1 -0
- package/dist/src/collection/index.d.ts +22 -0
- package/dist/src/collection/index.d.ts.map +1 -0
- package/dist/src/collection/index.js +21 -0
- package/dist/src/collection/index.js.map +1 -0
- package/dist/src/collection/serialize.d.ts +24 -0
- package/dist/src/collection/serialize.d.ts.map +1 -0
- package/dist/src/collection/serialize.js +127 -0
- package/dist/src/collection/serialize.js.map +1 -0
- package/dist/src/collection/types.d.ts +119 -0
- package/dist/src/collection/types.d.ts.map +1 -0
- package/dist/src/collection/types.js +2 -0
- package/dist/src/collection/types.js.map +1 -0
- package/dist/src/collection/view.d.ts +57 -0
- package/dist/src/collection/view.d.ts.map +1 -0
- package/dist/src/collection/view.js +49 -0
- package/dist/src/collection/view.js.map +1 -0
- package/dist/src/filter/builder.d.ts +127 -0
- package/dist/src/filter/builder.d.ts.map +1 -0
- package/dist/src/filter/builder.js +72 -0
- package/dist/src/filter/builder.js.map +1 -0
- package/dist/src/filter/compiler.d.ts +48 -0
- package/dist/src/filter/compiler.d.ts.map +1 -0
- package/dist/src/filter/compiler.js +132 -0
- package/dist/src/filter/compiler.js.map +1 -0
- package/dist/src/filter/index.d.ts +6 -0
- package/dist/src/filter/index.d.ts.map +1 -0
- package/dist/src/filter/index.js +4 -0
- package/dist/src/filter/index.js.map +1 -0
- package/dist/src/filter/types.d.ts +96 -0
- package/dist/src/filter/types.d.ts.map +1 -0
- package/dist/src/filter/types.js +44 -0
- package/dist/src/filter/types.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/rule/builder.d.ts +97 -0
- package/dist/src/rule/builder.d.ts.map +1 -0
- package/dist/src/rule/builder.js +126 -0
- package/dist/src/rule/builder.js.map +1 -0
- package/dist/src/rule/index.d.ts +3 -0
- package/dist/src/rule/index.d.ts.map +1 -0
- package/dist/src/rule/index.js +3 -0
- package/dist/src/rule/index.js.map +1 -0
- package/dist/src/rule/types.d.ts +129 -0
- package/dist/src/rule/types.d.ts.map +1 -0
- package/dist/src/rule/types.js +2 -0
- package/dist/src/rule/types.js.map +1 -0
- package/dist/tests/client/auth.test.d.ts +2 -0
- package/dist/tests/client/auth.test.d.ts.map +1 -0
- package/dist/tests/client/auth.test.js +67 -0
- package/dist/tests/client/auth.test.js.map +1 -0
- package/dist/tests/client/collection.test.d.ts +2 -0
- package/dist/tests/client/collection.test.d.ts.map +1 -0
- package/dist/tests/client/collection.test.js +593 -0
- package/dist/tests/client/collection.test.js.map +1 -0
- package/dist/tests/client/file.test.d.ts +2 -0
- package/dist/tests/client/file.test.d.ts.map +1 -0
- package/dist/tests/client/file.test.js +21 -0
- package/dist/tests/client/file.test.js.map +1 -0
- package/dist/tests/client/handler.test.d.ts +2 -0
- package/dist/tests/client/handler.test.d.ts.map +1 -0
- package/dist/tests/client/handler.test.js +24 -0
- package/dist/tests/client/handler.test.js.map +1 -0
- package/dist/tests/client/types.test.d.ts +2 -0
- package/dist/tests/client/types.test.d.ts.map +1 -0
- package/dist/tests/client/types.test.js +168 -0
- package/dist/tests/client/types.test.js.map +1 -0
- package/dist/tests/collection/auth.test.d.ts +2 -0
- package/dist/tests/collection/auth.test.d.ts.map +1 -0
- package/dist/tests/collection/auth.test.js +44 -0
- package/dist/tests/collection/auth.test.js.map +1 -0
- package/dist/tests/collection/base.test.d.ts +2 -0
- package/dist/tests/collection/base.test.d.ts.map +1 -0
- package/dist/tests/collection/base.test.js +70 -0
- package/dist/tests/collection/base.test.js.map +1 -0
- package/dist/tests/collection/bytes.test.d.ts +2 -0
- package/dist/tests/collection/bytes.test.d.ts.map +1 -0
- package/dist/tests/collection/bytes.test.js +9 -0
- package/dist/tests/collection/bytes.test.js.map +1 -0
- package/dist/tests/collection/field.test.d.ts +2 -0
- package/dist/tests/collection/field.test.d.ts.map +1 -0
- package/dist/tests/collection/field.test.js +140 -0
- package/dist/tests/collection/field.test.js.map +1 -0
- package/dist/tests/collection/index-type.test.d.ts +2 -0
- package/dist/tests/collection/index-type.test.d.ts.map +1 -0
- package/dist/tests/collection/index-type.test.js +28 -0
- package/dist/tests/collection/index-type.test.js.map +1 -0
- package/dist/tests/collection/serialize.test.d.ts +2 -0
- package/dist/tests/collection/serialize.test.d.ts.map +1 -0
- package/dist/tests/collection/serialize.test.js +165 -0
- package/dist/tests/collection/serialize.test.js.map +1 -0
- package/dist/tests/collection/view.test.d.ts +2 -0
- package/dist/tests/collection/view.test.d.ts.map +1 -0
- package/dist/tests/collection/view.test.js +66 -0
- package/dist/tests/collection/view.test.js.map +1 -0
- package/dist/tests/filter/compiler.test.d.ts +2 -0
- package/dist/tests/filter/compiler.test.d.ts.map +1 -0
- package/dist/tests/filter/compiler.test.js +156 -0
- package/dist/tests/filter/compiler.test.js.map +1 -0
- package/dist/tests/rule/builder.test.d.ts +2 -0
- package/dist/tests/rule/builder.test.d.ts.map +1 -0
- package/dist/tests/rule/builder.test.js +290 -0
- package/dist/tests/rule/builder.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { HttpClientRequest as HCR } from "@effect/platform";
|
|
2
|
+
import { Effect, MutableRef } from "effect";
|
|
3
|
+
import { MiraError } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Build a file request URL for the Mira file-serving endpoint.
|
|
6
|
+
*
|
|
7
|
+
* Constructs a URL of the form:
|
|
8
|
+
* `{baseUrl}/api/files/{collection}/{id}/{filename}?token={token}&thumb={spec}`
|
|
9
|
+
*
|
|
10
|
+
* Query parameters are only appended when defined.
|
|
11
|
+
*
|
|
12
|
+
* @param baseUrl - The base URL of the Mira server (e.g., "http://localhost:3000" or "/" for same-origin)
|
|
13
|
+
* @param collection - The collection name
|
|
14
|
+
* @param id - The record ID
|
|
15
|
+
* @param filename - The filename as stored in the record's file field
|
|
16
|
+
* @param opts.token - Optional short-lived JWT token for protected files
|
|
17
|
+
* @param opts.thumb - Optional thumbnail spec (e.g., "200x200", "100x100_fit")
|
|
18
|
+
* @returns The fully constructed file URL string
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* buildFileUrl("/", "posts", "abc123", "cover.jpg")
|
|
22
|
+
* // "/api/files/posts/abc123/cover.jpg"
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* buildFileUrl("http://localhost:8090", "users", "u1", "avatar.png", {
|
|
26
|
+
* token: "eyJ...",
|
|
27
|
+
* thumb: "200x200"
|
|
28
|
+
* })
|
|
29
|
+
* // "http://localhost:8090/api/files/users/u1/avatar.png?token=eyJ...&thumb=200x200"
|
|
30
|
+
*/
|
|
31
|
+
export function buildFileUrl(baseUrl, collection, id, filename, opts) {
|
|
32
|
+
const base = `${baseUrl}/api/files/${collection}/${id}/${filename}`;
|
|
33
|
+
const params = new URLSearchParams();
|
|
34
|
+
if (opts?.token !== undefined)
|
|
35
|
+
params.set("token", opts.token);
|
|
36
|
+
if (opts?.thumb !== undefined)
|
|
37
|
+
params.set("thumb", opts.thumb);
|
|
38
|
+
const qs = params.toString();
|
|
39
|
+
return qs ? `${base}?${qs}` : base;
|
|
40
|
+
}
|
|
41
|
+
function toExecuteEffect(reqEffect, execute) {
|
|
42
|
+
return reqEffect.pipe(Effect.flatMap((req) => execute(req)), Effect.catchTag("HttpBodyError", (e) => Effect.fail(new MiraError({ status: 500, body: String(e) }))));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a function that retrieves a short-lived file-access JWT token for a collection.
|
|
46
|
+
* Tokens are cached per collection with a 30-second freshness buffer before expiry.
|
|
47
|
+
*
|
|
48
|
+
* @internal Called internally by `makeFileFields`. Use `ProtectedFileFieldClient.getToken()` instead.
|
|
49
|
+
*/
|
|
50
|
+
export function makeGetFileToken(execute, cacheRef) {
|
|
51
|
+
return (collection) => Effect.gen(function* () {
|
|
52
|
+
const cache = MutableRef.get(cacheRef);
|
|
53
|
+
const cached = cache.get(collection);
|
|
54
|
+
if (cached !== undefined && Date.now() < cached.expiresAt - 30_000) {
|
|
55
|
+
return cached.token;
|
|
56
|
+
}
|
|
57
|
+
const data = yield* toExecuteEffect(HCR.bodyJson(HCR.post("/api/files/token"), { collection }), execute);
|
|
58
|
+
const newCache = new Map(cache).set(collection, data);
|
|
59
|
+
MutableRef.set(cacheRef, newCache);
|
|
60
|
+
return data.token;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the file field client interfaces for a collection.
|
|
65
|
+
* Iterates over the schema's properties, creating `PublicFileFieldClient` or
|
|
66
|
+
* `ProtectedFileFieldClient` instances for each `file`-kind field.
|
|
67
|
+
*
|
|
68
|
+
* @internal Called by `makeCollectionClient` — use `collection.fields` instead.
|
|
69
|
+
*/
|
|
70
|
+
export function makeFileFields(collection, schema, baseUrl, execute, cacheRef, makeClientHandler) {
|
|
71
|
+
const result = {};
|
|
72
|
+
const getFileToken = makeGetFileToken(execute, cacheRef);
|
|
73
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
74
|
+
if (prop["x-kind"] !== "file")
|
|
75
|
+
continue;
|
|
76
|
+
const isProtected = prop["x-protected"] === true;
|
|
77
|
+
if (isProtected) {
|
|
78
|
+
const protectedField = {
|
|
79
|
+
isProtected: true,
|
|
80
|
+
asyncUrl: (id, filename, opts) => makeClientHandler(Effect.gen(function* () {
|
|
81
|
+
const token = yield* getFileToken(collection.name);
|
|
82
|
+
return buildFileUrl(baseUrl, collection.name, id, filename, { token, ...(opts?.thumb !== undefined ? { thumb: opts.thumb } : {}) });
|
|
83
|
+
})),
|
|
84
|
+
url: (id, filename, opts) => buildFileUrl(baseUrl, collection.name, id, filename, { token: opts.token, ...(opts.thumb !== undefined ? { thumb: opts.thumb } : {}) }),
|
|
85
|
+
getToken: () => makeClientHandler(getFileToken(collection.name)),
|
|
86
|
+
};
|
|
87
|
+
result[key] = protectedField;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const publicField = {
|
|
91
|
+
isProtected: false,
|
|
92
|
+
url: (id, filename, opts) => buildFileUrl(baseUrl, collection.name, id, filename, opts),
|
|
93
|
+
};
|
|
94
|
+
result[key] = publicField;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/client/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { HttpClient, HttpClientRequest } from "@effect/platform";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import type { MiraError } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* A dual-interface handler for dealing with Mira server responses.
|
|
6
|
+
*
|
|
7
|
+
* When `TInput extends void` (query operations: getList, getOne, getFirstOrNone, getFullList):
|
|
8
|
+
* - `.raw()` — returns `Promise<TData>`, throws `MiraError` on failure
|
|
9
|
+
* - `.toEffect()` — returns `Effect.Effect<TData, MiraError, HttpClient.HttpClient>`
|
|
10
|
+
*
|
|
11
|
+
* When `TInput` is provided (mutation operations: create, update, delete):
|
|
12
|
+
* - `.raw(input: TInput)` — returns `Promise<TData>`, throws `MiraError` on failure
|
|
13
|
+
* - `.toEffect(input: TInput)` — returns `Effect.Effect<TData, MiraError, HttpClient.HttpClient>`
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import type { ClientHandler } from "@gettersethya/mira-client"
|
|
17
|
+
*
|
|
18
|
+
* // Query handler: TInput = void
|
|
19
|
+
* const listHandler: ClientHandler<{ items: Post[]; nextCursor: number | null }>
|
|
20
|
+
* const items = await listHandler.raw() // Promise-based
|
|
21
|
+
* const effect = listHandler.toEffect() // Effect-based
|
|
22
|
+
*
|
|
23
|
+
* // Mutation handler: TInput = { title: string }
|
|
24
|
+
* const createHandler: ClientHandler<Post, { title: string }>
|
|
25
|
+
* const post = await createHandler.raw({ title: "hello" })
|
|
26
|
+
* const createEffect = createHandler.toEffect({ title: "hello" })
|
|
27
|
+
*
|
|
28
|
+
* @see makeClientHandler — constructs a ClientHandler from an Effect
|
|
29
|
+
* @see makeMutationHandler — constructs a ClientHandler for mutations
|
|
30
|
+
* @see MiraError — the error thrown by .raw()
|
|
31
|
+
*/
|
|
32
|
+
export type ClientHandler<TData, TInput = void> = TInput extends void ? {
|
|
33
|
+
raw(): Promise<TData>;
|
|
34
|
+
toEffect(): Effect.Effect<TData, MiraError, HttpClient.HttpClient>;
|
|
35
|
+
} : {
|
|
36
|
+
raw(input: TInput): Promise<TData>;
|
|
37
|
+
toEffect(input: TInput): Effect.Effect<TData, MiraError, HttpClient.HttpClient>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Construct a `ClientHandler<T>` (query variant, TInput = void) from an Effect.
|
|
41
|
+
*
|
|
42
|
+
* The Effect is provided `FetchHttpClient.layer` at runtime when `.raw()` is called.
|
|
43
|
+
* The `.toEffect()` method returns the Effect without providing the layer, allowing
|
|
44
|
+
* the caller to supply their own `HttpClient` implementation (e.g., for testing).
|
|
45
|
+
*
|
|
46
|
+
* @param effect - The Effect to wrap. Must produce `T` on success or `MiraError` on failure
|
|
47
|
+
* @returns A ClientHandler with zero-arg .raw() and .toEffect()
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* import { Effect } from "effect"
|
|
51
|
+
* import { makeClientHandler } from "@gettersethya/mira-client"
|
|
52
|
+
*
|
|
53
|
+
* const handler = makeClientHandler<{ name: string }>(
|
|
54
|
+
* Effect.succeed({ name: "test" })
|
|
55
|
+
* )
|
|
56
|
+
* const result = await handler.raw() // { name: "test" }
|
|
57
|
+
*/
|
|
58
|
+
export declare function makeClientHandler<T>(effect: Effect.Effect<T, MiraError, HttpClient.HttpClient>): ClientHandler<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Construct a `ClientHandler<TData, TInput>` (mutation variant) from a function
|
|
61
|
+
* that accepts input and returns an Effect.
|
|
62
|
+
*
|
|
63
|
+
* The input is provided at call time (`.raw(input)` or `.toEffect(input)`).
|
|
64
|
+
* The Effect is provided `FetchHttpClient.layer` at runtime when `.raw()` is called.
|
|
65
|
+
*
|
|
66
|
+
* @param fn - A function that takes `TInput` and returns an Effect producing `TData`
|
|
67
|
+
* @returns A ClientHandler with input-arg .raw() and .toEffect()
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* import { Effect } from "effect"
|
|
71
|
+
* import { makeMutationHandler } from "@gettersethya/mira-client"
|
|
72
|
+
*
|
|
73
|
+
* const handler = makeMutationHandler<{ id: string }, { name: string }>(
|
|
74
|
+
* (input) => Effect.succeed({ id: "1", ...input })
|
|
75
|
+
* )
|
|
76
|
+
* const result = await handler.raw({ name: "test" }) // { id: "1", name: "test" }
|
|
77
|
+
*/
|
|
78
|
+
export declare function makeMutationHandler<TData, TInput>(fn: (input: TInput) => Effect.Effect<TData, MiraError, HttpClient.HttpClient>): ClientHandler<TData, TInput>;
|
|
79
|
+
/**
|
|
80
|
+
* The core HTTP execution function used internally by all client handlers.
|
|
81
|
+
* Takes an `HttpClientRequest`, sends it to the server, and returns the
|
|
82
|
+
* deserialized response body.
|
|
83
|
+
*
|
|
84
|
+
* Handles authentication token injection, base URL prefixing, and error mapping
|
|
85
|
+
* (HTTP 4xx/5xx responses become `MiraError` in the Effect error channel).
|
|
86
|
+
*
|
|
87
|
+
* @typeParam T - The expected response body type
|
|
88
|
+
* @param req - The HTTP request to execute (constructed via `HttpClientRequest.*`)
|
|
89
|
+
* @returns Effect that resolves to the parsed response body, or fails with MiraError
|
|
90
|
+
*/
|
|
91
|
+
export type ExecuteFn = <T>(req: HttpClientRequest.HttpClientRequest) => Effect.Effect<T, MiraError, HttpClient.HttpClient>;
|
|
92
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/client/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAErE,OAAO,EAAS,MAAM,EAAgB,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,MAAM,SAAS,IAAI,GACjE;IACE,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,CAAA;IACrB,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,CAAA;CACnE,GACD;IACE,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,CAAA;CAChF,CAAA;AAEL;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,GACzD,aAAa,CAAC,CAAC,CAAC,CAWlB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAC/C,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,GAC5E,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAY9B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,EACxB,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,KACrC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FetchHttpClient } from "@effect/platform";
|
|
2
|
+
import { Cause, Effect, Exit, Option } from "effect";
|
|
3
|
+
/**
|
|
4
|
+
* Construct a `ClientHandler<T>` (query variant, TInput = void) from an Effect.
|
|
5
|
+
*
|
|
6
|
+
* The Effect is provided `FetchHttpClient.layer` at runtime when `.raw()` is called.
|
|
7
|
+
* The `.toEffect()` method returns the Effect without providing the layer, allowing
|
|
8
|
+
* the caller to supply their own `HttpClient` implementation (e.g., for testing).
|
|
9
|
+
*
|
|
10
|
+
* @param effect - The Effect to wrap. Must produce `T` on success or `MiraError` on failure
|
|
11
|
+
* @returns A ClientHandler with zero-arg .raw() and .toEffect()
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { Effect } from "effect"
|
|
15
|
+
* import { makeClientHandler } from "@gettersethya/mira-client"
|
|
16
|
+
*
|
|
17
|
+
* const handler = makeClientHandler<{ name: string }>(
|
|
18
|
+
* Effect.succeed({ name: "test" })
|
|
19
|
+
* )
|
|
20
|
+
* const result = await handler.raw() // { name: "test" }
|
|
21
|
+
*/
|
|
22
|
+
export function makeClientHandler(effect) {
|
|
23
|
+
return {
|
|
24
|
+
raw: () => Effect.runPromiseExit(effect.pipe(Effect.provide(FetchHttpClient.layer))).then((exit) => {
|
|
25
|
+
if (Exit.isSuccess(exit))
|
|
26
|
+
return exit.value;
|
|
27
|
+
return Promise.reject(Option.getOrElse(Cause.failureOption(exit.cause), () => Cause.squash(exit.cause)));
|
|
28
|
+
}),
|
|
29
|
+
toEffect: () => effect,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Construct a `ClientHandler<TData, TInput>` (mutation variant) from a function
|
|
34
|
+
* that accepts input and returns an Effect.
|
|
35
|
+
*
|
|
36
|
+
* The input is provided at call time (`.raw(input)` or `.toEffect(input)`).
|
|
37
|
+
* The Effect is provided `FetchHttpClient.layer` at runtime when `.raw()` is called.
|
|
38
|
+
*
|
|
39
|
+
* @param fn - A function that takes `TInput` and returns an Effect producing `TData`
|
|
40
|
+
* @returns A ClientHandler with input-arg .raw() and .toEffect()
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* import { Effect } from "effect"
|
|
44
|
+
* import { makeMutationHandler } from "@gettersethya/mira-client"
|
|
45
|
+
*
|
|
46
|
+
* const handler = makeMutationHandler<{ id: string }, { name: string }>(
|
|
47
|
+
* (input) => Effect.succeed({ id: "1", ...input })
|
|
48
|
+
* )
|
|
49
|
+
* const result = await handler.raw({ name: "test" }) // { id: "1", name: "test" }
|
|
50
|
+
*/
|
|
51
|
+
export function makeMutationHandler(fn) {
|
|
52
|
+
const handler = {
|
|
53
|
+
raw: (input) => Effect.runPromiseExit(fn(input).pipe(Effect.provide(FetchHttpClient.layer))).then((exit) => {
|
|
54
|
+
if (Exit.isSuccess(exit))
|
|
55
|
+
return exit.value;
|
|
56
|
+
return Promise.reject(Option.getOrElse(Cause.failureOption(exit.cause), () => Cause.squash(exit.cause)));
|
|
57
|
+
}),
|
|
58
|
+
toEffect: (input) => fn(input),
|
|
59
|
+
};
|
|
60
|
+
return handler;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/client/handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAyCpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA0D;IAE1D,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CACR,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACtF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAA;YAC3C,OAAO,OAAO,CAAC,MAAM,CACnB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAClF,CAAA;QACH,CAAC,CAAC;QACJ,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;KACvB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CACjC,EAA6E;IAE7E,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,CAAC,KAAa,EAAE,EAAE,CACrB,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACzF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAA;YAC3C,OAAO,OAAO,CAAC,MAAM,CACnB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAClF,CAAA;QACH,CAAC,CAAC;QACJ,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;KACvC,CAAA;IACD,OAAO,OAAuC,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { createMiraClient } from "./factory.js";
|
|
2
|
+
export { makeClientHandler, makeMutationHandler } from "./handler.js";
|
|
3
|
+
export type { ClientHandler, ExecuteFn } from "./handler.js";
|
|
4
|
+
export { MiraError } from "./errors.js";
|
|
5
|
+
export type { InferRecord, InferCreateInput, InferMutationInput, WithExpand, CollectionFileFields, RelationKeys, FileKeys } from "./types.js";
|
|
6
|
+
export type { BrowserAuth, ServerAuth } from "./auth.js";
|
|
7
|
+
export type { PublicFileFieldClient, ProtectedFileFieldClient } from "./file.js";
|
|
8
|
+
export { buildFileUrl } from "./file.js";
|
|
9
|
+
export { makeCollectionClient } from "./collection.js";
|
|
10
|
+
export type { CollectionClient } from "./collection.js";
|
|
11
|
+
export { makeTelemetryClient } from "./telemetry.js";
|
|
12
|
+
export type { TelemetryClient } from "./telemetry.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACrE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC7I,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACxD,YAAY,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createMiraClient } from "./factory.js";
|
|
2
|
+
export { makeClientHandler, makeMutationHandler } from "./handler.js";
|
|
3
|
+
export { MiraError } from "./errors.js";
|
|
4
|
+
export { buildFileUrl } from "./file.js";
|
|
5
|
+
export { makeCollectionClient } from "./collection.js";
|
|
6
|
+
export { makeTelemetryClient } from "./telemetry.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAIvC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { FilterNode } from "@gettersethya/mira-collection";
|
|
2
|
+
import type { ClientHandler, ExecuteFn } from "./handler.js";
|
|
3
|
+
type LogEntry = {
|
|
4
|
+
id: number;
|
|
5
|
+
level: string;
|
|
6
|
+
message: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
traceId: string | null;
|
|
9
|
+
spanId: string | null;
|
|
10
|
+
};
|
|
11
|
+
type SpanEntry = {
|
|
12
|
+
id: number;
|
|
13
|
+
name: string;
|
|
14
|
+
traceId: string;
|
|
15
|
+
spanId: string;
|
|
16
|
+
parentSpanId: string | null;
|
|
17
|
+
kind: string;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
status: "ok" | "error";
|
|
20
|
+
error: string | null;
|
|
21
|
+
attributes: Record<string, string | number | boolean>;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
};
|
|
24
|
+
type LogsResponse = {
|
|
25
|
+
logs: Array<LogEntry>;
|
|
26
|
+
total: number;
|
|
27
|
+
limit: number;
|
|
28
|
+
offset: number;
|
|
29
|
+
};
|
|
30
|
+
type SpansResponse = {
|
|
31
|
+
spans: Array<SpanEntry>;
|
|
32
|
+
total: number;
|
|
33
|
+
limit: number;
|
|
34
|
+
offset: number;
|
|
35
|
+
};
|
|
36
|
+
export type TelemetryClient = {
|
|
37
|
+
getLogs(opts?: {
|
|
38
|
+
limit?: number;
|
|
39
|
+
offset?: number;
|
|
40
|
+
filter?: FilterNode;
|
|
41
|
+
}): ClientHandler<LogsResponse>;
|
|
42
|
+
getSpans(opts?: {
|
|
43
|
+
limit?: number;
|
|
44
|
+
offset?: number;
|
|
45
|
+
traceId?: string;
|
|
46
|
+
}): ClientHandler<SpansResponse>;
|
|
47
|
+
};
|
|
48
|
+
export declare function makeTelemetryClient(execute: ExecuteFn): TelemetryClient;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../../src/client/telemetry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG5D,KAAK,QAAQ,GAAG;IACd,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB,CAAA;AAED,KAAK,SAAS,GAAG;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,GAAG,OAAO,CAAA;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;IACrD,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,IAAI,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,UAAU,CAAA;KACpB,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;IAE/B,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,GAAG,aAAa,CAAC,aAAa,CAAC,CAAA;CACjC,CAAA;AAWD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,GAAG,eAAe,CAoBvE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpClientRequest as HCR } from "@effect/platform";
|
|
2
|
+
import { makeClientHandler } from "./handler.js";
|
|
3
|
+
function buildQueryParams(params) {
|
|
4
|
+
const sp = new URLSearchParams();
|
|
5
|
+
for (const [k, v] of Object.entries(params)) {
|
|
6
|
+
if (v !== undefined)
|
|
7
|
+
sp.set(k, v);
|
|
8
|
+
}
|
|
9
|
+
const qs = sp.toString();
|
|
10
|
+
return qs ? `?${qs}` : "";
|
|
11
|
+
}
|
|
12
|
+
export function makeTelemetryClient(execute) {
|
|
13
|
+
return {
|
|
14
|
+
getLogs: (opts) => {
|
|
15
|
+
const qs = buildQueryParams({
|
|
16
|
+
limit: opts?.limit !== undefined ? String(opts.limit) : undefined,
|
|
17
|
+
offset: opts?.offset !== undefined ? String(opts.offset) : undefined,
|
|
18
|
+
filter: opts?.filter !== undefined ? JSON.stringify(opts.filter) : undefined,
|
|
19
|
+
});
|
|
20
|
+
return makeClientHandler(execute(HCR.get(`/api/_telemetry/logs${qs}`)));
|
|
21
|
+
},
|
|
22
|
+
getSpans: (opts) => {
|
|
23
|
+
const qs = buildQueryParams({
|
|
24
|
+
limit: opts?.limit !== undefined ? String(opts.limit) : undefined,
|
|
25
|
+
offset: opts?.offset !== undefined ? String(opts.offset) : undefined,
|
|
26
|
+
traceId: opts?.traceId,
|
|
27
|
+
});
|
|
28
|
+
return makeClientHandler(execute(HCR.get(`/api/_telemetry/spans${qs}`)));
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../src/client/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAqDhD,SAAS,gBAAgB,CAAC,MAA0C;IAClE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,KAAK,SAAS;YAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACnC,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAA;IACxB,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAkB;IACpD,OAAO;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,EAAE,GAAG,gBAAgB,CAAC;gBAC1B,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBACjE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;gBACpE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;aAC7E,CAAC,CAAA;YACF,OAAO,iBAAiB,CAAC,OAAO,CAAe,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QACvF,CAAC;QAED,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,MAAM,EAAE,GAAG,gBAAgB,CAAC;gBAC1B,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBACjE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;gBACpE,OAAO,EAAE,IAAI,EAAE,OAAO;aACvB,CAAC,CAAA;YACF,OAAO,iBAAiB,CAAC,OAAO,CAAgB,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QACzF,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { AnyCollectionDef, FieldDef, FieldsMap, InferFieldValue } from "@gettersethya/mira-collection";
|
|
2
|
+
import type { ProtectedFileFieldClient, PublicFileFieldClient } from "./file.js";
|
|
3
|
+
/** Resolves the mutation value type for a field: File | Blob for file fields, InferFieldValue for everything else. */
|
|
4
|
+
type MutationFieldValue<F extends FieldDef> = F["kind"] extends "file" ? File | Blob : InferFieldValue<F>;
|
|
5
|
+
/**
|
|
6
|
+
* The input type for creating/updating records when file uploads are involved.
|
|
7
|
+
* Same structure as `InferCreateInput` but file fields accept `File | Blob`
|
|
8
|
+
* instead of the server-returned URL string.
|
|
9
|
+
*
|
|
10
|
+
* When the input contains any `Blob` values, the client SDK automatically
|
|
11
|
+
* dispatches a `multipart/form-data` request instead of JSON.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // For a collection with { avatar: Field.file() }
|
|
15
|
+
* // InferMutationInput resolves avatar to: File | Blob
|
|
16
|
+
*
|
|
17
|
+
* @see InferCreateInput — create input without file upload support
|
|
18
|
+
* @see InferRecord — the corresponding output type
|
|
19
|
+
*/
|
|
20
|
+
export type InferMutationInput<F extends FieldsMap> = {
|
|
21
|
+
[K in keyof F as F[K]["kind"] extends "seqId" ? never : F[K]["viewOnly"] extends true ? never : F[K]["required"] extends false ? K : never]?: MutationFieldValue<F[K]> | null;
|
|
22
|
+
} & {
|
|
23
|
+
[K in keyof F as F[K]["kind"] extends "seqId" ? never : F[K]["viewOnly"] extends true ? never : F[K]["required"] extends false ? never : K]: MutationFieldValue<F[K]>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The full record type returned from the server for a collection.
|
|
27
|
+
* Includes the system-managed `id`, `created`, and `updated` fields plus all
|
|
28
|
+
* user-defined fields with their correct TypeScript types.
|
|
29
|
+
*
|
|
30
|
+
* Optional fields (`required: false`) are typed as `T | null`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* interface Post { title: Field.text(); body: Field.text({ required: false }) }
|
|
34
|
+
* // InferRecord<Post> resolves to:
|
|
35
|
+
* // { id: string; created: string; updated: string } & {
|
|
36
|
+
* // title: string;
|
|
37
|
+
* // body: string | null;
|
|
38
|
+
* // }
|
|
39
|
+
*
|
|
40
|
+
* @see InferCreateInput — input type for creating records
|
|
41
|
+
* @see InferMutationInput — mutation input type (file fields use File | Blob)
|
|
42
|
+
*/
|
|
43
|
+
export type InferRecord<F extends FieldsMap> = {
|
|
44
|
+
id: string;
|
|
45
|
+
created: string;
|
|
46
|
+
updated: string;
|
|
47
|
+
} & {
|
|
48
|
+
[K in keyof F as F[K]["kind"] extends "seqId" ? never : K]: F[K]["required"] extends false ? InferFieldValue<F[K]> | null : InferFieldValue<F[K]>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The input type for creating a new record.
|
|
52
|
+
* Excludes system-managed fields (`seqId`) and view-only fields.
|
|
53
|
+
* Optional fields (`required: false`) are typed as `T | null` and are
|
|
54
|
+
* themselves optional (`K?`)
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // InferCreateInput<Post> resolves to:
|
|
58
|
+
* // { title: string; body?: string | null }
|
|
59
|
+
*
|
|
60
|
+
* @see InferRecord — the corresponding output type
|
|
61
|
+
* @see InferMutationInput — mutation variant that uses File | Blob for file fields
|
|
62
|
+
*/
|
|
63
|
+
export type InferCreateInput<F extends FieldsMap> = {
|
|
64
|
+
[K in keyof F as F[K]["kind"] extends "seqId" ? never : F[K]["viewOnly"] extends true ? never : F[K]["required"] extends false ? K : never]?: InferFieldValue<F[K]> | null;
|
|
65
|
+
} & {
|
|
66
|
+
[K in keyof F as F[K]["kind"] extends "seqId" ? never : F[K]["viewOnly"] extends true ? never : F[K]["required"] extends false ? never : K]: InferFieldValue<F[K]>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Extracts the field names of type `relation` from a FieldsMap.
|
|
70
|
+
* Used to constrain the `expand` option in collection queries.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // For { author: Field.relation(Users), title: Field.text() }
|
|
74
|
+
* // RelationKeys resolves to: "author"
|
|
75
|
+
*
|
|
76
|
+
* @see WithExpand — uses RelationKeys to type the expand parameter
|
|
77
|
+
*/
|
|
78
|
+
export type RelationKeys<F extends FieldsMap> = {
|
|
79
|
+
[K in keyof F]: F[K]["kind"] extends "relation" ? K : never;
|
|
80
|
+
}[keyof F] & string;
|
|
81
|
+
/**
|
|
82
|
+
* Extracts the field names of type `file` from a FieldsMap.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* // For { avatar: Field.file(), name: Field.text() }
|
|
86
|
+
* // FileKeys resolves to: "avatar"
|
|
87
|
+
*
|
|
88
|
+
* @see CollectionFileFields — maps file fields to their client interfaces
|
|
89
|
+
*/
|
|
90
|
+
export type FileKeys<F extends FieldsMap> = {
|
|
91
|
+
[K in keyof F]: F[K]["kind"] extends "file" ? K : never;
|
|
92
|
+
}[keyof F] & string;
|
|
93
|
+
/**
|
|
94
|
+
* Augments `InferRecord<F>` with an `expand` property containing the resolved
|
|
95
|
+
* related records for the requested relation field names.
|
|
96
|
+
*
|
|
97
|
+
* When `E` is an empty tuple (no expand requested), the result is just
|
|
98
|
+
* `InferRecord<F>` without the `expand` property.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* // WithExpand<PostFields, ["author"]> resolves to:
|
|
102
|
+
* // InferRecord<Post> & {
|
|
103
|
+
* // expand: { author: InferRecord<UserFields> }
|
|
104
|
+
* // }
|
|
105
|
+
*
|
|
106
|
+
* @see InferRecord — the base record type
|
|
107
|
+
* @see RelationKeys — used to constrain E to relation fields
|
|
108
|
+
*/
|
|
109
|
+
export type WithExpand<F extends FieldsMap, E extends ReadonlyArray<string>> = InferRecord<F> & ([
|
|
110
|
+
E
|
|
111
|
+
] extends [[]] ? {} : {
|
|
112
|
+
expand: {
|
|
113
|
+
[K in E[number] & RelationKeys<F>]: F[K] extends {
|
|
114
|
+
_target: infer Target extends AnyCollectionDef;
|
|
115
|
+
} ? InferRecord<Target["fields"]> : Record<string, unknown>;
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* Maps file-type fields in a FieldsMap to their corresponding client interfaces.
|
|
120
|
+
* Protected file fields get `ProtectedFileFieldClient`; public file fields get
|
|
121
|
+
* `PublicFileFieldClient`.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* // For { avatar: Field.file({ protected: true }), cover: Field.file() }
|
|
125
|
+
* // CollectionFileFields resolves to:
|
|
126
|
+
* // { avatar: ProtectedFileFieldClient; cover: PublicFileFieldClient }
|
|
127
|
+
*
|
|
128
|
+
* @see PublicFileFieldClient — synchronous URL builder
|
|
129
|
+
* @see ProtectedFileFieldClient — async URL builder with token acquisition
|
|
130
|
+
*/
|
|
131
|
+
export type CollectionFileFields<F extends FieldsMap> = {
|
|
132
|
+
[K in keyof F as F[K]["kind"] extends "file" ? K : never]: F[K] extends {
|
|
133
|
+
protected: true;
|
|
134
|
+
} ? ProtectedFileFieldClient : PublicFileFieldClient;
|
|
135
|
+
};
|
|
136
|
+
export {};
|
|
137
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { RuleBuilder } from "../rule/builder.js";
|
|
2
|
+
import type { RuleMap } from "../rule/types.js";
|
|
3
|
+
import type { OperandNode } from "../rule/types.js";
|
|
4
|
+
import type { IndexBuilder, IndexEntry } from "./index-builder.js";
|
|
5
|
+
import type { CollectionSchema, FieldDef, FieldsMap } from "./types.js";
|
|
6
|
+
type AuthSystemField = "id" | "email" | "password" | "emailVerified" | "created" | "updated" | "seqId";
|
|
7
|
+
type AuthRuleField = "id" | "email" | "emailVerified" | "created" | "updated" | "seqId";
|
|
8
|
+
type AuthSystemFieldDefs = {
|
|
9
|
+
id: FieldDef & {
|
|
10
|
+
kind: "text";
|
|
11
|
+
};
|
|
12
|
+
email: FieldDef & {
|
|
13
|
+
kind: "email";
|
|
14
|
+
};
|
|
15
|
+
emailVerified: FieldDef & {
|
|
16
|
+
kind: "boolean";
|
|
17
|
+
};
|
|
18
|
+
created: FieldDef & {
|
|
19
|
+
kind: "date";
|
|
20
|
+
};
|
|
21
|
+
updated: FieldDef & {
|
|
22
|
+
kind: "date";
|
|
23
|
+
};
|
|
24
|
+
seqId: FieldDef & {
|
|
25
|
+
kind: "seqId";
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
/** Rule builder for auth collections — extends RuleBuilder with `selfId()`. */
|
|
29
|
+
type AuthRuleBuilder<F extends FieldsMap> = RuleBuilder<F> & {
|
|
30
|
+
/** authId operand for this collection. Use instead of `Rule.authId(ThisCollection)` to avoid circular references. */
|
|
31
|
+
selfId(): OperandNode<any, string>;
|
|
32
|
+
};
|
|
33
|
+
type IndexCb<F extends FieldsMap> = (I: IndexBuilder<(keyof F & string) | AuthRuleField>) => Array<IndexEntry<(keyof F & string) | AuthRuleField>>;
|
|
34
|
+
type RuleCb<F extends FieldsMap> = (R: AuthRuleBuilder<F & AuthSystemFieldDefs>) => RuleMap;
|
|
35
|
+
/**
|
|
36
|
+
* Builder returned by `AuthCollection.define()`.
|
|
37
|
+
* Immediately satisfies `AnyCollectionDef` — no terminal `.build()` needed.
|
|
38
|
+
* Chain `.indexes()` and/or `.rules()` to add optional concerns.
|
|
39
|
+
* Each chained method returns a new builder; the original is unchanged.
|
|
40
|
+
*/
|
|
41
|
+
export type AuthCollectionBuilder<F extends FieldsMap> = {
|
|
42
|
+
name: string;
|
|
43
|
+
fields: F;
|
|
44
|
+
schema: CollectionSchema & {
|
|
45
|
+
"x-collection-kind": "auth";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Add collection-level indexes (in addition to the system email unique index
|
|
49
|
+
* and any field-level `unique`/`indexed` flags).
|
|
50
|
+
* Pass a callback to get a typed index builder with auto-completion over field names.
|
|
51
|
+
*/
|
|
52
|
+
indexes(cb: IndexCb<F>): AuthCollectionBuilder<F>;
|
|
53
|
+
/**
|
|
54
|
+
* Add per-action access rules. No rule means deny all.
|
|
55
|
+
* The rule builder includes `.selfId()` as a shorthand for the authenticated user's id
|
|
56
|
+
* on this collection — use it instead of `Rule.authId(ThisCollection)` to avoid circular references.
|
|
57
|
+
*/
|
|
58
|
+
rules(cb: RuleCb<F>): AuthCollectionBuilder<F>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Defines an auth collection for user authentication.
|
|
62
|
+
* Includes system-managed fields: `id`, `email`, `password`, `emailVerified`, `created`, `updated`, `seqId`.
|
|
63
|
+
* Only `extraFields` are user-defined; system field names are forbidden in `extraFields`.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const Users = AuthCollection.define("users", {
|
|
67
|
+
* name: Field.text(),
|
|
68
|
+
* avatar: Field.file({ maxSize: Bytes.fromMB(2) })
|
|
69
|
+
* })
|
|
70
|
+
* .rules((R) => ({
|
|
71
|
+
* list: R.field("id").eq(R.selfId()),
|
|
72
|
+
* create: R.public()
|
|
73
|
+
* }))
|
|
74
|
+
*/
|
|
75
|
+
export declare const AuthCollection: {
|
|
76
|
+
define<F extends FieldsMap & { [K in keyof F & AuthSystemField]?: never; }>(name: string, extraFields: F): AuthCollectionBuilder<F>;
|
|
77
|
+
};
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/collection/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAgC,MAAM,YAAY,CAAA;AAErG,KAAK,eAAe,GAAG,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AACtG,KAAK,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAEvF,KAAK,mBAAmB,GAAG;IACzB,EAAE,EAAa,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,KAAK,EAAU,QAAQ,GAAG;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;IAC3C,aAAa,EAAE,QAAQ,GAAG;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAA;IAC7C,OAAO,EAAQ,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAQ,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,KAAK,EAAU,QAAQ,GAAG;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAC5C,CAAA;AAED,+EAA+E;AAC/E,KAAK,eAAe,CAAC,CAAC,SAAS,SAAS,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IAC3D,qHAAqH;IACrH,MAAM,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;CACnC,CAAA;AAED,KAAK,OAAO,CAAC,CAAC,SAAS,SAAS,IAAI,CAClC,CAAC,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa,CAAC,KAChD,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAA;AAE1D,KAAK,MAAM,CAAC,CAAC,SAAS,SAAS,IAAI,CACjC,CAAC,EAAE,eAAe,CAAC,CAAC,GAAG,mBAAmB,CAAC,KACxC,OAAO,CAAA;AAEZ;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,SAAS,IAAI;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,gBAAgB,GAAG;QAAE,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1D;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAA;IACjD;;;;OAIG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAA;CAC/C,CAAA;AAqCD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc;WAClB,CAAC,SAAS,SAAS,GAAG,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAE,KAAK,GAAE,QACjE,MAAM,eACC,CAAC,GACb,qBAAqB,CAAC,CAAC,CAAC;CAG5B,CAAA"}
|