@lovrozagar/flare 0.7.0 → 0.7.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrozagar/flare",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Solid meta-framework. Server-driven, NDJSON streaming, renderToStream.",
5
5
  "keywords": [
6
6
  "flare",
@@ -54,7 +54,7 @@ export interface ServerBuilder<
54
54
  callerData?: unknown[];
55
55
  env: TEnv;
56
56
  request: Request;
57
- serverContext: Record<string, unknown>;
57
+ serverContext: TServerContext;
58
58
  url: URL;
59
59
  }) => TNewAuth | null | Promise<TNewAuth | null>,
60
60
  ) => ServerBuilder<TExcluded | "authenticateFn", TNewAuth, TServerContext, TEnv>;
@@ -72,12 +72,7 @@ export interface ServerBuilder<
72
72
  : (
73
73
  config:
74
74
  | SecurityConfig
75
- | ((ctx: {
76
- env: TEnv;
77
- nonce: string;
78
- request: Request;
79
- serverContext: Record<string, unknown>;
80
- }) => SecurityConfig),
75
+ | ((ctx: { env: TEnv; nonce: string; request: Request; serverContext: TServerContext }) => SecurityConfig),
81
76
  ) => ServerBuilder<TExcluded | "security", TAuth, TServerContext, TEnv>;
82
77
  serverContext: "serverContext" extends TExcluded
83
78
  ? never
@@ -1,3 +1,4 @@
1
+ import type { ResolvedAuth, ResolvedEnv, ResolvedServerContext } from "../route-builder/register.ts";
1
2
  import { FORM_FN_FIELD, parseServerFnPathname, serverFnPath } from "../protocol.ts";
2
3
  import { callServerFnOverHttp } from "./rpc.ts";
3
4
  import {
@@ -39,7 +40,8 @@ export interface PiggybackedQuery {
39
40
  key: unknown[];
40
41
  }
41
42
 
42
- export interface HandlerContext<TAuth, TInput, TEnv = unknown> {
43
+ /* TEnv defaults to the app's registered env (`createServer<Env>()`) */
44
+ export interface HandlerContext<TAuth, TInput, TEnv = ResolvedEnv> {
43
45
  auth: TAuth;
44
46
  env: TEnv;
45
47
  input: TInput;
@@ -56,15 +58,17 @@ export interface HandlerContext<TAuth, TInput, TEnv = unknown> {
56
58
  piggyback: (key: unknown[], data: unknown) => void;
57
59
  request: Request;
58
60
  revalidate: RevalidateFn;
59
- serverContext: Record<string, unknown>;
61
+ /* the app's `.serverContext()` result, typed through FlareRegister */
62
+ serverContext: ResolvedServerContext;
60
63
  }
61
64
 
62
- export interface StreamContext<TAuth, TInput, TEnv = unknown> {
65
+ export interface StreamContext<TAuth, TInput, TEnv = ResolvedEnv> {
63
66
  auth: TAuth;
64
67
  env: TEnv;
65
68
  input: TInput;
66
69
  request: Request;
67
- serverContext: Record<string, unknown>;
70
+ /* the app's `.serverContext()` result, typed through FlareRegister */
71
+ serverContext: ResolvedServerContext;
68
72
  signal: AbortSignal;
69
73
  }
70
74
 
@@ -78,12 +82,12 @@ export interface ServerFnRegistrationBase {
78
82
  }
79
83
 
80
84
  export interface ServerFnHandlerRegistration extends ServerFnRegistrationBase {
81
- fn: (ctx: HandlerContext<unknown, unknown>) => unknown | Promise<unknown>;
85
+ fn: (ctx: HandlerContext<unknown, unknown, unknown>) => unknown | Promise<unknown>;
82
86
  stream?: false;
83
87
  }
84
88
 
85
89
  export interface ServerFnStreamRegistration extends ServerFnRegistrationBase {
86
- fn: (ctx: StreamContext<unknown, unknown>) => AsyncGenerator<unknown>;
90
+ fn: (ctx: StreamContext<unknown, unknown, unknown>) => AsyncGenerator<unknown>;
87
91
  stream: true;
88
92
  }
89
93
 
@@ -99,22 +103,24 @@ interface BuilderState {
99
103
  name: string;
100
104
  }
101
105
 
102
- interface ServerFnBuilderTerminal<TAuth, TInput, TOutput> {
103
- handler(fn: (ctx: HandlerContext<TAuth, TInput>) => TOutput | Promise<TOutput>): ServerFn<TInput, TOutput>;
104
- input<T>(validator: Validator<T>): ServerFnBuilderTerminal<TAuth, T, TOutput>;
106
+ interface ServerFnBuilderTerminal<TAuth, TInput> {
107
+ /* the output type is the handler's: callers get it without restating it */
108
+ handler<TOutput>(fn: (ctx: HandlerContext<TAuth, TInput>) => TOutput | Promise<TOutput>): ServerFn<TInput, TOutput>;
109
+ input<T>(validator: Validator<T>): ServerFnBuilderTerminal<TAuth, T>;
105
110
  stream<TChunk>(fn: (ctx: StreamContext<TAuth, TInput>) => AsyncGenerator<TChunk>): StreamFn<TInput, TChunk>;
106
111
  }
107
112
 
108
- interface ServerFnBuilderAfterAuth<TAuth, TInput, TOutput> extends ServerFnBuilderTerminal<TAuth, TInput, TOutput> {
113
+ interface ServerFnBuilderAfterAuth<TAuth, TInput> extends ServerFnBuilderTerminal<TAuth, TInput> {
109
114
  authorize(
110
115
  fn: (ctx: { auth: TAuth; input: TInput }) => boolean | Promise<boolean>,
111
- ): ServerFnBuilderTerminal<TAuth, TInput, TOutput>;
112
- input<T>(validator: Validator<T>): ServerFnBuilderAfterAuth<TAuth, T, TOutput>;
116
+ ): ServerFnBuilderTerminal<TAuth, TInput>;
117
+ input<T>(validator: Validator<T>): ServerFnBuilderAfterAuth<TAuth, T>;
113
118
  }
114
119
 
115
- interface ServerFnBuilder<TAuth, TInput, TOutput> extends ServerFnBuilderAfterAuth<TAuth, TInput, TOutput> {
116
- authenticate(): ServerFnBuilderAfterAuth<unknown, TInput, TOutput>;
117
- input<T>(validator: Validator<T>): ServerFnBuilder<TAuth, T, TOutput>;
120
+ interface ServerFnBuilder<TAuth, TInput> extends ServerFnBuilderAfterAuth<TAuth, TInput> {
121
+ /* the app's `authenticateFn` result, typed through FlareRegister */
122
+ authenticate(): ServerFnBuilderAfterAuth<ResolvedAuth<true>, TInput>;
123
+ input<T>(validator: Validator<T>): ServerFnBuilder<TAuth, T>;
118
124
  }
119
125
 
120
126
  export type ServerFn<_TInput, TOutput> = ((_input: _TInput) => Promise<TOutput>) & {
@@ -128,15 +134,13 @@ export type StreamFn<_TInput, TChunk> = ((
128
134
  _registration?: ServerFnRegistration;
129
135
  };
130
136
 
131
- function createBuilderTerminal<TAuth, TInput, TOutput>(
132
- state: BuilderState,
133
- ): ServerFnBuilderTerminal<TAuth, TInput, TOutput> {
137
+ function createBuilderTerminal<TAuth, TInput>(state: BuilderState): ServerFnBuilderTerminal<TAuth, TInput> {
134
138
  return {
135
- handler(fn) {
139
+ handler<TOutput>(fn: (ctx: HandlerContext<TAuth, TInput>) => TOutput | Promise<TOutput>) {
136
140
  const registration: ServerFnHandlerRegistration = {
137
141
  authenticate: state.authenticate,
138
142
  authorizeFn: state.authorizeFn,
139
- fn: fn as (ctx: HandlerContext<unknown, unknown>) => unknown | Promise<unknown>,
143
+ fn: fn as (ctx: HandlerContext<unknown, unknown, unknown>) => unknown | Promise<unknown>,
140
144
  id: state.__id && state.__id.length > 0 ? state.__id : state.name,
141
145
  input: state.input,
142
146
  method: state.method,
@@ -168,7 +172,8 @@ function createBuilderTerminal<TAuth, TInput, TOutput>(
168
172
  };
169
173
  return await fn({
170
174
  auth: null as TAuth,
171
- env: {},
175
+ /* direct server-side invocation runs outside a request: there are no bindings */
176
+ env: {} as ResolvedEnv,
172
177
  input: validated,
173
178
  piggyback: () => {},
174
179
  request: new Request("http://localhost"),
@@ -180,7 +185,7 @@ function createBuilderTerminal<TAuth, TInput, TOutput>(
180
185
  return serverFn;
181
186
  },
182
187
  input<T>(validator: Validator<T>) {
183
- return createBuilderTerminal<TAuth, T, TOutput>({
188
+ return createBuilderTerminal<TAuth, T>({
184
189
  ...state,
185
190
  input: validator as Validator<unknown>,
186
191
  });
@@ -189,7 +194,7 @@ function createBuilderTerminal<TAuth, TInput, TOutput>(
189
194
  const registration: ServerFnStreamRegistration = {
190
195
  authenticate: state.authenticate,
191
196
  authorizeFn: state.authorizeFn,
192
- fn: fn as (ctx: StreamContext<unknown, unknown>) => AsyncGenerator<unknown>,
197
+ fn: fn as (ctx: StreamContext<unknown, unknown, unknown>) => AsyncGenerator<unknown>,
193
198
  id: state.__id && state.__id.length > 0 ? state.__id : state.name,
194
199
  input: state.input,
195
200
  method: state.method,
@@ -218,7 +223,7 @@ function createBuilderTerminal<TAuth, TInput, TOutput>(
218
223
  const validated = (await validatedPromise) as TInput;
219
224
  generator = fn({
220
225
  auth: null as TAuth,
221
- env: {} as unknown,
226
+ env: {} as ResolvedEnv,
222
227
  input: validated,
223
228
  request: new Request("http://localhost"),
224
229
  serverContext: getServerContext(),
@@ -243,19 +248,17 @@ function createBuilderTerminal<TAuth, TInput, TOutput>(
243
248
  };
244
249
  }
245
250
 
246
- function createBuilderAfterAuth<TAuth, TInput, TOutput>(
247
- state: BuilderState,
248
- ): ServerFnBuilderAfterAuth<TAuth, TInput, TOutput> {
251
+ function createBuilderAfterAuth<TAuth, TInput>(state: BuilderState): ServerFnBuilderAfterAuth<TAuth, TInput> {
249
252
  return {
250
- ...createBuilderTerminal<TAuth, TInput, TOutput>(state),
253
+ ...createBuilderTerminal<TAuth, TInput>(state),
251
254
  authorize(fn) {
252
- return createBuilderTerminal<TAuth, TInput, TOutput>({
255
+ return createBuilderTerminal<TAuth, TInput>({
253
256
  ...state,
254
257
  authorizeFn: fn as (ctx: { auth: unknown; input: unknown }) => boolean | Promise<boolean>,
255
258
  });
256
259
  },
257
260
  input<T>(validator: Validator<T>) {
258
- return createBuilderAfterAuth<TAuth, T, TOutput>({
261
+ return createBuilderAfterAuth<TAuth, T>({
259
262
  ...state,
260
263
  input: validator as Validator<unknown>,
261
264
  });
@@ -263,17 +266,17 @@ function createBuilderAfterAuth<TAuth, TInput, TOutput>(
263
266
  };
264
267
  }
265
268
 
266
- function createBuilder<TAuth, TInput, TOutput>(state: BuilderState): ServerFnBuilder<TAuth, TInput, TOutput> {
269
+ function createBuilder<TAuth, TInput>(state: BuilderState): ServerFnBuilder<TAuth, TInput> {
267
270
  return {
268
- ...createBuilderAfterAuth<TAuth, TInput, TOutput>(state),
271
+ ...createBuilderAfterAuth<TAuth, TInput>(state),
269
272
  authenticate() {
270
- return createBuilderAfterAuth<unknown, TInput, TOutput>({
273
+ return createBuilderAfterAuth<ResolvedAuth<true>, TInput>({
271
274
  ...state,
272
275
  authenticate: true,
273
276
  });
274
277
  },
275
278
  input<T>(validator: Validator<T>) {
276
- return createBuilder<TAuth, T, TOutput>({
279
+ return createBuilder<TAuth, T>({
277
280
  ...state,
278
281
  input: validator as Validator<unknown>,
279
282
  });
@@ -281,8 +284,8 @@ function createBuilder<TAuth, TInput, TOutput>(state: BuilderState): ServerFnBui
281
284
  };
282
285
  }
283
286
 
284
- export function createServerFn(config: ServerFnConfig): ServerFnBuilder<null, void, unknown> {
285
- return createBuilder<null, void, unknown>({
287
+ export function createServerFn(config: ServerFnConfig): ServerFnBuilder<null, void> {
288
+ return createBuilder<null, void>({
286
289
  __client: config.__client,
287
290
  __id: config.__id,
288
291
  authenticate: false,