sharetribe-cli 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/.eslintrc.json +29 -0
- package/.prettierrc +9 -0
- package/build.js +58 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +7 -0
- package/package.json +58 -0
- package/src/commands/assets/index.ts +338 -0
- package/src/commands/events/index.ts +289 -0
- package/src/commands/help.ts +19 -0
- package/src/commands/listing-approval.ts +121 -0
- package/src/commands/login.ts +43 -0
- package/src/commands/logout.ts +17 -0
- package/src/commands/notifications/index.ts +221 -0
- package/src/commands/process/aliases.ts +82 -0
- package/src/commands/process/combined.ts +62 -0
- package/src/commands/process/create.ts +35 -0
- package/src/commands/process/index.ts +309 -0
- package/src/commands/process/list.ts +75 -0
- package/src/commands/process/pull.ts +81 -0
- package/src/commands/process/push.ts +67 -0
- package/src/commands/search/index.ts +254 -0
- package/src/commands/stripe/index.ts +114 -0
- package/src/commands/version.ts +40 -0
- package/src/index.ts +131 -0
- package/src/types/index.ts +21 -0
- package/src/util/command-router.ts +41 -0
- package/src/util/help-formatter.ts +266 -0
- package/src/util/output.ts +83 -0
- package/test/help-comparison.test.ts +255 -0
- package/test/process-builder.test.ts +14 -0
- package/test/process-integration.test.ts +189 -0
- package/test/strict-comparison.test.ts +722 -0
- package/tsconfig.json +50 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Listing approval command - DEPRECATED
|
|
3
|
+
*
|
|
4
|
+
* This command is deprecated and should not be used.
|
|
5
|
+
* Use the Sharetribe Console instead.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
import {
|
|
10
|
+
getListingApprovalStatus as sdkGetStatus,
|
|
11
|
+
enableListingApproval as sdkEnable,
|
|
12
|
+
disableListingApproval as sdkDisable,
|
|
13
|
+
} from 'sharetribe-flex-build-sdk';
|
|
14
|
+
import { printError } from '../util/output.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets current listing approval status
|
|
18
|
+
*/
|
|
19
|
+
async function getStatus(marketplace: string): Promise<void> {
|
|
20
|
+
try {
|
|
21
|
+
const result = await sdkGetStatus(undefined, marketplace);
|
|
22
|
+
|
|
23
|
+
if (result.enabled) {
|
|
24
|
+
console.log(`Listing approvals are enabled in ${marketplace}`);
|
|
25
|
+
} else {
|
|
26
|
+
console.log(`Listing approvals are disabled in ${marketplace}`);
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
30
|
+
printError(error.message as string);
|
|
31
|
+
} else {
|
|
32
|
+
printError('Failed to get listing approval status');
|
|
33
|
+
}
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Enables listing approvals
|
|
40
|
+
*/
|
|
41
|
+
async function enableApprovals(marketplace: string): Promise<void> {
|
|
42
|
+
try {
|
|
43
|
+
await sdkEnable(undefined, marketplace);
|
|
44
|
+
console.log(`Successfully enabled listing approvals in ${marketplace}`);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
47
|
+
printError(error.message as string);
|
|
48
|
+
} else {
|
|
49
|
+
printError('Failed to enable listing approvals');
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Disables listing approvals
|
|
57
|
+
*/
|
|
58
|
+
async function disableApprovals(marketplace: string): Promise<void> {
|
|
59
|
+
try {
|
|
60
|
+
await sdkDisable(undefined, marketplace);
|
|
61
|
+
console.log(`Successfully disabled listing approvals in ${marketplace}`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
64
|
+
printError(error.message as string);
|
|
65
|
+
} else {
|
|
66
|
+
printError('Failed to disable listing approvals');
|
|
67
|
+
}
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Registers listing-approval command
|
|
74
|
+
*/
|
|
75
|
+
export function registerListingApprovalCommand(program: Command): void {
|
|
76
|
+
const cmd = program
|
|
77
|
+
.command('listing-approval')
|
|
78
|
+
.description('manage listing approvals (DEPRECATED - use Console instead)')
|
|
79
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');
|
|
80
|
+
|
|
81
|
+
// Default action - show status
|
|
82
|
+
cmd.action(async (opts) => {
|
|
83
|
+
console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');
|
|
84
|
+
const marketplace = opts.marketplace || program.opts().marketplace;
|
|
85
|
+
if (!marketplace) {
|
|
86
|
+
console.error('Error: --marketplace is required');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
await getStatus(marketplace);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Enable subcommand
|
|
93
|
+
cmd
|
|
94
|
+
.command('enable')
|
|
95
|
+
.description('enable listing approvals')
|
|
96
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
97
|
+
.action(async (opts) => {
|
|
98
|
+
console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');
|
|
99
|
+
const marketplace = opts.marketplace || program.opts().marketplace;
|
|
100
|
+
if (!marketplace) {
|
|
101
|
+
console.error('Error: --marketplace is required');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
await enableApprovals(marketplace);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Disable subcommand
|
|
108
|
+
cmd
|
|
109
|
+
.command('disable')
|
|
110
|
+
.description('disable listing approvals')
|
|
111
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
112
|
+
.action(async (opts) => {
|
|
113
|
+
console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');
|
|
114
|
+
const marketplace = opts.marketplace || program.opts().marketplace;
|
|
115
|
+
if (!marketplace) {
|
|
116
|
+
console.error('Error: --marketplace is required');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
await disableApprovals(marketplace);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Login command - interactive API key authentication
|
|
3
|
+
*
|
|
4
|
+
* Must match flex-cli behavior exactly:
|
|
5
|
+
* - Prompt for API key
|
|
6
|
+
* - Store in ~/.config/flex-cli/auth.edn
|
|
7
|
+
* - Display admin email on success
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import inquirer from 'inquirer';
|
|
11
|
+
import { writeAuth } from 'sharetribe-flex-build-sdk';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Executes the login command
|
|
15
|
+
*
|
|
16
|
+
* Prompts for API key and stores it in auth.edn
|
|
17
|
+
*/
|
|
18
|
+
export async function login(): Promise<void> {
|
|
19
|
+
const answers = await inquirer.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'password',
|
|
22
|
+
name: 'apiKey',
|
|
23
|
+
message: 'Enter API key:',
|
|
24
|
+
mask: '*',
|
|
25
|
+
validate: (input: string) => {
|
|
26
|
+
if (!input || input.trim().length === 0) {
|
|
27
|
+
return 'API key cannot be empty';
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
// Store the API key
|
|
35
|
+
writeAuth({ apiKey: answers.apiKey });
|
|
36
|
+
|
|
37
|
+
// TODO: Validate API key by making a test request to get admin email
|
|
38
|
+
// For now, just confirm storage
|
|
39
|
+
console.log('Successfully logged in.');
|
|
40
|
+
|
|
41
|
+
// Note: flex-cli displays admin email after successful login
|
|
42
|
+
// We'll need to implement API client to fetch this
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logout command - clears authentication
|
|
3
|
+
*
|
|
4
|
+
* Must match flex-cli behavior exactly
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { clearAuth } from 'sharetribe-flex-build-sdk';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Executes the logout command
|
|
11
|
+
*
|
|
12
|
+
* Clears auth.edn file
|
|
13
|
+
*/
|
|
14
|
+
export async function logout(): Promise<void> {
|
|
15
|
+
await clearAuth();
|
|
16
|
+
console.log('Successfully logged out.');
|
|
17
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notifications commands - manage email notifications
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import {
|
|
7
|
+
sendNotification as sdkSendNotification,
|
|
8
|
+
previewNotification as sdkPreviewNotification,
|
|
9
|
+
} from 'sharetribe-flex-build-sdk';
|
|
10
|
+
import { printError } from '../../util/output.js';
|
|
11
|
+
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { createServer, IncomingMessage, ServerResponse } from 'node:http';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Reads a notification template from a directory
|
|
18
|
+
*/
|
|
19
|
+
function readTemplate(templatePath: string): { html: string; subject: string } {
|
|
20
|
+
if (!existsSync(templatePath) || !statSync(templatePath).isDirectory()) {
|
|
21
|
+
throw new Error(`Template directory not found: ${templatePath}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const htmlPath = join(templatePath, 'template.html');
|
|
25
|
+
const subjectPath = join(templatePath, 'template-subject.txt');
|
|
26
|
+
|
|
27
|
+
if (!existsSync(htmlPath)) {
|
|
28
|
+
throw new Error(`template.html not found in ${templatePath}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!existsSync(subjectPath)) {
|
|
32
|
+
throw new Error(`template-subject.txt not found in ${templatePath}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const html = readFileSync(htmlPath, 'utf-8');
|
|
36
|
+
const subject = readFileSync(subjectPath, 'utf-8').trim();
|
|
37
|
+
|
|
38
|
+
return { html, subject };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Reads template context JSON file
|
|
43
|
+
*/
|
|
44
|
+
function readContext(contextPath?: string): unknown {
|
|
45
|
+
if (!contextPath) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!existsSync(contextPath)) {
|
|
50
|
+
throw new Error(`Context file not found: ${contextPath}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const content = readFileSync(contextPath, 'utf-8');
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(content);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw new Error(`Invalid JSON in context file: ${error}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sends a preview email to the marketplace admin
|
|
63
|
+
*/
|
|
64
|
+
async function sendNotification(
|
|
65
|
+
marketplace: string,
|
|
66
|
+
templatePath: string,
|
|
67
|
+
contextPath?: string
|
|
68
|
+
): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
const template = readTemplate(templatePath);
|
|
71
|
+
const context = readContext(contextPath);
|
|
72
|
+
|
|
73
|
+
const result = await sdkSendNotification(undefined, marketplace, { template, context });
|
|
74
|
+
|
|
75
|
+
console.log(`Preview successfully sent to ${result.adminEmail}`);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
78
|
+
printError(error.message as string);
|
|
79
|
+
} else {
|
|
80
|
+
printError('Failed to send notification');
|
|
81
|
+
}
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Previews a notification in the browser
|
|
88
|
+
*/
|
|
89
|
+
async function previewNotification(
|
|
90
|
+
marketplace: string,
|
|
91
|
+
templatePath: string,
|
|
92
|
+
contextPath?: string
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
try {
|
|
95
|
+
const template = readTemplate(templatePath);
|
|
96
|
+
const context = readContext(contextPath);
|
|
97
|
+
|
|
98
|
+
console.log(`Template: ${templatePath}`);
|
|
99
|
+
console.log(`Subject: ${template.subject}`);
|
|
100
|
+
console.log('');
|
|
101
|
+
console.log('Starting preview server at http://localhost:3535');
|
|
102
|
+
console.log('Press Ctrl+C to stop');
|
|
103
|
+
console.log('');
|
|
104
|
+
|
|
105
|
+
let previewHtml: string | null = null;
|
|
106
|
+
|
|
107
|
+
// Fetch preview from API
|
|
108
|
+
const fetchPreview = async () => {
|
|
109
|
+
try {
|
|
110
|
+
const result = await sdkPreviewNotification(undefined, marketplace, { template, context });
|
|
111
|
+
|
|
112
|
+
// Inject title into HTML
|
|
113
|
+
const html = result.html;
|
|
114
|
+
const titleTag = `<title>${template.subject}</title>`;
|
|
115
|
+
|
|
116
|
+
if (html.includes('<head>')) {
|
|
117
|
+
previewHtml = html.replace('<head>', `<head>\n${titleTag}`);
|
|
118
|
+
} else if (html.includes('<html>')) {
|
|
119
|
+
previewHtml = html.replace('<html>', `<html>\n<head>${titleTag}</head>`);
|
|
120
|
+
} else {
|
|
121
|
+
previewHtml = `<html><head>${titleTag}</head><body>${html}</body></html>`;
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
const errorMessage = error && typeof error === 'object' && 'message' in error
|
|
125
|
+
? (error.message as string)
|
|
126
|
+
: 'Failed to preview notification';
|
|
127
|
+
|
|
128
|
+
previewHtml = `
|
|
129
|
+
<html>
|
|
130
|
+
<head><title>Error</title></head>
|
|
131
|
+
<body style="font-family: sans-serif; padding: 20px;">
|
|
132
|
+
<h1 style="color: #d32f2f;">Error</h1>
|
|
133
|
+
<pre style="background: #f5f5f5; padding: 15px; border-radius: 4px;">${errorMessage}</pre>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Initial fetch
|
|
141
|
+
await fetchPreview();
|
|
142
|
+
|
|
143
|
+
// Create HTTP server
|
|
144
|
+
const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {
|
|
145
|
+
if (req.url === '/' || req.url === '') {
|
|
146
|
+
// Refresh preview on each request
|
|
147
|
+
await fetchPreview();
|
|
148
|
+
|
|
149
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
150
|
+
res.end(previewHtml);
|
|
151
|
+
} else {
|
|
152
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
153
|
+
res.end('Not Found');
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
server.listen(3535, () => {
|
|
158
|
+
console.log('Preview server started. Open http://localhost:3535 in your browser.');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Handle graceful shutdown
|
|
162
|
+
const shutdown = () => {
|
|
163
|
+
console.log('\nShutting down preview server...');
|
|
164
|
+
server.close(() => {
|
|
165
|
+
process.exit(0);
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
process.on('SIGINT', shutdown);
|
|
170
|
+
process.on('SIGTERM', shutdown);
|
|
171
|
+
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
174
|
+
printError(error.message as string);
|
|
175
|
+
} else {
|
|
176
|
+
printError('Failed to preview notification');
|
|
177
|
+
}
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Registers notifications commands
|
|
184
|
+
*/
|
|
185
|
+
export function registerNotificationsCommands(program: Command): void {
|
|
186
|
+
const notificationsCmd = program
|
|
187
|
+
.command('notifications')
|
|
188
|
+
.description('manage email notifications');
|
|
189
|
+
|
|
190
|
+
// notifications preview
|
|
191
|
+
notificationsCmd
|
|
192
|
+
.command('preview')
|
|
193
|
+
.description('render a preview of an email template')
|
|
194
|
+
.requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')
|
|
195
|
+
.option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')
|
|
196
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
197
|
+
.action(async (opts) => {
|
|
198
|
+
const marketplace = opts.marketplace || program.opts().marketplace;
|
|
199
|
+
if (!marketplace) {
|
|
200
|
+
console.error('Error: --marketplace is required');
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
await previewNotification(marketplace, opts.template, opts.context);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// notifications send
|
|
207
|
+
notificationsCmd
|
|
208
|
+
.command('send')
|
|
209
|
+
.description('send a preview of an email template to the logged in admin')
|
|
210
|
+
.requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')
|
|
211
|
+
.option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')
|
|
212
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
213
|
+
.action(async (opts) => {
|
|
214
|
+
const marketplace = opts.marketplace || program.opts().marketplace;
|
|
215
|
+
if (!marketplace) {
|
|
216
|
+
console.error('Error: --marketplace is required');
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
await sendNotification(marketplace, opts.template, opts.context);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process alias commands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
createAlias as sdkCreateAlias,
|
|
7
|
+
updateAlias as sdkUpdateAlias,
|
|
8
|
+
deleteAlias as sdkDeleteAlias
|
|
9
|
+
} from 'sharetribe-flex-build-sdk';
|
|
10
|
+
import { printError, printSuccess } from '../../util/output.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a process alias
|
|
14
|
+
*/
|
|
15
|
+
export async function createAlias(
|
|
16
|
+
marketplace: string,
|
|
17
|
+
processName: string,
|
|
18
|
+
version: number,
|
|
19
|
+
alias: string
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
try {
|
|
22
|
+
const result = await sdkCreateAlias(undefined, marketplace, processName, version, alias);
|
|
23
|
+
|
|
24
|
+
printSuccess(
|
|
25
|
+
`Alias ${result.alias} successfully created to point to version ${result.version}.`
|
|
26
|
+
);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
29
|
+
printError(error.message as string);
|
|
30
|
+
} else {
|
|
31
|
+
printError('Failed to create alias');
|
|
32
|
+
}
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Updates a process alias
|
|
39
|
+
*/
|
|
40
|
+
export async function updateAlias(
|
|
41
|
+
marketplace: string,
|
|
42
|
+
processName: string,
|
|
43
|
+
version: number,
|
|
44
|
+
alias: string
|
|
45
|
+
): Promise<void> {
|
|
46
|
+
try {
|
|
47
|
+
const result = await sdkUpdateAlias(undefined, marketplace, processName, version, alias);
|
|
48
|
+
|
|
49
|
+
printSuccess(
|
|
50
|
+
`Alias ${result.alias} successfully updated to point to version ${result.version}.`
|
|
51
|
+
);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
54
|
+
printError(error.message as string);
|
|
55
|
+
} else {
|
|
56
|
+
printError('Failed to update alias');
|
|
57
|
+
}
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Deletes a process alias
|
|
64
|
+
*/
|
|
65
|
+
export async function deleteAlias(
|
|
66
|
+
marketplace: string,
|
|
67
|
+
processName: string,
|
|
68
|
+
alias: string
|
|
69
|
+
): Promise<void> {
|
|
70
|
+
try {
|
|
71
|
+
const result = await sdkDeleteAlias(undefined, marketplace, processName, alias);
|
|
72
|
+
|
|
73
|
+
printSuccess(`Alias ${result.alias} successfully deleted.`);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
76
|
+
printError(error.message as string);
|
|
77
|
+
} else {
|
|
78
|
+
printError('Failed to delete alias');
|
|
79
|
+
}
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combined process command - create-or-push-and-create-or-update-alias
|
|
3
|
+
*
|
|
4
|
+
* This is the enhanced "superset" feature that combines multiple operations
|
|
5
|
+
* into one atomic command
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { deployProcess as sdkDeployProcess, parseProcessFile } from 'sharetribe-flex-build-sdk';
|
|
9
|
+
import { printError, printSuccess } from '../../util/output.js';
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates or pushes a process and creates or updates an alias
|
|
15
|
+
*
|
|
16
|
+
* This is an atomic operation that:
|
|
17
|
+
* 1. Tries to push a new version (create-version)
|
|
18
|
+
* 2. If process doesn't exist, creates it
|
|
19
|
+
* 3. Then creates or updates the alias
|
|
20
|
+
*/
|
|
21
|
+
export async function createOrPushAndCreateOrUpdateAlias(
|
|
22
|
+
marketplace: string,
|
|
23
|
+
processName: string,
|
|
24
|
+
path: string,
|
|
25
|
+
alias: string
|
|
26
|
+
): Promise<void> {
|
|
27
|
+
try {
|
|
28
|
+
const processFilePath = join(path, 'process.edn');
|
|
29
|
+
const processContent = readFileSync(processFilePath, 'utf-8');
|
|
30
|
+
const processDefinition = parseProcessFile(processContent);
|
|
31
|
+
|
|
32
|
+
const result = await sdkDeployProcess(
|
|
33
|
+
undefined, // Use auth from file
|
|
34
|
+
marketplace,
|
|
35
|
+
{
|
|
36
|
+
process: processName,
|
|
37
|
+
alias,
|
|
38
|
+
path: processFilePath,
|
|
39
|
+
processDefinition,
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (result.processCreated) {
|
|
44
|
+
printSuccess(`Process ${processName} successfully created.`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);
|
|
48
|
+
|
|
49
|
+
if (result.aliasCreated) {
|
|
50
|
+
printSuccess(`Alias ${result.alias} successfully created to point to version ${result.version}.`);
|
|
51
|
+
} else {
|
|
52
|
+
printSuccess(`Alias ${result.alias} successfully updated to point to version ${result.version}.`);
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
56
|
+
printError(error.message as string);
|
|
57
|
+
} else {
|
|
58
|
+
printError('Failed to create/push process and alias');
|
|
59
|
+
}
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process create command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createProcess as sdkCreateProcess } from 'sharetribe-flex-build-sdk';
|
|
6
|
+
import { printError, printSuccess } from '../../util/output.js';
|
|
7
|
+
import { readFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new transaction process
|
|
12
|
+
*/
|
|
13
|
+
export async function createProcess(
|
|
14
|
+
marketplace: string,
|
|
15
|
+
processName: string,
|
|
16
|
+
path: string
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
try {
|
|
19
|
+
const processFilePath = join(path, 'process.edn');
|
|
20
|
+
const processContent = readFileSync(processFilePath, 'utf-8');
|
|
21
|
+
|
|
22
|
+
const result = await sdkCreateProcess(undefined, marketplace, processName, processContent);
|
|
23
|
+
|
|
24
|
+
printSuccess(
|
|
25
|
+
`Process ${result.name} successfully created with version ${result.version}.`
|
|
26
|
+
);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
29
|
+
printError(error.message as string);
|
|
30
|
+
} else {
|
|
31
|
+
printError('Failed to create process');
|
|
32
|
+
}
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|