@cloudcannon/sdk 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -1
- package/dist/index.js +27 -0
- package/dist/schema.d.ts +66 -6
- package/dist/src/build.d.ts +6 -0
- package/dist/src/build.js +15 -0
- package/dist/src/editing-session-file.d.ts +13 -0
- package/dist/src/editing-session-file.js +58 -0
- package/dist/src/editing-session.d.ts +14 -0
- package/dist/src/editing-session.js +54 -0
- package/dist/src/site.d.ts +11 -1
- package/dist/src/site.js +91 -0
- package/dist/src/sync.d.ts +6 -0
- package/dist/src/sync.js +15 -0
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { components, operations, paths } from './schema.ts';
|
|
2
|
+
import { BuildClient } from './src/build.ts';
|
|
3
|
+
import { type CommitEditingSessionOptions, type CommitEditingSessionResponse, EditingSessionClient } from './src/editing-session.ts';
|
|
4
|
+
import { EditingSessionFileClient } from './src/editing-session-file.ts';
|
|
2
5
|
import { InboxClient } from './src/inbox.ts';
|
|
3
6
|
import { OrgClient } from './src/org.ts';
|
|
4
7
|
import { type BuildConfiguration, SiteClient } from './src/site.ts';
|
|
5
8
|
import { SiteInboxClient } from './src/site-inbox.ts';
|
|
6
|
-
|
|
9
|
+
import { SyncClient } from './src/sync.ts';
|
|
10
|
+
export type { BuildConfiguration, CommitEditingSessionOptions, CommitEditingSessionResponse };
|
|
7
11
|
export type Provider = operations['Providers_Repositories']['parameters']['path']['provider'];
|
|
8
12
|
export type Site = components['schemas']['SiteBlueprint'];
|
|
9
13
|
export type Org = components['schemas']['OrgBlueprintFull'];
|
|
@@ -15,6 +19,10 @@ export type SiteDam = components['schemas']['SiteDamBlueprint'];
|
|
|
15
19
|
export type FormSubmission = components['schemas']['FormHookBlueprint'];
|
|
16
20
|
export type Inbox = components['schemas']['InboxBlueprint'];
|
|
17
21
|
export type Dam = components['schemas']['DamBlueprint'];
|
|
22
|
+
export type EditingSession = components['schemas']['EditingSessionBlueprint'];
|
|
23
|
+
export type EditingSessionFile = components['schemas']['EditingSessionFileBlueprint'];
|
|
24
|
+
export type EditingSessionFileContribution = components['schemas']['EditingSessionFileContributionBlueprint'];
|
|
25
|
+
export type UploadData = operations['Index_UploadData']['responses']['200']['content']['application/json'];
|
|
18
26
|
export type ProviderDetails = {
|
|
19
27
|
provider: Provider;
|
|
20
28
|
repository: string;
|
|
@@ -73,5 +81,10 @@ export default class CloudCannonClient {
|
|
|
73
81
|
site(uuid: string): SiteClient;
|
|
74
82
|
inbox(uuid: string): InboxClient;
|
|
75
83
|
siteInbox(uuid: string): SiteInboxClient;
|
|
84
|
+
editingSession(uuid: string): EditingSessionClient;
|
|
85
|
+
editingSessionFile(uuid: string): EditingSessionFileClient;
|
|
86
|
+
build(uuid: string): BuildClient;
|
|
87
|
+
sync(uuid: string): SyncClient;
|
|
76
88
|
orgs(): Promise<Org[]>;
|
|
89
|
+
getUploadData(): Promise<UploadData>;
|
|
77
90
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { BuildClient } from "./src/build.js";
|
|
2
|
+
import { EditingSessionClient, } from "./src/editing-session.js";
|
|
3
|
+
import { EditingSessionFileClient } from "./src/editing-session-file.js";
|
|
1
4
|
import { InboxClient } from "./src/inbox.js";
|
|
2
5
|
import { OrgClient } from "./src/org.js";
|
|
3
6
|
import { SiteClient } from "./src/site.js";
|
|
4
7
|
import { SiteInboxClient } from "./src/site-inbox.js";
|
|
8
|
+
import { SyncClient } from "./src/sync.js";
|
|
5
9
|
export default class CloudCannonClient {
|
|
6
10
|
#apiKey;
|
|
7
11
|
#appDomain;
|
|
@@ -52,9 +56,32 @@ export default class CloudCannonClient {
|
|
|
52
56
|
siteInbox(uuid) {
|
|
53
57
|
return new SiteInboxClient(uuid, this);
|
|
54
58
|
}
|
|
59
|
+
editingSession(uuid) {
|
|
60
|
+
return new EditingSessionClient(uuid, this);
|
|
61
|
+
}
|
|
62
|
+
editingSessionFile(uuid) {
|
|
63
|
+
return new EditingSessionFileClient(uuid, this);
|
|
64
|
+
}
|
|
65
|
+
build(uuid) {
|
|
66
|
+
return new BuildClient(uuid, this);
|
|
67
|
+
}
|
|
68
|
+
sync(uuid) {
|
|
69
|
+
return new SyncClient(uuid, this);
|
|
70
|
+
}
|
|
55
71
|
async orgs() {
|
|
56
72
|
const resp = await this.fetch('/orgs');
|
|
57
73
|
const orgs = await resp.json();
|
|
58
74
|
return orgs;
|
|
59
75
|
}
|
|
76
|
+
async getUploadData() {
|
|
77
|
+
const resp = await this.fetch('/upload-data');
|
|
78
|
+
if (resp.status === 403) {
|
|
79
|
+
throw new Error('Error fetching upload data. Permission denied');
|
|
80
|
+
}
|
|
81
|
+
if (resp.status === 422) {
|
|
82
|
+
throw new Error('Error fetching upload data. Invalid request');
|
|
83
|
+
}
|
|
84
|
+
const uploadData = await resp.json();
|
|
85
|
+
return uploadData;
|
|
86
|
+
}
|
|
60
87
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -2202,6 +2202,23 @@ export interface paths {
|
|
|
2202
2202
|
patch?: never;
|
|
2203
2203
|
trace?: never;
|
|
2204
2204
|
};
|
|
2205
|
+
'/api/v0/upload-data': {
|
|
2206
|
+
parameters: {
|
|
2207
|
+
query?: never;
|
|
2208
|
+
header?: never;
|
|
2209
|
+
path?: never;
|
|
2210
|
+
cookie?: never;
|
|
2211
|
+
};
|
|
2212
|
+
/** @description Get the presigned data for file upload */
|
|
2213
|
+
get: operations['Index_UploadData'];
|
|
2214
|
+
put?: never;
|
|
2215
|
+
post?: never;
|
|
2216
|
+
delete?: never;
|
|
2217
|
+
options?: never;
|
|
2218
|
+
head?: never;
|
|
2219
|
+
patch?: never;
|
|
2220
|
+
trace?: never;
|
|
2221
|
+
};
|
|
2205
2222
|
'/api/v0/users': {
|
|
2206
2223
|
parameters: {
|
|
2207
2224
|
query?: never;
|
|
@@ -3841,7 +3858,7 @@ export interface operations {
|
|
|
3841
3858
|
[name: string]: unknown;
|
|
3842
3859
|
};
|
|
3843
3860
|
content: {
|
|
3844
|
-
'application/json': components['schemas']['
|
|
3861
|
+
'application/json': components['schemas']['EditingSessionFileContributionBlueprint'][];
|
|
3845
3862
|
};
|
|
3846
3863
|
};
|
|
3847
3864
|
403: components['responses']['ForbiddenResp'];
|
|
@@ -3859,9 +3876,9 @@ export interface operations {
|
|
|
3859
3876
|
requestBody: {
|
|
3860
3877
|
content: {
|
|
3861
3878
|
'application/json': {
|
|
3862
|
-
s3_key
|
|
3879
|
+
s3_key: string;
|
|
3863
3880
|
content_hash: string;
|
|
3864
|
-
previous_content_hash?:
|
|
3881
|
+
previous_content_hash?: string;
|
|
3865
3882
|
};
|
|
3866
3883
|
};
|
|
3867
3884
|
};
|
|
@@ -4039,7 +4056,13 @@ export interface operations {
|
|
|
4039
4056
|
};
|
|
4040
4057
|
cookie?: never;
|
|
4041
4058
|
};
|
|
4042
|
-
requestBody
|
|
4059
|
+
requestBody: {
|
|
4060
|
+
content: {
|
|
4061
|
+
'application/json': {
|
|
4062
|
+
previous_content_hash: string;
|
|
4063
|
+
};
|
|
4064
|
+
};
|
|
4065
|
+
};
|
|
4043
4066
|
responses: {
|
|
4044
4067
|
/** @description Created */
|
|
4045
4068
|
200: {
|
|
@@ -4257,8 +4280,8 @@ export interface operations {
|
|
|
4257
4280
|
edit_type?: string | null;
|
|
4258
4281
|
path?: string | null;
|
|
4259
4282
|
source_path?: string | null;
|
|
4260
|
-
discard_unsaved?:
|
|
4261
|
-
previous_content_hash?:
|
|
4283
|
+
discard_unsaved?: boolean;
|
|
4284
|
+
previous_content_hash?: string;
|
|
4262
4285
|
metadata?: {
|
|
4263
4286
|
[key: string]: unknown;
|
|
4264
4287
|
};
|
|
@@ -4266,6 +4289,15 @@ export interface operations {
|
|
|
4266
4289
|
};
|
|
4267
4290
|
};
|
|
4268
4291
|
responses: {
|
|
4292
|
+
/** @description Success */
|
|
4293
|
+
200: {
|
|
4294
|
+
headers: {
|
|
4295
|
+
[name: string]: unknown;
|
|
4296
|
+
};
|
|
4297
|
+
content: {
|
|
4298
|
+
'application/json': components['schemas']['EditingSessionFileBlueprint'];
|
|
4299
|
+
};
|
|
4300
|
+
};
|
|
4269
4301
|
/** @description Created */
|
|
4270
4302
|
201: {
|
|
4271
4303
|
headers: {
|
|
@@ -8613,6 +8645,34 @@ export interface operations {
|
|
|
8613
8645
|
403: components['responses']['ForbiddenResp'];
|
|
8614
8646
|
};
|
|
8615
8647
|
};
|
|
8648
|
+
Index_UploadData: {
|
|
8649
|
+
parameters: {
|
|
8650
|
+
query?: never;
|
|
8651
|
+
header?: never;
|
|
8652
|
+
path?: never;
|
|
8653
|
+
cookie?: never;
|
|
8654
|
+
};
|
|
8655
|
+
requestBody?: never;
|
|
8656
|
+
responses: {
|
|
8657
|
+
/** @description OK */
|
|
8658
|
+
200: {
|
|
8659
|
+
headers: {
|
|
8660
|
+
[name: string]: unknown;
|
|
8661
|
+
};
|
|
8662
|
+
content: {
|
|
8663
|
+
'application/json': {
|
|
8664
|
+
prefix: string;
|
|
8665
|
+
url: string;
|
|
8666
|
+
fields: {
|
|
8667
|
+
[key: string]: string;
|
|
8668
|
+
};
|
|
8669
|
+
};
|
|
8670
|
+
};
|
|
8671
|
+
};
|
|
8672
|
+
403: components['responses']['ForbiddenResp'];
|
|
8673
|
+
422: components['responses']['ErrorResp'];
|
|
8674
|
+
};
|
|
8675
|
+
};
|
|
8616
8676
|
Users_ShowCurrentUser: {
|
|
8617
8677
|
parameters: {
|
|
8618
8678
|
query?: never;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class BuildClient {
|
|
2
|
+
#uuid;
|
|
3
|
+
#client;
|
|
4
|
+
constructor(uuid, client) {
|
|
5
|
+
this.#uuid = uuid;
|
|
6
|
+
this.#client = client;
|
|
7
|
+
}
|
|
8
|
+
async get() {
|
|
9
|
+
const resp = await this.#client.fetch(`/builds/${this.#uuid}`);
|
|
10
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
11
|
+
throw new Error('Error fetching build. Permission denied');
|
|
12
|
+
}
|
|
13
|
+
return resp;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type CloudCannonClient from '../index.ts';
|
|
2
|
+
import type { EditingSessionFile, EditingSessionFileContribution } from '../index.ts';
|
|
3
|
+
import type { operations } from '../schema.js';
|
|
4
|
+
export type CreateContributionOptions = operations['Editing Session Contributions_Create']['requestBody']['content']['application/json'];
|
|
5
|
+
export type UnlockOptions = operations['Editing Session File_Unlock']['requestBody']['content']['application/json'];
|
|
6
|
+
export declare class EditingSessionFileClient {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(uuid: string, client: CloudCannonClient);
|
|
9
|
+
get(): Promise<EditingSessionFile>;
|
|
10
|
+
getContributions(): Promise<EditingSessionFileContribution[]>;
|
|
11
|
+
createContribution(body: CreateContributionOptions): Promise<EditingSessionFileContribution>;
|
|
12
|
+
unlock(body: UnlockOptions): Promise<EditingSessionFileContribution>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ApiError } from "./errors.js";
|
|
2
|
+
export class EditingSessionFileClient {
|
|
3
|
+
#uuid;
|
|
4
|
+
#client;
|
|
5
|
+
constructor(uuid, client) {
|
|
6
|
+
this.#uuid = uuid;
|
|
7
|
+
this.#client = client;
|
|
8
|
+
}
|
|
9
|
+
async get() {
|
|
10
|
+
const resp = await this.#client.fetch(`/editing_session_files/${this.#uuid}`);
|
|
11
|
+
if (resp.status === 403) {
|
|
12
|
+
throw new Error('Error fetching editing session file. Permission denied');
|
|
13
|
+
}
|
|
14
|
+
const file = await resp.json();
|
|
15
|
+
return file;
|
|
16
|
+
}
|
|
17
|
+
async getContributions() {
|
|
18
|
+
const resp = await this.#client.fetch(`/editing_session_files/${this.#uuid}/contributions`);
|
|
19
|
+
if (resp.status === 403) {
|
|
20
|
+
throw new Error('Error fetching editing session file contributions. Permission denied');
|
|
21
|
+
}
|
|
22
|
+
const contributions = await resp.json();
|
|
23
|
+
return contributions;
|
|
24
|
+
}
|
|
25
|
+
async createContribution(body) {
|
|
26
|
+
const resp = await this.#client.fetch(`/editing_session_files/${this.#uuid}/contributions`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body,
|
|
29
|
+
});
|
|
30
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
31
|
+
throw new Error('Error creating editing session file contribution. Permission denied');
|
|
32
|
+
}
|
|
33
|
+
if (resp.status === 422) {
|
|
34
|
+
const errorResp = await resp.json();
|
|
35
|
+
throw new ApiError('Error creating editing session file contribution. Invalid request', errorResp.errors, `/editing_session_files/${this.#uuid}/contributions`, { method: 'POST', body }, resp.status);
|
|
36
|
+
}
|
|
37
|
+
const contribution = await resp.json();
|
|
38
|
+
return contribution;
|
|
39
|
+
}
|
|
40
|
+
async unlock(body) {
|
|
41
|
+
const resp = await this.#client.fetch(`/editing_session_files/${this.#uuid}/unlock`, {
|
|
42
|
+
method: 'PUT',
|
|
43
|
+
body,
|
|
44
|
+
});
|
|
45
|
+
if (resp.status === 403) {
|
|
46
|
+
throw new Error('Error unlocking editing session file. Permission denied');
|
|
47
|
+
}
|
|
48
|
+
if (resp.status === 404) {
|
|
49
|
+
throw new Error('Error unlocking editing session file. File not found');
|
|
50
|
+
}
|
|
51
|
+
if (resp.status === 422) {
|
|
52
|
+
const errorResp = await resp.json();
|
|
53
|
+
throw new ApiError('Error unlocking editing session file. Invalid request', errorResp.errors, `/editing_session_files/${this.#uuid}/unlock`, { method: 'PUT', body }, resp.status);
|
|
54
|
+
}
|
|
55
|
+
const contribution = await resp.json();
|
|
56
|
+
return contribution;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type CloudCannonClient from '../index.ts';
|
|
2
|
+
import type { EditingSession, EditingSessionFile } from '../index.ts';
|
|
3
|
+
import type { operations } from '../schema.js';
|
|
4
|
+
export type CreateEditingSessionFileOptions = operations['Editing Session Files_Create']['requestBody']['content']['application/json'];
|
|
5
|
+
export type CommitEditingSessionOptions = operations['Editing Session_Commit']['requestBody']['content']['application/json'];
|
|
6
|
+
export type CommitEditingSessionResponse = operations['Editing Session_Commit']['responses']['200']['content']['application/json'];
|
|
7
|
+
export declare class EditingSessionClient {
|
|
8
|
+
#private;
|
|
9
|
+
constructor(uuid: string, client: CloudCannonClient);
|
|
10
|
+
get(): Promise<EditingSession>;
|
|
11
|
+
getFiles(): Promise<EditingSessionFile[]>;
|
|
12
|
+
createFile(body: CreateEditingSessionFileOptions): Promise<EditingSessionFile>;
|
|
13
|
+
commit(): Promise<CommitEditingSessionResponse>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ApiError } from "./errors.js";
|
|
2
|
+
export class EditingSessionClient {
|
|
3
|
+
#uuid;
|
|
4
|
+
#client;
|
|
5
|
+
constructor(uuid, client) {
|
|
6
|
+
this.#uuid = uuid;
|
|
7
|
+
this.#client = client;
|
|
8
|
+
}
|
|
9
|
+
async get() {
|
|
10
|
+
const resp = await this.#client.fetch(`/editing_sessions/${this.#uuid}`);
|
|
11
|
+
if (resp.status === 403) {
|
|
12
|
+
throw new Error('Error fetching editing session. Permission denied');
|
|
13
|
+
}
|
|
14
|
+
const editingSession = await resp.json();
|
|
15
|
+
return editingSession;
|
|
16
|
+
}
|
|
17
|
+
async getFiles() {
|
|
18
|
+
const resp = await this.#client.fetch(`/editing_sessions/${this.#uuid}/files`);
|
|
19
|
+
if (resp.status === 403) {
|
|
20
|
+
throw new Error('Error fetching editing session files. Permission denied');
|
|
21
|
+
}
|
|
22
|
+
const files = await resp.json();
|
|
23
|
+
return files;
|
|
24
|
+
}
|
|
25
|
+
async createFile(body) {
|
|
26
|
+
const resp = await this.#client.fetch(`/editing_sessions/${this.#uuid}/files`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body,
|
|
29
|
+
});
|
|
30
|
+
if (resp.status === 403) {
|
|
31
|
+
throw new Error('Error creating editing session file. Permission denied');
|
|
32
|
+
}
|
|
33
|
+
if (resp.status === 422) {
|
|
34
|
+
const errorResp = await resp.json();
|
|
35
|
+
throw new ApiError('Error creating editing session file. Invalid request', errorResp.errors, `/editing_sessions/${this.#uuid}/files`, { method: 'POST', body }, resp.status);
|
|
36
|
+
}
|
|
37
|
+
const file = await resp.json();
|
|
38
|
+
return file;
|
|
39
|
+
}
|
|
40
|
+
async commit() {
|
|
41
|
+
const resp = await this.#client.fetch(`/editing_sessions/${this.#uuid}/commit`, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
});
|
|
44
|
+
if (resp.status === 403) {
|
|
45
|
+
throw new Error('Error committing editing session. Permission denied');
|
|
46
|
+
}
|
|
47
|
+
if (resp.status === 422) {
|
|
48
|
+
const errorResp = await resp.json();
|
|
49
|
+
throw new ApiError('Error committing editing session. Invalid request', errorResp.errors, `/editing_sessions/${this.#uuid}/commit`, { method: 'POST' }, resp.status);
|
|
50
|
+
}
|
|
51
|
+
const result = await resp.json();
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/src/site.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type CloudCannonClient from '../index.ts';
|
|
2
|
-
import type { Build, ProviderDetails, Site, SiteDam, SiteInbox, SiteScan, Sync } from '../index.ts';
|
|
2
|
+
import type { Build, EditingSession, ProviderDetails, Site, SiteDam, SiteInbox, SiteScan, Sync } from '../index.ts';
|
|
3
3
|
import type { operations } from '../schema.js';
|
|
4
4
|
export type BuildConfiguration = Partial<Omit<operations['Sites_UpdateBuild']['requestBody']['content']['application/json'], 'build_configuration'>> & {
|
|
5
5
|
compile?: {
|
|
@@ -24,6 +24,11 @@ export type UpdateSiteOptions = operations['Sites_Update']['requestBody']['conte
|
|
|
24
24
|
export type CopySiteOptions = operations['Sites_Copy']['requestBody']['content']['application/json'];
|
|
25
25
|
export type ConnectInboxOptions = operations['Site Inboxes_Create']['requestBody']['content']['application/json'];
|
|
26
26
|
export type ConnectDamOptions = operations['Dams_Create']['requestBody']['content']['application/json'];
|
|
27
|
+
export type FileListing = operations['Files_Index']['responses']['200']['content']['application/json'][number];
|
|
28
|
+
export type UploadFileOptions = {
|
|
29
|
+
type?: string;
|
|
30
|
+
overwriteExistingFile?: boolean;
|
|
31
|
+
};
|
|
27
32
|
export declare class SiteClient {
|
|
28
33
|
#private;
|
|
29
34
|
constructor(uuid: string, client: CloudCannonClient);
|
|
@@ -34,6 +39,7 @@ export declare class SiteClient {
|
|
|
34
39
|
updateBuildConfig(options: BuildConfiguration): Promise<Site>;
|
|
35
40
|
getBuilds(): Promise<Build[]>;
|
|
36
41
|
rebuild(): Promise<void>;
|
|
42
|
+
listFiles(): Promise<FileListing[]>;
|
|
37
43
|
getFile(path: string): Promise<Response>;
|
|
38
44
|
getSyncs(): Promise<Sync[]>;
|
|
39
45
|
getScan(): Promise<SiteScan>;
|
|
@@ -48,4 +54,8 @@ export declare class SiteClient {
|
|
|
48
54
|
connectInbox(body: ConnectInboxOptions): Promise<SiteInbox>;
|
|
49
55
|
getDamConnections(): Promise<SiteDam[]>;
|
|
50
56
|
connectDam(body: ConnectDamOptions): Promise<SiteDam>;
|
|
57
|
+
getEditingSessions(): Promise<EditingSession[]>;
|
|
58
|
+
createEditingSession(): Promise<EditingSession>;
|
|
59
|
+
getLatestEditingSession(): Promise<EditingSession>;
|
|
60
|
+
uploadFile(path: string, content: BlobPart, options?: UploadFileOptions): Promise<void>;
|
|
51
61
|
}
|
package/dist/src/site.js
CHANGED
|
@@ -86,6 +86,18 @@ export class SiteClient {
|
|
|
86
86
|
throw new Error('Error creating build. Permission denied');
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
async listFiles() {
|
|
90
|
+
const resp = await this.#client.fetch(`/sites/${this.#uuid}/files`);
|
|
91
|
+
if (resp.status === 401) {
|
|
92
|
+
throw new Error('Error fetching files. Permission denied');
|
|
93
|
+
}
|
|
94
|
+
if (resp.status === 422) {
|
|
95
|
+
const errorResp = await resp.json();
|
|
96
|
+
throw new ApiError('Error fetching files. Invalid request', errorResp.errors, `/sites/${this.#uuid}/files`, {}, resp.status);
|
|
97
|
+
}
|
|
98
|
+
const files = await resp.json();
|
|
99
|
+
return files;
|
|
100
|
+
}
|
|
89
101
|
async getFile(path) {
|
|
90
102
|
const resp = await this.#client.fetch(`/sites/${this.#uuid}/files/${encodeURIComponent(path)}`);
|
|
91
103
|
if (resp.status === 401 || resp.status === 403) {
|
|
@@ -251,4 +263,83 @@ export class SiteClient {
|
|
|
251
263
|
const dam = await resp.json();
|
|
252
264
|
return dam;
|
|
253
265
|
}
|
|
266
|
+
async getEditingSessions() {
|
|
267
|
+
const resp = await this.#client.fetch(`/sites/${this.#uuid}/editing_sessions`);
|
|
268
|
+
if (resp.status === 403) {
|
|
269
|
+
throw new Error('Error fetching editing sessions. Permission denied');
|
|
270
|
+
}
|
|
271
|
+
const editingSessions = await resp.json();
|
|
272
|
+
return editingSessions;
|
|
273
|
+
}
|
|
274
|
+
async createEditingSession() {
|
|
275
|
+
const resp = await this.#client.fetch(`/sites/${this.#uuid}/editing_sessions`, {
|
|
276
|
+
method: 'POST',
|
|
277
|
+
});
|
|
278
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
279
|
+
throw new Error('Error creating editing session. Permission denied');
|
|
280
|
+
}
|
|
281
|
+
if (resp.status === 422) {
|
|
282
|
+
const errorResp = await resp.json();
|
|
283
|
+
throw new ApiError('Error creating editing session. Invalid request', errorResp.errors, `/sites/${this.#uuid}/editing_sessions`, { method: 'POST' }, resp.status);
|
|
284
|
+
}
|
|
285
|
+
const editingSession = await resp.json();
|
|
286
|
+
return editingSession;
|
|
287
|
+
}
|
|
288
|
+
async getLatestEditingSession() {
|
|
289
|
+
const resp = await this.#client.fetch(`/sites/${this.#uuid}/editing_sessions/latest`);
|
|
290
|
+
if (resp.status === 403) {
|
|
291
|
+
throw new Error('Error fetching latest editing session. Permission denied');
|
|
292
|
+
}
|
|
293
|
+
const editingSession = await resp.json();
|
|
294
|
+
return editingSession;
|
|
295
|
+
}
|
|
296
|
+
async uploadFile(path, content, options = {}) {
|
|
297
|
+
if (!path.startsWith('/')) {
|
|
298
|
+
path = `/${path}`;
|
|
299
|
+
}
|
|
300
|
+
const files = await this.listFiles();
|
|
301
|
+
const existingFile = files.find((file) => file.sitePath === path);
|
|
302
|
+
if (existingFile && !options.overwriteExistingFile) {
|
|
303
|
+
throw new Error('File already exists and overwriteExistingFile is not set');
|
|
304
|
+
}
|
|
305
|
+
const uploadData = await this.#client.getUploadData();
|
|
306
|
+
const editingSession = await this.createEditingSession();
|
|
307
|
+
const file = await this.#client.editingSession(editingSession.uuid).createFile({
|
|
308
|
+
path,
|
|
309
|
+
source_path: existingFile ? path : undefined,
|
|
310
|
+
edit_type: 'update',
|
|
311
|
+
});
|
|
312
|
+
const contributions = await this.#client.editingSessionFile(file.uuid).getContributions();
|
|
313
|
+
contributions.sort((a, b) => a.updated_at.localeCompare(b.updated_at));
|
|
314
|
+
const latestContribution = contributions.at(-1);
|
|
315
|
+
if (latestContribution && !options.overwriteExistingFile) {
|
|
316
|
+
throw new Error('File already exists and overwriteExistingFile is not set');
|
|
317
|
+
}
|
|
318
|
+
const s3Key = `${uploadData.prefix}/${Date.now()}${path}`;
|
|
319
|
+
const formData = new FormData();
|
|
320
|
+
formData.append('key', s3Key);
|
|
321
|
+
Object.keys(uploadData.fields).forEach((field) => {
|
|
322
|
+
if (field !== 'key') {
|
|
323
|
+
formData.append(field, uploadData.fields[field]);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
formData.append('file', new Blob([content], { type: options.type ?? 'text/plain' }));
|
|
327
|
+
const uploadResp = await fetch(uploadData.url, {
|
|
328
|
+
method: 'POST',
|
|
329
|
+
body: formData,
|
|
330
|
+
});
|
|
331
|
+
const etag = uploadResp.headers.get('ETag');
|
|
332
|
+
if (!etag) {
|
|
333
|
+
throw new Error('ETag not found in upload response');
|
|
334
|
+
}
|
|
335
|
+
const contentHash = etag.slice(1, -1);
|
|
336
|
+
await this.#client.editingSessionFile(file.uuid).createContribution({
|
|
337
|
+
s3_key: s3Key,
|
|
338
|
+
content_hash: contentHash,
|
|
339
|
+
previous_content_hash: latestContribution?.content_hash ?? existingFile?.md5,
|
|
340
|
+
});
|
|
341
|
+
await this.#client.editingSessionFile(file.uuid).unlock({
|
|
342
|
+
previous_content_hash: contentHash,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
254
345
|
}
|
package/dist/src/sync.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class SyncClient {
|
|
2
|
+
#uuid;
|
|
3
|
+
#client;
|
|
4
|
+
constructor(uuid, client) {
|
|
5
|
+
this.#uuid = uuid;
|
|
6
|
+
this.#client = client;
|
|
7
|
+
}
|
|
8
|
+
async get() {
|
|
9
|
+
const resp = await this.#client.fetch(`/syncs/${this.#uuid}`);
|
|
10
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
11
|
+
throw new Error('Error fetching sync. Permission denied');
|
|
12
|
+
}
|
|
13
|
+
return resp;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcannon/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "REST API client for the CloudCannon CMS.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"cloudcannon",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"test:watch": "node --test --watch",
|
|
44
44
|
"test:coverage": "node --test --test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info",
|
|
45
45
|
"lint": "biome check && tsc --noEmit",
|
|
46
|
-
"lint:fix": "biome check --fix"
|
|
46
|
+
"lint:fix": "biome check --fix",
|
|
47
|
+
"generate-schema": "npx openapi-typescript $1 -o ./schema.ts"
|
|
47
48
|
},
|
|
48
49
|
"author": "CloudCannon <support@cloudcannon.com>",
|
|
49
50
|
"license": "ISC",
|