docuseal-svelte 0.0.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 ADDED
@@ -0,0 +1,58 @@
1
+ # Svelte library
2
+
3
+ Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4
+
5
+ Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
+
7
+ ## Creating a project
8
+
9
+ If you're seeing this, you've probably already done this step. Congrats!
10
+
11
+ ```sh
12
+ # create a new project in the current directory
13
+ npx sv create
14
+
15
+ # create a new project in my-app
16
+ npx sv create my-app
17
+ ```
18
+
19
+ ## Developing
20
+
21
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
+
23
+ ```sh
24
+ npm run dev
25
+
26
+ # or start the server and open the app in a new browser tab
27
+ npm run dev -- --open
28
+ ```
29
+
30
+ Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
+
32
+ ## Building
33
+
34
+ To build your library:
35
+
36
+ ```sh
37
+ npm pack
38
+ ```
39
+
40
+ To create a production version of your showcase app:
41
+
42
+ ```sh
43
+ npm run build
44
+ ```
45
+
46
+ You can preview the production build with `npm run preview`.
47
+
48
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
+
50
+ ## Publishing
51
+
52
+ Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
+
54
+ To publish your library to [npm](https://www.npmjs.com):
55
+
56
+ ```sh
57
+ npm publish
58
+ ```
@@ -0,0 +1,247 @@
1
+ <script lang="ts">
2
+ import {onMount} from "svelte"
3
+ import type {
4
+ DocuSealBuilderField,
5
+ DocuSealBuilderSubmitter,
6
+ } from "../types/index.js"
7
+ import {DocuSealError} from "../utils/docuseal.js"
8
+
9
+ let {
10
+ token,
11
+ host = "cdn.docuseal.com",
12
+ withRecipientsButton = true,
13
+ withSendButton = true,
14
+ withTitle = true,
15
+ withDocumentsList = true,
16
+ withFieldsList = true,
17
+ withFieldPlaceholder = false,
18
+ onlyDefinedFields = false,
19
+ preview = false,
20
+ previewMode = false,
21
+ inputMode = false,
22
+ language = "en",
23
+ autosave = true,
24
+ roles = [],
25
+ fieldTypes = [],
26
+ drawFieldType = "text",
27
+ fields = [],
28
+ submitters = [],
29
+ requiredFields = [],
30
+ i18n = {},
31
+ withSignYourselfButton = true,
32
+ withUploadButton = true,
33
+ withSignatureId = undefined,
34
+ withAddPageButton = false,
35
+ customButton = {title: "", url: ""},
36
+ emailMessage = {subject: "", body: ""},
37
+ backgroundColor = "",
38
+ saveButtonText = "",
39
+ sendButtonText = "",
40
+ className = "",
41
+ customCss = "",
42
+ style = undefined,
43
+ onLoad = undefined,
44
+ onUpload = undefined,
45
+ onSend = undefined,
46
+ onSave = undefined,
47
+ onChange = undefined,
48
+ }: {
49
+ token: string
50
+ host?: string
51
+ withRecipientsButton?: boolean
52
+ withSendButton?: boolean
53
+ withTitle?: boolean
54
+ withDocumentsList?: boolean
55
+ withFieldsList?: boolean
56
+ withFieldPlaceholder?: boolean
57
+ onlyDefinedFields?: boolean
58
+ preview?: boolean
59
+ previewMode?: boolean
60
+ inputMode?: boolean
61
+ language?: string
62
+ autosave?: boolean
63
+ roles?: string[]
64
+ fieldTypes?: string[]
65
+ drawFieldType?: string
66
+ fields?: DocuSealBuilderField[]
67
+ submitters?: DocuSealBuilderSubmitter[]
68
+ requiredFields?: DocuSealBuilderField[]
69
+ i18n?: object
70
+ withSignYourselfButton?: boolean
71
+ withUploadButton?: boolean
72
+ withSignatureId?: boolean | undefined
73
+ withAddPageButton?: boolean
74
+ customButton?: {title: string; url: string}
75
+ emailMessage?: {subject: string; body: string}
76
+ backgroundColor?: string
77
+ saveButtonText?: string
78
+ sendButtonText?: string
79
+ className?: string
80
+ customCss?: string
81
+ style?: string | undefined
82
+ onLoad?: ((detail: any) => void) | undefined
83
+ onUpload?: ((detail: any) => void) | undefined
84
+ onSend?: ((detail: any) => void) | undefined
85
+ onSave?: ((detail: any) => void) | undefined
86
+ onChange?: ((detail: any) => void) | undefined
87
+ } = $props()
88
+
89
+ let el = $state<HTMLElement | null>(null)
90
+
91
+ const booleanToAttr = (value: any): string | undefined => {
92
+ if (value === true) return "true"
93
+ if (value === false) return "false"
94
+ return value
95
+ }
96
+
97
+ const validateHost = (host: string): void => {
98
+ const testUrl = `https://${host}`
99
+ try {
100
+ new URL(testUrl)
101
+ } catch {
102
+ throw new DocuSealError(`Invalid host: ${host}`, "INVALID_HOST")
103
+ }
104
+ }
105
+
106
+ const loadBuilderScript = (host: string): Promise<void> => {
107
+ return new Promise((resolve, reject) => {
108
+ const scriptId = "docuseal-builder-script"
109
+ const scriptSrc = `https://${host}/js/builder.js`
110
+
111
+ // Check if script already exists
112
+ const existingScript = document.getElementById(scriptId)
113
+ if (existingScript) {
114
+ resolve()
115
+ return
116
+ }
117
+
118
+ const script = document.createElement("script")
119
+ script.id = scriptId
120
+ script.async = true
121
+ script.src = scriptSrc
122
+
123
+ script.onload = () => resolve()
124
+ script.onerror = () =>
125
+ reject(
126
+ new DocuSealError(
127
+ `Failed to load DocuSeal builder script from ${scriptSrc}`,
128
+ "SCRIPT_LOAD_ERROR"
129
+ )
130
+ )
131
+
132
+ document.head.appendChild(script)
133
+ })
134
+ }
135
+
136
+ const setupEventListeners = (element: HTMLElement): (() => void) => {
137
+ const handleLoad = (e: Event) => {
138
+ if (onLoad && e instanceof CustomEvent) {
139
+ onLoad(e.detail)
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
+ }
159
+ }
160
+
161
+ const handleChange = (e: Event) => {
162
+ if (onChange && e instanceof CustomEvent) {
163
+ onChange(e.detail)
164
+ }
165
+ }
166
+
167
+ element.addEventListener("load", handleLoad)
168
+ element.addEventListener("upload", handleUpload)
169
+ element.addEventListener("send", handleSend)
170
+ element.addEventListener("save", handleSave)
171
+ element.addEventListener("change", handleChange)
172
+
173
+ // Return cleanup function
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
+ }
181
+ }
182
+
183
+ onMount(() => {
184
+ let cleanup: (() => void) | undefined
185
+
186
+ ;(async () => {
187
+ try {
188
+ validateHost(host)
189
+ await loadBuilderScript(host)
190
+ if (el) {
191
+ cleanup = setupEventListeners(el)
192
+ }
193
+ } catch (error) {
194
+ console.error("DocuSeal Builder initialization error:", error)
195
+ if (error instanceof DocuSealError) {
196
+ throw error
197
+ }
198
+ throw new DocuSealError(
199
+ "Failed to initialize DocuSeal Builder",
200
+ "INIT_ERROR",
201
+ error
202
+ )
203
+ }
204
+ })()
205
+
206
+ return () => {
207
+ if (cleanup) cleanup()
208
+ }
209
+ })
210
+ </script>
211
+
212
+ <docuseal-builder
213
+ bind:this={el}
214
+ data-token={token}
215
+ data-preview={booleanToAttr(preview || previewMode)}
216
+ data-input-mode={inputMode}
217
+ data-language={language}
218
+ data-autosave={booleanToAttr(autosave)}
219
+ data-send-button-text={sendButtonText}
220
+ data-save-button-text={saveButtonText}
221
+ data-roles={roles.join(",")}
222
+ data-field-types={fieldTypes.join(",")}
223
+ data-draw-field-type={drawFieldType}
224
+ data-fields={JSON.stringify(fields)}
225
+ data-submitters={JSON.stringify(submitters)}
226
+ data-required-fields={JSON.stringify(requiredFields)}
227
+ data-i18n={JSON.stringify(i18n)}
228
+ data-custom-button-title={customButton.title}
229
+ data-custom-button-url={customButton.url}
230
+ data-email-subject={emailMessage.subject}
231
+ data-email-body={emailMessage.body}
232
+ data-with-recipients-button={booleanToAttr(withRecipientsButton)}
233
+ data-with-send-button={booleanToAttr(withSendButton)}
234
+ data-with-documents-list={booleanToAttr(withDocumentsList)}
235
+ data-with-fields-list={booleanToAttr(withFieldsList)}
236
+ data-with-field-placeholder={booleanToAttr(withFieldPlaceholder)}
237
+ data-with-signature-id={booleanToAttr(withSignatureId)}
238
+ data-with-title={booleanToAttr(withTitle)}
239
+ data-only-defined-fields={booleanToAttr(onlyDefinedFields)}
240
+ data-with-upload-button={booleanToAttr(withUploadButton)}
241
+ data-with-add-page-button={booleanToAttr(withAddPageButton)}
242
+ data-with-sign-yourself-button={booleanToAttr(withSignYourselfButton)}
243
+ data-background-color={backgroundColor}
244
+ data-custom-css={customCss}
245
+ class={className}
246
+ {style}
247
+ ></docuseal-builder>
@@ -0,0 +1,50 @@
1
+ import type { DocuSealBuilderField, DocuSealBuilderSubmitter } from "../types/index.js";
2
+ type $$ComponentProps = {
3
+ token: string;
4
+ host?: string;
5
+ withRecipientsButton?: boolean;
6
+ withSendButton?: boolean;
7
+ withTitle?: boolean;
8
+ withDocumentsList?: boolean;
9
+ withFieldsList?: boolean;
10
+ withFieldPlaceholder?: boolean;
11
+ onlyDefinedFields?: boolean;
12
+ preview?: boolean;
13
+ previewMode?: boolean;
14
+ inputMode?: boolean;
15
+ language?: string;
16
+ autosave?: boolean;
17
+ roles?: string[];
18
+ fieldTypes?: string[];
19
+ drawFieldType?: string;
20
+ fields?: DocuSealBuilderField[];
21
+ submitters?: DocuSealBuilderSubmitter[];
22
+ requiredFields?: DocuSealBuilderField[];
23
+ i18n?: object;
24
+ withSignYourselfButton?: boolean;
25
+ withUploadButton?: boolean;
26
+ withSignatureId?: boolean | undefined;
27
+ withAddPageButton?: boolean;
28
+ customButton?: {
29
+ title: string;
30
+ url: string;
31
+ };
32
+ emailMessage?: {
33
+ subject: string;
34
+ body: string;
35
+ };
36
+ backgroundColor?: string;
37
+ saveButtonText?: string;
38
+ sendButtonText?: string;
39
+ className?: string;
40
+ customCss?: string;
41
+ style?: string | undefined;
42
+ onLoad?: ((detail: any) => void) | undefined;
43
+ onUpload?: ((detail: any) => void) | undefined;
44
+ onSend?: ((detail: any) => void) | undefined;
45
+ onSave?: ((detail: any) => void) | undefined;
46
+ onChange?: ((detail: any) => void) | undefined;
47
+ };
48
+ declare const DocuSealBuilder: import("svelte").Component<$$ComponentProps, {}, "">;
49
+ type DocuSealBuilder = ReturnType<typeof DocuSealBuilder>;
50
+ export default DocuSealBuilder;
@@ -0,0 +1,148 @@
1
+ <script lang="ts">
2
+ import {onMount} from "svelte"
3
+ import type {DocuSealFormField} from "../types/index.js"
4
+
5
+ export let src: string = ""
6
+ export let token: string = ""
7
+ export let host: string = "cdn.docuseal.com"
8
+ export let role: string = ""
9
+ export let submitter: string = ""
10
+ export let preview: boolean = false
11
+ export let dryRun: boolean = false
12
+ export let expand: boolean = true
13
+ export let minimize: boolean = false
14
+ export let orderAsOnPage: boolean = false
15
+ export let email: string = ""
16
+ export let name: string = ""
17
+ export let backgroundColor: string = ""
18
+ export let sendCopyEmail: boolean | undefined = undefined
19
+ export let applicationKey: string = ""
20
+ export let externalId: string = ""
21
+ export let logo: string = ""
22
+ export let language: string = ""
23
+ export let completedRedirectUrl: string = ""
24
+ export let completedButton: {title: string; url: string} = {
25
+ title: "",
26
+ url: "",
27
+ }
28
+ export let completedMessage: {title?: string; body?: string} = {
29
+ title: "",
30
+ body: "",
31
+ }
32
+ export let goToLast: boolean = true
33
+ export let skipFields: boolean = false
34
+ export let autoscrollFields: boolean = true
35
+ export let withTitle: boolean = true
36
+ export let withDecline: boolean = false
37
+ export let withFieldNames: boolean = true
38
+ export let withFieldPlaceholder: boolean = false
39
+ export let withDownloadButton: boolean = true
40
+ export let allowToResubmit: boolean = true
41
+ export let allowTypedSignature: boolean = true
42
+ export let signature: string = ""
43
+ export let rememberSignature: boolean = false
44
+ export let reuseSignature: boolean = true
45
+ export let withSendCopyButton: boolean = true
46
+ export let withCompleteButton: boolean = false
47
+ export let values: object = {}
48
+ export let metadata: object = {}
49
+ export let i18n: object = {}
50
+ export let fields: DocuSealFormField[] = []
51
+ export let readonlyFields: string[] = []
52
+ export let customCss: string = ""
53
+ export let className: string = ""
54
+ export let style: string | undefined = undefined
55
+
56
+ export let onComplete: ((detail: any) => void) | undefined = undefined
57
+ export let onInit: ((detail: any) => void) | undefined = undefined
58
+ export let onDecline: ((detail: any) => void) | undefined = undefined
59
+ export let onLoad: ((detail: any) => void) | undefined = undefined
60
+
61
+ let el: HTMLElement | null = null
62
+
63
+ const booleanToAttr = (value: any) =>
64
+ value === true ? "true" : value === false ? "false" : value
65
+
66
+ onMount(() => {
67
+ const scriptId = "docuseal-form-script"
68
+ const scriptSrc = `https://${host}/js/form.js`
69
+
70
+ if (!document.getElementById(scriptId)) {
71
+ const script = document.createElement("script")
72
+ script.id = scriptId
73
+ script.async = true
74
+ script.src = scriptSrc
75
+ document.head.appendChild(script)
76
+ }
77
+
78
+ const handleCompleted = (e: Event) =>
79
+ onComplete && onComplete((e as CustomEvent).detail)
80
+ const handleInit = (e: Event) => onInit && onInit((e as CustomEvent).detail)
81
+ const handleDecline = (e: Event) =>
82
+ onDecline && onDecline((e as CustomEvent).detail)
83
+ const handleLoad = (e: Event) => onLoad && onLoad((e as CustomEvent).detail)
84
+
85
+ if (el) {
86
+ el.addEventListener("completed", handleCompleted)
87
+ el.addEventListener("init", handleInit)
88
+ el.addEventListener("declined", handleDecline)
89
+ el.addEventListener("load", handleLoad)
90
+ }
91
+
92
+ return () => {
93
+ if (el) {
94
+ el.removeEventListener("completed", handleCompleted)
95
+ el.removeEventListener("init", handleInit)
96
+ el.removeEventListener("declined", handleDecline)
97
+ el.removeEventListener("load", handleLoad)
98
+ }
99
+ }
100
+ })
101
+ </script>
102
+
103
+ <docuseal-form
104
+ bind:this={el}
105
+ data-src={src}
106
+ data-token={token}
107
+ data-email={email}
108
+ data-name={name}
109
+ data-role={role || submitter}
110
+ data-external-id={externalId || applicationKey}
111
+ data-expand={booleanToAttr(expand)}
112
+ data-minimize={booleanToAttr(minimize)}
113
+ data-order-as-on-page={orderAsOnPage}
114
+ data-preview={booleanToAttr(preview)}
115
+ data-dry-run={booleanToAttr(dryRun)}
116
+ data-go-to-last={booleanToAttr(goToLast)}
117
+ data-skip-fields={booleanToAttr(skipFields)}
118
+ data-autoscroll-fields={booleanToAttr(autoscrollFields)}
119
+ data-send-copy-email={booleanToAttr(sendCopyEmail)}
120
+ data-with-title={booleanToAttr(withTitle)}
121
+ data-with-decline={booleanToAttr(withDecline)}
122
+ data-logo={logo}
123
+ data-language={language}
124
+ data-with-field-names={booleanToAttr(withFieldNames)}
125
+ data-with-field-placeholder={booleanToAttr(withFieldPlaceholder)}
126
+ data-with-download-button={booleanToAttr(withDownloadButton)}
127
+ data-allow-to-resubmit={booleanToAttr(allowToResubmit)}
128
+ data-allow-typed-signature={booleanToAttr(allowTypedSignature)}
129
+ data-signature={signature}
130
+ data-remember-signature={booleanToAttr(rememberSignature)}
131
+ data-reuse-signature={booleanToAttr(reuseSignature)}
132
+ data-completed-redirect-url={completedRedirectUrl}
133
+ data-with-send-copy-button={booleanToAttr(withSendCopyButton)}
134
+ data-with-complete-button={booleanToAttr(withCompleteButton)}
135
+ data-values={JSON.stringify(values)}
136
+ data-metadata={JSON.stringify(metadata)}
137
+ data-fields={JSON.stringify(fields)}
138
+ data-i18n={JSON.stringify(i18n)}
139
+ data-readonly-fields={readonlyFields.join(",")}
140
+ data-completed-message-title={completedMessage.title}
141
+ data-completed-message-body={completedMessage.body}
142
+ data-completed-button-title={completedButton.title}
143
+ data-completed-button-url={completedButton.url}
144
+ data-background-color={backgroundColor}
145
+ data-custom-css={customCss}
146
+ class={className}
147
+ {style}
148
+ ></docuseal-form>
@@ -0,0 +1,74 @@
1
+ import type { DocuSealFormField } from "../types/index.ts";
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
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const DocuSealForm: $$__sveltets_2_IsomorphicComponent<{
16
+ src?: string;
17
+ token?: string;
18
+ host?: string;
19
+ role?: string;
20
+ submitter?: string;
21
+ preview?: boolean;
22
+ dryRun?: boolean;
23
+ expand?: boolean;
24
+ minimize?: boolean;
25
+ orderAsOnPage?: boolean;
26
+ email?: string;
27
+ name?: string;
28
+ backgroundColor?: string;
29
+ sendCopyEmail?: boolean | undefined;
30
+ applicationKey?: string;
31
+ externalId?: string;
32
+ logo?: string;
33
+ language?: string;
34
+ completedRedirectUrl?: string;
35
+ completedButton?: {
36
+ title: string;
37
+ url: string;
38
+ };
39
+ completedMessage?: {
40
+ title?: string;
41
+ body?: string;
42
+ };
43
+ goToLast?: boolean;
44
+ skipFields?: boolean;
45
+ autoscrollFields?: boolean;
46
+ withTitle?: boolean;
47
+ withDecline?: boolean;
48
+ withFieldNames?: boolean;
49
+ withFieldPlaceholder?: boolean;
50
+ withDownloadButton?: boolean;
51
+ allowToResubmit?: boolean;
52
+ allowTypedSignature?: boolean;
53
+ signature?: string;
54
+ rememberSignature?: boolean;
55
+ reuseSignature?: boolean;
56
+ withSendCopyButton?: boolean;
57
+ withCompleteButton?: boolean;
58
+ values?: object;
59
+ metadata?: object;
60
+ i18n?: object;
61
+ fields?: DocuSealFormField[];
62
+ readonlyFields?: string[];
63
+ customCss?: string;
64
+ className?: string;
65
+ style?: string | undefined;
66
+ onComplete?: ((detail: any) => void) | undefined;
67
+ onInit?: ((detail: any) => void) | undefined;
68
+ onDecline?: ((detail: any) => void) | undefined;
69
+ onLoad?: ((detail: any) => void) | undefined;
70
+ }, {
71
+ [evt: string]: CustomEvent<any>;
72
+ }, {}, {}, string>;
73
+ type DocuSealForm = InstanceType<typeof DocuSealForm>;
74
+ export default DocuSealForm;
@@ -0,0 +1,4 @@
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 ADDED
@@ -0,0 +1,6 @@
1
+ // Reexport your entry components here
2
+ // Re-export components
3
+ export { default as DocuSealForm } from './components/DocuSealForm.svelte';
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';
@@ -0,0 +1,111 @@
1
+ interface CompletedMessage {
2
+ title?: string;
3
+ body?: string;
4
+ }
5
+ interface CompletedButton {
6
+ title: string;
7
+ url: string;
8
+ }
9
+ interface ValidationBase {
10
+ pattern?: string;
11
+ message?: string;
12
+ }
13
+ interface PreferencesBase {
14
+ font_size?: number;
15
+ font_type?: "bold" | "italic" | "bold_italic";
16
+ mask?: boolean | number;
17
+ font?: "Times" | "Helvetica" | "Courier";
18
+ color?: "black" | "white" | "blue";
19
+ align?: "left" | "center" | "right";
20
+ valign?: "top" | "center" | "bottom";
21
+ format?: string;
22
+ price?: number;
23
+ currency?: "USD" | "EUR" | "GBP" | "CAD" | "AUD";
24
+ }
25
+ export interface DocuSealFormField {
26
+ name: string;
27
+ title?: string;
28
+ description?: string;
29
+ type?: string;
30
+ position?: number;
31
+ required?: boolean;
32
+ readonly?: boolean;
33
+ validation?: ValidationBase;
34
+ preferences?: PreferencesBase;
35
+ }
36
+ export interface DocuSealFormProps {
37
+ src?: string;
38
+ token?: string;
39
+ host?: string;
40
+ role?: string;
41
+ submitter?: string;
42
+ expand?: boolean;
43
+ minimize?: boolean;
44
+ orderAsOnPage?: boolean;
45
+ preview?: boolean;
46
+ dryRun?: boolean;
47
+ email?: string;
48
+ name?: string;
49
+ applicationKey?: string;
50
+ externalId?: string;
51
+ backgroundColor?: string;
52
+ logo?: string;
53
+ language?: string;
54
+ completedMessage?: CompletedMessage;
55
+ completedRedirectUrl?: string;
56
+ completedButton?: CompletedButton;
57
+ goToLast?: boolean;
58
+ skipFields?: boolean;
59
+ autoscrollFields?: boolean;
60
+ withTitle?: boolean;
61
+ withDecline?: boolean;
62
+ withFieldNames?: boolean;
63
+ withFieldPlaceholder?: boolean;
64
+ sendCopyEmail?: boolean;
65
+ withDownloadButton?: boolean;
66
+ withSendCopyButton?: boolean;
67
+ withCompleteButton?: boolean;
68
+ allowToResubmit?: boolean;
69
+ allowTypedSignature?: boolean;
70
+ signature?: string;
71
+ rememberSignature?: boolean;
72
+ reuseSignature?: boolean;
73
+ values?: object;
74
+ metadata?: object;
75
+ i18n?: object;
76
+ fields?: DocuSealFormField[];
77
+ readonlyFields?: string[];
78
+ customCss?: string;
79
+ className?: string;
80
+ style?: string | undefined;
81
+ }
82
+ interface BuilderValidation extends ValidationBase {
83
+ min?: number | string;
84
+ max?: number | string;
85
+ step?: number;
86
+ }
87
+ interface BuilderPreferences extends PreferencesBase {
88
+ with_signature_id?: boolean;
89
+ }
90
+ export interface DocuSealBuilderField {
91
+ name: string;
92
+ type?: string;
93
+ role?: string;
94
+ title?: string;
95
+ description?: string;
96
+ required?: boolean;
97
+ readonly?: boolean;
98
+ default_value?: string;
99
+ width?: number;
100
+ height?: number;
101
+ options?: string[];
102
+ preferences?: BuilderPreferences;
103
+ validation?: BuilderValidation;
104
+ }
105
+ export interface DocuSealBuilderSubmitter {
106
+ email?: string;
107
+ role?: string;
108
+ name?: string;
109
+ phone?: string;
110
+ }
111
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Validates if a URL is a valid DocuSeal URL
3
+ */
4
+ export declare function isValidDocuSealUrl(url: string): boolean;
5
+ /**
6
+ * Builds a DocuSeal form URL with query parameters
7
+ */
8
+ export declare function buildFormUrl(baseUrl: string, params?: {
9
+ email?: string;
10
+ name?: string;
11
+ phone?: string;
12
+ [key: string]: string | undefined;
13
+ }): string;
14
+ /**
15
+ * Message types from DocuSeal iframe
16
+ */
17
+ export declare enum DocuSealEventType {
18
+ COMPLETED = "completed",
19
+ DECLINED = "declined",
20
+ ERROR = "error",
21
+ LOADED = "loaded",
22
+ RESIZE = "resize"
23
+ }
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
+ export declare class DocuSealError extends Error {
58
+ code?: string | undefined;
59
+ details?: any | undefined;
60
+ constructor(message: string, code?: string | undefined, details?: any | undefined);
61
+ }
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;
@@ -0,0 +1,131 @@
1
+ // src/lib/utils/docuseal.ts
2
+ /**
3
+ * Validates if a URL is a valid DocuSeal URL
4
+ */
5
+ export function isValidDocuSealUrl(url) {
6
+ try {
7
+ const parsed = new URL(url);
8
+ return parsed.hostname.includes('docuseal.co') ||
9
+ parsed.hostname.includes('docuseal.com');
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ /**
16
+ * Builds a DocuSeal form URL with query parameters
17
+ */
18
+ export function buildFormUrl(baseUrl, params) {
19
+ const url = new URL(baseUrl);
20
+ if (params) {
21
+ Object.entries(params).forEach(([key, value]) => {
22
+ if (value !== undefined) {
23
+ url.searchParams.set(key, value);
24
+ }
25
+ });
26
+ }
27
+ return url.toString();
28
+ }
29
+ /**
30
+ * Message types from DocuSeal iframe
31
+ */
32
+ export var DocuSealEventType;
33
+ (function (DocuSealEventType) {
34
+ DocuSealEventType["COMPLETED"] = "completed";
35
+ DocuSealEventType["DECLINED"] = "declined";
36
+ DocuSealEventType["ERROR"] = "error";
37
+ DocuSealEventType["LOADED"] = "loaded";
38
+ DocuSealEventType["RESIZE"] = "resize";
39
+ })(DocuSealEventType || (DocuSealEventType = {}));
40
+ /**
41
+ * Type guard for DocuSeal messages
42
+ */
43
+ export function isDocuSealMessage(event) {
44
+ return event.data?.source === 'docuseal' ||
45
+ event.data?.type?.startsWith('docuseal.');
46
+ }
47
+ /**
48
+ * Parse DocuSeal postMessage events
49
+ */
50
+ export function parseDocuSealEvent(event) {
51
+ if (!isDocuSealMessage(event)) {
52
+ return null;
53
+ }
54
+ const { type, data } = event.data;
55
+ return { type, data };
56
+ }
57
+ /**
58
+ * Create an iframe element with DocuSeal configuration
59
+ */
60
+ export function createDocuSealIframe(src, options) {
61
+ const iframe = document.createElement('iframe');
62
+ iframe.src = src;
63
+ iframe.title = options?.title || 'DocuSeal Form';
64
+ iframe.className = options?.className || '';
65
+ iframe.setAttribute('frameborder', '0');
66
+ iframe.setAttribute('allow', 'camera; microphone; clipboard-write');
67
+ if (options?.allowFullscreen) {
68
+ iframe.setAttribute('allowfullscreen', 'true');
69
+ }
70
+ iframe.style.width = '100%';
71
+ iframe.style.height = '100%';
72
+ return iframe;
73
+ }
74
+ /**
75
+ * Send a message to DocuSeal iframe
76
+ */
77
+ export function sendToDocuSeal(iframe, message) {
78
+ if (!iframe?.contentWindow) {
79
+ console.warn('DocuSeal iframe not ready');
80
+ return;
81
+ }
82
+ iframe.contentWindow.postMessage({ source: 'parent', ...message }, '*');
83
+ }
84
+ /**
85
+ * Calculates optimal iframe height based on content
86
+ */
87
+ export function calculateIframeHeight(contentHeight, minHeight = 400, maxHeight = 1200) {
88
+ if (!contentHeight)
89
+ return minHeight;
90
+ return Math.min(Math.max(contentHeight, minHeight), maxHeight);
91
+ }
92
+ /**
93
+ * Error types that can occur with DocuSeal
94
+ */
95
+ export class DocuSealError extends Error {
96
+ code;
97
+ details;
98
+ constructor(message, code, details) {
99
+ super(message);
100
+ this.code = code;
101
+ this.details = details;
102
+ this.name = 'DocuSealError';
103
+ }
104
+ }
105
+ /**
106
+ * Retry logic for failed operations
107
+ */
108
+ export async function retryOperation(operation, maxRetries = 3, delayMs = 1000) {
109
+ let lastError = new Error();
110
+ for (let i = 0; i < maxRetries; i++) {
111
+ try {
112
+ return await operation();
113
+ }
114
+ catch (error) {
115
+ lastError = error;
116
+ if (i < maxRetries - 1) {
117
+ await new Promise(resolve => setTimeout(resolve, delayMs * (i + 1)));
118
+ }
119
+ }
120
+ }
121
+ throw new DocuSealError(`Operation failed after ${maxRetries} retries`, 'RETRY_EXCEEDED', lastError);
122
+ }
123
+ /**
124
+ * Prefetch DocuSeal resources for faster loading
125
+ */
126
+ export function prefetchDocuSeal(url) {
127
+ const link = document.createElement('link');
128
+ link.rel = 'prefetch';
129
+ link.href = url;
130
+ document.head.appendChild(link);
131
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "docuseal-svelte",
3
+ "version": "0.0.1",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "preview": "vite preview",
8
+ "prepare": "svelte-kit sync || echo ''",
9
+ "prepack": "svelte-kit sync && svelte-package && publint",
10
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12
+ "release": "npm run build && changeset publish"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "!dist/**/*.test.*",
17
+ "!dist/**/*.spec.*"
18
+ ],
19
+ "sideEffects": [
20
+ "**/*.css"
21
+ ],
22
+ "svelte": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "type": "module",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "svelte": "./dist/index.js"
29
+ }
30
+ },
31
+ "peerDependencies": {
32
+ "svelte": "^5.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@changesets/cli": "^2.29.8",
36
+ "@sveltejs/adapter-auto": "^7.0.0",
37
+ "@sveltejs/kit": "^2.49.1",
38
+ "@sveltejs/package": "^2.5.7",
39
+ "@sveltejs/vite-plugin-svelte": "^6.2.1",
40
+ "publint": "^0.3.15",
41
+ "svelte": "^5.45.6",
42
+ "svelte-check": "^4.3.4",
43
+ "typescript": "^5.9.3",
44
+ "vite": "^7.2.6"
45
+ },
46
+ "keywords": [
47
+ "svelte",
48
+ "docuseal",
49
+ "document",
50
+ "signature",
51
+ "signing",
52
+ "pdf",
53
+ "component",
54
+ "library"
55
+ ]
56
+ }