@duffcloudservices/site-forms 0.1.1 → 0.1.3
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 +274 -260
- package/dist/composables/useFormSubmission.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +554 -398
- package/dist/index.js.map +1 -1
- package/dist/presets.d.ts +13 -0
- package/dist/site-forms.css +1 -0
- package/dist/types.d.ts +12 -2
- package/package.json +72 -73
- package/src/DcsForm.vue +295 -303
- package/src/__tests__/fields.test.ts +81 -82
- package/src/__tests__/multi-step.test.ts +45 -46
- package/src/__tests__/presets.test.ts +64 -0
- package/src/__tests__/schema.test.ts +41 -42
- package/src/__tests__/style-import.test.ts +9 -0
- package/src/__tests__/submission.test.ts +115 -77
- package/src/__tests__/validation.test.ts +29 -0
- package/src/__tests__/visible-if.test.ts +110 -111
- package/src/composables/useDcsForm.ts +201 -201
- package/src/composables/useFormSubmission.ts +113 -113
- package/src/composables/useFormValidation.ts +128 -127
- package/src/fields/DcsFormCheckbox.vue +35 -35
- package/src/fields/DcsFormCheckboxGroup.vue +52 -52
- package/src/fields/DcsFormDate.vue +34 -34
- package/src/fields/DcsFormFieldWrapper.vue +39 -39
- package/src/fields/DcsFormFile.vue +38 -38
- package/src/fields/DcsFormHidden.vue +17 -17
- package/src/fields/DcsFormHtmlBlock.vue +19 -19
- package/src/fields/DcsFormRadio.vue +45 -45
- package/src/fields/DcsFormSection.vue +19 -19
- package/src/fields/DcsFormSelect.vue +62 -62
- package/src/fields/DcsFormText.vue +54 -54
- package/src/fields/DcsFormTextarea.vue +43 -43
- package/src/index.ts +64 -51
- package/src/loaders/yaml.ts +51 -51
- package/src/presets.ts +192 -0
- package/src/schema/form-definition.schema.json +410 -45
- package/src/schema/validate.ts +58 -58
- package/src/shims.d.ts +10 -10
- package/src/style.css +256 -0
- package/src/types.ts +164 -140
package/README.md
CHANGED
|
@@ -1,260 +1,274 @@
|
|
|
1
|
-
# @duffcloudservices/site-forms
|
|
2
|
-
|
|
3
|
-
Shared `<DcsForm/>` runtime for DCS customer sites. Renders a managed
|
|
4
|
-
form definition (created in the portal Form Manager) from a build-time
|
|
5
|
-
`.dcs/forms/<formId>.yaml` snapshot, validates user input, and posts
|
|
6
|
-
submissions to the public site-forms API.
|
|
7
|
-
|
|
8
|
-
This is the single import surface for managed-form runtime code on
|
|
9
|
-
customer sites — do not redefine field components per site.
|
|
10
|
-
|
|
11
|
-
> **Inside the `dcs-again` workspace** the package is also reachable
|
|
12
|
-
> as `@duffcloudservices/site-forms` via `workspace:*` (the workspace
|
|
13
|
-
> name and the published name are the same).
|
|
14
|
-
> **In sibling customer-site repos** install the published package
|
|
15
|
-
> from public npm — see [`PUBLISHING.md`](./PUBLISHING.md) for the
|
|
16
|
-
> consumption story and registry setup.
|
|
17
|
-
|
|
18
|
-
## Install
|
|
19
|
-
|
|
20
|
-
### In a workspace app (inside `dcs-again`)
|
|
21
|
-
|
|
22
|
-
```jsonc
|
|
23
|
-
// portal/package.json
|
|
24
|
-
{
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"@duffcloudservices/site-forms": "workspace:*"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Then `pnpm install` from the repo root.
|
|
32
|
-
|
|
33
|
-
### In a sibling customer-site repo (e.g. `ktbraunlaw`, `kept`)
|
|
34
|
-
|
|
35
|
-
```powershell
|
|
36
|
-
pnpm add @duffcloudservices/site-forms
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
See [`PUBLISHING.md`](./PUBLISHING.md) for the registry, version, and
|
|
40
|
-
release-workflow details.
|
|
41
|
-
|
|
42
|
-
## Vite setup
|
|
43
|
-
|
|
44
|
-
Three pieces are required in the consuming site:
|
|
45
|
-
|
|
46
|
-
1. **`vite-plugin-yaml`** so YAML modules return parsed objects:
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
// vite.config.ts
|
|
50
|
-
import yaml from '@modyfi/vite-plugin-yaml'
|
|
51
|
-
|
|
52
|
-
export default defineConfig({
|
|
53
|
-
plugins: [vue(), yaml()],
|
|
54
|
-
})
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Without it, the loader falls back to parsing raw strings via
|
|
58
|
-
`js-yaml`, which works but pays the parse cost at boot.
|
|
59
|
-
|
|
60
|
-
2. **A `formsModules` loader** in your site that does the
|
|
61
|
-
`import.meta.glob` from a path Vite can resolve (see below).
|
|
62
|
-
|
|
63
|
-
3. **Env vars** the runtime reads:
|
|
64
|
-
|
|
65
|
-
| Variable | Purpose |
|
|
66
|
-
| ----------------------- | ---------------------------------------------------- |
|
|
67
|
-
| `VITE_DCS_PUBLIC_API` | Base URL of the DCS public API (no trailing slash). |
|
|
68
|
-
| `VITE_DCS_SITE_SLUG` | Default site slug used when the prop is omitted. |
|
|
69
|
-
|
|
70
|
-
### Why the `formsModules` prop is required in real sites
|
|
71
|
-
|
|
72
|
-
`<DcsForm/>` ships with an internal `import.meta.glob('/.dcs/forms/*.yaml')`
|
|
73
|
-
fallback, but Vite resolves the leading `/` against the **consumer's
|
|
74
|
-
Vite project root** (the directory containing `vite.config.ts`).
|
|
75
|
-
On every customer-site repo today, the `.dcs/forms/` directory lives
|
|
76
|
-
at the **repo root**, one or more levels above the Vite root
|
|
77
|
-
(typically `site/` or `docs/`). The internal glob therefore matches
|
|
78
|
-
nothing and you get:
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
[@duffcloudservices/site-forms] No form definition found for "contact".
|
|
82
|
-
Expected a YAML at /.dcs/forms/contact.yaml.
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
The fix is a one-file loader the rest of your site imports from.
|
|
86
|
-
|
|
87
|
-
#### Vue SPA (`vite.config.ts` in `site/`)
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// site/src/dcs-forms.ts
|
|
91
|
-
const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
|
|
92
|
-
eager: true,
|
|
93
|
-
import: 'default',
|
|
94
|
-
})
|
|
95
|
-
export const dcsFormsModules: Record<string, unknown> = modules
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
#### VitePress (`vite` block in `docs/.vitepress/config.ts`)
|
|
99
|
-
|
|
100
|
-
```ts
|
|
101
|
-
// docs/.vitepress/dcs-forms-loader.ts
|
|
102
|
-
const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
|
|
103
|
-
eager: true,
|
|
104
|
-
import: 'default',
|
|
105
|
-
})
|
|
106
|
-
export const dcsFormsModules: Record<string, unknown> = modules
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The relative depth (`../../`) depends on where the loader file lives
|
|
110
|
-
relative to the repo root. Adjust as needed.
|
|
111
|
-
|
|
112
|
-
## Usage
|
|
113
|
-
|
|
114
|
-
Place a YAML file at `<site>/.dcs/forms/contact.yaml`:
|
|
115
|
-
|
|
116
|
-
```yaml
|
|
117
|
-
formId: contact
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
import {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
@submit-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
| `submit-
|
|
170
|
-
| `
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
strip
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
1
|
+
# @duffcloudservices/site-forms
|
|
2
|
+
|
|
3
|
+
Shared `<DcsForm/>` runtime for DCS customer sites. Renders a managed
|
|
4
|
+
form definition (created in the portal Form Manager) from a build-time
|
|
5
|
+
`.dcs/forms/<formId>.yaml` snapshot, validates user input, and posts
|
|
6
|
+
submissions to the public site-forms API.
|
|
7
|
+
|
|
8
|
+
This is the single import surface for managed-form runtime code on
|
|
9
|
+
customer sites — do not redefine field components per site.
|
|
10
|
+
|
|
11
|
+
> **Inside the `dcs-again` workspace** the package is also reachable
|
|
12
|
+
> as `@duffcloudservices/site-forms` via `workspace:*` (the workspace
|
|
13
|
+
> name and the published name are the same).
|
|
14
|
+
> **In sibling customer-site repos** install the published package
|
|
15
|
+
> from public npm — see [`PUBLISHING.md`](./PUBLISHING.md) for the
|
|
16
|
+
> consumption story and registry setup.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
### In a workspace app (inside `dcs-again`)
|
|
21
|
+
|
|
22
|
+
```jsonc
|
|
23
|
+
// portal/package.json
|
|
24
|
+
{
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@duffcloudservices/site-forms": "workspace:*"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then `pnpm install` from the repo root.
|
|
32
|
+
|
|
33
|
+
### In a sibling customer-site repo (e.g. `ktbraunlaw`, `kept`)
|
|
34
|
+
|
|
35
|
+
```powershell
|
|
36
|
+
pnpm add @duffcloudservices/site-forms
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
See [`PUBLISHING.md`](./PUBLISHING.md) for the registry, version, and
|
|
40
|
+
release-workflow details.
|
|
41
|
+
|
|
42
|
+
## Vite setup
|
|
43
|
+
|
|
44
|
+
Three pieces are required in the consuming site:
|
|
45
|
+
|
|
46
|
+
1. **`vite-plugin-yaml`** so YAML modules return parsed objects:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// vite.config.ts
|
|
50
|
+
import yaml from '@modyfi/vite-plugin-yaml'
|
|
51
|
+
|
|
52
|
+
export default defineConfig({
|
|
53
|
+
plugins: [vue(), yaml()],
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Without it, the loader falls back to parsing raw strings via
|
|
58
|
+
`js-yaml`, which works but pays the parse cost at boot.
|
|
59
|
+
|
|
60
|
+
2. **A `formsModules` loader** in your site that does the
|
|
61
|
+
`import.meta.glob` from a path Vite can resolve (see below).
|
|
62
|
+
|
|
63
|
+
3. **Env vars** the runtime reads:
|
|
64
|
+
|
|
65
|
+
| Variable | Purpose |
|
|
66
|
+
| ----------------------- | ---------------------------------------------------- |
|
|
67
|
+
| `VITE_DCS_PUBLIC_API` | Base URL of the DCS public API (no trailing slash). |
|
|
68
|
+
| `VITE_DCS_SITE_SLUG` | Default site slug used when the prop is omitted. |
|
|
69
|
+
|
|
70
|
+
### Why the `formsModules` prop is required in real sites
|
|
71
|
+
|
|
72
|
+
`<DcsForm/>` ships with an internal `import.meta.glob('/.dcs/forms/*.yaml')`
|
|
73
|
+
fallback, but Vite resolves the leading `/` against the **consumer's
|
|
74
|
+
Vite project root** (the directory containing `vite.config.ts`).
|
|
75
|
+
On every customer-site repo today, the `.dcs/forms/` directory lives
|
|
76
|
+
at the **repo root**, one or more levels above the Vite root
|
|
77
|
+
(typically `site/` or `docs/`). The internal glob therefore matches
|
|
78
|
+
nothing and you get:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
[@duffcloudservices/site-forms] No form definition found for "contact".
|
|
82
|
+
Expected a YAML at /.dcs/forms/contact.yaml.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The fix is a one-file loader the rest of your site imports from.
|
|
86
|
+
|
|
87
|
+
#### Vue SPA (`vite.config.ts` in `site/`)
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// site/src/dcs-forms.ts
|
|
91
|
+
const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
|
|
92
|
+
eager: true,
|
|
93
|
+
import: 'default',
|
|
94
|
+
})
|
|
95
|
+
export const dcsFormsModules: Record<string, unknown> = modules
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### VitePress (`vite` block in `docs/.vitepress/config.ts`)
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
// docs/.vitepress/dcs-forms-loader.ts
|
|
102
|
+
const modules = import.meta.glob('../../.dcs/forms/*.yaml', {
|
|
103
|
+
eager: true,
|
|
104
|
+
import: 'default',
|
|
105
|
+
})
|
|
106
|
+
export const dcsFormsModules: Record<string, unknown> = modules
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The relative depth (`../../`) depends on where the loader file lives
|
|
110
|
+
relative to the repo root. Adjust as needed.
|
|
111
|
+
|
|
112
|
+
## Usage
|
|
113
|
+
|
|
114
|
+
Place a YAML file at `<site>/.dcs/forms/contact.yaml`:
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
formId: contact
|
|
118
|
+
submission:
|
|
119
|
+
kind: lead
|
|
120
|
+
fields:
|
|
121
|
+
- id: name
|
|
122
|
+
type: text
|
|
123
|
+
label: Name
|
|
124
|
+
required: true
|
|
125
|
+
- id: email
|
|
126
|
+
type: email
|
|
127
|
+
label: Email
|
|
128
|
+
required: true
|
|
129
|
+
- id: message
|
|
130
|
+
type: textarea
|
|
131
|
+
label: Message
|
|
132
|
+
required: true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Then in any page component:
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<script setup lang="ts">
|
|
139
|
+
import { DcsForm } from '@duffcloudservices/site-forms'
|
|
140
|
+
import { dcsFormsModules } from '@/dcs-forms'
|
|
141
|
+
</script>
|
|
142
|
+
|
|
143
|
+
<template>
|
|
144
|
+
<DcsForm
|
|
145
|
+
form-id="contact"
|
|
146
|
+
:forms-modules="dcsFormsModules"
|
|
147
|
+
@submit-success="onSuccess"
|
|
148
|
+
@submit-error="onError"
|
|
149
|
+
/>
|
|
150
|
+
</template>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Props
|
|
154
|
+
|
|
155
|
+
| Prop | Type | Default | Notes |
|
|
156
|
+
| -------------------- | --------------------------------- | -------------------------------------- | ----------------------------------------------------------- |
|
|
157
|
+
| `formId` | `string` (required) | — | Matches `.dcs/forms/<formId>.yaml`. |
|
|
158
|
+
| `siteSlug` | `string` | `import.meta.env.VITE_DCS_SITE_SLUG` | Path segment in the submission URL. |
|
|
159
|
+
| `definitionOverride` | `PortalFormDefinition` | — | Used by the portal preview iframe to show in-flight edits. |
|
|
160
|
+
| `apiBase` | `string` | `import.meta.env.VITE_DCS_PUBLIC_API` | Override for tests / non-prod environments. |
|
|
161
|
+
| `captchaToken` | `string` | — | Attached to the submission payload when set. |
|
|
162
|
+
| `formsModules` | `Record<string, unknown>` | internal fallback glob (rarely matches) | **Required in real sites.** Pass a `Record<string, unknown>` from your own `import.meta.glob('../../.dcs/forms/*.yaml', { eager: true, import: 'default' })` — see Vite setup section. |
|
|
163
|
+
|
|
164
|
+
## Emits
|
|
165
|
+
|
|
166
|
+
| Event | Payload | When |
|
|
167
|
+
| ------------------ | ---------------------- | ------------------------------------------- |
|
|
168
|
+
| `submit-success` | `DcsFormSubmitSuccess` | API responded `2xx`. |
|
|
169
|
+
| `submit-error` | `DcsFormSubmitError` | Network or non-2xx response after retries. |
|
|
170
|
+
| `validation-error` | `FormErrors` | Submit attempted with invalid required/regex/etc. fields. |
|
|
171
|
+
|
|
172
|
+
## Slots
|
|
173
|
+
|
|
174
|
+
Every slot exposes scoped data so consumers (KT Braun, Kept) can swap
|
|
175
|
+
shadcn primitives in without forking field components.
|
|
176
|
+
|
|
177
|
+
| Slot | Scope | Default |
|
|
178
|
+
| ---------- | ------------------------------------------------------------------ | ---------------------------------------------------- |
|
|
179
|
+
| `header` | `{ definition }` | Empty; page/section headings live outside the managed form |
|
|
180
|
+
| `progress` | `{ current, total, step }` | `Step N of M — Title` (multi-step only) |
|
|
181
|
+
| `actions` | `{ isFirstStep, isLastStep, submitting, prev, next }` | Plain `<button>` elements |
|
|
182
|
+
| `success` | `{ definition }` | `definition.successMessage` |
|
|
183
|
+
| `missing` | `{ formId }` | Friendly fallback when the YAML can't be found |
|
|
184
|
+
|
|
185
|
+
Per-field components (`DcsFormText` etc.) expose `#input` slots so a
|
|
186
|
+
shadcn site can replace the underlying primitive while keeping the
|
|
187
|
+
wrapper, label, help, and error-message structure.
|
|
188
|
+
|
|
189
|
+
## Composables
|
|
190
|
+
|
|
191
|
+
For sites that want a fully custom layout, drop `<DcsForm/>` and use
|
|
192
|
+
the underlying composables directly:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import {
|
|
196
|
+
useDcsForm,
|
|
197
|
+
validateForm,
|
|
198
|
+
submitFormValues,
|
|
199
|
+
parseFormYaml,
|
|
200
|
+
} from '@duffcloudservices/site-forms'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
- `useDcsForm({ definition })` — reactive `values`, `errors`, `steps`,
|
|
204
|
+
`next`, `prev`, `validateAll`, `collectSubmissionValues`, etc.
|
|
205
|
+
- `validateForm(def, values, fieldIds?)` — pure validator usable in
|
|
206
|
+
any setting (server-side, tests, custom adapters).
|
|
207
|
+
- `submitFormValues({ apiBase, siteSlug, payload })` — one-shot POST
|
|
208
|
+
with a single retry on 5xx and `multipart/form-data` when files are
|
|
209
|
+
present.
|
|
210
|
+
|
|
211
|
+
## Visual editor integration
|
|
212
|
+
|
|
213
|
+
The form root carries `data-form-key="<formId>"` and every field
|
|
214
|
+
wrapper carries `data-form-field-key="<fieldId>"`. The portal preview
|
|
215
|
+
iframe bridge uses these to discover managed forms, show the preview
|
|
216
|
+
affordance, and route preview click / context-menu actions into the same
|
|
217
|
+
portal `FormManagerSheet`. Do not strip these attributes in custom
|
|
218
|
+
layouts.
|
|
219
|
+
|
|
220
|
+
`definitionOverride` is a preview-only draft path for the iframe. The
|
|
221
|
+
durable form truth still lives in the form definition saved by the
|
|
222
|
+
portal and in the committed `.dcs/forms/<formId>.yaml` snapshot consumed
|
|
223
|
+
by the site runtime.
|
|
224
|
+
|
|
225
|
+
For the cross-package first-party component contract (runtime markers,
|
|
226
|
+
bridge discovery, portal entry points, rollout, validation), see
|
|
227
|
+
[`../FIRST-PARTY-COMPONENTS.md`](../FIRST-PARTY-COMPONENTS.md).
|
|
228
|
+
|
|
229
|
+
## Schema validation
|
|
230
|
+
|
|
231
|
+
In dev (`import.meta.env.DEV === true`) the runtime validates each
|
|
232
|
+
loaded definition against the JSON Schema bundled in
|
|
233
|
+
`src/schema/form-definition.schema.json` (snapshot of
|
|
234
|
+
`contracts/dist/form-definition.schema.json`) and logs failures via
|
|
235
|
+
`console.warn`. Production builds skip the warning to avoid noisy
|
|
236
|
+
end-user consoles.
|
|
237
|
+
|
|
238
|
+
When the contracts schema is regenerated (`pnpm --filter @dcs/contracts
|
|
239
|
+
generate`), refresh the snapshot:
|
|
240
|
+
|
|
241
|
+
```powershell
|
|
242
|
+
Copy-Item ../../contracts/dist/form-definition.schema.json ./src/schema/form-definition.schema.json -Force
|
|
243
|
+
pnpm --filter @duffcloudservices/site-forms test --run
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Scripts
|
|
247
|
+
|
|
248
|
+
```powershell
|
|
249
|
+
pnpm --filter @duffcloudservices/site-forms build # vite library build (esm + dts)
|
|
250
|
+
pnpm --filter @duffcloudservices/site-forms test # vitest --run
|
|
251
|
+
pnpm --filter @duffcloudservices/site-forms type-check # vue-tsc --noEmit
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Related docs
|
|
255
|
+
|
|
256
|
+
- **Authoring guide** — [`.docs/forms/AUTHORING.md`](../../.docs/forms/AUTHORING.md)
|
|
257
|
+
covers the YAML schema, worked examples, validation flow, HIPAA
|
|
258
|
+
guardrails, and the hand-coded → `<DcsForm/>` migration recipe.
|
|
259
|
+
- **Publishing** — [`PUBLISHING.md`](./PUBLISHING.md) covers the
|
|
260
|
+
registry, OIDC trusted publishing, version bump policy, and the
|
|
261
|
+
exact dep line sibling customer-site repos should add.
|
|
262
|
+
- **First-party visual-editor contract** —
|
|
263
|
+
[`../FIRST-PARTY-COMPONENTS.md`](../FIRST-PARTY-COMPONENTS.md)
|
|
264
|
+
captures the shared adaptation model used by forms and future
|
|
265
|
+
component families.
|
|
266
|
+
- **Validation CLI** — [`cli/forms/README.md`](../../cli/forms/README.md)
|
|
267
|
+
documents `dcs forms validate` and `dcs forms doctor`, which lint
|
|
268
|
+
the `.dcs/forms/*.yaml` files in a customer-site repo.
|
|
269
|
+
|
|
270
|
+
## Ownership
|
|
271
|
+
|
|
272
|
+
Per `packages/README.md`: external/consumer-facing docs live here, not
|
|
273
|
+
in repo-root docs. Cross-cutting details (e.g. the public submissions
|
|
274
|
+
API contract) belong in `contracts/README.md`.
|
|
@@ -10,7 +10,7 @@ export interface SubmitOptions {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* POSTs a form submission to
|
|
13
|
-
* `${apiBase}/
|
|
13
|
+
* `${apiBase}/sites/{siteSlug}/forms/{formId}/submissions`.
|
|
14
14
|
*
|
|
15
15
|
* Uses JSON for plain values and `multipart/form-data` when any
|
|
16
16
|
* value is a `File` (file-upload fields).
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export { validateField, validateForm, isFieldVisible, hasErrors, } from './compo
|
|
|
17
17
|
export { submitFormValues } from './composables/useFormSubmission';
|
|
18
18
|
export type { SubmitOptions } from './composables/useFormSubmission';
|
|
19
19
|
export { loadFormDefinitions, parseFormYaml } from './loaders/yaml';
|
|
20
|
+
export { buildStandardFormDefinition, STANDARD_FORM_PRESET_META, } from './presets';
|
|
21
|
+
export type { StandardFormPreset, BuildStandardFormOptions, } from './presets';
|
|
20
22
|
export { validateFormDefinition, warnIfInvalid, } from './schema/validate';
|
|
21
23
|
export type { SchemaValidationResult } from './schema/validate';
|
|
22
|
-
export type { DcsFormSubmitPayload, DcsFormSubmitSuccess, DcsFormSubmitError, FormErrors, FormValues, PortalFormDefinition, PortalFormField, PortalFormFieldType, PortalFormFieldOption, PortalFormFieldValidation, PortalFormFieldVisibleIf, PortalFormFieldWidth, PortalFormStep, PortalFormSubmissionConfig, PortalFormSubmissionLeadConfig, PortalFormSubmissionEmailConfig, PortalFormSubmissionWebhookConfig, } from './types';
|
|
24
|
+
export type { DcsFormSubmitPayload, DcsFormSubmitSuccess, DcsFormSubmitError, FormErrors, FormValues, PortalFormDefinition, PortalFormField, PortalFormKind, PortalFormFieldRole, PortalFormAttachmentPolicy, PortalFormFieldType, PortalFormFieldOption, PortalFormFieldValidation, PortalFormFieldVisibleIf, PortalFormFieldWidth, PortalFormStep, PortalFormSubmissionConfig, PortalFormSubmissionLeadConfig, PortalFormSubmissionEmailConfig, PortalFormSubmissionWebhookConfig, } from './types';
|