@slates-integrations/sharepoint 0.2.0-rc.6

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.
@@ -0,0 +1,96 @@
1
+ import { SlateTool } from 'slates';
2
+ import { SharePointClient } from '../lib/client';
3
+ import { spec } from '../spec';
4
+ import { oneOfRequiredError } from './errors';
5
+ import { z } from 'zod';
6
+
7
+ let driveOutputSchema = z.object({
8
+ driveId: z.string().describe('Unique drive ID'),
9
+ driveName: z.string().describe('Display name of the drive'),
10
+ driveType: z.string().optional().describe('Type of drive (e.g. "documentLibrary")'),
11
+ webUrl: z.string().optional().describe('URL of the drive'),
12
+ createdDateTime: z.string().optional().describe('When the drive was created'),
13
+ lastModifiedDateTime: z.string().optional().describe('When the drive was last modified'),
14
+ totalSize: z.number().optional().describe('Total storage quota in bytes'),
15
+ usedSize: z.number().optional().describe('Used storage in bytes'),
16
+ remainingSize: z.number().optional().describe('Remaining storage in bytes'),
17
+ ownerName: z.string().optional().describe('Display name of the drive owner')
18
+ });
19
+
20
+ export let getDrive = SlateTool.create(spec, {
21
+ name: 'Get Drives',
22
+ key: 'get_drive',
23
+ description: `Retrieve document libraries (drives) for a SharePoint site. Can get the default drive, a specific drive by ID, or list all drives on a site. Drives are the containers for files in SharePoint.`,
24
+ instructions: [
25
+ 'Provide **siteId** with **listAll** set to true to list all drives on a site.',
26
+ 'Provide **driveId** to retrieve a specific drive by ID.',
27
+ 'Provide **siteId** without **listAll** to get the default document library.'
28
+ ],
29
+ tags: {
30
+ readOnly: true,
31
+ destructive: false
32
+ }
33
+ })
34
+ .input(
35
+ z.object({
36
+ siteId: z.string().optional().describe('SharePoint site ID'),
37
+ driveId: z.string().optional().describe('Specific drive ID to retrieve'),
38
+ listAll: z.boolean().optional().describe('If true, list all drives on the site')
39
+ })
40
+ )
41
+ .output(
42
+ z.object({
43
+ drive: driveOutputSchema.optional().describe('Single drive details'),
44
+ drives: z
45
+ .array(driveOutputSchema)
46
+ .optional()
47
+ .describe('All drives (when listAll is true)')
48
+ })
49
+ )
50
+ .handleInvocation(async ctx => {
51
+ let client = new SharePointClient(ctx.auth.token);
52
+
53
+ let mapDrive = (d: any) => ({
54
+ driveId: d.id,
55
+ driveName: d.name,
56
+ driveType: d.driveType,
57
+ webUrl: d.webUrl,
58
+ createdDateTime: d.createdDateTime,
59
+ lastModifiedDateTime: d.lastModifiedDateTime,
60
+ totalSize: d.quota?.total,
61
+ usedSize: d.quota?.used,
62
+ remainingSize: d.quota?.remaining,
63
+ ownerName: d.owner?.user?.displayName
64
+ });
65
+
66
+ if (ctx.input.driveId) {
67
+ let drive = await client.getDrive(ctx.input.driveId);
68
+ return {
69
+ output: { drive: mapDrive(drive) },
70
+ message: `Retrieved drive **${drive.name}** (\`${drive.id}\`).`
71
+ };
72
+ }
73
+
74
+ if (!ctx.input.siteId) {
75
+ throw oneOfRequiredError('One of siteId or driveId must be provided.', [
76
+ 'siteId',
77
+ 'driveId'
78
+ ]);
79
+ }
80
+
81
+ if (ctx.input.listAll) {
82
+ let data = await client.listDrives(ctx.input.siteId);
83
+ let drives = (data.value || []).map(mapDrive);
84
+ return {
85
+ output: { drives },
86
+ message: `Found **${drives.length}** drive(s) on the site.`
87
+ };
88
+ }
89
+
90
+ let drive = await client.getDefaultDrive(ctx.input.siteId);
91
+ return {
92
+ output: { drive: mapDrive(drive) },
93
+ message: `Retrieved default drive **${drive.name}** (\`${drive.id}\`).`
94
+ };
95
+ })
96
+ .build();
@@ -0,0 +1,53 @@
1
+ import { SlateTool } from 'slates';
2
+ import { SharePointClient } from '../lib/client';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ let versionSchema = z.object({
7
+ versionId: z.string().describe('Version ID'),
8
+ lastModifiedDateTime: z.string().optional().describe('When this version was created'),
9
+ lastModifiedBy: z.string().optional().describe('User who created this version'),
10
+ size: z.number().optional().describe('Size of this version in bytes')
11
+ });
12
+
13
+ export let getFileVersions = SlateTool.create(spec, {
14
+ name: 'Get File Versions',
15
+ key: 'get_file_versions',
16
+ description: `Retrieve the version history of a file in a SharePoint document library. Returns all versions with their IDs, timestamps, and authors. Useful for auditing changes or rolling back to a previous version.`,
17
+ tags: {
18
+ readOnly: true,
19
+ destructive: false
20
+ }
21
+ })
22
+ .input(
23
+ z.object({
24
+ driveId: z.string().describe('Drive (document library) ID'),
25
+ itemId: z.string().describe('File item ID')
26
+ })
27
+ )
28
+ .output(
29
+ z.object({
30
+ versions: z.array(versionSchema).describe('File version history'),
31
+ totalCount: z.number().describe('Number of versions')
32
+ })
33
+ )
34
+ .handleInvocation(async ctx => {
35
+ let client = new SharePointClient(ctx.auth.token);
36
+ let data = await client.listDriveItemVersions(ctx.input.driveId, ctx.input.itemId);
37
+
38
+ let versions = (data.value || []).map((v: any) => ({
39
+ versionId: v.id,
40
+ lastModifiedDateTime: v.lastModifiedDateTime,
41
+ lastModifiedBy: v.lastModifiedBy?.user?.displayName,
42
+ size: v.size
43
+ }));
44
+
45
+ return {
46
+ output: {
47
+ versions,
48
+ totalCount: versions.length
49
+ },
50
+ message: `Found **${versions.length}** version(s) for the file.`
51
+ };
52
+ })
53
+ .build();
@@ -0,0 +1,79 @@
1
+ import { SlateTool } from 'slates';
2
+ import { SharePointClient } from '../lib/client';
3
+ import { spec } from '../spec';
4
+ import { oneOfRequiredError } from './errors';
5
+ import { z } from 'zod';
6
+
7
+ export let getSite = SlateTool.create(spec, {
8
+ name: 'Get Site',
9
+ key: 'get_site',
10
+ description: `Retrieve detailed information about a SharePoint site. Look up a site by its ID, hostname and path, or get the root site. Also supports listing subsites of a given site.`,
11
+ instructions: [
12
+ 'Provide **siteId** to look up a specific site by ID.',
13
+ 'Provide **hostname** (e.g. "contoso.sharepoint.com") and optionally **sitePath** (e.g. "sites/marketing") to look up by URL.',
14
+ 'Set **getRootSite** to true to get the tenant root site.'
15
+ ],
16
+ tags: {
17
+ readOnly: true,
18
+ destructive: false
19
+ }
20
+ })
21
+ .input(
22
+ z.object({
23
+ siteId: z.string().optional().describe('SharePoint site ID'),
24
+ hostname: z
25
+ .string()
26
+ .optional()
27
+ .describe('SharePoint site hostname, e.g. "contoso.sharepoint.com"'),
28
+ sitePath: z
29
+ .string()
30
+ .optional()
31
+ .describe('Relative path on the hostname, e.g. "sites/marketing"'),
32
+ getRootSite: z
33
+ .boolean()
34
+ .optional()
35
+ .describe('If true, returns the root site of the tenant')
36
+ })
37
+ )
38
+ .output(
39
+ z.object({
40
+ siteId: z.string().describe('Unique site ID'),
41
+ siteName: z.string().describe('Display name of the site'),
42
+ siteDescription: z.string().nullable().describe('Site description'),
43
+ webUrl: z.string().describe('Full URL of the site'),
44
+ createdDateTime: z.string().optional().describe('When the site was created'),
45
+ lastModifiedDateTime: z.string().optional().describe('When the site was last modified'),
46
+ hostname: z.string().optional().describe('Hostname of the site')
47
+ })
48
+ )
49
+ .handleInvocation(async ctx => {
50
+ let client = new SharePointClient(ctx.auth.token);
51
+ let site: any;
52
+
53
+ if (ctx.input.getRootSite) {
54
+ site = await client.getRootSite();
55
+ } else if (ctx.input.hostname) {
56
+ site = await client.getSiteByHostnameAndPath(ctx.input.hostname, ctx.input.sitePath);
57
+ } else if (ctx.input.siteId) {
58
+ site = await client.getSite(ctx.input.siteId);
59
+ } else {
60
+ throw oneOfRequiredError(
61
+ 'One of siteId, hostname, or getRootSite must be provided.',
62
+ ['siteId', 'hostname', 'getRootSite']
63
+ );
64
+ }
65
+
66
+ return {
67
+ output: {
68
+ siteId: site.id,
69
+ siteName: site.displayName || site.name,
70
+ siteDescription: site.description || null,
71
+ webUrl: site.webUrl,
72
+ createdDateTime: site.createdDateTime,
73
+ lastModifiedDateTime: site.lastModifiedDateTime,
74
+ hostname: site.siteCollection?.hostname
75
+ },
76
+ message: `Retrieved site **${site.displayName || site.name}** at ${site.webUrl}.`
77
+ };
78
+ })
79
+ .build();
@@ -0,0 +1,12 @@
1
+ export * from './get-site';
2
+ export * from './list-sites';
3
+ export * from './search';
4
+ export * from './search-drive';
5
+ export * from './manage-list';
6
+ export * from './manage-list-items';
7
+ export * from './manage-file';
8
+ export * from './get-drive';
9
+ export * from './get-file-versions';
10
+ export * from './manage-permissions';
11
+ export * from './manage-columns';
12
+ export * from './get-content-types';
@@ -0,0 +1,76 @@
1
+ import { SlateTool } from 'slates';
2
+ import { SharePointClient } from '../lib/client';
3
+ import { spec } from '../spec';
4
+ import { oneOfRequiredError } from './errors';
5
+ import { z } from 'zod';
6
+
7
+ let siteSchema = z.object({
8
+ siteId: z.string().describe('Unique site ID'),
9
+ siteName: z.string().describe('Display name of the site'),
10
+ siteDescription: z.string().nullable().describe('Site description'),
11
+ webUrl: z.string().describe('Full URL of the site'),
12
+ createdDateTime: z.string().optional().describe('When the site was created'),
13
+ lastModifiedDateTime: z.string().optional().describe('When the site was last modified')
14
+ });
15
+
16
+ export let listSites = SlateTool.create(spec, {
17
+ name: 'List Sites',
18
+ key: 'list_sites',
19
+ description: `Search for SharePoint sites by keyword, or list subsites of a given site. Returns a list of matching sites with their IDs and URLs.`,
20
+ instructions: [
21
+ 'Provide a **searchQuery** to find sites across the tenant.',
22
+ 'Provide a **parentSiteId** to list subsites of a specific site.'
23
+ ],
24
+ tags: {
25
+ readOnly: true,
26
+ destructive: false
27
+ }
28
+ })
29
+ .input(
30
+ z.object({
31
+ searchQuery: z
32
+ .string()
33
+ .optional()
34
+ .describe('Keyword to search for sites across the tenant'),
35
+ parentSiteId: z.string().optional().describe('Site ID to list subsites of')
36
+ })
37
+ )
38
+ .output(
39
+ z.object({
40
+ sites: z.array(siteSchema).describe('List of matching sites'),
41
+ totalCount: z.number().describe('Number of sites returned')
42
+ })
43
+ )
44
+ .handleInvocation(async ctx => {
45
+ let client = new SharePointClient(ctx.auth.token);
46
+ let result: any;
47
+
48
+ if (ctx.input.parentSiteId) {
49
+ result = await client.listSubsites(ctx.input.parentSiteId);
50
+ } else if (ctx.input.searchQuery) {
51
+ result = await client.searchSites(ctx.input.searchQuery);
52
+ } else {
53
+ throw oneOfRequiredError(
54
+ 'One of searchQuery or parentSiteId must be provided.',
55
+ ['searchQuery', 'parentSiteId']
56
+ );
57
+ }
58
+
59
+ let sites = (result.value || []).map((site: any) => ({
60
+ siteId: site.id,
61
+ siteName: site.displayName || site.name,
62
+ siteDescription: site.description || null,
63
+ webUrl: site.webUrl,
64
+ createdDateTime: site.createdDateTime,
65
+ lastModifiedDateTime: site.lastModifiedDateTime
66
+ }));
67
+
68
+ return {
69
+ output: {
70
+ sites,
71
+ totalCount: sites.length
72
+ },
73
+ message: `Found **${sites.length}** site(s)${ctx.input.searchQuery ? ` matching "${ctx.input.searchQuery}"` : ''}.`
74
+ };
75
+ })
76
+ .build();
@@ -0,0 +1,159 @@
1
+ import { SlateTool } from 'slates';
2
+ import { SharePointClient } from '../lib/client';
3
+ import { spec } from '../spec';
4
+ import { z } from 'zod';
5
+
6
+ let columnOutputSchema = z.object({
7
+ columnId: z.string().describe('Column ID'),
8
+ columnName: z.string().describe('Internal name of the column'),
9
+ displayName: z.string().describe('Display name of the column'),
10
+ columnDescription: z.string().optional().describe('Column description'),
11
+ columnType: z
12
+ .string()
13
+ .optional()
14
+ .describe('Column type (text, number, boolean, dateTime, choice, etc.)'),
15
+ required: z.boolean().optional().describe('Whether the column is required'),
16
+ readOnly: z.boolean().optional().describe('Whether the column is read-only'),
17
+ hidden: z.boolean().optional().describe('Whether the column is hidden'),
18
+ choices: z.array(z.string()).optional().describe('Available choices (for choice columns)')
19
+ });
20
+
21
+ export let manageColumns = SlateTool.create(spec, {
22
+ name: 'Manage Columns',
23
+ key: 'manage_columns',
24
+ description: `List, create, update, or delete columns (fields) on a SharePoint list. Columns define the schema and metadata structure of a list. Supports various column types including text, number, boolean, dateTime, choice, currency, and personOrGroup.`,
25
+ instructions: [
26
+ 'Set **action** to "list" to view all columns, "create" to add a new column, "update" to modify an existing column, or "delete" to remove a column.',
27
+ 'For "create", provide **columnName**, **columnType**, and optionally **choices** (for choice columns).',
28
+ 'For "update", provide **columnId** and the fields to update.'
29
+ ],
30
+ tags: {
31
+ destructive: false,
32
+ readOnly: false
33
+ }
34
+ })
35
+ .input(
36
+ z.object({
37
+ action: z
38
+ .enum(['list', 'create', 'update', 'delete'])
39
+ .describe('Column action to perform'),
40
+ siteId: z.string().describe('SharePoint site ID'),
41
+ listId: z.string().describe('SharePoint list ID'),
42
+ columnId: z.string().optional().describe('Column ID (required for update, delete)'),
43
+ columnName: z.string().optional().describe('Column name (for create)'),
44
+ columnDescription: z
45
+ .string()
46
+ .optional()
47
+ .describe('Column description (for create, update)'),
48
+ columnType: z
49
+ .enum(['text', 'number', 'boolean', 'dateTime', 'choice', 'currency', 'personOrGroup'])
50
+ .optional()
51
+ .describe('Column type (for create)'),
52
+ required: z
53
+ .boolean()
54
+ .optional()
55
+ .describe('Whether the column is required (for create, update)'),
56
+ choices: z
57
+ .array(z.string())
58
+ .optional()
59
+ .describe('Available choices for choice columns (for create)')
60
+ })
61
+ )
62
+ .output(
63
+ z.object({
64
+ column: columnOutputSchema.optional().describe('Column details (for create, update)'),
65
+ columns: z
66
+ .array(columnOutputSchema)
67
+ .optional()
68
+ .describe('List of columns (for list action)'),
69
+ deleted: z.boolean().optional().describe('Whether the column was deleted')
70
+ })
71
+ )
72
+ .handleInvocation(async ctx => {
73
+ let client = new SharePointClient(ctx.auth.token);
74
+ let {
75
+ action,
76
+ siteId,
77
+ listId,
78
+ columnId,
79
+ columnName,
80
+ columnDescription,
81
+ columnType,
82
+ required,
83
+ choices
84
+ } = ctx.input;
85
+
86
+ let detectType = (col: any): string => {
87
+ if (col.text) return 'text';
88
+ if (col.number) return 'number';
89
+ if (col.boolean) return 'boolean';
90
+ if (col.dateTime) return 'dateTime';
91
+ if (col.choice) return 'choice';
92
+ if (col.currency) return 'currency';
93
+ if (col.personOrGroup) return 'personOrGroup';
94
+ if (col.lookup) return 'lookup';
95
+ if (col.calculated) return 'calculated';
96
+ return 'unknown';
97
+ };
98
+
99
+ let mapColumn = (col: any) => ({
100
+ columnId: col.id,
101
+ columnName: col.name,
102
+ displayName: col.displayName || col.name,
103
+ columnDescription: col.description,
104
+ columnType: detectType(col),
105
+ required: col.required,
106
+ readOnly: col.readOnly,
107
+ hidden: col.hidden,
108
+ choices: col.choice?.choices
109
+ });
110
+
111
+ switch (action) {
112
+ case 'list': {
113
+ let data = await client.listColumns(siteId, listId);
114
+ let columns = (data.value || []).map(mapColumn);
115
+ return {
116
+ output: { columns },
117
+ message: `Found **${columns.length}** column(s) on the list.`
118
+ };
119
+ }
120
+
121
+ case 'create': {
122
+ if (!columnName) throw new Error('columnName is required for create.');
123
+ if (!columnType) throw new Error('columnType is required for create.');
124
+ let column = await client.createColumn(siteId, listId, {
125
+ name: columnName,
126
+ description: columnDescription,
127
+ type: columnType,
128
+ required,
129
+ choices
130
+ });
131
+ return {
132
+ output: { column: mapColumn(column) },
133
+ message: `Created column **${columnName}** (${columnType}).`
134
+ };
135
+ }
136
+
137
+ case 'update': {
138
+ if (!columnId) throw new Error('columnId is required for update.');
139
+ let updates: { description?: string; required?: boolean } = {};
140
+ if (columnDescription !== undefined) updates.description = columnDescription;
141
+ if (required !== undefined) updates.required = required;
142
+ let column = await client.updateColumn(siteId, listId, columnId, updates);
143
+ return {
144
+ output: { column: mapColumn(column) },
145
+ message: `Updated column \`${columnId}\`.`
146
+ };
147
+ }
148
+
149
+ case 'delete': {
150
+ if (!columnId) throw new Error('columnId is required for delete.');
151
+ await client.deleteColumn(siteId, listId, columnId);
152
+ return {
153
+ output: { deleted: true },
154
+ message: `Deleted column \`${columnId}\`.`
155
+ };
156
+ }
157
+ }
158
+ })
159
+ .build();