docuseal-svelte 0.0.4 → 0.1.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/README.md +12 -0
- package/dist/components/DocuSealBuilder.svelte +52 -52
- package/dist/components/DocuSealBuilder.svelte.d.ts +8 -0
- package/dist/components/DocuSealForm.svelte +20 -25
- package/dist/components/DocuSealForm.svelte.d.ts +2 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -6
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/docuseal.d.ts +0 -50
- package/dist/utils/docuseal.js +4 -95
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -26,6 +26,18 @@ This package supports:
|
|
|
26
26
|
- Svelte 4.x
|
|
27
27
|
- Svelte 5.x
|
|
28
28
|
|
|
29
|
+
## Development
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm test # run the test suite once
|
|
33
|
+
npm run test:watch # re-run tests as you edit
|
|
34
|
+
npm run check # type-check the library and the tests
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Tests live in the top-level `tests/` directory rather than beside the source, because
|
|
38
|
+
`svelte-package` copies everything under `src/lib` into `dist`. `npm run prepack` fails if a
|
|
39
|
+
test file ever reaches the built package.
|
|
40
|
+
|
|
29
41
|
## How to Contribute
|
|
30
42
|
|
|
31
43
|
Contributions are welcome! Please fork the repository and create a pull request with your changes. Make sure to create a changeset for any significant updates.
|
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
withTitle = true,
|
|
15
15
|
withDocumentsList = true,
|
|
16
16
|
withFieldsList = true,
|
|
17
|
+
withFieldsDetection = false,
|
|
17
18
|
withFieldPlaceholder = false,
|
|
19
|
+
withDynamicDocuments = false,
|
|
20
|
+
withPrefillable = false,
|
|
21
|
+
withCustomFieldsTab = false,
|
|
22
|
+
withRevisions = false,
|
|
18
23
|
onlyDefinedFields = false,
|
|
19
24
|
preview = false,
|
|
20
25
|
previewMode = false,
|
|
@@ -27,6 +32,7 @@
|
|
|
27
32
|
fields = [],
|
|
28
33
|
submitters = [],
|
|
29
34
|
requiredFields = [],
|
|
35
|
+
dateFormats = [],
|
|
30
36
|
i18n = {},
|
|
31
37
|
withSignYourselfButton = true,
|
|
32
38
|
withUploadButton = true,
|
|
@@ -45,6 +51,7 @@
|
|
|
45
51
|
onSend = undefined,
|
|
46
52
|
onSave = undefined,
|
|
47
53
|
onChange = undefined,
|
|
54
|
+
onError = undefined,
|
|
48
55
|
}: {
|
|
49
56
|
token: string
|
|
50
57
|
host?: string
|
|
@@ -53,7 +60,12 @@
|
|
|
53
60
|
withTitle?: boolean
|
|
54
61
|
withDocumentsList?: boolean
|
|
55
62
|
withFieldsList?: boolean
|
|
63
|
+
withFieldsDetection?: boolean
|
|
56
64
|
withFieldPlaceholder?: boolean
|
|
65
|
+
withDynamicDocuments?: boolean
|
|
66
|
+
withPrefillable?: boolean
|
|
67
|
+
withCustomFieldsTab?: boolean
|
|
68
|
+
withRevisions?: boolean
|
|
57
69
|
onlyDefinedFields?: boolean
|
|
58
70
|
preview?: boolean
|
|
59
71
|
previewMode?: boolean
|
|
@@ -66,6 +78,7 @@
|
|
|
66
78
|
fields?: DocuSealBuilderField[]
|
|
67
79
|
submitters?: DocuSealBuilderSubmitter[]
|
|
68
80
|
requiredFields?: DocuSealBuilderField[]
|
|
81
|
+
dateFormats?: string[]
|
|
69
82
|
i18n?: object
|
|
70
83
|
withSignYourselfButton?: boolean
|
|
71
84
|
withUploadButton?: boolean
|
|
@@ -84,6 +97,7 @@
|
|
|
84
97
|
onSend?: ((detail: any) => void) | undefined
|
|
85
98
|
onSave?: ((detail: any) => void) | undefined
|
|
86
99
|
onChange?: ((detail: any) => void) | undefined
|
|
100
|
+
onError?: ((error: DocuSealError) => void) | undefined
|
|
87
101
|
} = $props()
|
|
88
102
|
|
|
89
103
|
let el = $state<HTMLElement | null>(null)
|
|
@@ -108,7 +122,6 @@
|
|
|
108
122
|
const scriptId = "docuseal-builder-script"
|
|
109
123
|
const scriptSrc = `https://${host}/js/builder.js`
|
|
110
124
|
|
|
111
|
-
// Check if script already exists
|
|
112
125
|
const existingScript = document.getElementById(scriptId)
|
|
113
126
|
if (existingScript) {
|
|
114
127
|
resolve()
|
|
@@ -125,8 +138,8 @@
|
|
|
125
138
|
reject(
|
|
126
139
|
new DocuSealError(
|
|
127
140
|
`Failed to load DocuSeal builder script from ${scriptSrc}`,
|
|
128
|
-
"SCRIPT_LOAD_ERROR"
|
|
129
|
-
)
|
|
141
|
+
"SCRIPT_LOAD_ERROR",
|
|
142
|
+
),
|
|
130
143
|
)
|
|
131
144
|
|
|
132
145
|
document.head.appendChild(script)
|
|
@@ -134,55 +147,39 @@
|
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
const setupEventListeners = (element: HTMLElement): (() => void) => {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const handleUpload = (e: Event) => {
|
|
144
|
-
if (onUpload && e instanceof CustomEvent) {
|
|
145
|
-
onUpload(e.detail)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const handleSend = (e: Event) => {
|
|
150
|
-
if (onSend && e instanceof CustomEvent) {
|
|
151
|
-
onSend(e.detail)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const handleSave = (e: Event) => {
|
|
156
|
-
if (onSave && e instanceof CustomEvent) {
|
|
157
|
-
onSave(e.detail)
|
|
158
|
-
}
|
|
150
|
+
const handlers: Record<string, ((detail: any) => void) | undefined> = {
|
|
151
|
+
load: onLoad,
|
|
152
|
+
upload: onUpload,
|
|
153
|
+
send: onSend,
|
|
154
|
+
save: onSave,
|
|
155
|
+
change: onChange,
|
|
159
156
|
}
|
|
160
157
|
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
158
|
+
const removers = Object.entries(handlers).map(([eventName, handler]) => {
|
|
159
|
+
const listener = (e: Event) => {
|
|
160
|
+
if (handler && e instanceof CustomEvent) {
|
|
161
|
+
handler(e.detail)
|
|
162
|
+
}
|
|
164
163
|
}
|
|
165
|
-
}
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
element.addEventListener("save", handleSave)
|
|
171
|
-
element.addEventListener("change", handleChange)
|
|
165
|
+
element.addEventListener(eventName, listener)
|
|
166
|
+
return () => element.removeEventListener(eventName, listener)
|
|
167
|
+
})
|
|
172
168
|
|
|
173
|
-
|
|
174
|
-
return () => {
|
|
175
|
-
element.removeEventListener("load", handleLoad)
|
|
176
|
-
element.removeEventListener("upload", handleUpload)
|
|
177
|
-
element.removeEventListener("send", handleSend)
|
|
178
|
-
element.removeEventListener("save", handleSave)
|
|
179
|
-
element.removeEventListener("change", handleChange)
|
|
180
|
-
}
|
|
169
|
+
return () => removers.forEach((remove) => remove())
|
|
181
170
|
}
|
|
182
171
|
|
|
172
|
+
const asDocuSealError = (error: unknown): DocuSealError =>
|
|
173
|
+
error instanceof DocuSealError
|
|
174
|
+
? error
|
|
175
|
+
: new DocuSealError(
|
|
176
|
+
"Failed to initialize DocuSeal Builder",
|
|
177
|
+
"INIT_ERROR",
|
|
178
|
+
error,
|
|
179
|
+
)
|
|
180
|
+
|
|
183
181
|
onMount(() => {
|
|
184
182
|
let cleanup: (() => void) | undefined
|
|
185
|
-
|
|
186
183
|
;(async () => {
|
|
187
184
|
try {
|
|
188
185
|
validateHost(host)
|
|
@@ -191,15 +188,12 @@
|
|
|
191
188
|
cleanup = setupEventListeners(el)
|
|
192
189
|
}
|
|
193
190
|
} catch (error) {
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
191
|
+
const initError = asDocuSealError(error)
|
|
192
|
+
if (onError) {
|
|
193
|
+
onError(initError)
|
|
194
|
+
} else {
|
|
195
|
+
console.error("DocuSeal Builder initialization error:", initError)
|
|
197
196
|
}
|
|
198
|
-
throw new DocuSealError(
|
|
199
|
-
"Failed to initialize DocuSeal Builder",
|
|
200
|
-
"INIT_ERROR",
|
|
201
|
-
error
|
|
202
|
-
)
|
|
203
197
|
}
|
|
204
198
|
})()
|
|
205
199
|
|
|
@@ -213,7 +207,7 @@
|
|
|
213
207
|
bind:this={el}
|
|
214
208
|
data-token={token}
|
|
215
209
|
data-preview={booleanToAttr(preview || previewMode)}
|
|
216
|
-
data-input-mode={inputMode}
|
|
210
|
+
data-input-mode={booleanToAttr(inputMode)}
|
|
217
211
|
data-language={language}
|
|
218
212
|
data-autosave={booleanToAttr(autosave)}
|
|
219
213
|
data-send-button-text={sendButtonText}
|
|
@@ -224,6 +218,7 @@
|
|
|
224
218
|
data-fields={JSON.stringify(fields)}
|
|
225
219
|
data-submitters={JSON.stringify(submitters)}
|
|
226
220
|
data-required-fields={JSON.stringify(requiredFields)}
|
|
221
|
+
data-date-formats={dateFormats.join(",")}
|
|
227
222
|
data-i18n={JSON.stringify(i18n)}
|
|
228
223
|
data-custom-button-title={customButton.title}
|
|
229
224
|
data-custom-button-url={customButton.url}
|
|
@@ -232,9 +227,14 @@
|
|
|
232
227
|
data-with-recipients-button={booleanToAttr(withRecipientsButton)}
|
|
233
228
|
data-with-send-button={booleanToAttr(withSendButton)}
|
|
234
229
|
data-with-documents-list={booleanToAttr(withDocumentsList)}
|
|
230
|
+
data-with-dynamic-documents={booleanToAttr(withDynamicDocuments)}
|
|
235
231
|
data-with-fields-list={booleanToAttr(withFieldsList)}
|
|
232
|
+
data-with-fields-detection={booleanToAttr(withFieldsDetection)}
|
|
236
233
|
data-with-field-placeholder={booleanToAttr(withFieldPlaceholder)}
|
|
234
|
+
data-with-prefillable={booleanToAttr(withPrefillable)}
|
|
235
|
+
data-with-custom-fields-tab={booleanToAttr(withCustomFieldsTab)}
|
|
237
236
|
data-with-signature-id={booleanToAttr(withSignatureId)}
|
|
237
|
+
data-with-revisions={booleanToAttr(withRevisions)}
|
|
238
238
|
data-with-title={booleanToAttr(withTitle)}
|
|
239
239
|
data-only-defined-fields={booleanToAttr(onlyDefinedFields)}
|
|
240
240
|
data-with-upload-button={booleanToAttr(withUploadButton)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DocuSealBuilderField, DocuSealBuilderSubmitter } from "../types/index.js";
|
|
2
|
+
import { DocuSealError } from "../utils/docuseal.js";
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
token: string;
|
|
4
5
|
host?: string;
|
|
@@ -7,7 +8,12 @@ type $$ComponentProps = {
|
|
|
7
8
|
withTitle?: boolean;
|
|
8
9
|
withDocumentsList?: boolean;
|
|
9
10
|
withFieldsList?: boolean;
|
|
11
|
+
withFieldsDetection?: boolean;
|
|
10
12
|
withFieldPlaceholder?: boolean;
|
|
13
|
+
withDynamicDocuments?: boolean;
|
|
14
|
+
withPrefillable?: boolean;
|
|
15
|
+
withCustomFieldsTab?: boolean;
|
|
16
|
+
withRevisions?: boolean;
|
|
11
17
|
onlyDefinedFields?: boolean;
|
|
12
18
|
preview?: boolean;
|
|
13
19
|
previewMode?: boolean;
|
|
@@ -20,6 +26,7 @@ type $$ComponentProps = {
|
|
|
20
26
|
fields?: DocuSealBuilderField[];
|
|
21
27
|
submitters?: DocuSealBuilderSubmitter[];
|
|
22
28
|
requiredFields?: DocuSealBuilderField[];
|
|
29
|
+
dateFormats?: string[];
|
|
23
30
|
i18n?: object;
|
|
24
31
|
withSignYourselfButton?: boolean;
|
|
25
32
|
withUploadButton?: boolean;
|
|
@@ -44,6 +51,7 @@ type $$ComponentProps = {
|
|
|
44
51
|
onSend?: ((detail: any) => void) | undefined;
|
|
45
52
|
onSave?: ((detail: any) => void) | undefined;
|
|
46
53
|
onChange?: ((detail: any) => void) | undefined;
|
|
54
|
+
onError?: ((error: DocuSealError) => void) | undefined;
|
|
47
55
|
};
|
|
48
56
|
declare const DocuSealBuilder: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
49
57
|
type DocuSealBuilder = ReturnType<typeof DocuSealBuilder>;
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
export let withFieldNames: boolean = true
|
|
38
38
|
export let withFieldPlaceholder: boolean = false
|
|
39
39
|
export let withDownloadButton: boolean = true
|
|
40
|
+
export let onlyRequiredFields: boolean = false
|
|
40
41
|
export let allowToResubmit: boolean = true
|
|
41
42
|
export let allowTypedSignature: boolean = true
|
|
42
43
|
export let signature: string = ""
|
|
@@ -76,32 +77,25 @@
|
|
|
76
77
|
document.head.appendChild(script)
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const handleError = (e: Event) =>
|
|
86
|
-
onError && onError((e as CustomEvent).detail)
|
|
87
|
-
|
|
88
|
-
if (el) {
|
|
89
|
-
el.addEventListener("completed", handleCompleted)
|
|
90
|
-
el.addEventListener("init", handleInit)
|
|
91
|
-
el.addEventListener("declined", handleDecline)
|
|
92
|
-
el.addEventListener("load", handleLoad)
|
|
93
|
-
el.addEventListener("error", handleError)
|
|
80
|
+
const handlers: Record<string, ((detail: any) => void) | undefined> = {
|
|
81
|
+
completed: onComplete,
|
|
82
|
+
init: onInit,
|
|
83
|
+
declined: onDecline,
|
|
84
|
+
load: onLoad,
|
|
85
|
+
error: onError,
|
|
94
86
|
}
|
|
95
87
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
88
|
+
const element = el
|
|
89
|
+
if (!element) return
|
|
90
|
+
|
|
91
|
+
const removers = Object.entries(handlers).map(([eventName, handler]) => {
|
|
92
|
+
const listener = (e: Event) => handler && handler((e as CustomEvent).detail)
|
|
93
|
+
|
|
94
|
+
element.addEventListener(eventName, listener)
|
|
95
|
+
return () => element.removeEventListener(eventName, listener)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
return () => removers.forEach((remove) => remove())
|
|
105
99
|
})
|
|
106
100
|
</script>
|
|
107
101
|
|
|
@@ -115,7 +109,7 @@
|
|
|
115
109
|
data-external-id={externalId || applicationKey}
|
|
116
110
|
data-expand={booleanToAttr(expand)}
|
|
117
111
|
data-minimize={booleanToAttr(minimize)}
|
|
118
|
-
data-order-as-on-page={orderAsOnPage}
|
|
112
|
+
data-order-as-on-page={booleanToAttr(orderAsOnPage)}
|
|
119
113
|
data-preview={booleanToAttr(preview)}
|
|
120
114
|
data-dry-run={booleanToAttr(dryRun)}
|
|
121
115
|
data-go-to-last={booleanToAttr(goToLast)}
|
|
@@ -129,6 +123,7 @@
|
|
|
129
123
|
data-with-field-names={booleanToAttr(withFieldNames)}
|
|
130
124
|
data-with-field-placeholder={booleanToAttr(withFieldPlaceholder)}
|
|
131
125
|
data-with-download-button={booleanToAttr(withDownloadButton)}
|
|
126
|
+
data-only-required-fields={booleanToAttr(onlyRequiredFields)}
|
|
132
127
|
data-allow-to-resubmit={booleanToAttr(allowToResubmit)}
|
|
133
128
|
data-allow-typed-signature={booleanToAttr(allowTypedSignature)}
|
|
134
129
|
data-signature={signature}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DocuSealFormField } from "../types/index.
|
|
1
|
+
import type { DocuSealFormField } from "../types/index.js";
|
|
2
2
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
3
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
4
|
$$bindings?: Bindings;
|
|
@@ -48,6 +48,7 @@ declare const DocuSealForm: $$__sveltets_2_IsomorphicComponent<{
|
|
|
48
48
|
withFieldNames?: boolean;
|
|
49
49
|
withFieldPlaceholder?: boolean;
|
|
50
50
|
withDownloadButton?: boolean;
|
|
51
|
+
onlyRequiredFields?: boolean;
|
|
51
52
|
allowToResubmit?: boolean;
|
|
52
53
|
allowTypedSignature?: boolean;
|
|
53
54
|
signature?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as DocuSealForm } from
|
|
2
|
-
export { default as DocuSealBuilder } from
|
|
3
|
-
export type { DocuSealFormProps, DocuSealFormField, DocuSealBuilderField, DocuSealBuilderSubmitter, } from
|
|
4
|
-
export { isValidDocuSealUrl, buildFormUrl, DocuSealEventType, DocuSealError } from
|
|
1
|
+
export { default as DocuSealForm } from "./components/DocuSealForm.svelte";
|
|
2
|
+
export { default as DocuSealBuilder } from "./components/DocuSealBuilder.svelte";
|
|
3
|
+
export type { DocuSealFormProps, DocuSealFormField, DocuSealBuilderField, DocuSealBuilderSubmitter, } from "./types/index.js";
|
|
4
|
+
export { isValidDocuSealUrl, buildFormUrl, DocuSealEventType, DocuSealError, } from "./utils/docuseal.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
export { default as DocuSealBuilder } from './components/DocuSealBuilder.svelte';
|
|
5
|
-
// Re-export utilities (optional - if you want users to access them)
|
|
6
|
-
export { isValidDocuSealUrl, buildFormUrl, DocuSealEventType, DocuSealError } from './utils/docuseal.js';
|
|
1
|
+
export { default as DocuSealForm } from "./components/DocuSealForm.svelte";
|
|
2
|
+
export { default as DocuSealBuilder } from "./components/DocuSealBuilder.svelte";
|
|
3
|
+
export { isValidDocuSealUrl, buildFormUrl, DocuSealEventType, DocuSealError, } from "./utils/docuseal.js";
|
package/dist/types/index.d.ts
CHANGED
package/dist/utils/docuseal.d.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates if a URL is a valid DocuSeal URL
|
|
3
|
-
*/
|
|
4
1
|
export declare function isValidDocuSealUrl(url: string): boolean;
|
|
5
|
-
/**
|
|
6
|
-
* Builds a DocuSeal form URL with query parameters
|
|
7
|
-
*/
|
|
8
2
|
export declare function buildFormUrl(baseUrl: string, params?: {
|
|
9
3
|
email?: string;
|
|
10
4
|
name?: string;
|
|
11
5
|
phone?: string;
|
|
12
6
|
[key: string]: string | undefined;
|
|
13
7
|
}): string;
|
|
14
|
-
/**
|
|
15
|
-
* Message types from DocuSeal iframe
|
|
16
|
-
*/
|
|
17
8
|
export declare enum DocuSealEventType {
|
|
18
9
|
COMPLETED = "completed",
|
|
19
10
|
DECLINED = "declined",
|
|
@@ -21,49 +12,8 @@ export declare enum DocuSealEventType {
|
|
|
21
12
|
LOADED = "loaded",
|
|
22
13
|
RESIZE = "resize"
|
|
23
14
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Type guard for DocuSeal messages
|
|
26
|
-
*/
|
|
27
|
-
export declare function isDocuSealMessage(event: MessageEvent): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Parse DocuSeal postMessage events
|
|
30
|
-
*/
|
|
31
|
-
export declare function parseDocuSealEvent(event: MessageEvent): {
|
|
32
|
-
type: DocuSealEventType;
|
|
33
|
-
data?: any;
|
|
34
|
-
} | null;
|
|
35
|
-
/**
|
|
36
|
-
* Create an iframe element with DocuSeal configuration
|
|
37
|
-
*/
|
|
38
|
-
export declare function createDocuSealIframe(src: string, options?: {
|
|
39
|
-
title?: string;
|
|
40
|
-
className?: string;
|
|
41
|
-
allowFullscreen?: boolean;
|
|
42
|
-
}): HTMLIFrameElement;
|
|
43
|
-
/**
|
|
44
|
-
* Send a message to DocuSeal iframe
|
|
45
|
-
*/
|
|
46
|
-
export declare function sendToDocuSeal(iframe: HTMLIFrameElement | null, message: {
|
|
47
|
-
type: string;
|
|
48
|
-
data?: any;
|
|
49
|
-
}): void;
|
|
50
|
-
/**
|
|
51
|
-
* Calculates optimal iframe height based on content
|
|
52
|
-
*/
|
|
53
|
-
export declare function calculateIframeHeight(contentHeight?: number, minHeight?: number, maxHeight?: number): number;
|
|
54
|
-
/**
|
|
55
|
-
* Error types that can occur with DocuSeal
|
|
56
|
-
*/
|
|
57
15
|
export declare class DocuSealError extends Error {
|
|
58
16
|
code?: string | undefined;
|
|
59
17
|
details?: any | undefined;
|
|
60
18
|
constructor(message: string, code?: string | undefined, details?: any | undefined);
|
|
61
19
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Retry logic for failed operations
|
|
64
|
-
*/
|
|
65
|
-
export declare function retryOperation<T>(operation: () => Promise<T>, maxRetries?: number, delayMs?: number): Promise<T>;
|
|
66
|
-
/**
|
|
67
|
-
* Prefetch DocuSeal resources for faster loading
|
|
68
|
-
*/
|
|
69
|
-
export declare function prefetchDocuSeal(url: string): void;
|
package/dist/utils/docuseal.js
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
* Validates if a URL is a valid DocuSeal URL
|
|
3
|
-
*/
|
|
1
|
+
const DOCUSEAL_DOMAINS = ["docuseal.co", "docuseal.com", "docuseal.eu"];
|
|
4
2
|
export function isValidDocuSealUrl(url) {
|
|
5
3
|
try {
|
|
6
|
-
const
|
|
7
|
-
return
|
|
8
|
-
parsed.hostname.includes('docuseal.com');
|
|
4
|
+
const { hostname } = new URL(url);
|
|
5
|
+
return DOCUSEAL_DOMAINS.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`));
|
|
9
6
|
}
|
|
10
7
|
catch {
|
|
11
8
|
return false;
|
|
12
9
|
}
|
|
13
10
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Builds a DocuSeal form URL with query parameters
|
|
16
|
-
*/
|
|
17
11
|
export function buildFormUrl(baseUrl, params) {
|
|
18
12
|
const url = new URL(baseUrl);
|
|
19
13
|
if (params) {
|
|
@@ -25,9 +19,6 @@ export function buildFormUrl(baseUrl, params) {
|
|
|
25
19
|
}
|
|
26
20
|
return url.toString();
|
|
27
21
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Message types from DocuSeal iframe
|
|
30
|
-
*/
|
|
31
22
|
export var DocuSealEventType;
|
|
32
23
|
(function (DocuSealEventType) {
|
|
33
24
|
DocuSealEventType["COMPLETED"] = "completed";
|
|
@@ -36,61 +27,6 @@ export var DocuSealEventType;
|
|
|
36
27
|
DocuSealEventType["LOADED"] = "loaded";
|
|
37
28
|
DocuSealEventType["RESIZE"] = "resize";
|
|
38
29
|
})(DocuSealEventType || (DocuSealEventType = {}));
|
|
39
|
-
/**
|
|
40
|
-
* Type guard for DocuSeal messages
|
|
41
|
-
*/
|
|
42
|
-
export function isDocuSealMessage(event) {
|
|
43
|
-
return event.data?.source === 'docuseal' ||
|
|
44
|
-
event.data?.type?.startsWith('docuseal.');
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Parse DocuSeal postMessage events
|
|
48
|
-
*/
|
|
49
|
-
export function parseDocuSealEvent(event) {
|
|
50
|
-
if (!isDocuSealMessage(event)) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
const { type, data } = event.data;
|
|
54
|
-
return { type, data };
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Create an iframe element with DocuSeal configuration
|
|
58
|
-
*/
|
|
59
|
-
export function createDocuSealIframe(src, options) {
|
|
60
|
-
const iframe = document.createElement('iframe');
|
|
61
|
-
iframe.src = src;
|
|
62
|
-
iframe.title = options?.title || 'DocuSeal Form';
|
|
63
|
-
iframe.className = options?.className || '';
|
|
64
|
-
iframe.setAttribute('frameborder', '0');
|
|
65
|
-
iframe.setAttribute('allow', 'camera; microphone; clipboard-write');
|
|
66
|
-
if (options?.allowFullscreen) {
|
|
67
|
-
iframe.setAttribute('allowfullscreen', 'true');
|
|
68
|
-
}
|
|
69
|
-
iframe.style.width = '100%';
|
|
70
|
-
iframe.style.height = '100%';
|
|
71
|
-
return iframe;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Send a message to DocuSeal iframe
|
|
75
|
-
*/
|
|
76
|
-
export function sendToDocuSeal(iframe, message) {
|
|
77
|
-
if (!iframe?.contentWindow) {
|
|
78
|
-
console.warn('DocuSeal iframe not ready');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
iframe.contentWindow.postMessage({ source: 'parent', ...message }, '*');
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Calculates optimal iframe height based on content
|
|
85
|
-
*/
|
|
86
|
-
export function calculateIframeHeight(contentHeight, minHeight = 400, maxHeight = 1200) {
|
|
87
|
-
if (!contentHeight)
|
|
88
|
-
return minHeight;
|
|
89
|
-
return Math.min(Math.max(contentHeight, minHeight), maxHeight);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Error types that can occur with DocuSeal
|
|
93
|
-
*/
|
|
94
30
|
export class DocuSealError extends Error {
|
|
95
31
|
code;
|
|
96
32
|
details;
|
|
@@ -98,33 +34,6 @@ export class DocuSealError extends Error {
|
|
|
98
34
|
super(message);
|
|
99
35
|
this.code = code;
|
|
100
36
|
this.details = details;
|
|
101
|
-
this.name =
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Retry logic for failed operations
|
|
106
|
-
*/
|
|
107
|
-
export async function retryOperation(operation, maxRetries = 3, delayMs = 1000) {
|
|
108
|
-
let lastError = new Error();
|
|
109
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
110
|
-
try {
|
|
111
|
-
return await operation();
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
lastError = error;
|
|
115
|
-
if (i < maxRetries - 1) {
|
|
116
|
-
await new Promise(resolve => setTimeout(resolve, delayMs * (i + 1)));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
37
|
+
this.name = "DocuSealError";
|
|
119
38
|
}
|
|
120
|
-
throw new DocuSealError(`Operation failed after ${maxRetries} retries`, 'RETRY_EXCEEDED', lastError);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Prefetch DocuSeal resources for faster loading
|
|
124
|
-
*/
|
|
125
|
-
export function prefetchDocuSeal(url) {
|
|
126
|
-
const link = document.createElement('link');
|
|
127
|
-
link.rel = 'prefetch';
|
|
128
|
-
link.href = url;
|
|
129
|
-
document.head.appendChild(link);
|
|
130
39
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docuseal-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Docuseal Svelte component library for document signing and management.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/SirCen/docuseal-svelte.git"
|
|
8
|
+
"url": "git+https://github.com/SirCen/docuseal-svelte.git"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "vite dev",
|
|
12
12
|
"build": "vite build && npm run prepack",
|
|
13
|
+
"release": "npm stage publish",
|
|
13
14
|
"preview": "vite preview",
|
|
14
15
|
"prepare": "svelte-kit sync || echo ''",
|
|
15
|
-
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
16
|
+
"prepack": "svelte-kit sync && svelte-package && node scripts/assert-no-tests-in-dist.js && publint",
|
|
16
17
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
17
|
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
|
18
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest"
|
|
18
21
|
},
|
|
19
22
|
"files": [
|
|
20
23
|
"dist",
|
|
@@ -42,11 +45,14 @@
|
|
|
42
45
|
"@sveltejs/kit": "^2.49.1",
|
|
43
46
|
"@sveltejs/package": "^2.5.7",
|
|
44
47
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
48
|
+
"@testing-library/svelte": "^5.4.2",
|
|
49
|
+
"jsdom": "^30.0.1",
|
|
45
50
|
"publint": "^0.3.15",
|
|
46
51
|
"svelte": "^5.45.6",
|
|
47
52
|
"svelte-check": "^4.3.4",
|
|
48
53
|
"typescript": "^5.9.3",
|
|
49
|
-
"vite": "^7.2.6"
|
|
54
|
+
"vite": "^7.2.6",
|
|
55
|
+
"vitest": "^4.1.11"
|
|
50
56
|
},
|
|
51
57
|
"keywords": [
|
|
52
58
|
"svelte",
|