buildfree 1.0.0
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 +127 -0
- package/package.json +18 -0
- package/src/forms.js +327 -0
- package/src/index.js +84 -0
- package/src/records.js +189 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# BuildFree SDK
|
|
2
|
+
|
|
3
|
+
BuildFree is a simple Node.js SDK that lets you connect your application to the BuildFree CMS API and use your CMS data anywhere.
|
|
4
|
+
|
|
5
|
+
[buildfree.dev](https://buildfree.dev)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install buildfree
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
const { BuildFree } = require("buildfree");
|
|
19
|
+
|
|
20
|
+
const buildfree = new BuildFree({
|
|
21
|
+
apiKey: "cms_live_your_api_key"
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Records
|
|
28
|
+
|
|
29
|
+
### Get all records
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
const products = await buildfree.getRecords({
|
|
33
|
+
projectSlug: "my-project",
|
|
34
|
+
collectionSlug: "products"
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Get one record
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
const product = await buildfree.getRecord({
|
|
42
|
+
projectSlug: "my-project",
|
|
43
|
+
collectionSlug: "products",
|
|
44
|
+
recordId: "record-id"
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Forms
|
|
51
|
+
|
|
52
|
+
### Get a form
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
const form = await buildfree.getForm({
|
|
56
|
+
projectSlug: "my-project",
|
|
57
|
+
formSlug: "contact-form"
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Submit a form
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
const result = await buildfree.submitForm({
|
|
65
|
+
projectSlug: "my-project",
|
|
66
|
+
formSlug: "contact-form",
|
|
67
|
+
data: {
|
|
68
|
+
name: "John",
|
|
69
|
+
email: "john@example.com",
|
|
70
|
+
message: "Hello!"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## File Upload
|
|
78
|
+
|
|
79
|
+
Forms also support file uploads:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
const result = await buildfree.submitForm({
|
|
83
|
+
projectSlug: "my-project",
|
|
84
|
+
formSlug: "application-form",
|
|
85
|
+
|
|
86
|
+
data: {
|
|
87
|
+
name: "John"
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
files: [
|
|
91
|
+
{
|
|
92
|
+
fieldname: "resume",
|
|
93
|
+
path: "./resume.pdf"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## API Key
|
|
102
|
+
|
|
103
|
+
Your API key must start with:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
cms_live_
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> Keep your API key secure and use environment variables in production.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Available Methods
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
buildfree.getRecords()
|
|
117
|
+
buildfree.getRecord()
|
|
118
|
+
|
|
119
|
+
buildfree.getForm()
|
|
120
|
+
buildfree.submitForm()
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
**BuildFree** — Build your API. Use it anywhere.
|
|
126
|
+
|
|
127
|
+
[buildfree.dev](https://buildfree.dev)
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "buildfree",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official JavaScript SDK for buildfree",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"start": "node src/index.js",
|
|
9
|
+
"dev": ""
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "BuildFree",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"axios": "^1.20.0",
|
|
16
|
+
"nodemon": "^3.1.14"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/forms.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const FormData = require("form-data");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
class Forms {
|
|
6
|
+
|
|
7
|
+
constructor({
|
|
8
|
+
apiKey,
|
|
9
|
+
baseURL
|
|
10
|
+
}) {
|
|
11
|
+
|
|
12
|
+
this.client = axios.create({
|
|
13
|
+
|
|
14
|
+
baseURL,
|
|
15
|
+
|
|
16
|
+
timeout: 10000,
|
|
17
|
+
|
|
18
|
+
headers: {
|
|
19
|
+
"x-api-key": apiKey,
|
|
20
|
+
"Accept": "application/json"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// ==========================================================
|
|
29
|
+
// GET FORM
|
|
30
|
+
// ==========================================================
|
|
31
|
+
|
|
32
|
+
async getOne({
|
|
33
|
+
projectSlug,
|
|
34
|
+
formSlug
|
|
35
|
+
} = {}) {
|
|
36
|
+
|
|
37
|
+
// ==========================================
|
|
38
|
+
// VALIDATION
|
|
39
|
+
// ==========================================
|
|
40
|
+
|
|
41
|
+
if (!projectSlug) {
|
|
42
|
+
throw new Error("projectSlug is required");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!formSlug) {
|
|
46
|
+
throw new Error("formSlug is required");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// ==========================================
|
|
51
|
+
// REQUEST
|
|
52
|
+
// ==========================================
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
|
|
56
|
+
const response = await this.client.get(
|
|
57
|
+
|
|
58
|
+
`/public/${encodeURIComponent(projectSlug)}/forms/${encodeURIComponent(formSlug)}`
|
|
59
|
+
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return response.data;
|
|
63
|
+
|
|
64
|
+
} catch (error) {
|
|
65
|
+
|
|
66
|
+
this.handleError(error);
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
// ==========================================================
|
|
74
|
+
// SUBMIT FORM
|
|
75
|
+
// ==========================================================
|
|
76
|
+
|
|
77
|
+
async submit({
|
|
78
|
+
projectSlug,
|
|
79
|
+
formSlug,
|
|
80
|
+
data = {},
|
|
81
|
+
files = []
|
|
82
|
+
} = {}) {
|
|
83
|
+
|
|
84
|
+
// ==========================================
|
|
85
|
+
// VALIDATION
|
|
86
|
+
// ==========================================
|
|
87
|
+
|
|
88
|
+
if (!projectSlug) {
|
|
89
|
+
throw new Error("projectSlug is required");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!formSlug) {
|
|
93
|
+
throw new Error("formSlug is required");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
|
|
99
|
+
// ========================================================
|
|
100
|
+
// NORMAL JSON REQUEST
|
|
101
|
+
// ========================================================
|
|
102
|
+
|
|
103
|
+
if (!files || files.length === 0) {
|
|
104
|
+
|
|
105
|
+
const response = await this.client.post(
|
|
106
|
+
|
|
107
|
+
`/public/${encodeURIComponent(projectSlug)}/forms/${encodeURIComponent(formSlug)}/submit`,
|
|
108
|
+
|
|
109
|
+
data,
|
|
110
|
+
|
|
111
|
+
{
|
|
112
|
+
headers: {
|
|
113
|
+
"Content-Type": "application/json"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return response.data;
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
// ========================================================
|
|
125
|
+
// MULTIPART FORM REQUEST
|
|
126
|
+
// ========================================================
|
|
127
|
+
|
|
128
|
+
const formData = new FormData();
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
// ========================================================
|
|
132
|
+
// ADD NORMAL DATA
|
|
133
|
+
// ========================================================
|
|
134
|
+
|
|
135
|
+
for (
|
|
136
|
+
const [key, value]
|
|
137
|
+
of Object.entries(data)
|
|
138
|
+
) {
|
|
139
|
+
|
|
140
|
+
if (
|
|
141
|
+
value !== undefined &&
|
|
142
|
+
value !== null
|
|
143
|
+
) {
|
|
144
|
+
|
|
145
|
+
formData.append(
|
|
146
|
+
key,
|
|
147
|
+
value
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
// ========================================================
|
|
156
|
+
// ADD FILES
|
|
157
|
+
// ========================================================
|
|
158
|
+
|
|
159
|
+
for (const file of files) {
|
|
160
|
+
|
|
161
|
+
if (!file) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
// ------------------------------------------------------
|
|
167
|
+
// BUFFER
|
|
168
|
+
// ------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
if (Buffer.isBuffer(file.buffer)) {
|
|
171
|
+
|
|
172
|
+
formData.append(
|
|
173
|
+
|
|
174
|
+
file.fieldname,
|
|
175
|
+
|
|
176
|
+
file.buffer,
|
|
177
|
+
|
|
178
|
+
{
|
|
179
|
+
filename:
|
|
180
|
+
file.filename ||
|
|
181
|
+
file.originalname ||
|
|
182
|
+
"upload",
|
|
183
|
+
|
|
184
|
+
contentType:
|
|
185
|
+
file.contentType ||
|
|
186
|
+
file.mimetype
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
continue;
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
// ------------------------------------------------------
|
|
197
|
+
// FILE PATH
|
|
198
|
+
// ------------------------------------------------------
|
|
199
|
+
|
|
200
|
+
if (file.path) {
|
|
201
|
+
|
|
202
|
+
formData.append(
|
|
203
|
+
|
|
204
|
+
file.fieldname,
|
|
205
|
+
|
|
206
|
+
fs.createReadStream(
|
|
207
|
+
file.path
|
|
208
|
+
),
|
|
209
|
+
|
|
210
|
+
{
|
|
211
|
+
filename:
|
|
212
|
+
file.filename ||
|
|
213
|
+
file.originalname
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
continue;
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Invalid file for field: ${file.fieldname}`
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
// ========================================================
|
|
231
|
+
// SUBMIT
|
|
232
|
+
// ========================================================
|
|
233
|
+
|
|
234
|
+
const response = await this.client.post(
|
|
235
|
+
|
|
236
|
+
`/public/${encodeURIComponent(projectSlug)}/forms/${encodeURIComponent(formSlug)}/submit`,
|
|
237
|
+
|
|
238
|
+
formData,
|
|
239
|
+
|
|
240
|
+
{
|
|
241
|
+
headers: {
|
|
242
|
+
...formData.getHeaders()
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
return response.data;
|
|
250
|
+
|
|
251
|
+
} catch (error) {
|
|
252
|
+
|
|
253
|
+
this.handleError(error);
|
|
254
|
+
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
// ==========================================================
|
|
261
|
+
// ERROR HANDLER
|
|
262
|
+
// ==========================================================
|
|
263
|
+
|
|
264
|
+
handleError(error) {
|
|
265
|
+
|
|
266
|
+
// ==========================================
|
|
267
|
+
// SERVER RESPONSE
|
|
268
|
+
// ==========================================
|
|
269
|
+
|
|
270
|
+
if (error.response) {
|
|
271
|
+
|
|
272
|
+
const message =
|
|
273
|
+
error.response.data?.message ||
|
|
274
|
+
"CMS API request failed";
|
|
275
|
+
|
|
276
|
+
const apiError =
|
|
277
|
+
new Error(message);
|
|
278
|
+
|
|
279
|
+
apiError.status =
|
|
280
|
+
error.response.status;
|
|
281
|
+
|
|
282
|
+
apiError.response =
|
|
283
|
+
error.response.data;
|
|
284
|
+
|
|
285
|
+
throw apiError;
|
|
286
|
+
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
// ==========================================
|
|
291
|
+
// NO RESPONSE
|
|
292
|
+
// ==========================================
|
|
293
|
+
|
|
294
|
+
if (error.request) {
|
|
295
|
+
|
|
296
|
+
if (
|
|
297
|
+
error.code === "ECONNABORTED" ||
|
|
298
|
+
error.code === "ETIMEDOUT"
|
|
299
|
+
) {
|
|
300
|
+
|
|
301
|
+
throw new Error(
|
|
302
|
+
"CMS API request timed out"
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
throw new Error(
|
|
308
|
+
"Could not connect to CMS API"
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
// ==========================================
|
|
315
|
+
// UNKNOWN ERROR
|
|
316
|
+
// ==========================================
|
|
317
|
+
|
|
318
|
+
throw error;
|
|
319
|
+
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
module.exports = {
|
|
326
|
+
Forms
|
|
327
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const { Records } = require("./records");
|
|
2
|
+
const { Forms } = require("./forms");
|
|
3
|
+
|
|
4
|
+
class BuildFree {
|
|
5
|
+
|
|
6
|
+
constructor({
|
|
7
|
+
apiKey,
|
|
8
|
+
baseURL = "https://cms-backend-9nkz.onrender.com/api/v1"
|
|
9
|
+
} = {}) {
|
|
10
|
+
|
|
11
|
+
// ==========================================
|
|
12
|
+
// API KEY VALIDATION
|
|
13
|
+
// ==========================================
|
|
14
|
+
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
throw new Error("API key is required");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
typeof apiKey !== "string" ||
|
|
21
|
+
!apiKey.startsWith("cms_live_")
|
|
22
|
+
) {
|
|
23
|
+
throw new Error("Invalid API key");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// ==========================================
|
|
28
|
+
// INITIALIZE SERVICES
|
|
29
|
+
// ==========================================
|
|
30
|
+
|
|
31
|
+
this.records = new Records({
|
|
32
|
+
apiKey,
|
|
33
|
+
baseURL
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.forms = new Forms({
|
|
37
|
+
apiKey,
|
|
38
|
+
baseURL
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// ==========================================
|
|
45
|
+
// RECORDS
|
|
46
|
+
// ==========================================
|
|
47
|
+
|
|
48
|
+
getRecords(options) {
|
|
49
|
+
|
|
50
|
+
return this.records.getAll(options);
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
getRecord(options) {
|
|
56
|
+
|
|
57
|
+
return this.records.getOne(options);
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
// ==========================================
|
|
63
|
+
// FORMS
|
|
64
|
+
// ==========================================
|
|
65
|
+
|
|
66
|
+
getForm(options) {
|
|
67
|
+
|
|
68
|
+
return this.forms.getOne(options);
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
submitForm(options) {
|
|
74
|
+
|
|
75
|
+
return this.forms.submit(options);
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
module.exports = {
|
|
83
|
+
BuildFree
|
|
84
|
+
};
|
package/src/records.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
|
|
3
|
+
class Records {
|
|
4
|
+
|
|
5
|
+
constructor({
|
|
6
|
+
apiKey,
|
|
7
|
+
baseURL
|
|
8
|
+
}) {
|
|
9
|
+
|
|
10
|
+
this.client = axios.create({
|
|
11
|
+
|
|
12
|
+
baseURL,
|
|
13
|
+
|
|
14
|
+
timeout: 10000,
|
|
15
|
+
|
|
16
|
+
headers: {
|
|
17
|
+
"x-api-key": apiKey,
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
"Accept": "application/json"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// ==========================================================
|
|
28
|
+
// GET ALL RECORDS
|
|
29
|
+
// ==========================================================
|
|
30
|
+
|
|
31
|
+
async getAll({
|
|
32
|
+
projectSlug,
|
|
33
|
+
collectionSlug
|
|
34
|
+
} = {}) {
|
|
35
|
+
|
|
36
|
+
// ==========================================
|
|
37
|
+
// VALIDATION
|
|
38
|
+
// ==========================================
|
|
39
|
+
|
|
40
|
+
if (!projectSlug) {
|
|
41
|
+
throw new Error("projectSlug is required");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!collectionSlug) {
|
|
45
|
+
throw new Error("collectionSlug is required");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
// ==========================================
|
|
50
|
+
// REQUEST
|
|
51
|
+
// ==========================================
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
|
|
55
|
+
const response = await this.client.get(
|
|
56
|
+
|
|
57
|
+
`/public/${encodeURIComponent(projectSlug)}/${encodeURIComponent(collectionSlug)}`
|
|
58
|
+
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return response.data;
|
|
62
|
+
|
|
63
|
+
} catch (error) {
|
|
64
|
+
|
|
65
|
+
this.handleError(error);
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
// ==========================================================
|
|
73
|
+
// GET ONE RECORD
|
|
74
|
+
// ==========================================================
|
|
75
|
+
|
|
76
|
+
async getOne({
|
|
77
|
+
projectSlug,
|
|
78
|
+
collectionSlug,
|
|
79
|
+
recordId
|
|
80
|
+
} = {}) {
|
|
81
|
+
|
|
82
|
+
// ==========================================
|
|
83
|
+
// VALIDATION
|
|
84
|
+
// ==========================================
|
|
85
|
+
|
|
86
|
+
if (!projectSlug) {
|
|
87
|
+
throw new Error("projectSlug is required");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!collectionSlug) {
|
|
91
|
+
throw new Error("collectionSlug is required");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!recordId) {
|
|
95
|
+
throw new Error("recordId is required");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
// ==========================================
|
|
100
|
+
// REQUEST
|
|
101
|
+
// ==========================================
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
|
|
105
|
+
const response = await this.client.get(
|
|
106
|
+
|
|
107
|
+
`/public/${encodeURIComponent(projectSlug)}/${encodeURIComponent(collectionSlug)}/${encodeURIComponent(recordId)}`
|
|
108
|
+
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return response.data;
|
|
112
|
+
|
|
113
|
+
} catch (error) {
|
|
114
|
+
|
|
115
|
+
this.handleError(error);
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// ==========================================================
|
|
123
|
+
// ERROR HANDLER
|
|
124
|
+
// ==========================================================
|
|
125
|
+
|
|
126
|
+
handleError(error) {
|
|
127
|
+
|
|
128
|
+
// ==========================================
|
|
129
|
+
// SERVER RESPONSE
|
|
130
|
+
// ==========================================
|
|
131
|
+
|
|
132
|
+
if (error.response) {
|
|
133
|
+
|
|
134
|
+
const message =
|
|
135
|
+
error.response.data?.message ||
|
|
136
|
+
"CMS API request failed";
|
|
137
|
+
|
|
138
|
+
const apiError =
|
|
139
|
+
new Error(message);
|
|
140
|
+
|
|
141
|
+
apiError.status =
|
|
142
|
+
error.response.status;
|
|
143
|
+
|
|
144
|
+
apiError.response =
|
|
145
|
+
error.response.data;
|
|
146
|
+
|
|
147
|
+
throw apiError;
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
// ==========================================
|
|
153
|
+
// NO RESPONSE
|
|
154
|
+
// ==========================================
|
|
155
|
+
|
|
156
|
+
if (error.request) {
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
error.code === "ECONNABORTED" ||
|
|
160
|
+
error.code === "ETIMEDOUT"
|
|
161
|
+
) {
|
|
162
|
+
|
|
163
|
+
throw new Error(
|
|
164
|
+
"CMS API request timed out"
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
throw new Error(
|
|
170
|
+
"Could not connect to CMS API"
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
// ==========================================
|
|
177
|
+
// UNKNOWN ERROR
|
|
178
|
+
// ==========================================
|
|
179
|
+
|
|
180
|
+
throw error;
|
|
181
|
+
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
module.exports = {
|
|
188
|
+
Records
|
|
189
|
+
};
|