@stacksjs/forms 0.72.8 → 0.72.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.
@@ -0,0 +1,50 @@
1
+ import type { FormDefinition, FormFieldDefinition, FormFieldType, FormSettings } from './types';
2
+ /**
3
+ * Create or update a form and its fields for one site.
4
+ *
5
+ * Fields are REPLACED rather than merged: a form's fields are a single
6
+ * document in every editor that exists, and merging them by name would leave
7
+ * a removed field behind on the next provision.
8
+ */
9
+ export declare function createForm(siteId: number | null, input: CreateFormInput): Promise<CreatedForm>;
10
+ /** Load a form by its site-scoped handle, the way app code refers to one. */
11
+ export declare function loadFormByHandle(siteId: number | null, handle: string): Promise<FormDefinition | null>;
12
+ /** The field list as `createForm` takes it, for a definition already loaded. */
13
+ export declare function toCreateFields(fields: FormFieldDefinition[]): CreateFormFieldInput[];
14
+ /**
15
+ * Creating a form.
16
+ *
17
+ * The package could read a form, validate a submission against it, notify on
18
+ * it and export it - but not make one. Every app that wanted a form in code
19
+ * (a seeder, an onboarding step, a "give this tenant the standard enquiry
20
+ * form" button) had to write the Form + FormField inserts itself, which means
21
+ * every app also had to know that `options` and `conditions` are JSON columns
22
+ * and that fields carry their own `position`.
23
+ *
24
+ * `handle` is the identity, scoped to the site (there is a unique index on
25
+ * `site_id, handle`), so this is idempotent: provisioning the same form twice
26
+ * updates the one that exists rather than failing on the constraint or
27
+ * quietly making a second.
28
+ */
29
+ export declare interface CreateFormFieldInput {
30
+ name: string
31
+ label: string
32
+ type: FormFieldType
33
+ required?: boolean
34
+ width?: 'full' | 'half'
35
+ options?: Record<string, unknown>
36
+ conditions?: Record<string, unknown> | null
37
+ }
38
+ export declare interface CreateFormInput {
39
+ handle: string
40
+ name: string
41
+ status?: 'draft' | 'active' | 'closed'
42
+ settings?: FormSettings
43
+ fields: CreateFormFieldInput[]
44
+ }
45
+ export declare interface CreatedForm {
46
+ id: number
47
+ uuid: string
48
+ handle: string
49
+ created: boolean
50
+ }
package/dist/create.js ADDED
@@ -0,0 +1 @@
1
+ import{db}from"@stacksjs/database";import{loadFormByUuid}from"./definition";export async function createForm(siteId,input){const existing=await db.selectFrom("forms").select(["id","uuid"]).where("handle","=",input.handle).where("site_id",siteId===null?"is":"=",siteId).executeTakeFirst(),settings=JSON.stringify(input.settings??{});let formId,uuid,created=!1;if(existing){formId=Number(existing.id);uuid=String(existing.uuid);await db.updateTable("forms").set({name:input.name,status:input.status??"active",settings}).where("id","=",formId).execute()}else{uuid=crypto.randomUUID();await db.insertInto("forms").values({uuid,site_id:siteId,name:input.name,handle:input.handle,status:input.status??"active",settings}).execute();const row=await db.selectFrom("forms").select(["id"]).where("uuid","=",uuid).executeTakeFirst();formId=Number(row?.id);created=!0}await db.deleteFrom("form_fields").where("form_id","=",formId).execute();let position=0;for(const field of input.fields)await db.insertInto("form_fields").values({form_id:formId,name:field.name,label:field.label,type:field.type,required:field.required??!1,position:position++,width:field.width??"full",options:JSON.stringify(field.options??{}),conditions:field.conditions?JSON.stringify(field.conditions):null}).execute();return{id:formId,uuid,handle:input.handle,created}}export async function loadFormByHandle(siteId,handle){const row=await db.selectFrom("forms").select(["uuid"]).where("handle","=",handle).where("site_id",siteId===null?"is":"=",siteId).executeTakeFirst();if(!row)return null;return await loadFormByUuid(String(row.uuid),siteId)}export function toCreateFields(fields){return fields.map((field)=>({name:field.name,label:field.label,type:field.type,required:field.required,width:field.width,options:field.options,conditions:field.conditions}))}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export type { CreatedForm, CreateFormFieldInput, CreateFormInput } from './create';
1
2
  export type { SubmissionListRow, SubmitOptions, SubmitResult } from './submissions';
2
3
  export type {
3
4
  FieldChoice,
@@ -11,6 +12,7 @@ export type {
11
12
  ValidateSubmissionResult,
12
13
  } from './types';
13
14
  export { evaluateConditions, visibleFields } from './conditions';
15
+ export { createForm, loadFormByHandle, toCreateFields } from './create';
14
16
  export { loadFormByUuid, publicDefinition } from './definition';
15
17
  export { dispatchSubmissionNotifications } from './notifications';
16
18
  export {
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{evaluateConditions,visibleFields}from"./conditions";export{loadFormByUuid,publicDefinition}from"./definition";export{dispatchSubmissionNotifications}from"./notifications";export{completeSubmissionPayment,exportSubmissionsCsv,fetchSubmissions,submitForm}from"./submissions";export{computeAmountCents,validateSubmission}from"./validate";
1
+ export{evaluateConditions,visibleFields}from"./conditions";export{createForm,loadFormByHandle,toCreateFields}from"./create";export{loadFormByUuid,publicDefinition}from"./definition";export{dispatchSubmissionNotifications}from"./notifications";export{completeSubmissionPayment,exportSubmissionsCsv,fetchSubmissions,submitForm}from"./submissions";export{computeAmountCents,validateSubmission}from"./validate";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/forms",
3
3
  "type": "module",
4
- "version": "0.72.8",
4
+ "version": "0.72.10",
5
5
  "description": "The Stacks form-builder functionality.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -56,11 +56,11 @@
56
56
  "prepublishOnly": "bun run build"
57
57
  },
58
58
  "devDependencies": {
59
- "@stacksjs/config": "0.72.8",
60
- "@stacksjs/database": "0.72.8",
61
- "@stacksjs/notifications": "0.72.8",
62
- "@stacksjs/storage": "0.72.8",
63
- "@stacksjs/validation": "0.72.8",
59
+ "@stacksjs/config": "0.72.10",
60
+ "@stacksjs/database": "0.72.10",
61
+ "@stacksjs/notifications": "0.72.10",
62
+ "@stacksjs/storage": "0.72.10",
63
+ "@stacksjs/validation": "0.72.10",
64
64
  "better-dx": "^0.2.23"
65
65
  },
66
66
  "sideEffects": false