@slates-integrations/tableau 0.2.0-rc.8
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 +85 -0
- package/docs/SPEC.md +61 -0
- package/logo.png +0 -0
- package/package.json +19 -0
- package/slate.json +18 -0
- package/src/auth.ts +237 -0
- package/src/config.ts +17 -0
- package/src/index.ts +55 -0
- package/src/lib/client.ts +959 -0
- package/src/lib/errors.ts +94 -0
- package/src/lib/helpers.ts +15 -0
- package/src/lib/normalizers.ts +9 -0
- package/src/spec.ts +12 -0
- package/src/tools/export-view.ts +112 -0
- package/src/tools/get-site-info.ts +47 -0
- package/src/tools/get-view-data.ts +31 -0
- package/src/tools/index.ts +18 -0
- package/src/tools/list-datasources.ts +78 -0
- package/src/tools/list-views.ts +70 -0
- package/src/tools/list-workbooks.ts +88 -0
- package/src/tools/manage-alerts.ts +139 -0
- package/src/tools/manage-collections.ts +254 -0
- package/src/tools/manage-custom-views.ts +159 -0
- package/src/tools/manage-datasource.ts +129 -0
- package/src/tools/manage-favorites.ts +80 -0
- package/src/tools/manage-flows.ts +170 -0
- package/src/tools/manage-groups.ts +178 -0
- package/src/tools/manage-jobs.ts +120 -0
- package/src/tools/manage-permissions.ts +118 -0
- package/src/tools/manage-projects.ts +162 -0
- package/src/tools/manage-users.ts +184 -0
- package/src/tools/manage-workbook.ts +160 -0
- package/src/triggers/datasource-events.ts +119 -0
- package/src/triggers/index.ts +6 -0
- package/src/triggers/label-events.ts +98 -0
- package/src/triggers/site-events.ts +97 -0
- package/src/triggers/user-events.ts +98 -0
- package/src/triggers/view-events.ts +83 -0
- package/src/triggers/workbook-events.ts +108 -0
- package/tsconfig.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# <img src="https://provider-logos.metorial-cdn.com/tableau.png" height="20"> Tableau
|
|
2
|
+
|
|
3
|
+
Manage Tableau Cloud and Tableau Server resources programmatically through the Tableau REST API. Query and manage workbooks, data sources, views, custom views, flows, users, groups, projects, permissions, favorites, collections, jobs, and data-driven alerts. Export views as CSV, PNG, or PDF. Authentication supports Tableau personal access tokens, username/password sign-in, and connected-app or unified-access-token JWT sign-in.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
### Get Site Info
|
|
8
|
+
|
|
9
|
+
Retrieve information about the current Tableau site, including name, URL, storage usage, and configuration settings.
|
|
10
|
+
|
|
11
|
+
### Get View Data
|
|
12
|
+
|
|
13
|
+
Export the underlying data from a Tableau view as CSV. Useful for retrieving the tabular data behind a dashboard visualization.
|
|
14
|
+
|
|
15
|
+
### Export View
|
|
16
|
+
|
|
17
|
+
Export a Tableau view as CSV data, a PNG image, or a PDF file. Supports Tableau view filter query parameters and cache max-age controls.
|
|
18
|
+
|
|
19
|
+
### List Data Sources
|
|
20
|
+
|
|
21
|
+
List and search data sources on the Tableau site. Supports pagination, filtering, and sorting.
|
|
22
|
+
|
|
23
|
+
### List Views
|
|
24
|
+
|
|
25
|
+
List and search views across the Tableau site. Supports pagination, filtering, and sorting.
|
|
26
|
+
|
|
27
|
+
### List Workbooks
|
|
28
|
+
|
|
29
|
+
List and search workbooks on the Tableau site. Supports pagination, filtering, and sorting to find specific workbooks.
|
|
30
|
+
|
|
31
|
+
### Manage Data-Driven Alerts
|
|
32
|
+
|
|
33
|
+
List, get, delete data-driven alerts, and add or remove users from alert recipient lists. Data-driven alerts trigger when data in a view meets specified conditions.
|
|
34
|
+
|
|
35
|
+
### Manage Collections
|
|
36
|
+
|
|
37
|
+
List, get, create, update, or delete collections, and add, remove, or list collection items. Collections are curated groups of Tableau content.
|
|
38
|
+
|
|
39
|
+
### Manage Custom Views
|
|
40
|
+
|
|
41
|
+
List, get, update, delete, or export Tableau custom views. Custom views are saved user-specific configurations of workbook views.
|
|
42
|
+
|
|
43
|
+
### Manage Data Source
|
|
44
|
+
|
|
45
|
+
Get details, update, delete, or trigger extract refresh for a data source. Use the **action** field to select the operation.
|
|
46
|
+
|
|
47
|
+
### Manage Favorites
|
|
48
|
+
|
|
49
|
+
List, add, or remove favorites for a user. Supports workbooks, views, data sources, projects, and flows.
|
|
50
|
+
|
|
51
|
+
### Manage Flows
|
|
52
|
+
|
|
53
|
+
List, get, update, delete, or run Tableau Prep flows. Use the **action** field to select the operation.
|
|
54
|
+
|
|
55
|
+
### Manage Groups
|
|
56
|
+
|
|
57
|
+
List, create, update, delete groups, and add or remove users from groups. Use the **action** field to select the operation.
|
|
58
|
+
|
|
59
|
+
### Manage Jobs
|
|
60
|
+
|
|
61
|
+
List, get details, or cancel background jobs (extract refreshes, flow runs, subscriptions). Use the **action** field to select the operation.
|
|
62
|
+
|
|
63
|
+
### Manage Permissions
|
|
64
|
+
|
|
65
|
+
Query, add, or delete permissions on Tableau resources (workbooks, datasources, projects, views, flows). Permissions are granted to users or groups with specific capability modes.
|
|
66
|
+
|
|
67
|
+
### Manage Projects
|
|
68
|
+
|
|
69
|
+
List, create, update, or delete projects. Projects organize workbooks, data sources, and other content in Tableau.
|
|
70
|
+
|
|
71
|
+
### Manage Users
|
|
72
|
+
|
|
73
|
+
List, get, add, update, or remove users on the Tableau site. Use the **action** field to select the operation.
|
|
74
|
+
|
|
75
|
+
### Manage Workbook
|
|
76
|
+
|
|
77
|
+
Get details, update properties, delete, refresh extracts, or manage tags for a workbook. Use the **action** field to select the operation.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
This integration is licensed under the [FSL-1.1](https://github.com/metorial/metorial-platform/blob/dev/LICENSE).
|
|
82
|
+
|
|
83
|
+
<div align="center">
|
|
84
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
85
|
+
</div>
|
package/docs/SPEC.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Tableau Integration Specification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This integration uses Tableau's REST API to manage common Tableau Cloud and Tableau Server resources. It focuses on practical content and administration workflows: querying content, exporting views, managing users and groups, managing projects and permissions, monitoring jobs, managing favorites, managing current collections endpoints, and handling custom views and data-driven alerts.
|
|
6
|
+
|
|
7
|
+
The default REST API version is `3.28`, matching Tableau 2026.1 documentation. Classic endpoints use `/api/{api-version}/sites/{site-luid}`. Current collections CRUD and item endpoints use Tableau's per-resource path under `/api/-/collections`.
|
|
8
|
+
|
|
9
|
+
## Authentication
|
|
10
|
+
|
|
11
|
+
The integration signs in to Tableau and stores the returned credentials token, site LUID, user LUID, estimated expiration time, and auth method.
|
|
12
|
+
|
|
13
|
+
Supported sign-in methods:
|
|
14
|
+
|
|
15
|
+
- Personal access token (PAT)
|
|
16
|
+
- Username and password
|
|
17
|
+
- Connected app JWT
|
|
18
|
+
- Unified access token JWT by setting `isUat: true`
|
|
19
|
+
|
|
20
|
+
Tableau credentials tokens expire. Tableau Cloud tokens are documented as valid for 120 minutes, while Tableau Server tokens are typically valid for 240 minutes unless the server setting has changed. The integration records a conservative estimated expiration and can refresh PAT and username/password profiles by signing in again with the stored auth input. Non-refreshable auth methods report a user-facing `ServiceError` if a stored token is already expired.
|
|
21
|
+
|
|
22
|
+
## Tools
|
|
23
|
+
|
|
24
|
+
- `get_site_info`: Get current site details.
|
|
25
|
+
- `list_workbooks`: List and filter workbooks.
|
|
26
|
+
- `manage_workbook`: Get, update, delete, refresh, and tag workbooks.
|
|
27
|
+
- `list_datasources`: List and filter published data sources.
|
|
28
|
+
- `manage_datasource`: Get, update, delete, and refresh data sources.
|
|
29
|
+
- `list_views`: List and filter views.
|
|
30
|
+
- `get_view_data`: Export view underlying data as CSV.
|
|
31
|
+
- `export_view`: Export a view as CSV, PNG, or PDF.
|
|
32
|
+
- `manage_custom_views`: List, get, update, delete, and export custom views.
|
|
33
|
+
- `manage_users`: List, get, add, update, and remove site users.
|
|
34
|
+
- `manage_groups`: List, create, update, delete groups, and manage group membership.
|
|
35
|
+
- `manage_projects`: List, create, update, and delete projects.
|
|
36
|
+
- `manage_permissions`: Query, add, and delete permissions for supported Tableau resources.
|
|
37
|
+
- `manage_jobs`: List, get, and cancel background jobs.
|
|
38
|
+
- `manage_favorites`: List, add, and remove user favorites.
|
|
39
|
+
- `manage_flows`: List, get, update, delete, and run flows.
|
|
40
|
+
- `manage_collections`: List, get, create, update, delete collections, and add, remove, or list collection items.
|
|
41
|
+
- `manage_alerts`: List, get, delete, and manage recipients for data-driven alerts.
|
|
42
|
+
|
|
43
|
+
## Error Handling
|
|
44
|
+
|
|
45
|
+
Tool validation failures, auth failures, and upstream Tableau API failures are normalized to `ServiceError` from `@lowerdeck/error`. Upstream failures preserve the HTTP status when Tableau provides one.
|
|
46
|
+
|
|
47
|
+
## Live E2E
|
|
48
|
+
|
|
49
|
+
The private live E2E suite lives at `tests/integrations/tableau/tools.e2e.ts`. Stable content IDs can be supplied through `SLATES_E2E_FIXTURES`:
|
|
50
|
+
|
|
51
|
+
- `workbookId`
|
|
52
|
+
- `datasourceId`
|
|
53
|
+
- `viewId`
|
|
54
|
+
- `userId`
|
|
55
|
+
- `groupId`
|
|
56
|
+
- `customViewId`
|
|
57
|
+
- `collectionItemContentLuid`
|
|
58
|
+
- `collectionItemContentType`
|
|
59
|
+
- `collectionItemContentName`
|
|
60
|
+
|
|
61
|
+
The suite creates and deletes its own collection for collection CRUD coverage.
|
package/logo.png
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@slates-integrations/tableau",
|
|
3
|
+
"main": "src/index.ts",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
|
|
7
|
+
"typecheck": "tsc --noEmit"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@lowerdeck/error": "^1.1.0",
|
|
11
|
+
"@types/node": "^20",
|
|
12
|
+
"slates": "1.0.0-rc.10",
|
|
13
|
+
"zod": "^4.2"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5"
|
|
17
|
+
},
|
|
18
|
+
"version": "0.2.0-rc.8"
|
|
19
|
+
}
|
package/slate.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@metorial/tableau",
|
|
3
|
+
"description": "Manage Tableau Cloud and Tableau Server resources through the Tableau REST API. Query and manage workbooks, data sources, views, custom views, flows, users, groups, projects, permissions, favorites, collections, jobs, and data-driven alerts. Export views as CSV, PNG, or PDF.",
|
|
4
|
+
"categories": ["apis-and-http-requests", "document-processing"],
|
|
5
|
+
"skills": [
|
|
6
|
+
"query and manage workbooks",
|
|
7
|
+
"export views as CSV, PNG, or PDF",
|
|
8
|
+
"manage data source extracts",
|
|
9
|
+
"administer users and groups",
|
|
10
|
+
"configure permissions",
|
|
11
|
+
"monitor background jobs",
|
|
12
|
+
"manage flows and runs",
|
|
13
|
+
"manage data-driven alerts",
|
|
14
|
+
"manage collections and favorites",
|
|
15
|
+
"manage custom views"
|
|
16
|
+
],
|
|
17
|
+
"logoUrl": "https://provider-logos.metorial-cdn.com/tableau.png"
|
|
18
|
+
}
|
package/src/auth.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { SlateAuth, createAxios } from 'slates';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { tableauApiError, tableauServiceError } from './lib/errors';
|
|
4
|
+
|
|
5
|
+
type TableauAuthOutput = {
|
|
6
|
+
token: string;
|
|
7
|
+
siteId: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
expiresAt?: string;
|
|
10
|
+
authMethod?: 'personal_access_token' | 'username_password' | 'connected_app_jwt';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type TableauSignInInput = {
|
|
14
|
+
serverUrl: string;
|
|
15
|
+
siteContentUrl: string;
|
|
16
|
+
apiVersion: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type TableauPersonalAccessTokenInput = TableauSignInInput & {
|
|
20
|
+
tokenName: string;
|
|
21
|
+
tokenSecret: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type TableauUsernamePasswordInput = TableauSignInInput & {
|
|
25
|
+
username: string;
|
|
26
|
+
password: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type TableauConnectedAppJwtInput = TableauSignInInput & {
|
|
30
|
+
jwt: string;
|
|
31
|
+
isUat?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type TableauRefreshContext<Input> = {
|
|
35
|
+
output: TableauAuthOutput;
|
|
36
|
+
input: Input;
|
|
37
|
+
clientId: string;
|
|
38
|
+
clientSecret: string;
|
|
39
|
+
scopes: string[];
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
let estimateTokenExpiresAt = (serverUrl: string) => {
|
|
43
|
+
let lifetimeMinutes = /\.online\.tableau\.com/i.test(serverUrl) ? 110 : 230;
|
|
44
|
+
return new Date(Date.now() + lifetimeMinutes * 60 * 1000).toISOString();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let signIn = async (
|
|
48
|
+
input: TableauSignInInput,
|
|
49
|
+
credentials: Record<string, unknown>,
|
|
50
|
+
authMethod: NonNullable<TableauAuthOutput['authMethod']>
|
|
51
|
+
) => {
|
|
52
|
+
let baseUrl = input.serverUrl.replace(/\/+$/, '');
|
|
53
|
+
let http = createAxios({ baseURL: baseUrl });
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
let response = await http.post(`/api/${input.apiVersion}/auth/signin`, {
|
|
57
|
+
credentials: {
|
|
58
|
+
...credentials,
|
|
59
|
+
site: {
|
|
60
|
+
contentUrl: input.siteContentUrl
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
let responseCredentials = response.data?.credentials;
|
|
66
|
+
if (
|
|
67
|
+
!responseCredentials?.token ||
|
|
68
|
+
!responseCredentials?.site?.id ||
|
|
69
|
+
!responseCredentials?.user?.id
|
|
70
|
+
) {
|
|
71
|
+
throw tableauServiceError(
|
|
72
|
+
'Tableau sign-in response did not include token, site ID, and user ID.'
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
output: {
|
|
78
|
+
token: responseCredentials.token,
|
|
79
|
+
siteId: responseCredentials.site.id,
|
|
80
|
+
userId: responseCredentials.user.id,
|
|
81
|
+
expiresAt: estimateTokenExpiresAt(input.serverUrl),
|
|
82
|
+
authMethod
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
throw tableauApiError(error, 'sign-in');
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
let getProfile = async (ctx: { output: TableauAuthOutput; input: any }) => {
|
|
91
|
+
return {
|
|
92
|
+
profile: {
|
|
93
|
+
id: ctx.output.userId,
|
|
94
|
+
siteId: ctx.output.siteId,
|
|
95
|
+
authMethod: ctx.output.authMethod,
|
|
96
|
+
expiresAt: ctx.output.expiresAt
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
let personalAccessTokenAuth = {
|
|
102
|
+
type: 'auth.custom' as const,
|
|
103
|
+
name: 'Personal Access Token',
|
|
104
|
+
key: 'personal_access_token',
|
|
105
|
+
|
|
106
|
+
inputSchema: z.object({
|
|
107
|
+
serverUrl: z.string().describe('Tableau Server or Cloud URL'),
|
|
108
|
+
siteContentUrl: z.string().default('').describe('Site content URL'),
|
|
109
|
+
apiVersion: z.string().default('3.28').describe('API version'),
|
|
110
|
+
tokenName: z.string().describe('Personal access token name'),
|
|
111
|
+
tokenSecret: z.string().describe('Personal access token secret')
|
|
112
|
+
}),
|
|
113
|
+
|
|
114
|
+
getOutput: async (ctx: { input: TableauPersonalAccessTokenInput }) => {
|
|
115
|
+
let { serverUrl, siteContentUrl, apiVersion, tokenName, tokenSecret } = ctx.input;
|
|
116
|
+
|
|
117
|
+
return await signIn(
|
|
118
|
+
{ serverUrl, siteContentUrl, apiVersion },
|
|
119
|
+
{
|
|
120
|
+
personalAccessTokenName: tokenName,
|
|
121
|
+
personalAccessTokenSecret: tokenSecret
|
|
122
|
+
},
|
|
123
|
+
'personal_access_token'
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
handleTokenRefresh: async (
|
|
128
|
+
ctx: TableauRefreshContext<TableauPersonalAccessTokenInput>
|
|
129
|
+
) => {
|
|
130
|
+
let { serverUrl, siteContentUrl, apiVersion, tokenName, tokenSecret } = ctx.input;
|
|
131
|
+
|
|
132
|
+
return await signIn(
|
|
133
|
+
{ serverUrl, siteContentUrl, apiVersion },
|
|
134
|
+
{
|
|
135
|
+
personalAccessTokenName: tokenName,
|
|
136
|
+
personalAccessTokenSecret: tokenSecret
|
|
137
|
+
},
|
|
138
|
+
'personal_access_token'
|
|
139
|
+
);
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
getProfile
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
let usernamePasswordAuth = {
|
|
146
|
+
type: 'auth.custom' as const,
|
|
147
|
+
name: 'Username & Password',
|
|
148
|
+
key: 'username_password',
|
|
149
|
+
|
|
150
|
+
inputSchema: z.object({
|
|
151
|
+
serverUrl: z.string().describe('Tableau Server or Cloud URL'),
|
|
152
|
+
siteContentUrl: z.string().default('').describe('Site content URL'),
|
|
153
|
+
apiVersion: z.string().default('3.28').describe('API version'),
|
|
154
|
+
username: z.string().describe('Tableau username'),
|
|
155
|
+
password: z.string().describe('Tableau password')
|
|
156
|
+
}),
|
|
157
|
+
|
|
158
|
+
getOutput: async (ctx: { input: TableauUsernamePasswordInput }) => {
|
|
159
|
+
let { serverUrl, siteContentUrl, apiVersion, username, password } = ctx.input;
|
|
160
|
+
|
|
161
|
+
return await signIn(
|
|
162
|
+
{ serverUrl, siteContentUrl, apiVersion },
|
|
163
|
+
{
|
|
164
|
+
name: username,
|
|
165
|
+
password
|
|
166
|
+
},
|
|
167
|
+
'username_password'
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
handleTokenRefresh: async (ctx: TableauRefreshContext<TableauUsernamePasswordInput>) => {
|
|
172
|
+
let { serverUrl, siteContentUrl, apiVersion, username, password } = ctx.input;
|
|
173
|
+
|
|
174
|
+
return await signIn(
|
|
175
|
+
{ serverUrl, siteContentUrl, apiVersion },
|
|
176
|
+
{
|
|
177
|
+
name: username,
|
|
178
|
+
password
|
|
179
|
+
},
|
|
180
|
+
'username_password'
|
|
181
|
+
);
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
getProfile
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
let connectedAppJwtAuth = {
|
|
188
|
+
type: 'auth.custom' as const,
|
|
189
|
+
name: 'Connected App JWT',
|
|
190
|
+
key: 'connected_app_jwt',
|
|
191
|
+
|
|
192
|
+
inputSchema: z.object({
|
|
193
|
+
serverUrl: z.string().describe('Tableau Server or Cloud URL'),
|
|
194
|
+
siteContentUrl: z.string().default('').describe('Site content URL'),
|
|
195
|
+
apiVersion: z.string().default('3.28').describe('API version'),
|
|
196
|
+
jwt: z.string().describe('JWT generated for a Tableau connected app or UAT'),
|
|
197
|
+
isUat: z
|
|
198
|
+
.boolean()
|
|
199
|
+
.optional()
|
|
200
|
+
.describe('Set true when signing in with a Tableau Cloud unified access token JWT')
|
|
201
|
+
}),
|
|
202
|
+
|
|
203
|
+
getOutput: async (ctx: { input: TableauConnectedAppJwtInput }) => {
|
|
204
|
+
let { serverUrl, siteContentUrl, apiVersion, jwt, isUat } = ctx.input;
|
|
205
|
+
|
|
206
|
+
return await signIn(
|
|
207
|
+
{ serverUrl, siteContentUrl, apiVersion },
|
|
208
|
+
{
|
|
209
|
+
jwt,
|
|
210
|
+
...(isUat !== undefined ? { isUat } : {})
|
|
211
|
+
},
|
|
212
|
+
'connected_app_jwt'
|
|
213
|
+
);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
getProfile
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export let auth = SlateAuth.create()
|
|
220
|
+
.output(
|
|
221
|
+
z.object({
|
|
222
|
+
token: z.string().describe('Tableau credentials token for API requests'),
|
|
223
|
+
siteId: z.string().describe('Site LUID returned from sign-in'),
|
|
224
|
+
userId: z.string().describe('User LUID returned from sign-in'),
|
|
225
|
+
expiresAt: z
|
|
226
|
+
.string()
|
|
227
|
+
.optional()
|
|
228
|
+
.describe('Estimated ISO timestamp when the Tableau credentials token expires'),
|
|
229
|
+
authMethod: z
|
|
230
|
+
.enum(['personal_access_token', 'username_password', 'connected_app_jwt'])
|
|
231
|
+
.optional()
|
|
232
|
+
.describe('Authentication method used to obtain the Tableau credentials token')
|
|
233
|
+
})
|
|
234
|
+
)
|
|
235
|
+
.addCustomAuth(personalAccessTokenAuth)
|
|
236
|
+
.addCustomAuth(usernamePasswordAuth)
|
|
237
|
+
.addCustomAuth(connectedAppJwtAuth);
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SlateConfig } from 'slates';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export let config = SlateConfig.create(
|
|
5
|
+
z.object({
|
|
6
|
+
serverUrl: z
|
|
7
|
+
.string()
|
|
8
|
+
.describe('Tableau Server or Tableau Cloud URL (e.g., https://10ay.online.tableau.com)'),
|
|
9
|
+
siteContentUrl: z
|
|
10
|
+
.string()
|
|
11
|
+
.default('')
|
|
12
|
+
.describe(
|
|
13
|
+
'Site content URL identifier (e.g., "my-site"). Leave empty for the default site.'
|
|
14
|
+
),
|
|
15
|
+
apiVersion: z.string().default('3.28').describe('Tableau REST API version (e.g., "3.28")')
|
|
16
|
+
})
|
|
17
|
+
);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Slate } from 'slates';
|
|
2
|
+
import { spec } from './spec';
|
|
3
|
+
import {
|
|
4
|
+
listWorkbooks,
|
|
5
|
+
manageWorkbook,
|
|
6
|
+
listDatasources,
|
|
7
|
+
manageDatasource,
|
|
8
|
+
listViews,
|
|
9
|
+
getViewData,
|
|
10
|
+
exportView,
|
|
11
|
+
manageCustomViews,
|
|
12
|
+
manageUsers,
|
|
13
|
+
manageGroups,
|
|
14
|
+
manageProjects,
|
|
15
|
+
managePermissions,
|
|
16
|
+
manageJobs,
|
|
17
|
+
manageFavorites,
|
|
18
|
+
manageFlows,
|
|
19
|
+
manageCollections,
|
|
20
|
+
manageAlerts,
|
|
21
|
+
getSiteInfo
|
|
22
|
+
} from './tools';
|
|
23
|
+
import {
|
|
24
|
+
datasourceEvents,
|
|
25
|
+
workbookEvents,
|
|
26
|
+
userEvents,
|
|
27
|
+
labelEvents,
|
|
28
|
+
siteEvents,
|
|
29
|
+
viewEvents
|
|
30
|
+
} from './triggers';
|
|
31
|
+
|
|
32
|
+
export let provider = Slate.create({
|
|
33
|
+
spec,
|
|
34
|
+
tools: [
|
|
35
|
+
listWorkbooks,
|
|
36
|
+
manageWorkbook,
|
|
37
|
+
listDatasources,
|
|
38
|
+
manageDatasource,
|
|
39
|
+
listViews,
|
|
40
|
+
getViewData,
|
|
41
|
+
exportView,
|
|
42
|
+
manageCustomViews,
|
|
43
|
+
manageUsers,
|
|
44
|
+
manageGroups,
|
|
45
|
+
manageProjects,
|
|
46
|
+
managePermissions,
|
|
47
|
+
manageJobs,
|
|
48
|
+
manageFavorites,
|
|
49
|
+
manageFlows,
|
|
50
|
+
manageCollections,
|
|
51
|
+
manageAlerts,
|
|
52
|
+
getSiteInfo
|
|
53
|
+
],
|
|
54
|
+
triggers: [datasourceEvents, workbookEvents, userEvents, labelEvents, siteEvents, viewEvents]
|
|
55
|
+
});
|