UNPKG

11.4 kBMarkdownView Raw
1# Squidex Client Manager [![npm version](https://badge.fury.io/js/squidex-client-manager.svg)](https://badge.fury.io/js/squidex-client-manager) [![CircleCI](https://circleci.com/gh/scanf/squidex-client-manager.svg?style=svg)](https://circleci.com/gh/scanf/squidex-client-manager)
2
3[![Powered by Squidex](./GitHub/power-by.png)](https://squidex.io)
4
5This is a wrapper around the swagger [API][a] provided by Squidex.
6
7> The project is still a in early phase so the featureset is limited.
8
9Please note all examples below use `cloud.squidex.io` in the examples but you
10can easily change out the `https://cloud.squidex.io/api` portion with the
11following format `https://<my-server-url>/api/` for self-hosted version.
12
13## What is Squidex?
14
15[Squidex][s] is a open source headless CMS. To learn more about it checkout the
16following links:
17
18- [Docker containers](https://github.com/squidex/squidex-dockers)
19- [Source code](https://github.com/squidex/squidex)
20- [Documentation](https://docs.squidex.io)
21- [Hosted][s]
22
23## Installation
24
25### NPM
26
27```
28npm install squidex-client-manager
29```
30
31### Yarn
32
33```
34yarn add squidex-client-manager
35```
36
37## Usage
38
39You need to setup the client before using it. For getting values for the client see
40`https://cloud.squidex.io/app/<my-app>/settings/clients`
41
42When you have those values you can setup the client. Note that all examples
43below assume you are running in an `async` function.
44
45### Setting up the client
46
47```javascript
48const { SquidexClientManager } = require('squidex-client-manager');
49
50const client = new SquidexClientManager(
51 // Server Url
52 'https://cloud.squidex.io',
53 // App name
54 'my-blog-squidex',
55 // Client Id
56 'my-blog-squidex:developer',
57 // Client Secret
58 'my-secret',
59);
60```
61
62### Retrieving records
63
64By default only `20` records are returned, the max is `200` but you can combine
65it with `skip` to paginate between the results or use `AllRecords` like below.
66
67```javascript
68const records = await client.RecordsAsync('Articles', { top: 0 })
69console.log(JSON.stringify(records, null, 2))
70/* Output:
71[squidex-client-manager][debug]: Records(Articles, [object Object])
72[squidex-client-manager][debug]: GetModelByName(Articles)
73{
74 "total": 1,
75 "items": [
76 {
77 "id": "ffcbecb0-07a0-45f5-9b8e-bf53059fe25d",
78 "createdBy": "subject:5ce8610ec020db00018051c7",
79 "lastModifiedBy": "subject:5ce8610ec020db00018051c7",
80 "data": {
81 "title": {
82 "iv": "Hello Squidex"
83 },
84 "text": {
85 "iv": "## Testing markdown support"
86 }
87 },
88 "isPending": false,
89 "created": "2019-06-12T17:24:38Z",
90 "lastModified": "2019-06-12T17:24:38Z",
91 "status": "Published",
92 "version": 1
93 }
94 ]
95}
96*/
97
98const allRecords = await client.AllRecordsAsync('Articles');
99console.log(allRecords.length);
100500
101```
102
103### Retrieving a record
104
105```javascript
106const records = await client.RecordAsync('Articles', {
107 id: '4bb3a7bb-962d-4183-9ca6-35d170c34f3b'
108})
109console.log(JSON.stringify(records, null, 2))
110/* Output:
111[squidex-client-manager][debug]: Record(Articles, [object Object])
112[squidex-client-manager][debug]: GetModelByName(Articles)
113{
114 "title": {
115 "iv": "Testo-Wed Jun 12 2019 20:11:19 GMT+0200 (Central European Summer Time)"
116 }
117} */
118```
119
120### Creating a record
121
122```javascript
123const title = 'My post'
124const body = `
125## topic 1
126
127Lorem ipsum dolor sit amet, quo ne malis saperet fierent, has ut vivendo
128imperdiet disputando, no cum oratio abhorreant. Agam accusata prodesset cu
129pri, qui iudico constituto constituam an. Ne mel liber libris expetendis, per
130eu imperdiet dignissim. Pro ridens fabulas evertitur ut.
131`
132const expected = {
133 data: { title: { iv: title }, text: { iv: body } },
134 publish: true
135}
136const article = await client.CreateAsync('Articles', expected)
137console.log(JSON.stringify(article, null, 2))
138/* Output:
139[squidex-client-manager][debug]: Create(Articles, [object Object])
140[squidex-client-manager][debug]: GetModelByName(Articles)
141{
142 "id": "cdbcb9f7-f6f6-4a6a-81d9-0c6f9cf385f8",
143 "createdBy": "client:my-blog-squidex:developer",
144 "lastModifiedBy": "client:my-blog-squidex:developer",
145 "data": {
146 "title": {
147 "iv": "My post"
148 },
149 "text": {
150 "iv": "\n ## topic 1\n \n Lorem ipsum dolor sit amet, quo ne malis saperet fierent, has ut vivendo\n imperdiet disputando, no cum oratio abhorreant. Agam accusata prodesset cu\n pri, qui iudico constituto constituam an. Ne mel liber libris expetendis, per\n eu imperdiet dignissim. Pro ridens fabulas evertitur ut.\n "
151 }
152 },
153 "isPending": false,
154 "created": "2019-06-12T18:22:51Z",
155 "lastModified": "2019-06-12T18:22:51Z",
156 "status": "Published",
157 "version": 1
158}
159*/
160```
161
162### Deleting a record
163
164```javascript
165const deleted = await client.DeleteAsync('Articles', {
166 id: 'cdbcb9f7-f6f6-4a6a-81d9-0c6f9cf385f8'
167})
168console.log(JSON.stringify(deleted, null, 2))
169/* Output:
170[squidex-client-manager][debug]: Delete(Articles, [object Object])
171[squidex-client-manager][debug]: GetModelByName(Articles)
172{
173 "ok": true,
174 "url": "https://cloud.squidex.io/api/content/my-blog-squidex/articles/cdbcb9f7-f6f6-4a6a-81d9-0c6f9cf385f8/",
175 "status": 204,
176 "statusText": "No Content",
177 "headers": {
178 "date": "Wed, 12 Jun 2019 18:26:10 GMT",
179 "connection": "close",
180 "set-cookie": "__cfduid=d8ef8efcbcf5e2fb0d137c4ad4f26edf41560363970; expires=Thu, 11-Jun-20 18:26:10 GMT; path=/; domain=.squidex.io; HttpOnly; Secure",
181 "etag": "W/2",
182 "expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
183 "server": "cloudflare",
184 "cf-ray": "4e5ddf1eaef0cae4-ARN"
185 },
186 "text": {
187 "type": "Buffer",
188 "data": []
189 },
190 "data": {
191 "type": "Buffer",
192 "data": []
193 }
194}
195*/
196```
197
198### Updating a record
199
200Note that this function will override the other fields.
201
202```javascript
203// Get our record data
204const record = await client.RecordAsync('Articles', {
205 id: '4bb3a7bb-962d-4183-9ca6-35d170c34f3b'
206})
207
208// Change the relevant fields
209record.title.iv = 'the title is updated'
210record.text.iv = 'the article text updated'
211
212// Send the update
213const update = await client.UpdateAsync('Articles', {
214 id: '4bb3a7bb-962d-4183-9ca6-35d170c34f3b',
215 data: record
216});
217console.log(JSON.stringify(update, null, 2))
218/* Output:
219[squidex-client-manager][debug]: Update(Articles, [object Object])
220[squidex-client-manager][debug]: GetModelByName(Articles)
221{
222 "title": {
223 "iv": "the title is updated"
224 },
225 "text": {
226 "iv": "the article text"
227 }
228}
229*/
230```
231
232### Create or update a record
233
234If a record already exists it willl be merged.
235
236```javascript
237const createOrUpdate = await client.CreateOrUpdateAsync(
238 'Articles',
239 {
240 id: '4bb3a7bb-962d-4183-9ca6-35d170c34f3b',
241 data: {
242 title: { iv: 'title here is used as unique value for comparison' },
243 text: { iv: 'y' }
244 }
245 },
246 'title'
247)
248console.log(JSON.stringify(createOrUpdate, null, 2))
249/* Output:
250[squidex-client-manager][debug]: CreateOrUpdate(Articles, [object Object], title)
251[squidex-client-manager][debug]: filter Articles where title eq title here is used as unique value for comparison
252[squidex-client-manager][debug]: Records(Articles, [object Object])
253[squidex-client-manager][debug]: GetModelByName(Articles)
254[squidex-client-manager][debug]: Create(Articles, [object Object])
255[squidex-client-manager][debug]: GetModelByName(Articles)
256{
257 "id": "3b6c5b1c-51bd-45a2-8c07-736286c71b67",
258 "createdBy": "client:my-blog-squidex:developer",
259 "lastModifiedBy": "client:my-blog-squidex:developer",
260 "data": {
261 "title": {
262 "iv": "title here is used as unique value for comparison"
263 },
264 "text": {
265 "iv": "y"
266 }
267 },
268 "isPending": false,
269 "created": "2019-06-12T18:44:00Z",
270 "lastModified": "2019-06-12T18:44:00Z",
271 "status": "Draft",
272 "version": 0
273}
274*/
275```
276
277### Filtering
278
279The current implementation of filtering only supports comparisons i.e only
280`eq`. If you have use case that requests the full support of [OData
281Conventions][oc], please reach out by creating a [issue][i].
282
283If you only want to use `eq` then the following example should suffice
284
285```javascript
286const input = { data: { title: { iv: 'Hello Squidex' } }, publish: true }
287const filter = await client.FilterRecordsAsync('Articles', input, 'title')
288console.log(JSON.stringify(filter, null, 2))
289/* Output:
290[squidex-client-manager][debug]: filter Articles where title eq Hello Squidex
291[squidex-client-manager][debug]: Records(Articles, [object Object])
292[squidex-client-manager][debug]: GetModelByName(Articles)
293[
294 {
295 "id": "ffcbecb0-07a0-45f5-9b8e-bf53059fe25d",
296 "createdBy": "subject:5ce8610ec020db00018051c7",
297 "lastModifiedBy": "subject:5ce8610ec020db00018051c7",
298 "data": {
299 "title": {
300 "iv": "Hello Squidex"
301 },
302 "text": {
303 "iv": "## Testing markdown support"
304 }
305 },
306 "isPending": false,
307 "created": "2019-06-12T17:24:38Z",
308 "lastModified": "2019-06-12T17:24:38Z",
309 "status": "Published",
310 "version": 1
311 }
312]
313*/
314```
315
316#### Find one
317
318```javascript
319const record = await client.FindOne('Articles', 'title', 'Hello Squidex')
320console.log(JSON.stringify(record, null, 2))
321/* Output:
322[squidex-client-manager][debug]: Records(Articles, [object Object])
323[squidex-client-manager][debug]: GetModelByName(Articles)
324{
325 "id": "ffcbecb0-07a0-45f5-9b8e-bf53059fe25d",
326 "createdBy": "subject:5ce8610ec020db00018051c7",
327 "lastModifiedBy": "subject:5ce8610ec020db00018051c7",
328 "data": {
329 "title": {
330 "iv": "Hello Squidex"
331 },
332 "text": {
333 "iv": "## Testing markdown support"
334 }
335 },
336 "isPending": false,
337 "created": "2019-06-12T17:24:38Z",
338 "lastModified": "2019-06-12T17:24:38Z",
339 "status": "Published",
340 "version": 1
341}
342*/
343```
344
345#### Creating assets
346
347If you need to upload images or PDF's you can use `CreateAssetAsync`. The only restriction currently
348set is that the file must exist locally and be accessible. Also the mime type should be detectable.
349
350```javascript
351// The path to the file locally
352const filename = '../GitHub/power-by.png';
353const localImageFile = path.resolve(__dirname, filename);
354const upload = await client.CreateAssetAsync(localImageFile);
355console.log(upload.statusText, `${upload.url}/${upload.body.id}`);
356/* Output:
357Created https://cloud.squidex.io/api/assets/826d1176-d7c3-41cd-b166-13249fdcc225?version=0
358*/
359```
360
361## Disclaimer
362
363This project is not affiliated with [Squidex][0] and is an unofficial client.
364The project is developed and maintained by [Alexander Alemayhu][twitter] for [Fortress][f].
365
366## Troubleshooting
367
368This repository is intentionally testing against [cloud.squidex.io][c]. If for
369some reason you experience issues creating content via the API and are
370self-hosting. Make sure you are running a [recent release][rr] of Squidex.
371To check your version visit check version visit `https://<my-server-url>/api/info`
372
373### Misc things to check
374
375- Check the client has enough permissions (recommended role for testing is `Developer`).
376- Check the model name you are querying exists in the Squidex schema.
377- Check your token is valid.
378
379[a]: https://docs.squidex.io/guides/02-api
380[0]: https://squidex.io/
381[twitter]: https://twitter.com/aalemayhu
382[oc]: https://docs.squidex.io/guides/02-api#odata-conventions
383[i]: https://github.com/scanf/squidex-client-manager/issues/new
384[s]: https://squidex.io
385[f]: https://fortress.no/
386[rr]: https://github.com/Squidex/squidex/releases
387[c]: https://cloud.squidex.io