meadow-integration 1.0.1 → 1.0.4
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/CONTRIBUTING.md +50 -0
- package/README.md +223 -7
- package/docs/README.md +107 -7
- package/docs/_sidebar.md +38 -0
- package/docs/_topbar.md +7 -0
- package/docs/cli-reference.md +242 -0
- package/docs/comprehensions.md +98 -0
- package/docs/cover.md +11 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/examples-walkthrough.md +138 -0
- package/docs/index.html +37 -20
- package/docs/integration-adapter.md +109 -0
- package/docs/mapping-files.md +140 -0
- package/docs/programmatic-api.md +173 -0
- package/docs/rest-api-reference.md +731 -0
- package/docs/retold-catalog.json +153 -0
- package/docs/retold-keyword-index.json +4828 -0
- package/examples/Example-001-CSV-Check.sh +29 -0
- package/examples/Example-002-CSV-Transform-Implicit.sh +31 -0
- package/examples/Example-003-CSV-Transform-CLI-Options.sh +39 -0
- package/examples/Example-004-CSV-Transform-Mapping-File.sh +41 -0
- package/examples/Example-005-Multi-Entity-Bookstore.sh +60 -0
- package/examples/Example-006-Multi-CSV-Intersect.sh +74 -0
- package/examples/Example-007-Comprehension-To-Array.sh +41 -0
- package/examples/Example-008-Comprehension-To-CSV.sh +51 -0
- package/examples/Example-009-JSON-Array-Transform.sh +46 -0
- package/examples/Example-010-Programmatic-API.js +138 -0
- package/examples/README.md +44 -0
- package/examples/output/.gitignore +2 -0
- package/package.json +7 -4
- package/source/Meadow-Integration.js +3 -1
- package/source/cli/Meadow-Integration-CLI-Program.js +4 -1
- package/source/cli/commands/Meadow-Integration-Command-ObjectArrayToCSV.js +49 -32
- package/source/cli/commands/Meadow-Integration-Command-Serve.js +51 -0
- package/source/restserver/Meadow-Integration-Server-Endpoints.js +83 -0
- package/source/restserver/Meadow-Integration-Server.js +86 -0
- package/source/restserver/endpoints/Endpoint-CSVCheck.js +91 -0
- package/source/restserver/endpoints/Endpoint-CSVTransform.js +189 -0
- package/source/restserver/endpoints/Endpoint-ComprehensionArray.js +121 -0
- package/source/restserver/endpoints/Endpoint-ComprehensionIntersect.js +166 -0
- package/source/restserver/endpoints/Endpoint-ComprehensionPush.js +209 -0
- package/source/restserver/endpoints/Endpoint-EntityFromTabularFolder.js +252 -0
- package/source/restserver/endpoints/Endpoint-JSONArrayTransform.js +238 -0
- package/source/restserver/endpoints/Endpoint-ObjectArrayToCSV.js +231 -0
- package/source/restserver/endpoints/Endpoint-TSVCheck.js +93 -0
- package/source/restserver/endpoints/Endpoint-TSVTransform.js +191 -0
- package/test/Meadow-Integration-Server_test.js +1170 -0
- package/test/data/test-comprehension-secondary.json +8 -0
- package/test/data/test-comprehension.json +8 -0
- package/test/data/test-small.csv +6 -0
- package/test/data/test-small.json +7 -0
- package/test/data/test-small.tsv +6 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 001: CSV Check
|
|
3
|
+
# ---------------------
|
|
4
|
+
# Analyze a CSV file to get statistics about its structure and contents.
|
|
5
|
+
# This is typically the first step when working with a new data set.
|
|
6
|
+
#
|
|
7
|
+
# Usage: ./Example-001-CSV-Check.sh
|
|
8
|
+
# Output: examples/output/books-stats.json
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
12
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
13
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
14
|
+
|
|
15
|
+
echo "=== Example 001: CSV Check ==="
|
|
16
|
+
echo ""
|
|
17
|
+
echo "Running csvcheck on books.csv to gather statistics..."
|
|
18
|
+
echo ""
|
|
19
|
+
|
|
20
|
+
node "${CLI}" csvcheck "${DATA_DIR}/books.csv" \
|
|
21
|
+
-o "${OUTPUT_DIR}/books-stats.json"
|
|
22
|
+
|
|
23
|
+
echo ""
|
|
24
|
+
echo "Statistics written to: examples/output/books-stats.json"
|
|
25
|
+
echo ""
|
|
26
|
+
echo "You can examine the output file to see:"
|
|
27
|
+
echo " - Row and column counts"
|
|
28
|
+
echo " - Column headers"
|
|
29
|
+
echo " - Per-column statistics (empty counts, numeric counts, first/last values)"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 002: CSV Transform (Implicit Configuration)
|
|
3
|
+
# ----------------------------------------------------
|
|
4
|
+
# Transform a CSV file into a comprehension using auto-detected settings.
|
|
5
|
+
# When no mapping file or explicit options are provided, meadow-integration
|
|
6
|
+
# will infer the entity name from the filename and create a 1:1 column mapping.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./Example-002-CSV-Transform-Implicit.sh
|
|
9
|
+
# Output: examples/output/books-implicit-comprehension.json
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
13
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
14
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
15
|
+
|
|
16
|
+
echo "=== Example 002: CSV Transform (Implicit Configuration) ==="
|
|
17
|
+
echo ""
|
|
18
|
+
echo "Transforming books.csv into a comprehension with auto-detected settings..."
|
|
19
|
+
echo "(Entity name and GUID will be derived from the file name and first column)"
|
|
20
|
+
echo ""
|
|
21
|
+
|
|
22
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
23
|
+
-o "${OUTPUT_DIR}/books-implicit-comprehension.json"
|
|
24
|
+
|
|
25
|
+
echo ""
|
|
26
|
+
echo "Comprehension written to: examples/output/books-implicit-comprehension.json"
|
|
27
|
+
echo ""
|
|
28
|
+
echo "The implicit configuration:"
|
|
29
|
+
echo " - Entity name derived from the CSV filename"
|
|
30
|
+
echo " - GUID generated from the first column value"
|
|
31
|
+
echo " - All columns mapped 1:1 to comprehension fields"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 003: CSV Transform (CLI Options)
|
|
3
|
+
# -----------------------------------------
|
|
4
|
+
# Transform a CSV file into a comprehension using command-line options to
|
|
5
|
+
# control the entity name, GUID template, and column mappings.
|
|
6
|
+
#
|
|
7
|
+
# This gives you explicit control over:
|
|
8
|
+
# -e Entity name (what this data represents)
|
|
9
|
+
# -n GUID column name in the output
|
|
10
|
+
# -g GUID template (Pict template using column values)
|
|
11
|
+
#
|
|
12
|
+
# Usage: ./Example-003-CSV-Transform-CLI-Options.sh
|
|
13
|
+
# Output: examples/output/books-cli-comprehension.json
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
17
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
18
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
19
|
+
|
|
20
|
+
echo "=== Example 003: CSV Transform (CLI Options) ==="
|
|
21
|
+
echo ""
|
|
22
|
+
echo "Transforming books.csv with explicit CLI options..."
|
|
23
|
+
echo " Entity: Book"
|
|
24
|
+
echo " GUID Column: GUIDBook"
|
|
25
|
+
echo " GUID Template: Book_{~D:Record.id~}"
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
29
|
+
-e "Book" \
|
|
30
|
+
-n "GUIDBook" \
|
|
31
|
+
-g "Book_{~D:Record.id~}" \
|
|
32
|
+
-o "${OUTPUT_DIR}/books-cli-comprehension.json"
|
|
33
|
+
|
|
34
|
+
echo ""
|
|
35
|
+
echo "Comprehension written to: examples/output/books-cli-comprehension.json"
|
|
36
|
+
echo ""
|
|
37
|
+
echo "Each record in the comprehension now has:"
|
|
38
|
+
echo " - A GUIDBook field with values like 'Book_1', 'Book_2', etc."
|
|
39
|
+
echo " - All original CSV columns as additional fields"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 004: CSV Transform (Mapping File)
|
|
3
|
+
# ------------------------------------------
|
|
4
|
+
# Transform a CSV file using a mapping file for precise control over
|
|
5
|
+
# which columns are extracted and how they are named.
|
|
6
|
+
#
|
|
7
|
+
# The mapping file (mapping_books_Book.json) defines:
|
|
8
|
+
# Entity - The entity name
|
|
9
|
+
# GUIDTemplate - How to generate unique IDs
|
|
10
|
+
# Mappings - Column name -> Pict template pairs
|
|
11
|
+
#
|
|
12
|
+
# This is the recommended approach for production data integration.
|
|
13
|
+
#
|
|
14
|
+
# Usage: ./Example-004-CSV-Transform-Mapping-File.sh
|
|
15
|
+
# Output: examples/output/books-mapped-comprehension.json
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
19
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
20
|
+
MAPPING_DIR="${SCRIPT_DIR}/../docs/examples/bookstore"
|
|
21
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
22
|
+
|
|
23
|
+
echo "=== Example 004: CSV Transform (Mapping File) ==="
|
|
24
|
+
echo ""
|
|
25
|
+
echo "Transforming books.csv using mapping_books_Book.json..."
|
|
26
|
+
echo ""
|
|
27
|
+
echo "Mapping file contents:"
|
|
28
|
+
cat "${MAPPING_DIR}/mapping_books_Book.json"
|
|
29
|
+
echo ""
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
33
|
+
-m "${MAPPING_DIR}/mapping_books_Book.json" \
|
|
34
|
+
-o "${OUTPUT_DIR}/books-mapped-comprehension.json"
|
|
35
|
+
|
|
36
|
+
echo ""
|
|
37
|
+
echo "Comprehension written to: examples/output/books-mapped-comprehension.json"
|
|
38
|
+
echo ""
|
|
39
|
+
echo "Notice the output only contains the mapped fields:"
|
|
40
|
+
echo " Title, Language, PublicationYear, ISBN, Genre, Type, ImageURL"
|
|
41
|
+
echo " (not all 23 original CSV columns)"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 005: Multi-Entity Bookstore Integration
|
|
3
|
+
# -------------------------------------------------
|
|
4
|
+
# Build a complete multi-entity comprehension from a single CSV file.
|
|
5
|
+
# This demonstrates how one CSV can produce multiple entity types
|
|
6
|
+
# using different mapping files.
|
|
7
|
+
#
|
|
8
|
+
# The books.csv file contains book data with authors in a single column.
|
|
9
|
+
# We use three mapping files to extract:
|
|
10
|
+
# 1. Book - Basic book information
|
|
11
|
+
# 2. Author - Unique author names (using Solvers to split comma-separated authors)
|
|
12
|
+
# 3. BookAuthorJoin - Many-to-many relationship between books and authors
|
|
13
|
+
#
|
|
14
|
+
# Each transform pass adds its entity to the same comprehension file
|
|
15
|
+
# by using the -i flag to pass in the existing comprehension.
|
|
16
|
+
#
|
|
17
|
+
# Usage: ./Example-005-Multi-Entity-Bookstore.sh
|
|
18
|
+
# Output: examples/output/bookstore-comprehension.json
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
22
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
23
|
+
MAPPING_DIR="${SCRIPT_DIR}/../docs/examples/bookstore"
|
|
24
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
25
|
+
COMP_FILE="${OUTPUT_DIR}/bookstore-comprehension.json"
|
|
26
|
+
|
|
27
|
+
echo "=== Example 005: Multi-Entity Bookstore ==="
|
|
28
|
+
echo ""
|
|
29
|
+
|
|
30
|
+
# Step 1: Create the Book entity comprehension
|
|
31
|
+
echo "--- Step 1: Creating Book entities ---"
|
|
32
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
33
|
+
-m "${MAPPING_DIR}/mapping_books_Book.json" \
|
|
34
|
+
-o "${COMP_FILE}"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
# Step 2: Add the Author entities to the same comprehension
|
|
38
|
+
echo "--- Step 2: Adding Author entities ---"
|
|
39
|
+
echo "(Uses Solvers to split comma-separated author names into individual records)"
|
|
40
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
41
|
+
-m "${MAPPING_DIR}/mapping_books_Author.json" \
|
|
42
|
+
-i "${COMP_FILE}" \
|
|
43
|
+
-o "${COMP_FILE}"
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# Step 3: Add the BookAuthorJoin entities to complete the comprehension
|
|
47
|
+
echo "--- Step 3: Adding BookAuthorJoin entities ---"
|
|
48
|
+
echo "(Creates a join record for every book-author pair)"
|
|
49
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
50
|
+
-m "${MAPPING_DIR}/mapping_books_BookAuthorJoin.json" \
|
|
51
|
+
-i "${COMP_FILE}" \
|
|
52
|
+
-o "${COMP_FILE}"
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
echo "Complete bookstore comprehension written to: examples/output/bookstore-comprehension.json"
|
|
56
|
+
echo ""
|
|
57
|
+
echo "The comprehension contains three entity types:"
|
|
58
|
+
echo " - Book: One record per book"
|
|
59
|
+
echo " - Author: One record per unique author"
|
|
60
|
+
echo " - BookAuthorJoin: One record per book-author relationship"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 006: Multi-CSV Intersect (Seattle Neighborhoods)
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
# Merge data from multiple CSV files that share a common key.
|
|
5
|
+
# This is a common scenario when data about the same entities
|
|
6
|
+
# comes from different sources or different tables.
|
|
7
|
+
#
|
|
8
|
+
# The Seattle neighborhood data has three CSV files:
|
|
9
|
+
# - housing_characteristics_Neighborhoods.csv
|
|
10
|
+
# - housing_costs_Neighborhoods.csv
|
|
11
|
+
# - race_ethnicity_Neighborhoods.csv
|
|
12
|
+
#
|
|
13
|
+
# All three share a "Neighborhood Name" column. We transform
|
|
14
|
+
# each into a comprehension keyed on that column, then use
|
|
15
|
+
# comprehensionintersect to merge them into one unified dataset.
|
|
16
|
+
#
|
|
17
|
+
# Usage: ./Example-006-Multi-CSV-Intersect.sh
|
|
18
|
+
# Output: examples/output/seattle-merged.json
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
22
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data/seattle_neighborhoods"
|
|
23
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
24
|
+
|
|
25
|
+
echo "=== Example 006: Multi-CSV Intersect (Seattle Neighborhoods) ==="
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# Step 1: Transform housing characteristics
|
|
29
|
+
echo "--- Step 1: Transform housing characteristics CSV ---"
|
|
30
|
+
node "${CLI}" csvtransform "${DATA_DIR}/housing_characteristics_Neighborhoods.csv" \
|
|
31
|
+
-e "Neighborhood" \
|
|
32
|
+
-n "GUIDNeighborhood" \
|
|
33
|
+
-g "{~D:Record.Neighborhood Name~}" \
|
|
34
|
+
-o "${OUTPUT_DIR}/seattle-housing-chars.json"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
# Step 2: Transform housing costs
|
|
38
|
+
echo "--- Step 2: Transform housing costs CSV ---"
|
|
39
|
+
node "${CLI}" csvtransform "${DATA_DIR}/housing_costs_Neighborhoods.csv" \
|
|
40
|
+
-e "Neighborhood" \
|
|
41
|
+
-n "GUIDNeighborhood" \
|
|
42
|
+
-g "{~D:Record.Neighborhood Name~}" \
|
|
43
|
+
-o "${OUTPUT_DIR}/seattle-housing-costs.json"
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# Step 3: Transform race and ethnicity
|
|
47
|
+
echo "--- Step 3: Transform race and ethnicity CSV ---"
|
|
48
|
+
node "${CLI}" csvtransform "${DATA_DIR}/race_ethnicity_Neighborhoods.csv" \
|
|
49
|
+
-e "Neighborhood" \
|
|
50
|
+
-n "GUIDNeighborhood" \
|
|
51
|
+
-g "{~D:Record.Neighborhood Name~}" \
|
|
52
|
+
-o "${OUTPUT_DIR}/seattle-race-ethnicity.json"
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
# Step 4: Merge housing chars + housing costs
|
|
56
|
+
echo "--- Step 4: Intersect housing characteristics with housing costs ---"
|
|
57
|
+
node "${CLI}" comprehensionintersect "${OUTPUT_DIR}/seattle-housing-chars.json" \
|
|
58
|
+
-i "${OUTPUT_DIR}/seattle-housing-costs.json" \
|
|
59
|
+
-e "Neighborhood" \
|
|
60
|
+
-o "${OUTPUT_DIR}/seattle-merged.json"
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
# Step 5: Merge the result with race/ethnicity data
|
|
64
|
+
echo "--- Step 5: Intersect merged data with race/ethnicity ---"
|
|
65
|
+
node "${CLI}" comprehensionintersect "${OUTPUT_DIR}/seattle-merged.json" \
|
|
66
|
+
-i "${OUTPUT_DIR}/seattle-race-ethnicity.json" \
|
|
67
|
+
-e "Neighborhood" \
|
|
68
|
+
-o "${OUTPUT_DIR}/seattle-merged.json"
|
|
69
|
+
echo ""
|
|
70
|
+
|
|
71
|
+
echo "Merged comprehension written to: examples/output/seattle-merged.json"
|
|
72
|
+
echo ""
|
|
73
|
+
echo "Each neighborhood record now contains columns from all three source CSVs,"
|
|
74
|
+
echo "merged by matching Neighborhood Name."
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 007: Comprehension to Array
|
|
3
|
+
# -------------------------------------
|
|
4
|
+
# Convert an object-keyed comprehension into a JSON array.
|
|
5
|
+
# Comprehensions store records as { GUID: record } objects for
|
|
6
|
+
# fast lookup and merging. But sometimes you need a plain array,
|
|
7
|
+
# for instance to feed into a UI table or export to CSV.
|
|
8
|
+
#
|
|
9
|
+
# This example first creates a Book comprehension, then converts
|
|
10
|
+
# it from the object format to an array format.
|
|
11
|
+
#
|
|
12
|
+
# Usage: ./Example-007-Comprehension-To-Array.sh
|
|
13
|
+
# Output: examples/output/books-array.json
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
17
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
18
|
+
MAPPING_DIR="${SCRIPT_DIR}/../docs/examples/bookstore"
|
|
19
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
20
|
+
|
|
21
|
+
echo "=== Example 007: Comprehension to Array ==="
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
# Step 1: Create a Book comprehension
|
|
25
|
+
echo "--- Step 1: Create a Book comprehension ---"
|
|
26
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
27
|
+
-m "${MAPPING_DIR}/mapping_books_Book.json" \
|
|
28
|
+
-o "${OUTPUT_DIR}/books-for-array.json"
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
# Step 2: Convert from object comprehension to array
|
|
32
|
+
echo "--- Step 2: Convert to array format ---"
|
|
33
|
+
node "${CLI}" comprehensionarray "${OUTPUT_DIR}/books-for-array.json" \
|
|
34
|
+
-e "Book" \
|
|
35
|
+
-o "${OUTPUT_DIR}/books-array.json"
|
|
36
|
+
echo ""
|
|
37
|
+
|
|
38
|
+
echo "Array comprehension written to: examples/output/books-array.json"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "Object format: { 'Book': { 'Book_1': {...}, 'Book_2': {...} } }"
|
|
41
|
+
echo "Array format: [ {...}, {...}, ... ]"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 008: Comprehension to CSV
|
|
3
|
+
# ------------------------------------
|
|
4
|
+
# Export a comprehension back to CSV format. This is useful for:
|
|
5
|
+
# - Sharing data with tools that expect CSV input
|
|
6
|
+
# - Reviewing merged/transformed data in a spreadsheet
|
|
7
|
+
# - Round-tripping data through the integration pipeline
|
|
8
|
+
#
|
|
9
|
+
# Workflow:
|
|
10
|
+
# 1. CSV -> Comprehension (csvtransform with mapping file)
|
|
11
|
+
# 2. Object Comprehension -> Array (comprehensionarray)
|
|
12
|
+
# 3. Array -> CSV (objectarraytocsv)
|
|
13
|
+
#
|
|
14
|
+
# Usage: ./Example-008-Comprehension-To-CSV.sh
|
|
15
|
+
# Output: examples/output/books-export.csv
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
19
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
20
|
+
MAPPING_DIR="${SCRIPT_DIR}/../docs/examples/bookstore"
|
|
21
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
22
|
+
|
|
23
|
+
echo "=== Example 008: Comprehension to CSV ==="
|
|
24
|
+
echo ""
|
|
25
|
+
|
|
26
|
+
# Step 1: Create a Book comprehension (object format)
|
|
27
|
+
echo "--- Step 1: Create a Book comprehension ---"
|
|
28
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
29
|
+
-m "${MAPPING_DIR}/mapping_books_Book.json" \
|
|
30
|
+
-o "${OUTPUT_DIR}/books-for-csv.json"
|
|
31
|
+
echo ""
|
|
32
|
+
|
|
33
|
+
# Step 2: Convert to array format (objectarraytocsv needs an array)
|
|
34
|
+
echo "--- Step 2: Convert object comprehension to array ---"
|
|
35
|
+
node "${CLI}" comprehensionarray "${OUTPUT_DIR}/books-for-csv.json" \
|
|
36
|
+
-e "Book" \
|
|
37
|
+
-o "${OUTPUT_DIR}/books-array-for-csv.json"
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
# Step 3: Export array to CSV
|
|
41
|
+
# objectarraytocsv reads a plain JSON array and writes CSV
|
|
42
|
+
echo "--- Step 3: Export array to CSV ---"
|
|
43
|
+
node "${CLI}" objectarraytocsv "${OUTPUT_DIR}/books-array-for-csv.json" \
|
|
44
|
+
-o "${OUTPUT_DIR}/books-export.csv"
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
LINECOUNT=$(wc -l < "${OUTPUT_DIR}/books-export.csv")
|
|
48
|
+
echo "CSV exported to: examples/output/books-export.csv (${LINECOUNT} lines)"
|
|
49
|
+
echo ""
|
|
50
|
+
echo "First 3 lines of output:"
|
|
51
|
+
head -3 "${OUTPUT_DIR}/books-export.csv"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Example 009: JSON Array Transform
|
|
3
|
+
# -----------------------------------
|
|
4
|
+
# Transform a JSON array file into a comprehension.
|
|
5
|
+
# This works just like csvtransform but reads from a JSON array
|
|
6
|
+
# instead of a CSV file.
|
|
7
|
+
#
|
|
8
|
+
# This example first creates a JSON array from book data,
|
|
9
|
+
# then re-transforms it using the jsonarraytransform command.
|
|
10
|
+
#
|
|
11
|
+
# Usage: ./Example-009-JSON-Array-Transform.sh
|
|
12
|
+
# Output: examples/output/books-from-json.json
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
CLI="${SCRIPT_DIR}/../source/cli/Meadow-Integration-CLI-Run.js"
|
|
16
|
+
DATA_DIR="${SCRIPT_DIR}/../docs/examples/data"
|
|
17
|
+
MAPPING_DIR="${SCRIPT_DIR}/../docs/examples/bookstore"
|
|
18
|
+
OUTPUT_DIR="${SCRIPT_DIR}/output"
|
|
19
|
+
|
|
20
|
+
echo "=== Example 009: JSON Array Transform ==="
|
|
21
|
+
echo ""
|
|
22
|
+
|
|
23
|
+
# Step 1: First create a JSON array from the books CSV
|
|
24
|
+
echo "--- Step 1: Create a source JSON array ---"
|
|
25
|
+
node "${CLI}" csvtransform "${DATA_DIR}/books.csv" \
|
|
26
|
+
-e "Book" -n "GUIDBook" -g "Book_{~D:Record.id~}" \
|
|
27
|
+
-o "${OUTPUT_DIR}/books-object-source.json"
|
|
28
|
+
|
|
29
|
+
node "${CLI}" comprehensionarray "${OUTPUT_DIR}/books-object-source.json" \
|
|
30
|
+
-e "Book" \
|
|
31
|
+
-o "${OUTPUT_DIR}/books-json-array-source.json"
|
|
32
|
+
echo ""
|
|
33
|
+
|
|
34
|
+
# Step 2: Transform the JSON array into a new comprehension with mapping
|
|
35
|
+
echo "--- Step 2: Transform JSON array with mapping file ---"
|
|
36
|
+
node "${CLI}" jsonarraytransform "${OUTPUT_DIR}/books-json-array-source.json" \
|
|
37
|
+
-m "${MAPPING_DIR}/mapping_books_Book.json" \
|
|
38
|
+
-o "${OUTPUT_DIR}/books-from-json.json"
|
|
39
|
+
echo ""
|
|
40
|
+
|
|
41
|
+
echo "Comprehension from JSON array written to: examples/output/books-from-json.json"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "jsonarraytransform supports the same options as csvtransform:"
|
|
44
|
+
echo " -e, -n, -g, -c for CLI options"
|
|
45
|
+
echo " -m for mapping files"
|
|
46
|
+
echo " -i for incoming comprehension merging"
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example 010: Programmatic API
|
|
4
|
+
* ------------------------------
|
|
5
|
+
* Use meadow-integration services directly in your own Node.js code.
|
|
6
|
+
* This demonstrates using the TabularCheck and TabularTransform services
|
|
7
|
+
* without the CLI, which is useful when integrating into larger applications.
|
|
8
|
+
*
|
|
9
|
+
* Usage: node Example-010-Programmatic-API.js
|
|
10
|
+
*/
|
|
11
|
+
const libPict = require('pict');
|
|
12
|
+
const libFS = require('fs');
|
|
13
|
+
const libPath = require('path');
|
|
14
|
+
|
|
15
|
+
// Initialize pict (which extends fable with template parsing)
|
|
16
|
+
// The TabularTransform service uses parseTemplate, which requires pict.
|
|
17
|
+
let _Fable = new libPict({ LogLevel: 3 });
|
|
18
|
+
|
|
19
|
+
// Instantiate necessary services
|
|
20
|
+
_Fable.instantiateServiceProvider('CSVParser');
|
|
21
|
+
|
|
22
|
+
// Load and register the TabularCheck service
|
|
23
|
+
const libTabularCheck = require('../source/services/tabular/Service-TabularCheck.js');
|
|
24
|
+
_Fable.addAndInstantiateServiceType('MeadowIntegrationTabularCheck', libTabularCheck);
|
|
25
|
+
|
|
26
|
+
// Load and register the TabularTransform service
|
|
27
|
+
const libTabularTransform = require('../source/services/tabular/Service-TabularTransform.js');
|
|
28
|
+
_Fable.addAndInstantiateServiceType('MeadowIntegrationTabularTransform', libTabularTransform);
|
|
29
|
+
|
|
30
|
+
// ---- Part 1: Collecting Statistics ----
|
|
31
|
+
console.log('=== Part 1: TabularCheck - Collecting Statistics ===\n');
|
|
32
|
+
|
|
33
|
+
let tmpStatistics = _Fable.MeadowIntegrationTabularCheck.newStatisticsObject('ProgrammaticBooks');
|
|
34
|
+
|
|
35
|
+
// Read and parse a few lines from the CSV
|
|
36
|
+
let tmpCSVContent = libFS.readFileSync(
|
|
37
|
+
libPath.join(__dirname, '..', 'docs', 'examples', 'data', 'books.csv'),
|
|
38
|
+
'utf8'
|
|
39
|
+
);
|
|
40
|
+
let tmpLines = tmpCSVContent.split('\n');
|
|
41
|
+
|
|
42
|
+
// Parse each line and collect statistics (first 50 rows for quick demo)
|
|
43
|
+
let tmpRecordCount = 0;
|
|
44
|
+
for (let i = 0; i < Math.min(tmpLines.length, 50); i++)
|
|
45
|
+
{
|
|
46
|
+
let tmpRecord = _Fable.CSVParser.parseCSVLine(tmpLines[i]);
|
|
47
|
+
if (tmpRecord)
|
|
48
|
+
{
|
|
49
|
+
_Fable.MeadowIntegrationTabularCheck.collectStatistics(tmpRecord, tmpStatistics);
|
|
50
|
+
tmpRecordCount++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log(`Analyzed ${tmpStatistics.RowCount} rows with ${tmpStatistics.ColumnCount} columns`);
|
|
55
|
+
console.log(`Headers: ${tmpStatistics.Headers.join(', ')}`);
|
|
56
|
+
console.log('');
|
|
57
|
+
|
|
58
|
+
// Show a few column statistics
|
|
59
|
+
let tmpColumnKeys = Object.keys(tmpStatistics.ColumnStatistics);
|
|
60
|
+
for (let i = 0; i < Math.min(tmpColumnKeys.length, 5); i++)
|
|
61
|
+
{
|
|
62
|
+
let tmpKey = tmpColumnKeys[i];
|
|
63
|
+
let tmpStats = tmpStatistics.ColumnStatistics[tmpKey];
|
|
64
|
+
console.log(` [${tmpKey}]: ${tmpStats.Count} values, ${tmpStats.EmptyCount} empty, ${tmpStats.NumericCount} numeric`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---- Part 2: Transforming Records ----
|
|
68
|
+
console.log('\n=== Part 2: TabularTransform - Creating Comprehensions ===\n');
|
|
69
|
+
|
|
70
|
+
// Set up a mapping outcome
|
|
71
|
+
let tmpMappingOutcome = _Fable.MeadowIntegrationTabularTransform.newMappingOutcomeObject();
|
|
72
|
+
|
|
73
|
+
// Provide explicit configuration (same as a mapping file)
|
|
74
|
+
tmpMappingOutcome.ExplicitConfiguration = {
|
|
75
|
+
"Entity": "Book",
|
|
76
|
+
"GUIDTemplate": "Book_{~D:Record.id~}",
|
|
77
|
+
"Mappings": {
|
|
78
|
+
"Title": "{~D:Record.title~}",
|
|
79
|
+
"Language": "{~D:Record.language_code~}",
|
|
80
|
+
"ISBN": "{~D:Record.isbn~}",
|
|
81
|
+
"Genre": "Unknown",
|
|
82
|
+
"Type": "Book"
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Create an implicit config from the first record
|
|
87
|
+
let tmpFirstRecord = _Fable.CSVParser.parseCSVLine(tmpLines[1]);
|
|
88
|
+
tmpMappingOutcome.ImplicitConfiguration = _Fable.MeadowIntegrationTabularTransform.generateMappingConfigurationPrototype('books.csv', tmpFirstRecord);
|
|
89
|
+
|
|
90
|
+
// Merge configurations
|
|
91
|
+
tmpMappingOutcome.Configuration = Object.assign({},
|
|
92
|
+
tmpMappingOutcome.ImplicitConfiguration,
|
|
93
|
+
tmpMappingOutcome.ExplicitConfiguration
|
|
94
|
+
);
|
|
95
|
+
tmpMappingOutcome.Configuration.GUIDName = `GUID${tmpMappingOutcome.Configuration.Entity}`;
|
|
96
|
+
tmpMappingOutcome.Comprehension[tmpMappingOutcome.Configuration.Entity] = {};
|
|
97
|
+
|
|
98
|
+
// Transform records into the comprehension
|
|
99
|
+
for (let i = 1; i < Math.min(tmpLines.length, 11); i++)
|
|
100
|
+
{
|
|
101
|
+
let tmpRecord = _Fable.CSVParser.parseCSVLine(tmpLines[i]);
|
|
102
|
+
if (tmpRecord)
|
|
103
|
+
{
|
|
104
|
+
_Fable.MeadowIntegrationTabularTransform.addRecordToComprehension(
|
|
105
|
+
tmpRecord, tmpMappingOutcome);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Show results
|
|
110
|
+
let tmpBookKeys = Object.keys(tmpMappingOutcome.Comprehension.Book);
|
|
111
|
+
console.log(`Created ${tmpBookKeys.length} Book records in comprehension`);
|
|
112
|
+
console.log('');
|
|
113
|
+
|
|
114
|
+
// Print first 3 records
|
|
115
|
+
for (let i = 0; i < Math.min(tmpBookKeys.length, 3); i++)
|
|
116
|
+
{
|
|
117
|
+
let tmpBook = tmpMappingOutcome.Comprehension.Book[tmpBookKeys[i]];
|
|
118
|
+
console.log(` ${tmpBook.GUIDBook}: ${tmpBook.Title} (${tmpBook.Language})`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ---- Part 3: GUIDMap Service ----
|
|
122
|
+
console.log('\n=== Part 3: GUIDMap - Tracking External System IDs ===\n');
|
|
123
|
+
|
|
124
|
+
const libGUIDMap = require('../source/Meadow-Service-Integration-GUIDMap.js');
|
|
125
|
+
_Fable.addAndInstantiateServiceType('MeadowGUIDMap', libGUIDMap);
|
|
126
|
+
|
|
127
|
+
// Map external GUIDs to Meadow GUIDs and IDs
|
|
128
|
+
_Fable.MeadowGUIDMap.mapGUIDToID('Book', 'Book_1', 101);
|
|
129
|
+
_Fable.MeadowGUIDMap.mapGUIDToID('Book', 'Book_2', 102);
|
|
130
|
+
_Fable.MeadowGUIDMap.mapExternalGUIDtoMeadowGUID('Book', 'LEGACY-ISBN-439023483', 'Book_1');
|
|
131
|
+
|
|
132
|
+
// Look up in both directions
|
|
133
|
+
console.log(` GUID 'Book_1' -> ID: ${_Fable.MeadowGUIDMap.getIDFromGUID('Book', 'Book_1')}`);
|
|
134
|
+
console.log(` ID 101 -> GUID: ${_Fable.MeadowGUIDMap.getGUIDFromID('Book', 101)}`);
|
|
135
|
+
console.log(` External 'LEGACY-ISBN-439023483' -> Meadow GUID: ${_Fable.MeadowGUIDMap.getMeadowGUIDFromExternalGUID('Book', 'LEGACY-ISBN-439023483')}`);
|
|
136
|
+
console.log(` External 'LEGACY-ISBN-439023483' -> Meadow ID: ${_Fable.MeadowGUIDMap.getMeadowIDFromExternalGUID('Book', 'LEGACY-ISBN-439023483')}`);
|
|
137
|
+
|
|
138
|
+
console.log('\nDone!');
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Meadow Integration Examples
|
|
2
|
+
|
|
3
|
+
Runnable examples demonstrating meadow-integration features. Each example can be run from this directory and writes output to the `output/` folder.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
cd ..
|
|
9
|
+
npm install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Examples
|
|
13
|
+
|
|
14
|
+
| # | File | Description |
|
|
15
|
+
|---|------|-------------|
|
|
16
|
+
| 001 | `Example-001-CSV-Check.sh` | Analyze a CSV file structure and column statistics |
|
|
17
|
+
| 002 | `Example-002-CSV-Transform-Implicit.sh` | Auto-detect entity and columns from a CSV |
|
|
18
|
+
| 003 | `Example-003-CSV-Transform-CLI-Options.sh` | Use CLI flags to control entity name and GUID template |
|
|
19
|
+
| 004 | `Example-004-CSV-Transform-Mapping-File.sh` | Use a JSON mapping file for precise column control |
|
|
20
|
+
| 005 | `Example-005-Multi-Entity-Bookstore.sh` | Build Book, Author, and BookAuthorJoin from one CSV |
|
|
21
|
+
| 006 | `Example-006-Multi-CSV-Intersect.sh` | Merge three Seattle neighborhood CSVs by common key |
|
|
22
|
+
| 007 | `Example-007-Comprehension-To-Array.sh` | Convert object-keyed comprehension to a JSON array |
|
|
23
|
+
| 008 | `Example-008-Comprehension-To-CSV.sh` | Full round-trip: CSV to comprehension back to CSV |
|
|
24
|
+
| 009 | `Example-009-JSON-Array-Transform.sh` | Transform a JSON array file into a comprehension |
|
|
25
|
+
| 010 | `Example-010-Programmatic-API.js` | Use the services directly in Node.js code |
|
|
26
|
+
|
|
27
|
+
## Running
|
|
28
|
+
|
|
29
|
+
```shell
|
|
30
|
+
# Run a single example
|
|
31
|
+
./Example-001-CSV-Check.sh
|
|
32
|
+
|
|
33
|
+
# Run the Node.js programmatic example
|
|
34
|
+
node Example-010-Programmatic-API.js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Output files are written to `output/` and ignored by git.
|
|
38
|
+
|
|
39
|
+
## Data Sources
|
|
40
|
+
|
|
41
|
+
Examples use data from `../docs/examples/data/`:
|
|
42
|
+
|
|
43
|
+
- **books.csv** -- 10,000 book records from Goodreads (id, title, author, isbn, ratings, etc.)
|
|
44
|
+
- **seattle_neighborhoods/** -- Three Seattle ACS census datasets that share a Neighborhood Name column
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meadow-integration",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Meadow Data Integration",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mdwint": "source/cli/Meadow-Integration-CLI-Run.js"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"author": "steven velozo <steven@velozo.com>",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"quackage": "^1.0.
|
|
19
|
+
"quackage": "^1.0.51"
|
|
20
20
|
},
|
|
21
21
|
"mocha": {
|
|
22
22
|
"diff": true,
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
]
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"fable
|
|
41
|
-
"
|
|
40
|
+
"fable": "^3.1.55",
|
|
41
|
+
"fable-serviceproviderbase": "^3.0.18",
|
|
42
|
+
"orator": "^6.0.0",
|
|
43
|
+
"orator-serviceserver-restify": "^2.0.5",
|
|
44
|
+
"pict-service-commandlineutility": "^1.0.18"
|
|
42
45
|
}
|
|
43
46
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const libTabularCheck = require(`./services/tabular/Service-TabularCheck.js`);
|
|
2
|
+
const libIntegrationServer = require(`./restserver/Meadow-Integration-Server.js`);
|
|
2
3
|
|
|
3
4
|
module.exports = (
|
|
4
5
|
{
|
|
5
|
-
TabularCheck: libTabularCheck
|
|
6
|
+
TabularCheck: libTabularCheck,
|
|
7
|
+
IntegrationServer: libIntegrationServer
|
|
6
8
|
});
|
|
@@ -30,7 +30,10 @@ let _PictCLIProgram = new libCLIProgram(
|
|
|
30
30
|
require('./commands/Meadow-Integration-Command-ComprehensionIntersect.js'),
|
|
31
31
|
require('./commands/Meadow-Integration-Command-ComprehensionArray.js'),
|
|
32
32
|
|
|
33
|
-
require('./commands/Meadow-Integration-Command-ComprehensionPush.js')
|
|
33
|
+
require('./commands/Meadow-Integration-Command-ComprehensionPush.js'),
|
|
34
|
+
|
|
35
|
+
// REST server
|
|
36
|
+
require('./commands/Meadow-Integration-Command-Serve.js')
|
|
34
37
|
]);
|
|
35
38
|
|
|
36
39
|
_PictCLIProgram.instantiateServiceProvider('FilePersistence');
|