@holo-js/forms 0.3.15 → 0.3.16

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.
@@ -1,5 +1,4 @@
1
- import { ValidationSchema, SchemaInputShape, ValidationErrorBag, InferSchemaData, FormLikeValidationInput } from '@holo-js/validation';
2
- import { FormSchema } from './schema.js';
1
+ import { ValidationSchema, SchemaInputShape, ValidationErrorBag, InferValidationSchemaData, InferSchemaData, FormLikeValidationInput } from '@holo-js/validation';
3
2
 
4
3
  type FormFailureErrors = Readonly<Partial<Record<string, readonly string[]>>>;
5
4
  interface FormFailureOptions {
@@ -17,6 +16,7 @@ declare const sensitiveInputInternals: {
17
16
  DEFAULT_DONT_FLASH_FIELDS: readonly string[];
18
17
  };
19
18
 
19
+ type InferFormData<TSchema extends ValidationSchema> = InferValidationSchemaData<TSchema>;
20
20
  interface FormFailurePayload<TData> {
21
21
  readonly ok: false;
22
22
  readonly status: number;
@@ -109,15 +109,15 @@ interface FormSubmissionFailure<TData> {
109
109
  fail(options: FormFailureOptions): FormFailurePayload<TData>;
110
110
  }
111
111
  type FormSubmissionResult<TData> = FormSubmissionSuccess<TData> | FormSubmissionFailure<TData>;
112
- declare function serializeSubmissionState<TData>(valid: boolean, values: Partial<TData> | TData, errors: ValidationErrorBag<TData>, schemaDefinition?: FormSchema): SerializedFormSubmission<TData>;
113
- declare function createSubmission<TData>(valid: boolean, values: Partial<TData> | TData, errors: ValidationErrorBag<TData>, failureStatus?: number, schemaDefinition?: FormSchema, failureMetadata?: FormFailureMetadata): FormSubmissionResult<TData>;
114
- declare function createSuccessfulSubmission<TShape extends SchemaInputShape>(schemaDefinition: FormSchema<TShape>, data: InferSchemaData<TShape>): FormSubmissionSuccess<InferSchemaData<TShape>>;
115
- declare function createFailedSubmission<TShape extends SchemaInputShape>(schemaDefinition: FormSchema<TShape>, values: Partial<InferSchemaData<TShape>>, flattenedErrors: Record<string, readonly string[]>, status?: number, failureMetadata?: FormFailureMetadata): FormSubmissionFailure<InferSchemaData<TShape>>;
112
+ declare function serializeSubmissionState<TData>(valid: boolean, values: Partial<TData> | TData, errors: ValidationErrorBag<TData>, schemaDefinition?: ValidationSchema): SerializedFormSubmission<TData>;
113
+ declare function createSubmission<TData>(valid: boolean, values: Partial<TData> | TData, errors: ValidationErrorBag<TData>, failureStatus?: number, schemaDefinition?: ValidationSchema, failureMetadata?: FormFailureMetadata): FormSubmissionResult<TData>;
114
+ declare function createSuccessfulSubmission<TShape extends SchemaInputShape>(schemaDefinition: ValidationSchema<TShape>, data: InferSchemaData<TShape>): FormSubmissionSuccess<InferSchemaData<TShape>>;
115
+ declare function createFailedSubmission<TShape extends SchemaInputShape>(schemaDefinition: ValidationSchema<TShape>, values: Partial<InferSchemaData<TShape>>, flattenedErrors: Record<string, readonly string[]>, status?: number, failureMetadata?: FormFailureMetadata): FormSubmissionFailure<InferSchemaData<TShape>>;
116
116
  declare function isRequestLikeHeaders(value: unknown): value is RequestLikeHeaders;
117
117
  declare function normalizeRequestHeaders(input: unknown): Headers;
118
118
  declare function normalizeRequestLikeInput(input: FormLikeValidationInput | FormRequestLikeInput | null | undefined): Request | undefined;
119
- declare function safeParse<TShape extends SchemaInputShape>(input: FormLikeValidationInput | FormRequestLikeInput, schemaDefinition: FormSchema<TShape>, options?: FormSecurityOptions): Promise<FormSubmissionResult<InferSchemaData<TShape>>>;
120
- declare function validate<TShape extends SchemaInputShape>(input: FormLikeValidationInput | FormRequestLikeInput, schemaDefinition: FormSchema<TShape>, options?: FormSecurityOptions): Promise<InferSchemaData<TShape>>;
119
+ declare function safeParse<TShape extends SchemaInputShape>(input: FormLikeValidationInput | FormRequestLikeInput, schemaDefinition: ValidationSchema<TShape>, options?: FormSecurityOptions): Promise<FormSubmissionResult<InferSchemaData<TShape>>>;
120
+ declare function validate<TShape extends SchemaInputShape>(input: FormLikeValidationInput | FormRequestLikeInput, schemaDefinition: ValidationSchema<TShape>, options?: FormSecurityOptions): Promise<InferSchemaData<TShape>>;
121
121
  declare const formsInternals: {
122
122
  createSubmission: typeof createSubmission;
123
123
  isRequestLikeHeaders: typeof isRequestLikeHeaders;
@@ -129,4 +129,4 @@ declare const formsInternals: {
129
129
  serializeSubmissionState: typeof serializeSubmissionState;
130
130
  };
131
131
 
132
- export { type FormFailureErrors as F, type SerializedFormSubmission as S, type FormFailureInput as a, type FormFailureOptions as b, type FormFailurePayload as c, type FormRequestLikeInput as d, type FormSecurityOptions as e, type FormSubmissionFailure as f, type FormSubmissionResult as g, type FormSubmissionSuccess as h, type FormSuccessPayload as i, createFailedSubmission as j, createSuccessfulSubmission as k, formsInternals as l, sanitizeFlashedInput as m, sensitiveInputInternals as n, safeParse as s, validate as v };
132
+ export { type FormFailureErrors as F, type InferFormData as I, type SerializedFormSubmission as S, type FormFailureInput as a, type FormFailureOptions as b, type FormFailurePayload as c, type FormRequestLikeInput as d, type FormSecurityOptions as e, type FormSubmissionFailure as f, type FormSubmissionResult as g, type FormSubmissionSuccess as h, type FormSuccessPayload as i, createFailedSubmission as j, createSuccessfulSubmission as k, formsInternals as l, sanitizeFlashedInput as m, sensitiveInputInternals as n, safeParse as s, validate as v };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- export { F as FormFailureErrors, a as FormFailureInput, b as FormFailureOptions, c as FormFailurePayload, d as FormRequestLikeInput, e as FormSecurityOptions, f as FormSubmissionFailure, g as FormSubmissionResult, h as FormSubmissionSuccess, i as FormSuccessPayload, S as SerializedFormSubmission, j as createFailedSubmission, k as createSuccessfulSubmission, l as formsInternals, s as safeParse, m as sanitizeFlashedInput, n as sensitiveInputInternals, v as validate } from './contracts-BOhBkI9c.js';
2
- export { FormSchema, InferFormData, isFormSchema, schema } from './schema.js';
3
- export { DEFAULT_VALIDATION_BAG, ErrorTree, ErrorTreeNode, FieldDefinition, FieldRule, InferSchemaData, SerializedValidationException, StandardSchemaV1, StandardSchemaV1Issue, StandardSchemaV1Props, StandardSchemaV1Result, ValidationErrorBag, ValidationException, ValidationExceptionOptions, ValidationFailure, ValidationResult, ValidationSchema, ValidationSuccess, WebFileLike, createErrorBag, defineSchema, field, isValidationException, parse } from '@holo-js/validation';
1
+ export { F as FormFailureErrors, a as FormFailureInput, b as FormFailureOptions, c as FormFailurePayload, d as FormRequestLikeInput, e as FormSecurityOptions, f as FormSubmissionFailure, g as FormSubmissionResult, h as FormSubmissionSuccess, i as FormSuccessPayload, I as InferFormData, S as SerializedFormSubmission, j as createFailedSubmission, k as createSuccessfulSubmission, l as formsInternals, s as safeParse, m as sanitizeFlashedInput, n as sensitiveInputInternals, v as validate } from './contracts-CJ9Aq8pS.js';
2
+ import '@holo-js/validation';
4
3
 
5
4
  declare class FormContractError extends Error {
6
5
  constructor(message: string);
package/dist/index.mjs CHANGED
@@ -1,14 +1,3 @@
1
- import {
2
- DEFAULT_VALIDATION_BAG,
3
- ValidationException,
4
- createErrorBag,
5
- defineSchema,
6
- field,
7
- isFormSchema,
8
- isValidationException,
9
- parse,
10
- schema
11
- } from "./chunk-GPWXGHZE.mjs";
12
1
  import {
13
2
  normalizeFailureErrors,
14
3
  normalizeFailureInput,
@@ -22,8 +11,8 @@ import {
22
11
 
23
12
  // src/contracts.ts
24
13
  import {
25
- ValidationException as ValidationException2,
26
- createErrorBag as createErrorBag2,
14
+ ValidationException,
15
+ createErrorBag,
27
16
  safeParse as safeParseInput,
28
17
  validationInternals
29
18
  } from "@holo-js/validation";
@@ -89,7 +78,7 @@ function createSuccessfulSubmission(schemaDefinition, data) {
89
78
  return createSubmission(
90
79
  true,
91
80
  data,
92
- createErrorBag2(),
81
+ createErrorBag(),
93
82
  422,
94
83
  schemaDefinition
95
84
  );
@@ -100,7 +89,7 @@ function createFailedSubmission(schemaDefinition, values, flattenedErrors, statu
100
89
  return createSubmission(
101
90
  false,
102
91
  values,
103
- createErrorBag2(flattenedErrors),
92
+ createErrorBag(flattenedErrors),
104
93
  normalizedStatus,
105
94
  schemaDefinition,
106
95
  failureMetadata
@@ -479,7 +468,7 @@ async function validate(input, schemaDefinition, options = {}) {
479
468
  }
480
469
  const failure = result.fail();
481
470
  const exception = validationInternals.setValidationExceptionValues(
482
- ValidationException2.withMessages(result.errors.flatten(), {
471
+ ValidationException.withMessages(result.errors.flatten(), {
483
472
  bag: options.bag
484
473
  }),
485
474
  result.values
@@ -502,21 +491,12 @@ var formsInternals = {
502
491
  serializeSubmissionState
503
492
  };
504
493
  export {
505
- DEFAULT_VALIDATION_BAG,
506
494
  FormContractError,
507
- ValidationException,
508
- createErrorBag,
509
495
  createFailedSubmission,
510
496
  createSuccessfulSubmission,
511
- defineSchema,
512
- field,
513
497
  formsInternals,
514
- isFormSchema,
515
- isValidationException,
516
- parse,
517
498
  safeParse,
518
499
  sanitizeFlashedInput,
519
- schema,
520
500
  sensitiveInputInternals,
521
501
  validate
522
502
  };
@@ -1,6 +1,5 @@
1
- import { S as SerializedFormSubmission, c as FormFailurePayload, i as FormSuccessPayload, g as FormSubmissionResult } from '../contracts-BOhBkI9c.js';
2
- import { ValidationErrorBag, WebFileLike, SchemaInputShape, FieldBuilderInput, InferFieldOutput } from '@holo-js/validation';
3
- import { FormSchema, InferFormData } from '../schema.js';
1
+ import { S as SerializedFormSubmission, c as FormFailurePayload, i as FormSuccessPayload, g as FormSubmissionResult, I as InferFormData } from '../contracts-CJ9Aq8pS.js';
2
+ import { ValidationErrorBag, WebFileLike, ValidationSchema, SchemaInputShape, FieldBuilderInput, InferFieldOutput } from '@holo-js/validation';
4
3
 
5
4
  declare function collectFormDirtyPaths(current: unknown, initial: unknown, prefix?: string): readonly string[];
6
5
  declare class FormClientState<TValues, TSuccess = unknown> {
@@ -23,6 +22,10 @@ declare class FormClientState<TValues, TSuccess = unknown> {
23
22
 
24
23
  type PrimitiveLike = string | number | boolean | bigint | symbol | null | undefined | Date | Blob | WebFileLike;
25
24
  type ValidateOnMode = 'submit' | 'blur' | 'change';
25
+ type FormRequestCredentials = 'omit' | 'same-origin' | 'include';
26
+ interface ClientCsrfOptions {
27
+ readonly endpoint: string;
28
+ }
26
29
  interface ClientSubmitContext<TData> {
27
30
  readonly action?: string;
28
31
  readonly method: string;
@@ -41,6 +44,8 @@ type BrowserFormElement = {
41
44
  interface UseFormOptions<TData, TSuccess = unknown> {
42
45
  readonly action?: string;
43
46
  readonly method?: string;
47
+ readonly credentials?: FormRequestCredentials;
48
+ readonly csrf?: ClientCsrfOptions;
44
49
  readonly validateOn?: ValidateOnMode;
45
50
  readonly initialValues?: Partial<TData>;
46
51
  readonly initialState?: SerializedFormSubmission<TData> | FormFailurePayload<TData> | null;
@@ -63,7 +68,7 @@ type FormFieldTree<TData> = [TData] extends [readonly unknown[]] ? FormFieldStat
63
68
  type FormFieldTreeFromShape<TShape extends SchemaInputShape> = {
64
69
  readonly [K in Extract<keyof TShape, string>]: TShape[K] extends FieldBuilderInput ? FormFieldState<InferFieldOutput<TShape[K]>> : TShape[K] extends SchemaInputShape ? FormFieldTreeFromShape<TShape[K]> : never;
65
70
  };
66
- type InferFormFieldTree<TSchema extends FormSchema> = TSchema extends FormSchema<infer TShape> ? FormFieldTreeFromShape<TShape> : never;
71
+ type InferFormFieldTree<TSchema extends ValidationSchema> = TSchema extends ValidationSchema<infer TShape> ? FormFieldTreeFromShape<TShape> : never;
67
72
  interface UseFormResult<TData, TSuccess = unknown, TFields = FormFieldTree<TData>> {
68
73
  readonly fields: TFields;
69
74
  readonly values: TData;
@@ -83,6 +88,6 @@ declare function runWithBrowserFormElement<TData, TSuccess>(formClient: Pick<Use
83
88
  /**
84
89
  * @internal Shared headless form runtime for framework adapters.
85
90
  */
86
- declare function createFormClient<TSchema extends FormSchema, TSuccess = unknown>(schemaDefinition: TSchema, options?: UseFormOptions<InferFormData<TSchema>, TSuccess>): UseFormResult<InferFormData<TSchema>, TSuccess, InferFormFieldTree<TSchema>>;
91
+ declare function createFormClient<TSchema extends ValidationSchema, TSuccess = unknown>(schemaDefinition: TSchema, options?: UseFormOptions<InferFormData<TSchema>, TSuccess>): UseFormResult<InferFormData<TSchema>, TSuccess, InferFormFieldTree<TSchema>>;
87
92
 
88
- export { type ClientSubmitContext, type ClientSubmitResult, FormClientState, type FormFieldState, type FormFieldTree, type InferFormFieldTree, type UseFormOptions, type UseFormResult, type ValidateOnMode, collectFormDirtyPaths, createFormClient, markClientSubmitControlFlowError, runWithBrowserFormElement };
93
+ export { type ClientCsrfOptions, type ClientSubmitContext, type ClientSubmitResult, FormClientState, type FormFieldState, type FormFieldTree, type FormRequestCredentials, type InferFormFieldTree, type UseFormOptions, type UseFormResult, type ValidateOnMode, collectFormDirtyPaths, createFormClient, markClientSubmitControlFlowError, runWithBrowserFormElement };
@@ -601,7 +601,7 @@ function normalizeSubmissionLike(schemaDefinition, values, result) {
601
601
  valid: false,
602
602
  values: result.values,
603
603
  errors: result.errors,
604
- ...result.status === 429 && "retryAfter" in result ? { retryAfter: result.retryAfter } : {},
604
+ ...result.status === 429 && "retryAfterSeconds" in result ? { retryAfterSeconds: result.retryAfterSeconds } : {},
605
605
  ...result.status === 429 && "retryAt" in result ? { retryAt: result.retryAt } : {}
606
606
  };
607
607
  }
@@ -659,7 +659,7 @@ async function normalizeFetchResponse(response, fallbackValues) {
659
659
  return createTransportFailure(fallbackValues, response.status);
660
660
  }
661
661
  }
662
- async function defaultSubmitter(context) {
662
+ async function defaultSubmitter(context, options) {
663
663
  if (typeof fetch !== "function" || !context.action) {
664
664
  return {
665
665
  ok: true,
@@ -668,9 +668,11 @@ async function defaultSubmitter(context) {
668
668
  };
669
669
  }
670
670
  const method = context.method.toUpperCase();
671
+ const credentials = options.credentials ? { credentials: options.credentials } : {};
671
672
  if (method === "GET" || method === "HEAD") {
672
673
  const response2 = await fetch(appendQueryString(context.action, context.formData), {
673
- method
674
+ method,
675
+ ...credentials
674
676
  });
675
677
  if (method === "HEAD" || response2.status === 204 || response2.status === 205) {
676
678
  return {
@@ -681,8 +683,24 @@ async function defaultSubmitter(context) {
681
683
  }
682
684
  return await normalizeFetchResponse(response2, context.values);
683
685
  }
686
+ const headers = new Headers();
687
+ if (options.csrf) {
688
+ const csrfResponse = await fetch(options.csrf.endpoint, {
689
+ ...credentials
690
+ });
691
+ if (!csrfResponse.ok) {
692
+ return createTransportFailure(context.values, csrfResponse.status);
693
+ }
694
+ const csrfPayload = await csrfResponse.json();
695
+ if (!csrfPayload || typeof csrfPayload !== "object" || !("token" in csrfPayload) || typeof csrfPayload.token !== "string" || !csrfPayload.token) {
696
+ return createTransportFailure(context.values);
697
+ }
698
+ headers.set("X-CSRF-TOKEN", csrfPayload.token);
699
+ }
684
700
  const response = await fetch(context.action, {
685
701
  method,
702
+ ...credentials,
703
+ ...options.csrf ? { headers } : {},
686
704
  body: context.formData
687
705
  });
688
706
  return await normalizeFetchResponse(response, context.values);
@@ -758,7 +776,7 @@ function createFormClient(schemaDefinition, options = {}) {
758
776
  const finishSubmission = state.startSubmission();
759
777
  notifyListeners(state);
760
778
  try {
761
- const submitter = options.submitter ?? defaultSubmitter;
779
+ const submitter = options.submitter ?? ((context) => defaultSubmitter(context, options));
762
780
  const liveForm = browserForm ?? getActiveElementBrowserForm();
763
781
  const method = options.method ?? liveForm?.method ?? "POST";
764
782
  const action = options.action ?? liveForm?.action;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holo-js/forms",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "Holo-JS Framework - forms-first validation and submission contracts",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,11 +10,6 @@
10
10
  "import": "./dist/index.mjs",
11
11
  "default": "./dist/index.mjs"
12
12
  },
13
- "./schema": {
14
- "types": "./dist/schema.d.ts",
15
- "import": "./dist/schema.mjs",
16
- "default": "./dist/schema.mjs"
17
- },
18
13
  "./internal/client": {
19
14
  "types": "./dist/internal/client.d.ts",
20
15
  "import": "./dist/internal/client.mjs",
@@ -33,10 +28,10 @@
33
28
  "test": "vitest --run"
34
29
  },
35
30
  "dependencies": {
36
- "@holo-js/validation": "^0.3.15"
31
+ "@holo-js/validation": "^0.3.16"
37
32
  },
38
33
  "peerDependencies": {
39
- "@holo-js/security": "^0.3.15"
34
+ "@holo-js/security": "^0.3.16"
40
35
  },
41
36
  "peerDependenciesMeta": {
42
37
  "@holo-js/security": {
@@ -50,6 +45,6 @@
50
45
  "vitest": "^4.1.5"
51
46
  },
52
47
  "engines": {
53
- "node": ">=22.12.0"
48
+ "node": "^22.12.0 || ^24.0.0 || ^26.0.0"
54
49
  }
55
50
  }
@@ -1,40 +0,0 @@
1
- // src/schema.ts
2
- import {
3
- defineSchema,
4
- isValidationSchema
5
- } from "@holo-js/validation";
6
- import {
7
- createErrorBag,
8
- DEFAULT_VALIDATION_BAG,
9
- defineSchema as defineSchema2,
10
- field,
11
- isValidationException,
12
- parse,
13
- safeParse,
14
- ValidationException,
15
- validationInternals
16
- } from "@holo-js/validation";
17
- function schema(shapeOrSchema) {
18
- const base = isValidationSchema(shapeOrSchema) ? shapeOrSchema : defineSchema(shapeOrSchema);
19
- return Object.freeze({
20
- ...base,
21
- mode: "form"
22
- });
23
- }
24
- function isFormSchema(value) {
25
- return isValidationSchema(value) && value.mode === "form";
26
- }
27
-
28
- export {
29
- schema,
30
- isFormSchema,
31
- createErrorBag,
32
- DEFAULT_VALIDATION_BAG,
33
- defineSchema2 as defineSchema,
34
- field,
35
- isValidationException,
36
- parse,
37
- safeParse,
38
- ValidationException,
39
- validationInternals
40
- };
package/dist/schema.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { SchemaInputShape, ValidationSchema, InferSchemaData } from '@holo-js/validation';
2
- export { DEFAULT_VALIDATION_BAG, ErrorTree, ErrorTreeNode, FieldDefinition, FieldRule, InferSchemaData, SerializedValidationException, StandardSchemaV1, StandardSchemaV1Issue, StandardSchemaV1Props, StandardSchemaV1Result, ValidationErrorBag, ValidationException, ValidationExceptionOptions, ValidationFailure, ValidationResult, ValidationSchema, ValidationSuccess, WebFileLike, createErrorBag, defineSchema, field, isValidationException, parse, safeParse, validationInternals } from '@holo-js/validation';
3
-
4
- interface FormSchema<TShape extends SchemaInputShape = SchemaInputShape> extends ValidationSchema<TShape> {
5
- readonly mode: 'form';
6
- readonly fields: ValidationSchema<TShape>['fields'];
7
- readonly $values?: Partial<InferSchemaData<TShape>>;
8
- }
9
- type InferFormData<TSchema extends FormSchema> = TSchema extends FormSchema<infer TShape> ? InferSchemaData<TShape> : never;
10
- declare function schema<TShape extends SchemaInputShape>(shapeOrSchema: TShape | ValidationSchema<TShape>): FormSchema<TShape>;
11
- declare function isFormSchema(value: unknown): value is FormSchema;
12
-
13
- export { type FormSchema, type InferFormData, isFormSchema, schema };
package/dist/schema.mjs DELETED
@@ -1,26 +0,0 @@
1
- import {
2
- DEFAULT_VALIDATION_BAG,
3
- ValidationException,
4
- createErrorBag,
5
- defineSchema,
6
- field,
7
- isFormSchema,
8
- isValidationException,
9
- parse,
10
- safeParse,
11
- schema,
12
- validationInternals
13
- } from "./chunk-GPWXGHZE.mjs";
14
- export {
15
- DEFAULT_VALIDATION_BAG,
16
- ValidationException,
17
- createErrorBag,
18
- defineSchema,
19
- field,
20
- isFormSchema,
21
- isValidationException,
22
- parse,
23
- safeParse,
24
- schema,
25
- validationInternals
26
- };