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/README.md +222 -0
- package/build.js +49 -0
- package/package.json +54 -0
- package/src/api/client.ts +218 -0
- package/src/api/http-client.ts +135 -0
- package/src/api/multipart.ts +78 -0
- package/src/api/transit.ts +96 -0
- package/src/assets.ts +116 -0
- package/src/auth-storage.ts +77 -0
- package/src/deploy.ts +96 -0
- package/src/edn-process.ts +126 -0
- package/src/events.ts +203 -0
- package/src/index.ts +101 -0
- package/src/listing-approval.ts +59 -0
- package/src/notifications.ts +89 -0
- package/src/processes.ts +320 -0
- package/src/sdk-exports.md +25 -0
- package/src/search.ts +273 -0
- package/src/stripe.ts +39 -0
- package/src/types/jsedn.d.ts +9 -0
- package/src/types/transit-js.d.ts +10 -0
- package/src/types.ts +38 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +8 -0
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
|
+
}
|