@miso.ai/server-sdk 0.6.6-beta.3 → 0.6.6-beta.5
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/cli/merge-local.js +92 -81
- package/package.json +2 -2
- package/src/version.js +1 -1
package/cli/merge-local.js
CHANGED
|
@@ -1,116 +1,127 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import 'dotenv/config';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { Transform } from 'stream';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { createReadStream } from 'fs';
|
|
5
|
+
import { createGunzip } from 'zlib';
|
|
7
6
|
import { pipeline } from 'stream/promises';
|
|
8
|
-
import {
|
|
7
|
+
import { chain } from 'stream-chain';
|
|
9
8
|
import split2 from 'split2';
|
|
9
|
+
import { stream, trimObj } from '@miso.ai/server-commons';
|
|
10
|
+
|
|
11
|
+
const PWD = process.env.PWD;
|
|
10
12
|
|
|
11
13
|
process.stdout.on('error', err => err.code == 'EPIPE' && process.exit(0));
|
|
12
14
|
|
|
13
15
|
function build(yargs) {
|
|
14
16
|
return yargs
|
|
15
|
-
.positional('
|
|
16
|
-
describe: '
|
|
17
|
+
.positional('file1', {
|
|
18
|
+
describe: 'First record file',
|
|
17
19
|
type: 'string',
|
|
18
20
|
demandOption: true,
|
|
21
|
+
})
|
|
22
|
+
.positional('file2', {
|
|
23
|
+
describe: 'Second record file',
|
|
24
|
+
type: 'string',
|
|
25
|
+
})
|
|
26
|
+
.option('join-mode', {
|
|
27
|
+
alias: 'm',
|
|
28
|
+
describe: 'Join mode',
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: 'merge',
|
|
31
|
+
choices: ['merge', 'rewrite-meta', 'remeta'],
|
|
32
|
+
})
|
|
33
|
+
.option('join-function', {
|
|
34
|
+
alias: 'f',
|
|
35
|
+
describe: 'Join function',
|
|
36
|
+
type: 'string',
|
|
37
|
+
})
|
|
38
|
+
.option('stdin', {
|
|
39
|
+
alias: 'i',
|
|
40
|
+
describe: 'Read the first stream from stdin',
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
default: false,
|
|
19
43
|
});
|
|
20
44
|
}
|
|
21
45
|
|
|
22
|
-
async function run({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
46
|
+
async function run({ file1, file2, stdin, joinMode, joinFunction }) {
|
|
47
|
+
if (stdin) {
|
|
48
|
+
file2 = file1;
|
|
49
|
+
file1 = undefined;
|
|
50
|
+
} else if (!file2) {
|
|
51
|
+
throw new Error('Second file is required');
|
|
52
|
+
}
|
|
53
|
+
const stream1 = chain([
|
|
54
|
+
stdin ? process.stdin : createReadStream(file1),
|
|
55
|
+
...(file1 && file1.endsWith('.gz')) ? [createGunzip()] : [],
|
|
56
|
+
split2(JSON.parse),
|
|
57
|
+
]);
|
|
58
|
+
const stream2 = chain([
|
|
59
|
+
createReadStream(file2),
|
|
60
|
+
...(file2 && file2.endsWith('.gz')) ? [createGunzip()] : [],
|
|
26
61
|
split2(JSON.parse),
|
|
27
|
-
|
|
62
|
+
]);
|
|
63
|
+
await pipeline(
|
|
64
|
+
stream.joinStreams([stream1, stream2], await getJoinFunction(joinMode, joinFunction)),
|
|
28
65
|
new stream.OutputStream(),
|
|
29
66
|
);
|
|
30
67
|
}
|
|
31
68
|
|
|
32
|
-
async function
|
|
33
|
-
|
|
34
|
-
const content = await readContent(file);
|
|
35
|
-
for (let line of content.split('\n')) {
|
|
36
|
-
line = line.trim();
|
|
37
|
-
if (!line) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
69
|
+
async function getJoinFunction(joinMode, joinFunction) {
|
|
70
|
+
if (joinFunction) {
|
|
40
71
|
try {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.error(`Missing product_id: ${line}`);
|
|
45
|
-
continue;
|
|
72
|
+
const fn = await import(join(PWD, joinFunction));
|
|
73
|
+
if (!fn.default) {
|
|
74
|
+
throw new Error('Join function must have a default export');
|
|
46
75
|
}
|
|
47
|
-
|
|
48
|
-
} catch (
|
|
49
|
-
console.error(`
|
|
76
|
+
return fn.default;
|
|
77
|
+
} catch (e) {
|
|
78
|
+
console.error(`Failed to load join function ${joinFunction}:`, e);
|
|
79
|
+
process.exit(1);
|
|
50
80
|
}
|
|
51
81
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
82
|
+
switch (joinMode) {
|
|
83
|
+
case 'merge':
|
|
84
|
+
return merge;
|
|
85
|
+
case 'rewrite-meta':
|
|
86
|
+
case 'remeta':
|
|
87
|
+
return rewriteMeta;
|
|
88
|
+
default:
|
|
89
|
+
throw new Error(`Unsupported join mode: ${joinMode}`);
|
|
59
90
|
}
|
|
60
|
-
return fileBuffer.toString('utf-8');
|
|
61
91
|
}
|
|
62
92
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
...
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.on('drain', () => this._handleDrain());
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
_transform(record, _, next) {
|
|
78
|
-
const patch = this._patches.get(record.product_id);
|
|
79
|
-
if (patch) {
|
|
80
|
-
record = this._patch(record, patch);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const pause = !this.push(record);
|
|
84
|
-
if (pause) {
|
|
85
|
-
this._next = next;
|
|
86
|
-
} else {
|
|
87
|
-
next();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
93
|
+
function merge(record1, record2) {
|
|
94
|
+
assertSameProductId(record1, record2);
|
|
95
|
+
return trimObj({
|
|
96
|
+
...record1,
|
|
97
|
+
...record2,
|
|
98
|
+
custom_attributes: trimObj({
|
|
99
|
+
...(record1 && record1.custom_attributes),
|
|
100
|
+
...(record2 && record2.custom_attributes),
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
90
104
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
function rewriteMeta(record1, record2) {
|
|
106
|
+
assertSameProductId(record1, record2);
|
|
107
|
+
const { description, html, children } = record1;
|
|
108
|
+
const { description: _0, html: _1, children: _2, ...rest } = record2;
|
|
109
|
+
return trimObj({
|
|
110
|
+
...rest,
|
|
111
|
+
description,
|
|
112
|
+
html,
|
|
113
|
+
children,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
102
116
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
117
|
+
function assertSameProductId(record1, record2) {
|
|
118
|
+
if (record1.product_id !== record2.product_id) {
|
|
119
|
+
throw new Error(`Product IDs do not match: ${record1.product_id} and ${record2.product_id}`);
|
|
107
120
|
}
|
|
108
|
-
|
|
109
121
|
}
|
|
110
122
|
|
|
111
|
-
|
|
112
123
|
export default {
|
|
113
|
-
command: 'merge-local <
|
|
124
|
+
command: 'merge-local <file1> [file2]',
|
|
114
125
|
alias: ['patch-local'],
|
|
115
126
|
description: 'Apply patch records from file onto input record stream',
|
|
116
127
|
builder: build,
|
package/package.json
CHANGED
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"simonpai <simon.pai@askmiso.com>"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@miso.ai/server-commons": "0.6.6-beta.
|
|
19
|
+
"@miso.ai/server-commons": "0.6.6-beta.5",
|
|
20
20
|
"axios": "^1.6.2",
|
|
21
21
|
"axios-retry": "^4.5.0",
|
|
22
22
|
"dotenv": "^16.0.1",
|
|
23
23
|
"split2": "^4.1.0",
|
|
24
24
|
"yargs": "^17.5.1"
|
|
25
25
|
},
|
|
26
|
-
"version": "0.6.6-beta.
|
|
26
|
+
"version": "0.6.6-beta.5"
|
|
27
27
|
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '0.6.6-beta.
|
|
1
|
+
export default '0.6.6-beta.5';
|