@mustafaaksoy41/sharepoint-kit 0.1.2
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 +293 -0
- package/dist/bin/sp-generate-types.js +784 -0
- package/dist/bin/sp-generate-types.js.map +1 -0
- package/dist/chunk-2FU6XS6S.cjs +142 -0
- package/dist/chunk-2FU6XS6S.cjs.map +1 -0
- package/dist/chunk-MLY32NZB.js +131 -0
- package/dist/chunk-MLY32NZB.js.map +1 -0
- package/dist/chunk-V6K5IFVV.cjs +253 -0
- package/dist/chunk-V6K5IFVV.cjs.map +1 -0
- package/dist/chunk-VOGWZXJY.js +246 -0
- package/dist/chunk-VOGWZXJY.js.map +1 -0
- package/dist/cli/index.cjs +516 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +117 -0
- package/dist/cli/index.d.ts +117 -0
- package/dist/cli/index.js +505 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/components/index.cjs +509 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +118 -0
- package/dist/components/index.d.ts +118 -0
- package/dist/components/index.js +494 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config-loader-Nbidwviq.d.cts +33 -0
- package/dist/config-loader-Nbidwviq.d.ts +33 -0
- package/dist/hooks/index.cjs +45 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +51 -0
- package/dist/hooks/index.d.ts +51 -0
- package/dist/hooks/index.js +24 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.cjs +32 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/sp-client-A9dM9oYp.d.ts +31 -0
- package/dist/sp-client-DTChApOB.d.cts +31 -0
- package/dist/types-Dk0jbejG.d.cts +108 -0
- package/dist/types-Dk0jbejG.d.ts +108 -0
- package/package.json +123 -0
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# @mustafaaksoy41/sharepoint-kit
|
|
2
|
+
|
|
3
|
+
Full-featured SharePoint Graph API client, React hooks, Radix UI components, and CLI type generator for TypeScript projects. Supports Next.js App Router and Pages Router.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Data Client** - Type-safe CRUD operations via Microsoft Graph API with retry/throttle handling
|
|
8
|
+
- **React Hooks** - SWR-based hooks (`useSpList`, `useSpItem`, `useSpCreate`, `useSpUpdate`, `useSpDelete`)
|
|
9
|
+
- **Radix UI Components** - Ready-to-use `<SpListTable>`, `<SpItemForm>`, `<SpItemCard>`, `<SpErrorBoundary>`
|
|
10
|
+
- **CLI Type Generator** - Auto-generate TypeScript interfaces from your SharePoint content types
|
|
11
|
+
- **Config-based** - Each user defines their own SharePoint structure via `sharepoint.config.ts`
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @mustafaaksoy41/sharepoint-kit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Peer Dependencies
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install react react-dom swr @radix-ui/themes @radix-ui/react-icons
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### 1. Generate Types from SharePoint
|
|
28
|
+
|
|
29
|
+
Create a `sharepoint.config.ts`:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
export default {
|
|
33
|
+
siteId: 'root',
|
|
34
|
+
tenantId: process.env.SHAREPOINT_TENANT_ID,
|
|
35
|
+
clientId: process.env.SHAREPOINT_CLIENT_ID,
|
|
36
|
+
defaultStrategy: 'interactive',
|
|
37
|
+
contentTypes: [
|
|
38
|
+
{
|
|
39
|
+
listName: 'Faturalar',
|
|
40
|
+
contentTypeName: 'Fatura Denemesi',
|
|
41
|
+
outputType: 'Invoice',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
contentTypeName: 'Belge',
|
|
45
|
+
outputType: 'Document',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
options: {
|
|
49
|
+
outputDir: './generated',
|
|
50
|
+
fieldNameMapping: {
|
|
51
|
+
'Fatura_x0020_Numaras_x0131_': 'faturaNo',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Run the CLI:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx sp-generate-types --config sharepoint.config.ts
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This generates `./generated/sp-types.ts`:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
export interface Invoice {
|
|
67
|
+
faturaNo?: string;
|
|
68
|
+
Tutar?: number;
|
|
69
|
+
Title?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface Document {
|
|
73
|
+
Title?: string;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Use the Data Client
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { createSpClient } from '@mustafaaksoy41/sharepoint-kit';
|
|
81
|
+
import type { Invoice } from './generated/sp-types';
|
|
82
|
+
|
|
83
|
+
const client = createSpClient({
|
|
84
|
+
siteId: 'root',
|
|
85
|
+
getAccessToken: async () => yourTokenFunction(),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// CRUD operations with full type safety
|
|
89
|
+
const items = await client.getListItems<Invoice>({
|
|
90
|
+
listId: '50fc630f-...',
|
|
91
|
+
contentTypeName: 'Fatura Denemesi',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const item = await client.getItem<Invoice>({ listId: '...', itemId: '6' });
|
|
95
|
+
const created = await client.createItem<Invoice>({ listId: '...', fields: { Tutar: 500 } });
|
|
96
|
+
const updated = await client.updateItem<Invoice>({ listId: '...', itemId: '6', fields: { Tutar: 600 } });
|
|
97
|
+
await client.deleteItem({ listId: '...', itemId: '6' });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. Use React Hooks
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { SpProvider } from '@mustafaaksoy41/sharepoint-kit/components';
|
|
104
|
+
import { useSpList, useSpItem, useSpCreate } from '@mustafaaksoy41/sharepoint-kit/hooks';
|
|
105
|
+
import type { Invoice } from './generated/sp-types';
|
|
106
|
+
|
|
107
|
+
// Wrap your app
|
|
108
|
+
function App() {
|
|
109
|
+
return (
|
|
110
|
+
<SpProvider config={{ siteId: 'root', getAccessToken }}>
|
|
111
|
+
<InvoiceList />
|
|
112
|
+
</SpProvider>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function InvoiceList() {
|
|
117
|
+
const { data, isLoading, error } = useSpList<Invoice>({
|
|
118
|
+
listId: '50fc630f-...',
|
|
119
|
+
contentTypeName: 'Fatura Denemesi',
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (isLoading) return <p>Loading...</p>;
|
|
123
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<ul>
|
|
127
|
+
{data?.map((item) => (
|
|
128
|
+
<li key={item.id}>{item.fields.Title} - {item.fields.Tutar}</li>
|
|
129
|
+
))}
|
|
130
|
+
</ul>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 4. Use Radix UI Components
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
import { SpProvider, SpListTable, SpItemForm, SpErrorBoundary } from '@mustafaaksoy41/sharepoint-kit/components';
|
|
139
|
+
import type { Invoice } from './generated/sp-types';
|
|
140
|
+
|
|
141
|
+
function App() {
|
|
142
|
+
return (
|
|
143
|
+
<SpProvider config={{ siteId: 'root', getAccessToken }}>
|
|
144
|
+
<SpErrorBoundary onAuthError={() => router.push('/login')}>
|
|
145
|
+
<SpListTable<Invoice>
|
|
146
|
+
listId="50fc630f-..."
|
|
147
|
+
contentTypeName="Fatura Denemesi"
|
|
148
|
+
columns={[
|
|
149
|
+
{ key: 'faturaNo', label: 'Fatura No' },
|
|
150
|
+
{ key: 'Tutar', label: 'Tutar', format: 'currency' },
|
|
151
|
+
]}
|
|
152
|
+
onRowClick={(item, id) => router.push(`/invoices/${id}`)}
|
|
153
|
+
/>
|
|
154
|
+
</SpErrorBoundary>
|
|
155
|
+
</SpProvider>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Authentication
|
|
161
|
+
|
|
162
|
+
You can use **Microsoft Login** (recommended) or **manual token / bypass**.
|
|
163
|
+
|
|
164
|
+
### Microsoft Login
|
|
165
|
+
|
|
166
|
+
In your app `.env` add (use `NEXT_PUBLIC_` so the browser can read them):
|
|
167
|
+
|
|
168
|
+
```env
|
|
169
|
+
NEXT_PUBLIC_SHAREPOINT_TENANT_ID=your-tenant-id
|
|
170
|
+
NEXT_PUBLIC_SHAREPOINT_CLIENT_ID=your-client-id
|
|
171
|
+
NEXT_PUBLIC_SHAREPOINT_REDIRECT_URI=http://localhost:3000
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
In Azure AD: App Registration → Authentication → add **SPA** with this Redirect URI. API permissions: **Sites.Read.All** (Delegated).
|
|
175
|
+
|
|
176
|
+
Wrap your app with `SpAuthProvider` + `loginConfig`:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
import { SpAuthProvider, SpProviderWithAuth, type SpLoginConfig } from '@mustafaaksoy41/sharepoint-kit/components';
|
|
180
|
+
import { Theme } from '@radix-ui/themes';
|
|
181
|
+
|
|
182
|
+
const loginConfig: SpLoginConfig = {
|
|
183
|
+
tenantId: process.env.NEXT_PUBLIC_SHAREPOINT_TENANT_ID!,
|
|
184
|
+
clientId: process.env.NEXT_PUBLIC_SHAREPOINT_CLIENT_ID!,
|
|
185
|
+
redirectUri: process.env.NEXT_PUBLIC_SHAREPOINT_REDIRECT_URI!,
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
<Theme>
|
|
189
|
+
<SpAuthProvider loginConfig={loginConfig}>
|
|
190
|
+
<SpProviderWithAuth siteId="root">
|
|
191
|
+
{/* Your app */}
|
|
192
|
+
</SpProviderWithAuth>
|
|
193
|
+
</SpAuthProvider>
|
|
194
|
+
</Theme>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Users will see "Sign in with Microsoft"; after login the token is stored and used for Graph API calls.
|
|
198
|
+
|
|
199
|
+
### Manual token or bypass (development)
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
<SpAuthProvider bypassEnabled={true}>
|
|
203
|
+
<SpProviderWithAuth siteId="root">
|
|
204
|
+
{/* Your app */}
|
|
205
|
+
</SpProviderWithAuth>
|
|
206
|
+
</SpAuthProvider>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## CLI Usage
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Interactive mode (default)
|
|
213
|
+
npx sp-generate-types --config sharepoint.config.ts
|
|
214
|
+
|
|
215
|
+
# Non-interactive mode (for CI/CD)
|
|
216
|
+
npx sp-generate-types --config sharepoint.config.ts --non-interactive
|
|
217
|
+
|
|
218
|
+
# With strategy
|
|
219
|
+
npx sp-generate-types --config sharepoint.config.ts --non-interactive --strategy first
|
|
220
|
+
# Strategies: interactive | first | error | all
|
|
221
|
+
|
|
222
|
+
# Clear cache
|
|
223
|
+
npx sp-generate-types --config sharepoint.config.ts --clear-cache
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Config Options
|
|
227
|
+
|
|
228
|
+
| Field | Type | Required | Description |
|
|
229
|
+
|-------|------|----------|-------------|
|
|
230
|
+
| `siteId` | `string` | Yes | SharePoint site ID |
|
|
231
|
+
| `tenantId` | `string` | Yes | Azure AD tenant ID |
|
|
232
|
+
| `clientId` | `string` | Yes | Azure AD app client ID |
|
|
233
|
+
| `defaultStrategy` | `string` | No | Default list selection strategy |
|
|
234
|
+
| `contentTypes` | `array` | Yes | Content types to generate |
|
|
235
|
+
| `options.outputDir` | `string` | No | Output directory (default: `./generated`) |
|
|
236
|
+
| `options.fieldNameMapping` | `object` | No | SharePoint field name to TS property name mapping |
|
|
237
|
+
|
|
238
|
+
### Content Type Config
|
|
239
|
+
|
|
240
|
+
| Field | Type | Required | Description |
|
|
241
|
+
|-------|------|----------|-------------|
|
|
242
|
+
| `contentTypeName` | `string` | Yes | SharePoint content type name |
|
|
243
|
+
| `outputType` | `string` | Yes | TypeScript interface name |
|
|
244
|
+
| `listId` | `string` | No | SharePoint list ID (optional) |
|
|
245
|
+
| `listName` | `string` | No | SharePoint list display name (optional) |
|
|
246
|
+
| `strategy` | `string` | No | Override default strategy |
|
|
247
|
+
|
|
248
|
+
### List Resolution Logic
|
|
249
|
+
|
|
250
|
+
1. If `listId` is provided, use it directly
|
|
251
|
+
2. If `listName` is provided, find the list by name
|
|
252
|
+
3. If neither is provided, scan all lists for the content type
|
|
253
|
+
- If found in one list, use it
|
|
254
|
+
- If found in multiple lists, ask the user (interactive) or apply strategy
|
|
255
|
+
|
|
256
|
+
## Error Handling
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { SpError, SpAuthError, SpNotFoundError, SpThrottleError, SpValidationError } from '@mustafaaksoy41/sharepoint-kit';
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
await client.getItem({ listId, itemId: '999' });
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (error instanceof SpAuthError) {
|
|
265
|
+
// 401/403 - redirect to login
|
|
266
|
+
} else if (error instanceof SpNotFoundError) {
|
|
267
|
+
// 404 - item not found
|
|
268
|
+
} else if (error instanceof SpThrottleError) {
|
|
269
|
+
// 429 - retryAfter available
|
|
270
|
+
console.log(`Retry after ${error.retryAfter} seconds`);
|
|
271
|
+
} else if (error instanceof SpValidationError) {
|
|
272
|
+
// 400 - validation errors
|
|
273
|
+
console.log(error.fieldErrors);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Type Mapping
|
|
279
|
+
|
|
280
|
+
| SharePoint Type | TypeScript Type |
|
|
281
|
+
|----------------|-----------------|
|
|
282
|
+
| Text, Note, Choice | `string` |
|
|
283
|
+
| MultiChoice | `string[]` |
|
|
284
|
+
| Number, Currency | `number` |
|
|
285
|
+
| Boolean | `boolean` |
|
|
286
|
+
| DateTime | `string` (ISO) |
|
|
287
|
+
| Lookup | `{ id: number; value: string }` |
|
|
288
|
+
| User | `{ id: number; email: string; displayName: string }` |
|
|
289
|
+
| URL | `{ url: string; description: string }` |
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT
|