@chill-sharp/ts-client 1.1.12 → 1.1.15
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 +705 -705
- package/package.json +46 -46
- package/src/client.ts +1809 -1809
- package/src/errors.ts +34 -34
- package/src/index.ts +87 -87
- package/src/test_tmp.txt +1 -1
- package/src/version.ts +20 -20
package/README.md
CHANGED
|
@@ -1,707 +1,707 @@
|
|
|
1
|
-
# @chill-sharp/ts-client
|
|
2
|
-
|
|
3
|
-
TypeScript client for a generic ChillSharp service.
|
|
4
|
-
|
|
5
|
-
This package targets the standard ChillSharp HTTP surface:
|
|
6
|
-
|
|
7
|
-
- core Chill API at `/api/chill`
|
|
8
|
-
- schema API at `/api/chill-schema`
|
|
9
|
-
- auth API at `/api/chill-auth`
|
|
10
|
-
- i18n API at `/api/chill-i18n`
|
|
11
|
-
- entity-change notifications at `/api/chill/notify`
|
|
12
|
-
|
|
13
|
-
It is intentionally lightweight. Payloads are plain JavaScript objects so the client can work against arbitrary ChillSharp models without code generation.
|
|
14
|
-
|
|
15
|
-
## Install
|
|
16
|
-
|
|
17
|
-
From the repository root:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
cd extra/chill-sharp-ts-client
|
|
21
|
-
npm install
|
|
22
|
-
npm run build
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Or from another project:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
npm install ../extra/chill-sharp-ts-client
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The client uses the runtime `fetch` API available in modern browsers and Node.js 18+.
|
|
32
|
-
|
|
33
|
-
## Local Linking
|
|
34
|
-
|
|
35
|
-
This package now builds automatically on `npm install`, `npm pack`, and `npm link` through the `prepare` and `prepack` scripts.
|
|
36
|
-
|
|
37
|
-
Example local workflow:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
cd extra/chill-sharp-ts-client
|
|
41
|
-
npm install
|
|
42
|
-
npm link
|
|
43
|
-
|
|
44
|
-
cd path/to/your-app
|
|
45
|
-
npm link @chill-sharp/ts-client
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Quick Start
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import { ChillSharpClient } from "@chill-sharp/ts-client";
|
|
52
|
-
|
|
53
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
54
|
-
cultureName: "it-IT"
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const created = await client.create({
|
|
58
|
-
ChillType: "Model.Post",
|
|
59
|
-
Guid: "00000000-0000-0000-0000-000000000001",
|
|
60
|
-
Properties: {
|
|
61
|
-
Title: "Hello",
|
|
62
|
-
Author: "Ada Lovelace"
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const found = await client.find({
|
|
67
|
-
ChillType: "Model.Post",
|
|
68
|
-
Guid: created.Guid as string
|
|
69
|
-
});
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Construction Modes
|
|
73
|
-
|
|
74
|
-
### Anonymous or externally authenticated
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
78
|
-
cultureName: "it-IT"
|
|
79
|
-
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
SignalR entity-change subscriptions use the same bearer token flow as the other authenticated endpoints. Browser SignalR connections send credentials by default; if your app needs a non-credentialed cross-origin negotiate request, set `signalRWithCredentials: false` when creating the client.
|
|
83
|
-
|
|
84
|
-
### With an existing access token
|
|
85
|
-
|
|
86
|
-
```ts
|
|
87
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
88
|
-
accessToken: "your-jwt-token",
|
|
89
|
-
cultureName: "it-IT"
|
|
90
|
-
});
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### With username and password
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
97
|
-
username: "root",
|
|
98
|
-
password: "Pass123$",
|
|
99
|
-
cultureName: "it-IT"
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
If the service supports ChillSharp auth endpoints, the client can log in and refresh tokens automatically.
|
|
104
|
-
|
|
105
|
-
## Core ChillSharp Operations
|
|
106
|
-
|
|
107
|
-
Query payloads can now include:
|
|
108
|
-
|
|
109
|
-
- `ordering.propertyName`
|
|
110
|
-
- `ordering.direction`
|
|
111
|
-
|
|
112
|
-
If you omit `ordering`, the backend defaults to `Position`. Entity payloads also include `position`, which defaults to `0`.
|
|
113
|
-
|
|
114
|
-
### Query
|
|
115
|
-
|
|
116
|
-
Use `query()` when `ChillType` points to a concrete query type such as `Query.PostQuery`.
|
|
117
|
-
|
|
118
|
-
```ts
|
|
119
|
-
const result = await client.query({
|
|
120
|
-
chillType: "Query.PostQuery",
|
|
121
|
-
properties: {
|
|
122
|
-
title: "Hello"
|
|
123
|
-
},
|
|
124
|
-
ordering: {
|
|
125
|
-
propertyName: "Position",
|
|
126
|
-
direction: "ASC"
|
|
127
|
-
},
|
|
128
|
-
resultProperties: [
|
|
129
|
-
{ name: "Guid" },
|
|
130
|
-
{ name: "Title" },
|
|
131
|
-
{ name: "Author" }
|
|
132
|
-
]
|
|
133
|
-
});
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
When `ordering.propertyName` points to a Chill entity reference such as `Blog`, the backend orders by `Blog.Label`.
|
|
137
|
-
|
|
138
|
-
### Lookup
|
|
139
|
-
|
|
140
|
-
Use `lookup()` when `ChillType` points to an entity type and you only need generic full-text search.
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
const result = await client.lookup({
|
|
144
|
-
chillType: "Model.Post",
|
|
145
|
-
properties: {
|
|
146
|
-
fullTextSearch: "Ada Lovelace"
|
|
147
|
-
},
|
|
148
|
-
ordering: {
|
|
149
|
-
propertyName: "Blog",
|
|
150
|
-
direction: "ASC"
|
|
151
|
-
},
|
|
152
|
-
resultProperties: [
|
|
153
|
-
{ name: "Guid" },
|
|
154
|
-
{ name: "Title" },
|
|
155
|
-
{ name: "Author" }
|
|
156
|
-
]
|
|
157
|
-
});
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Find
|
|
161
|
-
|
|
162
|
-
```ts
|
|
163
|
-
const entity = await client.find({
|
|
164
|
-
ChillType: "Model.Post",
|
|
165
|
-
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
166
|
-
});
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Create
|
|
170
|
-
|
|
171
|
-
```ts
|
|
172
|
-
const entity = await client.create({
|
|
173
|
-
chillType: "Model.Post",
|
|
174
|
-
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
175
|
-
position: 10,
|
|
176
|
-
properties: {
|
|
177
|
-
title: "New title",
|
|
178
|
-
author: "Grace Hopper"
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Update
|
|
184
|
-
|
|
185
|
-
```ts
|
|
186
|
-
const updated = await client.update({
|
|
187
|
-
chillType: "Model.Post",
|
|
188
|
-
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
189
|
-
position: 20,
|
|
190
|
-
properties: {
|
|
191
|
-
title: "Updated title"
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Delete
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
await client.delete({
|
|
200
|
-
ChillType: "Model.Post",
|
|
201
|
-
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Attachments
|
|
206
|
-
|
|
207
|
-
Use the attachment helpers when the host enables `ChillSharp.Attachment`.
|
|
208
|
-
|
|
209
|
-
```ts
|
|
210
|
-
const post = {
|
|
211
|
-
ChillType: "Model.Post",
|
|
212
|
-
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const uploaded = await client.uploadAttachment(post, {
|
|
216
|
-
fileName: "contract.txt",
|
|
217
|
-
content: new Blob(["hello attachment"], { type: "text/plain" }),
|
|
218
|
-
contentType: "text/plain"
|
|
219
|
-
}, {
|
|
220
|
-
title: "Contract",
|
|
221
|
-
description: "Signed draft",
|
|
222
|
-
isPublic: false
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const attachments = await client.getAttachments(post);
|
|
226
|
-
const fileBlob = await client.downloadAttachment(uploaded[0]);
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Chunk
|
|
230
|
-
|
|
231
|
-
Use `chunk()` when several operations should be sent in one HTTP request.
|
|
232
|
-
The operations are executed in `Index` order when you provide it. For write-heavy batches, set `Index` explicitly.
|
|
233
|
-
|
|
234
|
-
```ts
|
|
235
|
-
const operations = await client.chunk([
|
|
236
|
-
{
|
|
237
|
-
Index: 0,
|
|
238
|
-
Verb: "create",
|
|
239
|
-
Entity: {
|
|
240
|
-
ChillType: "Model.Post",
|
|
241
|
-
Guid: "11111111-1111-1111-1111-111111111111",
|
|
242
|
-
Properties: { Title: "First", Author: "A" }
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
Index: 1,
|
|
247
|
-
Verb: "create",
|
|
248
|
-
Entity: {
|
|
249
|
-
ChillType: "Model.Post",
|
|
250
|
-
Guid: "22222222-2222-2222-2222-222222222222",
|
|
251
|
-
Properties: { Title: "Second", Author: "B" }
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
Index: 2,
|
|
256
|
-
Verb: "update",
|
|
257
|
-
Entity: {
|
|
258
|
-
ChillType: "Model.Post",
|
|
259
|
-
Guid: "11111111-1111-1111-1111-111111111111",
|
|
260
|
-
Properties: { Title: "First updated" }
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
]);
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Chunk inside one transaction
|
|
267
|
-
|
|
268
|
-
Wrap the batch with `transaction` and `commit` when all write operations must succeed or fail together.
|
|
269
|
-
|
|
270
|
-
```ts
|
|
271
|
-
const operations = await client.chunk([
|
|
272
|
-
{
|
|
273
|
-
Index: 0,
|
|
274
|
-
Verb: "transaction"
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
Index: 1,
|
|
278
|
-
Verb: "create",
|
|
279
|
-
Entity: {
|
|
280
|
-
ChillType: "Model.Blog",
|
|
281
|
-
Guid: crypto.randomUUID(),
|
|
282
|
-
Properties: {
|
|
283
|
-
Name: "Batch blog",
|
|
284
|
-
Url: "https://example.local/batch-blog"
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
Index: 2,
|
|
290
|
-
Verb: "create",
|
|
291
|
-
Entity: {
|
|
292
|
-
ChillType: "Model.Post",
|
|
293
|
-
Guid: crypto.randomUUID(),
|
|
294
|
-
Properties: {
|
|
295
|
-
Title: "Batch post",
|
|
296
|
-
Author: "Grace Hopper"
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
Index: 3,
|
|
302
|
-
Verb: "commit"
|
|
303
|
-
}
|
|
304
|
-
]);
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
Use this pattern only for the operations that must share the same database transaction. If one write fails before `commit`, the transaction is not committed.
|
|
308
|
-
|
|
309
|
-
### Test
|
|
310
|
-
|
|
311
|
-
```ts
|
|
312
|
-
const status = await client.test();
|
|
313
|
-
// "ChillSharp is up and running!"
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
Use this to verify the Chill endpoint is reachable before sending API payloads.
|
|
317
|
-
|
|
318
|
-
## Notification Operations
|
|
319
|
-
|
|
320
|
-
### Subscribe to all changes for a chill type
|
|
321
|
-
|
|
322
|
-
```ts
|
|
323
|
-
const subscription = await client.subscribeToEntityChanges("Model.Post", (changes) => {
|
|
324
|
-
for (const change of changes) {
|
|
325
|
-
console.log(change.chillType, change.guid, change.action);
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Subscribe to one entity only
|
|
331
|
-
|
|
332
|
-
```ts
|
|
333
|
-
const subscription = await client.subscribeToEntityChanges(
|
|
334
|
-
"Model.Post",
|
|
335
|
-
(changes) => {
|
|
336
|
-
console.log("single entity changed", changes);
|
|
337
|
-
},
|
|
338
|
-
"f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
339
|
-
);
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### Unsubscribe
|
|
343
|
-
|
|
344
|
-
```ts
|
|
345
|
-
await subscription.unsubscribe();
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Close the shared notification connection
|
|
349
|
-
|
|
350
|
-
```ts
|
|
351
|
-
await client.disconnectEntityChanges();
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
The notification callback receives arrays shaped like:
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
[
|
|
358
|
-
{
|
|
359
|
-
chillType: "Model.Post",
|
|
360
|
-
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
361
|
-
action: "UPDATED"
|
|
362
|
-
}
|
|
363
|
-
]
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
## Schema Operations
|
|
367
|
-
|
|
368
|
-
### Get schema
|
|
369
|
-
|
|
370
|
-
```ts
|
|
371
|
-
const schema = await client.getSchema("Model.Post", "default");
|
|
372
|
-
console.log(schema.handleAttachments);
|
|
373
|
-
console.log(schema.relations);
|
|
374
|
-
|
|
375
|
-
// Override the constructor default for one call
|
|
376
|
-
const englishSchema = await client.getSchema("Model.Post", "default", "en-GB");
|
|
377
|
-
|
|
378
|
-
// Refresh a persisted schema from the current runtime model for one call.
|
|
379
|
-
// Existing properties keep their saved metadata, new model properties are added,
|
|
380
|
-
// and properties no longer present on the model are removed.
|
|
381
|
-
const refreshedSchema = await client.getSchema("Model.Post", "default", undefined, true);
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
Entity schemas now also expose `relations`, derived from annotated collection properties. Each relation entry includes:
|
|
385
|
-
|
|
386
|
-
- `chillType` for the child or relation entity
|
|
387
|
-
- `chillQuery` for the resolved query type when available
|
|
388
|
-
- `fixedValues` and `fixedQueryValues` containing the `@{mock}` parent placeholder keyed by the child FK/reference property name
|
|
389
|
-
- `relationLabel` with `labelGuid`, `primaryDefaultText`, and `secondaryDefaultText`
|
|
390
|
-
|
|
391
|
-
### Get schema list
|
|
392
|
-
|
|
393
|
-
```ts
|
|
394
|
-
const schemaList = await client.getSchemaList();
|
|
395
|
-
const englishSchemaList = await client.getSchemaList("en-GB");
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### Set schema
|
|
399
|
-
|
|
400
|
-
```ts
|
|
401
|
-
await client.setSchema({
|
|
402
|
-
ChillType: "Model.Post",
|
|
403
|
-
ChillViewCode: "default",
|
|
404
|
-
DisplayName: "Post",
|
|
405
|
-
Properties: [
|
|
406
|
-
{
|
|
407
|
-
Name: "Title",
|
|
408
|
-
DisplayName: "Post title"
|
|
409
|
-
}
|
|
410
|
-
]
|
|
411
|
-
});
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
### Get entity options
|
|
415
|
-
|
|
416
|
-
```ts
|
|
417
|
-
const options = await client.getEntityOptions("Model.Post");
|
|
418
|
-
console.log(options.handleAttachments);
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### Set entity options
|
|
422
|
-
|
|
423
|
-
```ts
|
|
424
|
-
const options = await client.setEntityOptions({
|
|
425
|
-
chillType: "Model.Post",
|
|
426
|
-
checksumEnabled: true,
|
|
427
|
-
handleAttachments: true,
|
|
428
|
-
labelFormatString: "{Title}",
|
|
429
|
-
shortLabelFormatString: "{Title}",
|
|
430
|
-
fullTextContentFormatString: "{Title} {Author}",
|
|
431
|
-
enableMCP: true,
|
|
432
|
-
mcpDescription: "Post resource exposed to MCP clients.",
|
|
433
|
-
changeLogEnabled: true
|
|
434
|
-
});
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
### Get menu
|
|
438
|
-
|
|
439
|
-
Use `getMenu()` to load root menu nodes or the direct children of one menu item.
|
|
440
|
-
|
|
441
|
-
```ts
|
|
442
|
-
const rootMenu = await client.getMenu();
|
|
443
|
-
const childMenu = await client.getMenu("8d0946dc-fc2b-4d95-b5ca-6f12d9618a5b");
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
`getMenu()` returns one tree level at a time.
|
|
447
|
-
|
|
1
|
+
# @chill-sharp/ts-client
|
|
2
|
+
|
|
3
|
+
TypeScript client for a generic ChillSharp service.
|
|
4
|
+
|
|
5
|
+
This package targets the standard ChillSharp HTTP surface:
|
|
6
|
+
|
|
7
|
+
- core Chill API at `/api/chill`
|
|
8
|
+
- schema API at `/api/chill-schema`
|
|
9
|
+
- auth API at `/api/chill-auth`
|
|
10
|
+
- i18n API at `/api/chill-i18n`
|
|
11
|
+
- entity-change notifications at `/api/chill/notify`
|
|
12
|
+
|
|
13
|
+
It is intentionally lightweight. Payloads are plain JavaScript objects so the client can work against arbitrary ChillSharp models without code generation.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
From the repository root:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd extra/chill-sharp-ts-client
|
|
21
|
+
npm install
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or from another project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install ../extra/chill-sharp-ts-client
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The client uses the runtime `fetch` API available in modern browsers and Node.js 18+.
|
|
32
|
+
|
|
33
|
+
## Local Linking
|
|
34
|
+
|
|
35
|
+
This package now builds automatically on `npm install`, `npm pack`, and `npm link` through the `prepare` and `prepack` scripts.
|
|
36
|
+
|
|
37
|
+
Example local workflow:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd extra/chill-sharp-ts-client
|
|
41
|
+
npm install
|
|
42
|
+
npm link
|
|
43
|
+
|
|
44
|
+
cd path/to/your-app
|
|
45
|
+
npm link @chill-sharp/ts-client
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { ChillSharpClient } from "@chill-sharp/ts-client";
|
|
52
|
+
|
|
53
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
54
|
+
cultureName: "it-IT"
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const created = await client.create({
|
|
58
|
+
ChillType: "Model.Post",
|
|
59
|
+
Guid: "00000000-0000-0000-0000-000000000001",
|
|
60
|
+
Properties: {
|
|
61
|
+
Title: "Hello",
|
|
62
|
+
Author: "Ada Lovelace"
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const found = await client.find({
|
|
67
|
+
ChillType: "Model.Post",
|
|
68
|
+
Guid: created.Guid as string
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Construction Modes
|
|
73
|
+
|
|
74
|
+
### Anonymous or externally authenticated
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
78
|
+
cultureName: "it-IT"
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
SignalR entity-change subscriptions use the same bearer token flow as the other authenticated endpoints. Browser SignalR connections send credentials by default; if your app needs a non-credentialed cross-origin negotiate request, set `signalRWithCredentials: false` when creating the client.
|
|
83
|
+
|
|
84
|
+
### With an existing access token
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
88
|
+
accessToken: "your-jwt-token",
|
|
89
|
+
cultureName: "it-IT"
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### With username and password
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
97
|
+
username: "root",
|
|
98
|
+
password: "Pass123$",
|
|
99
|
+
cultureName: "it-IT"
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If the service supports ChillSharp auth endpoints, the client can log in and refresh tokens automatically.
|
|
104
|
+
|
|
105
|
+
## Core ChillSharp Operations
|
|
106
|
+
|
|
107
|
+
Query payloads can now include:
|
|
108
|
+
|
|
109
|
+
- `ordering.propertyName`
|
|
110
|
+
- `ordering.direction`
|
|
111
|
+
|
|
112
|
+
If you omit `ordering`, the backend defaults to `Position`. Entity payloads also include `position`, which defaults to `0`.
|
|
113
|
+
|
|
114
|
+
### Query
|
|
115
|
+
|
|
116
|
+
Use `query()` when `ChillType` points to a concrete query type such as `Query.PostQuery`.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
const result = await client.query({
|
|
120
|
+
chillType: "Query.PostQuery",
|
|
121
|
+
properties: {
|
|
122
|
+
title: "Hello"
|
|
123
|
+
},
|
|
124
|
+
ordering: {
|
|
125
|
+
propertyName: "Position",
|
|
126
|
+
direction: "ASC"
|
|
127
|
+
},
|
|
128
|
+
resultProperties: [
|
|
129
|
+
{ name: "Guid" },
|
|
130
|
+
{ name: "Title" },
|
|
131
|
+
{ name: "Author" }
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
When `ordering.propertyName` points to a Chill entity reference such as `Blog`, the backend orders by `Blog.Label`.
|
|
137
|
+
|
|
138
|
+
### Lookup
|
|
139
|
+
|
|
140
|
+
Use `lookup()` when `ChillType` points to an entity type and you only need generic full-text search.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const result = await client.lookup({
|
|
144
|
+
chillType: "Model.Post",
|
|
145
|
+
properties: {
|
|
146
|
+
fullTextSearch: "Ada Lovelace"
|
|
147
|
+
},
|
|
148
|
+
ordering: {
|
|
149
|
+
propertyName: "Blog",
|
|
150
|
+
direction: "ASC"
|
|
151
|
+
},
|
|
152
|
+
resultProperties: [
|
|
153
|
+
{ name: "Guid" },
|
|
154
|
+
{ name: "Title" },
|
|
155
|
+
{ name: "Author" }
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Find
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const entity = await client.find({
|
|
164
|
+
ChillType: "Model.Post",
|
|
165
|
+
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Create
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const entity = await client.create({
|
|
173
|
+
chillType: "Model.Post",
|
|
174
|
+
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
175
|
+
position: 10,
|
|
176
|
+
properties: {
|
|
177
|
+
title: "New title",
|
|
178
|
+
author: "Grace Hopper"
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Update
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const updated = await client.update({
|
|
187
|
+
chillType: "Model.Post",
|
|
188
|
+
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
189
|
+
position: 20,
|
|
190
|
+
properties: {
|
|
191
|
+
title: "Updated title"
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Delete
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
await client.delete({
|
|
200
|
+
ChillType: "Model.Post",
|
|
201
|
+
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Attachments
|
|
206
|
+
|
|
207
|
+
Use the attachment helpers when the host enables `ChillSharp.Attachment`.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
const post = {
|
|
211
|
+
ChillType: "Model.Post",
|
|
212
|
+
Guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const uploaded = await client.uploadAttachment(post, {
|
|
216
|
+
fileName: "contract.txt",
|
|
217
|
+
content: new Blob(["hello attachment"], { type: "text/plain" }),
|
|
218
|
+
contentType: "text/plain"
|
|
219
|
+
}, {
|
|
220
|
+
title: "Contract",
|
|
221
|
+
description: "Signed draft",
|
|
222
|
+
isPublic: false
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const attachments = await client.getAttachments(post);
|
|
226
|
+
const fileBlob = await client.downloadAttachment(uploaded[0]);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Chunk
|
|
230
|
+
|
|
231
|
+
Use `chunk()` when several operations should be sent in one HTTP request.
|
|
232
|
+
The operations are executed in `Index` order when you provide it. For write-heavy batches, set `Index` explicitly.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const operations = await client.chunk([
|
|
236
|
+
{
|
|
237
|
+
Index: 0,
|
|
238
|
+
Verb: "create",
|
|
239
|
+
Entity: {
|
|
240
|
+
ChillType: "Model.Post",
|
|
241
|
+
Guid: "11111111-1111-1111-1111-111111111111",
|
|
242
|
+
Properties: { Title: "First", Author: "A" }
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
Index: 1,
|
|
247
|
+
Verb: "create",
|
|
248
|
+
Entity: {
|
|
249
|
+
ChillType: "Model.Post",
|
|
250
|
+
Guid: "22222222-2222-2222-2222-222222222222",
|
|
251
|
+
Properties: { Title: "Second", Author: "B" }
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
Index: 2,
|
|
256
|
+
Verb: "update",
|
|
257
|
+
Entity: {
|
|
258
|
+
ChillType: "Model.Post",
|
|
259
|
+
Guid: "11111111-1111-1111-1111-111111111111",
|
|
260
|
+
Properties: { Title: "First updated" }
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
]);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Chunk inside one transaction
|
|
267
|
+
|
|
268
|
+
Wrap the batch with `transaction` and `commit` when all write operations must succeed or fail together.
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
const operations = await client.chunk([
|
|
272
|
+
{
|
|
273
|
+
Index: 0,
|
|
274
|
+
Verb: "transaction"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
Index: 1,
|
|
278
|
+
Verb: "create",
|
|
279
|
+
Entity: {
|
|
280
|
+
ChillType: "Model.Blog",
|
|
281
|
+
Guid: crypto.randomUUID(),
|
|
282
|
+
Properties: {
|
|
283
|
+
Name: "Batch blog",
|
|
284
|
+
Url: "https://example.local/batch-blog"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
Index: 2,
|
|
290
|
+
Verb: "create",
|
|
291
|
+
Entity: {
|
|
292
|
+
ChillType: "Model.Post",
|
|
293
|
+
Guid: crypto.randomUUID(),
|
|
294
|
+
Properties: {
|
|
295
|
+
Title: "Batch post",
|
|
296
|
+
Author: "Grace Hopper"
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
Index: 3,
|
|
302
|
+
Verb: "commit"
|
|
303
|
+
}
|
|
304
|
+
]);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Use this pattern only for the operations that must share the same database transaction. If one write fails before `commit`, the transaction is not committed.
|
|
308
|
+
|
|
309
|
+
### Test
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
const status = await client.test();
|
|
313
|
+
// "ChillSharp is up and running!"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Use this to verify the Chill endpoint is reachable before sending API payloads.
|
|
317
|
+
|
|
318
|
+
## Notification Operations
|
|
319
|
+
|
|
320
|
+
### Subscribe to all changes for a chill type
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
const subscription = await client.subscribeToEntityChanges("Model.Post", (changes) => {
|
|
324
|
+
for (const change of changes) {
|
|
325
|
+
console.log(change.chillType, change.guid, change.action);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Subscribe to one entity only
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
const subscription = await client.subscribeToEntityChanges(
|
|
334
|
+
"Model.Post",
|
|
335
|
+
(changes) => {
|
|
336
|
+
console.log("single entity changed", changes);
|
|
337
|
+
},
|
|
338
|
+
"f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11"
|
|
339
|
+
);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Unsubscribe
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
await subscription.unsubscribe();
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Close the shared notification connection
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
await client.disconnectEntityChanges();
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
The notification callback receives arrays shaped like:
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
[
|
|
358
|
+
{
|
|
359
|
+
chillType: "Model.Post",
|
|
360
|
+
guid: "f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11",
|
|
361
|
+
action: "UPDATED"
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Schema Operations
|
|
367
|
+
|
|
368
|
+
### Get schema
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
const schema = await client.getSchema("Model.Post", "default");
|
|
372
|
+
console.log(schema.handleAttachments);
|
|
373
|
+
console.log(schema.relations);
|
|
374
|
+
|
|
375
|
+
// Override the constructor default for one call
|
|
376
|
+
const englishSchema = await client.getSchema("Model.Post", "default", "en-GB");
|
|
377
|
+
|
|
378
|
+
// Refresh a persisted schema from the current runtime model for one call.
|
|
379
|
+
// Existing properties keep their saved metadata, new model properties are added,
|
|
380
|
+
// and properties no longer present on the model are removed.
|
|
381
|
+
const refreshedSchema = await client.getSchema("Model.Post", "default", undefined, true);
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Entity schemas now also expose `relations`, derived from annotated collection properties. Each relation entry includes:
|
|
385
|
+
|
|
386
|
+
- `chillType` for the child or relation entity
|
|
387
|
+
- `chillQuery` for the resolved query type when available
|
|
388
|
+
- `fixedValues` and `fixedQueryValues` containing the `@{mock}` parent placeholder keyed by the child FK/reference property name
|
|
389
|
+
- `relationLabel` with `labelGuid`, `primaryDefaultText`, and `secondaryDefaultText`
|
|
390
|
+
|
|
391
|
+
### Get schema list
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
const schemaList = await client.getSchemaList();
|
|
395
|
+
const englishSchemaList = await client.getSchemaList("en-GB");
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Set schema
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
await client.setSchema({
|
|
402
|
+
ChillType: "Model.Post",
|
|
403
|
+
ChillViewCode: "default",
|
|
404
|
+
DisplayName: "Post",
|
|
405
|
+
Properties: [
|
|
406
|
+
{
|
|
407
|
+
Name: "Title",
|
|
408
|
+
DisplayName: "Post title"
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Get entity options
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
const options = await client.getEntityOptions("Model.Post");
|
|
418
|
+
console.log(options.handleAttachments);
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Set entity options
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
const options = await client.setEntityOptions({
|
|
425
|
+
chillType: "Model.Post",
|
|
426
|
+
checksumEnabled: true,
|
|
427
|
+
handleAttachments: true,
|
|
428
|
+
labelFormatString: "{Title}",
|
|
429
|
+
shortLabelFormatString: "{Title}",
|
|
430
|
+
fullTextContentFormatString: "{Title} {Author}",
|
|
431
|
+
enableMCP: true,
|
|
432
|
+
mcpDescription: "Post resource exposed to MCP clients.",
|
|
433
|
+
changeLogEnabled: true
|
|
434
|
+
});
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Get menu
|
|
438
|
+
|
|
439
|
+
Use `getMenu()` to load root menu nodes or the direct children of one menu item.
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
const rootMenu = await client.getMenu();
|
|
443
|
+
const childMenu = await client.getMenu("8d0946dc-fc2b-4d95-b5ca-6f12d9618a5b");
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`getMenu()` returns one tree level at a time.
|
|
447
|
+
|
|
448
448
|
For the full menu-tree contract and `MenuHierarchy` filtering behavior, see [../../doc/MenuGuide/README.md](../../doc/MenuGuide/README.md).
|
|
449
|
-
|
|
450
|
-
### Set menu
|
|
451
|
-
|
|
452
|
-
Use `setMenu()` to create or update one menu item.
|
|
453
|
-
|
|
454
|
-
```ts
|
|
455
|
-
const savedMenu = await client.setMenu({
|
|
456
|
-
guid: "00000000-0000-0000-0000-000000000000",
|
|
457
|
-
positionNo: 10,
|
|
458
|
-
title: "Posts",
|
|
459
|
-
description: "Open the post management screen",
|
|
460
|
-
parent: null,
|
|
461
|
-
componentName: "CRUD",
|
|
462
|
-
componentConfigurationJson: "{\"chillType\":\"Model.Post\"}",
|
|
463
|
-
menuHierarchy: "SECTION-A.POSTS"
|
|
464
|
-
});
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
`positionNo` is persisted by the backend and controls sibling ordering. Lower values are returned first.
|
|
468
|
-
|
|
469
|
-
### Delete menu
|
|
470
|
-
|
|
471
|
-
Use `deleteMenu()` to remove one menu item and all nested child nodes below it.
|
|
472
|
-
|
|
473
|
-
```ts
|
|
474
|
-
await client.deleteMenu("8d0946dc-fc2b-4d95-b5ca-6f12d9618a5b");
|
|
475
|
-
```
|
|
476
|
-
|
|
449
|
+
|
|
450
|
+
### Set menu
|
|
451
|
+
|
|
452
|
+
Use `setMenu()` to create or update one menu item.
|
|
453
|
+
|
|
454
|
+
```ts
|
|
455
|
+
const savedMenu = await client.setMenu({
|
|
456
|
+
guid: "00000000-0000-0000-0000-000000000000",
|
|
457
|
+
positionNo: 10,
|
|
458
|
+
title: "Posts",
|
|
459
|
+
description: "Open the post management screen",
|
|
460
|
+
parent: null,
|
|
461
|
+
componentName: "CRUD",
|
|
462
|
+
componentConfigurationJson: "{\"chillType\":\"Model.Post\"}",
|
|
463
|
+
menuHierarchy: "SECTION-A.POSTS"
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
`positionNo` is persisted by the backend and controls sibling ordering. Lower values are returned first.
|
|
468
|
+
|
|
469
|
+
### Delete menu
|
|
470
|
+
|
|
471
|
+
Use `deleteMenu()` to remove one menu item and all nested child nodes below it.
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
await client.deleteMenu("8d0946dc-fc2b-4d95-b5ca-6f12d9618a5b");
|
|
475
|
+
```
|
|
476
|
+
|
|
477
477
|
For parent handling, delete behavior, validation rules, and filtering behavior, see [../../doc/MenuGuide/README.md](../../doc/MenuGuide/README.md).
|
|
478
|
-
|
|
479
|
-
## I18n Operations
|
|
480
|
-
|
|
481
|
-
### Get text
|
|
482
|
-
|
|
483
|
-
```ts
|
|
484
|
-
const text = await client.getText({
|
|
485
|
-
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
486
|
-
CultureName: "it-IT",
|
|
487
|
-
PrimaryCultureName: "en-GB",
|
|
488
|
-
PrimaryDefaultText: "Blog title",
|
|
489
|
-
SecondaryCultureName: "it-IT",
|
|
490
|
-
SecondaryDefaultText: "Titolo del blog"
|
|
491
|
-
});
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Get texts
|
|
495
|
-
|
|
496
|
-
```ts
|
|
497
|
-
const texts = await client.getTexts([
|
|
498
|
-
{
|
|
499
|
-
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
500
|
-
CultureName: "it-IT",
|
|
501
|
-
PrimaryCultureName: "en-GB",
|
|
502
|
-
PrimaryDefaultText: "Blog title",
|
|
503
|
-
SecondaryCultureName: "it-IT",
|
|
504
|
-
SecondaryDefaultText: "Titolo del blog"
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
LabelGuid: "2f6ef6f7-b0a9-44f8-bfd2-a3b3ed5b9a81",
|
|
508
|
-
CultureName: "it-IT",
|
|
509
|
-
PrimaryCultureName: "en-GB",
|
|
510
|
-
PrimaryDefaultText: "Blog url",
|
|
511
|
-
SecondaryCultureName: "it-IT",
|
|
512
|
-
SecondaryDefaultText: "Url del blog"
|
|
513
|
-
}
|
|
514
|
-
]);
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
### Set text
|
|
518
|
-
|
|
519
|
-
```ts
|
|
520
|
-
const saved = await client.setText({
|
|
521
|
-
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
522
|
-
CultureName: "it-IT",
|
|
523
|
-
Value: "Titolo del blog"
|
|
524
|
-
});
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
## Auth Operations
|
|
528
|
-
|
|
529
|
-
The client assumes the auth base path is derived from `/api/chill` to `/api/chill-auth`, matching the .NET client.
|
|
530
|
-
|
|
531
|
-
### Register account
|
|
532
|
-
|
|
533
|
-
```ts
|
|
534
|
-
const token = await client.registerAuthAccount({
|
|
535
|
-
UserName: "root",
|
|
536
|
-
Email: "root@example.com",
|
|
537
|
-
Password: "Pass123$",
|
|
538
|
-
DisplayName: "Root",
|
|
539
|
-
DisplayCultureName: "it-IT",
|
|
540
|
-
CreateChillAuthUser: true
|
|
541
|
-
});
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
If `DisplayCultureName` is provided and `CreateChillAuthUser` is `true`, the server presets the linked `AuthUser` with culture-based defaults for `displayTimeZone`, `displayDateFormat`, and `displayNumberFormat`.
|
|
545
|
-
|
|
546
|
-
### Login
|
|
547
|
-
|
|
548
|
-
```ts
|
|
549
|
-
const token = await client.loginAuthAccount({
|
|
550
|
-
UserNameOrEmail: "root",
|
|
551
|
-
Password: "Pass123$"
|
|
552
|
-
});
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
### Refresh current token
|
|
556
|
-
|
|
557
|
-
```ts
|
|
558
|
-
const token = await client.refreshAuthAccount();
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
### Change password
|
|
562
|
-
|
|
563
|
-
```ts
|
|
564
|
-
const result = await client.changeAuthPassword({
|
|
565
|
-
CurrentPassword: "Pass123$",
|
|
566
|
-
NewPassword: "Pass456$"
|
|
567
|
-
});
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
### Request password reset
|
|
571
|
-
|
|
572
|
-
```ts
|
|
573
|
-
const resetToken = await client.requestAuthPasswordReset({
|
|
574
|
-
UserNameOrEmail: "root"
|
|
575
|
-
});
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
### Reset password
|
|
579
|
-
|
|
580
|
-
```ts
|
|
581
|
-
const result = await client.resetAuthPassword({
|
|
582
|
-
UserId: resetToken.UserId as string,
|
|
583
|
-
ResetToken: resetToken.ResetToken as string,
|
|
584
|
-
NewPassword: "Pass789$"
|
|
585
|
-
});
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
## Auth Management Operations
|
|
589
|
-
|
|
590
|
-
Use these endpoints when the host exposes ChillSharp auth management APIs.
|
|
591
|
-
|
|
592
|
-
### Get current permissions
|
|
593
|
-
|
|
594
|
-
```ts
|
|
595
|
-
const permissions = await client.getAuthPermissions();
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### Get user list
|
|
599
|
-
|
|
600
|
-
```ts
|
|
601
|
-
const users = await client.getAuthUserList();
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
Each auth user item includes `displayCultureName`, `displayTimeZone`, `displayDateFormat`, and `displayNumberFormat`.
|
|
605
|
-
|
|
606
|
-
### Get managed user
|
|
607
|
-
|
|
608
|
-
```ts
|
|
609
|
-
const user = await client.getAuthUser("f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11");
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### Set managed user
|
|
613
|
-
|
|
614
|
-
```ts
|
|
615
|
-
const user = await client.setAuthUser({
|
|
616
|
-
guid: null,
|
|
617
|
-
externalId: "identity-user-001",
|
|
618
|
-
userName: "identity.user",
|
|
619
|
-
displayName: "Identity User",
|
|
620
|
-
displayCultureName: "it-IT",
|
|
621
|
-
displayTimeZone: "W. Europe Standard Time",
|
|
622
|
-
displayDateFormat: "DD/MM/YYYY",
|
|
623
|
-
displayNumberFormat: "1.000,00",
|
|
624
|
-
isActive: true,
|
|
625
|
-
canManagePermissions: false,
|
|
626
|
-
canManageSchema: true,
|
|
627
|
-
roleGuids: [],
|
|
628
|
-
permissions: []
|
|
629
|
-
});
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
### Get role list
|
|
633
|
-
|
|
634
|
-
```ts
|
|
635
|
-
const roles = await client.getAuthRoleList();
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### Get managed role
|
|
639
|
-
|
|
640
|
-
```ts
|
|
641
|
-
const role = await client.getAuthRole("e2f0d8d5-0a1f-4d15-9396-2ab5f6c4ff22");
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### Set managed role
|
|
645
|
-
|
|
646
|
-
```ts
|
|
647
|
-
const role = await client.setAuthRole({
|
|
648
|
-
guid: null,
|
|
649
|
-
name: "Editors",
|
|
650
|
-
description: "Can edit posts",
|
|
651
|
-
isActive: true,
|
|
652
|
-
userGuids: [],
|
|
653
|
-
permissions: []
|
|
654
|
-
});
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
## Error Handling
|
|
658
|
-
|
|
659
|
-
All request failures raise `ChillSharpClientError`.
|
|
660
|
-
|
|
661
|
-
```ts
|
|
662
|
-
import { ChillSharpClient, ChillSharpClientError } from "@chill-sharp/ts-client";
|
|
663
|
-
|
|
664
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
665
|
-
cultureName: "it-IT"
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
try {
|
|
669
|
-
await client.getSchema("Model.Post", "default");
|
|
670
|
-
} catch (error) {
|
|
671
|
-
if (error instanceof ChillSharpClientError) {
|
|
672
|
-
console.log(error.statusCode);
|
|
673
|
-
console.log(error.responseText);
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
```
|
|
677
|
-
|
|
678
|
-
## Custom Fetch
|
|
679
|
-
|
|
680
|
-
If you need custom transport behavior, pass your own `fetch` implementation:
|
|
681
|
-
|
|
682
|
-
```ts
|
|
683
|
-
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
684
|
-
fetchImpl: fetch
|
|
685
|
-
});
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
## Generic Payload Strategy
|
|
689
|
-
|
|
690
|
-
This package does not generate TypeScript model classes for your Chill entities.
|
|
691
|
-
|
|
692
|
-
That is intentional:
|
|
693
|
-
|
|
694
|
-
- ChillSharp models are application-specific
|
|
695
|
-
- the standard Chill API already works well with generic objects
|
|
696
|
-
- a generic client is easier to reuse across many different ChillSharp services
|
|
697
|
-
|
|
698
|
-
If you need strongly typed TypeScript clients, generate them from your host OpenAPI document as described in [doc/ClientGeneration/README.md](../../doc/ClientGeneration/README.md).
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
478
|
+
|
|
479
|
+
## I18n Operations
|
|
480
|
+
|
|
481
|
+
### Get text
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
const text = await client.getText({
|
|
485
|
+
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
486
|
+
CultureName: "it-IT",
|
|
487
|
+
PrimaryCultureName: "en-GB",
|
|
488
|
+
PrimaryDefaultText: "Blog title",
|
|
489
|
+
SecondaryCultureName: "it-IT",
|
|
490
|
+
SecondaryDefaultText: "Titolo del blog"
|
|
491
|
+
});
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Get texts
|
|
495
|
+
|
|
496
|
+
```ts
|
|
497
|
+
const texts = await client.getTexts([
|
|
498
|
+
{
|
|
499
|
+
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
500
|
+
CultureName: "it-IT",
|
|
501
|
+
PrimaryCultureName: "en-GB",
|
|
502
|
+
PrimaryDefaultText: "Blog title",
|
|
503
|
+
SecondaryCultureName: "it-IT",
|
|
504
|
+
SecondaryDefaultText: "Titolo del blog"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
LabelGuid: "2f6ef6f7-b0a9-44f8-bfd2-a3b3ed5b9a81",
|
|
508
|
+
CultureName: "it-IT",
|
|
509
|
+
PrimaryCultureName: "en-GB",
|
|
510
|
+
PrimaryDefaultText: "Blog url",
|
|
511
|
+
SecondaryCultureName: "it-IT",
|
|
512
|
+
SecondaryDefaultText: "Url del blog"
|
|
513
|
+
}
|
|
514
|
+
]);
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Set text
|
|
518
|
+
|
|
519
|
+
```ts
|
|
520
|
+
const saved = await client.setText({
|
|
521
|
+
LabelGuid: "4e16f6c0-6b95-4d67-98bc-9f4d0d63eaf1",
|
|
522
|
+
CultureName: "it-IT",
|
|
523
|
+
Value: "Titolo del blog"
|
|
524
|
+
});
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Auth Operations
|
|
528
|
+
|
|
529
|
+
The client assumes the auth base path is derived from `/api/chill` to `/api/chill-auth`, matching the .NET client.
|
|
530
|
+
|
|
531
|
+
### Register account
|
|
532
|
+
|
|
533
|
+
```ts
|
|
534
|
+
const token = await client.registerAuthAccount({
|
|
535
|
+
UserName: "root",
|
|
536
|
+
Email: "root@example.com",
|
|
537
|
+
Password: "Pass123$",
|
|
538
|
+
DisplayName: "Root",
|
|
539
|
+
DisplayCultureName: "it-IT",
|
|
540
|
+
CreateChillAuthUser: true
|
|
541
|
+
});
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
If `DisplayCultureName` is provided and `CreateChillAuthUser` is `true`, the server presets the linked `AuthUser` with culture-based defaults for `displayTimeZone`, `displayDateFormat`, and `displayNumberFormat`.
|
|
545
|
+
|
|
546
|
+
### Login
|
|
547
|
+
|
|
548
|
+
```ts
|
|
549
|
+
const token = await client.loginAuthAccount({
|
|
550
|
+
UserNameOrEmail: "root",
|
|
551
|
+
Password: "Pass123$"
|
|
552
|
+
});
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Refresh current token
|
|
556
|
+
|
|
557
|
+
```ts
|
|
558
|
+
const token = await client.refreshAuthAccount();
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Change password
|
|
562
|
+
|
|
563
|
+
```ts
|
|
564
|
+
const result = await client.changeAuthPassword({
|
|
565
|
+
CurrentPassword: "Pass123$",
|
|
566
|
+
NewPassword: "Pass456$"
|
|
567
|
+
});
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Request password reset
|
|
571
|
+
|
|
572
|
+
```ts
|
|
573
|
+
const resetToken = await client.requestAuthPasswordReset({
|
|
574
|
+
UserNameOrEmail: "root"
|
|
575
|
+
});
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Reset password
|
|
579
|
+
|
|
580
|
+
```ts
|
|
581
|
+
const result = await client.resetAuthPassword({
|
|
582
|
+
UserId: resetToken.UserId as string,
|
|
583
|
+
ResetToken: resetToken.ResetToken as string,
|
|
584
|
+
NewPassword: "Pass789$"
|
|
585
|
+
});
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
## Auth Management Operations
|
|
589
|
+
|
|
590
|
+
Use these endpoints when the host exposes ChillSharp auth management APIs.
|
|
591
|
+
|
|
592
|
+
### Get current permissions
|
|
593
|
+
|
|
594
|
+
```ts
|
|
595
|
+
const permissions = await client.getAuthPermissions();
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Get user list
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
const users = await client.getAuthUserList();
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Each auth user item includes `displayCultureName`, `displayTimeZone`, `displayDateFormat`, and `displayNumberFormat`.
|
|
605
|
+
|
|
606
|
+
### Get managed user
|
|
607
|
+
|
|
608
|
+
```ts
|
|
609
|
+
const user = await client.getAuthUser("f2d5d5e3-0a1f-4d15-9396-2ab5f6c4ff11");
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Set managed user
|
|
613
|
+
|
|
614
|
+
```ts
|
|
615
|
+
const user = await client.setAuthUser({
|
|
616
|
+
guid: null,
|
|
617
|
+
externalId: "identity-user-001",
|
|
618
|
+
userName: "identity.user",
|
|
619
|
+
displayName: "Identity User",
|
|
620
|
+
displayCultureName: "it-IT",
|
|
621
|
+
displayTimeZone: "W. Europe Standard Time",
|
|
622
|
+
displayDateFormat: "DD/MM/YYYY",
|
|
623
|
+
displayNumberFormat: "1.000,00",
|
|
624
|
+
isActive: true,
|
|
625
|
+
canManagePermissions: false,
|
|
626
|
+
canManageSchema: true,
|
|
627
|
+
roleGuids: [],
|
|
628
|
+
permissions: []
|
|
629
|
+
});
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Get role list
|
|
633
|
+
|
|
634
|
+
```ts
|
|
635
|
+
const roles = await client.getAuthRoleList();
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### Get managed role
|
|
639
|
+
|
|
640
|
+
```ts
|
|
641
|
+
const role = await client.getAuthRole("e2f0d8d5-0a1f-4d15-9396-2ab5f6c4ff22");
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### Set managed role
|
|
645
|
+
|
|
646
|
+
```ts
|
|
647
|
+
const role = await client.setAuthRole({
|
|
648
|
+
guid: null,
|
|
649
|
+
name: "Editors",
|
|
650
|
+
description: "Can edit posts",
|
|
651
|
+
isActive: true,
|
|
652
|
+
userGuids: [],
|
|
653
|
+
permissions: []
|
|
654
|
+
});
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
## Error Handling
|
|
658
|
+
|
|
659
|
+
All request failures raise `ChillSharpClientError`.
|
|
660
|
+
|
|
661
|
+
```ts
|
|
662
|
+
import { ChillSharpClient, ChillSharpClientError } from "@chill-sharp/ts-client";
|
|
663
|
+
|
|
664
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
665
|
+
cultureName: "it-IT"
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
try {
|
|
669
|
+
await client.getSchema("Model.Post", "default");
|
|
670
|
+
} catch (error) {
|
|
671
|
+
if (error instanceof ChillSharpClientError) {
|
|
672
|
+
console.log(error.statusCode);
|
|
673
|
+
console.log(error.responseText);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
## Custom Fetch
|
|
679
|
+
|
|
680
|
+
If you need custom transport behavior, pass your own `fetch` implementation:
|
|
681
|
+
|
|
682
|
+
```ts
|
|
683
|
+
const client = new ChillSharpClient("http://localhost:5000/api/chill", {
|
|
684
|
+
fetchImpl: fetch
|
|
685
|
+
});
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
## Generic Payload Strategy
|
|
689
|
+
|
|
690
|
+
This package does not generate TypeScript model classes for your Chill entities.
|
|
691
|
+
|
|
692
|
+
That is intentional:
|
|
693
|
+
|
|
694
|
+
- ChillSharp models are application-specific
|
|
695
|
+
- the standard Chill API already works well with generic objects
|
|
696
|
+
- a generic client is easier to reuse across many different ChillSharp services
|
|
697
|
+
|
|
698
|
+
If you need strongly typed TypeScript clients, generate them from your host OpenAPI document as described in [doc/ClientGeneration/README.md](../../doc/ClientGeneration/README.md).
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|