@content-island/vscode-api-client 0.1.5 → 0.2.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/dist/index.d.ts CHANGED
@@ -11,7 +11,27 @@ declare interface ApiClient {
11
11
  getRawContentList: <M extends Model = Model & Record<string, any>>(queryParam?: ContentListQueryParams<M>) => Promise<Content[]>;
12
12
  getRawContent: <M extends Model = Model & Record<string, any>>(queryParam: ContentQueryParams<M>) => Promise<Content>;
13
13
  getContentListSize: <M extends Model = Model & Record<string, any>>(queryParam?: ContentListSizeQueryParams<M>) => Promise<number>;
14
- updateContentFieldValue: (contentId: string, fieldId: string, value: any) => Promise<boolean>;
14
+ /**
15
+ * Updates (or upserts, when selected by `fieldName`+`language`) a field value on an existing content.
16
+ *
17
+ * The selector chooses how to identify the target:
18
+ * - `{ fieldName, language }` — by field name and language. Upserts when the pair does not exist, which
19
+ * makes it ideal to add translations or fill values for new languages on an existing content.
20
+ *
21
+ * @example By reference (preferred for new integrations)
22
+ * await client.updateContentFieldValue(contentId, { fieldName: 'title', language: 'en' }, 'Hello');
23
+ */
24
+ updateContentFieldValue(contentId: string, selector: FieldSelector, value: unknown): Promise<boolean>;
25
+ /** @deprecated Pass a `FieldSelector` instead: `updateContentFieldValue(contentId, { fieldName: "name", language: "en" }, value)`. */
26
+ updateContentFieldValue(contentId: string, fieldId: string, value: unknown): Promise<boolean>;
27
+ uploadMedia: (params: UploadMediaParams) => Promise<Media>;
28
+ createContent: (params: CreateContentParams) => Promise<CreateContentResponse>;
29
+ /**
30
+ * Publishes an existing content: snapshots its current draft fieldValues into publishedValues and
31
+ * sets its status to "published". Idempotent — re-publishing an already-published content refreshes
32
+ * the live snapshot from the current draft.
33
+ */
34
+ publishContent: (contentId: string) => Promise<boolean>;
15
35
  }
16
36
 
17
37
  declare interface BaseModel {
@@ -23,6 +43,7 @@ declare interface BaseModel {
23
43
  export declare type ClientFilter<Type = string | boolean | number> = Type | {
24
44
  in?: Type[];
25
45
  ne?: Type;
46
+ nin?: Type[];
26
47
  };
27
48
 
28
49
  export declare interface Content {
@@ -30,6 +51,7 @@ export declare interface Content {
30
51
  name: string;
31
52
  contentType: Lookup;
32
53
  lastUpdate: string;
54
+ status?: Status;
33
55
  fields: Field[];
34
56
  }
35
57
 
@@ -44,10 +66,27 @@ declare interface ContentTypeField extends Lookup {
44
66
  tsType: string;
45
67
  isArray: boolean;
46
68
  isRequired?: boolean;
69
+ validations?: Validation[];
47
70
  }
48
71
 
49
72
  export declare const createClient: (options?: VSCodeClientOptions) => VSCodeApiClient;
50
73
 
74
+ declare interface CreateContentParams {
75
+ contentType: string;
76
+ name: string;
77
+ content?: Array<{
78
+ language?: LanguageCode;
79
+ fields: Array<{
80
+ name: string;
81
+ value: any;
82
+ }>;
83
+ }>;
84
+ }
85
+
86
+ declare interface CreateContentResponse {
87
+ id: string;
88
+ }
89
+
51
90
  declare interface Entity extends BaseModel {
52
91
  type: 'entity';
53
92
  fieldList?: Field_2[];
@@ -75,7 +114,7 @@ export declare interface Field {
75
114
  value: any;
76
115
  type: FieldType;
77
116
  isArray: boolean;
78
- language: string;
117
+ language: LanguageCode;
79
118
  }
80
119
 
81
120
  declare interface Field_2 {
@@ -87,6 +126,11 @@ declare interface Field_2 {
87
126
  validations?: Validation[];
88
127
  }
89
128
 
129
+ declare type FieldSelector = {
130
+ fieldName: string;
131
+ language: string;
132
+ };
133
+
90
134
  export declare type FieldType =
91
135
  | 'short-text'
92
136
  | 'long-text'
@@ -103,6 +147,7 @@ declare type FilterableFields<M extends Model = Model> = {
103
147
  lastUpdate?: ClientFilter<string>;
104
148
  language?: M['language'];
105
149
  contentType?: ClientFilter<string>;
150
+ status?: ClientFilter<Status>;
106
151
  includeRelatedContent?: boolean;
107
152
  } & AllowedFields<M, 'filter'>;
108
153
 
@@ -348,6 +393,13 @@ declare type SortableFields<M extends Model> = {
348
393
 
349
394
  declare type SortOrder = 'asc' | 'desc';
350
395
 
396
+ declare type Status = 'draft' | 'published' | 'changed';
397
+
398
+ declare interface UploadMediaParams {
399
+ file: Blob | File;
400
+ fileName?: string;
401
+ }
402
+
351
403
  declare type Validation = { name: string; customArgs?: any };
352
404
 
353
405
  export declare interface VSCodeApiClient extends ApiClient {
package/dist/index.js CHANGED
@@ -1,76 +1,76 @@
1
1
  import { createClient as I } from "@content-island/api-client";
2
- import { mapContentToModel as Y } from "@content-island/api-client";
3
- import * as r from "vscode";
2
+ import { mapContentToModel as z } from "@content-island/api-client";
3
+ import * as c from "vscode";
4
4
  import _ from "node:crypto";
5
5
  import A from "node:util";
6
- let E;
6
+ let C;
7
7
  const P = () => {
8
- if (!E)
8
+ if (!C)
9
9
  throw new Error("Extension context has not been set.");
10
- return E;
10
+ return C;
11
11
  }, S = (t) => {
12
- E = t;
12
+ C = t;
13
13
  };
14
14
  let l = {
15
15
  getContext: P,
16
16
  setContext: S
17
17
  };
18
- const g = {
18
+ const d = {
19
19
  IS_PRODUCTION: !0,
20
20
  DEFAULT_API_CLIENT_DOMAIN: "api.contentisland.net",
21
21
  DEFAULT_API_CLIENT_VERSION: "1.0",
22
22
  DEFAULT_LOGIN_DOMAIN: "app.contentisland.net"
23
- }, d = "content-island-vscode", u = {
24
- SALT: `${d}.salt`,
25
- ACCESS_TOKEN_BY_PROJECT_ID: (t) => `${d}.access-token.${t}`,
26
- METADATA_BY_PROJECT_ID: (t) => `${d}.metadata.${t}`
23
+ }, w = "content-island-vscode", u = {
24
+ SALT: `${w}.salt`,
25
+ ACCESS_TOKEN_BY_PROJECT_ID: (t) => `${w}.access-token.${t}`,
26
+ METADATA_BY_PROJECT_ID: (t) => `${w}.metadata.${t}`
27
27
  }, h = {
28
28
  get: async (t) => await l.getContext().secrets.get(u.METADATA_BY_PROJECT_ID(t)),
29
29
  set: async (t, o) => {
30
30
  await l.getContext().secrets.store(u.METADATA_BY_PROJECT_ID(t), o);
31
31
  }
32
- }, C = {
32
+ }, E = {
33
33
  get: async (t) => await l.getContext().secrets.get(u.ACCESS_TOKEN_BY_PROJECT_ID(t)),
34
34
  set: async (t, o) => {
35
35
  await l.getContext().secrets.store(u.ACCESS_TOKEN_BY_PROJECT_ID(t), o);
36
36
  }
37
37
  }, L = (t) => {
38
- const s = (t.secureProtocol === void 0 ? g.IS_PRODUCTION : t.secureProtocol) ? "https" : "http", e = t.domain ? t.domain : g.DEFAULT_API_CLIENT_DOMAIN, n = t.apiVersion ? t.apiVersion : g.DEFAULT_API_CLIENT_VERSION;
38
+ const s = (t.secureProtocol === void 0 ? d.IS_PRODUCTION : t.secureProtocol) ? "https" : "http", e = t.domain ? t.domain : d.DEFAULT_API_CLIENT_DOMAIN, n = t.apiVersion ? t.apiVersion : d.DEFAULT_API_CLIENT_VERSION;
39
39
  return `${s}://${e}/api/${n}`;
40
40
  }, f = (t) => {
41
- const s = (t.secureProtocol === void 0 ? g.IS_PRODUCTION : t.secureProtocol) ? "https" : "http", e = t.loginDomain ? t.loginDomain : g.DEFAULT_LOGIN_DOMAIN;
41
+ const s = (t.secureProtocol === void 0 ? d.IS_PRODUCTION : t.secureProtocol) ? "https" : "http", e = t.loginDomain ? t.loginDomain : d.DEFAULT_LOGIN_DOMAIN;
42
42
  return `${s}://${e}/#/?redirect=vscode`;
43
- }, y = 16, p = (t = y) => _.randomBytes(t).toString("hex"), O = 64, m = "sha512", x = 1e5, D = async (t, o, s = O) => (await A.promisify(_.pbkdf2)(t, o, x, s, m)).toString("hex"), N = async () => {
43
+ }, p = 16, y = (t = p) => _.randomBytes(t).toString("hex"), O = 64, m = "sha512", x = 1e5, D = async (t, o, s = O) => (await A.promisify(_.pbkdf2)(t, o, x, s, m)).toString("hex"), N = async () => {
44
44
  const t = l.getContext();
45
45
  let o = await t.secrets.get(u.SALT);
46
- return o || (o = p(32), await t.secrets.store(u.SALT, o)), o;
47
- }, k = 32, R = async (t) => {
46
+ return o || (o = y(32), await t.secrets.store(u.SALT, o)), o;
47
+ }, M = 32, k = async (t) => {
48
48
  const o = await N();
49
- return await D(t, o, k);
50
- }, w = async (t) => {
49
+ return await D(t, o, M);
50
+ }, g = async (t) => {
51
51
  const o = "Open Login Page";
52
- if (await r.window.showInformationMessage(
52
+ if (await c.window.showInformationMessage(
53
53
  "You need to log in to Content Island to continue. Do you want to open the login page?",
54
54
  o
55
55
  ) !== o)
56
56
  return;
57
- const e = r.Uri.parse(f(t));
58
- await r.env.openExternal(e);
59
- }, M = (t) => {
57
+ const e = c.Uri.parse(f(t));
58
+ await c.env.openExternal(e);
59
+ }, R = (t) => {
60
60
  try {
61
61
  return JSON.parse(t.message);
62
62
  } catch {
63
63
  return null;
64
64
  }
65
- }, i = (t, o) => async (...s) => {
65
+ }, r = (t, o) => async (...s) => {
66
66
  try {
67
67
  return await t(...s);
68
68
  } catch (e) {
69
- const n = M(e);
69
+ const n = R(e);
70
70
  if (n) {
71
71
  if (n.status === 401)
72
- throw await w(o), new Error("Unauthorized: Please log in to continue.");
73
- n.status === 403 && r.window.showErrorMessage("Access forbidden: You do not have permission to perform this action.");
72
+ throw await g(o), new Error("Unauthorized: Please log in to continue.");
73
+ n.status === 403 && c.window.showErrorMessage("Access forbidden: You do not have permission to perform this action.");
74
74
  }
75
75
  throw e;
76
76
  }
@@ -90,24 +90,24 @@ const g = {
90
90
  body: JSON.stringify(a)
91
91
  });
92
92
  } catch {
93
- r.window.showErrorMessage(
93
+ c.window.showErrorMessage(
94
94
  "Unable to connect to the authorization server. Check your network connection and try again."
95
95
  );
96
96
  return;
97
97
  }
98
98
  if (!n.ok) {
99
- n.status === 401 ? await w(t) : n.status === 403 && r.window.showErrorMessage(
99
+ n.status === 401 ? await g(t) : n.status === 403 && c.window.showErrorMessage(
100
100
  "You do not have permission to access this resource. Please check your access rights in Content Island."
101
- ), r.window.showErrorMessage(
101
+ ), c.window.showErrorMessage(
102
102
  "Failed to obtain access token. Please complete the authorization in Content Island."
103
103
  );
104
104
  return;
105
105
  }
106
106
  try {
107
- const c = await n.json();
108
- return (!c?.accessToken || typeof c.accessToken != "string") && (r.window.showErrorMessage("Invalid response from the authorization server."), await w(t)), c.accessToken;
107
+ const i = await n.json();
108
+ return (!i?.accessToken || typeof i.accessToken != "string") && (c.window.showErrorMessage("Invalid response from the authorization server."), await g(t)), i.accessToken;
109
109
  } catch {
110
- r.window.showErrorMessage("Error processing response from the authorization server.");
110
+ c.window.showErrorMessage("Error processing response from the authorization server.");
111
111
  }
112
112
  }, T = (t) => {
113
113
  const o = `PREVIEW_${t.accessToken}`, s = I({ ...t, accessToken: o });
@@ -117,7 +117,7 @@ const g = {
117
117
  const e = await s.getProject();
118
118
  return {
119
119
  ...e,
120
- id: await R(e.id)
120
+ id: await k(e.id)
121
121
  };
122
122
  }
123
123
  };
@@ -131,14 +131,14 @@ const g = {
131
131
  const a = await U(t, e, n);
132
132
  if (a) {
133
133
  s(a, n);
134
- const c = await o.getProject();
135
- await C.set(c.id, a), await h.set(c.id, n);
134
+ const i = await o.getProject();
135
+ await E.set(i.id, a), await h.set(i.id, n);
136
136
  }
137
137
  },
138
138
  authorizeByProjectId: async (e) => {
139
- const n = await C.get(e), a = await h.get(e);
139
+ const n = await E.get(e), a = await h.get(e);
140
140
  if (!n || !a) {
141
- await w(t);
141
+ await g(t);
142
142
  return;
143
143
  }
144
144
  s(n, a);
@@ -146,16 +146,22 @@ const g = {
146
146
  setVSCodeExtensionContext: (e) => {
147
147
  l.setContext(e);
148
148
  },
149
- getProject: (...e) => i(() => o.getProject(...e), t)(),
150
- getContentList: (...e) => i(() => o.getContentList(...e), t)(),
151
- getContent: (...e) => i(() => o.getContent(...e), t)(),
152
- getRawContentList: (...e) => i(() => o.getRawContentList(...e), t)(),
153
- getRawContent: (...e) => i(() => o.getRawContent(...e), t)(),
154
- getContentListSize: (...e) => i(() => o.getContentListSize(...e), t)(),
155
- updateContentFieldValue: (...e) => i(() => o.updateContentFieldValue(...e), t)()
149
+ getProject: (...e) => r(() => o.getProject(...e), t)(),
150
+ getContentList: (...e) => r(() => o.getContentList(...e), t)(),
151
+ getContent: (...e) => r(() => o.getContent(...e), t)(),
152
+ getRawContentList: (...e) => r(() => o.getRawContentList(...e), t)(),
153
+ getRawContent: (...e) => r(() => o.getRawContent(...e), t)(),
154
+ getContentListSize: (...e) => r(() => o.getContentListSize(...e), t)(),
155
+ updateContentFieldValue: (e, n, a) => r(
156
+ () => o.updateContentFieldValue(e, n, a),
157
+ t
158
+ )(),
159
+ uploadMedia: (...e) => r(() => o.uploadMedia(...e), t)(),
160
+ createContent: (...e) => r(() => o.createContent(...e), t)(),
161
+ publishContent: (...e) => r(() => o.publishContent(...e), t)()
156
162
  };
157
163
  };
158
164
  export {
159
165
  B as createClient,
160
- Y as mapContentToModel
166
+ z as mapContentToModel
161
167
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@content-island/vscode-api-client",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Content Island - VSCode Extension API Client",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -24,15 +24,15 @@
24
24
  "#*": "./src/*"
25
25
  },
26
26
  "scripts": {
27
- "prebuild:dev": "sh ./create-dev-env.sh",
28
- "build:dev": "vite build --mode development",
27
+ "create-env": "sh ./create-dev-env.sh",
28
+ "build:dev": "npm run create-env && vite build --mode development",
29
29
  "build": "vite build",
30
30
  "type-check": "tsc --noEmit --preserveWatchOutput",
31
31
  "test": "vitest run -c ./config/test/config.ts",
32
32
  "test:watch": "vitest -c ./config/test/config.ts"
33
33
  },
34
34
  "dependencies": {
35
- "@content-island/api-client": "0.17.0"
35
+ "@content-island/api-client": "0.19.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@content-island/common-backend": "*",