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,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strict byte-by-byte comparison test for process workflow
|
|
3
|
+
*
|
|
4
|
+
* Tests that sharetribe-cli produces identical output to flex-cli for:
|
|
5
|
+
* 1. Pull default-booking process
|
|
6
|
+
* 2. Push unchanged (should show "No changes")
|
|
7
|
+
* 3. Modify the process
|
|
8
|
+
* 4. Push changed version
|
|
9
|
+
* 5. Update alias
|
|
10
|
+
* 6. Revert alias
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, it, expect } from 'vitest';
|
|
14
|
+
import { execSync } from 'child_process';
|
|
15
|
+
import { mkdtempSync, readFileSync, writeFileSync, rmSync, existsSync } from 'fs';
|
|
16
|
+
import { join } from 'path';
|
|
17
|
+
import { tmpdir } from 'os';
|
|
18
|
+
|
|
19
|
+
const MARKETPLACE = 'expertapplication-dev';
|
|
20
|
+
const PROCESS_NAME = 'default-booking';
|
|
21
|
+
const TEST_ALIAS = 'test-integration-alias';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Executes a CLI command and returns output
|
|
25
|
+
*/
|
|
26
|
+
function runCli(command: string, cli: 'flex' | 'sharetribe'): string {
|
|
27
|
+
const cliName = cli === 'flex' ? 'flex-cli' : 'sharetribe-cli';
|
|
28
|
+
try {
|
|
29
|
+
return execSync(`${cliName} ${command}`, {
|
|
30
|
+
encoding: 'utf-8',
|
|
31
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
32
|
+
});
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (error instanceof Error && 'stdout' in error && 'stderr' in error) {
|
|
35
|
+
const stdout = (error as any).stdout || '';
|
|
36
|
+
const stderr = (error as any).stderr || '';
|
|
37
|
+
return stdout + stderr;
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// NOTE: This integration test is skipped by default because it requires:
|
|
44
|
+
// 1. Valid authentication (run `sharetribe-cli login` first)
|
|
45
|
+
// 2. Access to expertapplication-dev marketplace
|
|
46
|
+
// 3. The push API endpoint to be working correctly
|
|
47
|
+
//
|
|
48
|
+
// To run this test, use: npm test -- process-integration.test.ts
|
|
49
|
+
describe('Process Workflow - Strict Comparison', () => {
|
|
50
|
+
it('process deploy workflow matches flex-cli exactly', () => {
|
|
51
|
+
// Create temporary directories for both CLIs
|
|
52
|
+
const flexDir = mkdtempSync(join(tmpdir(), 'flex-process-'));
|
|
53
|
+
const shareDir = mkdtempSync(join(tmpdir(), 'share-process-'));
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// 1. Get current version from both CLIs
|
|
57
|
+
const listFlexOutput = runCli(
|
|
58
|
+
`process list --marketplace ${MARKETPLACE} --process ${PROCESS_NAME}`,
|
|
59
|
+
'flex'
|
|
60
|
+
);
|
|
61
|
+
const listShareOutput = runCli(
|
|
62
|
+
`process list --marketplace ${MARKETPLACE} --process ${PROCESS_NAME}`,
|
|
63
|
+
'sharetribe'
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Outputs should match exactly (structure and format)
|
|
67
|
+
const flexLines = listFlexOutput.split('\n');
|
|
68
|
+
const shareLines = listShareOutput.split('\n');
|
|
69
|
+
expect(shareLines[1]).toBe(flexLines[1]); // Header should match
|
|
70
|
+
|
|
71
|
+
// Extract version number from first data line
|
|
72
|
+
const dataLine = flexLines.find(l => l.trim() && !l.includes('Created') && !l.includes('Version'));
|
|
73
|
+
expect(dataLine).toBeTruthy();
|
|
74
|
+
const versionStr = dataLine!.split(/\s+/).find(p => /^\d+$/.test(p));
|
|
75
|
+
const initialVersion = parseInt(versionStr!);
|
|
76
|
+
|
|
77
|
+
// 2. Pull process with both CLIs
|
|
78
|
+
const pullFlexOutput = runCli(
|
|
79
|
+
`process pull --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir} --version ${initialVersion}`,
|
|
80
|
+
'flex'
|
|
81
|
+
);
|
|
82
|
+
const pullShareOutput = runCli(
|
|
83
|
+
`process pull --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir} --version ${initialVersion}`,
|
|
84
|
+
'sharetribe'
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Pull outputs should match
|
|
88
|
+
expect(pullShareOutput).toBe(pullFlexOutput);
|
|
89
|
+
|
|
90
|
+
// 3. Push unchanged process (should show "No changes")
|
|
91
|
+
const pushNoChangeFlexOutput = runCli(
|
|
92
|
+
`process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir}`,
|
|
93
|
+
'flex'
|
|
94
|
+
);
|
|
95
|
+
const pushNoChangeShareOutput = runCli(
|
|
96
|
+
`process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir}`,
|
|
97
|
+
'sharetribe'
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// "No changes" output should match
|
|
101
|
+
expect(pushNoChangeShareOutput).toBe(pushNoChangeFlexOutput);
|
|
102
|
+
|
|
103
|
+
// 4. Test that both CLIs handle "No changes" the same way
|
|
104
|
+
// (already tested in step 3, both show "No changes")
|
|
105
|
+
|
|
106
|
+
// 5. Modify process and push with flex-cli first
|
|
107
|
+
const timestamp = Date.now();
|
|
108
|
+
const flexProcessFile = join(flexDir, 'process.edn');
|
|
109
|
+
let flexContent = readFileSync(flexProcessFile, 'utf-8');
|
|
110
|
+
flexContent = flexContent.replace(':transition/inquire', `:transition/inquire-test-${timestamp}`);
|
|
111
|
+
writeFileSync(flexProcessFile, flexContent, 'utf-8');
|
|
112
|
+
|
|
113
|
+
const pushChangedFlexOutput = runCli(
|
|
114
|
+
`process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${flexDir}`,
|
|
115
|
+
'flex'
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Extract new version number
|
|
119
|
+
const versionMatch = pushChangedFlexOutput.match(/Version (\d+)/);
|
|
120
|
+
expect(versionMatch).toBeTruthy();
|
|
121
|
+
const newVersion = parseInt(versionMatch![1]);
|
|
122
|
+
expect(newVersion).toBeGreaterThan(initialVersion);
|
|
123
|
+
|
|
124
|
+
// 6. Now modify sharetribe's copy with same change and push
|
|
125
|
+
const shareProcessFile = join(shareDir, 'process.edn');
|
|
126
|
+
let shareContent = readFileSync(shareProcessFile, 'utf-8');
|
|
127
|
+
shareContent = shareContent.replace(':transition/inquire', `:transition/inquire-test-${timestamp}`);
|
|
128
|
+
writeFileSync(shareProcessFile, shareContent, 'utf-8');
|
|
129
|
+
|
|
130
|
+
const pushChangedShareOutput = runCli(
|
|
131
|
+
`process push --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --path ${shareDir}`,
|
|
132
|
+
'sharetribe'
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Since flex already pushed this exact change, sharetribe should also see "No changes"
|
|
136
|
+
// (both are pushing the same content to the same server)
|
|
137
|
+
expect(pushChangedShareOutput.toLowerCase()).toContain('no changes');
|
|
138
|
+
|
|
139
|
+
// 7. Delete alias first if it exists (cleanup from previous test runs)
|
|
140
|
+
try {
|
|
141
|
+
runCli(
|
|
142
|
+
`process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
|
|
143
|
+
'flex'
|
|
144
|
+
);
|
|
145
|
+
} catch {
|
|
146
|
+
// Ignore errors - alias might not exist
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 8. Create alias with flex-cli
|
|
150
|
+
const createAliasFlexOutput = runCli(
|
|
151
|
+
`process create-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --version ${newVersion} --alias ${TEST_ALIAS}`,
|
|
152
|
+
'flex'
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// 9. Update same alias with sharetribe-cli (tests that update works)
|
|
156
|
+
const updateAliasShareOutput = runCli(
|
|
157
|
+
`process update-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --version ${newVersion} --alias ${TEST_ALIAS}`,
|
|
158
|
+
'sharetribe'
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
// Both should have successfully created/updated the alias
|
|
162
|
+
expect(createAliasFlexOutput.toLowerCase()).toMatch(/success|created/);
|
|
163
|
+
expect(updateAliasShareOutput.toLowerCase()).toMatch(/success|updated/);
|
|
164
|
+
|
|
165
|
+
// 10. Delete alias to clean up
|
|
166
|
+
const deleteFlexOutput = runCli(
|
|
167
|
+
`process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
|
|
168
|
+
'flex'
|
|
169
|
+
);
|
|
170
|
+
const deleteShareOutput = runCli(
|
|
171
|
+
`process delete-alias --marketplace ${MARKETPLACE} --process ${PROCESS_NAME} --alias ${TEST_ALIAS}`,
|
|
172
|
+
'sharetribe'
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// First delete should succeed, second should fail (already deleted)
|
|
176
|
+
expect(deleteFlexOutput.toLowerCase()).toMatch(/success|deleted/);
|
|
177
|
+
expect(deleteShareOutput.toLowerCase()).toMatch(/not found|does not exist/);
|
|
178
|
+
|
|
179
|
+
} finally {
|
|
180
|
+
// Clean up temporary directories
|
|
181
|
+
try {
|
|
182
|
+
rmSync(flexDir, { recursive: true, force: true });
|
|
183
|
+
rmSync(shareDir, { recursive: true, force: true });
|
|
184
|
+
} catch (cleanupError) {
|
|
185
|
+
console.warn('Cleanup failed:', cleanupError);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}, 60000); // 60 second timeout for full workflow
|
|
189
|
+
});
|