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,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process command - main entry point for process subcommands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { listProcesses } from './list.js';
|
|
7
|
+
import { createProcess } from './create.js';
|
|
8
|
+
import { pushProcess } from './push.js';
|
|
9
|
+
import { pullProcess } from './pull.js';
|
|
10
|
+
import { createAlias, updateAlias, deleteAlias } from './aliases.js';
|
|
11
|
+
import { createOrPushAndCreateOrUpdateAlias } from './combined.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Registers all process subcommands
|
|
15
|
+
*/
|
|
16
|
+
export function registerProcessCommands(program: Command): void {
|
|
17
|
+
// Register the parent 'process' command for help display
|
|
18
|
+
const processCmd = program
|
|
19
|
+
.command('process')
|
|
20
|
+
.description('describe a process file')
|
|
21
|
+
.option('--path <PROCESS_DIR>', 'path to the directory where the process.edn file is')
|
|
22
|
+
.option('--transition <TRANSITION_NAME>', 'transition name, e.g. transition/request to get more details of it')
|
|
23
|
+
.action(async (options) => {
|
|
24
|
+
// Process describe functionality
|
|
25
|
+
if (options.path) {
|
|
26
|
+
console.log(`Describing process at: ${options.path}`);
|
|
27
|
+
if (options.transition) {
|
|
28
|
+
console.log(`Transition: ${options.transition}`);
|
|
29
|
+
}
|
|
30
|
+
// TODO: Implement actual process file parsing and description
|
|
31
|
+
console.log('Process description not yet implemented');
|
|
32
|
+
} else {
|
|
33
|
+
// If no options, show help
|
|
34
|
+
processCmd.outputHelp();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Register subcommands - these are registered as BOTH subcommands (for help) and top-level (for routing)
|
|
39
|
+
|
|
40
|
+
// process list (as subcommand)
|
|
41
|
+
processCmd
|
|
42
|
+
.command('list')
|
|
43
|
+
.description('list all transaction processes')
|
|
44
|
+
.option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')
|
|
45
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
48
|
+
if (!marketplace) {
|
|
49
|
+
console.error('Error: --marketplace is required');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
await listProcesses(marketplace, options.process);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// process create
|
|
56
|
+
processCmd
|
|
57
|
+
.command('create')
|
|
58
|
+
.description('create a new transaction process')
|
|
59
|
+
.requiredOption('--process <PROCESS_NAME>', 'name for the new process')
|
|
60
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')
|
|
61
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
64
|
+
if (!marketplace) {
|
|
65
|
+
console.error('Error: --marketplace is required');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
await createProcess(marketplace, options.process, options.path);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// process push
|
|
72
|
+
processCmd
|
|
73
|
+
.command('push')
|
|
74
|
+
.description('push a process file to the remote')
|
|
75
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
76
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')
|
|
77
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
78
|
+
.action(async (options) => {
|
|
79
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
80
|
+
if (!marketplace) {
|
|
81
|
+
console.error('Error: --marketplace is required');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
await pushProcess(marketplace, options.process, options.path);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// process pull
|
|
88
|
+
processCmd
|
|
89
|
+
.command('pull')
|
|
90
|
+
.description('fetch a process file')
|
|
91
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
92
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')
|
|
93
|
+
.option('--version <VERSION_NUM>', 'version number')
|
|
94
|
+
.option('--alias <PROCESS_ALIAS>', 'alias name')
|
|
95
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
96
|
+
.action(async (options) => {
|
|
97
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
98
|
+
if (!marketplace) {
|
|
99
|
+
console.error('Error: --marketplace is required');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
await pullProcess(marketplace, options.process, options.path, options.version, options.alias);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// process create-alias
|
|
106
|
+
processCmd
|
|
107
|
+
.command('create-alias')
|
|
108
|
+
.description('create a new alias')
|
|
109
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
110
|
+
.requiredOption('--version <VERSION_NUM>', 'version number')
|
|
111
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
112
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
113
|
+
.allowUnknownOption(false)
|
|
114
|
+
.action(async (options) => {
|
|
115
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
116
|
+
if (!marketplace) {
|
|
117
|
+
console.error('Error: --marketplace is required');
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
await createAlias(marketplace, options.process, parseInt(options.version), options.alias);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// process update-alias
|
|
124
|
+
processCmd
|
|
125
|
+
.command('update-alias')
|
|
126
|
+
.description('update an existing alias')
|
|
127
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
128
|
+
.requiredOption('--version <VERSION_NUM>', 'version number')
|
|
129
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
130
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
131
|
+
.action(async (options) => {
|
|
132
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
133
|
+
if (!marketplace) {
|
|
134
|
+
console.error('Error: --marketplace is required');
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// process delete-alias
|
|
141
|
+
processCmd
|
|
142
|
+
.command('delete-alias')
|
|
143
|
+
.description('delete an existing alias')
|
|
144
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
145
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
146
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
147
|
+
.action(async (options) => {
|
|
148
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
149
|
+
if (!marketplace) {
|
|
150
|
+
console.error('Error: --marketplace is required');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
await deleteAlias(marketplace, options.process, options.alias);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// process deploy (combined command: create-or-push-and-create-or-update-alias)
|
|
157
|
+
processCmd
|
|
158
|
+
.command('deploy')
|
|
159
|
+
.description('deploy a process file with alias (create/push + alias create/update)')
|
|
160
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
161
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')
|
|
162
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
163
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
164
|
+
.action(async (options) => {
|
|
165
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
166
|
+
if (!marketplace) {
|
|
167
|
+
console.error('Error: --marketplace is required');
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
await createOrPushAndCreateOrUpdateAlias(
|
|
171
|
+
marketplace,
|
|
172
|
+
options.process,
|
|
173
|
+
options.path,
|
|
174
|
+
options.alias
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Register top-level command aliases for routing (hidden from help)
|
|
179
|
+
// These handle the routed commands like 'process-pull' that avoid Commander's parent/child option conflicts
|
|
180
|
+
|
|
181
|
+
program
|
|
182
|
+
.command('process-list', { hidden: true })
|
|
183
|
+
.description('list all transaction processes')
|
|
184
|
+
.option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')
|
|
185
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
186
|
+
.action(async (options) => {
|
|
187
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
188
|
+
if (!marketplace) {
|
|
189
|
+
console.error('Error: --marketplace is required');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
await listProcesses(marketplace, options.process);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
program
|
|
196
|
+
.command('process-create', { hidden: true })
|
|
197
|
+
.description('create a new transaction process')
|
|
198
|
+
.requiredOption('--process <PROCESS_NAME>', 'name for the new process')
|
|
199
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')
|
|
200
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
201
|
+
.action(async (options) => {
|
|
202
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
203
|
+
if (!marketplace) {
|
|
204
|
+
console.error('Error: --marketplace is required');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
await createProcess(marketplace, options.process, options.path);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
program
|
|
211
|
+
.command('process-push', { hidden: true })
|
|
212
|
+
.description('push a process file to the remote')
|
|
213
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
214
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')
|
|
215
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
216
|
+
.action(async (options) => {
|
|
217
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
218
|
+
if (!marketplace) {
|
|
219
|
+
console.error('Error: --marketplace is required');
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
await pushProcess(marketplace, options.process, options.path);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
program
|
|
226
|
+
.command('process-pull', { hidden: true })
|
|
227
|
+
.description('fetch a process file')
|
|
228
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
229
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')
|
|
230
|
+
.option('--version <VERSION_NUM>', 'version number')
|
|
231
|
+
.option('--alias <PROCESS_ALIAS>', 'alias name')
|
|
232
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
233
|
+
.action(async (options) => {
|
|
234
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
235
|
+
if (!marketplace) {
|
|
236
|
+
console.error('Error: --marketplace is required');
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
await pullProcess(marketplace, options.process, options.path, options.version, options.alias);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
program
|
|
243
|
+
.command('process-create-alias', { hidden: true })
|
|
244
|
+
.description('create a new alias')
|
|
245
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
246
|
+
.requiredOption('--version <VERSION_NUM>', 'version number')
|
|
247
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
248
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
249
|
+
.action(async (options) => {
|
|
250
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
251
|
+
if (!marketplace) {
|
|
252
|
+
console.error('Error: --marketplace is required');
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
await createAlias(marketplace, options.process, parseInt(options.version), options.alias);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
program
|
|
259
|
+
.command('process-update-alias', { hidden: true })
|
|
260
|
+
.description('update an existing alias')
|
|
261
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
262
|
+
.requiredOption('--version <VERSION_NUM>', 'version number')
|
|
263
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
264
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
265
|
+
.action(async (options) => {
|
|
266
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
267
|
+
if (!marketplace) {
|
|
268
|
+
console.error('Error: --marketplace is required');
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
program
|
|
275
|
+
.command('process-delete-alias', { hidden: true })
|
|
276
|
+
.description('delete an existing alias')
|
|
277
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
278
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
279
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
280
|
+
.action(async (options) => {
|
|
281
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
282
|
+
if (!marketplace) {
|
|
283
|
+
console.error('Error: --marketplace is required');
|
|
284
|
+
process.exit(1);
|
|
285
|
+
}
|
|
286
|
+
await deleteAlias(marketplace, options.process, options.alias);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
program
|
|
290
|
+
.command('process-deploy', { hidden: true })
|
|
291
|
+
.description('deploy a process file with alias (create/push + alias create/update)')
|
|
292
|
+
.requiredOption('--process <PROCESS_NAME>', 'name of the process')
|
|
293
|
+
.requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')
|
|
294
|
+
.requiredOption('--alias <ALIAS>', 'alias name')
|
|
295
|
+
.option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')
|
|
296
|
+
.action(async (options) => {
|
|
297
|
+
const marketplace = options.marketplace || program.opts().marketplace;
|
|
298
|
+
if (!marketplace) {
|
|
299
|
+
console.error('Error: --marketplace is required');
|
|
300
|
+
process.exit(1);
|
|
301
|
+
}
|
|
302
|
+
await createOrPushAndCreateOrUpdateAlias(
|
|
303
|
+
marketplace,
|
|
304
|
+
options.process,
|
|
305
|
+
options.path,
|
|
306
|
+
options.alias
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process list command - lists all transaction processes
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
listProcesses as sdkListProcesses,
|
|
7
|
+
listProcessVersions as sdkListProcessVersions,
|
|
8
|
+
} from 'sharetribe-flex-build-sdk';
|
|
9
|
+
import { printTable, printError } from '../../util/output.js';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Formats timestamp to match flex-cli format for process list
|
|
14
|
+
*/
|
|
15
|
+
function formatProcessTimestamp(timestamp: string): string {
|
|
16
|
+
try {
|
|
17
|
+
const date = new Date(timestamp);
|
|
18
|
+
const year = date.getFullYear();
|
|
19
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
20
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
21
|
+
const timeString = date.toLocaleTimeString('en-US');
|
|
22
|
+
|
|
23
|
+
return `${year}-${month}-${day} ${timeString}`;
|
|
24
|
+
} catch {
|
|
25
|
+
return timestamp;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Lists all processes for a marketplace
|
|
31
|
+
*/
|
|
32
|
+
export async function listProcesses(marketplace: string, processName?: string): Promise<void> {
|
|
33
|
+
try {
|
|
34
|
+
// If processName is specified, show version history for that process
|
|
35
|
+
if (processName) {
|
|
36
|
+
const versions = await sdkListProcessVersions(undefined, marketplace, processName);
|
|
37
|
+
|
|
38
|
+
if (versions.length === 0) {
|
|
39
|
+
console.log(`No versions found for process: ${processName}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const versionRows = versions.map((v) => ({
|
|
44
|
+
'Created': formatProcessTimestamp(v.createdAt),
|
|
45
|
+
'Version': v.version.toString(),
|
|
46
|
+
'Aliases': v.aliases?.join(', ') || '',
|
|
47
|
+
'Transactions': v.transactionCount?.toString() || '0',
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
printTable(['Created', 'Version', 'Aliases', 'Transactions'], versionRows);
|
|
51
|
+
} else {
|
|
52
|
+
// List all processes
|
|
53
|
+
const processes = await sdkListProcesses(undefined, marketplace);
|
|
54
|
+
|
|
55
|
+
if (processes.length === 0) {
|
|
56
|
+
console.log('No processes found.');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const processRows = processes.map((p) => ({
|
|
61
|
+
'Name': p.name,
|
|
62
|
+
'Latest version': p.version?.toString() || '',
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
printTable(['Name', 'Latest version'], processRows);
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
69
|
+
printError(error.message as string);
|
|
70
|
+
} else {
|
|
71
|
+
printError('Failed to list processes');
|
|
72
|
+
}
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process pull command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { getProcess } from 'sharetribe-flex-build-sdk';
|
|
6
|
+
import { printError, printSuccess } from '../../util/output.js';
|
|
7
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Pulls a process from the server
|
|
12
|
+
*/
|
|
13
|
+
export async function pullProcess(
|
|
14
|
+
marketplace: string,
|
|
15
|
+
processName: string,
|
|
16
|
+
path: string,
|
|
17
|
+
version?: string,
|
|
18
|
+
alias?: string
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
try {
|
|
21
|
+
const process = await getProcess(undefined, marketplace, processName, { version, alias });
|
|
22
|
+
|
|
23
|
+
if (!process.definition) {
|
|
24
|
+
throw new Error('No process definition in response');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Ensure directory exists (print message if creating new directory)
|
|
28
|
+
const { existsSync } = await import('node:fs');
|
|
29
|
+
const dirExists = existsSync(path);
|
|
30
|
+
mkdirSync(path, { recursive: true });
|
|
31
|
+
|
|
32
|
+
if (!dirExists) {
|
|
33
|
+
console.error(`Creating a new directory: ${path}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Write process.edn file
|
|
37
|
+
const processFilePath = join(path, 'process.edn');
|
|
38
|
+
writeFileSync(processFilePath, process.definition, 'utf-8');
|
|
39
|
+
|
|
40
|
+
// Write email templates if they exist
|
|
41
|
+
const templates = process.emailTemplates || [];
|
|
42
|
+
|
|
43
|
+
if (templates && Array.isArray(templates) && templates.length > 0) {
|
|
44
|
+
const templatesDir = join(path, 'templates');
|
|
45
|
+
mkdirSync(templatesDir, { recursive: true });
|
|
46
|
+
|
|
47
|
+
for (const template of templates) {
|
|
48
|
+
const templateName = template.name;
|
|
49
|
+
const htmlContent = template.html;
|
|
50
|
+
const subjectContent = template.subject;
|
|
51
|
+
|
|
52
|
+
if (templateName) {
|
|
53
|
+
// Create subdirectory for this template
|
|
54
|
+
const templateSubdir = join(templatesDir, templateName);
|
|
55
|
+
mkdirSync(templateSubdir, { recursive: true });
|
|
56
|
+
|
|
57
|
+
// Write HTML file
|
|
58
|
+
if (htmlContent) {
|
|
59
|
+
const htmlPath = join(templateSubdir, `${templateName}-html.html`);
|
|
60
|
+
writeFileSync(htmlPath, htmlContent, 'utf-8');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Write subject file
|
|
64
|
+
if (subjectContent) {
|
|
65
|
+
const subjectPath = join(templateSubdir, `${templateName}-subject.txt`);
|
|
66
|
+
writeFileSync(subjectPath, subjectContent, 'utf-8');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.error(`Saved process to ${path}`);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
75
|
+
printError(error.message as string);
|
|
76
|
+
} else {
|
|
77
|
+
printError('Failed to pull process');
|
|
78
|
+
}
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process push command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { pushProcess as sdkPushProcess } from 'sharetribe-flex-build-sdk';
|
|
6
|
+
import { printError, printSuccess } from '../../util/output.js';
|
|
7
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Reads email templates from the templates directory
|
|
12
|
+
*/
|
|
13
|
+
function readTemplates(path: string): Array<{ name: string; html: string; subject: string }> {
|
|
14
|
+
const templatesDir = join(path, 'templates');
|
|
15
|
+
const templates: Array<{ name: string; html: string; subject: string }> = [];
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const templateDirs = readdirSync(templatesDir);
|
|
19
|
+
for (const templateName of templateDirs) {
|
|
20
|
+
const templatePath = join(templatesDir, templateName);
|
|
21
|
+
const htmlFile = join(templatePath, `${templateName}-html.html`);
|
|
22
|
+
const subjectFile = join(templatePath, `${templateName}-subject.txt`);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const html = readFileSync(htmlFile, 'utf-8');
|
|
26
|
+
const subject = readFileSync(subjectFile, 'utf-8');
|
|
27
|
+
templates.push({ name: templateName, html, subject });
|
|
28
|
+
} catch {
|
|
29
|
+
// Skip if files don't exist
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// No templates directory - return empty array
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return templates;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Pushes a new version of an existing process
|
|
41
|
+
*/
|
|
42
|
+
export async function pushProcess(
|
|
43
|
+
marketplace: string,
|
|
44
|
+
processName: string,
|
|
45
|
+
path: string
|
|
46
|
+
): Promise<void> {
|
|
47
|
+
try {
|
|
48
|
+
const processFilePath = join(path, 'process.edn');
|
|
49
|
+
const processContent = readFileSync(processFilePath, 'utf-8');
|
|
50
|
+
const templates = readTemplates(path);
|
|
51
|
+
|
|
52
|
+
const result = await sdkPushProcess(undefined, marketplace, processName, processContent, templates);
|
|
53
|
+
|
|
54
|
+
if (result.noChanges) {
|
|
55
|
+
console.log('No changes');
|
|
56
|
+
} else {
|
|
57
|
+
printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
61
|
+
printError(error.message as string);
|
|
62
|
+
} else {
|
|
63
|
+
printError('Failed to push process');
|
|
64
|
+
}
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|