@foxtware/mineral 0.1.36 → 0.1.38

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.
Files changed (38) hide show
  1. package/.creds.yml.sample +9 -0
  2. package/api/marketingcloud/docs.md +6 -0
  3. package/api/marketingcloud/marketingcloud.constants.js +5 -0
  4. package/api/marketingcloud/marketingcloud.utils.js +67 -0
  5. package/api/marketingcloud/marketingcloudAttributesSearch.js +87 -0
  6. package/api/marketingcloud/marketingcloudAuthGet.js +111 -0
  7. package/api/marketingcloud/marketingcloudContactGet.js +79 -0
  8. package/api/marketingcloud/marketingcloudContactSearch.js +87 -0
  9. package/api/marketingcloud/marketingcloudSmsSubscriptionsGet.js +79 -0
  10. package/api/peoplevox/peoplevoxItemEdit.js +59 -22
  11. package/api/peoplevox/peoplevoxOrderEdit.js +49 -25
  12. package/api/shopify/shopifyInventoryItemUpdate.js +22 -16
  13. package/api/shopify/shopifyInventoryItemsUpdateBulk.js +79 -0
  14. package/api/shopify/shopifyMetafieldsSetBulk.js +87 -0
  15. package/api/shopify/shopifyProductGet.js +1 -0
  16. package/api/shopify/shopifyProductUpdate.js +136 -0
  17. package/api/shopify/shopifyProductUpdateTrigger.js +96 -0
  18. package/api/snowflake/docs.md +8 -2
  19. package/api/snowflake/snowflake.constants.js +19 -0
  20. package/api/snowflake/snowflake.utils.js +326 -0
  21. package/api/snowflake/snowflakeAuthGet.js +73 -0
  22. package/api/snowflake/snowflakeDatabasesGet.js +62 -0
  23. package/api/snowflake/snowflakeDynamicTablesGet.js +72 -0
  24. package/api/snowflake/snowflakeEventTablesGet.js +72 -0
  25. package/api/snowflake/snowflakeGet.js +153 -0
  26. package/api/snowflake/snowflakeIntegrationsGet.js +59 -0
  27. package/api/snowflake/snowflakeQuery.js +227 -0
  28. package/api/snowflake/snowflakeSchemasGet.js +69 -0
  29. package/api/snowflake/snowflakeStatementCancel.js +75 -0
  30. package/api/snowflake/snowflakeStatementExecute.js +105 -0
  31. package/api/snowflake/snowflakeStatementGet.js +80 -0
  32. package/api/snowflake/snowflakeTablesGet.js +72 -0
  33. package/api/snowflake/snowflakeUsersGet.js +60 -0
  34. package/api/snowflake/snowflakeWarehousesGet.js +43 -0
  35. package/api/starshipit/starshipitProductUpdate.js +1 -1
  36. package/api/starshipit/starshipitProductsGet.js +13 -6
  37. package/api/utils.js +62 -3
  38. package/package.json +1 -1
@@ -0,0 +1,326 @@
1
+ const crypto = require('crypto');
2
+
3
+ const {
4
+ JWT_LIFETIME_SECONDS,
5
+ } = require('../snowflake/snowflake.constants');
6
+ const { resolveCreds } = require('../pipelineSteps');
7
+ const {
8
+ FetchClient,
9
+ appendUrlToBase,
10
+ fetchClientCommonSteps,
11
+ customFetch,
12
+ } = require('../utils');
13
+
14
+ const jwtCache = new Map();
15
+ const oauthAccessTokenCache = new Map();
16
+
17
+ const base64Url = (input) => {
18
+ const buf = Buffer.isBuffer(input) ? input : Buffer.from(input);
19
+ return buf
20
+ .toString('base64')
21
+ .replace(/=/g, '')
22
+ .replace(/\+/g, '-')
23
+ .replace(/\//g, '_');
24
+ };
25
+
26
+ const normalizeAccountForJwt = (account) => {
27
+ return String(account || '')
28
+ .trim()
29
+ .replace(/\./g, '-')
30
+ .toUpperCase();
31
+ };
32
+
33
+ const loadPrivateKeyObject = (privateKeyPem, passphrase) => {
34
+ const keyInput = {
35
+ key: privateKeyPem,
36
+ format: 'pem',
37
+ };
38
+ if (passphrase) {
39
+ keyInput.passphrase = passphrase;
40
+ }
41
+ return crypto.createPrivateKey(keyInput);
42
+ };
43
+
44
+ const publicKeyFingerprint = (privateKeyObject) => {
45
+ const publicKeyDer = crypto
46
+ .createPublicKey(privateKeyObject)
47
+ .export({ type: 'spki', format: 'der' });
48
+ const hash = crypto.createHash('sha256').update(publicKeyDer).digest('base64');
49
+ return `SHA256:${ hash }`;
50
+ };
51
+
52
+ const signJwtRs256 = (payload, privateKeyObject) => {
53
+ const header = { alg: 'RS256', typ: 'JWT' };
54
+ const encodedHeader = base64Url(JSON.stringify(header));
55
+ const encodedPayload = base64Url(JSON.stringify(payload));
56
+ const data = `${ encodedHeader }.${ encodedPayload }`;
57
+ const signature = crypto.sign('RSA-SHA256', Buffer.from(data), privateKeyObject);
58
+ return `${ data }.${ base64Url(signature) }`;
59
+ };
60
+
61
+ const generateKeyPairJwt = ({
62
+ ACCOUNT,
63
+ USER,
64
+ PRIVATE_KEY,
65
+ PRIVATE_KEY_PASSPHRASE,
66
+ PUBLIC_KEY_FP,
67
+ }) => {
68
+ const privateKeyObject = loadPrivateKeyObject(
69
+ PRIVATE_KEY,
70
+ PRIVATE_KEY_PASSPHRASE,
71
+ );
72
+ const fingerprint = PUBLIC_KEY_FP || publicKeyFingerprint(privateKeyObject);
73
+ const account = normalizeAccountForJwt(ACCOUNT);
74
+ const user = String(USER || '').toUpperCase();
75
+ const qualifiedUsername = `${ account }.${ user }`;
76
+ const nowSeconds = Math.floor(Date.now() / 1000);
77
+
78
+ const payload = {
79
+ iss: `${ qualifiedUsername }.${ fingerprint }`,
80
+ sub: qualifiedUsername,
81
+ iat: nowSeconds,
82
+ exp: nowSeconds + JWT_LIFETIME_SECONDS,
83
+ };
84
+
85
+ return signJwtRs256(payload, privateKeyObject);
86
+ };
87
+
88
+ const accountBaseUrl = (accountOrBase) => {
89
+ const raw = String(accountOrBase || '').trim();
90
+ if (/^https?:\/\//i.test(raw)) {
91
+ return raw.replace(/\/$/, '');
92
+ }
93
+ const host = raw
94
+ .replace(/\.snowflakecomputing\.com.*$/i, '');
95
+ return `https://${ host }.snowflakecomputing.com`;
96
+ };
97
+
98
+ const formEncode = (obj) => {
99
+ const search = new URLSearchParams();
100
+ for (const [key, value] of Object.entries(obj)) {
101
+ if (value === undefined || value === null) {
102
+ continue;
103
+ }
104
+ search.append(key, value);
105
+ }
106
+ return search.toString();
107
+ };
108
+
109
+ const mintOauthAccessToken = async (creds) => {
110
+ const {
111
+ ACCOUNT,
112
+ BASE_URL,
113
+ CLIENT_ID,
114
+ CLIENT_SECRET,
115
+ REFRESH_TOKEN,
116
+ AUTH_CODE,
117
+ REDIRECT_URI = 'http://localhost',
118
+ } = creds;
119
+
120
+ if (!CLIENT_ID || !CLIENT_SECRET) {
121
+ throw new Error('snowflake OAuth requires CLIENT_ID and CLIENT_SECRET');
122
+ }
123
+
124
+ const baseUrl = accountBaseUrl(BASE_URL || ACCOUNT);
125
+ const basic = Buffer
126
+ .from(`${ CLIENT_ID }:${ CLIENT_SECRET }`)
127
+ .toString('base64');
128
+
129
+ let body;
130
+ if (REFRESH_TOKEN) {
131
+ body = formEncode({
132
+ grant_type: 'refresh_token',
133
+ refresh_token: REFRESH_TOKEN,
134
+ });
135
+ } else if (AUTH_CODE) {
136
+ body = formEncode({
137
+ grant_type: 'authorization_code',
138
+ code: AUTH_CODE,
139
+ redirect_uri: REDIRECT_URI,
140
+ });
141
+ } else {
142
+ throw new Error(
143
+ 'snowflake OAuth requires REFRESH_TOKEN or AUTH_CODE alongside CLIENT_ID/SECRET',
144
+ );
145
+ }
146
+
147
+ const response = await customFetch(
148
+ `${ baseUrl }/oauth/token-request`,
149
+ {
150
+ method: 'post',
151
+ headers: {
152
+ Authorization: `Basic ${ basic }`,
153
+ 'Content-Type': 'application/x-www-form-urlencoded',
154
+ },
155
+ body,
156
+ },
157
+ );
158
+
159
+ if (!response.ok) {
160
+ throw new Error(
161
+ `Snowflake OAuth token request failed: ${ JSON.stringify(response.error ?? response.data) }`,
162
+ );
163
+ }
164
+
165
+ const {
166
+ access_token: accessToken,
167
+ expires_in: expiresIn = 600,
168
+ refresh_token: newRefreshToken,
169
+ } = response.data ?? {};
170
+
171
+ if (!accessToken) {
172
+ throw new Error('Snowflake OAuth response missing access_token');
173
+ }
174
+
175
+ return {
176
+ accessToken,
177
+ expiresIn,
178
+ refreshToken: newRefreshToken,
179
+ };
180
+ };
181
+
182
+ const resolveSnowflakeAuth = async (creds) => {
183
+ if (creds?.ACCESS_TOKEN) {
184
+ return {
185
+ token: creds.ACCESS_TOKEN,
186
+ tokenType: creds.TOKEN_TYPE || 'OAUTH',
187
+ };
188
+ }
189
+
190
+ if (creds?.PRIVATE_KEY && creds?.ACCOUNT && creds?.USER) {
191
+ const cacheKey = [
192
+ creds.ACCOUNT,
193
+ creds.USER,
194
+ crypto.createHash('sha256').update(creds.PRIVATE_KEY).digest('hex').slice(0, 16),
195
+ ].join('::');
196
+
197
+ const cached = jwtCache.get(cacheKey);
198
+ if (cached && cached.expiresAt > Date.now() + 120_000) {
199
+ return {
200
+ token: cached.token,
201
+ tokenType: 'KEYPAIR_JWT',
202
+ };
203
+ }
204
+
205
+ const token = generateKeyPairJwt(creds);
206
+ jwtCache.set(cacheKey, {
207
+ token,
208
+ expiresAt: Date.now() + JWT_LIFETIME_SECONDS * 1000,
209
+ });
210
+
211
+ return {
212
+ token,
213
+ tokenType: 'KEYPAIR_JWT',
214
+ };
215
+ }
216
+
217
+ // OAuth client credentials-style refresh (no Upstash; in-process cache only)
218
+ if (creds?.CLIENT_ID && creds?.CLIENT_SECRET && (creds?.REFRESH_TOKEN || creds?.AUTH_CODE)) {
219
+ const cacheKey = `${ creds.CLIENT_ID }::${ creds.ACCOUNT || creds.BASE_URL || '' }`;
220
+ const cached = oauthAccessTokenCache.get(cacheKey);
221
+ if (cached && cached.expiresAt > Date.now() + 30_000) {
222
+ return {
223
+ token: cached.token,
224
+ tokenType: 'OAUTH',
225
+ };
226
+ }
227
+
228
+ const minted = await mintOauthAccessToken(creds);
229
+ oauthAccessTokenCache.set(cacheKey, {
230
+ token: minted.accessToken,
231
+ expiresAt: Date.now() + (minted.expiresIn - 30) * 1000,
232
+ });
233
+
234
+ return {
235
+ token: minted.accessToken,
236
+ tokenType: 'OAUTH',
237
+ };
238
+ }
239
+
240
+ throw new Error(
241
+ 'snowflake creds require ACCESS_TOKEN, or ACCOUNT + USER + PRIVATE_KEY, or CLIENT_ID + CLIENT_SECRET + REFRESH_TOKEN|AUTH_CODE',
242
+ );
243
+ };
244
+
245
+ const useUrlAndAuthHeaders = async (state) => {
246
+ const { requestPayload, context } = state;
247
+ const { creds } = context;
248
+
249
+ const { token, tokenType } = await resolveSnowflakeAuth(creds);
250
+ const baseUrl = accountBaseUrl(creds.BASE_URL || creds.ACCOUNT);
251
+
252
+ return {
253
+ requestPayload: {
254
+ ...requestPayload,
255
+ url: appendUrlToBase(baseUrl, requestPayload.url),
256
+ headers: {
257
+ Authorization: `Bearer ${ token }`,
258
+ 'X-Snowflake-Authorization-Token-Type': tokenType,
259
+ Accept: 'application/json',
260
+ 'User-Agent': 'mineral/snowflake',
261
+ ...requestPayload.headers,
262
+ },
263
+ },
264
+ };
265
+ };
266
+
267
+ const snowflakeClient = new FetchClient({
268
+ pipeline: [
269
+ resolveCreds,
270
+ useUrlAndAuthHeaders,
271
+ 'fetch',
272
+ fetchClientCommonSteps.exitEarlyOnNotOk,
273
+ ],
274
+ });
275
+
276
+ const mapRows = (resultSet) => {
277
+ const columns = resultSet?.resultSetMetaData?.rowType ?? [];
278
+ const data = resultSet?.data ?? [];
279
+
280
+ if (!columns.length) {
281
+ return data;
282
+ }
283
+
284
+ const names = columns.map((col) => col.name);
285
+ return data.map((row) => {
286
+ const obj = {};
287
+ for (let i = 0; i < names.length; i += 1) {
288
+ obj[names[i]] = row[i] ?? null;
289
+ }
290
+ return obj;
291
+ });
292
+ };
293
+
294
+ const sessionContextFromCreds = (creds = {}, overrides = {}) => {
295
+ const {
296
+ WAREHOUSE,
297
+ DATABASE,
298
+ SCHEMA,
299
+ ROLE,
300
+ } = creds;
301
+
302
+ return {
303
+ ...(WAREHOUSE || overrides.warehouse ? {
304
+ warehouse: overrides.warehouse ?? WAREHOUSE,
305
+ } : {}),
306
+ ...(DATABASE || overrides.database ? {
307
+ database: overrides.database ?? DATABASE,
308
+ } : {}),
309
+ ...(SCHEMA || overrides.schema ? {
310
+ schema: overrides.schema ?? SCHEMA,
311
+ } : {}),
312
+ ...(ROLE || overrides.role ? {
313
+ role: overrides.role ?? ROLE,
314
+ } : {}),
315
+ };
316
+ };
317
+
318
+ module.exports = {
319
+ snowflakeClient,
320
+ resolveSnowflakeAuth,
321
+ generateKeyPairJwt,
322
+ mintOauthAccessToken,
323
+ mapRows,
324
+ sessionContextFromCreds,
325
+ accountBaseUrl,
326
+ };
@@ -0,0 +1,73 @@
1
+ // https://docs.snowflake.com/en/user-guide/oauth-custom
2
+ // Mint or return an access token. Prefer ACCESS_TOKEN in creds for steady-state;
3
+ // use CLIENT_ID + CLIENT_SECRET + REFRESH_TOKEN|AUTH_CODE to mint.
4
+
5
+ const { ArgsWarden, logDeep } = require('../utils');
6
+ const { credsValidator } = require('../validators');
7
+ const {
8
+ resolveSnowflakeAuth,
9
+ mintOauthAccessToken,
10
+ } = require('../snowflake/snowflake.utils');
11
+ const { credsFromPayload } = require('../utils');
12
+
13
+ const argsWarden = new ArgsWarden([
14
+ ['credsPayload', credsValidator],
15
+ ]);
16
+
17
+ const snowflakeAuthGet = async (
18
+ credsPayload,
19
+ {
20
+ forceRefresh = false,
21
+ } = {},
22
+ ) => {
23
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
24
+ credsPayload,
25
+ });
26
+ if (rejectResponse) {
27
+ return rejectResponse;
28
+ }
29
+
30
+ try {
31
+ const creds = await credsFromPayload(credsPayload);
32
+
33
+ if (forceRefresh && creds.CLIENT_ID && creds.CLIENT_SECRET) {
34
+ const minted = await mintOauthAccessToken(creds);
35
+ return {
36
+ ok: true,
37
+ data: {
38
+ accessToken: minted.accessToken,
39
+ expiresIn: minted.expiresIn,
40
+ ...(minted.refreshToken ? { refreshToken: minted.refreshToken } : {}),
41
+ },
42
+ };
43
+ }
44
+
45
+ const { token, tokenType } = await resolveSnowflakeAuth(creds);
46
+ return {
47
+ ok: true,
48
+ data: {
49
+ accessToken: token,
50
+ tokenType,
51
+ },
52
+ };
53
+ } catch (error) {
54
+ logDeep({ error });
55
+ return {
56
+ ok: false,
57
+ error: {
58
+ code: 'AUTH_FAILED',
59
+ message: error?.message || 'Failed to resolve Snowflake access token',
60
+ details: error,
61
+ },
62
+ };
63
+ }
64
+ };
65
+
66
+ const funcApiConfig = {
67
+ argsWarden,
68
+ };
69
+
70
+ module.exports = {
71
+ snowflakeAuthGet,
72
+ funcApiConfig,
73
+ };
@@ -0,0 +1,62 @@
1
+ // https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference/database
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const {
6
+ snowflakeGet,
7
+ snowflakeGetter,
8
+ } = require('../snowflake/snowflakeGet');
9
+ const {
10
+ REST_API_VERSION,
11
+ DEFAULT_SHOW_LIMIT,
12
+ } = require('../snowflake/snowflake.constants');
13
+
14
+ const argsWarden = new ArgsWarden([
15
+ ['credsPayload', credsValidator],
16
+ ]);
17
+
18
+ const snowflakeDatabasesGetImpl = async (
19
+ returnGetter,
20
+ credsPayload,
21
+ {
22
+ like,
23
+ startsWith,
24
+ history,
25
+ showLimit = DEFAULT_SHOW_LIMIT,
26
+ fromName,
27
+ apiVersion = REST_API_VERSION,
28
+ fetchClient,
29
+ ...getterOptions
30
+ } = {},
31
+ ) => {
32
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
33
+ credsPayload,
34
+ });
35
+ if (rejectResponse) {
36
+ return rejectResponse;
37
+ }
38
+
39
+ const method = returnGetter ? snowflakeGetter : snowflakeGet;
40
+
41
+ return method(credsPayload, `/api/${ apiVersion }/databases`, {
42
+ params: {
43
+ ...(like !== undefined && { like }),
44
+ ...(startsWith !== undefined && { startsWith }),
45
+ ...(history !== undefined && { history }),
46
+ ...(fromName !== undefined && { fromName }),
47
+ },
48
+ showLimit,
49
+ fetchClient,
50
+ ...getterOptions,
51
+ });
52
+ };
53
+
54
+ const funcApiConfig = {
55
+ argsWarden,
56
+ };
57
+
58
+ module.exports = {
59
+ snowflakeDatabasesGet: (...args) => snowflakeDatabasesGetImpl(false, ...args),
60
+ snowflakeDatabasesGetter: (...args) => snowflakeDatabasesGetImpl(true, ...args),
61
+ funcApiConfig,
62
+ };
@@ -0,0 +1,72 @@
1
+ // https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference/dynamic-table
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const {
6
+ snowflakeGet,
7
+ snowflakeGetter,
8
+ } = require('../snowflake/snowflakeGet');
9
+ const {
10
+ REST_API_VERSION,
11
+ DEFAULT_SHOW_LIMIT,
12
+ } = require('../snowflake/snowflake.constants');
13
+
14
+ const argsWarden = new ArgsWarden([
15
+ ['credsPayload', credsValidator],
16
+ ['databaseName'],
17
+ ['schemaName'],
18
+ ]);
19
+
20
+ const snowflakeDynamicTablesGetImpl = async (
21
+ returnGetter,
22
+ credsPayload,
23
+ databaseName,
24
+ schemaName,
25
+ {
26
+ like,
27
+ startsWith,
28
+ history,
29
+ showLimit = DEFAULT_SHOW_LIMIT,
30
+ fromName,
31
+ apiVersion = REST_API_VERSION,
32
+ fetchClient,
33
+ ...getterOptions
34
+ } = {},
35
+ ) => {
36
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
37
+ credsPayload,
38
+ databaseName,
39
+ schemaName,
40
+ });
41
+ if (rejectResponse) {
42
+ return rejectResponse;
43
+ }
44
+
45
+ const method = returnGetter ? snowflakeGetter : snowflakeGet;
46
+
47
+ return method(
48
+ credsPayload,
49
+ `/api/${ apiVersion }/databases/${ databaseName }/schemas/${ schemaName }/dynamic-tables`,
50
+ {
51
+ params: {
52
+ ...(like !== undefined && { like }),
53
+ ...(startsWith !== undefined && { startsWith }),
54
+ ...(history !== undefined && { history }),
55
+ ...(fromName !== undefined && { fromName }),
56
+ },
57
+ showLimit,
58
+ fetchClient,
59
+ ...getterOptions,
60
+ },
61
+ );
62
+ };
63
+
64
+ const funcApiConfig = {
65
+ argsWarden,
66
+ };
67
+
68
+ module.exports = {
69
+ snowflakeDynamicTablesGet: (...args) => snowflakeDynamicTablesGetImpl(false, ...args),
70
+ snowflakeDynamicTablesGetter: (...args) => snowflakeDynamicTablesGetImpl(true, ...args),
71
+ funcApiConfig,
72
+ };
@@ -0,0 +1,72 @@
1
+ // https://docs.snowflake.com/en/developer-guide/snowflake-rest-api/reference/event-table
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const {
6
+ snowflakeGet,
7
+ snowflakeGetter,
8
+ } = require('../snowflake/snowflakeGet');
9
+ const {
10
+ REST_API_VERSION,
11
+ DEFAULT_SHOW_LIMIT,
12
+ } = require('../snowflake/snowflake.constants');
13
+
14
+ const argsWarden = new ArgsWarden([
15
+ ['credsPayload', credsValidator],
16
+ ['databaseName'],
17
+ ['schemaName'],
18
+ ]);
19
+
20
+ const snowflakeEventTablesGetImpl = async (
21
+ returnGetter,
22
+ credsPayload,
23
+ databaseName,
24
+ schemaName,
25
+ {
26
+ like,
27
+ startsWith,
28
+ history,
29
+ showLimit = DEFAULT_SHOW_LIMIT,
30
+ fromName,
31
+ apiVersion = REST_API_VERSION,
32
+ fetchClient,
33
+ ...getterOptions
34
+ } = {},
35
+ ) => {
36
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
37
+ credsPayload,
38
+ databaseName,
39
+ schemaName,
40
+ });
41
+ if (rejectResponse) {
42
+ return rejectResponse;
43
+ }
44
+
45
+ const method = returnGetter ? snowflakeGetter : snowflakeGet;
46
+
47
+ return method(
48
+ credsPayload,
49
+ `/api/${ apiVersion }/databases/${ databaseName }/schemas/${ schemaName }/event-tables`,
50
+ {
51
+ params: {
52
+ ...(like !== undefined && { like }),
53
+ ...(startsWith !== undefined && { startsWith }),
54
+ ...(history !== undefined && { history }),
55
+ ...(fromName !== undefined && { fromName }),
56
+ },
57
+ showLimit,
58
+ fetchClient,
59
+ ...getterOptions,
60
+ },
61
+ );
62
+ };
63
+
64
+ const funcApiConfig = {
65
+ argsWarden,
66
+ };
67
+
68
+ module.exports = {
69
+ snowflakeEventTablesGet: (...args) => snowflakeEventTablesGetImpl(false, ...args),
70
+ snowflakeEventTablesGetter: (...args) => snowflakeEventTablesGetImpl(true, ...args),
71
+ funcApiConfig,
72
+ };