@superdurable/connector-jotform 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +4 -2
- package/dex-connector.json +118 -0
- package/dist/chunk-ZKAGZX4P.js +152 -0
- package/dist/connection-D-MiEsWp.d.ts +123 -0
- package/dist/index.d.ts +149 -0
- package/dist/index.js +287 -0
- package/dist/mock.d.ts +56 -0
- package/dist/mock.js +130 -0
- package/package.json +59 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Super Durable
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Jotform TypeScript connector
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This package implements `listForms` and `getSubmission` for Dex TypeScript Flows. Both Queries replay Go-recorded provider requests, branches, retries, and exact outputs. Submission answers stay outside Flow results.
|
|
4
|
+
|
|
5
|
+
Create a read-only API key in [Jotform My Account > API](https://www.jotform.com/myaccount/api) and save it in the Dex Web secret `api_key` field. Select the US, EU, or HIPAA endpoint for your account. See the [connector README](../README.md) and the [runnable form inspection Flow](examples/form-inspection/README.md). Live Jotform authorization remains unverified.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"connectorId": "jotform",
|
|
3
|
+
"releaseTag": "connectors/jotform/go/v0.1.0",
|
|
4
|
+
"package": {
|
|
5
|
+
"ecosystem": "npm",
|
|
6
|
+
"name": "@superdurable/connector-jotform",
|
|
7
|
+
"version": "0.1.0"
|
|
8
|
+
},
|
|
9
|
+
"factories": [
|
|
10
|
+
{
|
|
11
|
+
"name": "newListFormsStep",
|
|
12
|
+
"kind": "query",
|
|
13
|
+
"operationId": "listForms",
|
|
14
|
+
"inputType": "ListFormsInput",
|
|
15
|
+
"description": "List one page of form titles and IDs without submission answers.",
|
|
16
|
+
"fields": {
|
|
17
|
+
"stepType": "stepType",
|
|
18
|
+
"annotations": "annotations",
|
|
19
|
+
"connectionName": "connectionName",
|
|
20
|
+
"resultAttribute": "resultAttribute"
|
|
21
|
+
},
|
|
22
|
+
"branches": [
|
|
23
|
+
{
|
|
24
|
+
"id": "listed",
|
|
25
|
+
"field": "listed",
|
|
26
|
+
"optional": false
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "providerRejected",
|
|
30
|
+
"field": "providerRejected",
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "invalidResponse",
|
|
35
|
+
"field": "invalidResponse",
|
|
36
|
+
"optional": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "defect",
|
|
40
|
+
"field": "defect",
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"inputSchema": {
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"description": "ListFormsInput selects a zero-based page of at most 100 forms.",
|
|
47
|
+
"properties": {
|
|
48
|
+
"limit": {
|
|
49
|
+
"description": "Limit is the maximum form count; zero defaults to 20.",
|
|
50
|
+
"type": "integer"
|
|
51
|
+
},
|
|
52
|
+
"offset": {
|
|
53
|
+
"description": "Offset is the zero-based form offset; zero starts the first page.",
|
|
54
|
+
"type": "integer"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"required": [
|
|
58
|
+
"offset"
|
|
59
|
+
],
|
|
60
|
+
"type": "object"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "newGetSubmissionStep",
|
|
65
|
+
"kind": "query",
|
|
66
|
+
"operationId": "getSubmission",
|
|
67
|
+
"inputType": "GetSubmissionInput",
|
|
68
|
+
"description": "Read one submission's ID, form ID, status, and creation timestamp; answers are intentionally excluded.",
|
|
69
|
+
"fields": {
|
|
70
|
+
"stepType": "stepType",
|
|
71
|
+
"annotations": "annotations",
|
|
72
|
+
"connectionName": "connectionName",
|
|
73
|
+
"resultAttribute": "resultAttribute"
|
|
74
|
+
},
|
|
75
|
+
"branches": [
|
|
76
|
+
{
|
|
77
|
+
"id": "found",
|
|
78
|
+
"field": "found",
|
|
79
|
+
"optional": false
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "notFound",
|
|
83
|
+
"field": "notFound",
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "providerRejected",
|
|
88
|
+
"field": "providerRejected",
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "invalidResponse",
|
|
93
|
+
"field": "invalidResponse",
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "defect",
|
|
98
|
+
"field": "defect",
|
|
99
|
+
"optional": true
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"inputSchema": {
|
|
103
|
+
"additionalProperties": false,
|
|
104
|
+
"description": "GetSubmissionInput selects one numeric Jotform submission ID.",
|
|
105
|
+
"properties": {
|
|
106
|
+
"submissionId": {
|
|
107
|
+
"description": "SubmissionID is the numeric ID from Jotform's submission URL or API.",
|
|
108
|
+
"type": "string"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"required": [
|
|
112
|
+
"submissionId"
|
|
113
|
+
],
|
|
114
|
+
"type": "object"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/generated/models.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { SecretString } from "@superdurable/connectors-sdk";
|
|
4
|
+
var ConfigSchema = z.object({
|
|
5
|
+
"baseUrl": z.string().optional(),
|
|
6
|
+
"timeoutMs": z.number().int().optional(),
|
|
7
|
+
"maxResponseBytes": z.number().int().optional()
|
|
8
|
+
});
|
|
9
|
+
function decodeCredentials(value) {
|
|
10
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("credential fields are invalid");
|
|
11
|
+
const fields = value;
|
|
12
|
+
const allowed = /* @__PURE__ */ new Set(["api_key"]);
|
|
13
|
+
if (Object.keys(fields).some((key) => !allowed.has(key))) throw new TypeError("stored credential does not match the connector credential fields");
|
|
14
|
+
if (fields["api_key"] != null && !(typeof fields["api_key"] === "string")) throw new TypeError("credential api_key has an invalid type");
|
|
15
|
+
const credentials = {};
|
|
16
|
+
if (!fields["api_key"]) throw new TypeError("credential api_key is required");
|
|
17
|
+
credentials.apiKey = new SecretString(fields["api_key"] ?? "");
|
|
18
|
+
return credentials;
|
|
19
|
+
}
|
|
20
|
+
var ListFormsInputSchema = z.strictObject({
|
|
21
|
+
"offset": z.number().int(),
|
|
22
|
+
"limit": z.number().int().optional()
|
|
23
|
+
});
|
|
24
|
+
var FormMetadataSchema = z.strictObject({
|
|
25
|
+
"id": z.string(),
|
|
26
|
+
"title": z.string(),
|
|
27
|
+
"status": z.string()
|
|
28
|
+
});
|
|
29
|
+
var FormsPageSchema = z.strictObject({
|
|
30
|
+
"forms": z.array(FormMetadataSchema).nullable(),
|
|
31
|
+
"offset": z.number().int(),
|
|
32
|
+
"limit": z.number().int()
|
|
33
|
+
});
|
|
34
|
+
var GetSubmissionInputSchema = z.strictObject({
|
|
35
|
+
"submissionId": z.string()
|
|
36
|
+
});
|
|
37
|
+
var SubmissionMetadataSchema = z.strictObject({
|
|
38
|
+
"id": z.string(),
|
|
39
|
+
"formId": z.string(),
|
|
40
|
+
"status": z.string(),
|
|
41
|
+
"createdAt": z.string()
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// src/generated/definitions.ts
|
|
45
|
+
var ConnectorID = "jotform";
|
|
46
|
+
var ProviderID = "jotform";
|
|
47
|
+
var ListFormsBranch = {
|
|
48
|
+
Listed: "listed",
|
|
49
|
+
ProviderRejected: "providerRejected",
|
|
50
|
+
InvalidResponse: "invalidResponse",
|
|
51
|
+
Defect: "defect"
|
|
52
|
+
};
|
|
53
|
+
var ListFormsBranchListed = ListFormsBranch.Listed;
|
|
54
|
+
var ListFormsBranchProviderRejected = ListFormsBranch.ProviderRejected;
|
|
55
|
+
var ListFormsBranchInvalidResponse = ListFormsBranch.InvalidResponse;
|
|
56
|
+
var ListFormsBranchDefect = ListFormsBranch.Defect;
|
|
57
|
+
var ListFormsDefinition = {
|
|
58
|
+
operation: { connectorId: ConnectorID, operationId: "listForms" },
|
|
59
|
+
branches: [
|
|
60
|
+
{ id: "listed", description: "Jotform returned the selected form page." },
|
|
61
|
+
{ id: "providerRejected", description: "Jotform conclusively rejected the request.", optional: true },
|
|
62
|
+
{ id: "invalidResponse", description: "Jotform returned malformed or oversized JSON.", optional: true },
|
|
63
|
+
{ id: "defect", description: "Local input or connection credentials are invalid.", optional: true }
|
|
64
|
+
],
|
|
65
|
+
stepDefaults: { executeMethodTimeoutMs: 3e4, executeDurability: "async" }
|
|
66
|
+
};
|
|
67
|
+
var ListFormsMetadata = { kind: "query", idempotency: "none", authorization: "required" };
|
|
68
|
+
var GetSubmissionBranch = {
|
|
69
|
+
Found: "found",
|
|
70
|
+
NotFound: "notFound",
|
|
71
|
+
ProviderRejected: "providerRejected",
|
|
72
|
+
InvalidResponse: "invalidResponse",
|
|
73
|
+
Defect: "defect"
|
|
74
|
+
};
|
|
75
|
+
var GetSubmissionBranchFound = GetSubmissionBranch.Found;
|
|
76
|
+
var GetSubmissionBranchNotFound = GetSubmissionBranch.NotFound;
|
|
77
|
+
var GetSubmissionBranchProviderRejected = GetSubmissionBranch.ProviderRejected;
|
|
78
|
+
var GetSubmissionBranchInvalidResponse = GetSubmissionBranch.InvalidResponse;
|
|
79
|
+
var GetSubmissionBranchDefect = GetSubmissionBranch.Defect;
|
|
80
|
+
var GetSubmissionDefinition = {
|
|
81
|
+
operation: { connectorId: ConnectorID, operationId: "getSubmission" },
|
|
82
|
+
branches: [
|
|
83
|
+
{ id: "found", description: "Jotform returned the submission metadata." },
|
|
84
|
+
{ id: "notFound", description: "The submission does not exist or is inaccessible.", optional: true },
|
|
85
|
+
{ id: "providerRejected", description: "Jotform conclusively rejected the request.", optional: true },
|
|
86
|
+
{ id: "invalidResponse", description: "Jotform returned malformed or oversized JSON.", optional: true },
|
|
87
|
+
{ id: "defect", description: "Local input or connection credentials are invalid.", optional: true }
|
|
88
|
+
],
|
|
89
|
+
stepDefaults: { executeMethodTimeoutMs: 3e4, executeDurability: "async" }
|
|
90
|
+
};
|
|
91
|
+
var GetSubmissionMetadata = { kind: "query", idempotency: "none", authorization: "required" };
|
|
92
|
+
|
|
93
|
+
// src/generated/connection.ts
|
|
94
|
+
import { ConnectionRefSchema } from "@superdurable/connectors-sdk";
|
|
95
|
+
var Connection = class {
|
|
96
|
+
/** Stable provider and connection name. */
|
|
97
|
+
reference;
|
|
98
|
+
/** Bound provider operations. */
|
|
99
|
+
operations;
|
|
100
|
+
/** Validate a reference and bind operations. */
|
|
101
|
+
constructor(reference, operations) {
|
|
102
|
+
this.reference = ConnectionRefSchema.parse(reference);
|
|
103
|
+
if (this.reference.provider !== ProviderID) throw new TypeError("connection provider differs from the manifest");
|
|
104
|
+
if (!operations) throw new TypeError("connector operations are required");
|
|
105
|
+
this.operations = operations;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
function newConnection(client, reference) {
|
|
109
|
+
if (!client) throw new TypeError("connector client is required");
|
|
110
|
+
return new Connection(reference, client);
|
|
111
|
+
}
|
|
112
|
+
function newConnectionWithOperations(operations, reference) {
|
|
113
|
+
return new Connection(reference, operations);
|
|
114
|
+
}
|
|
115
|
+
function newProjectConnection(project, connectionName, createClient) {
|
|
116
|
+
if (!project) throw new TypeError("loaded project is required");
|
|
117
|
+
const reference = ConnectionRefSchema.parse({ provider: ProviderID, name: connectionName });
|
|
118
|
+
const selected = project.configuration.connections.find((entry) => entry.connectorId === ConnectorID && entry.connectionName === connectionName);
|
|
119
|
+
if (!selected || selected.provider !== ProviderID) throw new TypeError("project connection is not configured");
|
|
120
|
+
return newConnection(createClient(project, connectionName), reference);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
ConfigSchema,
|
|
125
|
+
decodeCredentials,
|
|
126
|
+
ListFormsInputSchema,
|
|
127
|
+
FormMetadataSchema,
|
|
128
|
+
FormsPageSchema,
|
|
129
|
+
GetSubmissionInputSchema,
|
|
130
|
+
SubmissionMetadataSchema,
|
|
131
|
+
ConnectorID,
|
|
132
|
+
ProviderID,
|
|
133
|
+
ListFormsBranch,
|
|
134
|
+
ListFormsBranchListed,
|
|
135
|
+
ListFormsBranchProviderRejected,
|
|
136
|
+
ListFormsBranchInvalidResponse,
|
|
137
|
+
ListFormsBranchDefect,
|
|
138
|
+
ListFormsDefinition,
|
|
139
|
+
ListFormsMetadata,
|
|
140
|
+
GetSubmissionBranch,
|
|
141
|
+
GetSubmissionBranchFound,
|
|
142
|
+
GetSubmissionBranchNotFound,
|
|
143
|
+
GetSubmissionBranchProviderRejected,
|
|
144
|
+
GetSubmissionBranchInvalidResponse,
|
|
145
|
+
GetSubmissionBranchDefect,
|
|
146
|
+
GetSubmissionDefinition,
|
|
147
|
+
GetSubmissionMetadata,
|
|
148
|
+
Connection,
|
|
149
|
+
newConnection,
|
|
150
|
+
newConnectionWithOperations,
|
|
151
|
+
newProjectConnection
|
|
152
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { CredentialProvider, SecretString, Query, ConnectionRef } from '@superdurable/connectors-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/** Connector configuration; omitted fields use manifest defaults. */
|
|
5
|
+
interface Config {
|
|
6
|
+
/** Jotform API endpoint, as an absolute HTTPS URL. Leave blank for the displayed US default; use https://eu-api.jotform.com for an EU account or https://hipaa-api.jotform.com for HIPAA. Override only for your account region or a trusted test gateway. */
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
/** Maximum duration of one API request as a positive Go duration such as 15s or 1m. Blank uses the displayed default; increase only for slow responses. Runtime value in milliseconds. */
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
/** Positive maximum complete API response in bytes. Blank uses the displayed default; increase for known larger form lists. Oversized responses select invalidResponse. */
|
|
11
|
+
maxResponseBytes?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Runtime schema for manifest configuration. */
|
|
14
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
15
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
16
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
maxResponseBytes: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
/** Private connector credentials resolved by the host. */
|
|
20
|
+
interface Credentials {
|
|
21
|
+
/** Secret provider-issued API key from Jotform My Account > API at https://www.jotform.com/myaccount/api. Create or select a read-only key and copy its full string; blank makes calls select defect. Dex stores it as a secret and sends it only in the APIKEY header. */
|
|
22
|
+
apiKey: SecretString;
|
|
23
|
+
}
|
|
24
|
+
/** Decode private credential fields for the connector. */
|
|
25
|
+
declare function decodeCredentials(value: unknown): Credentials;
|
|
26
|
+
/** Host-owned source of private connector credentials. */
|
|
27
|
+
type CredentialSource = CredentialProvider<Credentials>;
|
|
28
|
+
/** ListFormsInput selects a zero-based page of at most 100 forms. */
|
|
29
|
+
interface ListFormsInput {
|
|
30
|
+
/** Offset is the zero-based form offset; zero starts the first page. */
|
|
31
|
+
"offset": number;
|
|
32
|
+
/** Limit is the maximum form count; zero defaults to 20. */
|
|
33
|
+
"limit"?: number | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** FormMetadata contains public form identity and status without questions or answers. */
|
|
36
|
+
interface FormMetadata {
|
|
37
|
+
/** ID is the provider form ID. */
|
|
38
|
+
"id": string;
|
|
39
|
+
/** Title is the form's untrusted display title. */
|
|
40
|
+
"title": string;
|
|
41
|
+
/** Status is the provider form status. */
|
|
42
|
+
"status": string;
|
|
43
|
+
}
|
|
44
|
+
/** FormsPage is one offset-based Jotform form page. */
|
|
45
|
+
interface FormsPage {
|
|
46
|
+
/** Forms contains the selected page. */
|
|
47
|
+
"forms": Array<FormMetadata> | null;
|
|
48
|
+
/** Offset is the requested zero-based offset. */
|
|
49
|
+
"offset": number;
|
|
50
|
+
/** Limit is the requested maximum count. */
|
|
51
|
+
"limit": number;
|
|
52
|
+
}
|
|
53
|
+
/** GetSubmissionInput selects one numeric Jotform submission ID. */
|
|
54
|
+
interface GetSubmissionInput {
|
|
55
|
+
/** SubmissionID is the numeric ID from Jotform's submission URL or API. */
|
|
56
|
+
"submissionId": string;
|
|
57
|
+
}
|
|
58
|
+
/** SubmissionMetadata omits answers, which may contain secrets or personal data. */
|
|
59
|
+
interface SubmissionMetadata {
|
|
60
|
+
/** ID is the stable submission ID. */
|
|
61
|
+
"id": string;
|
|
62
|
+
/** FormID identifies the owning form. */
|
|
63
|
+
"formId": string;
|
|
64
|
+
/** Status is the provider submission status. */
|
|
65
|
+
"status": string;
|
|
66
|
+
/** CreatedAt is Jotform's raw creation timestamp. */
|
|
67
|
+
"createdAt": string;
|
|
68
|
+
}
|
|
69
|
+
/** Runtime validator for ListFormsInput. */
|
|
70
|
+
declare const ListFormsInputSchema: z.ZodObject<{
|
|
71
|
+
offset: z.ZodNumber;
|
|
72
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
/** Runtime validator for FormMetadata. */
|
|
75
|
+
declare const FormMetadataSchema: z.ZodObject<{
|
|
76
|
+
id: z.ZodString;
|
|
77
|
+
title: z.ZodString;
|
|
78
|
+
status: z.ZodString;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
/** Runtime validator for FormsPage. */
|
|
81
|
+
declare const FormsPageSchema: z.ZodObject<{
|
|
82
|
+
forms: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
83
|
+
id: z.ZodString;
|
|
84
|
+
title: z.ZodString;
|
|
85
|
+
status: z.ZodString;
|
|
86
|
+
}, z.core.$strict>>>;
|
|
87
|
+
offset: z.ZodNumber;
|
|
88
|
+
limit: z.ZodNumber;
|
|
89
|
+
}, z.core.$strict>;
|
|
90
|
+
/** Runtime validator for GetSubmissionInput. */
|
|
91
|
+
declare const GetSubmissionInputSchema: z.ZodObject<{
|
|
92
|
+
submissionId: z.ZodString;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
/** Runtime validator for SubmissionMetadata. */
|
|
95
|
+
declare const SubmissionMetadataSchema: z.ZodObject<{
|
|
96
|
+
id: z.ZodString;
|
|
97
|
+
formId: z.ZodString;
|
|
98
|
+
status: z.ZodString;
|
|
99
|
+
createdAt: z.ZodString;
|
|
100
|
+
}, z.core.$strict>;
|
|
101
|
+
|
|
102
|
+
/** Typed operations supplied by a client or mock. */
|
|
103
|
+
interface Operations {
|
|
104
|
+
/** Invoke listForms through this connection. */
|
|
105
|
+
listForms(): Query<ListFormsInput, FormsPage>;
|
|
106
|
+
/** Invoke getSubmission through this connection. */
|
|
107
|
+
getSubmission(): Query<GetSubmissionInput, SubmissionMetadata>;
|
|
108
|
+
}
|
|
109
|
+
/** Named connector connection kept outside Flow state. */
|
|
110
|
+
declare class Connection<BoundOperations = Operations> {
|
|
111
|
+
/** Stable provider and connection name. */
|
|
112
|
+
readonly reference: ConnectionRef;
|
|
113
|
+
/** Bound provider operations. */
|
|
114
|
+
readonly operations: BoundOperations;
|
|
115
|
+
/** Validate a reference and bind operations. */
|
|
116
|
+
constructor(reference: ConnectionRef, operations: BoundOperations);
|
|
117
|
+
}
|
|
118
|
+
/** Bind a client to a named connection. */
|
|
119
|
+
declare function newConnection(client: Operations, reference: ConnectionRef): Connection;
|
|
120
|
+
/** Bind scripted operations to a named connection. */
|
|
121
|
+
declare function newConnectionWithOperations(operations: Operations, reference: ConnectionRef): Connection;
|
|
122
|
+
|
|
123
|
+
export { Connection as C, type FormsPage as F, type GetSubmissionInput as G, type ListFormsInput as L, type Operations as O, type SubmissionMetadata as S, type Config as a, type Credentials as b, ConfigSchema as c, type CredentialSource as d, type FormMetadata as e, FormMetadataSchema as f, FormsPageSchema as g, GetSubmissionInputSchema as h, ListFormsInputSchema as i, SubmissionMetadataSchema as j, decodeCredentials as k, newConnectionWithOperations as l, newConnection as n };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { G as GetSubmissionInput, S as SubmissionMetadata, C as Connection, L as ListFormsInput, F as FormsPage, O as Operations, a as Config, b as Credentials } from './connection-D-MiEsWp.js';
|
|
2
|
+
export { c as ConfigSchema, d as CredentialSource, e as FormMetadata, f as FormMetadataSchema, g as FormsPageSchema, h as GetSubmissionInputSchema, i as ListFormsInputSchema, j as SubmissionMetadataSchema, k as decodeCredentials, n as newConnection, l as newConnectionWithOperations } from './connection-D-MiEsWp.js';
|
|
3
|
+
import { QueryDefinition, QueryStepConfig, Query, QueryResult, QueryStep, CredentialProvider, Call, QueryAttempt, Failure } from '@superdurable/connectors-sdk';
|
|
4
|
+
import { StepTarget } from '@superdurable/dex';
|
|
5
|
+
import { LoadedProject } from '@superdurable/connectors-sdk/projectconfig';
|
|
6
|
+
import { ProviderRequest, ProviderResponse } from '@superdurable/connectors-sdk/providerhttp';
|
|
7
|
+
import 'zod';
|
|
8
|
+
|
|
9
|
+
/** Stable connector identity. */
|
|
10
|
+
declare const ConnectorID = "jotform";
|
|
11
|
+
/** Provider identity for named connections. */
|
|
12
|
+
declare const ProviderID = "jotform";
|
|
13
|
+
/** Branch IDs for listForms. */
|
|
14
|
+
declare const ListFormsBranch: {
|
|
15
|
+
readonly Listed: "listed";
|
|
16
|
+
readonly ProviderRejected: "providerRejected";
|
|
17
|
+
readonly InvalidResponse: "invalidResponse";
|
|
18
|
+
readonly Defect: "defect";
|
|
19
|
+
};
|
|
20
|
+
/** Jotform returned the selected form page. */
|
|
21
|
+
declare const ListFormsBranchListed: "listed";
|
|
22
|
+
/** Jotform conclusively rejected the request. */
|
|
23
|
+
declare const ListFormsBranchProviderRejected: "providerRejected";
|
|
24
|
+
/** Jotform returned malformed or oversized JSON. */
|
|
25
|
+
declare const ListFormsBranchInvalidResponse: "invalidResponse";
|
|
26
|
+
/** Local input or connection credentials are invalid. */
|
|
27
|
+
declare const ListFormsBranchDefect: "defect";
|
|
28
|
+
/** Manifest definition for listForms. */
|
|
29
|
+
declare const ListFormsDefinition: QueryDefinition;
|
|
30
|
+
/** Manifest metadata for listForms. */
|
|
31
|
+
declare const ListFormsMetadata: {
|
|
32
|
+
readonly kind: "query";
|
|
33
|
+
readonly idempotency: "none";
|
|
34
|
+
readonly authorization: "required";
|
|
35
|
+
};
|
|
36
|
+
/** Branch IDs for getSubmission. */
|
|
37
|
+
declare const GetSubmissionBranch: {
|
|
38
|
+
readonly Found: "found";
|
|
39
|
+
readonly NotFound: "notFound";
|
|
40
|
+
readonly ProviderRejected: "providerRejected";
|
|
41
|
+
readonly InvalidResponse: "invalidResponse";
|
|
42
|
+
readonly Defect: "defect";
|
|
43
|
+
};
|
|
44
|
+
/** Jotform returned the submission metadata. */
|
|
45
|
+
declare const GetSubmissionBranchFound: "found";
|
|
46
|
+
/** The submission does not exist or is inaccessible. */
|
|
47
|
+
declare const GetSubmissionBranchNotFound: "notFound";
|
|
48
|
+
/** Jotform conclusively rejected the request. */
|
|
49
|
+
declare const GetSubmissionBranchProviderRejected: "providerRejected";
|
|
50
|
+
/** Jotform returned malformed or oversized JSON. */
|
|
51
|
+
declare const GetSubmissionBranchInvalidResponse: "invalidResponse";
|
|
52
|
+
/** Local input or connection credentials are invalid. */
|
|
53
|
+
declare const GetSubmissionBranchDefect: "defect";
|
|
54
|
+
/** Manifest definition for getSubmission. */
|
|
55
|
+
declare const GetSubmissionDefinition: QueryDefinition;
|
|
56
|
+
/** Manifest metadata for getSubmission. */
|
|
57
|
+
declare const GetSubmissionMetadata: {
|
|
58
|
+
readonly kind: "query";
|
|
59
|
+
readonly idempotency: "none";
|
|
60
|
+
readonly authorization: "required";
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** Configuration for the listForms connector Step. */
|
|
64
|
+
interface ListFormsStepConfig<StepInput, OperationInput = ListFormsInput, OperationOutput = FormsPage> extends Omit<QueryStepConfig<StepInput, OperationInput, OperationOutput>, 'operation' | 'connection' | 'branches'> {
|
|
65
|
+
/** Named connection supplying this operation. */
|
|
66
|
+
connection: Connection<{
|
|
67
|
+
listForms(): Query<OperationInput, OperationOutput>;
|
|
68
|
+
}>;
|
|
69
|
+
/** Name matching the bound connection. */
|
|
70
|
+
connectionName: string;
|
|
71
|
+
/** Jotform returned the selected form page. */
|
|
72
|
+
listed: StepTarget<QueryResult<OperationOutput>>;
|
|
73
|
+
/** Jotform conclusively rejected the request. */
|
|
74
|
+
providerRejected?: StepTarget<QueryResult<OperationOutput>>;
|
|
75
|
+
/** Jotform returned malformed or oversized JSON. */
|
|
76
|
+
invalidResponse?: StepTarget<QueryResult<OperationOutput>>;
|
|
77
|
+
/** Local input or connection credentials are invalid. */
|
|
78
|
+
defect?: StepTarget<QueryResult<OperationOutput>>;
|
|
79
|
+
}
|
|
80
|
+
/** Build the listForms Step from a named connection. */
|
|
81
|
+
declare function newListFormsStep<StepInput, OperationInput = ListFormsInput, OperationOutput = FormsPage>(configuration: ListFormsStepConfig<StepInput, OperationInput, OperationOutput>): QueryStep<StepInput, OperationInput, OperationOutput>;
|
|
82
|
+
/** Configuration for the getSubmission connector Step. */
|
|
83
|
+
interface GetSubmissionStepConfig<StepInput, OperationInput = GetSubmissionInput, OperationOutput = SubmissionMetadata> extends Omit<QueryStepConfig<StepInput, OperationInput, OperationOutput>, 'operation' | 'connection' | 'branches'> {
|
|
84
|
+
/** Named connection supplying this operation. */
|
|
85
|
+
connection: Connection<{
|
|
86
|
+
getSubmission(): Query<OperationInput, OperationOutput>;
|
|
87
|
+
}>;
|
|
88
|
+
/** Name matching the bound connection. */
|
|
89
|
+
connectionName: string;
|
|
90
|
+
/** Jotform returned the submission metadata. */
|
|
91
|
+
found: StepTarget<QueryResult<OperationOutput>>;
|
|
92
|
+
/** The submission does not exist or is inaccessible. */
|
|
93
|
+
notFound?: StepTarget<QueryResult<OperationOutput>>;
|
|
94
|
+
/** Jotform conclusively rejected the request. */
|
|
95
|
+
providerRejected?: StepTarget<QueryResult<OperationOutput>>;
|
|
96
|
+
/** Jotform returned malformed or oversized JSON. */
|
|
97
|
+
invalidResponse?: StepTarget<QueryResult<OperationOutput>>;
|
|
98
|
+
/** Local input or connection credentials are invalid. */
|
|
99
|
+
defect?: StepTarget<QueryResult<OperationOutput>>;
|
|
100
|
+
}
|
|
101
|
+
/** Build the getSubmission Step from a named connection. */
|
|
102
|
+
declare function newGetSubmissionStep<StepInput, OperationInput = GetSubmissionInput, OperationOutput = SubmissionMetadata>(configuration: GetSubmissionStepConfig<StepInput, OperationInput, OperationOutput>): QueryStep<StepInput, OperationInput, OperationOutput>;
|
|
103
|
+
|
|
104
|
+
/** Open one named Jotform connection from Dex project configuration. */
|
|
105
|
+
declare function newProjectConnection(project: LoadedProject, connectionName: string): Connection<Operations>;
|
|
106
|
+
|
|
107
|
+
/** Optional provider transport for local tests and examples. */
|
|
108
|
+
interface JotformClientOptions {
|
|
109
|
+
/** One bounded provider request sender. */ send?: (request: ProviderRequest) => Promise<ProviderResponse>;
|
|
110
|
+
}
|
|
111
|
+
interface ProviderOutcome {
|
|
112
|
+
body?: Uint8Array;
|
|
113
|
+
branch?: string;
|
|
114
|
+
failure?: Failure;
|
|
115
|
+
retry?: boolean;
|
|
116
|
+
retryAfterMs?: number;
|
|
117
|
+
}
|
|
118
|
+
/** Authenticated Jotform client with call-time API key resolution. */
|
|
119
|
+
declare class JotformClient {
|
|
120
|
+
private readonly credentials;
|
|
121
|
+
private readonly baseUrl;
|
|
122
|
+
private readonly timeoutMs;
|
|
123
|
+
private readonly maxResponseBytes;
|
|
124
|
+
private readonly sendRequest;
|
|
125
|
+
/** Validate configuration without contacting Jotform. */
|
|
126
|
+
constructor(config: Config, credentials: CredentialProvider<Credentials>, options?: JotformClientOptions);
|
|
127
|
+
/** Bind the form-list Query. */ listForms(): ListFormsOperation;
|
|
128
|
+
/** Bind the submission metadata Query. */ getSubmission(): GetSubmissionOperation;
|
|
129
|
+
/** Fetch one provider response and classify transport and HTTP failures. */
|
|
130
|
+
exchange(call: Call, operation: string, path: string, hasNotFound: boolean): Promise<ProviderOutcome>;
|
|
131
|
+
}
|
|
132
|
+
/** List form IDs, titles, and statuses without questions or answers. */
|
|
133
|
+
declare class ListFormsOperation implements Query<ListFormsInput, FormsPage> {
|
|
134
|
+
private readonly client;
|
|
135
|
+
/** Bind the provider client. */ constructor(client: JotformClient);
|
|
136
|
+
/** Return the manifest-generated contract. */ definition(): QueryDefinition;
|
|
137
|
+
/** Read one page or select a Go-compatible optional branch. */
|
|
138
|
+
invoke(call: Call, input: ListFormsInput): Promise<QueryAttempt<FormsPage>>;
|
|
139
|
+
}
|
|
140
|
+
/** Read one submission's ID, form ID, status, and timestamp without answers. */
|
|
141
|
+
declare class GetSubmissionOperation implements Query<GetSubmissionInput, SubmissionMetadata> {
|
|
142
|
+
private readonly client;
|
|
143
|
+
/** Bind the provider client. */ constructor(client: JotformClient);
|
|
144
|
+
/** Return the manifest-generated contract. */ definition(): QueryDefinition;
|
|
145
|
+
/** Read a submission or select a Go-compatible optional branch. */
|
|
146
|
+
invoke(call: Call, input: GetSubmissionInput): Promise<QueryAttempt<SubmissionMetadata>>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { Config, Connection, ConnectorID, Credentials, FormsPage, GetSubmissionBranch, GetSubmissionBranchDefect, GetSubmissionBranchFound, GetSubmissionBranchInvalidResponse, GetSubmissionBranchNotFound, GetSubmissionBranchProviderRejected, GetSubmissionDefinition, GetSubmissionInput, GetSubmissionMetadata, GetSubmissionOperation, type GetSubmissionStepConfig, JotformClient, type JotformClientOptions, ListFormsBranch, ListFormsBranchDefect, ListFormsBranchInvalidResponse, ListFormsBranchListed, ListFormsBranchProviderRejected, ListFormsDefinition, ListFormsInput, ListFormsMetadata, ListFormsOperation, type ListFormsStepConfig, ProviderID, SubmissionMetadata, newGetSubmissionStep, newListFormsStep, newProjectConnection };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfigSchema,
|
|
3
|
+
Connection,
|
|
4
|
+
ConnectorID,
|
|
5
|
+
FormMetadataSchema,
|
|
6
|
+
FormsPageSchema,
|
|
7
|
+
GetSubmissionBranch,
|
|
8
|
+
GetSubmissionBranchDefect,
|
|
9
|
+
GetSubmissionBranchFound,
|
|
10
|
+
GetSubmissionBranchInvalidResponse,
|
|
11
|
+
GetSubmissionBranchNotFound,
|
|
12
|
+
GetSubmissionBranchProviderRejected,
|
|
13
|
+
GetSubmissionDefinition,
|
|
14
|
+
GetSubmissionInputSchema,
|
|
15
|
+
GetSubmissionMetadata,
|
|
16
|
+
ListFormsBranch,
|
|
17
|
+
ListFormsBranchDefect,
|
|
18
|
+
ListFormsBranchInvalidResponse,
|
|
19
|
+
ListFormsBranchListed,
|
|
20
|
+
ListFormsBranchProviderRejected,
|
|
21
|
+
ListFormsDefinition,
|
|
22
|
+
ListFormsInputSchema,
|
|
23
|
+
ListFormsMetadata,
|
|
24
|
+
ProviderID,
|
|
25
|
+
SubmissionMetadataSchema,
|
|
26
|
+
decodeCredentials,
|
|
27
|
+
newConnection,
|
|
28
|
+
newConnectionWithOperations,
|
|
29
|
+
newProjectConnection
|
|
30
|
+
} from "./chunk-ZKAGZX4P.js";
|
|
31
|
+
|
|
32
|
+
// src/generated/steps.ts
|
|
33
|
+
import { goToBranch, newQueryStep } from "@superdurable/connectors-sdk";
|
|
34
|
+
function newListFormsStep(configuration) {
|
|
35
|
+
const { connection, connectionName, listed, providerRejected, invalidResponse, defect, ...stepConfiguration } = configuration;
|
|
36
|
+
if (!connection || connection.reference.name !== connectionName) throw new TypeError("Step connection name differs from the bound connection");
|
|
37
|
+
return newQueryStep({ ...stepConfiguration, operation: connection.operations.listForms(), connection: connection.reference, branches: [
|
|
38
|
+
goToBranch("listed", listed),
|
|
39
|
+
...providerRejected ? [goToBranch("providerRejected", providerRejected)] : [],
|
|
40
|
+
...invalidResponse ? [goToBranch("invalidResponse", invalidResponse)] : [],
|
|
41
|
+
...defect ? [goToBranch("defect", defect)] : []
|
|
42
|
+
] });
|
|
43
|
+
}
|
|
44
|
+
function newGetSubmissionStep(configuration) {
|
|
45
|
+
const { connection, connectionName, found, notFound, providerRejected, invalidResponse, defect, ...stepConfiguration } = configuration;
|
|
46
|
+
if (!connection || connection.reference.name !== connectionName) throw new TypeError("Step connection name differs from the bound connection");
|
|
47
|
+
return newQueryStep({ ...stepConfiguration, operation: connection.operations.getSubmission(), connection: connection.reference, branches: [
|
|
48
|
+
goToBranch("found", found),
|
|
49
|
+
...notFound ? [goToBranch("notFound", notFound)] : [],
|
|
50
|
+
...providerRejected ? [goToBranch("providerRejected", providerRejected)] : [],
|
|
51
|
+
...invalidResponse ? [goToBranch("invalidResponse", invalidResponse)] : [],
|
|
52
|
+
...defect ? [goToBranch("defect", defect)] : []
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/project.ts
|
|
57
|
+
import { SecretString as SecretString2 } from "@superdurable/connectors-sdk";
|
|
58
|
+
import { z } from "zod";
|
|
59
|
+
|
|
60
|
+
// src/client.ts
|
|
61
|
+
import { SecretString, newQueryBranch, newQueryRetry } from "@superdurable/connectors-sdk";
|
|
62
|
+
import { BodyTooLargeError, isHeaderSafeCredential, parseRetryAfter, sendProviderRequest, validateBaseURL } from "@superdurable/connectors-sdk/providerhttp";
|
|
63
|
+
var emptyPage = () => ({ forms: [], offset: 0, limit: 0 });
|
|
64
|
+
var emptySubmission = () => ({ id: "", formId: "", status: "", createdAt: "" });
|
|
65
|
+
var numericID = /^[0-9]{1,24}$/;
|
|
66
|
+
var JotformClient = class {
|
|
67
|
+
/** Validate configuration without contacting Jotform. */
|
|
68
|
+
constructor(config, credentials, options = {}) {
|
|
69
|
+
this.credentials = credentials;
|
|
70
|
+
if (!credentials) throw new TypeError("Jotform credential source is required");
|
|
71
|
+
this.baseUrl = validateBaseURL(config.baseUrl || "https://api.jotform.com");
|
|
72
|
+
this.timeoutMs = config.timeoutMs || 15e3;
|
|
73
|
+
this.maxResponseBytes = config.maxResponseBytes || 1048576;
|
|
74
|
+
if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs <= 0) throw new TypeError("Jotform timeout is invalid");
|
|
75
|
+
if (!Number.isSafeInteger(this.maxResponseBytes) || this.maxResponseBytes <= 0) throw new TypeError("Jotform response limit is invalid");
|
|
76
|
+
this.sendRequest = options.send ?? sendProviderRequest;
|
|
77
|
+
}
|
|
78
|
+
credentials;
|
|
79
|
+
baseUrl;
|
|
80
|
+
timeoutMs;
|
|
81
|
+
maxResponseBytes;
|
|
82
|
+
sendRequest;
|
|
83
|
+
/** Bind the form-list Query. */
|
|
84
|
+
listForms() {
|
|
85
|
+
return new ListFormsOperation(this);
|
|
86
|
+
}
|
|
87
|
+
/** Bind the submission metadata Query. */
|
|
88
|
+
getSubmission() {
|
|
89
|
+
return new GetSubmissionOperation(this);
|
|
90
|
+
}
|
|
91
|
+
/** Fetch one provider response and classify transport and HTTP failures. */
|
|
92
|
+
async exchange(call, operation, path, hasNotFound) {
|
|
93
|
+
let apiKey;
|
|
94
|
+
try {
|
|
95
|
+
const resolved = await this.credentials.resolve(call, call.context.cancellationSignal);
|
|
96
|
+
apiKey = resolved.apiKey instanceof SecretString ? resolved.apiKey.reveal() : "";
|
|
97
|
+
} catch {
|
|
98
|
+
return { branch: "defect", failure: failure(operation, "AUTHENTICATION", "connection credentials are unavailable or invalid") };
|
|
99
|
+
}
|
|
100
|
+
if (!apiKey || !isHeaderSafeCredential(apiKey)) return { branch: "defect", failure: failure(operation, "AUTHENTICATION", "connection credentials are unavailable or invalid") };
|
|
101
|
+
const request = {
|
|
102
|
+
url: `${this.baseUrl}${path}`,
|
|
103
|
+
method: "GET",
|
|
104
|
+
headers: { Accept: "application/json", APIKEY: apiKey },
|
|
105
|
+
maxResponseBytes: this.maxResponseBytes,
|
|
106
|
+
timeoutMs: this.timeoutMs,
|
|
107
|
+
addressPolicy: this.baseUrl.startsWith("https://") ? "publicHTTPS" : "privateNetworkHTTP",
|
|
108
|
+
signal: call.context.cancellationSignal
|
|
109
|
+
};
|
|
110
|
+
let response;
|
|
111
|
+
try {
|
|
112
|
+
response = await this.sendRequest(request);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof BodyTooLargeError && error.status !== void 0) {
|
|
115
|
+
response = { status: error.status, headers: error.headers ?? {}, body: new Uint8Array() };
|
|
116
|
+
if (response.status === 200) return { branch: "invalidResponse", failure: failure(operation, "RESPONSE_TOO_LARGE", "Jotform response exceeded the configured limit") };
|
|
117
|
+
} else return { retry: true, failure: failure(operation, "TRANSPORT", "Jotform request failed") };
|
|
118
|
+
}
|
|
119
|
+
const status = response.status;
|
|
120
|
+
const retryAfter = parseRetryAfter(headerValue(response.headers["retry-after"]));
|
|
121
|
+
if (status === 429) return { retry: true, retryAfterMs: retryAfter, failure: failure(operation, "RATE_LIMIT", "Jotform rate limited the request") };
|
|
122
|
+
if (status === 408 || status >= 500) return { retry: true, retryAfterMs: retryAfter, failure: failure(operation, "AVAILABILITY", "Jotform is temporarily unavailable") };
|
|
123
|
+
if (status === 404 && hasNotFound) return { branch: "notFound", failure: failure(operation, "NOT_FOUND", "Jotform did not find the submission") };
|
|
124
|
+
if (status !== 200) return { branch: "providerRejected", failure: failure(operation, "PROVIDER_REJECTION", `Jotform rejected HTTP ${status}`) };
|
|
125
|
+
if (response.body.length > this.maxResponseBytes) return { branch: "invalidResponse", failure: failure(operation, "RESPONSE_TOO_LARGE", "Jotform response exceeded the configured limit") };
|
|
126
|
+
return { body: response.body };
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var ListFormsOperation = class {
|
|
130
|
+
/** Bind the provider client. */
|
|
131
|
+
constructor(client) {
|
|
132
|
+
this.client = client;
|
|
133
|
+
}
|
|
134
|
+
client;
|
|
135
|
+
/** Return the manifest-generated contract. */
|
|
136
|
+
definition() {
|
|
137
|
+
return ListFormsDefinition;
|
|
138
|
+
}
|
|
139
|
+
/** Read one page or select a Go-compatible optional branch. */
|
|
140
|
+
async invoke(call, input) {
|
|
141
|
+
if (!input || !Number.isSafeInteger(input.offset) || input.offset < 0 || input.limit !== void 0 && (!Number.isSafeInteger(input.limit) || input.limit < 0 || input.limit > 100)) {
|
|
142
|
+
return terminal("listForms", "defect", "VALIDATION", "offset or limit is invalid", emptyPage());
|
|
143
|
+
}
|
|
144
|
+
const limit = input.limit || 20;
|
|
145
|
+
const path = `/user/forms?${new URLSearchParams({ offset: String(input.offset), limit: String(limit) })}`;
|
|
146
|
+
const result = await this.client.exchange(call, "listForms", path, false);
|
|
147
|
+
if (result.retry) return newQueryRetry(result.failure, result.retryAfterMs);
|
|
148
|
+
if (result.failure) return newQueryBranch(result.branch, emptyPage(), {}, result.failure);
|
|
149
|
+
const document = parseJSON(result.body);
|
|
150
|
+
if (!isObject(document)) return invalid("listForms", emptyPage());
|
|
151
|
+
const providerDecision = responseCodeDecision("listForms", document, emptyPage(), false);
|
|
152
|
+
if (providerDecision) return providerDecision;
|
|
153
|
+
if (!Array.isArray(document.content)) return invalid("listForms", emptyPage());
|
|
154
|
+
const forms = [];
|
|
155
|
+
for (const item of document.content) {
|
|
156
|
+
if (!isObject(item) || typeof item.id !== "string" || !numericID.test(item.id) || typeof item.title !== "string" || !item.title || item.status != null && typeof item.status !== "string") return invalid("listForms", emptyPage());
|
|
157
|
+
forms.push({ id: item.id, title: item.title, status: item.status ?? "" });
|
|
158
|
+
}
|
|
159
|
+
return newQueryBranch("listed", { forms, offset: input.offset, limit });
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var GetSubmissionOperation = class {
|
|
163
|
+
/** Bind the provider client. */
|
|
164
|
+
constructor(client) {
|
|
165
|
+
this.client = client;
|
|
166
|
+
}
|
|
167
|
+
client;
|
|
168
|
+
/** Return the manifest-generated contract. */
|
|
169
|
+
definition() {
|
|
170
|
+
return GetSubmissionDefinition;
|
|
171
|
+
}
|
|
172
|
+
/** Read a submission or select a Go-compatible optional branch. */
|
|
173
|
+
async invoke(call, input) {
|
|
174
|
+
if (!input || typeof input.submissionId !== "string" || !numericID.test(input.submissionId)) return terminal("getSubmission", "defect", "VALIDATION", "submission ID must be numeric", emptySubmission());
|
|
175
|
+
const result = await this.client.exchange(call, "getSubmission", `/submission/${input.submissionId}`, true);
|
|
176
|
+
if (result.retry) return newQueryRetry(result.failure, result.retryAfterMs);
|
|
177
|
+
if (result.failure) return newQueryBranch(result.branch, emptySubmission(), {}, result.failure);
|
|
178
|
+
const document = parseJSON(result.body);
|
|
179
|
+
if (!isObject(document)) return invalid("getSubmission", emptySubmission());
|
|
180
|
+
const providerDecision = responseCodeDecision("getSubmission", document, emptySubmission(), true);
|
|
181
|
+
if (providerDecision) return providerDecision;
|
|
182
|
+
const content = document.content;
|
|
183
|
+
if (!isObject(content) || typeof content.id !== "string" || !numericID.test(content.id) || typeof content.form_id !== "string" || !numericID.test(content.form_id) || typeof content.created_at !== "string" || !content.created_at || content.status != null && typeof content.status !== "string") return invalid("getSubmission", emptySubmission());
|
|
184
|
+
return newQueryBranch("found", { id: content.id, formId: content.form_id, status: content.status ?? "", createdAt: content.created_at });
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
function responseCodeDecision(operation, document, empty, hasNotFound) {
|
|
188
|
+
const code = document.responseCode;
|
|
189
|
+
if (code != null && (!Number.isInteger(code) || typeof code !== "number")) return invalid(operation, empty);
|
|
190
|
+
if (code === 200) return void 0;
|
|
191
|
+
if (code === 429 || typeof code === "number" && code >= 500) return newQueryRetry(failure(operation, "AVAILABILITY", "Jotform reported temporary unavailability"));
|
|
192
|
+
if (code === 404 && hasNotFound) return terminal(operation, "notFound", "NOT_FOUND", "Jotform did not find the submission", empty);
|
|
193
|
+
return terminal(operation, "providerRejected", "PROVIDER_REJECTION", "Jotform rejected the request", empty);
|
|
194
|
+
}
|
|
195
|
+
function failure(operation, kind, message) {
|
|
196
|
+
return { provider: "jotform", operation, kind, message };
|
|
197
|
+
}
|
|
198
|
+
function terminal(operation, branch, kind, message, empty) {
|
|
199
|
+
return newQueryBranch(branch, empty, {}, failure(operation, kind, message));
|
|
200
|
+
}
|
|
201
|
+
function invalid(operation, empty) {
|
|
202
|
+
return terminal(operation, "invalidResponse", "PROTOCOL", "Jotform returned invalid JSON", empty);
|
|
203
|
+
}
|
|
204
|
+
function isObject(value) {
|
|
205
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
206
|
+
}
|
|
207
|
+
function parseJSON(body) {
|
|
208
|
+
try {
|
|
209
|
+
return JSON.parse(Buffer.from(body).toString("utf8"));
|
|
210
|
+
} catch {
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function headerValue(value) {
|
|
215
|
+
return Array.isArray(value) ? value[0] ?? "" : value ?? "";
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/project.ts
|
|
219
|
+
function newProjectConnection2(project, connectionName) {
|
|
220
|
+
return newProjectConnection(project, connectionName, (loadedProject, name) => {
|
|
221
|
+
const selected = loadedProject.configuration.connections.find((entry) => entry.connectorId === "jotform" && entry.connectionName === name);
|
|
222
|
+
if (!selected) throw new TypeError("Jotform project connection is not configured");
|
|
223
|
+
const fields = z.strictObject({ baseUrl: z.string().optional(), timeout: z.union([z.string(), z.number().int()]).optional(), maxResponseBytes: z.number().int().optional() }).parse(selected.configuration);
|
|
224
|
+
const timeoutMs = typeof fields.timeout === "number" ? Math.ceil(fields.timeout / 1e6) : fields.timeout ? parseDurationMilliseconds(fields.timeout) : void 0;
|
|
225
|
+
const config = {
|
|
226
|
+
...fields.baseUrl ? { baseUrl: fields.baseUrl } : {},
|
|
227
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
228
|
+
...fields.maxResponseBytes !== void 0 ? { maxResponseBytes: fields.maxResponseBytes } : {}
|
|
229
|
+
};
|
|
230
|
+
const credentials = {
|
|
231
|
+
async resolve(_call, signal) {
|
|
232
|
+
const privateFields = await loadedProject.resolveCredential("jotform", name, signal);
|
|
233
|
+
if (typeof privateFields.api_key !== "string") throw new TypeError("Jotform API Key is unavailable");
|
|
234
|
+
return { apiKey: new SecretString2(privateFields.api_key) };
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
return new JotformClient(config, credentials);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function parseDurationMilliseconds(value) {
|
|
241
|
+
let remaining = value;
|
|
242
|
+
let milliseconds = 0;
|
|
243
|
+
const units = { ns: 1e-6, us: 1e-3, "\xB5s": 1e-3, ms: 1, s: 1e3, m: 6e4, h: 36e5 };
|
|
244
|
+
while (remaining) {
|
|
245
|
+
const part = /^(\d+(?:\.\d+)?)(ns|us|µs|ms|s|m|h)/.exec(remaining);
|
|
246
|
+
if (!part) throw new TypeError("Jotform timeout must be a positive Go duration");
|
|
247
|
+
milliseconds += Number(part[1]) * (units[part[2] ?? ""] ?? NaN);
|
|
248
|
+
remaining = remaining.slice(part[0].length);
|
|
249
|
+
}
|
|
250
|
+
if (!Number.isSafeInteger(milliseconds) || milliseconds <= 0) throw new TypeError("Jotform timeout must resolve to positive whole milliseconds");
|
|
251
|
+
return milliseconds;
|
|
252
|
+
}
|
|
253
|
+
export {
|
|
254
|
+
ConfigSchema,
|
|
255
|
+
Connection,
|
|
256
|
+
ConnectorID,
|
|
257
|
+
FormMetadataSchema,
|
|
258
|
+
FormsPageSchema,
|
|
259
|
+
GetSubmissionBranch,
|
|
260
|
+
GetSubmissionBranchDefect,
|
|
261
|
+
GetSubmissionBranchFound,
|
|
262
|
+
GetSubmissionBranchInvalidResponse,
|
|
263
|
+
GetSubmissionBranchNotFound,
|
|
264
|
+
GetSubmissionBranchProviderRejected,
|
|
265
|
+
GetSubmissionDefinition,
|
|
266
|
+
GetSubmissionInputSchema,
|
|
267
|
+
GetSubmissionMetadata,
|
|
268
|
+
GetSubmissionOperation,
|
|
269
|
+
JotformClient,
|
|
270
|
+
ListFormsBranch,
|
|
271
|
+
ListFormsBranchDefect,
|
|
272
|
+
ListFormsBranchInvalidResponse,
|
|
273
|
+
ListFormsBranchListed,
|
|
274
|
+
ListFormsBranchProviderRejected,
|
|
275
|
+
ListFormsDefinition,
|
|
276
|
+
ListFormsInputSchema,
|
|
277
|
+
ListFormsMetadata,
|
|
278
|
+
ListFormsOperation,
|
|
279
|
+
ProviderID,
|
|
280
|
+
SubmissionMetadataSchema,
|
|
281
|
+
decodeCredentials,
|
|
282
|
+
newConnection,
|
|
283
|
+
newConnectionWithOperations,
|
|
284
|
+
newGetSubmissionStep,
|
|
285
|
+
newListFormsStep,
|
|
286
|
+
newProjectConnection2 as newProjectConnection
|
|
287
|
+
};
|
package/dist/mock.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { MockQuery, Case } from '@superdurable/connectors-sdk/connectormock';
|
|
2
|
+
import { Failure } from '@superdurable/connectors-sdk';
|
|
3
|
+
import { O as Operations, C as Connection, L as ListFormsInput, F as FormsPage, G as GetSubmissionInput, S as SubmissionMetadata, e as FormMetadata } from './connection-D-MiEsWp.js';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
/** Go zero value for ListFormsInput in scripted cases. */
|
|
7
|
+
declare const emptyListFormsInput: ListFormsInput;
|
|
8
|
+
/** Go zero value for FormMetadata in scripted cases. */
|
|
9
|
+
declare const emptyFormMetadata: FormMetadata;
|
|
10
|
+
/** Go zero value for FormsPage in scripted cases. */
|
|
11
|
+
declare const emptyFormsPage: FormsPage;
|
|
12
|
+
/** Go zero value for GetSubmissionInput in scripted cases. */
|
|
13
|
+
declare const emptyGetSubmissionInput: GetSubmissionInput;
|
|
14
|
+
/** Go zero value for SubmissionMetadata in scripted cases. */
|
|
15
|
+
declare const emptySubmissionMetadata: SubmissionMetadata;
|
|
16
|
+
/** Script the listed branch. */
|
|
17
|
+
declare function listFormsListed(value: FormsPage, failure?: Failure): Case<FormsPage>;
|
|
18
|
+
/** Script the providerRejected branch. */
|
|
19
|
+
declare function listFormsProviderRejected(value: FormsPage, failure?: Failure): Case<FormsPage>;
|
|
20
|
+
/** Script the invalidResponse branch. */
|
|
21
|
+
declare function listFormsInvalidResponse(value: FormsPage, failure?: Failure): Case<FormsPage>;
|
|
22
|
+
/** Script the defect branch. */
|
|
23
|
+
declare function listFormsDefect(value: FormsPage, failure?: Failure): Case<FormsPage>;
|
|
24
|
+
/** Script a safe retry of listForms. */
|
|
25
|
+
declare function listFormsRetry(failure: Failure, retryAfterMs?: number): Case<FormsPage>;
|
|
26
|
+
/** Manifest scenario listedDefault for listForms. */
|
|
27
|
+
declare function listFormsListedDefault(): Case<FormsPage>;
|
|
28
|
+
/** Default listForms scenario. */
|
|
29
|
+
declare function listFormsDefault(): Case<FormsPage>;
|
|
30
|
+
/** Script the found branch. */
|
|
31
|
+
declare function getSubmissionFound(value: SubmissionMetadata, failure?: Failure): Case<SubmissionMetadata>;
|
|
32
|
+
/** Script the notFound branch. */
|
|
33
|
+
declare function getSubmissionNotFound(value: SubmissionMetadata, failure?: Failure): Case<SubmissionMetadata>;
|
|
34
|
+
/** Script the providerRejected branch. */
|
|
35
|
+
declare function getSubmissionProviderRejected(value: SubmissionMetadata, failure?: Failure): Case<SubmissionMetadata>;
|
|
36
|
+
/** Script the invalidResponse branch. */
|
|
37
|
+
declare function getSubmissionInvalidResponse(value: SubmissionMetadata, failure?: Failure): Case<SubmissionMetadata>;
|
|
38
|
+
/** Script the defect branch. */
|
|
39
|
+
declare function getSubmissionDefect(value: SubmissionMetadata, failure?: Failure): Case<SubmissionMetadata>;
|
|
40
|
+
/** Script a safe retry of getSubmission. */
|
|
41
|
+
declare function getSubmissionRetry(failure: Failure, retryAfterMs?: number): Case<SubmissionMetadata>;
|
|
42
|
+
/** Manifest scenario foundDefault for getSubmission. */
|
|
43
|
+
declare function getSubmissionFoundDefault(): Case<SubmissionMetadata>;
|
|
44
|
+
/** Default getSubmission scenario. */
|
|
45
|
+
declare function getSubmissionDefault(): Case<SubmissionMetadata>;
|
|
46
|
+
/** Scripted operations and manifest defaults for this connector. */
|
|
47
|
+
declare class GeneratedMock implements Operations {
|
|
48
|
+
#private;
|
|
49
|
+
constructor(connectionName: string);
|
|
50
|
+
connection(): Connection;
|
|
51
|
+
listForms(): MockQuery<ListFormsInput, FormsPage>;
|
|
52
|
+
getSubmission(): MockQuery<GetSubmissionInput, SubmissionMetadata>;
|
|
53
|
+
assertNoFailures(): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { GeneratedMock, GeneratedMock as Mock, emptyFormMetadata, emptyFormsPage, emptyGetSubmissionInput, emptyListFormsInput, emptySubmissionMetadata, getSubmissionDefault, getSubmissionDefect, getSubmissionFound, getSubmissionFoundDefault, getSubmissionInvalidResponse, getSubmissionNotFound, getSubmissionProviderRejected, getSubmissionRetry, listFormsDefault, listFormsDefect, listFormsInvalidResponse, listFormsListed, listFormsListedDefault, listFormsProviderRejected, listFormsRetry };
|
package/dist/mock.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FormMetadataSchema,
|
|
3
|
+
FormsPageSchema,
|
|
4
|
+
GetSubmissionDefinition,
|
|
5
|
+
GetSubmissionInputSchema,
|
|
6
|
+
ListFormsDefinition,
|
|
7
|
+
ListFormsInputSchema,
|
|
8
|
+
ProviderID,
|
|
9
|
+
SubmissionMetadataSchema,
|
|
10
|
+
newConnectionWithOperations
|
|
11
|
+
} from "./chunk-ZKAGZX4P.js";
|
|
12
|
+
|
|
13
|
+
// src/generated/mock.ts
|
|
14
|
+
import { branchCase, retryCase, newQuery } from "@superdurable/connectors-sdk/connectormock";
|
|
15
|
+
var emptyListFormsInput = ListFormsInputSchema.parse({
|
|
16
|
+
"offset": 0
|
|
17
|
+
});
|
|
18
|
+
var emptyFormMetadata = FormMetadataSchema.parse({
|
|
19
|
+
"id": "",
|
|
20
|
+
"title": "",
|
|
21
|
+
"status": ""
|
|
22
|
+
});
|
|
23
|
+
var emptyFormsPage = FormsPageSchema.parse({
|
|
24
|
+
"forms": [],
|
|
25
|
+
"offset": 0,
|
|
26
|
+
"limit": 0
|
|
27
|
+
});
|
|
28
|
+
var emptyGetSubmissionInput = GetSubmissionInputSchema.parse({
|
|
29
|
+
"submissionId": ""
|
|
30
|
+
});
|
|
31
|
+
var emptySubmissionMetadata = SubmissionMetadataSchema.parse({
|
|
32
|
+
"id": "",
|
|
33
|
+
"formId": "",
|
|
34
|
+
"status": "",
|
|
35
|
+
"createdAt": ""
|
|
36
|
+
});
|
|
37
|
+
function listFormsListed(value, failure) {
|
|
38
|
+
return branchCase("listed", value, failure);
|
|
39
|
+
}
|
|
40
|
+
function listFormsProviderRejected(value, failure) {
|
|
41
|
+
return branchCase("providerRejected", value, failure);
|
|
42
|
+
}
|
|
43
|
+
function listFormsInvalidResponse(value, failure) {
|
|
44
|
+
return branchCase("invalidResponse", value, failure);
|
|
45
|
+
}
|
|
46
|
+
function listFormsDefect(value, failure) {
|
|
47
|
+
return branchCase("defect", value, failure);
|
|
48
|
+
}
|
|
49
|
+
function listFormsRetry(failure, retryAfterMs = 0) {
|
|
50
|
+
return retryCase(failure, retryAfterMs);
|
|
51
|
+
}
|
|
52
|
+
function listFormsListedDefault() {
|
|
53
|
+
const value = FormsPageSchema.parse({ "forms": [{ "id": "241234567890123", "status": "ENABLED", "title": "Contact request" }], "limit": 20, "offset": 0 });
|
|
54
|
+
return branchCase("listed", value);
|
|
55
|
+
}
|
|
56
|
+
function listFormsDefault() {
|
|
57
|
+
return listFormsListedDefault();
|
|
58
|
+
}
|
|
59
|
+
function getSubmissionFound(value, failure) {
|
|
60
|
+
return branchCase("found", value, failure);
|
|
61
|
+
}
|
|
62
|
+
function getSubmissionNotFound(value, failure) {
|
|
63
|
+
return branchCase("notFound", value, failure);
|
|
64
|
+
}
|
|
65
|
+
function getSubmissionProviderRejected(value, failure) {
|
|
66
|
+
return branchCase("providerRejected", value, failure);
|
|
67
|
+
}
|
|
68
|
+
function getSubmissionInvalidResponse(value, failure) {
|
|
69
|
+
return branchCase("invalidResponse", value, failure);
|
|
70
|
+
}
|
|
71
|
+
function getSubmissionDefect(value, failure) {
|
|
72
|
+
return branchCase("defect", value, failure);
|
|
73
|
+
}
|
|
74
|
+
function getSubmissionRetry(failure, retryAfterMs = 0) {
|
|
75
|
+
return retryCase(failure, retryAfterMs);
|
|
76
|
+
}
|
|
77
|
+
function getSubmissionFoundDefault() {
|
|
78
|
+
const value = SubmissionMetadataSchema.parse({ "createdAt": "2026-11-07 10:00:00", "formId": "241234567890123", "id": "241234567890123456", "status": "ACTIVE" });
|
|
79
|
+
return branchCase("found", value);
|
|
80
|
+
}
|
|
81
|
+
function getSubmissionDefault() {
|
|
82
|
+
return getSubmissionFoundDefault();
|
|
83
|
+
}
|
|
84
|
+
var GeneratedMock = class {
|
|
85
|
+
#listForms;
|
|
86
|
+
#getSubmission;
|
|
87
|
+
#connection;
|
|
88
|
+
constructor(connectionName) {
|
|
89
|
+
this.#listForms = newQuery(ListFormsDefinition).default(listFormsDefault());
|
|
90
|
+
this.#getSubmission = newQuery(GetSubmissionDefinition).default(getSubmissionDefault());
|
|
91
|
+
this.#connection = newConnectionWithOperations(this, { provider: ProviderID, name: connectionName });
|
|
92
|
+
}
|
|
93
|
+
connection() {
|
|
94
|
+
return this.#connection;
|
|
95
|
+
}
|
|
96
|
+
listForms() {
|
|
97
|
+
return this.#listForms;
|
|
98
|
+
}
|
|
99
|
+
getSubmission() {
|
|
100
|
+
return this.#getSubmission;
|
|
101
|
+
}
|
|
102
|
+
assertNoFailures() {
|
|
103
|
+
this.#listForms.assertNoFailures();
|
|
104
|
+
this.#getSubmission.assertNoFailures();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
export {
|
|
108
|
+
GeneratedMock,
|
|
109
|
+
GeneratedMock as Mock,
|
|
110
|
+
emptyFormMetadata,
|
|
111
|
+
emptyFormsPage,
|
|
112
|
+
emptyGetSubmissionInput,
|
|
113
|
+
emptyListFormsInput,
|
|
114
|
+
emptySubmissionMetadata,
|
|
115
|
+
getSubmissionDefault,
|
|
116
|
+
getSubmissionDefect,
|
|
117
|
+
getSubmissionFound,
|
|
118
|
+
getSubmissionFoundDefault,
|
|
119
|
+
getSubmissionInvalidResponse,
|
|
120
|
+
getSubmissionNotFound,
|
|
121
|
+
getSubmissionProviderRejected,
|
|
122
|
+
getSubmissionRetry,
|
|
123
|
+
listFormsDefault,
|
|
124
|
+
listFormsDefect,
|
|
125
|
+
listFormsInvalidResponse,
|
|
126
|
+
listFormsListed,
|
|
127
|
+
listFormsListedDefault,
|
|
128
|
+
listFormsProviderRejected,
|
|
129
|
+
listFormsRetry
|
|
130
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdurable/connector-jotform",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Jotform connector for Dex TypeScript applications",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/superdurable/dex-connectors-library.git",
|
|
9
|
+
"directory": "connectors/jotform/typescript"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": "^22.0.0 || ^24.0.0"
|
|
14
|
+
},
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./mock": {
|
|
23
|
+
"types": "./dist/mock.d.ts",
|
|
24
|
+
"import": "./dist/mock.js"
|
|
25
|
+
},
|
|
26
|
+
"./dex-connector.json": "./dex-connector.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"dex-connector.json"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"prepack": "npm run build",
|
|
36
|
+
"build": "tsup src/index.ts src/mock.ts --format esm --dts --clean",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"lint": "eslint src test examples",
|
|
39
|
+
"test": "vitest run --exclude test/integration/**",
|
|
40
|
+
"test:integration": "vitest run test/integration/*.integration.test.ts",
|
|
41
|
+
"example:worker": "tsx examples/form-inspection/worker.ts",
|
|
42
|
+
"example:start": "tsx examples/form-inspection/start.ts",
|
|
43
|
+
"check": "npm run typecheck && npm run lint && npm test && npm run build"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@superdurable/connectors-sdk": "0.1.1",
|
|
47
|
+
"@superdurable/dex": ">=1.28.0",
|
|
48
|
+
"zod": "^4.1.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@eslint/js": "^9.0.0",
|
|
52
|
+
"@types/node": "^22.0.0",
|
|
53
|
+
"eslint": "^9.0.0",
|
|
54
|
+
"tsup": "^8.0.0",
|
|
55
|
+
"tsx": "^4.23.15",
|
|
56
|
+
"typescript": "^5.9.0",
|
|
57
|
+
"typescript-eslint": "^8.0.0",
|
|
58
|
+
"vitest": "^3.0.0",
|
|
59
|
+
"yaml": "^2.9.1"
|
|
60
|
+
}
|
|
61
|
+
}
|