@content-island/api-client 0.17.0 → 0.19.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 +39 -0
- package/dist/index.d.ts +70 -2
- package/dist/index.js +148 -93
- package/dist/index.umd.cjs +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,6 +6,45 @@
|
|
|
6
6
|
npm install @content-island/api-client
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
+
## Authentication
|
|
10
|
+
|
|
11
|
+
The client is configured with a single `accessToken` option that is sent on every
|
|
12
|
+
request as `Authorization: Bearer <accessToken>`. Content Island supports two kinds
|
|
13
|
+
of tokens:
|
|
14
|
+
|
|
15
|
+
- **Read token** — grants read-only access to the project. Use it for any `get*`
|
|
16
|
+
method (fetching content, listing, sizing, project metadata).
|
|
17
|
+
- **Write token** — grants both read and write access. Required for any method
|
|
18
|
+
that creates, updates, or uploads data.
|
|
19
|
+
|
|
20
|
+
A write token is a strict superset of a read token: it works for everything. A
|
|
21
|
+
read token only works for the read methods. Calling a write method with a read
|
|
22
|
+
token returns `403 Forbidden`.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { createClient } from '@content-island/api-client';
|
|
26
|
+
|
|
27
|
+
// Read-only consumer (e.g. SSG/SSR site fetching content):
|
|
28
|
+
const reader = createClient({ accessToken: '<your-read-token>' });
|
|
29
|
+
|
|
30
|
+
// Authoring tools, ingestion pipelines, admin scripts:
|
|
31
|
+
const writer = createClient({ accessToken: '<your-write-token>' });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Token required per method
|
|
35
|
+
|
|
36
|
+
| Method | Token required |
|
|
37
|
+
| ------------------------- | ----------------- |
|
|
38
|
+
| `getProject` | Read **or** Write |
|
|
39
|
+
| `getContentList` | Read **or** Write |
|
|
40
|
+
| `getContent` | Read **or** Write |
|
|
41
|
+
| `getRawContentList` | Read **or** Write |
|
|
42
|
+
| `getRawContent` | Read **or** Write |
|
|
43
|
+
| `getContentListSize` | Read **or** Write |
|
|
44
|
+
| `createContent` | **Write** |
|
|
45
|
+
| `updateContentFieldValue` | **Write** |
|
|
46
|
+
| `uploadMedia` | **Write** |
|
|
47
|
+
|
|
9
48
|
## Examples
|
|
10
49
|
|
|
11
50
|
### Basic Usage
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,27 @@ export declare interface ApiClient {
|
|
|
9
9
|
getRawContentList: <M extends Model = Model & Record<string, any>>(queryParam?: ContentListQueryParams<M>) => Promise<Content[]>;
|
|
10
10
|
getRawContent: <M extends Model = Model & Record<string, any>>(queryParam: ContentQueryParams<M>) => Promise<Content>;
|
|
11
11
|
getContentListSize: <M extends Model = Model & Record<string, any>>(queryParam?: ContentListSizeQueryParams<M>) => Promise<number>;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Updates (or upserts, when selected by `fieldName`+`language`) a field value on an existing content.
|
|
14
|
+
*
|
|
15
|
+
* The selector chooses how to identify the target:
|
|
16
|
+
* - `{ fieldName, language }` — by field name and language. Upserts when the pair does not exist, which
|
|
17
|
+
* makes it ideal to add translations or fill values for new languages on an existing content.
|
|
18
|
+
*
|
|
19
|
+
* @example By reference (preferred for new integrations)
|
|
20
|
+
* await client.updateContentFieldValue(contentId, { fieldName: 'title', language: 'en' }, 'Hello');
|
|
21
|
+
*/
|
|
22
|
+
updateContentFieldValue(contentId: string, selector: FieldSelector, value: unknown): Promise<boolean>;
|
|
23
|
+
/** @deprecated Pass a `FieldSelector` instead: `updateContentFieldValue(contentId, { fieldName: "name", language: "en" }, value)`. */
|
|
24
|
+
updateContentFieldValue(contentId: string, fieldId: string, value: unknown): Promise<boolean>;
|
|
25
|
+
uploadMedia: (params: UploadMediaParams) => Promise<Media>;
|
|
26
|
+
createContent: (params: CreateContentParams) => Promise<CreateContentResponse>;
|
|
27
|
+
/**
|
|
28
|
+
* Publishes an existing content: snapshots its current draft fieldValues into publishedValues and
|
|
29
|
+
* sets its status to "published". Idempotent — re-publishing an already-published content refreshes
|
|
30
|
+
* the live snapshot from the current draft.
|
|
31
|
+
*/
|
|
32
|
+
publishContent: (contentId: string) => Promise<boolean>;
|
|
13
33
|
}
|
|
14
34
|
|
|
15
35
|
declare interface BaseModel {
|
|
@@ -21,6 +41,7 @@ declare interface BaseModel {
|
|
|
21
41
|
export declare type ClientFilter<Type = string | boolean | number> = Type | {
|
|
22
42
|
in?: Type[];
|
|
23
43
|
ne?: Type;
|
|
44
|
+
nin?: Type[];
|
|
24
45
|
};
|
|
25
46
|
|
|
26
47
|
export declare interface Content {
|
|
@@ -28,6 +49,7 @@ export declare interface Content {
|
|
|
28
49
|
name: string;
|
|
29
50
|
contentType: Lookup;
|
|
30
51
|
lastUpdate: string;
|
|
52
|
+
status?: Status;
|
|
31
53
|
fields: Field[];
|
|
32
54
|
}
|
|
33
55
|
|
|
@@ -42,10 +64,43 @@ declare interface ContentTypeField extends Lookup {
|
|
|
42
64
|
tsType: string;
|
|
43
65
|
isArray: boolean;
|
|
44
66
|
isRequired?: boolean;
|
|
67
|
+
validations?: Validation[];
|
|
45
68
|
}
|
|
46
69
|
|
|
47
70
|
export declare const createClient: (options: Options) => ApiClient;
|
|
48
71
|
|
|
72
|
+
export declare interface CreateContentField {
|
|
73
|
+
name: string;
|
|
74
|
+
value: any;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export declare interface CreateContentLanguageEntry {
|
|
78
|
+
language?: LanguageCode;
|
|
79
|
+
fields: CreateContentField[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export declare interface CreateContentParams {
|
|
83
|
+
contentType: string;
|
|
84
|
+
name: string;
|
|
85
|
+
content?: Array<{
|
|
86
|
+
language?: LanguageCode;
|
|
87
|
+
fields: Array<{
|
|
88
|
+
name: string;
|
|
89
|
+
value: any;
|
|
90
|
+
}>;
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export declare interface CreateContentPayload {
|
|
95
|
+
contentType: string;
|
|
96
|
+
name: string;
|
|
97
|
+
content: CreateContentLanguageEntry[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export declare interface CreateContentResponse {
|
|
101
|
+
id: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
49
104
|
declare interface Entity extends BaseModel {
|
|
50
105
|
type: 'entity';
|
|
51
106
|
fieldList?: Field_2[];
|
|
@@ -73,7 +128,7 @@ export declare interface Field {
|
|
|
73
128
|
value: any;
|
|
74
129
|
type: FieldType;
|
|
75
130
|
isArray: boolean;
|
|
76
|
-
language:
|
|
131
|
+
language: LanguageCode;
|
|
77
132
|
}
|
|
78
133
|
|
|
79
134
|
declare interface Field_2 {
|
|
@@ -85,6 +140,11 @@ declare interface Field_2 {
|
|
|
85
140
|
validations?: Validation[];
|
|
86
141
|
}
|
|
87
142
|
|
|
143
|
+
declare type FieldSelector = {
|
|
144
|
+
fieldName: string;
|
|
145
|
+
language: string;
|
|
146
|
+
};
|
|
147
|
+
|
|
88
148
|
export declare type FieldType =
|
|
89
149
|
| 'short-text'
|
|
90
150
|
| 'long-text'
|
|
@@ -101,6 +161,7 @@ declare type FilterableFields<M extends Model = Model> = {
|
|
|
101
161
|
lastUpdate?: ClientFilter<string>;
|
|
102
162
|
language?: M['language'];
|
|
103
163
|
contentType?: ClientFilter<string>;
|
|
164
|
+
status?: ClientFilter<Status>;
|
|
104
165
|
includeRelatedContent?: boolean;
|
|
105
166
|
} & AllowedFields<M, 'filter'>;
|
|
106
167
|
|
|
@@ -346,6 +407,13 @@ declare type SortableFields<M extends Model> = {
|
|
|
346
407
|
|
|
347
408
|
declare type SortOrder = 'asc' | 'desc';
|
|
348
409
|
|
|
410
|
+
declare type Status = 'draft' | 'published' | 'changed';
|
|
411
|
+
|
|
412
|
+
export declare interface UploadMediaParams {
|
|
413
|
+
file: Blob | File;
|
|
414
|
+
fileName?: string;
|
|
415
|
+
}
|
|
416
|
+
|
|
349
417
|
declare type Validation = { name: string; customArgs?: any };
|
|
350
418
|
|
|
351
419
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,121 +1,176 @@
|
|
|
1
|
-
const
|
|
2
|
-
const n = t.startsWith("fields.");
|
|
3
|
-
if (A(e))
|
|
4
|
-
return O(t, e, n);
|
|
5
|
-
if (e.in)
|
|
6
|
-
return `${t}[in]=${e.in.join(",")}${n && e.in.length > 0 ? l(t, e.in[0]) : ""}`;
|
|
7
|
-
if (e.ne !== void 0)
|
|
8
|
-
return `${t}[ne]=${e.ne}${n ? l(t, e.ne) : ""}`;
|
|
9
|
-
}, _ = (t) => Object.entries(t).map(([e, n]) => `${e}:${n}`).join(","), p = (t, e) => {
|
|
10
|
-
let n = "";
|
|
11
|
-
return t.take !== void 0 && (n += `take=${t.take}`), t.skip !== void 0 && (n += n ? `${e}skip=${t.skip}` : `skip=${t.skip}`), n;
|
|
12
|
-
}, C = (t, e) => Object.entries(t).reduce((n, [o, r], a) => {
|
|
13
|
-
if (o === "sort" && typeof r == "object" && r !== null && !Array.isArray(r)) {
|
|
14
|
-
const s = _(r);
|
|
15
|
-
return a === 0 ? `sort=${s}` : `${n}${e}sort=${s}`;
|
|
16
|
-
} else if (o === "pagination" && typeof r == "object" && r !== null) {
|
|
17
|
-
const s = p(r, e);
|
|
18
|
-
return a === 0 ? s : `${n}${e}${s}`;
|
|
19
|
-
} else if (r !== void 0 && o !== "sort" && o !== "pagination") {
|
|
20
|
-
const s = r;
|
|
21
|
-
return a === 0 ? N(o, s) : `${n}${e}${N(o, s)}`;
|
|
22
|
-
}
|
|
23
|
-
return n;
|
|
24
|
-
}, ""), g = (t) => t && Object.keys(t).length > 0 ? `?${C(t, "&")}` : "", S = {
|
|
1
|
+
const g = {
|
|
25
2
|
IS_PRODUCTION: !0,
|
|
26
3
|
DEFAULT_API_CLIENT_DOMAIN: "api.contentisland.net",
|
|
27
4
|
DEFAULT_API_CLIENT_VERSION: "1.0"
|
|
28
|
-
},
|
|
5
|
+
}, r = {
|
|
29
6
|
SESSION_KEY: "authorization",
|
|
30
7
|
SESSION_TYPE: "Bearer",
|
|
31
|
-
METADATA_KEY: "x-metadata"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
8
|
+
METADATA_KEY: "x-metadata",
|
|
9
|
+
CHUNK_UPLOAD_KEY: "x-chunk-upload"
|
|
10
|
+
}, O = {
|
|
11
|
+
CHUNK_SIZE: 20 * 1024 * 1024
|
|
12
|
+
// 20MB
|
|
13
|
+
}, $ = (t, n) => `&${t}.type=${typeof n}`, P = (t) => typeof t == "string" || typeof t == "number" || typeof t == "boolean", K = (t, n, e) => `${t}=${n}${e ? $(t, n) : ""}`, U = (t, n) => {
|
|
14
|
+
const e = t.startsWith("fields.");
|
|
15
|
+
if (P(n))
|
|
16
|
+
return K(t, n, e);
|
|
17
|
+
if (n.in)
|
|
18
|
+
return `${t}[in]=${n.in.join(",")}${e && n.in.length > 0 ? $(t, n.in[0]) : ""}`;
|
|
19
|
+
if (n.ne !== void 0)
|
|
20
|
+
return `${t}[ne]=${n.ne}${e ? $(t, n.ne) : ""}`;
|
|
21
|
+
if (n.nin)
|
|
22
|
+
return `${t}[nin]=${n.nin.join(",")}${e && n.nin.length > 0 ? $(t, n.nin[0]) : ""}`;
|
|
23
|
+
}, Y = (t) => Object.entries(t).map(([n, e]) => `${n}:${e}`).join(","), j = (t, n) => {
|
|
24
|
+
let e = "";
|
|
25
|
+
return t.take !== void 0 && (e += `take=${t.take}`), t.skip !== void 0 && (e += e ? `${n}skip=${t.skip}` : `skip=${t.skip}`), e;
|
|
26
|
+
}, M = (t, n) => Object.entries(t).reduce((e, [c, s], a) => {
|
|
27
|
+
if (c === "sort" && typeof s == "object" && s !== null && !Array.isArray(s)) {
|
|
28
|
+
const o = Y(s);
|
|
29
|
+
return a === 0 ? `sort=${o}` : `${e}${n}sort=${o}`;
|
|
30
|
+
} else if (c === "pagination" && typeof s == "object" && s !== null) {
|
|
31
|
+
const o = j(s, n);
|
|
32
|
+
return a === 0 ? o : `${e}${n}${o}`;
|
|
33
|
+
} else if (s !== void 0 && c !== "sort" && c !== "pagination") {
|
|
34
|
+
const o = s;
|
|
35
|
+
return a === 0 ? U(c, o) : `${e}${n}${U(c, o)}`;
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
return e;
|
|
38
|
+
}, ""), C = (t) => t && Object.keys(t).length > 0 ? `?${M(t, "&")}` : "", N = async (t) => {
|
|
39
|
+
const n = await t.json().catch(() => null);
|
|
43
40
|
throw Error(
|
|
44
41
|
JSON.stringify({
|
|
45
|
-
status:
|
|
46
|
-
statusText:
|
|
42
|
+
status: t.status,
|
|
43
|
+
statusText: t.statusText,
|
|
44
|
+
...n ? { body: n } : {}
|
|
47
45
|
})
|
|
48
46
|
);
|
|
49
|
-
}
|
|
47
|
+
}, d = (t) => {
|
|
48
|
+
const e = (t.secureProtocol === void 0 ? g.IS_PRODUCTION : t.secureProtocol) ? "https" : "http", c = t.domain ? t.domain : g.DEFAULT_API_CLIENT_DOMAIN, s = t.apiVersion ? t.apiVersion : g.DEFAULT_API_CLIENT_VERSION;
|
|
49
|
+
return `${e}://${c}/api/${s}`;
|
|
50
|
+
}, k = async (t, n) => fetch(`${d(n)}${t}`, {
|
|
51
|
+
headers: {
|
|
52
|
+
[r.SESSION_KEY]: `${r.SESSION_TYPE} ${n.accessToken}`,
|
|
53
|
+
...n.metadata ? { [r.METADATA_KEY]: n.metadata } : {}
|
|
54
|
+
}
|
|
55
|
+
}).then((e) => e.ok ? e.json() : N(e)), R = async (t, n, e) => fetch(`${d(e)}${t}`, {
|
|
50
56
|
method: "PUT",
|
|
51
57
|
headers: {
|
|
52
58
|
"Content-Type": "application/json",
|
|
53
|
-
[
|
|
54
|
-
...
|
|
59
|
+
[r.SESSION_KEY]: `${r.SESSION_TYPE} ${e.accessToken}`,
|
|
60
|
+
...e.metadata ? { [r.METADATA_KEY]: e.metadata } : {}
|
|
55
61
|
},
|
|
56
|
-
body: JSON.stringify(
|
|
57
|
-
}).then((
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
body: JSON.stringify(n)
|
|
63
|
+
}).then((c) => c.ok ? !0 : N(c)), b = async (t, n, e) => fetch(`${d(e)}${t}`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
[r.SESSION_KEY]: `${r.SESSION_TYPE} ${e.accessToken}`,
|
|
68
|
+
...e.metadata ? { [r.METADATA_KEY]: e.metadata } : {}
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(n)
|
|
71
|
+
}).then((c) => c.ok ? c.json() : N(c)), F = async (t, n, e, c) => fetch(`${d(e)}${t}`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
[r.SESSION_KEY]: `${r.SESSION_TYPE} ${e.accessToken}`,
|
|
75
|
+
...e.metadata ? { [r.METADATA_KEY]: e.metadata } : {},
|
|
76
|
+
...c
|
|
77
|
+
},
|
|
78
|
+
body: n
|
|
79
|
+
}).then((s) => s.ok ? s.json() : N(s)), w = async (t, n) => fetch(`${d(n)}${t}`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
[r.SESSION_KEY]: `${r.SESSION_TYPE} ${n.accessToken}`,
|
|
83
|
+
...n.metadata ? { [r.METADATA_KEY]: n.metadata } : {}
|
|
84
|
+
}
|
|
85
|
+
}).then((e) => e.ok ? !0 : N(e)), E = {
|
|
86
|
+
get: k,
|
|
87
|
+
put: R,
|
|
88
|
+
post: b,
|
|
89
|
+
postFormData: F,
|
|
90
|
+
postNoBody: w
|
|
91
|
+
}, B = (t) => t == null ? void 0 : t.includes("|"), H = (t, n) => Array.isArray(t) ? t.map(n) : [], z = (t, n) => t.isArray ? H(t.value, (e) => _(e, n)) : _(t.value, n), x = (t) => B(t.type) && (t.isArray ? t.value.every((n) => typeof n == "object" && "contentType" in n) : typeof t.value == "object" && "contentType" in t.value), J = (t, n) => t.reduce(
|
|
92
|
+
(e, c) => ({
|
|
93
|
+
...e,
|
|
94
|
+
[c.name]: x(c) ? z(c, n) : c.value
|
|
73
95
|
}),
|
|
74
96
|
{}
|
|
75
|
-
),
|
|
76
|
-
var
|
|
77
|
-
const
|
|
78
|
-
return Object.keys(
|
|
79
|
-
id:
|
|
80
|
-
language:
|
|
81
|
-
lastUpdate:
|
|
82
|
-
...
|
|
97
|
+
), Z = (t, n, e, c) => {
|
|
98
|
+
var i;
|
|
99
|
+
const s = e ?? ((i = t[0]) == null ? void 0 : i.language), a = t.filter((T) => T.language === s), o = J(a, s);
|
|
100
|
+
return Object.keys(o).length === 0 && console.warn(`No fields found for language "${s}" and content id "${n}"`), {
|
|
101
|
+
id: n,
|
|
102
|
+
language: s,
|
|
103
|
+
lastUpdate: c,
|
|
104
|
+
...o
|
|
83
105
|
};
|
|
84
|
-
},
|
|
106
|
+
}, _ = (t, n) => Array.isArray(t == null ? void 0 : t.fields) ? Z(t.fields, t.id, n, t.lastUpdate) : {}, u = {
|
|
85
107
|
PROJECT: "/project",
|
|
86
|
-
CONTENT_LIST: (t) => `/contents${
|
|
87
|
-
CONTENT: (t) => `/content${
|
|
88
|
-
CONTENT_LIST_SIZE: (t) => t ? `/contents/size${
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
CONTENT_LIST: (t) => `/contents${C(t)}`,
|
|
109
|
+
CONTENT: (t) => `/content${C(t)}`,
|
|
110
|
+
CONTENT_LIST_SIZE: (t) => t ? `/contents/size${C(t)}` : "/contents/size",
|
|
111
|
+
CREATE_CONTENT: "/content",
|
|
112
|
+
UPDATE_CONTENT: (t) => `/content/${t}`,
|
|
113
|
+
PUBLISH_CONTENT: (t) => `/content/${t}/publish`,
|
|
114
|
+
UPLOAD_MEDIA: "/resource/upload"
|
|
115
|
+
}, V = (t) => {
|
|
116
|
+
const n = (a) => E.get(u.CONTENT_LIST(a), t), e = (a) => E.get(u.CONTENT(a), t), c = () => E.get(u.PROJECT, t), s = async () => {
|
|
117
|
+
var o;
|
|
118
|
+
const a = await c();
|
|
119
|
+
return (o = a == null ? void 0 : a.languages) == null ? void 0 : o[0];
|
|
94
120
|
};
|
|
95
121
|
return {
|
|
96
|
-
getProject:
|
|
122
|
+
getProject: c,
|
|
97
123
|
getContentList: async (a) => {
|
|
98
|
-
const
|
|
99
|
-
return Array.isArray(
|
|
124
|
+
const o = await n(a), i = (a == null ? void 0 : a.language) ?? await s();
|
|
125
|
+
return Array.isArray(o) ? o.map((T) => _(T, i)) : [];
|
|
100
126
|
},
|
|
101
127
|
getContent: async (a) => {
|
|
102
|
-
const
|
|
103
|
-
return
|
|
128
|
+
const o = await e(a), i = (a == null ? void 0 : a.language) ?? await s();
|
|
129
|
+
return _(o, i);
|
|
130
|
+
},
|
|
131
|
+
getRawContentList: n,
|
|
132
|
+
getRawContent: e,
|
|
133
|
+
getContentListSize: (a) => E.get(u.CONTENT_LIST_SIZE(a), t),
|
|
134
|
+
updateContentFieldValue: (a, o, i) => {
|
|
135
|
+
const T = typeof o == "string" ? { id: o, value: i } : {
|
|
136
|
+
fieldName: o.fieldName,
|
|
137
|
+
language: o.language,
|
|
138
|
+
value: i
|
|
139
|
+
};
|
|
140
|
+
return E.put(`${u.UPDATE_CONTENT(a)}`, T, t);
|
|
141
|
+
},
|
|
142
|
+
uploadMedia: async (a) => {
|
|
143
|
+
const { file: o } = a, i = a.fileName ?? "upload", T = Math.ceil(o.size / O.CHUNK_SIZE);
|
|
144
|
+
let p, I, h, f;
|
|
145
|
+
for (let l = 0; l < T; l++) {
|
|
146
|
+
const y = l * O.CHUNK_SIZE, m = Math.min(y + O.CHUNK_SIZE, o.size), D = o.slice(y, m, o.type), L = {
|
|
147
|
+
chunkIndex: l,
|
|
148
|
+
chunkSize: D.size,
|
|
149
|
+
totalChunks: T,
|
|
150
|
+
uploadId: p,
|
|
151
|
+
multiPartUpload: I,
|
|
152
|
+
filePrefix: h
|
|
153
|
+
}, A = new FormData();
|
|
154
|
+
A.append("chunkOptions", JSON.stringify(L)), A.append("chunk", D, i);
|
|
155
|
+
const S = await E.postFormData(u.UPLOAD_MEDIA, A, t, {
|
|
156
|
+
[r.CHUNK_UPLOAD_KEY]: "true"
|
|
157
|
+
});
|
|
158
|
+
"uploadId" in S ? (p = S.uploadId, I = S.multiPartUpload, h = S.filePrefix) : f = S;
|
|
159
|
+
}
|
|
160
|
+
return f;
|
|
161
|
+
},
|
|
162
|
+
createContent: async (a) => {
|
|
163
|
+
const o = {
|
|
164
|
+
contentType: a.contentType,
|
|
165
|
+
name: a.name,
|
|
166
|
+
content: a.content || []
|
|
167
|
+
};
|
|
168
|
+
return E.post(u.CREATE_CONTENT, o, t);
|
|
104
169
|
},
|
|
105
|
-
|
|
106
|
-
getRawContent: n,
|
|
107
|
-
getContentListSize: (a) => T.get(u.CONTENT_LIST_SIZE(a), t),
|
|
108
|
-
updateContentFieldValue: (a, s, c) => T.put(
|
|
109
|
-
`${u.CONTENT(null)}/${a}`,
|
|
110
|
-
{
|
|
111
|
-
id: s,
|
|
112
|
-
value: c
|
|
113
|
-
},
|
|
114
|
-
t
|
|
115
|
-
)
|
|
170
|
+
publishContent: (a) => E.postNoBody(u.PUBLISH_CONTENT(a), t)
|
|
116
171
|
};
|
|
117
172
|
};
|
|
118
173
|
export {
|
|
119
|
-
|
|
120
|
-
|
|
174
|
+
V as createClient,
|
|
175
|
+
_ as mapContentToModel
|
|
121
176
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(d,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(d=typeof globalThis<"u"?globalThis:d||self,S(d.ApiClient={}))})(this,function(d){"use strict";const S={IS_PRODUCTION:!0,DEFAULT_API_CLIENT_DOMAIN:"api.contentisland.net",DEFAULT_API_CLIENT_VERSION:"1.0"},r={SESSION_KEY:"authorization",SESSION_TYPE:"Bearer",METADATA_KEY:"x-metadata",CHUNK_UPLOAD_KEY:"x-chunk-upload"},A={CHUNK_SIZE:20*1024*1024},g=(t,e)=>`&${t}.type=${typeof e}`,U=t=>typeof t=="string"||typeof t=="number"||typeof t=="boolean",L=(t,e,n)=>`${t}=${e}${n?g(t,e):""}`,h=(t,e)=>{const n=t.startsWith("fields.");if(U(e))return L(t,e,n);if(e.in)return`${t}[in]=${e.in.join(",")}${n&&e.in.length>0?g(t,e.in[0]):""}`;if(e.ne!==void 0)return`${t}[ne]=${e.ne}${n?g(t,e.ne):""}`;if(e.nin)return`${t}[nin]=${e.nin.join(",")}${n&&e.nin.length>0?g(t,e.nin[0]):""}`},j=t=>Object.entries(t).map(([e,n])=>`${e}:${n}`).join(","),K=(t,e)=>{let n="";return t.take!==void 0&&(n+=`take=${t.take}`),t.skip!==void 0&&(n+=n?`${e}skip=${t.skip}`:`skip=${t.skip}`),n},Y=(t,e)=>Object.entries(t).reduce((n,[s,c],a)=>{if(s==="sort"&&typeof c=="object"&&c!==null&&!Array.isArray(c)){const o=j(c);return a===0?`sort=${o}`:`${n}${e}sort=${o}`}else if(s==="pagination"&&typeof c=="object"&&c!==null){const o=K(c,e);return a===0?o:`${n}${e}${o}`}else if(c!==void 0&&s!=="sort"&&s!=="pagination"){const o=c;return a===0?h(s,o):`${n}${e}${h(s,o)}`}return n},""),O=t=>t&&Object.keys(t).length>0?`?${Y(t,"&")}`:"",l=async t=>{const e=await t.json().catch(()=>null);throw Error(JSON.stringify({status:t.status,statusText:t.statusText,...e?{body:e}:{}}))},N=t=>{const n=(t.secureProtocol===void 0?S.IS_PRODUCTION:t.secureProtocol)?"https":"http",s=t.domain?t.domain:S.DEFAULT_API_CLIENT_DOMAIN,c=t.apiVersion?t.apiVersion:S.DEFAULT_API_CLIENT_VERSION;return`${n}://${s}/api/${c}`},T={get:async(t,e)=>fetch(`${N(e)}${t}`,{headers:{[r.SESSION_KEY]:`${r.SESSION_TYPE} ${e.accessToken}`,...e.metadata?{[r.METADATA_KEY]:e.metadata}:{}}}).then(n=>n.ok?n.json():l(n)),put:async(t,e,n)=>fetch(`${N(n)}${t}`,{method:"PUT",headers:{"Content-Type":"application/json",[r.SESSION_KEY]:`${r.SESSION_TYPE} ${n.accessToken}`,...n.metadata?{[r.METADATA_KEY]:n.metadata}:{}},body:JSON.stringify(e)}).then(s=>s.ok?!0:l(s)),post:async(t,e,n)=>fetch(`${N(n)}${t}`,{method:"POST",headers:{"Content-Type":"application/json",[r.SESSION_KEY]:`${r.SESSION_TYPE} ${n.accessToken}`,...n.metadata?{[r.METADATA_KEY]:n.metadata}:{}},body:JSON.stringify(e)}).then(s=>s.ok?s.json():l(s)),postFormData:async(t,e,n,s)=>fetch(`${N(n)}${t}`,{method:"POST",headers:{[r.SESSION_KEY]:`${r.SESSION_TYPE} ${n.accessToken}`,...n.metadata?{[r.METADATA_KEY]:n.metadata}:{},...s},body:e}).then(c=>c.ok?c.json():l(c)),postNoBody:async(t,e)=>fetch(`${N(e)}${t}`,{method:"POST",headers:{[r.SESSION_KEY]:`${r.SESSION_TYPE} ${e.accessToken}`,...e.metadata?{[r.METADATA_KEY]:e.metadata}:{}}}).then(n=>n.ok?!0:l(n))},M=t=>t==null?void 0:t.includes("|"),b=(t,e)=>Array.isArray(t)?t.map(e):[],k=(t,e)=>t.isArray?b(t.value,n=>$(n,e)):$(t.value,e),R=t=>M(t.type)&&(t.isArray?t.value.every(e=>typeof e=="object"&&"contentType"in e):typeof t.value=="object"&&"contentType"in t.value),F=(t,e)=>t.reduce((n,s)=>({...n,[s.name]:R(s)?k(s,e):s.value}),{}),w=(t,e,n,s)=>{var i;const c=n??((i=t[0])==null?void 0:i.language),a=t.filter(E=>E.language===c),o=F(a,c);return Object.keys(o).length===0&&console.warn(`No fields found for language "${c}" and content id "${e}"`),{id:e,language:c,lastUpdate:s,...o}},$=(t,e)=>Array.isArray(t==null?void 0:t.fields)?w(t.fields,t.id,e,t.lastUpdate):{},u={PROJECT:"/project",CONTENT_LIST:t=>`/contents${O(t)}`,CONTENT:t=>`/content${O(t)}`,CONTENT_LIST_SIZE:t=>t?`/contents/size${O(t)}`:"/contents/size",CREATE_CONTENT:"/content",UPDATE_CONTENT:t=>`/content/${t}`,PUBLISH_CONTENT:t=>`/content/${t}/publish`,UPLOAD_MEDIA:"/resource/upload"},B=t=>{const e=a=>T.get(u.CONTENT_LIST(a),t),n=a=>T.get(u.CONTENT(a),t),s=()=>T.get(u.PROJECT,t),c=async()=>{var o;const a=await s();return(o=a==null?void 0:a.languages)==null?void 0:o[0]};return{getProject:s,getContentList:async a=>{const o=await e(a),i=(a==null?void 0:a.language)??await c();return Array.isArray(o)?o.map(E=>$(E,i)):[]},getContent:async a=>{const o=await n(a),i=(a==null?void 0:a.language)??await c();return $(o,i)},getRawContentList:e,getRawContent:n,getContentListSize:a=>T.get(u.CONTENT_LIST_SIZE(a),t),updateContentFieldValue:(a,o,i)=>{const E=typeof o=="string"?{id:o,value:i}:{fieldName:o.fieldName,language:o.language,value:i};return T.put(`${u.UPDATE_CONTENT(a)}`,E,t)},uploadMedia:async a=>{const{file:o}=a,i=a.fileName??"upload",E=Math.ceil(o.size/A.CHUNK_SIZE);let f,I,y,m;for(let p=0;p<E;p++){const D=p*A.CHUNK_SIZE,H=Math.min(D+A.CHUNK_SIZE,o.size),P=o.slice(D,H,o.type),z={chunkIndex:p,chunkSize:P.size,totalChunks:E,uploadId:f,multiPartUpload:I,filePrefix:y},C=new FormData;C.append("chunkOptions",JSON.stringify(z)),C.append("chunk",P,i);const _=await T.postFormData(u.UPLOAD_MEDIA,C,t,{[r.CHUNK_UPLOAD_KEY]:"true"});"uploadId"in _?(f=_.uploadId,I=_.multiPartUpload,y=_.filePrefix):m=_}return m},createContent:async a=>{const o={contentType:a.contentType,name:a.name,content:a.content||[]};return T.post(u.CREATE_CONTENT,o,t)},publishContent:a=>T.postNoBody(u.PUBLISH_CONTENT(a),t)}};d.createClient=B,d.mapContentToModel=$,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@content-island/api-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Content Island - REST API Client",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"
|
|
25
|
-
"build:dev": "vite build --mode development",
|
|
24
|
+
"create-env": "sh ./create-dev-env.sh",
|
|
25
|
+
"build:dev": "npm run create-env && vite build --mode development",
|
|
26
26
|
"build": "vite build",
|
|
27
27
|
"type-check": "tsc --noEmit --preserveWatchOutput",
|
|
28
28
|
"test": "vitest run -c ./config/test/config.ts",
|