sharetribe-flex-build-sdk 1.15.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/src/events.ts ADDED
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Events query functions
3
+ *
4
+ * Programmatic API for querying marketplace events
5
+ */
6
+
7
+ import { apiGet } from './api/client.js';
8
+
9
+ export interface EventData {
10
+ sequenceId: number;
11
+ resourceId: string;
12
+ eventType: string;
13
+ createdAt: string;
14
+ resourceType?: string;
15
+ source?: string;
16
+ id?: string;
17
+ resource?: unknown;
18
+ auditData?: {
19
+ userId?: string | null;
20
+ adminId?: string | null;
21
+ clientId?: string | null;
22
+ requestId?: string | null;
23
+ };
24
+ auditEmails?: {
25
+ userEmail?: string | null;
26
+ adminEmail?: string | null;
27
+ };
28
+ previousValues?: unknown;
29
+ marketplaceId?: string;
30
+ }
31
+
32
+ export interface QueryEventsOptions {
33
+ resourceId?: string;
34
+ relatedResourceId?: string;
35
+ eventTypes?: string;
36
+ sequenceId?: number;
37
+ afterSeqId?: number;
38
+ beforeSeqId?: number;
39
+ afterTs?: string;
40
+ beforeTs?: string;
41
+ limit?: number;
42
+ }
43
+
44
+ /**
45
+ * Validates query parameters
46
+ */
47
+ function validateParams(opts: QueryEventsOptions): void {
48
+ const exclusiveParams = [
49
+ opts.sequenceId !== undefined,
50
+ opts.afterSeqId !== undefined,
51
+ opts.beforeSeqId !== undefined,
52
+ opts.afterTs !== undefined,
53
+ opts.beforeTs !== undefined,
54
+ ];
55
+
56
+ if (exclusiveParams.filter(Boolean).length > 1) {
57
+ throw new Error(
58
+ 'Only one of sequenceId, afterSeqId, beforeSeqId, afterTs, or beforeTs can be specified'
59
+ );
60
+ }
61
+
62
+ if (opts.resourceId && opts.relatedResourceId) {
63
+ throw new Error('Only one of resourceId or relatedResourceId can be specified');
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Builds query parameters for API
69
+ */
70
+ function buildQueryParams(
71
+ marketplace: string,
72
+ opts: QueryEventsOptions
73
+ ): Record<string, string> {
74
+ const params: Record<string, string> = {
75
+ marketplace,
76
+ latest: 'true'
77
+ };
78
+
79
+ if (opts.resourceId) params['resource-id'] = opts.resourceId;
80
+ if (opts.relatedResourceId) params['related-resource-id'] = opts.relatedResourceId;
81
+ if (opts.eventTypes) params['event-types'] = opts.eventTypes;
82
+ if (opts.sequenceId !== undefined) params['sequence-id'] = opts.sequenceId.toString();
83
+ if (opts.afterSeqId !== undefined) {
84
+ params['start-after-sequence-id'] = opts.afterSeqId.toString();
85
+ params.latest = 'false';
86
+ }
87
+ if (opts.beforeSeqId !== undefined) params['sequence-id-end'] = opts.beforeSeqId.toString();
88
+ if (opts.afterTs) {
89
+ params['start-after-created-at'] = opts.afterTs;
90
+ params.latest = 'false';
91
+ }
92
+ if (opts.beforeTs) params['created-at-end'] = opts.beforeTs;
93
+ if (opts.limit !== undefined) params.perPage = opts.limit.toString();
94
+
95
+ return params;
96
+ }
97
+
98
+ /**
99
+ * Transforms event from API format to standard format
100
+ */
101
+ function transformEvent(event: any): EventData {
102
+ const eventData = event['event/data'];
103
+ const eventAudit = event['event/audit'];
104
+
105
+ return {
106
+ eventType: eventData.eventType,
107
+ createdAt: eventData.createdAt,
108
+ resourceType: eventData.resourceType,
109
+ source: eventData.source,
110
+ resourceId: eventData.resourceId,
111
+ id: eventData.id,
112
+ resource: eventData.resource || null,
113
+ auditData: eventData.auditData || {
114
+ userId: null,
115
+ adminId: null,
116
+ clientId: null,
117
+ requestId: null,
118
+ },
119
+ auditEmails: eventAudit ? {
120
+ userEmail: eventAudit['user/email'] || null,
121
+ adminEmail: eventAudit['admin/email'] || null,
122
+ } : undefined,
123
+ sequenceId: eventData.sequenceId,
124
+ previousValues: eventData.previousValues || null,
125
+ marketplaceId: eventData.marketplaceId,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Queries marketplace events
131
+ *
132
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
133
+ * @param marketplace - Marketplace ID
134
+ * @param options - Query options
135
+ * @returns Array of events
136
+ */
137
+ export async function queryEvents(
138
+ apiKey: string | undefined,
139
+ marketplace: string,
140
+ options: QueryEventsOptions = {}
141
+ ): Promise<EventData[]> {
142
+ validateParams(options);
143
+
144
+ const queryParams = buildQueryParams(marketplace, options);
145
+ const response = await apiGet<{ data: any[] }>(apiKey, '/events/query', queryParams);
146
+
147
+ return response.data.map(transformEvent);
148
+ }
149
+
150
+ /**
151
+ * Polls for new events and calls callback when new events are found
152
+ *
153
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
154
+ * @param marketplace - Marketplace ID
155
+ * @param options - Query options
156
+ * @param callback - Function called with new events
157
+ * @param pollInterval - Interval in milliseconds between polls (default: 5000)
158
+ * @returns Function to stop polling
159
+ */
160
+ export function pollEvents(
161
+ apiKey: string | undefined,
162
+ marketplace: string,
163
+ options: QueryEventsOptions,
164
+ callback: (events: EventData[]) => void,
165
+ pollInterval: number = 5000
166
+ ): () => void {
167
+ let lastSeqId: number | undefined;
168
+ let intervalId: NodeJS.Timeout;
169
+ let isStopped = false;
170
+
171
+ const poll = async () => {
172
+ if (isStopped) return;
173
+
174
+ try {
175
+ const queryOpts = { ...options };
176
+ if (lastSeqId !== undefined) {
177
+ queryOpts.afterSeqId = lastSeqId;
178
+ }
179
+
180
+ const events = await queryEvents(apiKey, marketplace, queryOpts);
181
+
182
+ if (events.length > 0) {
183
+ callback(events);
184
+ lastSeqId = Math.max(...events.map(e => e.sequenceId));
185
+ }
186
+ } catch (error) {
187
+ // Silently continue polling on errors
188
+ // Caller can handle errors in their callback if needed
189
+ }
190
+ };
191
+
192
+ // Initial poll
193
+ poll();
194
+
195
+ // Set up interval
196
+ intervalId = setInterval(poll, pollInterval);
197
+
198
+ // Return stop function
199
+ return () => {
200
+ isStopped = true;
201
+ clearInterval(intervalId);
202
+ };
203
+ }
package/src/index.ts ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Sharetribe Flex Build SDK
3
+ *
4
+ * Programmatic API matching all CLI capabilities
5
+ */
6
+
7
+ // Export process management functions
8
+ export {
9
+ listProcesses,
10
+ listProcessVersions,
11
+ getProcess,
12
+ createProcess,
13
+ pushProcess,
14
+ createAlias,
15
+ updateAlias,
16
+ deleteAlias,
17
+ type ProcessListItem,
18
+ type ProcessVersion,
19
+ type ProcessDetails,
20
+ type CreateProcessResult,
21
+ type PushProcessResult,
22
+ type AliasResult,
23
+ } from './processes.js';
24
+
25
+ // Export process deployment functions
26
+ export {
27
+ deployProcess,
28
+ type DeployProcessOptions,
29
+ type DeployProcessResult,
30
+ } from './deploy.js';
31
+
32
+ // Export search schema management functions
33
+ export {
34
+ listSearchSchemas,
35
+ setSearchSchema,
36
+ unsetSearchSchema,
37
+ type SearchSchema,
38
+ type SetSearchSchemaOptions,
39
+ type UnsetSearchSchemaOptions,
40
+ } from './search.js';
41
+
42
+ // Export events query functions
43
+ export {
44
+ queryEvents,
45
+ pollEvents,
46
+ type EventData,
47
+ type QueryEventsOptions,
48
+ } from './events.js';
49
+
50
+ // Export types
51
+ export type {
52
+ ProcessState,
53
+ ProcessTransition,
54
+ ProcessNotification,
55
+ ProcessAction,
56
+ ProcessDefinition,
57
+ } from './types.js';
58
+
59
+ // Export EDN process utilities
60
+ export {
61
+ parseProcessFile,
62
+ serializeProcess,
63
+ } from './edn-process.js';
64
+
65
+ // Export authentication functions
66
+ export {
67
+ writeAuth,
68
+ clearAuth,
69
+ type AuthData,
70
+ } from './auth-storage.js';
71
+
72
+ // Export asset management functions
73
+ export {
74
+ pullAssets,
75
+ pushAssets,
76
+ type Asset,
77
+ type PullAssetsResult,
78
+ type PushAssetsResult,
79
+ } from './assets.js';
80
+
81
+ // Export notification management functions
82
+ export {
83
+ sendNotification,
84
+ previewNotification,
85
+ type EmailTemplate,
86
+ type NotificationOptions,
87
+ } from './notifications.js';
88
+
89
+ // Export listing approval functions
90
+ export {
91
+ getListingApprovalStatus,
92
+ enableListingApproval,
93
+ disableListingApproval,
94
+ } from './listing-approval.js';
95
+
96
+ // Export Stripe integration functions
97
+ export {
98
+ updateStripeVersion,
99
+ SUPPORTED_STRIPE_VERSIONS,
100
+ type StripeApiVersion,
101
+ } from './stripe.js';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Listing approval management functions
3
+ *
4
+ * Programmatic API for managing listing approvals
5
+ */
6
+
7
+ import { apiGet, apiPostTransit } from './api/client.js';
8
+
9
+ /**
10
+ * Gets current listing approval status
11
+ *
12
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
13
+ * @param marketplace - Marketplace ID
14
+ * @returns Whether listing approvals are enabled
15
+ */
16
+ export async function getListingApprovalStatus(
17
+ apiKey: string | undefined,
18
+ marketplace: string
19
+ ): Promise<{ enabled: boolean }> {
20
+ const response = await apiGet<{ data: { 'listing-approval-enabled': boolean } }>(
21
+ apiKey,
22
+ '/marketplace/show',
23
+ { marketplace }
24
+ );
25
+
26
+ return {
27
+ enabled: response.data['listing-approval-enabled'],
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Enables listing approvals
33
+ *
34
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
35
+ * @param marketplace - Marketplace ID
36
+ * @returns Success confirmation
37
+ */
38
+ export async function enableListingApproval(
39
+ apiKey: string | undefined,
40
+ marketplace: string
41
+ ): Promise<{ success: true }> {
42
+ await apiPostTransit(apiKey, '/listing-approval/enable', { marketplace }, {});
43
+ return { success: true };
44
+ }
45
+
46
+ /**
47
+ * Disables listing approvals
48
+ *
49
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
50
+ * @param marketplace - Marketplace ID
51
+ * @returns Success confirmation
52
+ */
53
+ export async function disableListingApproval(
54
+ apiKey: string | undefined,
55
+ marketplace: string
56
+ ): Promise<{ success: true }> {
57
+ await apiPostTransit(apiKey, '/listing-approval/disable', { marketplace }, {});
58
+ return { success: true };
59
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Notification management functions
3
+ *
4
+ * Programmatic API for managing email notifications
5
+ */
6
+
7
+ import { apiPost } from './api/client.js';
8
+
9
+ export interface EmailTemplate {
10
+ html: string;
11
+ subject: string;
12
+ }
13
+
14
+ export interface NotificationOptions {
15
+ template: EmailTemplate;
16
+ context?: unknown;
17
+ }
18
+
19
+ /**
20
+ * Sends a preview email to the marketplace admin
21
+ *
22
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
23
+ * @param marketplace - Marketplace ID
24
+ * @param options - Email template and context
25
+ * @returns Admin email that received the preview
26
+ */
27
+ export async function sendNotification(
28
+ apiKey: string | undefined,
29
+ marketplace: string,
30
+ options: NotificationOptions
31
+ ): Promise<{ adminEmail: string }> {
32
+ const body: Record<string, unknown> = {
33
+ template: {
34
+ 'template-html': options.template.html,
35
+ 'template-subject': options.template.subject,
36
+ },
37
+ };
38
+
39
+ if (options.context !== undefined) {
40
+ body['template-context'] = options.context;
41
+ }
42
+
43
+ const response = await apiPost<{ data: { 'admin-email': string } }>(
44
+ apiKey,
45
+ '/notifications/send',
46
+ { marketplace },
47
+ body
48
+ );
49
+
50
+ return {
51
+ adminEmail: response.data['admin-email'],
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Previews a notification (renders HTML)
57
+ *
58
+ * @param apiKey - Sharetribe API key (optional, reads from auth file if not provided)
59
+ * @param marketplace - Marketplace ID
60
+ * @param options - Email template and context
61
+ * @returns Rendered HTML
62
+ */
63
+ export async function previewNotification(
64
+ apiKey: string | undefined,
65
+ marketplace: string,
66
+ options: NotificationOptions
67
+ ): Promise<{ html: string }> {
68
+ const body: Record<string, unknown> = {
69
+ template: {
70
+ 'template-html': options.template.html,
71
+ 'template-subject': options.template.subject,
72
+ },
73
+ };
74
+
75
+ if (options.context !== undefined) {
76
+ body['template-context'] = options.context;
77
+ }
78
+
79
+ const response = await apiPost<{ data: { html: string } }>(
80
+ apiKey,
81
+ '/notifications/preview',
82
+ { marketplace },
83
+ body
84
+ );
85
+
86
+ return {
87
+ html: response.data.html,
88
+ };
89
+ }