@keystrokehq/snowflake 0.0.1
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/README.md +247 -0
- package/dist/_official/index.d.mts +2 -0
- package/dist/_official/index.mjs +3 -0
- package/dist/_runtime/index.d.mts +1 -0
- package/dist/_runtime/index.mjs +1 -0
- package/dist/accounts.d.mts +40 -0
- package/dist/accounts.mjs +51 -0
- package/dist/bulk.d.mts +71 -0
- package/dist/bulk.mjs +65 -0
- package/dist/catalog.d.mts +144 -0
- package/dist/catalog.mjs +158 -0
- package/dist/client.d.mts +44 -0
- package/dist/client.mjs +273 -0
- package/dist/common-BnKTPQXc.mjs +92 -0
- package/dist/connection.d.mts +2 -0
- package/dist/connection.mjs +3 -0
- package/dist/databases.d.mts +2 -0
- package/dist/databases.mjs +3 -0
- package/dist/errors-DKnc9o_a.mjs +95 -0
- package/dist/events.d.mts +382 -0
- package/dist/events.mjs +291 -0
- package/dist/file-formats.d.mts +39 -0
- package/dist/file-formats.mjs +48 -0
- package/dist/functions.d.mts +53 -0
- package/dist/functions.mjs +56 -0
- package/dist/grants.d.mts +93 -0
- package/dist/grants.mjs +102 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/integration-CCWMSTlO.d.mts +170 -0
- package/dist/integration-Dptv8L0L.mjs +207 -0
- package/dist/org-admin.d.mts +80 -0
- package/dist/org-admin.mjs +79 -0
- package/dist/pipes.d.mts +119 -0
- package/dist/pipes.mjs +106 -0
- package/dist/procedures.d.mts +61 -0
- package/dist/procedures.mjs +79 -0
- package/dist/results.d.mts +16 -0
- package/dist/results.mjs +64 -0
- package/dist/retry-0hMfb8cC.mjs +164 -0
- package/dist/retry-w7cTp1QL.d.mts +10 -0
- package/dist/roles.d.mts +60 -0
- package/dist/roles.mjs +74 -0
- package/dist/rows.d.mts +106 -0
- package/dist/rows.mjs +223 -0
- package/dist/schemas/index.d.mts +2 -0
- package/dist/schemas/index.mjs +4 -0
- package/dist/schemas-catalog.d.mts +2 -0
- package/dist/schemas-catalog.mjs +3 -0
- package/dist/shares.d.mts +56 -0
- package/dist/shares.mjs +77 -0
- package/dist/sql-options-2k5xQ-oS.d.mts +32 -0
- package/dist/sql-options-DI-OmLU6.mjs +79 -0
- package/dist/sql-safety-CywdR3EP.mjs +56 -0
- package/dist/sql.d.mts +84 -0
- package/dist/sql.mjs +209 -0
- package/dist/stages.d.mts +64 -0
- package/dist/stages.mjs +81 -0
- package/dist/statements-B2ThF_4b.mjs +81 -0
- package/dist/statements-DJL0qVNA.d.mts +238 -0
- package/dist/status-page.d.mts +510 -0
- package/dist/status-page.mjs +261 -0
- package/dist/streaming.d.mts +70 -0
- package/dist/streaming.mjs +56 -0
- package/dist/streams.d.mts +71 -0
- package/dist/streams.mjs +78 -0
- package/dist/tables.d.mts +2 -0
- package/dist/tables.mjs +3 -0
- package/dist/tasks.d.mts +79 -0
- package/dist/tasks.mjs +104 -0
- package/dist/triggers.d.mts +578 -0
- package/dist/triggers.mjs +1363 -0
- package/dist/users.d.mts +61 -0
- package/dist/users.mjs +67 -0
- package/dist/verification.d.mts +201 -0
- package/dist/verification.mjs +512 -0
- package/dist/views.d.mts +2 -0
- package/dist/views.mjs +3 -0
- package/dist/warehouses.d.mts +68 -0
- package/dist/warehouses.mjs +101 -0
- package/package.json +190 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { defineOfficialIntegration } from "@keystrokehq/integration-authoring/official";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { CredentialSet } from "@keystrokehq/core";
|
|
4
|
+
|
|
5
|
+
//#region src/webhook-credentials.ts
|
|
6
|
+
/**
|
|
7
|
+
* Webhook credential sets for the Snowflake auto-ingest triggers.
|
|
8
|
+
*
|
|
9
|
+
* Snowflake has no native webhook product — auto-ingest relies on
|
|
10
|
+
* cloud-provider event buses (AWS SNS, GCP Pub/Sub, Azure Event Grid)
|
|
11
|
+
* that forward object-storage notifications to a public endpoint.
|
|
12
|
+
* Each cloud has a different trust model, so we ship one credential
|
|
13
|
+
* set per cloud rather than a single generic "auto-ingest" set.
|
|
14
|
+
*
|
|
15
|
+
* These credentials hold only the verification material the webhook
|
|
16
|
+
* receiver needs — the cloud provider itself controls who can publish
|
|
17
|
+
* to the topic/queue/event-grid. All auth fields are strings to keep
|
|
18
|
+
* them CredentialSet-compatible (auth shapes are Zod objects without
|
|
19
|
+
* unions/optionals-at-root).
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* AWS SNS webhook credentials.
|
|
23
|
+
*
|
|
24
|
+
* SNS verifies message authenticity via an X.509 signature whose public
|
|
25
|
+
* cert is published at an SNS-hosted URL. The only real secret is the
|
|
26
|
+
* optional {@link expectedTopicArn}: tight-scoping to a single topic
|
|
27
|
+
* prevents an attacker that fooled SNS signing (not possible absent a
|
|
28
|
+
* certificate compromise) from posting events from an unrelated topic.
|
|
29
|
+
*/
|
|
30
|
+
const snowflakeS3SnsWebhookCredentialSet = new CredentialSet({
|
|
31
|
+
id: "snowflake-s3-sns-webhook",
|
|
32
|
+
exposure: "platform-only",
|
|
33
|
+
name: "Snowflake Auto-Ingest — AWS SNS",
|
|
34
|
+
auth: z.object({
|
|
35
|
+
expectedTopicArn: z.string().optional(),
|
|
36
|
+
allowedSigningCertHostPattern: z.string().default("^sns\\.[a-z0-9-]+\\.amazonaws\\.com(\\.cn)?$").optional(),
|
|
37
|
+
autoConfirmSubscriptions: z.enum(["true", "false"]).default("false").optional()
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* GCP Pub/Sub push subscriptions sign each request with a Google-minted
|
|
42
|
+
* OIDC JWT (RS256) in the `Authorization` header. Verification requires
|
|
43
|
+
* knowing:
|
|
44
|
+
*
|
|
45
|
+
* - `expectedAudience`: the OIDC audience configured on the push
|
|
46
|
+
* subscription (commonly the webhook URL itself).
|
|
47
|
+
* - `expectedServiceAccount`: the push subscription's service-account
|
|
48
|
+
* email, which appears as the JWT `email` claim.
|
|
49
|
+
*
|
|
50
|
+
* Both are public identifiers, but pinning them prevents an attacker
|
|
51
|
+
* with any valid Google OIDC token from impersonating the subscription.
|
|
52
|
+
*/
|
|
53
|
+
const snowflakeGcsPubSubWebhookCredentialSet = new CredentialSet({
|
|
54
|
+
id: "snowflake-gcs-pubsub-webhook",
|
|
55
|
+
exposure: "platform-only",
|
|
56
|
+
name: "Snowflake Auto-Ingest — GCS Pub/Sub",
|
|
57
|
+
auth: z.object({
|
|
58
|
+
expectedAudience: z.string().min(1),
|
|
59
|
+
expectedServiceAccount: z.string().min(1),
|
|
60
|
+
jwksUri: z.string().default("https://www.googleapis.com/oauth2/v3/certs").optional(),
|
|
61
|
+
issuer: z.string().default("https://accounts.google.com").optional()
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Azure Event Grid authenticates webhook endpoints via one-time
|
|
66
|
+
* handshake validation (validation code or URL) rather than per-request
|
|
67
|
+
* signatures. If the operator wires a **shared secret** into the
|
|
68
|
+
* Event Grid subscription as a custom header, that secret can be
|
|
69
|
+
* checked here as a defence-in-depth measure.
|
|
70
|
+
*
|
|
71
|
+
* Event Grid's synchronous handshake (`SubscriptionValidationEvent`) is
|
|
72
|
+
* not fulfillable through the Keystroke static-response webhook
|
|
73
|
+
* primitive; Snowflake operators should use **manual handshake** or
|
|
74
|
+
* Cloud-Events schema. See `IMPLEMENTATION_NOTES.md` § trigger webhooks.
|
|
75
|
+
*/
|
|
76
|
+
const snowflakeAzureEventGridWebhookCredentialSet = new CredentialSet({
|
|
77
|
+
id: "snowflake-azure-eventgrid-webhook",
|
|
78
|
+
exposure: "platform-only",
|
|
79
|
+
name: "Snowflake Auto-Ingest — Azure Event Grid",
|
|
80
|
+
auth: z.object({
|
|
81
|
+
sharedSecret: z.string().optional(),
|
|
82
|
+
sharedSecretHeader: z.string().default("aeg-subscription-secret").optional(),
|
|
83
|
+
expectedTopicArn: z.string().optional()
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/integration.ts
|
|
89
|
+
/**
|
|
90
|
+
* Public auth schema for Snowflake connections.
|
|
91
|
+
*
|
|
92
|
+
* Modeled as a discriminated union on `mode`. `connection.kind` is `manual`
|
|
93
|
+
* because Keystroke does not run an interactive Snowflake OAuth dance — OAuth
|
|
94
|
+
* mode accepts a bearer token provided by the caller (external IdP /
|
|
95
|
+
* Snowflake-hosted OAuth). See `IMPLEMENTATION_NOTES.md` § 2 for rationale.
|
|
96
|
+
*/
|
|
97
|
+
const snowflakeAuthModeSchema = z.enum([
|
|
98
|
+
"keypair",
|
|
99
|
+
"oauth",
|
|
100
|
+
"pat",
|
|
101
|
+
"basic"
|
|
102
|
+
]);
|
|
103
|
+
/**
|
|
104
|
+
* Flat Zod object — the official integration contract constrains `auth` to a
|
|
105
|
+
* `ZodObject<ZodRawShape>`, so mode-specific fields are declared as optional
|
|
106
|
+
* and validated via `superRefine` below. Runtime invariants still cover:
|
|
107
|
+
* - keypair → requires SNOWFLAKE_USER + SNOWFLAKE_PRIVATE_KEY
|
|
108
|
+
* - oauth → requires SNOWFLAKE_OAUTH_ACCESS_TOKEN
|
|
109
|
+
* - pat → requires SNOWFLAKE_USER + SNOWFLAKE_PAT
|
|
110
|
+
* - basic → requires SNOWFLAKE_USER + SNOWFLAKE_PASSWORD
|
|
111
|
+
*/
|
|
112
|
+
const baseSnowflakeAuthShape = {
|
|
113
|
+
mode: snowflakeAuthModeSchema,
|
|
114
|
+
SNOWFLAKE_ACCOUNT: z.string().min(1),
|
|
115
|
+
SNOWFLAKE_USER: z.string().min(1).optional(),
|
|
116
|
+
SNOWFLAKE_PRIVATE_KEY: z.string().min(1).optional(),
|
|
117
|
+
SNOWFLAKE_PRIVATE_KEY_PASSPHRASE: z.string().optional(),
|
|
118
|
+
SNOWFLAKE_PAT: z.string().min(1).optional(),
|
|
119
|
+
SNOWFLAKE_PASSWORD: z.string().min(1).optional(),
|
|
120
|
+
SNOWFLAKE_OAUTH_ACCESS_TOKEN: z.string().min(1).optional(),
|
|
121
|
+
SNOWFLAKE_OAUTH_REFRESH_TOKEN: z.string().optional(),
|
|
122
|
+
SNOWFLAKE_OAUTH_CLIENT_ID: z.string().optional(),
|
|
123
|
+
SNOWFLAKE_OAUTH_CLIENT_SECRET: z.string().optional(),
|
|
124
|
+
SNOWFLAKE_OAUTH_TOKEN_URL: z.string().url().optional(),
|
|
125
|
+
SNOWFLAKE_OAUTH_SCOPES: z.string().optional(),
|
|
126
|
+
SNOWFLAKE_ROLE: z.string().optional(),
|
|
127
|
+
SNOWFLAKE_WAREHOUSE: z.string().optional(),
|
|
128
|
+
SNOWFLAKE_DATABASE: z.string().optional(),
|
|
129
|
+
SNOWFLAKE_SCHEMA: z.string().optional(),
|
|
130
|
+
SNOWFLAKE_HOST: z.string().optional(),
|
|
131
|
+
SNOWFLAKE_REGION: z.string().optional(),
|
|
132
|
+
SNOWFLAKE_PUBLIC_KEY_FP: z.string().optional()
|
|
133
|
+
};
|
|
134
|
+
const snowflakeAuthSchema = z.object(baseSnowflakeAuthShape).superRefine((value, ctx) => {
|
|
135
|
+
if (value.mode === "keypair") {
|
|
136
|
+
if (!value.SNOWFLAKE_USER) ctx.addIssue({
|
|
137
|
+
code: z.ZodIssueCode.custom,
|
|
138
|
+
path: ["SNOWFLAKE_USER"],
|
|
139
|
+
message: "SNOWFLAKE_USER is required when mode = \"keypair\""
|
|
140
|
+
});
|
|
141
|
+
if (!value.SNOWFLAKE_PRIVATE_KEY) ctx.addIssue({
|
|
142
|
+
code: z.ZodIssueCode.custom,
|
|
143
|
+
path: ["SNOWFLAKE_PRIVATE_KEY"],
|
|
144
|
+
message: "SNOWFLAKE_PRIVATE_KEY is required when mode = \"keypair\""
|
|
145
|
+
});
|
|
146
|
+
} else if (value.mode === "oauth") {
|
|
147
|
+
if (!value.SNOWFLAKE_OAUTH_ACCESS_TOKEN) ctx.addIssue({
|
|
148
|
+
code: z.ZodIssueCode.custom,
|
|
149
|
+
path: ["SNOWFLAKE_OAUTH_ACCESS_TOKEN"],
|
|
150
|
+
message: "SNOWFLAKE_OAUTH_ACCESS_TOKEN is required when mode = \"oauth\""
|
|
151
|
+
});
|
|
152
|
+
} else if (value.mode === "pat") {
|
|
153
|
+
if (!value.SNOWFLAKE_USER) ctx.addIssue({
|
|
154
|
+
code: z.ZodIssueCode.custom,
|
|
155
|
+
path: ["SNOWFLAKE_USER"],
|
|
156
|
+
message: "SNOWFLAKE_USER is required when mode = \"pat\""
|
|
157
|
+
});
|
|
158
|
+
if (!value.SNOWFLAKE_PAT) ctx.addIssue({
|
|
159
|
+
code: z.ZodIssueCode.custom,
|
|
160
|
+
path: ["SNOWFLAKE_PAT"],
|
|
161
|
+
message: "SNOWFLAKE_PAT is required when mode = \"pat\""
|
|
162
|
+
});
|
|
163
|
+
} else if (value.mode === "basic") {
|
|
164
|
+
if (!value.SNOWFLAKE_USER) ctx.addIssue({
|
|
165
|
+
code: z.ZodIssueCode.custom,
|
|
166
|
+
path: ["SNOWFLAKE_USER"],
|
|
167
|
+
message: "SNOWFLAKE_USER is required when mode = \"basic\""
|
|
168
|
+
});
|
|
169
|
+
if (!value.SNOWFLAKE_PASSWORD) ctx.addIssue({
|
|
170
|
+
code: z.ZodIssueCode.custom,
|
|
171
|
+
path: ["SNOWFLAKE_PASSWORD"],
|
|
172
|
+
message: "SNOWFLAKE_PASSWORD is required when mode = \"basic\""
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
/**
|
|
177
|
+
* `auth` shape used when defining the official integration. Must be a
|
|
178
|
+
* `ZodObject<ZodRawShape>` — refinements are attached for callers via
|
|
179
|
+
* {@link parseSnowflakeCredentials}.
|
|
180
|
+
*/
|
|
181
|
+
const snowflakeAuthObjectSchema = z.object(baseSnowflakeAuthShape);
|
|
182
|
+
const snowflakeOfficialIntegration = {
|
|
183
|
+
id: "snowflake",
|
|
184
|
+
name: "Snowflake",
|
|
185
|
+
description: "Snowflake data cloud: SQL API v2, Snowpipe (file + streaming), warehouses, roles, users, grants, shares, streams, tasks, and administration for Keystroke workflows.",
|
|
186
|
+
auth: snowflakeAuthObjectSchema
|
|
187
|
+
};
|
|
188
|
+
const snowflakeBundle = defineOfficialIntegration({
|
|
189
|
+
...snowflakeOfficialIntegration,
|
|
190
|
+
internal: { other: [
|
|
191
|
+
snowflakeS3SnsWebhookCredentialSet,
|
|
192
|
+
snowflakeGcsPubSubWebhookCredentialSet,
|
|
193
|
+
snowflakeAzureEventGridWebhookCredentialSet
|
|
194
|
+
] }
|
|
195
|
+
});
|
|
196
|
+
const snowflake = snowflakeBundle.credentialSet;
|
|
197
|
+
/**
|
|
198
|
+
* Parse raw credential values through the full refinement pipeline. Callers
|
|
199
|
+
* (client, operations) should use this instead of the raw object schema so
|
|
200
|
+
* mode-specific invariants are enforced.
|
|
201
|
+
*/
|
|
202
|
+
function parseSnowflakeCredentials(input) {
|
|
203
|
+
return snowflakeAuthSchema.parse(input);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
//#endregion
|
|
207
|
+
export { snowflakeBundle as a, snowflakeGcsPubSubWebhookCredentialSet as c, snowflakeAuthSchema as i, snowflakeS3SnsWebhookCredentialSet as l, snowflake as n, snowflakeOfficialIntegration as o, snowflakeAuthModeSchema as r, snowflakeAzureEventGridWebhookCredentialSet as s, parseSnowflakeCredentials as t };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SnowflakeClient } from "./client.mjs";
|
|
2
|
+
import { d as HydratedRow, m as ColumnMeta } from "./statements-DJL0qVNA.mjs";
|
|
3
|
+
import { t as OptionMap } from "./sql-options-2k5xQ-oS.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/org-admin.d.ts
|
|
6
|
+
interface OrgAdminContext {
|
|
7
|
+
readonly warehouse?: string;
|
|
8
|
+
readonly role?: string;
|
|
9
|
+
}
|
|
10
|
+
interface ListOrganizationAccountsOptions extends OrgAdminContext {
|
|
11
|
+
readonly like?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ListOrganizationAccountsResult {
|
|
14
|
+
readonly columns: readonly ColumnMeta[];
|
|
15
|
+
readonly rows: readonly HydratedRow[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* `SHOW ORGANIZATION ACCOUNTS`. Lists every account in the org (ORGADMIN
|
|
19
|
+
* only).
|
|
20
|
+
*/
|
|
21
|
+
declare function listOrganizationAccounts(client: SnowflakeClient, options?: ListOrganizationAccountsOptions): Promise<ListOrganizationAccountsResult>;
|
|
22
|
+
interface CreateOrganizationAccountOptions extends OrgAdminContext {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly adminName: string;
|
|
25
|
+
readonly adminPassword: string;
|
|
26
|
+
readonly email: string;
|
|
27
|
+
/** `STANDARD`, `ENTERPRISE`, `BUSINESS_CRITICAL`, `VPS`. */
|
|
28
|
+
readonly edition: 'STANDARD' | 'ENTERPRISE' | 'BUSINESS_CRITICAL' | 'VPS';
|
|
29
|
+
/** Snowflake region identifier, e.g. `AWS_US_WEST_2`. */
|
|
30
|
+
readonly region?: string;
|
|
31
|
+
readonly regionGroup?: string;
|
|
32
|
+
readonly firstName?: string;
|
|
33
|
+
readonly lastName?: string;
|
|
34
|
+
readonly mustChangePassword?: boolean;
|
|
35
|
+
readonly comment?: string;
|
|
36
|
+
/** Any other `KEY = value` options the org admin wants to forward. */
|
|
37
|
+
readonly options?: OptionMap;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* `CREATE ORGANIZATION ACCOUNT <name>
|
|
41
|
+
* ADMIN_NAME = '...' ADMIN_PASSWORD = '...' EMAIL = '...'
|
|
42
|
+
* EDITION = '...' [REGION = '...'] [REGION_GROUP = '...']
|
|
43
|
+
* [FIRST_NAME = '...'] [LAST_NAME = '...']
|
|
44
|
+
* [MUST_CHANGE_PASSWORD = TRUE|FALSE]
|
|
45
|
+
* [COMMENT = '...']`
|
|
46
|
+
*/
|
|
47
|
+
declare function createOrganizationAccount(client: SnowflakeClient, options: CreateOrganizationAccountOptions): Promise<void>;
|
|
48
|
+
interface AlterAccountOptions extends OrgAdminContext {
|
|
49
|
+
/**
|
|
50
|
+
* Target account name — if omitted, the statement targets the current
|
|
51
|
+
* account (`ALTER ACCOUNT SET ...`). When provided, Snowflake runs it as
|
|
52
|
+
* `ALTER ACCOUNT <name> SET ...` (ORGADMIN scope).
|
|
53
|
+
*/
|
|
54
|
+
readonly name?: string;
|
|
55
|
+
readonly ifExists?: boolean;
|
|
56
|
+
readonly set?: OptionMap;
|
|
57
|
+
readonly unset?: readonly string[];
|
|
58
|
+
readonly setResourceMonitor?: string;
|
|
59
|
+
readonly unsetResourceMonitor?: boolean;
|
|
60
|
+
readonly comment?: string;
|
|
61
|
+
}
|
|
62
|
+
declare function alterAccount(client: SnowflakeClient, options: AlterAccountOptions): Promise<void>;
|
|
63
|
+
interface EnableAccountFeatureOptions extends OrgAdminContext {
|
|
64
|
+
/** Feature parameter name, e.g. `ENABLE_UNREDACTED_QUERY_SYNTAX_ERROR`. */
|
|
65
|
+
readonly feature: string;
|
|
66
|
+
/** When `false`, emits `SET <FEATURE> = FALSE` (i.e., disables it). */
|
|
67
|
+
readonly enabled?: boolean;
|
|
68
|
+
readonly ifExists?: boolean;
|
|
69
|
+
/** Scope the change to a specific account (requires ORGADMIN). */
|
|
70
|
+
readonly name?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generic `ALTER ACCOUNT SET <FEATURE> = TRUE|FALSE` wrapper. Snowflake
|
|
74
|
+
* exposes a growing set of account-level boolean parameters; this helper
|
|
75
|
+
* keeps the pattern uniform for workflow authors without embedding the
|
|
76
|
+
* full (ever-changing) feature catalogue in the package.
|
|
77
|
+
*/
|
|
78
|
+
declare function enableAccountFeature(client: SnowflakeClient, options: EnableAccountFeatureOptions): Promise<void>;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { AlterAccountOptions, CreateOrganizationAccountOptions, EnableAccountFeatureOptions, ListOrganizationAccountsOptions, ListOrganizationAccountsResult, OrgAdminContext, alterAccount, createOrganizationAccount, enableAccountFeature, listOrganizationAccounts };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { executeSql } from "./sql.mjs";
|
|
2
|
+
import { a as quoteLiteral, i as quoteIdentifier, r as likeClause } from "./sql-safety-CywdR3EP.mjs";
|
|
3
|
+
import { t as formatOptions } from "./sql-options-DI-OmLU6.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/org-admin.ts
|
|
6
|
+
/**
|
|
7
|
+
* `SHOW ORGANIZATION ACCOUNTS`. Lists every account in the org (ORGADMIN
|
|
8
|
+
* only).
|
|
9
|
+
*/
|
|
10
|
+
async function listOrganizationAccounts(client, options = {}) {
|
|
11
|
+
const result = await executeSql(client, {
|
|
12
|
+
statement: `SHOW ORGANIZATION ACCOUNTS${likeClause(options.like)}`,
|
|
13
|
+
warehouse: options.warehouse,
|
|
14
|
+
role: options.role
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
columns: result.columns,
|
|
18
|
+
rows: result.rows
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* `CREATE ORGANIZATION ACCOUNT <name>
|
|
23
|
+
* ADMIN_NAME = '...' ADMIN_PASSWORD = '...' EMAIL = '...'
|
|
24
|
+
* EDITION = '...' [REGION = '...'] [REGION_GROUP = '...']
|
|
25
|
+
* [FIRST_NAME = '...'] [LAST_NAME = '...']
|
|
26
|
+
* [MUST_CHANGE_PASSWORD = TRUE|FALSE]
|
|
27
|
+
* [COMMENT = '...']`
|
|
28
|
+
*/
|
|
29
|
+
async function createOrganizationAccount(client, options) {
|
|
30
|
+
const parts = [
|
|
31
|
+
`ADMIN_NAME = ${quoteLiteral(options.adminName)}`,
|
|
32
|
+
`ADMIN_PASSWORD = ${quoteLiteral(options.adminPassword)}`,
|
|
33
|
+
`EMAIL = ${quoteLiteral(options.email)}`,
|
|
34
|
+
`EDITION = ${quoteLiteral(options.edition)}`
|
|
35
|
+
];
|
|
36
|
+
if (options.region) parts.push(`REGION = ${quoteLiteral(options.region)}`);
|
|
37
|
+
if (options.regionGroup) parts.push(`REGION_GROUP = ${quoteLiteral(options.regionGroup)}`);
|
|
38
|
+
if (options.firstName) parts.push(`FIRST_NAME = ${quoteLiteral(options.firstName)}`);
|
|
39
|
+
if (options.lastName) parts.push(`LAST_NAME = ${quoteLiteral(options.lastName)}`);
|
|
40
|
+
if (options.mustChangePassword !== void 0) parts.push(`MUST_CHANGE_PASSWORD = ${options.mustChangePassword ? "TRUE" : "FALSE"}`);
|
|
41
|
+
if (options.comment) parts.push(`COMMENT = ${quoteLiteral(options.comment)}`);
|
|
42
|
+
if (options.options && Object.keys(options.options).length > 0) parts.push(formatOptions(options.options));
|
|
43
|
+
await executeSql(client, {
|
|
44
|
+
statement: `CREATE ORGANIZATION ACCOUNT ${quoteIdentifier(options.name)} ${parts.join(" ")}`,
|
|
45
|
+
warehouse: options.warehouse,
|
|
46
|
+
role: options.role
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async function alterAccount(client, options) {
|
|
50
|
+
let tail;
|
|
51
|
+
if (options.setResourceMonitor !== void 0) tail = `SET RESOURCE_MONITOR = ${quoteIdentifier(options.setResourceMonitor)}`;
|
|
52
|
+
else if (options.unsetResourceMonitor) tail = "UNSET RESOURCE_MONITOR";
|
|
53
|
+
else if (options.set && Object.keys(options.set).length > 0) tail = `SET ${formatOptions(options.set)}`;
|
|
54
|
+
else if (options.unset && options.unset.length > 0) tail = `UNSET ${options.unset.map((k) => k.toUpperCase()).join(", ")}`;
|
|
55
|
+
else if (options.comment !== void 0) tail = `SET COMMENT = ${quoteLiteral(options.comment)}`;
|
|
56
|
+
else throw new Error("alterAccount requires one of: set / unset / setResourceMonitor / unsetResourceMonitor / comment");
|
|
57
|
+
await executeSql(client, {
|
|
58
|
+
statement: `ALTER ACCOUNT${options.ifExists ? " IF EXISTS" : ""}${options.name ? ` ${quoteIdentifier(options.name)}` : ""} ${tail}`,
|
|
59
|
+
warehouse: options.warehouse,
|
|
60
|
+
role: options.role
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Generic `ALTER ACCOUNT SET <FEATURE> = TRUE|FALSE` wrapper. Snowflake
|
|
65
|
+
* exposes a growing set of account-level boolean parameters; this helper
|
|
66
|
+
* keeps the pattern uniform for workflow authors without embedding the
|
|
67
|
+
* full (ever-changing) feature catalogue in the package.
|
|
68
|
+
*/
|
|
69
|
+
async function enableAccountFeature(client, options) {
|
|
70
|
+
const enabled = options.enabled !== false;
|
|
71
|
+
await executeSql(client, {
|
|
72
|
+
statement: `ALTER ACCOUNT${options.ifExists ? " IF EXISTS" : ""}${options.name ? ` ${quoteIdentifier(options.name)}` : ""} SET ${options.feature.toUpperCase()} = ${enabled ? "TRUE" : "FALSE"}`,
|
|
73
|
+
warehouse: options.warehouse,
|
|
74
|
+
role: options.role
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { alterAccount, createOrganizationAccount, enableAccountFeature, listOrganizationAccounts };
|
package/dist/pipes.d.mts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { SnowflakeClient } from "./client.mjs";
|
|
2
|
+
import { d as HydratedRow } from "./statements-DJL0qVNA.mjs";
|
|
3
|
+
import { CatalogResult, ShowScopedOptions, showPipes } from "./catalog.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/pipes.d.ts
|
|
6
|
+
interface PipeRef {
|
|
7
|
+
readonly database?: string;
|
|
8
|
+
readonly schema?: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
}
|
|
11
|
+
interface PipeContext {
|
|
12
|
+
readonly warehouse?: string;
|
|
13
|
+
readonly role?: string;
|
|
14
|
+
}
|
|
15
|
+
interface CreatePipeOptions extends PipeRef, PipeContext {
|
|
16
|
+
readonly orReplace?: boolean;
|
|
17
|
+
readonly ifNotExists?: boolean;
|
|
18
|
+
readonly autoIngest?: boolean;
|
|
19
|
+
/** S3 SNS topic ARN (AUTO_INGEST buckets sending SNS notifications). */
|
|
20
|
+
readonly awsSnsTopic?: string;
|
|
21
|
+
/** Notification integration for GCS / Azure Event Grid ingest. */
|
|
22
|
+
readonly integration?: string;
|
|
23
|
+
/** Notification integration that receives ERRORS (Snowflake error-integration object). */
|
|
24
|
+
readonly errorIntegration?: string;
|
|
25
|
+
readonly comment?: string;
|
|
26
|
+
/** The `COPY INTO ...` body that defines what this pipe loads. */
|
|
27
|
+
readonly copyStatement: string;
|
|
28
|
+
}
|
|
29
|
+
declare function createPipe(client: SnowflakeClient, options: CreatePipeOptions): Promise<void>;
|
|
30
|
+
interface AlterPipeOptions extends PipeRef, PipeContext {
|
|
31
|
+
readonly setPipeExecutionPaused?: boolean;
|
|
32
|
+
readonly comment?: string;
|
|
33
|
+
readonly refresh?: {
|
|
34
|
+
readonly prefix?: string;
|
|
35
|
+
readonly modifiedAfter?: string;
|
|
36
|
+
};
|
|
37
|
+
readonly rename?: PipeRef;
|
|
38
|
+
readonly unset?: readonly string[];
|
|
39
|
+
}
|
|
40
|
+
declare function alterPipe(client: SnowflakeClient, options: AlterPipeOptions): Promise<void>;
|
|
41
|
+
interface DropPipeOptions extends PipeRef, PipeContext {
|
|
42
|
+
readonly ifExists?: boolean;
|
|
43
|
+
}
|
|
44
|
+
declare function dropPipe(client: SnowflakeClient, options: DropPipeOptions): Promise<void>;
|
|
45
|
+
interface DescribePipeOptions extends PipeRef, PipeContext {}
|
|
46
|
+
declare function describePipe(client: SnowflakeClient, options: DescribePipeOptions): Promise<readonly HydratedRow[]>;
|
|
47
|
+
/** Convenience for `ALTER PIPE name REFRESH ...`. */
|
|
48
|
+
declare function refreshPipe(client: SnowflakeClient, options: PipeRef & PipeContext & {
|
|
49
|
+
readonly prefix?: string;
|
|
50
|
+
readonly modifiedAfter?: string;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
interface SnowpipeInsertFile {
|
|
53
|
+
readonly path: string;
|
|
54
|
+
readonly size?: number | bigint;
|
|
55
|
+
}
|
|
56
|
+
interface InsertFilesOptions extends PipeRef {
|
|
57
|
+
readonly files: readonly SnowpipeInsertFile[];
|
|
58
|
+
readonly requestId?: string;
|
|
59
|
+
}
|
|
60
|
+
interface InsertFilesResponse {
|
|
61
|
+
readonly requestId: string;
|
|
62
|
+
/** Server-reported ingest batch id (`pipe` field per Snowflake docs). */
|
|
63
|
+
readonly pipe?: string;
|
|
64
|
+
readonly responseCode?: string;
|
|
65
|
+
readonly message?: string;
|
|
66
|
+
readonly skippedFiles?: readonly {
|
|
67
|
+
readonly path: string;
|
|
68
|
+
readonly reason?: string;
|
|
69
|
+
}[];
|
|
70
|
+
}
|
|
71
|
+
declare function insertFiles(client: SnowflakeClient, options: InsertFilesOptions): Promise<InsertFilesResponse>;
|
|
72
|
+
interface InsertReportOptions extends PipeRef {
|
|
73
|
+
readonly beginMark?: string;
|
|
74
|
+
readonly requestId?: string;
|
|
75
|
+
}
|
|
76
|
+
interface InsertReportResponse {
|
|
77
|
+
readonly pipe?: string;
|
|
78
|
+
readonly completeResult?: boolean;
|
|
79
|
+
readonly nextBeginMark?: string;
|
|
80
|
+
readonly files?: readonly {
|
|
81
|
+
readonly path: string;
|
|
82
|
+
readonly stageLocation?: string;
|
|
83
|
+
readonly fileSize?: number;
|
|
84
|
+
readonly timeReceived?: string;
|
|
85
|
+
readonly lastInsertTime?: string;
|
|
86
|
+
readonly rowsInserted?: number;
|
|
87
|
+
readonly rowsParsed?: number;
|
|
88
|
+
readonly errorsSeen?: number;
|
|
89
|
+
readonly errorLimit?: number;
|
|
90
|
+
readonly firstError?: string;
|
|
91
|
+
readonly status?: string;
|
|
92
|
+
}[];
|
|
93
|
+
}
|
|
94
|
+
declare function insertReport(client: SnowflakeClient, options: InsertReportOptions): Promise<InsertReportResponse>;
|
|
95
|
+
interface LoadHistoryScanOptions extends PipeRef {
|
|
96
|
+
readonly startTimeInclusive: string;
|
|
97
|
+
readonly endTimeExclusive: string;
|
|
98
|
+
readonly requestId?: string;
|
|
99
|
+
}
|
|
100
|
+
interface LoadHistoryScanResponse {
|
|
101
|
+
readonly pipe?: string;
|
|
102
|
+
readonly completeResult?: boolean;
|
|
103
|
+
readonly files?: readonly {
|
|
104
|
+
readonly path: string;
|
|
105
|
+
readonly stageLocation?: string;
|
|
106
|
+
readonly fileSize?: number;
|
|
107
|
+
readonly timeReceived?: string;
|
|
108
|
+
readonly lastInsertTime?: string;
|
|
109
|
+
readonly rowsInserted?: number;
|
|
110
|
+
readonly rowsParsed?: number;
|
|
111
|
+
readonly errorsSeen?: number;
|
|
112
|
+
readonly errorLimit?: number;
|
|
113
|
+
readonly firstError?: string;
|
|
114
|
+
readonly status?: string;
|
|
115
|
+
}[];
|
|
116
|
+
}
|
|
117
|
+
declare function loadHistoryScan(client: SnowflakeClient, options: LoadHistoryScanOptions): Promise<LoadHistoryScanResponse>;
|
|
118
|
+
//#endregion
|
|
119
|
+
export { AlterPipeOptions, type CatalogResult, CreatePipeOptions, DescribePipeOptions, DropPipeOptions, InsertFilesOptions, InsertFilesResponse, InsertReportOptions, InsertReportResponse, LoadHistoryScanOptions, LoadHistoryScanResponse, PipeContext, PipeRef, type ShowScopedOptions, SnowpipeInsertFile, alterPipe, createPipe, describePipe, dropPipe, insertFiles, insertReport, loadHistoryScan, refreshPipe, showPipes };
|
package/dist/pipes.mjs
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { executeSql } from "./sql.mjs";
|
|
2
|
+
import { a as quoteLiteral, i as quoteIdentifier, t as buildFqn } from "./sql-safety-CywdR3EP.mjs";
|
|
3
|
+
import { showPipes } from "./catalog.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/pipes.ts
|
|
6
|
+
function pipeFqn(ref) {
|
|
7
|
+
return buildFqn(ref.database, ref.schema, ref.name);
|
|
8
|
+
}
|
|
9
|
+
function pipeRestPath(ref, required) {
|
|
10
|
+
if (required && (!ref.database || !ref.schema)) throw new Error("Snowpipe REST requires fully-qualified database.schema.pipe (provide `database` and `schema`)");
|
|
11
|
+
return [
|
|
12
|
+
ref.database,
|
|
13
|
+
ref.schema,
|
|
14
|
+
ref.name
|
|
15
|
+
].filter((segment) => segment !== void 0 && segment.length > 0).join(".");
|
|
16
|
+
}
|
|
17
|
+
async function createPipe(client, options) {
|
|
18
|
+
const prefix = `CREATE${options.orReplace ? " OR REPLACE" : ""} PIPE${options.ifNotExists ? " IF NOT EXISTS" : ""}`;
|
|
19
|
+
const auto = options.autoIngest ? " AUTO_INGEST = TRUE" : "";
|
|
20
|
+
const sns = options.awsSnsTopic ? ` AWS_SNS_TOPIC = ${quoteLiteral(options.awsSnsTopic)}` : "";
|
|
21
|
+
const integration = options.integration ? ` INTEGRATION = ${quoteLiteral(options.integration)}` : "";
|
|
22
|
+
const errorIntegration = options.errorIntegration ? ` ERROR_INTEGRATION = ${quoteIdentifier(options.errorIntegration)}` : "";
|
|
23
|
+
const comment = options.comment ? ` COMMENT = ${quoteLiteral(options.comment)}` : "";
|
|
24
|
+
await executeSql(client, {
|
|
25
|
+
statement: `${prefix} ${pipeFqn(options)}${auto}${sns}${integration}${errorIntegration}${comment} AS ${options.copyStatement}`,
|
|
26
|
+
warehouse: options.warehouse,
|
|
27
|
+
role: options.role
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async function alterPipe(client, options) {
|
|
31
|
+
let tail;
|
|
32
|
+
if (options.rename) tail = `RENAME TO ${pipeFqn(options.rename)}`;
|
|
33
|
+
else if (options.refresh) tail = `REFRESH${options.refresh.prefix ? ` PREFIX = ${quoteLiteral(options.refresh.prefix)}` : ""}${options.refresh.modifiedAfter ? ` MODIFIED_AFTER = ${quoteLiteral(options.refresh.modifiedAfter)}` : ""}`;
|
|
34
|
+
else if (options.setPipeExecutionPaused !== void 0) tail = `SET PIPE_EXECUTION_PAUSED = ${options.setPipeExecutionPaused ? "TRUE" : "FALSE"}`;
|
|
35
|
+
else if (options.comment !== void 0) tail = `SET COMMENT = ${quoteLiteral(options.comment)}`;
|
|
36
|
+
else if (options.unset && options.unset.length > 0) tail = `UNSET ${options.unset.map((k) => k.toUpperCase()).join(", ")}`;
|
|
37
|
+
else throw new Error("alterPipe requires one of: rename / refresh / setPipeExecutionPaused / comment / unset");
|
|
38
|
+
await executeSql(client, {
|
|
39
|
+
statement: `ALTER PIPE ${pipeFqn(options)} ${tail}`,
|
|
40
|
+
warehouse: options.warehouse,
|
|
41
|
+
role: options.role
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async function dropPipe(client, options) {
|
|
45
|
+
await executeSql(client, {
|
|
46
|
+
statement: `DROP PIPE${options.ifExists ? " IF EXISTS" : ""} ${pipeFqn(options)}`,
|
|
47
|
+
warehouse: options.warehouse,
|
|
48
|
+
role: options.role
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function describePipe(client, options) {
|
|
52
|
+
return (await executeSql(client, {
|
|
53
|
+
statement: `DESCRIBE PIPE ${pipeFqn(options)}`,
|
|
54
|
+
warehouse: options.warehouse,
|
|
55
|
+
role: options.role
|
|
56
|
+
})).rows;
|
|
57
|
+
}
|
|
58
|
+
/** Convenience for `ALTER PIPE name REFRESH ...`. */
|
|
59
|
+
async function refreshPipe(client, options) {
|
|
60
|
+
await alterPipe(client, {
|
|
61
|
+
...options,
|
|
62
|
+
refresh: {
|
|
63
|
+
prefix: options.prefix,
|
|
64
|
+
modifiedAfter: options.modifiedAfter
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async function insertFiles(client, options) {
|
|
69
|
+
if (options.files.length === 0) throw new Error("insertFiles requires at least one file");
|
|
70
|
+
const path = `/v1/data/pipes/${pipeRestPath(options, true)}/insertFiles`;
|
|
71
|
+
const body = { files: options.files.map((f) => ({
|
|
72
|
+
path: f.path,
|
|
73
|
+
...f.size !== void 0 ? { size: typeof f.size === "bigint" ? Number(f.size) : f.size } : {}
|
|
74
|
+
})) };
|
|
75
|
+
return client.request(path, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body,
|
|
78
|
+
requestId: options.requestId,
|
|
79
|
+
query: options.requestId ? { requestId: options.requestId } : void 0
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function insertReport(client, options) {
|
|
83
|
+
const path = `/v1/data/pipes/${pipeRestPath(options, true)}/insertReport`;
|
|
84
|
+
const query = {};
|
|
85
|
+
if (options.beginMark) query.beginMark = options.beginMark;
|
|
86
|
+
if (options.requestId) query.requestId = options.requestId;
|
|
87
|
+
return client.request(path, {
|
|
88
|
+
method: "GET",
|
|
89
|
+
query
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function loadHistoryScan(client, options) {
|
|
93
|
+
const path = `/v1/data/pipes/${pipeRestPath(options, true)}/loadHistoryScan`;
|
|
94
|
+
const query = {
|
|
95
|
+
startTimeInclusive: options.startTimeInclusive,
|
|
96
|
+
endTimeExclusive: options.endTimeExclusive
|
|
97
|
+
};
|
|
98
|
+
if (options.requestId) query.requestId = options.requestId;
|
|
99
|
+
return client.request(path, {
|
|
100
|
+
method: "GET",
|
|
101
|
+
query
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
export { alterPipe, createPipe, describePipe, dropPipe, insertFiles, insertReport, loadHistoryScan, refreshPipe, showPipes };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { SnowflakeClient } from "./client.mjs";
|
|
2
|
+
import { d as HydratedRow, v as SqlBinding } from "./statements-DJL0qVNA.mjs";
|
|
3
|
+
import { ExecuteSqlResult } from "./sql.mjs";
|
|
4
|
+
import { t as OptionMap } from "./sql-options-2k5xQ-oS.mjs";
|
|
5
|
+
import { CatalogResult, ShowScopedOptions, showProcedures } from "./catalog.mjs";
|
|
6
|
+
import { RowValue } from "./rows.mjs";
|
|
7
|
+
|
|
8
|
+
//#region src/procedures.d.ts
|
|
9
|
+
interface ProcedureRef {
|
|
10
|
+
readonly database?: string;
|
|
11
|
+
readonly schema?: string;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
}
|
|
14
|
+
interface ProcedureContext {
|
|
15
|
+
readonly warehouse?: string;
|
|
16
|
+
readonly role?: string;
|
|
17
|
+
}
|
|
18
|
+
interface ProcedureArgument {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly type: string;
|
|
21
|
+
readonly defaultExpression?: string;
|
|
22
|
+
}
|
|
23
|
+
type ProcedureLanguage = 'SQL' | 'JAVASCRIPT' | 'PYTHON' | 'JAVA' | 'SCALA';
|
|
24
|
+
type ExecuteAs = 'CALLER' | 'OWNER';
|
|
25
|
+
interface CreateProcedureOptions extends ProcedureRef, ProcedureContext {
|
|
26
|
+
readonly orReplace?: boolean;
|
|
27
|
+
readonly ifNotExists?: boolean;
|
|
28
|
+
readonly secure?: boolean;
|
|
29
|
+
readonly arguments?: readonly ProcedureArgument[];
|
|
30
|
+
readonly returns: string;
|
|
31
|
+
readonly language?: ProcedureLanguage;
|
|
32
|
+
readonly executeAs?: ExecuteAs;
|
|
33
|
+
/** Additional keywords: `STRICT`, `IMMUTABLE`, `VOLATILE`, etc. */
|
|
34
|
+
readonly modifiers?: readonly string[];
|
|
35
|
+
/** Language-specific options: `RUNTIME_VERSION`, `PACKAGES`, `HANDLER`, `IMPORTS`. */
|
|
36
|
+
readonly options?: OptionMap;
|
|
37
|
+
readonly comment?: string;
|
|
38
|
+
readonly as: string;
|
|
39
|
+
readonly dollarQuotedBody?: boolean;
|
|
40
|
+
}
|
|
41
|
+
declare function createProcedure(client: SnowflakeClient, options: CreateProcedureOptions): Promise<void>;
|
|
42
|
+
interface DropProcedureOptions extends ProcedureRef, ProcedureContext {
|
|
43
|
+
readonly ifExists?: boolean;
|
|
44
|
+
readonly arguments?: readonly ProcedureArgument[];
|
|
45
|
+
}
|
|
46
|
+
declare function dropProcedure(client: SnowflakeClient, options: DropProcedureOptions): Promise<void>;
|
|
47
|
+
interface DescribeProcedureOptions extends ProcedureRef, ProcedureContext {
|
|
48
|
+
readonly arguments?: readonly ProcedureArgument[];
|
|
49
|
+
}
|
|
50
|
+
declare function describeProcedure(client: SnowflakeClient, options: DescribeProcedureOptions): Promise<readonly HydratedRow[]>;
|
|
51
|
+
interface CallProcedureOptions extends ProcedureRef, ProcedureContext {
|
|
52
|
+
/** Positional arguments — every value flows through SQL API bindings (`?` placeholders). */
|
|
53
|
+
readonly arguments?: readonly RowValue[];
|
|
54
|
+
/** Pre-built bindings map (takes precedence over `arguments`). */
|
|
55
|
+
readonly bindings?: Readonly<Record<string, SqlBinding>>;
|
|
56
|
+
/** Raw SQL expression list when you need to pass a named function, subquery, or bind-unfriendly value. */
|
|
57
|
+
readonly rawArguments?: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
declare function callProcedure(client: SnowflakeClient, options: CallProcedureOptions): Promise<ExecuteSqlResult<HydratedRow | readonly unknown[]>>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { CallProcedureOptions, type CatalogResult, CreateProcedureOptions, DescribeProcedureOptions, DropProcedureOptions, ExecuteAs, ProcedureArgument, ProcedureContext, ProcedureLanguage, ProcedureRef, type ShowScopedOptions, callProcedure, createProcedure, describeProcedure, dropProcedure, showProcedures };
|