@sourceregistry/sveltekit-enhance 1.1.0 → 1.1.2

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 CHANGED
@@ -9,7 +9,7 @@ Use `@sourceregistry/sveltekit-enhance` to build cleaner actions, loads, methods
9
9
 
10
10
  ## Why teams use this
11
11
 
12
- - Standardize server-side guard logic across routes.
12
+ - Standardize server-side context logic across routes.
13
13
  - Reduce repetitive request parsing and validation code.
14
14
  - Keep middleware-like behavior explicit and composable.
15
15
  - Improve observability with correlation IDs on every response.
@@ -29,7 +29,7 @@ The package provides an `enhance` wrapper for:
29
29
  - `enhance.method(...)`
30
30
  - `enhance.handle(...)`
31
31
 
32
- Each wrapper accepts one or more guard functions and merges their outputs into a typed `guard` object.
32
+ Each wrapper accepts one or more context functions and merges their outputs into a typed `context` object.
33
33
 
34
34
  ## Quick start
35
35
 
@@ -40,13 +40,13 @@ import {Auth, FeatureFlag, form} from '@sourceregistry/sveltekit-enhance';
40
40
 
41
41
  export const actions = {
42
42
  save: enhance.action(
43
- async ({request, guard}) => {
43
+ async ({request, context}) => {
44
44
  const data = await request.formData();
45
45
  const email = form.string$(data, 'email');
46
46
 
47
47
  return {
48
48
  ok: true,
49
- token: guard.token,
49
+ token: context.token,
50
50
  email
51
51
  };
52
52
  },
@@ -53,7 +53,7 @@ declare const createContext: (data: FormData) => {
53
53
  date$: (name: string, parser?: (formdata: FormData, name: string) => number | string | Date) => Date;
54
54
  process: <T, R>(name: string, parser: ((formdata: FormData, name: string) => T) | ((name: string) => T), processor: (val: T, name: string) => R) => R;
55
55
  number: (name: string) => number | undefined;
56
- number$: (name: string) => number | undefined;
56
+ number$: (name: string) => number;
57
57
  boolean: (name: string) => boolean | undefined;
58
58
  boolean$: (name: string) => boolean;
59
59
  json: <T = unknown, F = T>(name: string, transformer?: (val: F) => T) => T | undefined;
@@ -102,7 +102,7 @@ export declare function string$(formdata: FormData, name: string): string;
102
102
  */
103
103
  export declare function pattern$(formdata: FormData, name: string, pattern: string | RegExp): string;
104
104
  export declare function number(formdata: FormData, name: string): number | undefined;
105
- export declare function number$(formdata: FormData, name: string): number | undefined;
105
+ export declare function number$(formdata: FormData, name: string): number;
106
106
  export declare function boolean(formdata: FormData, name: string): boolean | undefined;
107
107
  export declare function boolean$(formdata: FormData, name: string): boolean;
108
108
  export declare function date(formdata: FormData, name: string, parser?: (formdata: FormData, name: string) => number | string | Date | undefined): Date | undefined;
@@ -190,7 +190,7 @@ export declare const schema: <const T extends AnyValidator>(validator: T, option
190
190
  readonly date$: (name: string, parser?: (formdata: FormData, name: string) => number | string | Date) => Date;
191
191
  readonly process: <T_1, R>(name: string, parser: ((formdata: FormData, name: string) => T_1) | ((name: string) => T_1), processor: (val: T_1, name: string) => R) => R;
192
192
  readonly number: (name: string) => number | undefined;
193
- readonly number$: (name: string) => number | undefined;
193
+ readonly number$: (name: string) => number;
194
194
  readonly boolean: (name: string) => boolean | undefined;
195
195
  readonly boolean$: (name: string) => boolean;
196
196
  readonly json: <T_1 = unknown, F = T_1>(name: string, transformer?: (val: F) => T_1) => T_1 | undefined;
@@ -270,7 +270,7 @@ export declare const Form: {
270
270
  readonly date$: (name: string, parser?: (formdata: FormData, name: string) => number | string | Date) => Date;
271
271
  readonly process: <T_1, R>(name: string, parser: ((formdata: FormData, name: string) => T_1) | ((name: string) => T_1), processor: (val: T_1, name: string) => R) => R;
272
272
  readonly number: (name: string) => number | undefined;
273
- readonly number$: (name: string) => number | undefined;
273
+ readonly number$: (name: string) => number;
274
274
  readonly boolean: (name: string) => boolean | undefined;
275
275
  readonly boolean$: (name: string) => boolean;
276
276
  readonly json: <T_1 = unknown, F = T_1>(name: string, transformer?: (val: F) => T_1) => T_1 | undefined;
@@ -133,7 +133,7 @@ export function number(formdata, name) {
133
133
  export function number$(formdata, name) {
134
134
  const _number = number(formdata, name);
135
135
  if (_number === undefined) {
136
- fail(400, { targets: [name], message: `${name} is required` });
136
+ return fail(400, { targets: [name], message: `${name} is required` });
137
137
  }
138
138
  return _number;
139
139
  }
@@ -425,7 +425,7 @@ export function selector$(formData, cases, useArray = false) {
425
425
  if ('$error' in cases) {
426
426
  cases?.['$error']?.('Unable to find value');
427
427
  }
428
- fail(400, { targets: Object.keys(cases), message: `Unable to find value` });
428
+ return fail(400, { targets: Object.keys(cases), message: `Unable to find value` });
429
429
  }
430
430
  return result;
431
431
  }
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export type EnhanceInput<CallType extends EnhanceCallType = EnhanceCallType, Par
21
21
  get errorHandlers(): EnhanceErrorHandler[];
22
22
  } & (CallType extends 'handle' ? {
23
23
  get responseHandlers(): EnhanceResponseHandler[];
24
- resolve: (event?: RequestEvent) => never;
24
+ resolve: (event?: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
25
25
  readonly event: RequestEvent;
26
26
  } : CallType extends 'load' ? {
27
27
  parent: ServerLoadEvent<Params, ParentData, RouteId>['parent'];
package/dist/index.js CHANGED
@@ -118,6 +118,7 @@ handle, ...contexts) => {
118
118
  };
119
119
  export const handle = (handle, ...contexts) => async (input) => {
120
120
  let combined = {};
121
+ let resolved = false;
121
122
  const contextInput = Object.assign(input.event, {
122
123
  __errorHandlers__: [],
123
124
  __responseHandler__: [],
@@ -129,24 +130,71 @@ export const handle = (handle, ...contexts) => async (input) => {
129
130
  get responseHandlers() {
130
131
  return this.__responseHandler__;
131
132
  },
132
- resolve: (event = input.event) => {
133
- throw input.resolve(event);
133
+ resolve: (event = input.event, opts) => {
134
+ resolved = true;
135
+ return apply_handle(contexts.length, event, opts);
134
136
  },
135
137
  get event() {
136
138
  return input.event;
137
139
  }
138
140
  });
139
- for (const context of contexts) {
141
+ const merge_options = (parent_options, options) => {
142
+ const transformPageChunk = async ({ html, done }) => {
143
+ if (options?.transformPageChunk) {
144
+ html = (await options.transformPageChunk({ html, done })) ?? '';
145
+ }
146
+ if (parent_options?.transformPageChunk) {
147
+ html = (await parent_options.transformPageChunk({ html, done })) ?? '';
148
+ }
149
+ return html;
150
+ };
151
+ return {
152
+ transformPageChunk,
153
+ filterSerializedResponseHeaders: parent_options?.filterSerializedResponseHeaders ??
154
+ options?.filterSerializedResponseHeaders,
155
+ preload: parent_options?.preload ?? options?.preload
156
+ };
157
+ };
158
+ const apply_handle = async (i, event, parent_options) => {
159
+ if (i < contexts.length) {
160
+ const context = contexts[i];
161
+ const previous_resolve = contextInput.resolve;
162
+ contextInput.resolve = (next_event = event, options) => {
163
+ resolved = true;
164
+ return apply_handle(i + 1, next_event, merge_options(parent_options, options));
165
+ };
166
+ try {
167
+ resolved = false;
168
+ const result = await context(contextInput);
169
+ if (result instanceof Response)
170
+ return result;
171
+ if (resolved) {
172
+ throw new Error('enhance.handle context called resolve but did not return its response');
173
+ }
174
+ combined = Object.assign(combined, result);
175
+ return apply_handle(i + 1, event, parent_options);
176
+ }
177
+ catch (e) {
178
+ return EnhanceErrorHandle(e, contextInput);
179
+ }
180
+ finally {
181
+ contextInput.resolve = previous_resolve;
182
+ }
183
+ }
140
184
  try {
141
- const result = await context(contextInput);
142
- combined = Object.assign(combined, result);
185
+ return await handle({
186
+ ...input,
187
+ context: combined,
188
+ event,
189
+ resolve: (next_event, options) => input.resolve(next_event, merge_options(parent_options, options))
190
+ });
143
191
  }
144
192
  catch (e) {
145
193
  return EnhanceErrorHandle(e, contextInput);
146
194
  }
147
- }
195
+ };
148
196
  try {
149
- const response = await handle(Object.assign(input, { context: combined }));
197
+ const response = await apply_handle(0, input.event);
150
198
  if (contextInput.responseHandlers.length > 0) {
151
199
  for (const responseHandler of contextInput.responseHandlers) {
152
200
  await responseHandler({ event: contextInput, response });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sourceregistry/sveltekit-enhance",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Composable enhance and form utilities for SvelteKit actions, loads, methods, and hooks.",
5
5
  "author": "A.P.A. Slaa (a.p.a.slaa@projectsource.nl)",
6
6
  "scripts": {