@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/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
- };