@tailorkit/app 0.1.0-beta.42 → 0.1.0-beta.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5B5RGL5W.js → chunk-MYK3WL3S.js} +38 -20
- package/dist/{chunk-YX3JURMG.js → chunk-QDZXHVTU.js} +44 -29
- package/dist/{chunk-Q6X2VQKX.js → chunk-YFKW5FBP.js} +6 -3
- package/dist/client/reference.d.ts +3 -3
- package/dist/client/session.d.ts +2 -23
- package/dist/client-connection.js +1 -1
- package/dist/client.js +2 -2
- package/dist/index.js +3 -3
- package/dist/protocol.d.ts +23 -23
- package/dist/protocol.js +15 -6
- package/dist/server/builder.d.ts +14 -13
- package/dist/server/functions.d.ts +29 -22
- package/dist/server/instances.d.ts +2 -2
- package/dist/server.js +1 -1
- package/dist/validation.d.ts +5 -0
- package/dist/views.d.ts +7 -7
- package/package.json +5 -3
|
@@ -9,27 +9,45 @@ import { RPCLink as FetchLink } from "@orpc/client/fetch";
|
|
|
9
9
|
import { RPCLink } from "@orpc/client/websocket";
|
|
10
10
|
|
|
11
11
|
// src/client/session.ts
|
|
12
|
-
import
|
|
12
|
+
import * as v2 from "valibot";
|
|
13
|
+
|
|
14
|
+
// src/validation.ts
|
|
15
|
+
import * as v from "valibot";
|
|
16
|
+
var jsonValueSchema = v.lazy(
|
|
17
|
+
() => v.union([
|
|
18
|
+
v.string(),
|
|
19
|
+
v.pipe(v.number(), v.finite()),
|
|
20
|
+
v.boolean(),
|
|
21
|
+
v.null(),
|
|
22
|
+
v.array(jsonValueSchema),
|
|
23
|
+
v.record(v.string(), jsonValueSchema)
|
|
24
|
+
])
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// src/client/session.ts
|
|
13
28
|
var isObjectValue = (value) => typeof value === "object" && value !== null;
|
|
14
|
-
var identitySchema =
|
|
15
|
-
appId:
|
|
16
|
-
deploymentId:
|
|
17
|
-
expiresAt:
|
|
18
|
-
installationId:
|
|
19
|
-
projectId:
|
|
20
|
-
scope:
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
var identitySchema = v2.object({
|
|
30
|
+
appId: v2.string(),
|
|
31
|
+
deploymentId: v2.string(),
|
|
32
|
+
expiresAt: v2.pipe(v2.number(), v2.finite()),
|
|
33
|
+
installationId: v2.string(),
|
|
34
|
+
projectId: v2.string(),
|
|
35
|
+
scope: v2.object({
|
|
36
|
+
name: v2.string(),
|
|
37
|
+
value: v2.record(v2.string(), jsonValueSchema)
|
|
38
|
+
}),
|
|
39
|
+
subjectId: v2.optional(v2.string()),
|
|
40
|
+
toolUrl: v2.string()
|
|
23
41
|
});
|
|
24
|
-
var sessionSchema =
|
|
25
|
-
expiresAt:
|
|
26
|
-
identity:
|
|
27
|
-
subjectId:
|
|
28
|
-
token:
|
|
29
|
-
toolUrl:
|
|
30
|
-
url:
|
|
42
|
+
var sessionSchema = v2.object({
|
|
43
|
+
expiresAt: v2.pipe(v2.number(), v2.finite()),
|
|
44
|
+
identity: v2.optional(identitySchema),
|
|
45
|
+
subjectId: v2.optional(v2.string()),
|
|
46
|
+
token: v2.string(),
|
|
47
|
+
toolUrl: v2.optional(v2.string()),
|
|
48
|
+
url: v2.string()
|
|
31
49
|
});
|
|
32
|
-
var parseSession = (value) =>
|
|
50
|
+
var parseSession = (value) => v2.parse(sessionSchema, value);
|
|
33
51
|
var APP_SESSION_RENEWAL_MS = 6e4;
|
|
34
52
|
var freezeIdentity = (value) => {
|
|
35
53
|
if (isObjectValue(value) && !Object.isFrozen(value)) {
|
|
@@ -80,11 +98,11 @@ var createSessionProvider = (options) => {
|
|
|
80
98
|
"Unable to authorize the app backend"
|
|
81
99
|
);
|
|
82
100
|
}
|
|
83
|
-
const parsed =
|
|
101
|
+
const parsed = v2.safeParse(sessionSchema, await response.json());
|
|
84
102
|
if (!parsed.success) {
|
|
85
103
|
throw new AppError("UNAVAILABLE", "Invalid app session");
|
|
86
104
|
}
|
|
87
|
-
cached = parsed.
|
|
105
|
+
cached = parsed.output;
|
|
88
106
|
if (cached.identity) {
|
|
89
107
|
cached.identity = freezeIdentity(cached.identity);
|
|
90
108
|
}
|
|
@@ -23,7 +23,7 @@ var defineServer = (functions) => {
|
|
|
23
23
|
var defineDatabase = (definition) => Object.freeze({ relations: definition.relations });
|
|
24
24
|
|
|
25
25
|
// src/server/builder.ts
|
|
26
|
-
import
|
|
26
|
+
import * as v from "valibot";
|
|
27
27
|
var FunctionBuilder = class _FunctionBuilder {
|
|
28
28
|
kind;
|
|
29
29
|
args;
|
|
@@ -103,17 +103,30 @@ var FunctionBuilder = class _FunctionBuilder {
|
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
105
|
var fn = Object.freeze({
|
|
106
|
-
action: new FunctionBuilder("action",
|
|
107
|
-
mutation: new FunctionBuilder("mutation",
|
|
108
|
-
query: new FunctionBuilder("query",
|
|
106
|
+
action: new FunctionBuilder("action", v.undefined(), void 0, {}),
|
|
107
|
+
mutation: new FunctionBuilder("mutation", v.undefined(), void 0, {}),
|
|
108
|
+
query: new FunctionBuilder("query", v.undefined(), void 0, {})
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
// src/server/instances.ts
|
|
112
|
-
import
|
|
113
|
-
var addressSchema =
|
|
114
|
-
path:
|
|
115
|
-
slot:
|
|
112
|
+
import * as v2 from "valibot";
|
|
113
|
+
var addressSchema = v2.object({
|
|
114
|
+
path: v2.pipe(v2.string(), v2.startsWith("/"), v2.maxLength(1024)),
|
|
115
|
+
slot: v2.pipe(v2.string(), v2.minLength(1), v2.maxLength(255))
|
|
116
116
|
});
|
|
117
|
+
var instanceResults = v2.pipe(
|
|
118
|
+
v2.array(
|
|
119
|
+
v2.object({
|
|
120
|
+
data: v2.unknown(),
|
|
121
|
+
key: v2.pipe(v2.string(), v2.minLength(1)),
|
|
122
|
+
metadata: v2.record(v2.string(), v2.unknown())
|
|
123
|
+
})
|
|
124
|
+
),
|
|
125
|
+
v2.check(
|
|
126
|
+
(items) => new Set(items.map((item) => item.key)).size === items.length,
|
|
127
|
+
"Instance keys must be unique"
|
|
128
|
+
)
|
|
129
|
+
);
|
|
117
130
|
var registeredQueries = (functions) => {
|
|
118
131
|
const queries = {};
|
|
119
132
|
for (const [name, fn2] of Object.entries(functions)) {
|
|
@@ -139,7 +152,7 @@ var withInstanceResolvers = (app, resolvers) => {
|
|
|
139
152
|
const queries = registeredQueries(app.functions);
|
|
140
153
|
const registry = /* @__PURE__ */ new Map();
|
|
141
154
|
for (const resolver of resolvers) {
|
|
142
|
-
|
|
155
|
+
v2.parse(addressSchema, resolver);
|
|
143
156
|
let paths = registry.get(resolver.slot);
|
|
144
157
|
if (!paths) {
|
|
145
158
|
paths = /* @__PURE__ */ new Map();
|
|
@@ -150,45 +163,47 @@ var withInstanceResolvers = (app, resolvers) => {
|
|
|
150
163
|
`Duplicate instance resolver for slot "${resolver.slot}" and path "${resolver.path}".`
|
|
151
164
|
);
|
|
152
165
|
}
|
|
153
|
-
|
|
154
|
-
z2.object({
|
|
155
|
-
data: resolver.dataSchema,
|
|
156
|
-
key: z2.string().min(1),
|
|
157
|
-
metadata: z2.record(z2.string(), z2.unknown())
|
|
158
|
-
})
|
|
159
|
-
).refine(
|
|
160
|
-
(items) => new Set(items.map((item) => item.key)).size === items.length,
|
|
161
|
-
{
|
|
162
|
-
message: "Instance keys must be unique"
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
paths.set(resolver.path, { resolver, result });
|
|
166
|
+
paths.set(resolver.path, resolver);
|
|
166
167
|
}
|
|
167
168
|
const instances = {
|
|
168
169
|
resolve: action({
|
|
169
|
-
args:
|
|
170
|
-
|
|
170
|
+
args: v2.object({
|
|
171
|
+
...addressSchema.entries,
|
|
172
|
+
context: v2.record(v2.string(), v2.unknown())
|
|
171
173
|
}),
|
|
172
174
|
functions: queries,
|
|
173
175
|
handler: async ({ args, identity, signal, queries: queriesValue }) => {
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
176
|
+
const resolver = registry.get(args.slot)?.get(args.path);
|
|
177
|
+
if (!resolver) {
|
|
176
178
|
throw new AppError("NOT_FOUND", "Instance resolver not found");
|
|
177
179
|
}
|
|
178
|
-
const value = await
|
|
180
|
+
const value = await resolver.resolve({
|
|
179
181
|
context: args.context,
|
|
180
182
|
identity,
|
|
181
183
|
queries: queriesValue,
|
|
182
184
|
signal
|
|
183
185
|
});
|
|
184
|
-
const result =
|
|
186
|
+
const result = v2.safeParse(instanceResults, value);
|
|
185
187
|
if (!result.success) {
|
|
186
188
|
throw new AppError(
|
|
187
189
|
"INTERNAL_SERVER_ERROR",
|
|
188
190
|
"Invalid function result"
|
|
189
191
|
);
|
|
190
192
|
}
|
|
191
|
-
return
|
|
193
|
+
return await Promise.all(
|
|
194
|
+
result.output.map(async (item) => {
|
|
195
|
+
const parsed = await resolver.dataSchema["~standard"].validate(
|
|
196
|
+
item.data
|
|
197
|
+
);
|
|
198
|
+
if (parsed.issues) {
|
|
199
|
+
throw new AppError(
|
|
200
|
+
"INTERNAL_SERVER_ERROR",
|
|
201
|
+
"Invalid function result"
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
return { ...item, data: parsed.value };
|
|
205
|
+
})
|
|
206
|
+
);
|
|
192
207
|
}
|
|
193
208
|
})
|
|
194
209
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createClient,
|
|
3
3
|
reference
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MYK3WL3S.js";
|
|
5
5
|
import {
|
|
6
6
|
AppError,
|
|
7
7
|
appError
|
|
@@ -566,7 +566,7 @@ var createFileClient = (options) => {
|
|
|
566
566
|
};
|
|
567
567
|
|
|
568
568
|
// src/client/tools.ts
|
|
569
|
-
import
|
|
569
|
+
import * as v from "valibot";
|
|
570
570
|
var executeServerTool = async (session, path, input, request = globalThis.fetch, signal) => {
|
|
571
571
|
const response = await request(session.url, {
|
|
572
572
|
body: JSON.stringify({ input, path, requestId: crypto.randomUUID() }),
|
|
@@ -593,7 +593,10 @@ var executeServerTool = async (session, path, input, request = globalThis.fetch,
|
|
|
593
593
|
"Tool call failed"
|
|
594
594
|
);
|
|
595
595
|
}
|
|
596
|
-
return
|
|
596
|
+
return v.parse(
|
|
597
|
+
v.object({ output: v.optional(v.unknown()) }),
|
|
598
|
+
await response.json()
|
|
599
|
+
).output;
|
|
597
600
|
};
|
|
598
601
|
var callTool = async (kind, path, input) => {
|
|
599
602
|
const bridge = globalThis.__tailorkitTools;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
import type { FunctionResult, Functions } from "#server/functions";
|
|
3
3
|
export interface Reference<K extends "query" | "mutation" | "action", I, O> {
|
|
4
4
|
readonly name: string;
|
|
@@ -12,9 +12,9 @@ export declare const reference: <K extends "query" | "mutation" | "action", I, O
|
|
|
12
12
|
export type References<F> = {
|
|
13
13
|
readonly [N in keyof F]: F[N] extends {
|
|
14
14
|
kind: infer K extends "query" | "mutation" | "action";
|
|
15
|
-
args: infer A extends
|
|
15
|
+
args: infer A extends StandardSchemaV1;
|
|
16
16
|
handler: (...args: never[]) => infer _Output;
|
|
17
|
-
} ? Reference<K,
|
|
17
|
+
} ? Reference<K, StandardSchemaV1.InferInput<A>, FunctionResult<F[N]>> : F[N] extends Functions ? References<F[N]> : never;
|
|
18
18
|
};
|
|
19
19
|
/** Browser references inferred directly from the server's exported function type. */
|
|
20
20
|
export declare const createApi: <F extends Functions>() => References<F>;
|
package/dist/client/session.d.ts
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as v from "valibot";
|
|
2
2
|
import type { Identity } from "#server/functions";
|
|
3
|
-
declare const
|
|
4
|
-
expiresAt: z.ZodNumber;
|
|
5
|
-
identity: z.ZodOptional<z.ZodObject<{
|
|
6
|
-
appId: z.ZodString;
|
|
7
|
-
deploymentId: z.ZodString;
|
|
8
|
-
expiresAt: z.ZodNumber;
|
|
9
|
-
installationId: z.ZodString;
|
|
10
|
-
projectId: z.ZodString;
|
|
11
|
-
scope: z.ZodObject<{
|
|
12
|
-
name: z.ZodString;
|
|
13
|
-
value: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
14
|
-
}, z.core.$strip>;
|
|
15
|
-
subjectId: z.ZodOptional<z.ZodString>;
|
|
16
|
-
toolUrl: z.ZodString;
|
|
17
|
-
}, z.core.$strip>>;
|
|
18
|
-
subjectId: z.ZodOptional<z.ZodString>;
|
|
19
|
-
token: z.ZodString;
|
|
20
|
-
toolUrl: z.ZodOptional<z.ZodString>;
|
|
21
|
-
url: z.ZodString;
|
|
22
|
-
}, z.core.$strip>;
|
|
23
|
-
export declare const parseSession: (value: Parameters<typeof sessionSchema.parse>[0]) => Session;
|
|
3
|
+
export declare const parseSession: (value: Parameters<typeof v.parse>[1]) => Session;
|
|
24
4
|
export interface Session {
|
|
25
5
|
toolUrl?: string;
|
|
26
6
|
identity?: Identity;
|
|
@@ -38,4 +18,3 @@ export declare const createSessionProvider: (options: {
|
|
|
38
18
|
}) => (input: {
|
|
39
19
|
refresh: boolean;
|
|
40
20
|
}) => Promise<Session>;
|
|
41
|
-
export {};
|
package/dist/client.js
CHANGED
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
useAction,
|
|
10
10
|
useMutation,
|
|
11
11
|
useQuery
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YFKW5FBP.js";
|
|
13
13
|
import {
|
|
14
14
|
createApi,
|
|
15
15
|
createClient,
|
|
16
16
|
createSessionProvider,
|
|
17
17
|
reference
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-MYK3WL3S.js";
|
|
19
19
|
import {
|
|
20
20
|
AppError,
|
|
21
21
|
appError
|
package/dist/index.js
CHANGED
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
useAction,
|
|
10
10
|
useMutation,
|
|
11
11
|
useQuery
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YFKW5FBP.js";
|
|
13
13
|
import {
|
|
14
14
|
createApi,
|
|
15
15
|
createClient,
|
|
16
16
|
createSessionProvider,
|
|
17
17
|
reference
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-MYK3WL3S.js";
|
|
19
19
|
import {
|
|
20
20
|
action,
|
|
21
21
|
and,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
table,
|
|
44
44
|
text,
|
|
45
45
|
withInstanceResolvers
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-QDZXHVTU.js";
|
|
47
47
|
import {
|
|
48
48
|
AppError,
|
|
49
49
|
appError
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { ContractRouterClient } from "@orpc/contract";
|
|
2
|
-
import
|
|
3
|
-
export declare const invocationSchema:
|
|
4
|
-
args:
|
|
5
|
-
name:
|
|
6
|
-
},
|
|
7
|
-
export type Invocation =
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
export declare const invocationSchema: v.StrictObjectSchema<{
|
|
4
|
+
readonly args: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
5
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 512, undefined>, v.RegexAction<string, undefined>]>;
|
|
6
|
+
}, undefined>;
|
|
7
|
+
export type Invocation = v.InferOutput<typeof invocationSchema>;
|
|
8
8
|
export type MutationInvocation = Invocation & {
|
|
9
9
|
requestId: string;
|
|
10
10
|
};
|
|
11
11
|
/** Public wire contract; implementations and clients both depend on this definition. */
|
|
12
12
|
export declare const appContract: {
|
|
13
|
-
actions: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<
|
|
14
|
-
args:
|
|
15
|
-
name:
|
|
16
|
-
},
|
|
13
|
+
actions: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<v.StrictObjectSchema<{
|
|
14
|
+
readonly args: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
15
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 512, undefined>, v.RegexAction<string, undefined>]>;
|
|
16
|
+
}, undefined>, import("@orpc/contract").Schema<unknown, unknown>, {
|
|
17
17
|
BAD_REQUEST: {};
|
|
18
18
|
CONFLICT: {};
|
|
19
19
|
FORBIDDEN: {};
|
|
@@ -23,11 +23,11 @@ export declare const appContract: {
|
|
|
23
23
|
UNAUTHORIZED: {};
|
|
24
24
|
UNAVAILABLE: {};
|
|
25
25
|
}>;
|
|
26
|
-
mutations: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<
|
|
27
|
-
args:
|
|
28
|
-
name:
|
|
29
|
-
requestId:
|
|
30
|
-
},
|
|
26
|
+
mutations: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<v.StrictObjectSchema<{
|
|
27
|
+
readonly args: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
28
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 512, undefined>, v.RegexAction<string, undefined>]>;
|
|
29
|
+
readonly requestId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UuidAction<string, undefined>]>;
|
|
30
|
+
}, undefined>, import("@orpc/contract").Schema<unknown, unknown>, {
|
|
31
31
|
BAD_REQUEST: {};
|
|
32
32
|
CONFLICT: {};
|
|
33
33
|
FORBIDDEN: {};
|
|
@@ -37,10 +37,10 @@ export declare const appContract: {
|
|
|
37
37
|
UNAUTHORIZED: {};
|
|
38
38
|
UNAVAILABLE: {};
|
|
39
39
|
}>;
|
|
40
|
-
queries: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<
|
|
41
|
-
args:
|
|
42
|
-
name:
|
|
43
|
-
},
|
|
40
|
+
queries: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<v.StrictObjectSchema<{
|
|
41
|
+
readonly args: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
42
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 512, undefined>, v.RegexAction<string, undefined>]>;
|
|
43
|
+
}, undefined>, import("@orpc/contract").Schema<unknown, unknown>, {
|
|
44
44
|
BAD_REQUEST: {};
|
|
45
45
|
CONFLICT: {};
|
|
46
46
|
FORBIDDEN: {};
|
|
@@ -50,10 +50,10 @@ export declare const appContract: {
|
|
|
50
50
|
UNAUTHORIZED: {};
|
|
51
51
|
UNAVAILABLE: {};
|
|
52
52
|
}>;
|
|
53
|
-
subscribe: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<
|
|
54
|
-
args:
|
|
55
|
-
name:
|
|
56
|
-
},
|
|
53
|
+
subscribe: import("@orpc/contract").ProcedureContractBuilderWithInputOutput<v.StrictObjectSchema<{
|
|
54
|
+
readonly args: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
55
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 512, undefined>, v.RegexAction<string, undefined>]>;
|
|
56
|
+
}, undefined>, import("@orpc/contract").Schema<AsyncIterableIterator<unknown>, AsyncIterableIterator<unknown>>, {
|
|
57
57
|
BAD_REQUEST: {};
|
|
58
58
|
CONFLICT: {};
|
|
59
59
|
FORBIDDEN: {};
|
package/dist/protocol.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// src/protocol.ts
|
|
2
2
|
import { oc, type } from "@orpc/contract";
|
|
3
|
-
import
|
|
4
|
-
var invocationSchema =
|
|
5
|
-
args:
|
|
6
|
-
name:
|
|
7
|
-
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
var invocationSchema = v.strictObject({
|
|
5
|
+
args: v.optional(v.unknown()),
|
|
6
|
+
name: v.pipe(
|
|
7
|
+
v.string(),
|
|
8
|
+
v.maxLength(512),
|
|
9
|
+
v.regex(
|
|
10
|
+
/^(?:[a-zA-Z][a-zA-Z0-9_]{0,63}|_tailorkit)(?:\.[a-zA-Z][a-zA-Z0-9_]{0,63})*$/u
|
|
11
|
+
)
|
|
8
12
|
)
|
|
9
13
|
});
|
|
10
14
|
var procedure = oc.errors({
|
|
@@ -19,7 +23,12 @@ var procedure = oc.errors({
|
|
|
19
23
|
});
|
|
20
24
|
var appContract = {
|
|
21
25
|
actions: procedure.input(invocationSchema).output(type()),
|
|
22
|
-
mutations: procedure.input(
|
|
26
|
+
mutations: procedure.input(
|
|
27
|
+
v.strictObject({
|
|
28
|
+
...invocationSchema.entries,
|
|
29
|
+
requestId: v.pipe(v.string(), v.uuid())
|
|
30
|
+
})
|
|
31
|
+
).output(type()),
|
|
23
32
|
queries: procedure.input(invocationSchema).output(type()),
|
|
24
33
|
// A pass-through type schema preserves the private hibernation iterator instance.
|
|
25
34
|
subscribe: procedure.input(invocationSchema).output(type())
|
package/dist/server/builder.d.ts
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
1
2
|
import type { AnyRelations, EmptyRelations } from "drizzle-orm/relations";
|
|
2
|
-
import
|
|
3
|
+
import * as v from "valibot";
|
|
3
4
|
import type { DatabaseDefinition } from "#database/definition";
|
|
4
5
|
import type { MutationDatabase, QueryDatabase } from "#database/types";
|
|
5
6
|
import type { ActionContext, EmptyFunctions, FunctionKind, Functions, Identity } from "./functions";
|
|
6
|
-
type HandlerContext<K extends FunctionKind, A extends
|
|
7
|
-
input:
|
|
7
|
+
type HandlerContext<K extends FunctionKind, A extends StandardSchemaV1, F extends Functions, D extends AnyRelations> = {
|
|
8
|
+
input: StandardSchemaV1.InferOutput<A>;
|
|
8
9
|
} & (K extends "action" ? ActionContext<F> : {
|
|
9
10
|
db: K extends "query" ? QueryDatabase<D> : MutationDatabase<D>;
|
|
10
11
|
identity: Identity;
|
|
11
12
|
});
|
|
12
|
-
type OutputInput<R> = R extends
|
|
13
|
+
type OutputInput<R> = R extends StandardSchemaV1 ? StandardSchemaV1.InferInput<R> : unknown;
|
|
13
14
|
type HandlerOutput<K, O> = K extends "action" ? O | Promise<O> : O & ([O] extends [never] ? unknown : O extends PromiseLike<unknown> ? never : unknown);
|
|
14
|
-
type BuiltFunction<K extends FunctionKind, A extends
|
|
15
|
+
type BuiltFunction<K extends FunctionKind, A extends StandardSchemaV1, R, O, F extends Functions, D extends AnyRelations> = {
|
|
15
16
|
readonly kind: K;
|
|
16
17
|
readonly args: A;
|
|
17
18
|
readonly database?: DatabaseDefinition<D>;
|
|
18
19
|
readonly handler: (context: Omit<HandlerContext<K, A, F, D>, "input"> & {
|
|
19
|
-
args:
|
|
20
|
+
args: StandardSchemaV1.InferOutput<A>;
|
|
20
21
|
}) => HandlerOutput<K, O>;
|
|
21
|
-
} & (R extends
|
|
22
|
+
} & (R extends StandardSchemaV1 ? {
|
|
22
23
|
readonly result: R;
|
|
23
24
|
} : unknown) & (K extends "action" ? {
|
|
24
25
|
readonly functions: F;
|
|
25
26
|
} : unknown);
|
|
26
27
|
/** Immutable builders preserve the validated input and wire output types at every step. */
|
|
27
|
-
declare class FunctionBuilder<K extends FunctionKind, A extends
|
|
28
|
+
declare class FunctionBuilder<K extends FunctionKind, A extends StandardSchemaV1, R extends StandardSchemaV1 | undefined = undefined, F extends Functions = EmptyFunctions, D extends AnyRelations = EmptyRelations> {
|
|
28
29
|
private readonly kind;
|
|
29
30
|
private readonly args;
|
|
30
31
|
private readonly result;
|
|
31
32
|
private readonly calls;
|
|
32
33
|
private readonly databaseDefinition;
|
|
33
34
|
constructor(kind: K, args: A, result: R, calls: F, database?: DatabaseDefinition<D>);
|
|
34
|
-
input<S extends
|
|
35
|
-
output<S extends
|
|
35
|
+
input<S extends StandardSchemaV1>(schema: S): FunctionBuilder<K, S, R, F, D>;
|
|
36
|
+
output<S extends StandardSchemaV1>(schema: S): FunctionBuilder<K, A, S, F, D>;
|
|
36
37
|
functions<const G extends Functions>(this: FunctionBuilder<"action", A, R, F, D>, functions: G): FunctionBuilder<"action", A, R, G, D>;
|
|
37
38
|
database<const E extends AnyRelations>(this: FunctionBuilder<K, A, R, F, D> & (K extends "action" ? never : unknown), database: DatabaseDefinition<E>): FunctionBuilder<K, A, R, F, E>;
|
|
38
39
|
handler<O extends OutputInput<R>>(handler: (context: HandlerContext<K, A, F, D>) => HandlerOutput<K, O>): BuiltFunction<K, A, R, O, F, D>;
|
|
39
40
|
}
|
|
40
41
|
export declare const fn: Readonly<{
|
|
41
|
-
action: FunctionBuilder<"action",
|
|
42
|
-
mutation: FunctionBuilder<"mutation",
|
|
43
|
-
query: FunctionBuilder<"query",
|
|
42
|
+
action: FunctionBuilder<"action", v.UndefinedSchema<undefined>, undefined, {}, EmptyRelations>;
|
|
43
|
+
mutation: FunctionBuilder<"mutation", v.UndefinedSchema<undefined>, undefined, {}, EmptyRelations>;
|
|
44
|
+
query: FunctionBuilder<"query", v.UndefinedSchema<undefined>, undefined, {}, EmptyRelations>;
|
|
44
45
|
}>;
|
|
45
46
|
export {};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
1
2
|
import type { AnyRelations, EmptyRelations } from "drizzle-orm/relations";
|
|
2
|
-
import type { z } from "zod";
|
|
3
3
|
import type { TailorKitServerTools } from "#client/tools";
|
|
4
4
|
import type { DatabaseDefinition } from "#database/definition";
|
|
5
5
|
import type { QueryDatabase, MutationDatabase } from "#database/types";
|
|
6
|
+
import type { JsonValue } from "#validation";
|
|
6
7
|
export type EmptyFunctions = Record<never, never>;
|
|
7
8
|
export interface Identity {
|
|
8
9
|
readonly subjectId?: string;
|
|
9
10
|
readonly scope: {
|
|
10
11
|
name: string;
|
|
11
|
-
value: Record<string,
|
|
12
|
+
value: Record<string, JsonValue>;
|
|
12
13
|
};
|
|
13
14
|
readonly toolUrl: string;
|
|
14
15
|
readonly projectId: string;
|
|
@@ -19,8 +20,8 @@ export interface Identity {
|
|
|
19
20
|
}
|
|
20
21
|
export type FunctionKind = "query" | "mutation" | "action";
|
|
21
22
|
export type FunctionResult<D> = D extends {
|
|
22
|
-
result: infer R extends
|
|
23
|
-
} ?
|
|
23
|
+
result: infer R extends StandardSchemaV1;
|
|
24
|
+
} ? StandardSchemaV1.InferOutput<R> : D extends {
|
|
24
25
|
handler: (context: never) => infer O;
|
|
25
26
|
} ? Awaited<O> : never;
|
|
26
27
|
export type FunctionCalls<F, K extends "query" | "mutation"> = {
|
|
@@ -29,13 +30,19 @@ export type FunctionCalls<F, K extends "query" | "mutation"> = {
|
|
|
29
30
|
} ? F[N] extends {
|
|
30
31
|
kind: K;
|
|
31
32
|
} ? N : never : N]: F[N] extends {
|
|
32
|
-
args: infer A extends
|
|
33
|
+
args: infer A extends StandardSchemaV1;
|
|
33
34
|
handler: (context: never) => infer _Output;
|
|
34
|
-
} ? K extends "mutation" ? (...args: undefined extends
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
} ? K extends "mutation" ? (...args: undefined extends StandardSchemaV1.InferInput<A> ? [
|
|
36
|
+
args?: StandardSchemaV1.InferInput<A>,
|
|
37
|
+
options?: {
|
|
38
|
+
requestId?: string;
|
|
39
|
+
}
|
|
40
|
+
] : [
|
|
41
|
+
args: StandardSchemaV1.InferInput<A>,
|
|
42
|
+
options?: {
|
|
43
|
+
requestId?: string;
|
|
44
|
+
}
|
|
45
|
+
]) => Promise<FunctionResult<F[N]>> : (...args: undefined extends StandardSchemaV1.InferInput<A> ? [args?: StandardSchemaV1.InferInput<A>] : [args: StandardSchemaV1.InferInput<A>]) => Promise<FunctionResult<F[N]>> : F[N] extends Functions ? FunctionCalls<F[N], K> : never;
|
|
39
46
|
};
|
|
40
47
|
export interface ActionContext<F extends Functions = EmptyFunctions> {
|
|
41
48
|
readonly identity: Identity;
|
|
@@ -46,52 +53,52 @@ export interface ActionContext<F extends Functions = EmptyFunctions> {
|
|
|
46
53
|
readonly queries: FunctionCalls<F, "query">;
|
|
47
54
|
readonly mutations: FunctionCalls<F, "mutation">;
|
|
48
55
|
}
|
|
49
|
-
export interface FunctionDefinition<K extends FunctionKind, A extends
|
|
56
|
+
export interface FunctionDefinition<K extends FunctionKind, A extends StandardSchemaV1, O, F extends Functions = EmptyFunctions, D extends AnyRelations = EmptyRelations> {
|
|
50
57
|
readonly kind: K;
|
|
51
58
|
readonly args: A;
|
|
52
59
|
readonly database?: K extends "action" ? never : DatabaseDefinition<D>;
|
|
53
|
-
readonly result?:
|
|
60
|
+
readonly result?: StandardSchemaV1<unknown, O>;
|
|
54
61
|
readonly handler: (context: {
|
|
55
|
-
args:
|
|
62
|
+
args: StandardSchemaV1.InferOutput<A>;
|
|
56
63
|
} & (K extends "action" ? ActionContext<F> : {
|
|
57
64
|
db: K extends "query" ? QueryDatabase<D> : MutationDatabase<D>;
|
|
58
65
|
identity: Identity;
|
|
59
66
|
})) => K extends "action" ? O | Promise<O> : O;
|
|
60
67
|
}
|
|
61
|
-
export declare const query: <A extends
|
|
68
|
+
export declare const query: <A extends StandardSchemaV1, O, const D extends AnyRelations = EmptyRelations>(definition: Omit<FunctionDefinition<"query", A, O, EmptyFunctions, D>, "kind"> & {
|
|
62
69
|
handler: FunctionDefinition<"query", A, O, EmptyFunctions, D>["handler"] & ([O] extends [never] ? unknown : O extends PromiseLike<unknown> ? never : unknown);
|
|
63
70
|
}) => Readonly<{
|
|
64
71
|
args: A;
|
|
65
72
|
database?: DatabaseDefinition<D> | undefined;
|
|
66
|
-
result?:
|
|
73
|
+
result?: StandardSchemaV1<unknown, O> | undefined;
|
|
67
74
|
handler: FunctionDefinition<"query", A, O, EmptyFunctions, D>["handler"] & ([O] extends [never] ? unknown : O extends PromiseLike<unknown> ? never : unknown);
|
|
68
75
|
kind: "query";
|
|
69
76
|
}>;
|
|
70
|
-
export declare const mutation: <A extends
|
|
77
|
+
export declare const mutation: <A extends StandardSchemaV1, O, const D extends AnyRelations = EmptyRelations>(definition: Omit<FunctionDefinition<"mutation", A, O, EmptyFunctions, D>, "kind"> & {
|
|
71
78
|
handler: FunctionDefinition<"mutation", A, O, EmptyFunctions, D>["handler"] & ([O] extends [never] ? unknown : O extends PromiseLike<unknown> ? never : unknown);
|
|
72
79
|
}) => Readonly<{
|
|
73
80
|
args: A;
|
|
74
81
|
database?: DatabaseDefinition<D> | undefined;
|
|
75
|
-
result?:
|
|
82
|
+
result?: StandardSchemaV1<unknown, O> | undefined;
|
|
76
83
|
handler: FunctionDefinition<"mutation", A, O, EmptyFunctions, D>["handler"] & ([O] extends [never] ? unknown : O extends PromiseLike<unknown> ? never : unknown);
|
|
77
84
|
kind: "mutation";
|
|
78
85
|
}>;
|
|
79
|
-
export declare const action: <A extends
|
|
86
|
+
export declare const action: <A extends StandardSchemaV1, O, const F extends Functions = EmptyFunctions>(definition: Omit<FunctionDefinition<"action", A, O, F>, "kind"> & {
|
|
80
87
|
functions?: F;
|
|
81
88
|
}) => Readonly<{
|
|
82
89
|
args: A;
|
|
83
90
|
database?: undefined;
|
|
84
|
-
result?:
|
|
91
|
+
result?: StandardSchemaV1<unknown, O> | undefined;
|
|
85
92
|
handler: (context: {
|
|
86
|
-
args:
|
|
93
|
+
args: StandardSchemaV1.InferOutput<A>;
|
|
87
94
|
} & ActionContext<F>) => O | Promise<O>;
|
|
88
95
|
functions?: F;
|
|
89
96
|
kind: "action";
|
|
90
97
|
}>;
|
|
91
98
|
export interface RegisteredFunction<TOutput = unknown> {
|
|
92
99
|
kind: FunctionKind;
|
|
93
|
-
args:
|
|
94
|
-
result?:
|
|
100
|
+
args: StandardSchemaV1;
|
|
101
|
+
result?: StandardSchemaV1;
|
|
95
102
|
handler: (context: never) => TOutput;
|
|
96
103
|
functions?: Functions;
|
|
97
104
|
database?: DatabaseDefinition;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
import type { ViewDataFields } from "#views";
|
|
3
3
|
import type { AppDefinition, Identity } from "./functions";
|
|
4
4
|
interface InstanceResolver<TOutput = unknown> {
|
|
5
5
|
slot: string;
|
|
6
6
|
path: string;
|
|
7
|
-
dataSchema:
|
|
7
|
+
dataSchema: StandardSchemaV1;
|
|
8
8
|
resolve: (context: {
|
|
9
9
|
context: ViewDataFields;
|
|
10
10
|
identity: Identity;
|
package/dist/server.js
CHANGED
package/dist/views.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
1
2
|
import { h } from "preact";
|
|
2
3
|
import type { ComponentChild, ComponentChildren, VNode } from "preact";
|
|
3
|
-
import type { z } from "zod";
|
|
4
4
|
import type { FunctionCalls, Identity } from "./server/functions";
|
|
5
5
|
export interface TailorKitViews {
|
|
6
6
|
}
|
|
@@ -20,10 +20,10 @@ export interface InstanceResolverContext<TPath extends AppViewPath> {
|
|
|
20
20
|
signal: AbortSignal;
|
|
21
21
|
queries: FunctionCalls<TailorKitServerFunctions, "query">;
|
|
22
22
|
}
|
|
23
|
-
export interface ViewInstances<TPath extends AppViewPath, TSchema extends
|
|
23
|
+
export interface ViewInstances<TPath extends AppViewPath, TSchema extends StandardSchemaV1> {
|
|
24
24
|
dataSchema: TSchema;
|
|
25
25
|
/** Runs on the app server. Only registered queries are available. */
|
|
26
|
-
resolve: (context: InstanceResolverContext<TPath>) => ViewInstance<
|
|
26
|
+
resolve: (context: InstanceResolverContext<TPath>) => ViewInstance<StandardSchemaV1.InferInput<TSchema>>[] | Promise<ViewInstance<StandardSchemaV1.InferInput<TSchema>>[]>;
|
|
27
27
|
}
|
|
28
28
|
export type SlotName = keyof TailorKitSlots & string;
|
|
29
29
|
export type ViewPath = Extract<keyof TailorKitViews & string, `/${string}`>;
|
|
@@ -93,7 +93,7 @@ export type TailorKitClientWithMeta<TViews extends SlotDefinitions = SlotDefinit
|
|
|
93
93
|
$meta: TailorKitClientMeta;
|
|
94
94
|
$runtime: TailorKitClientRuntime;
|
|
95
95
|
};
|
|
96
|
-
type ViewOptions<TPath extends AppViewPath, TSlot extends SlotName, TSchema extends
|
|
96
|
+
type ViewOptions<TPath extends AppViewPath, TSlot extends SlotName, TSchema extends StandardSchemaV1> = {
|
|
97
97
|
[S in TSlot]: {
|
|
98
98
|
slot: S;
|
|
99
99
|
view: TPath;
|
|
@@ -110,13 +110,13 @@ type ViewOptions<TPath extends AppViewPath, TSlot extends SlotName, TSchema exte
|
|
|
110
110
|
}[TSlot];
|
|
111
111
|
/** In .view.tsx files, the builder supplies the slot and filename-derived path.
|
|
112
112
|
* An explicit view must match the file path and provides precise host context typing. */
|
|
113
|
-
export declare function defineView<const TPath extends AppViewPath = AppViewPath, TSchema extends
|
|
113
|
+
export declare function defineView<const TPath extends AppViewPath = AppViewPath, TSchema extends StandardSchemaV1 = StandardSchemaV1>(options: {
|
|
114
114
|
slot?: never;
|
|
115
115
|
view?: TPath;
|
|
116
116
|
component: View;
|
|
117
117
|
instances?: ViewInstances<TPath, TSchema>;
|
|
118
|
-
}): ViewDefinition<TPath,
|
|
119
|
-
export declare function defineView<const TPath extends AppViewPath, const TSlot extends SlotName, TSchema extends
|
|
118
|
+
}): ViewDefinition<TPath, StandardSchemaV1.InferOutput<TSchema>>;
|
|
119
|
+
export declare function defineView<const TPath extends AppViewPath, const TSlot extends SlotName, TSchema extends StandardSchemaV1>(options: ViewOptions<TPath, TSlot, TSchema>): ViewDefinition<TPath, StandardSchemaV1.InferOutput<TSchema>, TSlot> & SlotInstanceDefinition<TSlot>;
|
|
120
120
|
export declare const createRemoteComponent: <TProps extends object, TChildren extends boolean = false>(name: string, options?: {
|
|
121
121
|
callbacks?: Record<string, number>;
|
|
122
122
|
children?: TChildren;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailorkit/app",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.44",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -64,9 +64,10 @@
|
|
|
64
64
|
"@nanostores/preact": "1.1.1",
|
|
65
65
|
"@orpc/client": "2.0.0-beta.40",
|
|
66
66
|
"@orpc/contract": "2.0.0-beta.40",
|
|
67
|
+
"@standard-schema/spec": "^1.1.0",
|
|
67
68
|
"drizzle-orm": "1.0.0-rc.4-5d5b77c",
|
|
68
69
|
"nanostores": "1.5.5",
|
|
69
|
-
"
|
|
70
|
+
"valibot": "^1.5.0"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
72
73
|
"@tailorkit/config": "0.0.0",
|
|
@@ -76,7 +77,8 @@
|
|
|
76
77
|
"tsup": "^8.5.1",
|
|
77
78
|
"typescript": "^7.0.2",
|
|
78
79
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
|
|
79
|
-
"vite-plus": "1.1.0"
|
|
80
|
+
"vite-plus": "1.1.0",
|
|
81
|
+
"zod": "^4.6.5"
|
|
80
82
|
},
|
|
81
83
|
"peerDependencies": {
|
|
82
84
|
"preact": "^11.0.0"
|