multiwoven-integrations 0.7.8 → 0.8.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.
- checksums.yaml +4 -4
- data/lib/multiwoven/integrations/core/base_connector.rb +2 -1
- data/lib/multiwoven/integrations/core/constants.rb +12 -0
- data/lib/multiwoven/integrations/core/destination_connector.rb +8 -0
- data/lib/multiwoven/integrations/core/http_client.rb +2 -1
- data/lib/multiwoven/integrations/destination/airtable/client.rb +0 -8
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/client.rb +0 -8
- data/lib/multiwoven/integrations/destination/klaviyo/client.rb +5 -5
- data/lib/multiwoven/integrations/destination/microsoft_excel/client.rb +194 -0
- data/lib/multiwoven/integrations/destination/microsoft_excel/config/catalog.json +7 -0
- data/lib/multiwoven/integrations/destination/microsoft_excel/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/microsoft_excel/config/spec.json +19 -0
- data/lib/multiwoven/integrations/destination/microsoft_excel/icon.svg +18 -0
- data/lib/multiwoven/integrations/rollout.rb +2 -1
- data/lib/multiwoven/integrations.rb +1 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d6c095f758588db92c0232cc771651405956eca4cb6c6ddcd76bf4076347e94
|
4
|
+
data.tar.gz: e42faebd684460ed4aeebdc09520c929a68b1757410598ccc0679e0cb1474849
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d29ac63ac873aa8467ffa10e280353dec803ede7cc670d91233bf70e8e2fdd56b55894c1ca8beca6783b130e75cc68721a4a0e41ea4af75a8bdcaa2b008159c
|
7
|
+
data.tar.gz: 9bf9ae850bb8e2b75466e20afb9fa8ca769368af72ec7f6ffe76e8bf7469d744497694ffcf9a2464ae275b2cb1a7fd484d0b08a4017280f03b577a2ec795bb2a
|
@@ -63,7 +63,8 @@ module Multiwoven
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def failure_status(error)
|
66
|
-
|
66
|
+
message = error&.message || "failed"
|
67
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"], message: message).to_multiwoven_message
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
@@ -36,6 +36,17 @@ module Multiwoven
|
|
36
36
|
AIRTABLE_BASES_ENDPOINT = "https://api.airtable.com/v0/meta/bases"
|
37
37
|
AIRTABLE_GET_BASE_SCHEMA_ENDPOINT = "https://api.airtable.com/v0/meta/bases/{baseId}/tables"
|
38
38
|
|
39
|
+
MS_EXCEL_AUTH_ENDPOINT = "https://graph.microsoft.com/v1.0/me"
|
40
|
+
MS_EXCEL_TABLE_ROW_WRITE_API = "https://graph.microsoft.com/v1.0/drives/%<drive_id>s/items/%<item_id>s/"\
|
41
|
+
"workbook/worksheets/%<sheet_name>s/tables/%<table_name>s/rows"
|
42
|
+
MS_EXCEL_TABLE_API = "https://graph.microsoft.com/v1.0/drives/%<drive_id>s/items/%<item_id>s/workbook/"\
|
43
|
+
"worksheets/sheet/tables?$select=name"
|
44
|
+
MS_EXCEL_FILES_API = "https://graph.microsoft.com/v1.0/drives/%<drive_id>s/root/children"
|
45
|
+
MS_EXCEL_WORKSHEETS_API = "https://graph.microsoft.com/v1.0/drives/%<drive_id>s/items/%<item_id>s/"\
|
46
|
+
"workbook/worksheets"
|
47
|
+
MS_EXCEL_SHEET_RANGE_API = "https://graph.microsoft.com/v1.0/drives/%<drive_id>s/items/%<item_id>s/"\
|
48
|
+
"workbook/worksheets/%<sheet_name>s/range(address='A1:Z1')/usedRange?$select=values"
|
49
|
+
|
39
50
|
AWS_ACCESS_KEY_ID = ENV["AWS_ACCESS_KEY_ID"]
|
40
51
|
AWS_SECRET_ACCESS_KEY = ENV["AWS_SECRET_ACCESS_KEY"]
|
41
52
|
|
@@ -44,6 +55,7 @@ module Multiwoven
|
|
44
55
|
HTTP_POST = "POST"
|
45
56
|
HTTP_PUT = "PUT"
|
46
57
|
HTTP_DELETE = "DELETE"
|
58
|
+
HTTP_PATCH = "PATCH"
|
47
59
|
|
48
60
|
# google sheets
|
49
61
|
GOOGLE_SHEETS_SCOPE = "https://www.googleapis.com/auth/drive"
|
@@ -15,6 +15,14 @@ module Multiwoven
|
|
15
15
|
success: success, failed: failure, logs: log_message_array
|
16
16
|
).to_multiwoven_message
|
17
17
|
end
|
18
|
+
|
19
|
+
def auth_headers(access_token)
|
20
|
+
{
|
21
|
+
"Accept" => "application/json",
|
22
|
+
"Authorization" => "Bearer #{access_token}",
|
23
|
+
"Content-Type" => "application/json"
|
24
|
+
}
|
25
|
+
end
|
18
26
|
end
|
19
27
|
end
|
20
28
|
end
|
@@ -19,13 +19,14 @@ module Multiwoven
|
|
19
19
|
when Constants::HTTP_GET then Net::HTTP::Get
|
20
20
|
when Constants::HTTP_POST then Net::HTTP::Post
|
21
21
|
when Constants::HTTP_PUT then Net::HTTP::Put
|
22
|
+
when Constants::HTTP_PATCH then Net::HTTP::Patch
|
22
23
|
when Constants::HTTP_DELETE then Net::HTTP::Delete
|
23
24
|
else raise ArgumentError, "Unsupported HTTP method: #{method}"
|
24
25
|
end
|
25
26
|
|
26
27
|
request = request_class.new(uri)
|
27
28
|
headers.each { |key, value| request[key] = value }
|
28
|
-
request.body = payload.to_json if payload && %w[POST PUT].include?(method.upcase)
|
29
|
+
request.body = payload.to_json if payload && %w[POST PUT PATCH].include?(method.upcase)
|
29
30
|
request
|
30
31
|
end
|
31
32
|
end
|
@@ -109,14 +109,6 @@ module Multiwoven
|
|
109
109
|
}
|
110
110
|
end
|
111
111
|
|
112
|
-
def auth_headers(access_token)
|
113
|
-
{
|
114
|
-
"Accept" => "application/json",
|
115
|
-
"Authorization" => "Bearer #{access_token}",
|
116
|
-
"Content-Type" => "application/json"
|
117
|
-
}
|
118
|
-
end
|
119
|
-
|
120
112
|
def base_id_exists?(bases, base_id)
|
121
113
|
return if extract_bases(bases).any? { |base| base["id"] == base_id }
|
122
114
|
|
@@ -110,14 +110,6 @@ module Multiwoven::Integrations::Destination
|
|
110
110
|
[schema, data]
|
111
111
|
end
|
112
112
|
|
113
|
-
def auth_headers(access_token)
|
114
|
-
{
|
115
|
-
"Accept" => "application/json",
|
116
|
-
"Authorization" => "Bearer #{access_token}",
|
117
|
-
"Content-Type" => "application/json"
|
118
|
-
}
|
119
|
-
end
|
120
|
-
|
121
113
|
def ad_account_exists?(response, ad_account_id)
|
122
114
|
return if extract_data(response).any? { |ad_account| ad_account["id"] == "act_#{ad_account_id}" }
|
123
115
|
|
@@ -38,6 +38,7 @@ module Multiwoven::Integrations::Destination
|
|
38
38
|
|
39
39
|
request_method = sync_config.stream.request_method
|
40
40
|
|
41
|
+
log_message_array = []
|
41
42
|
write_success = 0
|
42
43
|
write_failure = 0
|
43
44
|
records.each do |record|
|
@@ -45,6 +46,7 @@ module Multiwoven::Integrations::Destination
|
|
45
46
|
# Add hardcode values into payload
|
46
47
|
record["data"] ||= {}
|
47
48
|
record["data"]["type"] = sync_config.stream.name
|
49
|
+
args = [request_method, url, record]
|
48
50
|
|
49
51
|
response = Multiwoven::Integrations::Core::HttpClient.request(
|
50
52
|
url,
|
@@ -57,6 +59,7 @@ module Multiwoven::Integrations::Destination
|
|
57
59
|
else
|
58
60
|
write_failure += 1
|
59
61
|
end
|
62
|
+
log_message_array << log_request_response("info", args, response)
|
60
63
|
rescue StandardError => e
|
61
64
|
handle_exception(e, {
|
62
65
|
context: "KLAVIYO:RECORD:WRITE:FAILURE",
|
@@ -65,12 +68,9 @@ module Multiwoven::Integrations::Destination
|
|
65
68
|
sync_run_id: sync_config.sync_run_id
|
66
69
|
})
|
67
70
|
write_failure += 1
|
71
|
+
log_message_array << log_request_response("error", args, e.message)
|
68
72
|
end
|
69
|
-
|
70
|
-
success: write_success,
|
71
|
-
failed: write_failure
|
72
|
-
)
|
73
|
-
tracker.to_multiwoven_message
|
73
|
+
tracking_message(write_success, write_failure, log_message_array)
|
74
74
|
rescue StandardError => e
|
75
75
|
# TODO: Handle rate limiting seperately
|
76
76
|
handle_exception(e, {
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Multiwoven::Integrations::Destination
|
4
|
+
module MicrosoftExcel
|
5
|
+
include Multiwoven::Integrations::Core
|
6
|
+
class Client < DestinationConnector
|
7
|
+
prepend Multiwoven::Integrations::Core::RateLimiter
|
8
|
+
def check_connection(connection_config)
|
9
|
+
connection_config = connection_config.with_indifferent_access
|
10
|
+
drive_id = create_connection(connection_config)
|
11
|
+
if drive_id
|
12
|
+
success_status
|
13
|
+
else
|
14
|
+
failure_status(nil)
|
15
|
+
end
|
16
|
+
rescue StandardError => e
|
17
|
+
handle_exception(e, {
|
18
|
+
context: "MICROSOFT:EXCEL:CHECK_CONNECTION:EXCEPTION",
|
19
|
+
type: "error"
|
20
|
+
})
|
21
|
+
failure_status(e)
|
22
|
+
end
|
23
|
+
|
24
|
+
def discover(connection_config)
|
25
|
+
catalog_json = read_json(CATALOG_SPEC_PATH)
|
26
|
+
connection_config = connection_config.with_indifferent_access
|
27
|
+
token = connection_config[:token]
|
28
|
+
drive_id = create_connection(connection_config)
|
29
|
+
records = get_file(token, drive_id)
|
30
|
+
records.each do |record|
|
31
|
+
file_id = record[:id]
|
32
|
+
record[:worksheets] = get_file_data(token, drive_id, file_id)
|
33
|
+
end
|
34
|
+
catalog = Catalog.new(streams: create_streams(records, catalog_json))
|
35
|
+
catalog.to_multiwoven_message
|
36
|
+
rescue StandardError => e
|
37
|
+
handle_exception(e, {
|
38
|
+
context: "MICROSOFT:EXCEL:DISCOVER:EXCEPTION",
|
39
|
+
type: "error"
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
def write(sync_config, records, _action = "destination_insert")
|
44
|
+
connection_config = sync_config.destination.connection_specification.with_indifferent_access
|
45
|
+
token = connection_config[:token]
|
46
|
+
file_name = sync_config.stream.name.split(", ").first
|
47
|
+
sheet_name = sync_config.stream.name.split(", ").last
|
48
|
+
drive_id = create_connection(connection_config)
|
49
|
+
excel_files = get_file(token, drive_id)
|
50
|
+
worksheet = excel_files.find { |file| file[:name] == file_name }
|
51
|
+
item_id = worksheet[:id]
|
52
|
+
|
53
|
+
table = get_table(token, drive_id, item_id)
|
54
|
+
write_url = format(MS_EXCEL_TABLE_ROW_WRITE_API, drive_id: drive_id, item_id: item_id, sheet_name: sheet_name,
|
55
|
+
table_name: table["name"])
|
56
|
+
payload = { values: records.map(&:values) }
|
57
|
+
process_write_request(write_url, payload, token, sync_config)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def create_connection(connection_config)
|
63
|
+
token = connection_config[:token]
|
64
|
+
response = Multiwoven::Integrations::Core::HttpClient.request(
|
65
|
+
MS_EXCEL_AUTH_ENDPOINT,
|
66
|
+
HTTP_GET,
|
67
|
+
headers: auth_headers(token)
|
68
|
+
)
|
69
|
+
JSON.parse(response.body)["id"]
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_table(token, drive_id, item_id)
|
73
|
+
table_url = format(MS_EXCEL_TABLE_API, drive_id: drive_id, item_id: item_id)
|
74
|
+
response = Multiwoven::Integrations::Core::HttpClient.request(
|
75
|
+
table_url,
|
76
|
+
HTTP_GET,
|
77
|
+
headers: auth_headers(token)
|
78
|
+
)
|
79
|
+
JSON.parse(response.body)["value"].first
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_file(token, drive_id)
|
83
|
+
url = format(MS_EXCEL_FILES_API, drive_id: drive_id)
|
84
|
+
response = Multiwoven::Integrations::Core::HttpClient.request(
|
85
|
+
url,
|
86
|
+
HTTP_GET,
|
87
|
+
headers: auth_headers(token)
|
88
|
+
)
|
89
|
+
files = JSON.parse(response.body)["value"]
|
90
|
+
excel_files = files.select { |file| file["name"].match(/\.(xlsx|xls|xlsm)$/) }
|
91
|
+
excel_files.map { |file| { name: file["name"], id: file["id"] } }
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_all_sheets(token, drive_id, item_id)
|
95
|
+
base_url = format(MS_EXCEL_WORKSHEETS_API, drive_id: drive_id, item_id: item_id)
|
96
|
+
worksheet_response = Multiwoven::Integrations::Core::HttpClient.request(
|
97
|
+
base_url,
|
98
|
+
HTTP_GET,
|
99
|
+
headers: auth_headers(token)
|
100
|
+
)
|
101
|
+
JSON.parse(worksheet_response.body)["value"]
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_file_data(token, drive_id, item_id)
|
105
|
+
result = []
|
106
|
+
worksheets_data = get_all_sheets(token, drive_id, item_id)
|
107
|
+
worksheets_data.each do |sheet|
|
108
|
+
sheet_name = sheet["name"]
|
109
|
+
sheet_url = format(MS_EXCEL_SHEET_RANGE_API, drive_id: drive_id, item_id: item_id, sheet_name: sheet_name)
|
110
|
+
|
111
|
+
sheet_response = Multiwoven::Integrations::Core::HttpClient.request(
|
112
|
+
sheet_url,
|
113
|
+
HTTP_GET,
|
114
|
+
headers: auth_headers(token)
|
115
|
+
)
|
116
|
+
sheets_data = JSON.parse(sheet_response.body)
|
117
|
+
result << {
|
118
|
+
sheet_name: sheet_name,
|
119
|
+
column_names: sheets_data["values"].first
|
120
|
+
}
|
121
|
+
end
|
122
|
+
result
|
123
|
+
end
|
124
|
+
|
125
|
+
def create_streams(records, catalog_json)
|
126
|
+
group_by_table(records).flat_map do |_, record|
|
127
|
+
record.map do |_, r|
|
128
|
+
Multiwoven::Integrations::Protocol::Stream.new(
|
129
|
+
name: r[:workbook],
|
130
|
+
action: StreamAction["fetch"],
|
131
|
+
json_schema: convert_to_json_schema(r[:columns]),
|
132
|
+
request_rate_limit: catalog_json["request_rate_limit"] || 60,
|
133
|
+
request_rate_limit_unit: catalog_json["request_rate_limit_unit"] || "minute",
|
134
|
+
request_rate_concurrency: catalog_json["request_rate_concurrency"] || 1
|
135
|
+
)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def group_by_table(records)
|
141
|
+
result = {}
|
142
|
+
|
143
|
+
records.each_with_index do |entries, entries_index|
|
144
|
+
entries[:worksheets].each_with_index do |sheet, entry_index|
|
145
|
+
workbook_sheet = "#{entries[:name]}, #{sheet[:sheet_name]}"
|
146
|
+
columns = sheet[:column_names].map do |column_name|
|
147
|
+
column_name = "empty column" if column_name.empty?
|
148
|
+
{
|
149
|
+
column_name: column_name,
|
150
|
+
data_type: "String",
|
151
|
+
is_nullable: true
|
152
|
+
}
|
153
|
+
end
|
154
|
+
result[entries_index] ||= {}
|
155
|
+
result[entries_index][entry_index] = { workbook: workbook_sheet, columns: columns }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
result
|
159
|
+
end
|
160
|
+
|
161
|
+
def process_write_request(write_url, payload, token, sync_config)
|
162
|
+
write_success = 0
|
163
|
+
write_failure = 0
|
164
|
+
log_message_array = []
|
165
|
+
|
166
|
+
begin
|
167
|
+
response = Multiwoven::Integrations::Core::HttpClient.request(
|
168
|
+
write_url,
|
169
|
+
HTTP_POST,
|
170
|
+
payload: payload,
|
171
|
+
headers: auth_headers(token)
|
172
|
+
)
|
173
|
+
if success?(response)
|
174
|
+
write_success += 1
|
175
|
+
else
|
176
|
+
write_failure += 1
|
177
|
+
end
|
178
|
+
log_message_array << log_request_response("info", [HTTP_POST, write_url, payload], response)
|
179
|
+
rescue StandardError => e
|
180
|
+
handle_exception(e, {
|
181
|
+
context: "MICROSOFT:EXCEL:RECORD:WRITE:EXCEPTION",
|
182
|
+
type: "error",
|
183
|
+
sync_id: sync_config.sync_id,
|
184
|
+
sync_run_id: sync_config.sync_run_id
|
185
|
+
})
|
186
|
+
write_failure += 1
|
187
|
+
log_message_array << log_request_response("error", [HTTP_POST, write_url, payload], e.message)
|
188
|
+
end
|
189
|
+
|
190
|
+
tracking_message(write_success, write_failure, log_message_array)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "MicrosoftExcel",
|
4
|
+
"title": "Microsoft Excel",
|
5
|
+
"connector_type": "destination",
|
6
|
+
"category": "Database",
|
7
|
+
"documentation_url": "https://docs.squared.ai/guides/data-integration/destination/microsoft_excel",
|
8
|
+
"github_issue_label": "destination-microsoft-excel",
|
9
|
+
"icon": "icon.svg",
|
10
|
+
"license": "MIT",
|
11
|
+
"release_stage": "alpha",
|
12
|
+
"support_level": "community",
|
13
|
+
"tags": ["language:ruby", "multiwoven"]
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"documentation_url": "https://docs.squared.ai/guides/data-integration/destination/microsoft_excel",
|
3
|
+
"stream_type": "dynamic",
|
4
|
+
"connector_query_type": "raw_sql",
|
5
|
+
"connection_specification": {
|
6
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
7
|
+
"title": "Microsoft Excel",
|
8
|
+
"type": "object",
|
9
|
+
"required": ["token"],
|
10
|
+
"properties": {
|
11
|
+
"token": {
|
12
|
+
"description": "Token from Microsoft Graph.",
|
13
|
+
"type": "string",
|
14
|
+
"title": "Token",
|
15
|
+
"order": 0
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="800" width="1200" viewBox="-343.4625 -532.5 2976.675 3195">
|
2
|
+
<path d="M1437.75 1011.75L532.5 852v1180.393c0 53.907 43.7 97.607 97.607 97.607h1562.036c53.907 0 97.607-43.7 97.607-97.607V1597.5z" fill="#185C37"/>
|
3
|
+
<path d="M1437.75 0H630.107C576.2 0 532.5 43.7 532.5 97.607V532.5l905.25 532.5L1917 1224.75 2289.75 1065V532.5z" fill="#21A366"/>
|
4
|
+
<path d="M532.5 532.5h905.25V1065H532.5z" fill="#107C41"/>
|
5
|
+
<path d="M1180.393 426H532.5v1331.25h647.893c53.834-.175 97.432-43.773 97.607-97.607V523.607c-.175-53.834-43.773-97.432-97.607-97.607z" opacity=".1"/>
|
6
|
+
<path d="M1127.143 479.25H532.5V1810.5h594.643c53.834-.175 97.432-43.773 97.607-97.607V576.857c-.175-53.834-43.773-97.432-97.607-97.607z" opacity=".2"/>
|
7
|
+
<path d="M1127.143 479.25H532.5V1704h594.643c53.834-.175 97.432-43.773 97.607-97.607V576.857c-.175-53.834-43.773-97.432-97.607-97.607z" opacity=".2"/>
|
8
|
+
<path d="M1073.893 479.25H532.5V1704h541.393c53.834-.175 97.432-43.773 97.607-97.607V576.857c-.175-53.834-43.773-97.432-97.607-97.607z" opacity=".2"/>
|
9
|
+
<linearGradient gradientTransform="matrix(1 0 0 -1 0 2132)" y2="404.982" x2="967.987" y1="1729.018" x1="203.513" gradientUnits="userSpaceOnUse" id="a">
|
10
|
+
<stop offset="0" stop-color="#18884f"/>
|
11
|
+
<stop offset=".5" stop-color="#117e43"/>
|
12
|
+
<stop offset="1" stop-color="#0b6631"/>
|
13
|
+
</linearGradient>
|
14
|
+
<path d="M97.607 479.25h976.285c53.907 0 97.607 43.7 97.607 97.607v976.285c0 53.907-43.7 97.607-97.607 97.607H97.607C43.7 1650.75 0 1607.05 0 1553.143V576.857c0-53.907 43.7-97.607 97.607-97.607z" fill="url(#a)"/>
|
15
|
+
<path d="M302.3 1382.264l205.332-318.169L319.5 747.683h151.336l102.666 202.35c9.479 19.223 15.975 33.494 19.49 42.919h1.331a798.667 798.667 0 0121.3-44.677L725.371 747.79H864.3l-192.925 314.548L869.2 1382.263H721.378L602.79 1160.158a186.298 186.298 0 01-14.164-29.66h-1.757a140.458 140.458 0 01-13.739 28.755l-122.102 223.011z" fill="#FFF"/>
|
16
|
+
<path d="M2192.143 0H1437.75v532.5h852V97.607C2289.75 43.7 2246.05 0 2192.143 0z" fill="#33C481"/>
|
17
|
+
<path d="M1437.75 1065h852v532.5h-852z" fill="#107C41"/>
|
18
|
+
</svg>
|
@@ -81,6 +81,7 @@ require_relative "integrations/destination/iterable/client"
|
|
81
81
|
require_relative "integrations/destination/maria_db/client"
|
82
82
|
require_relative "integrations/destination/databricks_lakehouse/client"
|
83
83
|
require_relative "integrations/destination/oracle_db/client"
|
84
|
+
require_relative "integrations/destination/microsoft_excel/client"
|
84
85
|
|
85
86
|
module Multiwoven
|
86
87
|
module Integrations
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multiwoven-integrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Subin T P
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -544,6 +544,11 @@ files:
|
|
544
544
|
- lib/multiwoven/integrations/destination/maria_db/config/meta.json
|
545
545
|
- lib/multiwoven/integrations/destination/maria_db/config/spec.json
|
546
546
|
- lib/multiwoven/integrations/destination/maria_db/icon.svg
|
547
|
+
- lib/multiwoven/integrations/destination/microsoft_excel/client.rb
|
548
|
+
- lib/multiwoven/integrations/destination/microsoft_excel/config/catalog.json
|
549
|
+
- lib/multiwoven/integrations/destination/microsoft_excel/config/meta.json
|
550
|
+
- lib/multiwoven/integrations/destination/microsoft_excel/config/spec.json
|
551
|
+
- lib/multiwoven/integrations/destination/microsoft_excel/icon.svg
|
547
552
|
- lib/multiwoven/integrations/destination/oracle_db/client.rb
|
548
553
|
- lib/multiwoven/integrations/destination/oracle_db/config/meta.json
|
549
554
|
- lib/multiwoven/integrations/destination/oracle_db/config/spec.json
|