@forzalabs/remora 1.1.1 ā 1.1.2
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/index.js +8311 -106
- package/json_schemas/consumer-schema.json +1226 -0
- package/json_schemas/producer-schema.json +308 -0
- package/json_schemas/project-schema.json +100 -0
- package/json_schemas/source-schema.json +249 -0
- package/package.json +8 -25
- package/workers/ExecutorWorker.js +7644 -31
- package/actions/automap.js +0 -61
- package/actions/compile.js +0 -41
- package/actions/create_consumer.js +0 -59
- package/actions/create_producer.js +0 -25
- package/actions/debug.js +0 -46
- package/actions/deploy.js +0 -80
- package/actions/discover.js +0 -20
- package/actions/init.js +0 -61
- package/actions/mock.js +0 -27
- package/actions/run.js +0 -98
- package/actions/sample.js +0 -160
package/actions/sample.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import ora from 'ora';
|
|
3
|
-
import { Environment } from '@remora/app-common';
|
|
4
|
-
import { ProducerEngine } from '@remora/app-engines';
|
|
5
|
-
import { DatasetRecord } from '@remora/app-engines';
|
|
6
|
-
import { compile } from './compile';
|
|
7
|
-
import { Helper } from '@remora/app-helper';
|
|
8
|
-
export const sample = async (resourceName, sampleSize = 10) => {
|
|
9
|
-
try {
|
|
10
|
-
compile();
|
|
11
|
-
console.log(); // needed for newline
|
|
12
|
-
const spinner = ora(chalk.blue('Sampling dataset...')).start();
|
|
13
|
-
// Try to find the resource as a producer first, then as a consumer
|
|
14
|
-
const producer = Environment.getProducer(resourceName);
|
|
15
|
-
const consumer = Environment.getConsumer(resourceName);
|
|
16
|
-
if (!producer && !consumer) {
|
|
17
|
-
spinner.fail(chalk.red(`Resource "${resourceName}" not found. Please check if it exists as a producer or consumer.`));
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
20
|
-
let sampleData;
|
|
21
|
-
let resourceType;
|
|
22
|
-
if (producer) {
|
|
23
|
-
resourceType = 'Producer';
|
|
24
|
-
spinner.text = chalk.blue(`Sampling from producer "${resourceName}"...`);
|
|
25
|
-
sampleData = await ProducerEngine.readSampleData(producer, sampleSize, false);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
resourceType = 'Consumer';
|
|
29
|
-
spinner.text = chalk.blue(`Sampling from consumer "${resourceName}"...`);
|
|
30
|
-
sampleData = await sampleFromConsumer(consumer, sampleSize);
|
|
31
|
-
}
|
|
32
|
-
spinner.succeed(chalk.green(`Sample data retrieved from ${resourceType.toLowerCase()} "${resourceName}"`));
|
|
33
|
-
if (sampleData.length === 0) {
|
|
34
|
-
console.log(chalk.yellow('No data found in the dataset.'));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Display the sample data
|
|
38
|
-
console.log(chalk.cyan(`\nš Sample Data (showing ${sampleData.length} rows):`));
|
|
39
|
-
console.log(chalk.gray('ā'.repeat(80)));
|
|
40
|
-
displayDataAsTable(sampleData);
|
|
41
|
-
console.log(chalk.gray('ā'.repeat(80)));
|
|
42
|
-
console.log(chalk.green(`ā
Successfully sampled ${sampleData.length} rows from ${resourceType.toLowerCase()} "${resourceName}"`));
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
const myErr = Helper.asError(err);
|
|
46
|
-
console.error(chalk.red.bold('\nā Error during sampling:'), myErr.message);
|
|
47
|
-
if (Helper.isDev())
|
|
48
|
-
console.log(myErr.stack);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
const sampleFromConsumer = async (consumer, sampleSize) => {
|
|
53
|
-
// For consumers, we need to get sample data from the first producer
|
|
54
|
-
// and then apply the consumer's field mappings to show what the output would look like
|
|
55
|
-
const firstProducerRef = consumer.producers[0];
|
|
56
|
-
if (!firstProducerRef) {
|
|
57
|
-
throw new Error(`Consumer "${consumer.name}" has no producers configured`);
|
|
58
|
-
}
|
|
59
|
-
const producer = Environment.getProducer(firstProducerRef.name);
|
|
60
|
-
if (!producer) {
|
|
61
|
-
const subConsumer = Environment.getConsumer(firstProducerRef.name);
|
|
62
|
-
if (!subConsumer) {
|
|
63
|
-
throw new Error(`Producer or consumer "${firstProducerRef.name}" not found for consumer "${consumer.name}"`);
|
|
64
|
-
}
|
|
65
|
-
// If it's a consumer that references another consumer, sample from that consumer
|
|
66
|
-
return await sampleFromConsumer(subConsumer, sampleSize);
|
|
67
|
-
}
|
|
68
|
-
// Get raw sample data from the producer
|
|
69
|
-
const rawSampleData = await ProducerEngine.readSampleData(producer, sampleSize, false);
|
|
70
|
-
// For consumers with wildcard fields ("*"), return all data as-is
|
|
71
|
-
const hasWildcard = consumer.fields.some(field => field.key === '*');
|
|
72
|
-
if (hasWildcard) {
|
|
73
|
-
return rawSampleData;
|
|
74
|
-
}
|
|
75
|
-
// For consumers with specific field mappings, show only the mapped fields
|
|
76
|
-
// This gives users a preview of what the consumer output would look like
|
|
77
|
-
const mappedData = rawSampleData.map(record => {
|
|
78
|
-
const mappedRecord = new DatasetRecord('', [], record._delimiter);
|
|
79
|
-
consumer.fields.forEach(field => {
|
|
80
|
-
if (field.key !== '*') {
|
|
81
|
-
const sourceValue = record.getValue(field.key);
|
|
82
|
-
const outputKey = field.alias || field.key;
|
|
83
|
-
mappedRecord.setValue(outputKey, sourceValue);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
return mappedRecord;
|
|
87
|
-
});
|
|
88
|
-
return mappedData;
|
|
89
|
-
};
|
|
90
|
-
const displayDataAsTable = (data) => {
|
|
91
|
-
if (data.length === 0)
|
|
92
|
-
return;
|
|
93
|
-
// Get all unique field names from the sample data
|
|
94
|
-
const allFields = new Set();
|
|
95
|
-
data.forEach(record => {
|
|
96
|
-
Object.keys(record._value).forEach(key => allFields.add(key));
|
|
97
|
-
});
|
|
98
|
-
const fields = Array.from(allFields);
|
|
99
|
-
// Calculate column widths
|
|
100
|
-
const columnWidths = {};
|
|
101
|
-
// Start with header widths
|
|
102
|
-
fields.forEach(field => {
|
|
103
|
-
columnWidths[field] = field.length;
|
|
104
|
-
});
|
|
105
|
-
// Check data widths
|
|
106
|
-
data.forEach(record => {
|
|
107
|
-
fields.forEach(field => {
|
|
108
|
-
const value = record._value[field];
|
|
109
|
-
const displayValue = formatValue(value);
|
|
110
|
-
columnWidths[field] = Math.max(columnWidths[field], displayValue.length);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
// Limit column width to prevent overly wide tables
|
|
114
|
-
const maxColumnWidth = 30;
|
|
115
|
-
fields.forEach(field => {
|
|
116
|
-
columnWidths[field] = Math.min(columnWidths[field], maxColumnWidth);
|
|
117
|
-
});
|
|
118
|
-
// Print header
|
|
119
|
-
const headerRow = fields.map(field => chalk.bold(field.padEnd(columnWidths[field]))).join(' ā ');
|
|
120
|
-
console.log('ā ' + headerRow + ' ā');
|
|
121
|
-
// Print separator
|
|
122
|
-
const separator = fields.map(field => 'ā'.repeat(columnWidths[field])).join('āā¼ā');
|
|
123
|
-
console.log('āā' + separator + 'āā¤');
|
|
124
|
-
// Print data rows
|
|
125
|
-
data.forEach((record, index) => {
|
|
126
|
-
const dataRow = fields.map(field => {
|
|
127
|
-
const value = record._value[field];
|
|
128
|
-
const displayValue = formatValue(value);
|
|
129
|
-
const truncatedValue = displayValue.length > maxColumnWidth
|
|
130
|
-
? displayValue.substring(0, maxColumnWidth - 3) + '...'
|
|
131
|
-
: displayValue;
|
|
132
|
-
return truncatedValue.padEnd(columnWidths[field]);
|
|
133
|
-
}).join(' ā ');
|
|
134
|
-
// Alternate row colors for better readability
|
|
135
|
-
if (index % 2 === 0) {
|
|
136
|
-
console.log('ā ' + chalk.white(dataRow) + ' ā');
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
console.log('ā ' + chalk.gray(dataRow) + ' ā');
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
};
|
|
143
|
-
const formatValue = (value) => {
|
|
144
|
-
if (value === null || value === undefined) {
|
|
145
|
-
return chalk.dim('null');
|
|
146
|
-
}
|
|
147
|
-
if (typeof value === 'string') {
|
|
148
|
-
return value;
|
|
149
|
-
}
|
|
150
|
-
if (typeof value === 'number') {
|
|
151
|
-
return chalk.cyan(value.toString());
|
|
152
|
-
}
|
|
153
|
-
if (typeof value === 'boolean') {
|
|
154
|
-
return chalk.yellow(value.toString());
|
|
155
|
-
}
|
|
156
|
-
if (value instanceof Date) {
|
|
157
|
-
return chalk.magenta(value.toISOString());
|
|
158
|
-
}
|
|
159
|
-
return chalk.dim(JSON.stringify(value));
|
|
160
|
-
};
|