@inneropen/marvin-sdk 2.0.0-next.17 → 2.0.0-next.2

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/dist/platform.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  HttpClient,
3
- MarvinValidationError,
4
3
  SessionAuth,
5
4
  init_core
6
- } from "./chunk-WJC4X7TB.js";
5
+ } from "./chunk-25F3IF6S.js";
7
6
 
8
7
  // src/platform/client.ts
9
8
  init_core();
@@ -24,8 +23,7 @@ var EntriesModule = class {
24
23
  * Get a single entry by ID
25
24
  */
26
25
  async get(id) {
27
- const validId = this.http.validatePathParam(id, "entry ID");
28
- return this.http.get(`/api/platform/entries/${validId}`);
26
+ return this.http.get(`/api/platform/entries/${id}`);
29
27
  }
30
28
  /**
31
29
  * Create a new entry
@@ -37,31 +35,26 @@ var EntriesModule = class {
37
35
  * Update an entry
38
36
  */
39
37
  async update(id, data) {
40
- const validId = this.http.validatePathParam(id, "entry ID");
41
- return this.http.patch(`/api/platform/entries/${validId}`, data);
38
+ return this.http.patch(`/api/platform/entries/${id}`, data);
42
39
  }
43
40
  /**
44
41
  * Delete an entry
45
42
  */
46
43
  async delete(id) {
47
- const validId = this.http.validatePathParam(id, "entry ID");
48
- return this.http.delete(`/api/platform/entries/${validId}`);
44
+ return this.http.delete(`/api/platform/entries/${id}`);
49
45
  }
50
46
  /**
51
47
  * Get collections that this entry belongs to
52
48
  */
53
49
  async listCollections(entryId) {
54
- const validId = this.http.validatePathParam(entryId, "entry ID");
55
- return this.http.get(`/api/platform/entries/${validId}/collections`);
50
+ return this.http.get(`/api/platform/entries/${entryId}/collections`);
56
51
  }
57
52
  /**
58
53
  * Add entry to a collection
59
54
  */
60
55
  async addToCollection(entryId, collectionId) {
61
- const validEntryId = this.http.validatePathParam(entryId, "entry ID");
62
- const validCollectionId = this.http.validatePathParam(collectionId, "collection ID");
63
56
  return this.http.post(
64
- `/api/platform/entries/${validEntryId}/collections/${validCollectionId}`,
57
+ `/api/platform/entries/${entryId}/collections/${collectionId}`,
65
58
  {}
66
59
  );
67
60
  }
@@ -69,9 +62,7 @@ var EntriesModule = class {
69
62
  * Remove entry from a collection
70
63
  */
71
64
  async removeFromCollection(entryId, collectionId) {
72
- const validEntryId = this.http.validatePathParam(entryId, "entry ID");
73
- const validCollectionId = this.http.validatePathParam(collectionId, "collection ID");
74
- return this.http.delete(`/api/platform/entries/${validEntryId}/collections/${validCollectionId}`);
65
+ return this.http.delete(`/api/platform/entries/${entryId}/collections/${collectionId}`);
75
66
  }
76
67
  };
77
68
 
@@ -91,8 +82,7 @@ var CollectionsModule = class {
91
82
  * Get a single collection by ID
92
83
  */
93
84
  async get(id) {
94
- const validId = this.http.validatePathParam(id, "id");
95
- return this.http.get(`/api/platform/collections/${validId}`);
85
+ return this.http.get(`/api/platform/collections/${id}`);
96
86
  }
97
87
  /**
98
88
  * Create a new collection
@@ -104,29 +94,25 @@ var CollectionsModule = class {
104
94
  * Update a collection
105
95
  */
106
96
  async update(id, data) {
107
- const validId = this.http.validatePathParam(id, "id");
108
- return this.http.patch(`/api/platform/collections/${validId}`, data);
97
+ return this.http.patch(`/api/platform/collections/${id}`, data);
109
98
  }
110
99
  /**
111
100
  * Delete a collection
112
101
  */
113
102
  async delete(id) {
114
- const validId = this.http.validatePathParam(id, "collection ID");
115
- return this.http.delete(`/api/platform/collections/${validId}`);
103
+ return this.http.delete(`/api/platform/collections/${id}`);
116
104
  }
117
105
  /**
118
106
  * Get entries in a collection
119
107
  */
120
108
  async getEntries(id) {
121
- const validId = this.http.validatePathParam(id, "collection ID");
122
- return this.http.get(`/api/platform/collections/${validId}/entries`);
109
+ return this.http.get(`/api/platform/collections/${id}/entries`);
123
110
  }
124
111
  /**
125
112
  * Reorder entries in a collection
126
113
  */
127
114
  async reorderEntries(id, entries) {
128
- const validId = this.http.validatePathParam(id, "collection ID");
129
- return this.http.patch(`/api/platform/collections/${validId}/entries/order`, { entries });
115
+ return this.http.patch(`/api/platform/collections/${id}/entries/order`, { entries });
130
116
  }
131
117
  };
132
118
 
@@ -146,8 +132,7 @@ var ResourcesModule = class {
146
132
  * Get a single resource by ID
147
133
  */
148
134
  async get(id) {
149
- const validId = this.http.validatePathParam(id, "id");
150
- return this.http.get(`/api/platform/resources/${validId}`);
135
+ return this.http.get(`/api/platform/resources/${id}`);
151
136
  }
152
137
  /**
153
138
  * Create a new resource
@@ -159,8 +144,7 @@ var ResourcesModule = class {
159
144
  * Update a resource
160
145
  */
161
146
  async update(id, data) {
162
- const validId = this.http.validatePathParam(id, "id");
163
- return this.http.patch(`/api/platform/resources/${validId}`, data);
147
+ return this.http.patch(`/api/platform/resources/${id}`, data);
164
148
  }
165
149
  /**
166
150
  * Delete a resource
@@ -177,53 +161,11 @@ var ResourcesModule = class {
177
161
  };
178
162
 
179
163
  // src/platform/assets.ts
180
- init_core();
181
164
  var AssetsModule = class {
182
165
  constructor(http) {
183
166
  this.http = http;
184
167
  }
185
168
  http;
186
- /**
187
- * Validate file before upload
188
- */
189
- validateFile(file, options) {
190
- const maxSize = options?.maxFileSize || 100 * 1024 * 1024;
191
- const allowedTypes = options?.allowedMimeTypes;
192
- if (file.size === 0) {
193
- throw new MarvinValidationError("File is empty");
194
- }
195
- if (file.size > maxSize) {
196
- const maxMB = Math.round(maxSize / (1024 * 1024));
197
- const fileMB = Math.round(file.size / (1024 * 1024));
198
- throw new MarvinValidationError(
199
- `File size (${fileMB}MB) exceeds maximum allowed size of ${maxMB}MB`
200
- );
201
- }
202
- if (allowedTypes && allowedTypes.length > 0) {
203
- if (file instanceof File && file.type) {
204
- const isAllowed = allowedTypes.some((allowed) => {
205
- if (allowed.endsWith("/*")) {
206
- const prefix = allowed.slice(0, -2);
207
- return file.type.startsWith(prefix);
208
- }
209
- return file.type === allowed;
210
- });
211
- if (!isAllowed) {
212
- throw new MarvinValidationError(
213
- `File type "${file.type}" is not allowed. Allowed types: ${allowedTypes.join(", ")}`
214
- );
215
- }
216
- }
217
- }
218
- if (file instanceof File) {
219
- if (!file.name || file.name.trim().length === 0) {
220
- throw new MarvinValidationError("File must have a valid name");
221
- }
222
- if (file.name.includes("..") || file.name.includes("/") || file.name.includes("\\")) {
223
- throw new MarvinValidationError("Invalid filename: cannot contain path separators");
224
- }
225
- }
226
- }
227
169
  /**
228
170
  * List all assets
229
171
  */
@@ -234,31 +176,16 @@ var AssetsModule = class {
234
176
  * Get a single asset by ID
235
177
  */
236
178
  async get(id) {
237
- const validId = this.http.validatePathParam(id, "id");
238
- return this.http.get(`/api/platform/assets/${validId}`);
179
+ return this.http.get(`/api/platform/assets/${id}`);
239
180
  }
240
181
  /**
241
182
  * Upload a new asset file
242
183
  *
243
184
  * @param file - The file to upload (File or Blob)
244
185
  * @param metadata - Asset metadata (slug, name, altText, description, metadata)
245
- * @param options - Upload options (file size limits, allowed types)
246
186
  * @returns The created asset with extracted metadata
247
- *
248
- * @example
249
- * ```typescript
250
- * // Upload with default limits (100MB, all types)
251
- * const asset = await assets.upload(file, { slug: 'my-image', name: 'My Image' });
252
- *
253
- * // Upload with restrictions
254
- * const asset = await assets.upload(file,
255
- * { slug: 'avatar', name: 'Avatar' },
256
- * { maxFileSize: 5 * 1024 * 1024, allowedMimeTypes: ['image/*'] }
257
- * );
258
- * ```
259
187
  */
260
- async upload(file, metadata, options) {
261
- this.validateFile(file, options);
188
+ async upload(file, metadata) {
262
189
  const formData = new FormData();
263
190
  formData.append("file", file);
264
191
  formData.append("slug", metadata.slug);
@@ -278,24 +205,13 @@ var AssetsModule = class {
278
205
  * Update an asset (editable fields only: slug, name, altText, description, metadata)
279
206
  */
280
207
  async update(id, data) {
281
- const validId = this.http.validatePathParam(id, "id");
282
- return this.http.patch(`/api/platform/assets/${validId}`, data);
208
+ return this.http.patch(`/api/platform/assets/${id}`, data);
283
209
  }
284
210
  /**
285
211
  * Delete an asset (removes file from storage and database)
286
212
  */
287
213
  async delete(id) {
288
- const validId = this.http.validatePathParam(id, "asset ID");
289
- return this.http.delete(`/api/platform/assets/${validId}`);
290
- }
291
- /**
292
- * Get download URL for an asset file
293
- * Use this to create download links or fetch the file directly
294
- */
295
- getDownloadUrl(id, baseUrl) {
296
- const validId = this.http.validatePathParam(id, "asset ID");
297
- const base = baseUrl || (typeof window !== "undefined" && window.location ? window.location.origin : "");
298
- return `${base}/api/platform/assets/${validId}/file`;
214
+ return this.http.delete(`/api/platform/assets/${id}`);
299
215
  }
300
216
  };
301
217
 
@@ -315,8 +231,7 @@ var APIClientsModule = class {
315
231
  * Get a single API client by ID
316
232
  */
317
233
  async get(id) {
318
- const validId = this.http.validatePathParam(id, "id");
319
- return this.http.get(`/api/platform/api-clients/${validId}`);
234
+ return this.http.get(`/api/platform/api-clients/${id}`);
320
235
  }
321
236
  /**
322
237
  * Create a new API client (returns client with token)
@@ -328,8 +243,7 @@ var APIClientsModule = class {
328
243
  * Update an API client
329
244
  */
330
245
  async update(id, data) {
331
- const validId = this.http.validatePathParam(id, "id");
332
- return this.http.patch(`/api/platform/api-clients/${validId}`, data);
246
+ return this.http.patch(`/api/platform/api-clients/${id}`, data);
333
247
  }
334
248
  /**
335
249
  * Delete an API client
@@ -540,23 +454,11 @@ var InvitesModule = class {
540
454
  }
541
455
  /**
542
456
  * Generate invitation URL from a token
543
- *
544
- * @param token - Invitation token
545
- * @param baseUrl - Base URL for the frontend (required in browser environments)
546
- * @returns Full invitation URL
547
- *
548
- * @example
549
- * ```typescript
550
- * // Node.js (can use env vars)
551
- * const url = invites.getInvitationUrl(token);
552
- *
553
- * // Browser (must provide baseUrl)
554
- * const url = invites.getInvitationUrl(token, 'https://app.example.com');
555
- * ```
457
+ * Uses MARVIN_FRONTEND_URL for the base URL, falls back to MARVIN_API_URL with common port mappings
556
458
  */
557
459
  getInvitationUrl(token, baseUrl) {
558
460
  let base = baseUrl;
559
- if (!base && typeof process !== "undefined" && process.env) {
461
+ if (!base) {
560
462
  base = process.env.MARVIN_FRONTEND_URL;
561
463
  if (!base && process.env.MARVIN_API_URL) {
562
464
  const apiUrl = process.env.MARVIN_API_URL;
@@ -568,17 +470,11 @@ var InvitesModule = class {
568
470
  base = apiUrl;
569
471
  }
570
472
  }
571
- }
572
- if (!base) {
573
- if (typeof window !== "undefined" && window.location) {
574
- base = window.location.origin;
575
- } else {
576
- throw new Error(
577
- 'baseUrl is required when not in Node.js environment. Pass the frontend URL as second argument: getInvitationUrl(token, "https://app.example.com")'
578
- );
473
+ if (!base) {
474
+ base = "http://localhost:4321";
579
475
  }
580
476
  }
581
- return `${base}/register?token=${encodeURIComponent(token)}`;
477
+ return `${base}/register?token=${token}`;
582
478
  }
583
479
  };
584
480
 
@@ -627,63 +523,11 @@ var NotificationsModule = class {
627
523
  };
628
524
 
629
525
  // src/platform/webhooks.ts
630
- init_core();
631
526
  var WebhooksModule = class {
632
527
  constructor(http) {
633
528
  this.http = http;
634
529
  }
635
530
  http;
636
- /**
637
- * Validate webhook URL to prevent SSRF attacks
638
- */
639
- validateWebhookUrl(url) {
640
- if (!url || typeof url !== "string") {
641
- throw new MarvinValidationError("Webhook URL is required and must be a string");
642
- }
643
- let parsed;
644
- try {
645
- parsed = new URL(url);
646
- } catch {
647
- throw new MarvinValidationError("Invalid webhook URL format. Expected: https://example.com/webhook");
648
- }
649
- if (!["http:", "https:"].includes(parsed.protocol)) {
650
- throw new MarvinValidationError(
651
- `Webhook URL must use HTTP or HTTPS protocol. Got: ${parsed.protocol}`
652
- );
653
- }
654
- const hostname = parsed.hostname.toLowerCase();
655
- const blockedHosts = [
656
- "localhost",
657
- "127.0.0.1",
658
- "0.0.0.0",
659
- "::1",
660
- "169.254.169.254",
661
- // AWS metadata service
662
- "[::]"
663
- ];
664
- if (blockedHosts.some((blocked) => hostname === blocked || hostname.includes(blocked))) {
665
- throw new MarvinValidationError(
666
- "Webhook URL cannot target localhost or internal network addresses"
667
- );
668
- }
669
- const ipv4Regex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
670
- const match = hostname.match(ipv4Regex);
671
- if (match) {
672
- const octets = match.slice(1).map(Number);
673
- if (octets[0] === 10) {
674
- throw new MarvinValidationError("Webhook URL cannot target private IP range (10.x.x.x)");
675
- }
676
- if (octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) {
677
- throw new MarvinValidationError("Webhook URL cannot target private IP range (172.16-31.x.x)");
678
- }
679
- if (octets[0] === 192 && octets[1] === 168) {
680
- throw new MarvinValidationError("Webhook URL cannot target private IP range (192.168.x.x)");
681
- }
682
- }
683
- if (url.length > 2048) {
684
- throw new MarvinValidationError("Webhook URL exceeds maximum length of 2048 characters");
685
- }
686
- }
687
531
  /**
688
532
  * List all webhooks for the current workspace
689
533
  */
@@ -695,43 +539,31 @@ var WebhooksModule = class {
695
539
  * Get a webhook by ID
696
540
  */
697
541
  async get(id) {
698
- const validId = this.http.validatePathParam(id, "webhook ID");
699
- return this.http.get(`/api/groups/webhooks/${validId}`);
542
+ return this.http.get(`/api/groups/webhooks/${id}`);
700
543
  }
701
544
  /**
702
545
  * Create a new webhook
703
- * Validates URL to prevent SSRF attacks
704
546
  */
705
547
  async create(data) {
706
- if (data.url) {
707
- this.validateWebhookUrl(data.url);
708
- }
709
548
  return this.http.post("/api/groups/webhooks", data);
710
549
  }
711
550
  /**
712
551
  * Update a webhook
713
- * Validates URL if provided to prevent SSRF attacks
714
552
  */
715
553
  async update(id, data) {
716
- const validId = this.http.validatePathParam(id, "webhook ID");
717
- if (data.url) {
718
- this.validateWebhookUrl(data.url);
719
- }
720
- return this.http.put(`/api/groups/webhooks/${validId}`, data);
554
+ return this.http.put(`/api/groups/webhooks/${id}`, data);
721
555
  }
722
556
  /**
723
557
  * Delete a webhook
724
558
  */
725
559
  async delete(id) {
726
- const validId = this.http.validatePathParam(id, "webhook ID");
727
- await this.http.delete(`/api/groups/webhooks/${validId}`);
560
+ await this.http.delete(`/api/groups/webhooks/${id}`);
728
561
  }
729
562
  /**
730
563
  * Test a webhook
731
564
  */
732
565
  async test(id) {
733
- const validId = this.http.validatePathParam(id, "webhook ID");
734
- return this.http.post(`/api/groups/webhooks/${validId}/test`, {});
566
+ return this.http.post(`/api/groups/webhooks/${id}/test`, {});
735
567
  }
736
568
  /**
737
569
  * Rerun failed webhooks
@@ -823,7 +655,6 @@ var AdminSystemModule = class {
823
655
  }
824
656
  /**
825
657
  * Update email settings
826
- * Note: Password field is write-only and will not be returned in response
827
658
  */
828
659
  async updateEmailSettings(data) {
829
660
  return this.http.put("/api/admin/email", data);
@@ -1099,235 +930,7 @@ var ThemeModule = class {
1099
930
  }
1100
931
  };
1101
932
 
1102
- // src/platform/emailTemplates.ts
1103
- var EmailTemplatesClient = class {
1104
- constructor(http) {
1105
- this.http = http;
1106
- }
1107
- http;
1108
- /**
1109
- * List all email templates for the workspace
1110
- * @param groupId - Workspace ID
1111
- */
1112
- async list(groupId) {
1113
- return this.http.get(`/api/platform/workspaces/${groupId}/email-templates`);
1114
- }
1115
- /**
1116
- * Get a specific email template
1117
- * @param groupId - Workspace ID
1118
- * @param templateId - Template ID
1119
- */
1120
- async get(groupId, templateId) {
1121
- return this.http.get(`/api/platform/workspaces/${groupId}/email-templates/${templateId}`);
1122
- }
1123
- /**
1124
- * Create a new email template
1125
- * @param groupId - Workspace ID
1126
- * @param data - Template data
1127
- */
1128
- async create(groupId, data) {
1129
- return this.http.post(`/api/platform/workspaces/${groupId}/email-templates`, data);
1130
- }
1131
- /**
1132
- * Update an email template
1133
- * @param groupId - Workspace ID
1134
- * @param templateId - Template ID
1135
- * @param data - Updated template data
1136
- */
1137
- async update(groupId, templateId, data) {
1138
- return this.http.patch(`/api/platform/workspaces/${groupId}/email-templates/${templateId}`, data);
1139
- }
1140
- /**
1141
- * Delete an email template
1142
- * @param groupId - Workspace ID
1143
- * @param templateId - Template ID
1144
- */
1145
- async delete(groupId, templateId) {
1146
- await this.http.delete(`/api/platform/workspaces/${groupId}/email-templates/${templateId}`);
1147
- }
1148
- /**
1149
- * Send a test email using a template
1150
- * @param groupId - Workspace ID
1151
- * @param templateId - Template ID
1152
- * @param recipientEmail - Test recipient email address
1153
- */
1154
- async sendTest(groupId, templateId, recipientEmail) {
1155
- return this.http.post(`/api/platform/workspaces/${groupId}/email-templates/${templateId}/test`, {
1156
- recipient_email: recipientEmail
1157
- });
1158
- }
1159
- };
1160
-
1161
- // src/platform/scheduledTasks.ts
1162
- var ScheduledTasksModule = class {
1163
- constructor(http) {
1164
- this.http = http;
1165
- }
1166
- http;
1167
- /**
1168
- * List all scheduled tasks for the current workspace
1169
- */
1170
- async list() {
1171
- return this.http.get("/api/platform/scheduled-tasks");
1172
- }
1173
- /**
1174
- * Get a scheduled task by ID or slug
1175
- */
1176
- async get(idOrSlug) {
1177
- const validIdOrSlug = this.http.validatePathParam(idOrSlug, "idOrSlug");
1178
- return this.http.get(`/api/platform/scheduled-tasks/${validIdOrSlug}`);
1179
- }
1180
- /**
1181
- * Create a new scheduled task
1182
- */
1183
- async create(data) {
1184
- return this.http.post("/api/platform/scheduled-tasks", data);
1185
- }
1186
- /**
1187
- * Update a scheduled task
1188
- */
1189
- async update(idOrSlug, data) {
1190
- const validIdOrSlug = this.http.validatePathParam(idOrSlug, "idOrSlug");
1191
- return this.http.patch(`/api/platform/scheduled-tasks/${validIdOrSlug}`, data);
1192
- }
1193
- /**
1194
- * Delete a scheduled task
1195
- */
1196
- async delete(idOrSlug) {
1197
- await this.http.delete(`/api/platform/scheduled-tasks/${idOrSlug}`);
1198
- }
1199
- /**
1200
- * Manually trigger task execution (bypass schedule)
1201
- */
1202
- async execute(idOrSlug) {
1203
- await this.http.post(`/api/platform/scheduled-tasks/${idOrSlug}/execute`, {});
1204
- }
1205
- /**
1206
- * Get task execution history
1207
- */
1208
- async history(idOrSlug, options) {
1209
- const params = new URLSearchParams();
1210
- if (options?.limit) {
1211
- params.set("limit", options.limit.toString());
1212
- }
1213
- const query = params.toString() ? `?${params.toString()}` : "";
1214
- return this.http.get(
1215
- `/api/platform/scheduled-tasks/${idOrSlug}/history${query}`
1216
- );
1217
- }
1218
- /**
1219
- * Get available task types
1220
- */
1221
- async taskTypes(options) {
1222
- const params = new URLSearchParams();
1223
- if (options?.detailed) {
1224
- params.set("detailed", "true");
1225
- }
1226
- const query = params.toString() ? `?${params.toString()}` : "";
1227
- return this.http.get(`/api/platform/scheduled-tasks/task-types${query}`);
1228
- }
1229
- };
1230
-
1231
- // src/platform/forms.ts
1232
- init_core();
1233
- var FormsModule = class {
1234
- constructor(http) {
1235
- this.http = http;
1236
- }
1237
- http;
1238
- /**
1239
- * Validate form submission data
1240
- * - Prevents XSS by checking for script tags
1241
- * - Validates data is a proper object
1242
- * - Checks for reasonable size limits
1243
- */
1244
- validateFormData(data) {
1245
- if (!data || typeof data !== "object") {
1246
- throw new MarvinValidationError("Form data must be a valid object");
1247
- }
1248
- const jsonString = JSON.stringify(data);
1249
- const sizeInBytes = new Blob([jsonString]).size;
1250
- if (sizeInBytes > 1024 * 1024) {
1251
- throw new MarvinValidationError("Form data exceeds maximum size of 1MB");
1252
- }
1253
- const checkForScripts = (value) => {
1254
- if (typeof value === "string") {
1255
- if (/<script[\s\S]*?>[\s\S]*?<\/script>/gi.test(value)) {
1256
- throw new MarvinValidationError("Form data contains potentially malicious content");
1257
- }
1258
- } else if (Array.isArray(value)) {
1259
- value.forEach(checkForScripts);
1260
- } else if (value && typeof value === "object") {
1261
- Object.values(value).forEach(checkForScripts);
1262
- }
1263
- };
1264
- Object.values(data).forEach(checkForScripts);
1265
- }
1266
- /**
1267
- * List all forms
1268
- */
1269
- async list() {
1270
- return this.http.get("/api/platform/forms");
1271
- }
1272
- /**
1273
- * Get a single form by ID
1274
- */
1275
- async get(id) {
1276
- const validId = this.http.validatePathParam(id, "id");
1277
- return this.http.get(`/api/platform/forms/${validId}`);
1278
- }
1279
- /**
1280
- * Create a new form
1281
- */
1282
- async create(data) {
1283
- return this.http.post("/api/platform/forms", data);
1284
- }
1285
- /**
1286
- * Update a form
1287
- */
1288
- async update(id, data) {
1289
- const validId = this.http.validatePathParam(id, "id");
1290
- return this.http.patch(`/api/platform/forms/${validId}`, data);
1291
- }
1292
- /**
1293
- * Delete a form
1294
- */
1295
- async delete(id) {
1296
- return this.http.delete(`/api/platform/forms/${id}`);
1297
- }
1298
- /**
1299
- * Get submissions for a form
1300
- */
1301
- async getSubmissions(formId) {
1302
- return this.http.get(`/api/platform/forms/${formId}/submissions`);
1303
- }
1304
- /**
1305
- * Get a published form by slug (Publishing API - public access)
1306
- */
1307
- async getPublishedForm(slug) {
1308
- return this.http.get(`/api/publish/forms/${slug}`);
1309
- }
1310
- /**
1311
- * Submit data to a published form (Publishing API - public access)
1312
- * Validates data before submission to prevent XSS and malicious content
1313
- */
1314
- async submitForm(slug, data) {
1315
- const validSlug = this.http.validatePathParam(slug, "form slug");
1316
- this.validateFormData(data);
1317
- return this.http.post(`/api/publish/forms/${validSlug}/submit`, {
1318
- dataJson: data
1319
- });
1320
- }
1321
- };
1322
-
1323
933
  // src/platform/client.ts
1324
- function createPlatformConfigFromEnv(overrides) {
1325
- return {
1326
- apiUrl: overrides?.apiUrl || process.env.MARVIN_API_URL || "http://localhost:8080",
1327
- userToken: overrides?.userToken || process.env.MARVIN_USER_TOKEN,
1328
- credentials: overrides?.credentials || "include"
1329
- };
1330
- }
1331
934
  var PlatformClient = class extends HttpClient {
1332
935
  entries;
1333
936
  collections;
@@ -1345,16 +948,13 @@ var PlatformClient = class extends HttpClient {
1345
948
  eventLog;
1346
949
  session;
1347
950
  theme;
1348
- emailTemplates;
1349
- scheduledTasks;
1350
- forms;
1351
951
  // Admin modules
1352
952
  adminUsers;
1353
953
  adminSystem;
1354
954
  adminMaintenance;
1355
955
  constructor(config) {
1356
956
  const httpConfig = {
1357
- baseUrl: config.apiUrl || "http://localhost:8080",
957
+ baseUrl: config.apiUrl,
1358
958
  auth: new SessionAuth(config.userToken),
1359
959
  credentials: config.credentials || "include"
1360
960
  };
@@ -1375,17 +975,13 @@ var PlatformClient = class extends HttpClient {
1375
975
  this.eventLog = new EventLogModule(this);
1376
976
  this.session = new AuthModule(this);
1377
977
  this.theme = new ThemeModule(this);
1378
- this.emailTemplates = new EmailTemplatesClient(this);
1379
- this.scheduledTasks = new ScheduledTasksModule(this);
1380
- this.forms = new FormsModule(this);
1381
978
  this.adminUsers = new AdminUsersModule(this);
1382
979
  this.adminSystem = new AdminSystemModule(this);
1383
980
  this.adminMaintenance = new AdminMaintenanceModule(this);
1384
981
  }
1385
982
  };
1386
983
  function createPlatformClient(config) {
1387
- const finalConfig = createPlatformConfigFromEnv(config);
1388
- return new PlatformClient(finalConfig);
984
+ return new PlatformClient(config);
1389
985
  }
1390
986
  export {
1391
987
  APIClientsModule,
@@ -1395,22 +991,18 @@ export {
1395
991
  AssetsModule,
1396
992
  AuthModule,
1397
993
  CollectionsModule,
1398
- EmailTemplatesClient,
1399
994
  EntriesModule,
1400
995
  EntryTypesModule,
1401
996
  EventLogModule,
1402
997
  EventsModule,
1403
- FormsModule,
1404
998
  InvitesModule,
1405
999
  NotificationsModule,
1406
1000
  PlatformClient,
1407
1001
  ResourcesModule,
1408
- ScheduledTasksModule,
1409
1002
  ThemeModule,
1410
1003
  UserModule,
1411
1004
  WebhooksModule,
1412
1005
  WorkspaceMembersModule,
1413
1006
  WorkspacesModule,
1414
- createPlatformClient,
1415
- createPlatformConfigFromEnv
1007
+ createPlatformClient
1416
1008
  };