@aiqadam/qadam-snowflake 0.3.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/LICENSE +22 -0
- package/NOTICE +6 -0
- package/README.md +5 -0
- package/package.json +23 -0
- package/src/i18n/de.json +120 -0
- package/src/i18n/es.json +120 -0
- package/src/i18n/fr.json +120 -0
- package/src/i18n/ja.json +120 -0
- package/src/i18n/nl.json +120 -0
- package/src/i18n/pt.json +120 -0
- package/src/i18n/ru.json +16 -0
- package/src/i18n/translation.json +120 -0
- package/src/i18n/vi.json +14 -0
- package/src/i18n/zh.json +120 -0
- package/src/index.d.ts +11 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +63 -0
- package/src/index.js.map +1 -0
- package/src/lib/actions/create-dynamic-table.d.ts +45 -0
- package/src/lib/actions/create-dynamic-table.d.ts.map +1 -0
- package/src/lib/actions/create-dynamic-table.js +82 -0
- package/src/lib/actions/create-dynamic-table.js.map +1 -0
- package/src/lib/actions/delete-row.d.ts +43 -0
- package/src/lib/actions/delete-row.d.ts.map +1 -0
- package/src/lib/actions/delete-row.js +50 -0
- package/src/lib/actions/delete-row.js.map +1 -0
- package/src/lib/actions/execute-stored-procedure.d.ts +43 -0
- package/src/lib/actions/execute-stored-procedure.d.ts.map +1 -0
- package/src/lib/actions/execute-stored-procedure.js +97 -0
- package/src/lib/actions/execute-stored-procedure.js.map +1 -0
- package/src/lib/actions/get-row-by-id.d.ts +53 -0
- package/src/lib/actions/get-row-by-id.d.ts.map +1 -0
- package/src/lib/actions/get-row-by-id.js +72 -0
- package/src/lib/actions/get-row-by-id.js.map +1 -0
- package/src/lib/actions/get-table-schema.d.ts +42 -0
- package/src/lib/actions/get-table-schema.d.ts.map +1 -0
- package/src/lib/actions/get-table-schema.js +54 -0
- package/src/lib/actions/get-table-schema.js.map +1 -0
- package/src/lib/actions/insert-multiple-rows.d.ts +43 -0
- package/src/lib/actions/insert-multiple-rows.d.ts.map +1 -0
- package/src/lib/actions/insert-multiple-rows.js +86 -0
- package/src/lib/actions/insert-multiple-rows.js.map +1 -0
- package/src/lib/actions/insert-row.d.ts +52 -0
- package/src/lib/actions/insert-row.d.ts.map +1 -0
- package/src/lib/actions/insert-row.js +41 -0
- package/src/lib/actions/insert-row.js.map +1 -0
- package/src/lib/actions/list-tables.d.ts +32 -0
- package/src/lib/actions/list-tables.d.ts.map +1 -0
- package/src/lib/actions/list-tables.js +52 -0
- package/src/lib/actions/list-tables.js.map +1 -0
- package/src/lib/actions/load-data-from-stage.d.ts +48 -0
- package/src/lib/actions/load-data-from-stage.d.ts.map +1 -0
- package/src/lib/actions/load-data-from-stage.js +124 -0
- package/src/lib/actions/load-data-from-stage.js.map +1 -0
- package/src/lib/actions/run-multiple-queries.d.ts +17 -0
- package/src/lib/actions/run-multiple-queries.d.ts.map +1 -0
- package/src/lib/actions/run-multiple-queries.js +147 -0
- package/src/lib/actions/run-multiple-queries.js.map +1 -0
- package/src/lib/actions/run-query.d.ts +16 -0
- package/src/lib/actions/run-query.d.ts.map +1 -0
- package/src/lib/actions/run-query.js +58 -0
- package/src/lib/actions/run-query.js.map +1 -0
- package/src/lib/actions/search-rows.d.ts +45 -0
- package/src/lib/actions/search-rows.d.ts.map +1 -0
- package/src/lib/actions/search-rows.js +63 -0
- package/src/lib/actions/search-rows.js.map +1 -0
- package/src/lib/actions/update-row.d.ts +53 -0
- package/src/lib/actions/update-row.d.ts.map +1 -0
- package/src/lib/actions/update-row.js +59 -0
- package/src/lib/actions/update-row.js.map +1 -0
- package/src/lib/actions/upsert-row.d.ts +62 -0
- package/src/lib/actions/upsert-row.d.ts.map +1 -0
- package/src/lib/actions/upsert-row.js +98 -0
- package/src/lib/actions/upsert-row.js.map +1 -0
- package/src/lib/auth.d.ts +22 -0
- package/src/lib/auth.d.ts.map +1 -0
- package/src/lib/auth.js +246 -0
- package/src/lib/auth.js.map +1 -0
- package/src/lib/common/index.d.ts +93 -0
- package/src/lib/common/index.d.ts.map +1 -0
- package/src/lib/common/index.js +319 -0
- package/src/lib/common/index.js.map +1 -0
- package/src/lib/triggers/new-column.d.ts +163 -0
- package/src/lib/triggers/new-column.d.ts.map +1 -0
- package/src/lib/triggers/new-column.js +94 -0
- package/src/lib/triggers/new-column.js.map +1 -0
- package/src/lib/triggers/new-or-updated-row.d.ts +203 -0
- package/src/lib/triggers/new-or-updated-row.d.ts.map +1 -0
- package/src/lib/triggers/new-or-updated-row.js +108 -0
- package/src/lib/triggers/new-or-updated-row.js.map +1 -0
- package/src/lib/triggers/new-row.d.ts +203 -0
- package/src/lib/triggers/new-row.d.ts.map +1 -0
- package/src/lib/triggers/new-row.js +107 -0
- package/src/lib/triggers/new-row.js.map +1 -0
- package/src/lib/triggers/new-table.d.ts +123 -0
- package/src/lib/triggers/new-table.d.ts.map +1 -0
- package/src/lib/triggers/new-table.js +94 -0
- package/src/lib/triggers/new-table.js.map +1 -0
- package/src/lib/triggers/new-view.d.ts +123 -0
- package/src/lib/triggers/new-view.d.ts.map +1 -0
- package/src/lib/triggers/new-view.js +94 -0
- package/src/lib/triggers/new-view.js.map +1 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.searchRowsAction = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const qadams_framework_1 = require("@aiqadam/qadams-framework");
|
|
6
|
+
const auth_1 = require("../auth");
|
|
7
|
+
const common_1 = require("../common");
|
|
8
|
+
exports.searchRowsAction = (0, qadams_framework_1.createAction)({
|
|
9
|
+
name: 'search_rows',
|
|
10
|
+
displayName: 'Search Rows',
|
|
11
|
+
description: 'Search for rows in a Snowflake table using an optional WHERE condition, ordering, and row limit.',
|
|
12
|
+
audience: 'both',
|
|
13
|
+
aiMetadata: {
|
|
14
|
+
description: 'Returns rows from a Snowflake table with an optional WHERE filter, ORDER BY sort, and row limit (default 100); leaving the filter empty returns all rows up to the limit. Use to retrieve a filtered or sorted set of records; for a single row by key use Get Row by ID. The filter and sort clauses are embedded directly into SQL, so pass only trusted values. Read-only and idempotent.',
|
|
15
|
+
idempotent: true,
|
|
16
|
+
},
|
|
17
|
+
auth: auth_1.snowflakeAuth,
|
|
18
|
+
props: {
|
|
19
|
+
database: common_1.snowflakeCommonProps.database,
|
|
20
|
+
schema: common_1.snowflakeCommonProps.schema,
|
|
21
|
+
table: common_1.snowflakeCommonProps.table,
|
|
22
|
+
where_clause: qadams_framework_1.Property.ShortText({
|
|
23
|
+
displayName: 'Filter Condition',
|
|
24
|
+
description: "Optional SQL WHERE condition to narrow down results (e.g. `status = 'active' AND age > 18`). " +
|
|
25
|
+
'Leave empty to return all rows (subject to the row limit). ' +
|
|
26
|
+
'**Security note:** this value is embedded directly in SQL. Only use static values or data from trusted, internal steps — never pass unvalidated end-user input here.',
|
|
27
|
+
required: false,
|
|
28
|
+
}),
|
|
29
|
+
order_by: qadams_framework_1.Property.ShortText({
|
|
30
|
+
displayName: 'Sort By',
|
|
31
|
+
description: 'Optional column(s) to sort results by (SQL ORDER BY clause). Examples: `created_at DESC` sorts newest first; `name ASC, age DESC` sorts by name then age. ' +
|
|
32
|
+
'**Security note:** this value is embedded directly in SQL. Only use static values or data from trusted, internal steps — never pass unvalidated end-user input here.',
|
|
33
|
+
required: false,
|
|
34
|
+
}),
|
|
35
|
+
limit: qadams_framework_1.Property.Number({
|
|
36
|
+
displayName: 'Row Limit',
|
|
37
|
+
description: 'Maximum number of rows to return. Defaults to 100.',
|
|
38
|
+
required: false,
|
|
39
|
+
defaultValue: 100,
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
run(context) {
|
|
43
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const { table, where_clause, order_by, limit } = context.propsValue;
|
|
45
|
+
let sql = `SELECT * FROM ${table}`;
|
|
46
|
+
if (where_clause)
|
|
47
|
+
sql += ` WHERE ${where_clause}`;
|
|
48
|
+
if (order_by)
|
|
49
|
+
sql += ` ORDER BY ${order_by}`;
|
|
50
|
+
sql += ` LIMIT ${Math.trunc(limit !== null && limit !== void 0 ? limit : 100)}`;
|
|
51
|
+
const connection = (0, common_1.configureConnection)(context.auth);
|
|
52
|
+
yield (0, common_1.connect)(connection);
|
|
53
|
+
try {
|
|
54
|
+
const result = yield (0, common_1.execute)(connection, sql, []);
|
|
55
|
+
return result !== null && result !== void 0 ? result : [];
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
yield (0, common_1.destroy)(connection);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=search-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-rows.js","sourceRoot":"","sources":["../../../../src/lib/actions/search-rows.ts"],"names":[],"mappings":";;;;AAAA,gEAAmE;AACnE,kCAAwC;AACxC,sCAOmB;AAEN,QAAA,gBAAgB,GAAG,IAAA,+BAAY,EAAC;IAC3C,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,aAAa;IAC1B,WAAW,EACT,kGAAkG;IACpG,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE;QACV,WAAW,EACT,8XAA8X;QAChY,UAAU,EAAE,IAAI;KACjB;IACD,IAAI,EAAE,oBAAa;IACnB,KAAK,EAAE;QACL,QAAQ,EAAE,6BAAoB,CAAC,QAAQ;QACvC,MAAM,EAAE,6BAAoB,CAAC,MAAM;QACnC,KAAK,EAAE,6BAAoB,CAAC,KAAK;QACjC,YAAY,EAAE,2BAAQ,CAAC,SAAS,CAAC;YAC/B,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EACT,+FAA+F;gBAC/F,6DAA6D;gBAC7D,sKAAsK;YACxK,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,QAAQ,EAAE,2BAAQ,CAAC,SAAS,CAAC;YAC3B,WAAW,EAAE,SAAS;YACtB,WAAW,EACT,4JAA4J;gBAC5J,sKAAsK;YACxK,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,KAAK,EAAE,2BAAQ,CAAC,MAAM,CAAC;YACrB,WAAW,EAAE,WAAW;YACxB,WAAW,EAAE,oDAAoD;YACjE,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,GAAG;SAClB,CAAC;KACH;IACK,GAAG,CAAC,OAAO;;YACf,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;YAEpE,IAAI,GAAG,GAAG,iBAAiB,KAAK,EAAE,CAAC;YACnC,IAAI,YAAY;gBAAE,GAAG,IAAI,UAAU,YAAY,EAAE,CAAC;YAClD,IAAI,QAAQ;gBAAE,GAAG,IAAI,aAAa,QAAQ,EAAE,CAAC;YAC7C,GAAG,IAAI,UAAU,IAAI,CAAC,KAAK,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,GAAG,CAAC,EAAE,CAAC;YAE5C,MAAM,UAAU,GAAG,IAAA,4BAAmB,EAAC,OAAO,CAAC,IAA0B,CAAC,CAAC;YAC3E,MAAM,IAAA,gBAAO,EAAC,UAAU,CAAC,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAA,gBAAO,EAAC,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;gBAClD,OAAO,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;YACtB,CAAC;oBAAS,CAAC;gBACT,MAAM,IAAA,gBAAO,EAAC,UAAU,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;KAAA;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const updateRowAction: import("@aiqadam/qadams-framework").IAction<(import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
2
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
3
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
4
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
5
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
6
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
7
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
8
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
9
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
10
|
+
}>)[], {
|
|
11
|
+
database: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
12
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
13
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
14
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
15
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
16
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
17
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
18
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
19
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
20
|
+
}>)[]>;
|
|
21
|
+
schema: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
22
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
23
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
24
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
25
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
26
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
27
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
28
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
29
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
30
|
+
}>)[]>;
|
|
31
|
+
table: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
32
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
33
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
34
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
35
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
36
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
37
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
38
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
39
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
40
|
+
}>)[]>;
|
|
41
|
+
table_update_values: import("@aiqadam/qadams-framework").DynamicProperties<true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
42
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
43
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
44
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
45
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
46
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
47
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
48
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
49
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
50
|
+
}>)[]>;
|
|
51
|
+
where_clause: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
52
|
+
}>;
|
|
53
|
+
//# sourceMappingURL=update-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-row.d.ts","sourceRoot":"","sources":["../../../../src/lib/actions/update-row.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4D1B,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateRowAction = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const qadams_framework_1 = require("@aiqadam/qadams-framework");
|
|
6
|
+
const auth_1 = require("../auth");
|
|
7
|
+
const common_1 = require("../common");
|
|
8
|
+
exports.updateRowAction = (0, qadams_framework_1.createAction)({
|
|
9
|
+
name: 'update_row',
|
|
10
|
+
displayName: 'Update Row',
|
|
11
|
+
description: 'Update one or more rows in a Snowflake table that match a WHERE condition.',
|
|
12
|
+
audience: 'both',
|
|
13
|
+
aiMetadata: {
|
|
14
|
+
description: 'Runs an UPDATE on a Snowflake table, setting the provided column values on every row matching the given WHERE condition; leaving the condition empty updates ALL rows. Use to modify existing records in place. Repeating the same call generally yields the same final state (it sets values rather than incrementing), but it is a mutating write and the WHERE clause is embedded directly into SQL, so supply only trusted values there.',
|
|
15
|
+
idempotent: false,
|
|
16
|
+
},
|
|
17
|
+
auth: auth_1.snowflakeAuth,
|
|
18
|
+
props: {
|
|
19
|
+
database: common_1.snowflakeCommonProps.database,
|
|
20
|
+
schema: common_1.snowflakeCommonProps.schema,
|
|
21
|
+
table: common_1.snowflakeCommonProps.table,
|
|
22
|
+
table_update_values: common_1.snowflakeCommonProps.table_update_values,
|
|
23
|
+
where_clause: qadams_framework_1.Property.ShortText({
|
|
24
|
+
displayName: 'WHERE Condition',
|
|
25
|
+
description: "A SQL condition to filter which rows to update (e.g. `id = 42` or `status = 'active'`). " +
|
|
26
|
+
'Leave empty to update ALL rows in the table (use with caution). ' +
|
|
27
|
+
'**Security note:** this value is embedded directly in SQL. Only use static values or data from trusted, internal steps — never pass unvalidated end-user input here.',
|
|
28
|
+
required: false,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
run(context) {
|
|
32
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
const { table, table_update_values: columnValues, where_clause, } = context.propsValue;
|
|
35
|
+
const setEntries = Object.entries(columnValues).filter(([, v]) => v !== null && v !== undefined && v !== '');
|
|
36
|
+
if (setEntries.length === 0) {
|
|
37
|
+
throw new Error('At least one column value must be provided to update.');
|
|
38
|
+
}
|
|
39
|
+
const setClauses = setEntries.map(([col]) => `${col} = ?`).join(', ');
|
|
40
|
+
const binds = setEntries.map(([, v]) => v);
|
|
41
|
+
const sql = where_clause
|
|
42
|
+
? `UPDATE ${table} SET ${setClauses} WHERE ${where_clause}`
|
|
43
|
+
: `UPDATE ${table} SET ${setClauses}`;
|
|
44
|
+
const connection = (0, common_1.configureConnection)(context.auth);
|
|
45
|
+
yield (0, common_1.connect)(connection);
|
|
46
|
+
try {
|
|
47
|
+
const result = yield (0, common_1.execute)(connection, sql, binds);
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
rows_updated: (_b = (_a = result === null || result === void 0 ? void 0 : result[0]) === null || _a === void 0 ? void 0 : _a['number of rows updated']) !== null && _b !== void 0 ? _b : null,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
yield (0, common_1.destroy)(connection);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=update-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-row.js","sourceRoot":"","sources":["../../../../src/lib/actions/update-row.ts"],"names":[],"mappings":";;;;AAAA,gEAAmE;AACnE,kCAAwC;AACxC,sCAOmB;AAEN,QAAA,eAAe,GAAG,IAAA,+BAAY,EAAC;IAC1C,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,YAAY;IACzB,WAAW,EACT,4EAA4E;IAC9E,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE;QACV,WAAW,EACT,8aAA8a;QAChb,UAAU,EAAE,KAAK;KAClB;IACD,IAAI,EAAE,oBAAa;IACnB,KAAK,EAAE;QACL,QAAQ,EAAE,6BAAoB,CAAC,QAAQ;QACvC,MAAM,EAAE,6BAAoB,CAAC,MAAM;QACnC,KAAK,EAAE,6BAAoB,CAAC,KAAK;QACjC,mBAAmB,EAAE,6BAAoB,CAAC,mBAAmB;QAC7D,YAAY,EAAE,2BAAQ,CAAC,SAAS,CAAC;YAC/B,WAAW,EAAE,iBAAiB;YAC9B,WAAW,EACT,0FAA0F;gBAC1F,kEAAkE;gBAClE,sKAAsK;YACxK,QAAQ,EAAE,KAAK;SAChB,CAAC;KACH;IACK,GAAG,CAAC,OAAO;;;YACf,MAAM,EACJ,KAAK,EACL,mBAAmB,EAAE,YAAY,EACjC,YAAY,GACb,GAAG,OAAO,CAAC,UAAU,CAAC;YAEvB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,CACpD,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,CACrD,CAAC;YAEF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,CAAC;YAED,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAa,CAAC;YAEvD,MAAM,GAAG,GAAG,YAAY;gBACtB,CAAC,CAAC,UAAU,KAAK,QAAQ,UAAU,UAAU,YAAY,EAAE;gBAC3D,CAAC,CAAC,UAAU,KAAK,QAAQ,UAAU,EAAE,CAAC;YAExC,MAAM,UAAU,GAAG,IAAA,4BAAmB,EAAC,OAAO,CAAC,IAA0B,CAAC,CAAC;YAC3E,MAAM,IAAA,gBAAO,EAAC,UAAU,CAAC,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAA,gBAAO,EAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACrD,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,YAAY,EAAE,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,CAAC,CAAC,0CAAG,wBAAwB,CAAC,mCAAI,IAAI;iBAC9D,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,MAAM,IAAA,gBAAO,EAAC,UAAU,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;KAAA;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export declare const upsertRowAction: import("@aiqadam/qadams-framework").IAction<(import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
2
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
3
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
4
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
5
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
6
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
7
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
8
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
9
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
10
|
+
}>)[], {
|
|
11
|
+
database: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
12
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
13
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
14
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
15
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
16
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
17
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
18
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
19
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
20
|
+
}>)[]>;
|
|
21
|
+
schema: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
22
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
23
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
24
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
25
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
26
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
27
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
28
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
29
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
30
|
+
}>)[]>;
|
|
31
|
+
table: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
32
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
33
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
34
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
35
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
36
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
37
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
38
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
39
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
40
|
+
}>)[]>;
|
|
41
|
+
match_column: import("@aiqadam/qadams-framework").DropdownProperty<string, true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
42
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
43
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
44
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
45
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
46
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
47
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
48
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
49
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
50
|
+
}>)[]>;
|
|
51
|
+
table_column_values: import("@aiqadam/qadams-framework").DynamicProperties<true, (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
52
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
53
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
54
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
55
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
56
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
57
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
58
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
59
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
60
|
+
}>)[]>;
|
|
61
|
+
}>;
|
|
62
|
+
//# sourceMappingURL=upsert-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upsert-row.d.ts","sourceRoot":"","sources":["../../../../src/lib/actions/upsert-row.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyG1B,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.upsertRowAction = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const qadams_framework_1 = require("@aiqadam/qadams-framework");
|
|
6
|
+
const auth_1 = require("../auth");
|
|
7
|
+
const common_1 = require("../common");
|
|
8
|
+
exports.upsertRowAction = (0, qadams_framework_1.createAction)({
|
|
9
|
+
name: 'upsert_row',
|
|
10
|
+
displayName: 'Upsert Row',
|
|
11
|
+
description: 'Insert a new row or update an existing one if a row with the same match column value already exists (MERGE INTO).',
|
|
12
|
+
audience: 'both',
|
|
13
|
+
aiMetadata: {
|
|
14
|
+
description: 'Inserts a row into a Snowflake table, or updates the existing row when one already matches on the chosen match column, via MERGE INTO. Use when you want create-or-update semantics keyed on a stable identifier instead of separate insert/update logic. The match column must be among the supplied column values, and at least one other column is required. Idempotent when the match column is a stable unique key: repeating the call converges to the same row state.',
|
|
15
|
+
idempotent: true,
|
|
16
|
+
},
|
|
17
|
+
auth: auth_1.snowflakeAuth,
|
|
18
|
+
props: {
|
|
19
|
+
database: common_1.snowflakeCommonProps.database,
|
|
20
|
+
schema: common_1.snowflakeCommonProps.schema,
|
|
21
|
+
table: common_1.snowflakeCommonProps.table,
|
|
22
|
+
match_column: qadams_framework_1.Property.Dropdown({
|
|
23
|
+
auth: auth_1.snowflakeAuth,
|
|
24
|
+
displayName: 'Match Column',
|
|
25
|
+
description: 'The column used to identify whether a row already exists (e.g. the primary key or a unique identifier column).',
|
|
26
|
+
refreshers: ['table'],
|
|
27
|
+
required: true,
|
|
28
|
+
options: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth, table }) {
|
|
29
|
+
if (!auth) {
|
|
30
|
+
return {
|
|
31
|
+
disabled: true,
|
|
32
|
+
options: [],
|
|
33
|
+
placeholder: 'Please connect your account first',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (!table) {
|
|
37
|
+
return {
|
|
38
|
+
disabled: true,
|
|
39
|
+
options: [],
|
|
40
|
+
placeholder: 'Please select a table first',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return (0, common_1.getTableColumnOptions)(auth, table);
|
|
44
|
+
}),
|
|
45
|
+
}),
|
|
46
|
+
table_column_values: common_1.snowflakeCommonProps.table_column_values,
|
|
47
|
+
},
|
|
48
|
+
run(context) {
|
|
49
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
var _a, _b, _c, _d;
|
|
51
|
+
const { table, match_column, table_column_values: columnValues, } = context.propsValue;
|
|
52
|
+
const columns = Object.keys(columnValues);
|
|
53
|
+
if (columns.length === 0) {
|
|
54
|
+
throw new Error('At least one column value must be provided.');
|
|
55
|
+
}
|
|
56
|
+
if (!columns.includes(match_column)) {
|
|
57
|
+
throw new Error(`Match column "${match_column}" must be included in the column values. ` +
|
|
58
|
+
`Please add a value for "${match_column}" in the columns to upsert.`);
|
|
59
|
+
}
|
|
60
|
+
// Build MERGE INTO statement
|
|
61
|
+
// source: SELECT ? AS col1, ? AS col2, ...
|
|
62
|
+
const sourceSelects = columns.map((col) => `? AS ${col}`).join(', ');
|
|
63
|
+
const updateEntries = columns.filter((col) => col !== match_column);
|
|
64
|
+
if (updateEntries.length === 0) {
|
|
65
|
+
throw new Error('At least one column other than the match column must be provided to update.');
|
|
66
|
+
}
|
|
67
|
+
const updateSets = updateEntries
|
|
68
|
+
.map((col) => `target.${col} = source.${col}`)
|
|
69
|
+
.join(', ');
|
|
70
|
+
const insertCols = columns.join(', ');
|
|
71
|
+
const insertVals = columns.map((col) => `source.${col}`).join(', ');
|
|
72
|
+
const sql = `
|
|
73
|
+
MERGE INTO ${table} AS target
|
|
74
|
+
USING (SELECT ${sourceSelects}) AS source
|
|
75
|
+
ON target.${match_column} = source.${match_column}
|
|
76
|
+
WHEN MATCHED THEN
|
|
77
|
+
UPDATE SET ${updateSets}
|
|
78
|
+
WHEN NOT MATCHED THEN
|
|
79
|
+
INSERT (${insertCols}) VALUES (${insertVals})
|
|
80
|
+
`.trim();
|
|
81
|
+
const binds = Object.values(columnValues);
|
|
82
|
+
const connection = (0, common_1.configureConnection)(context.auth);
|
|
83
|
+
yield (0, common_1.connect)(connection);
|
|
84
|
+
try {
|
|
85
|
+
const result = yield (0, common_1.execute)(connection, sql, binds);
|
|
86
|
+
return {
|
|
87
|
+
success: true,
|
|
88
|
+
rows_inserted: (_b = (_a = result === null || result === void 0 ? void 0 : result[0]) === null || _a === void 0 ? void 0 : _a['number of rows inserted']) !== null && _b !== void 0 ? _b : null,
|
|
89
|
+
rows_updated: (_d = (_c = result === null || result === void 0 ? void 0 : result[0]) === null || _c === void 0 ? void 0 : _c['number of rows updated']) !== null && _d !== void 0 ? _d : null,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
yield (0, common_1.destroy)(connection);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=upsert-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upsert-row.js","sourceRoot":"","sources":["../../../../src/lib/actions/upsert-row.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const snowflakeOAuth2Auth: import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props>;
|
|
2
|
+
export declare const snowflakeCustomAuth: import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
3
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
4
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
5
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
6
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
7
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
8
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
9
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
10
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const snowflakeAuth: (import("@aiqadam/qadams-framework").OAuth2Property<import("@aiqadam/qadams-framework").OAuth2Props> | import("@aiqadam/qadams-framework").CustomAuthProperty<{
|
|
13
|
+
account: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
14
|
+
username: import("@aiqadam/qadams-framework").ShortTextProperty<true>;
|
|
15
|
+
password: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
16
|
+
privateKey: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
17
|
+
privateKeyPassphrase: import("@aiqadam/qadams-framework").SecretTextProperty<false>;
|
|
18
|
+
database: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
19
|
+
role: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
20
|
+
warehouse: import("@aiqadam/qadams-framework").ShortTextProperty<false>;
|
|
21
|
+
}>)[];
|
|
22
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/auth.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,mBAAmB,qGAqG9B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;EA4H9B,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;KAA6C,CAAC"}
|
package/src/lib/auth.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.snowflakeAuth = exports.snowflakeCustomAuth = exports.snowflakeOAuth2Auth = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const qadams_framework_1 = require("@aiqadam/qadams-framework");
|
|
6
|
+
const snowflake_sdk_1 = tslib_1.__importDefault(require("snowflake-sdk"));
|
|
7
|
+
// Suppress the SDK's verbose INFO/DEBUG logs so they don't corrupt stdout IPC
|
|
8
|
+
snowflake_sdk_1.default.configure({ logLevel: 'ERROR' });
|
|
9
|
+
function formatPrivateKey(privateKey) {
|
|
10
|
+
const lines = privateKey
|
|
11
|
+
.replace('-----BEGIN PRIVATE KEY-----', '')
|
|
12
|
+
.replace('-----END PRIVATE KEY-----', '')
|
|
13
|
+
.trim()
|
|
14
|
+
.split(' ');
|
|
15
|
+
return [
|
|
16
|
+
'-----BEGIN PRIVATE KEY-----',
|
|
17
|
+
...lines,
|
|
18
|
+
'-----END PRIVATE KEY-----',
|
|
19
|
+
].join('\n');
|
|
20
|
+
}
|
|
21
|
+
function connectAsync(conn) {
|
|
22
|
+
return new Promise((resolve, reject) => conn.connect((err) => (err ? reject(err) : resolve())));
|
|
23
|
+
}
|
|
24
|
+
function destroyAsync(conn) {
|
|
25
|
+
return new Promise((resolve, reject) => conn.destroy((err) => (err ? reject(err) : resolve())));
|
|
26
|
+
}
|
|
27
|
+
exports.snowflakeOAuth2Auth = qadams_framework_1.QadamAuth.OAuth2({
|
|
28
|
+
displayName: 'OAuth',
|
|
29
|
+
description: `Connect via Snowflake OAuth using a custom security integration.
|
|
30
|
+
|
|
31
|
+
> **Prerequisite:** You need the \`ACCOUNTADMIN\` role (or a role with the \`CREATE INTEGRATION\` privilege).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### Step 1 — Create a security integration
|
|
36
|
+
|
|
37
|
+
Open a **SQL Worksheet** in your Snowflake console and run:
|
|
38
|
+
|
|
39
|
+
\`\`\`sql
|
|
40
|
+
CREATE SECURITY INTEGRATION "activepieces"
|
|
41
|
+
TYPE = OAUTH
|
|
42
|
+
OAUTH_CLIENT = CUSTOM
|
|
43
|
+
OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
|
|
44
|
+
OAUTH_REDIRECT_URI = 'https://flow.aiqadam.org/redirect'
|
|
45
|
+
ENABLED = TRUE
|
|
46
|
+
OAUTH_ISSUE_REFRESH_TOKENS = TRUE
|
|
47
|
+
OAUTH_USE_SECONDARY_ROLES = IMPLICIT;
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
> Replace the redirect URI with the one shown on your Activepieces OAuth connection page.
|
|
51
|
+
>
|
|
52
|
+
> \`OAUTH_USE_SECONDARY_ROLES = IMPLICIT\` lets the access token use any role granted to the user. Without it, the token is bound to the user's default Snowflake role and the **Default Role** field below will be ignored.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### Step 2 — Retrieve client credentials
|
|
57
|
+
|
|
58
|
+
Run the following query to get your **Client ID** and **Client Secret**:
|
|
59
|
+
|
|
60
|
+
\`\`\`sql
|
|
61
|
+
SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('activepieces');
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
Copy \`OAUTH_CLIENT_ID\` and \`OAUTH_CLIENT_SECRET\` from the JSON result.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### Step 3 — Find your Account Identifier
|
|
69
|
+
|
|
70
|
+
Click the **account icon** at the bottom-left of the Snowflake console → **View account details**.
|
|
71
|
+
Copy the **Account Identifier** (e.g. \`xy12345.us-east-1\` or \`orgname-accountname\`).
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### Step 4 — Connect
|
|
76
|
+
|
|
77
|
+
Enter the **Client ID** and **Client Secret** in the Activepieces OAuth2 settings for this connection, fill in the **Account Identifier** below, then click **Connect**.`,
|
|
78
|
+
authUrl: 'https://{account}.snowflakecomputing.com/oauth/authorize',
|
|
79
|
+
tokenUrl: 'https://{account}.snowflakecomputing.com/oauth/token-request',
|
|
80
|
+
scope: ['refresh_token'],
|
|
81
|
+
pkce: false,
|
|
82
|
+
authorizationMethod: qadams_framework_1.OAuth2AuthorizationMethod.BODY,
|
|
83
|
+
required: true,
|
|
84
|
+
props: {
|
|
85
|
+
account: qadams_framework_1.Property.ShortText({
|
|
86
|
+
displayName: 'Account Identifier',
|
|
87
|
+
required: true,
|
|
88
|
+
description: 'Account icon (bottom-left) → **View account details** → copy the **Account Identifier**. Examples: `xy12345.us-east-1`, `orgname-accountname`.',
|
|
89
|
+
}),
|
|
90
|
+
database: qadams_framework_1.Property.ShortText({
|
|
91
|
+
displayName: 'Default Database',
|
|
92
|
+
required: false,
|
|
93
|
+
description: 'Optional. Default database for queries. Find names under **Data → Databases**.',
|
|
94
|
+
}),
|
|
95
|
+
warehouse: qadams_framework_1.Property.ShortText({
|
|
96
|
+
displayName: 'Default Warehouse',
|
|
97
|
+
required: false,
|
|
98
|
+
description: 'Optional. Default virtual warehouse. Find names under **Admin → Warehouses**.',
|
|
99
|
+
}),
|
|
100
|
+
role: qadams_framework_1.Property.ShortText({
|
|
101
|
+
displayName: 'Default Role',
|
|
102
|
+
required: false,
|
|
103
|
+
description: 'Optional. Default security role. Find names under **Admin → Users & Roles → Roles**.',
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
validate: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth }) {
|
|
107
|
+
try {
|
|
108
|
+
const conn = snowflake_sdk_1.default.createConnection({
|
|
109
|
+
account: auth.props['account'],
|
|
110
|
+
authenticator: 'OAUTH',
|
|
111
|
+
token: auth.access_token,
|
|
112
|
+
database: auth.props['database'],
|
|
113
|
+
warehouse: auth.props['warehouse'],
|
|
114
|
+
role: auth.props['role'],
|
|
115
|
+
application: 'ActivePieces',
|
|
116
|
+
});
|
|
117
|
+
yield connectAsync(conn);
|
|
118
|
+
yield destroyAsync(conn);
|
|
119
|
+
return { valid: true };
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
return { valid: false, error: e.message };
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
exports.snowflakeCustomAuth = qadams_framework_1.QadamAuth.CustomAuth({
|
|
127
|
+
displayName: 'Username & Password / Key Pair',
|
|
128
|
+
description: `Connect using your Snowflake username with either a **password** or an **RSA private key**.
|
|
129
|
+
|
|
130
|
+
### Finding your Account Identifier
|
|
131
|
+
|
|
132
|
+
Click the **account icon** at the bottom-left of the Snowflake console → **View account details**.
|
|
133
|
+
Copy the **Account Identifier** (e.g. \`xy12345.us-east-1\` or \`orgname-accountname\`).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Option A — Password
|
|
138
|
+
|
|
139
|
+
Use your Snowflake username and the password you use to log in at [app.snowflake.com](https://app.snowflake.com).
|
|
140
|
+
Your username is shown in the profile section at the top-left of the console, or under **Admin → Users & Roles → Users**.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### Option B — Key Pair *(recommended for automation)*
|
|
145
|
+
|
|
146
|
+
**1. Generate a key pair** (run in your terminal):
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
# Unencrypted (no passphrase needed)
|
|
150
|
+
openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out rsa_key.p8
|
|
151
|
+
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
|
|
152
|
+
|
|
153
|
+
# Encrypted (you will be prompted for a passphrase)
|
|
154
|
+
openssl genrsa 2048 | openssl pkcs8 -topk8 -out rsa_key_encrypted.p8
|
|
155
|
+
openssl rsa -in rsa_key_encrypted.p8 -pubout -out rsa_key.pub
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
**2. Register the public key** with your Snowflake user (run in a SQL Worksheet):
|
|
159
|
+
|
|
160
|
+
\`\`\`sql
|
|
161
|
+
ALTER USER <your_username>
|
|
162
|
+
SET RSA_PUBLIC_KEY='<contents of rsa_key.pub, excluding the BEGIN/END lines>';
|
|
163
|
+
\`\`\`
|
|
164
|
+
|
|
165
|
+
**3. Paste the private key** — copy the full contents of \`rsa_key.p8\` (including the \`-----BEGIN PRIVATE KEY-----\` header and footer) into the **Private Key** field below.`,
|
|
166
|
+
props: {
|
|
167
|
+
account: qadams_framework_1.Property.ShortText({
|
|
168
|
+
displayName: 'Account Identifier',
|
|
169
|
+
required: true,
|
|
170
|
+
description: 'Account icon (bottom-left) → **View account details** → copy the **Account Identifier**. Examples: `xy12345.us-east-1`, `orgname-accountname`.',
|
|
171
|
+
}),
|
|
172
|
+
username: qadams_framework_1.Property.ShortText({
|
|
173
|
+
displayName: 'Username',
|
|
174
|
+
required: true,
|
|
175
|
+
description: 'Your Snowflake login name. Shown in the profile section (top-left of the console) or under **Admin → Users & Roles → Users**.',
|
|
176
|
+
}),
|
|
177
|
+
password: qadams_framework_1.QadamAuth.SecretText({
|
|
178
|
+
displayName: 'Password',
|
|
179
|
+
description: 'Your Snowflake password *(Option A)*. Leave blank if you are using a Private Key.',
|
|
180
|
+
required: false,
|
|
181
|
+
}),
|
|
182
|
+
privateKey: qadams_framework_1.QadamAuth.SecretText({
|
|
183
|
+
displayName: 'Private Key',
|
|
184
|
+
description: 'RSA private key in PEM format *(Option B)*. Paste the full contents of your `.p8` file, including the `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines. Leave blank if you are using a Password.',
|
|
185
|
+
required: false,
|
|
186
|
+
}),
|
|
187
|
+
privateKeyPassphrase: qadams_framework_1.QadamAuth.SecretText({
|
|
188
|
+
displayName: 'Private Key Passphrase',
|
|
189
|
+
description: 'Passphrase for the private key. Only required if you generated an **encrypted** key pair.',
|
|
190
|
+
required: false,
|
|
191
|
+
}),
|
|
192
|
+
database: qadams_framework_1.Property.ShortText({
|
|
193
|
+
displayName: 'Default Database',
|
|
194
|
+
description: 'Optional. Default database for queries. Find names under **Data → Databases**.',
|
|
195
|
+
required: false,
|
|
196
|
+
}),
|
|
197
|
+
role: qadams_framework_1.Property.ShortText({
|
|
198
|
+
displayName: 'Default Role',
|
|
199
|
+
description: 'Optional. Default security role. Find names under **Admin → Users & Roles → Roles**.',
|
|
200
|
+
required: false,
|
|
201
|
+
}),
|
|
202
|
+
warehouse: qadams_framework_1.Property.ShortText({
|
|
203
|
+
displayName: 'Default Warehouse',
|
|
204
|
+
description: 'Optional. Default virtual warehouse. Find names under **Admin → Warehouses**.',
|
|
205
|
+
required: false,
|
|
206
|
+
}),
|
|
207
|
+
},
|
|
208
|
+
required: true,
|
|
209
|
+
validate: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth }) {
|
|
210
|
+
if (!auth.password && !auth.privateKey) {
|
|
211
|
+
return {
|
|
212
|
+
valid: false,
|
|
213
|
+
error: 'Either Password or Private Key must be provided.',
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
const connectionOptions = {
|
|
218
|
+
account: auth.account,
|
|
219
|
+
username: auth.username,
|
|
220
|
+
database: auth.database,
|
|
221
|
+
warehouse: auth.warehouse,
|
|
222
|
+
role: auth.role,
|
|
223
|
+
application: 'ActivePieces',
|
|
224
|
+
};
|
|
225
|
+
if (auth.privateKey) {
|
|
226
|
+
connectionOptions.authenticator = 'SNOWFLAKE_JWT';
|
|
227
|
+
connectionOptions.privateKey = formatPrivateKey(auth.privateKey);
|
|
228
|
+
if (auth.privateKeyPassphrase) {
|
|
229
|
+
connectionOptions.privateKeyPass = auth.privateKeyPassphrase;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
connectionOptions.password = auth.password;
|
|
234
|
+
}
|
|
235
|
+
const conn = snowflake_sdk_1.default.createConnection(connectionOptions);
|
|
236
|
+
yield connectAsync(conn);
|
|
237
|
+
yield destroyAsync(conn);
|
|
238
|
+
return { valid: true };
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
return { valid: false, error: e.message };
|
|
242
|
+
}
|
|
243
|
+
}),
|
|
244
|
+
});
|
|
245
|
+
exports.snowflakeAuth = [exports.snowflakeOAuth2Auth, exports.snowflakeCustomAuth];
|
|
246
|
+
//# sourceMappingURL=auth.js.map
|