bb-relay 0.0.22 → 0.0.23

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.
@@ -0,0 +1,46 @@
1
+ import { W as Wrapper } from './Project-B7IjpqOJ.mjs';
2
+
3
+ type BaseRelease = {
4
+ storageRef: string;
5
+ changes: string;
6
+ version: string;
7
+ type: "production" | "beta" | "draft";
8
+ slug: string;
9
+ metadata: {
10
+ uploadedAt: number;
11
+ totalFiles: number;
12
+ totalSize: number;
13
+ };
14
+ createdAt: string;
15
+ id: string;
16
+ updatedAt: string;
17
+ userId: string;
18
+ installs: number;
19
+ };
20
+ type Release = Wrapper<BaseRelease>;
21
+
22
+ type Status = Omit<Release["doc"], "type">;
23
+ /**
24
+ * This will be pulled from two firestore
25
+ * The part of name, description etc will be in the main
26
+ * Things like installs will be in the registry
27
+ */
28
+ type BasePlugin = {
29
+ userId: string;
30
+ slug: string;
31
+ name: string;
32
+ description: string | null;
33
+ archived?: boolean;
34
+ deprecated?: boolean;
35
+ beta: Status | null;
36
+ production: Status | null;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ tags: string[];
40
+ username: string;
41
+ id: string;
42
+ avatar?: string;
43
+ };
44
+ type Plugin = Wrapper<BasePlugin>;
45
+
46
+ export type { Plugin as P, Release as R };
@@ -0,0 +1,46 @@
1
+ import { W as Wrapper } from './Project-B_Vppjgw.js';
2
+
3
+ type BaseRelease = {
4
+ storageRef: string;
5
+ changes: string;
6
+ version: string;
7
+ type: "production" | "beta" | "draft";
8
+ slug: string;
9
+ metadata: {
10
+ uploadedAt: number;
11
+ totalFiles: number;
12
+ totalSize: number;
13
+ };
14
+ createdAt: string;
15
+ id: string;
16
+ updatedAt: string;
17
+ userId: string;
18
+ installs: number;
19
+ };
20
+ type Release = Wrapper<BaseRelease>;
21
+
22
+ type Status = Omit<Release["doc"], "type">;
23
+ /**
24
+ * This will be pulled from two firestore
25
+ * The part of name, description etc will be in the main
26
+ * Things like installs will be in the registry
27
+ */
28
+ type BasePlugin = {
29
+ userId: string;
30
+ slug: string;
31
+ name: string;
32
+ description: string | null;
33
+ archived?: boolean;
34
+ deprecated?: boolean;
35
+ beta: Status | null;
36
+ production: Status | null;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ tags: string[];
40
+ username: string;
41
+ id: string;
42
+ avatar?: string;
43
+ };
44
+ type Plugin = Wrapper<BasePlugin>;
45
+
46
+ export type { Plugin as P, Release as R };
@@ -0,0 +1,6 @@
1
+ type Result<T = null> = {
2
+ data: T | null;
3
+ error: string | null;
4
+ };
5
+
6
+ export type { Result as R };
@@ -0,0 +1,6 @@
1
+ type Result<T = null> = {
2
+ data: T | null;
3
+ error: string | null;
4
+ };
5
+
6
+ export type { Result as R };
package/dist/api.d.mts CHANGED
@@ -320,12 +320,26 @@ type GitRequests = {
320
320
 
321
321
  type BBRequest = FileRequests & FolderRequest & StorageRequests & ProjectRequest & AppRequest & GitRequests;
322
322
 
323
+ type EventParam<K extends keyof BBEvent> = {
324
+ id: string;
325
+ type: K;
326
+ source: "event";
327
+ };
328
+
323
329
  interface EventReturn<K extends keyof BBEvent> {
330
+ id: string;
324
331
  type: K;
325
332
  response: BBEvent[K]["response"];
326
333
  responseId: string;
327
334
  }
328
335
 
336
+ type RequestParam<K extends keyof BBRequest> = {
337
+ id: string;
338
+ type: K;
339
+ arg: BBRequest[K]["args"];
340
+ source: "request";
341
+ };
342
+
329
343
  interface RequestReturn<K extends keyof BBRequest> {
330
344
  id: string;
331
345
  type: K;
@@ -334,4 +348,4 @@ interface RequestReturn<K extends keyof BBRequest> {
334
348
  responseId: string;
335
349
  }
336
350
 
337
- export type { BBEvent, BBRequest, EventReturn, RequestReturn };
351
+ export type { BBEvent, BBRequest, EventParam, EventReturn, RequestParam, RequestReturn };
package/dist/api.d.ts CHANGED
@@ -320,12 +320,26 @@ type GitRequests = {
320
320
 
321
321
  type BBRequest = FileRequests & FolderRequest & StorageRequests & ProjectRequest & AppRequest & GitRequests;
322
322
 
323
+ type EventParam<K extends keyof BBEvent> = {
324
+ id: string;
325
+ type: K;
326
+ source: "event";
327
+ };
328
+
323
329
  interface EventReturn<K extends keyof BBEvent> {
330
+ id: string;
324
331
  type: K;
325
332
  response: BBEvent[K]["response"];
326
333
  responseId: string;
327
334
  }
328
335
 
336
+ type RequestParam<K extends keyof BBRequest> = {
337
+ id: string;
338
+ type: K;
339
+ arg: BBRequest[K]["args"];
340
+ source: "request";
341
+ };
342
+
329
343
  interface RequestReturn<K extends keyof BBRequest> {
330
344
  id: string;
331
345
  type: K;
@@ -334,4 +348,4 @@ interface RequestReturn<K extends keyof BBRequest> {
334
348
  responseId: string;
335
349
  }
336
350
 
337
- export type { BBEvent, BBRequest, EventReturn, RequestReturn };
351
+ export type { BBEvent, BBRequest, EventParam, EventReturn, RequestParam, RequestReturn };
@@ -1,5 +1,6 @@
1
1
  import { W as Wrapper } from './Project-B7IjpqOJ.mjs';
2
2
  export { P as Project } from './Project-B7IjpqOJ.mjs';
3
+ export { P as Plugin, R as Release } from './Plugin-BMoQ48uq.mjs';
3
4
  import './PROJECT_CATEGORY-BivLHtB6.mjs';
4
5
  import './Commit-PdsjrKSG.mjs';
5
6
 
@@ -15,49 +16,6 @@ type BaseUser = {
15
16
  };
16
17
  type User = Wrapper<BaseUser>;
17
18
 
18
- type BaseRelease = {
19
- storageRef: string;
20
- changes: string;
21
- version: string;
22
- type: "production" | "beta" | "draft";
23
- slug: string;
24
- metadata: {
25
- uploadedAt: number;
26
- totalFiles: number;
27
- totalSize: number;
28
- };
29
- createdAt: string;
30
- id: string;
31
- updatedAt: string;
32
- userId: string;
33
- installs: number;
34
- };
35
- type Release = Wrapper<BaseRelease>;
36
-
37
- type Status = Omit<Release["doc"], "type">;
38
- /**
39
- * This will be pulled from two firestore
40
- * The part of name, description etc will be in the main
41
- * Things like installs will be in the registry
42
- */
43
- type BasePlugin = {
44
- userId: string;
45
- slug: string;
46
- name: string;
47
- description: string | null;
48
- archived?: boolean;
49
- deprecated?: boolean;
50
- beta: Status | null;
51
- production: Status | null;
52
- createdAt: string;
53
- updatedAt: string;
54
- tags: string[];
55
- username: string;
56
- id: string;
57
- avatar?: string;
58
- };
59
- type Plugin = Wrapper<BasePlugin>;
60
-
61
19
  type BaseRating = {
62
20
  userId: string;
63
21
  RatingId: string;
@@ -71,4 +29,4 @@ type BaseRating = {
71
29
  };
72
30
  type Rating = Wrapper<BaseRating>;
73
31
 
74
- export type { Plugin, Rating, Release, User };
32
+ export type { Rating, User };
@@ -1,5 +1,6 @@
1
1
  import { W as Wrapper } from './Project-B_Vppjgw.js';
2
2
  export { P as Project } from './Project-B_Vppjgw.js';
3
+ export { P as Plugin, R as Release } from './Plugin-BojCB5ZJ.js';
3
4
  import './PROJECT_CATEGORY-BivLHtB6.js';
4
5
  import './Commit-PdsjrKSG.js';
5
6
 
@@ -15,49 +16,6 @@ type BaseUser = {
15
16
  };
16
17
  type User = Wrapper<BaseUser>;
17
18
 
18
- type BaseRelease = {
19
- storageRef: string;
20
- changes: string;
21
- version: string;
22
- type: "production" | "beta" | "draft";
23
- slug: string;
24
- metadata: {
25
- uploadedAt: number;
26
- totalFiles: number;
27
- totalSize: number;
28
- };
29
- createdAt: string;
30
- id: string;
31
- updatedAt: string;
32
- userId: string;
33
- installs: number;
34
- };
35
- type Release = Wrapper<BaseRelease>;
36
-
37
- type Status = Omit<Release["doc"], "type">;
38
- /**
39
- * This will be pulled from two firestore
40
- * The part of name, description etc will be in the main
41
- * Things like installs will be in the registry
42
- */
43
- type BasePlugin = {
44
- userId: string;
45
- slug: string;
46
- name: string;
47
- description: string | null;
48
- archived?: boolean;
49
- deprecated?: boolean;
50
- beta: Status | null;
51
- production: Status | null;
52
- createdAt: string;
53
- updatedAt: string;
54
- tags: string[];
55
- username: string;
56
- id: string;
57
- avatar?: string;
58
- };
59
- type Plugin = Wrapper<BasePlugin>;
60
-
61
19
  type BaseRating = {
62
20
  userId: string;
63
21
  RatingId: string;
@@ -71,4 +29,4 @@ type BaseRating = {
71
29
  };
72
30
  type Rating = Wrapper<BaseRating>;
73
31
 
74
- export type { Plugin, Rating, Release, User };
32
+ export type { Rating, User };
package/dist/editor.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { C as Commit } from './Commit-PdsjrKSG.mjs';
2
2
  export { C as CopyArg, a as FileContent, b as FileStat, F as FolderContent, G as GitFileStatus } from './FileStat-CmS6lR3e.mjs';
3
3
  import { L as Language, a as Locale } from './Locale-WvQQn-Rm.mjs';
4
+ export { R as Result } from './Result-BLbZLEgX.mjs';
4
5
 
5
6
  type IconArg = {
6
7
  pluginId?: string;
package/dist/editor.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { C as Commit } from './Commit-PdsjrKSG.js';
2
2
  export { C as CopyArg, a as FileContent, b as FileStat, F as FolderContent, G as GitFileStatus } from './FileStat-CmS6lR3e.js';
3
3
  import { L as Language, a as Locale } from './Locale-WvQQn-Rm.js';
4
+ export { R as Result } from './Result-BLbZLEgX.js';
4
5
 
5
6
  type IconArg = {
6
7
  pluginId?: string;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,7 @@
1
- import { BBRequest, RequestReturn, BBEvent, EventReturn } from './api.mjs';
2
- import './FileStat-CmS6lR3e.mjs';
1
+ import { BBRequest, RequestReturn, BBEvent, EventReturn, EventParam, RequestParam } from './api.mjs';
2
+ import { a as FileContent } from './FileStat-CmS6lR3e.mjs';
3
+ export { R as Result } from './Result-BLbZLEgX.mjs';
4
+ import { P as Plugin } from './Plugin-BMoQ48uq.mjs';
3
5
  import './Project-B7IjpqOJ.mjs';
4
6
  import './PROJECT_CATEGORY-BivLHtB6.mjs';
5
7
  import './Commit-PdsjrKSG.mjs';
@@ -19,19 +21,13 @@ declare class BBRelay {
19
21
  * It will let the app know which event to listen to and update the iframe
20
22
  * @param event the params that will be sent to the editor
21
23
  */
22
- declare function registerEvent<K extends keyof BBEvent>(event: {
23
- type: K;
24
- }): void;
24
+ declare function registerEvent<K extends keyof BBEvent>(event: EventParam<K>): void;
25
25
 
26
26
  /**
27
27
  * This will be used to send message (request) from the iframe to editor
28
28
  * @param request the params that will be sent to the editor
29
29
  */
30
- declare function registerRequest<K extends keyof BBRequest>(request: {
31
- id: string;
32
- type: K;
33
- arg: BBRequest[K]["args"];
34
- }): void;
30
+ declare function registerRequest<K extends keyof BBRequest>(request: RequestParam<K>): void;
35
31
 
36
32
  /**
37
33
  * This is the function to inject styles to the iframe from the parent window
@@ -41,11 +37,36 @@ declare function registerRequest<K extends keyof BBRequest>(request: {
41
37
  declare function injectStyles(css: string): () => void;
42
38
 
43
39
  type Manifest = {
44
- text: string;
45
40
  id: string;
41
+ name: string;
42
+ description?: string;
43
+ keyword?: string[];
44
+ sidebar?: {
45
+ icon: string;
46
+ title: string;
47
+ path: string;
48
+ };
49
+ main?: {
50
+ path: string;
51
+ type: FileContent["type"];
52
+ extensions: string[];
53
+ };
54
+ permissions: string[];
55
+ iconsPath?: string;
56
+ background?: string;
57
+ manifest_version: 1;
58
+ version: string;
59
+ author?: string;
60
+ homepage?: string;
61
+ repository?: string;
62
+ [key: string]: unknown;
46
63
  };
47
64
 
48
- declare const validateManifest: (manifestContent: string) => Manifest[];
65
+ declare const validateManifest: (manifestContent: string) => {
66
+ errors: string[];
67
+ fileChecks: string[];
68
+ content: Manifest;
69
+ };
49
70
 
50
71
  interface FileNode {
51
72
  name: string;
@@ -62,11 +83,8 @@ interface Zip {
62
83
  totalSize: number;
63
84
  }
64
85
 
65
- type Result<T = null> = {
66
- data: T | null;
67
- error: string | null;
68
- };
69
-
70
86
  declare function extractStyles(): string;
71
87
 
72
- export { type FileNode, type Manifest, type Result, type Zip, BBRelay as default, extractStyles, injectStyles, registerEvent, registerRequest, validateManifest };
88
+ declare function validateUpload(manifest: Manifest, plugin: Plugin["doc"]): boolean;
89
+
90
+ export { type FileNode, type Manifest, type Zip, BBRelay as default, extractStyles, injectStyles, registerEvent, registerRequest, validateManifest, validateUpload };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { BBRequest, RequestReturn, BBEvent, EventReturn } from './api.js';
2
- import './FileStat-CmS6lR3e.js';
1
+ import { BBRequest, RequestReturn, BBEvent, EventReturn, EventParam, RequestParam } from './api.js';
2
+ import { a as FileContent } from './FileStat-CmS6lR3e.js';
3
+ export { R as Result } from './Result-BLbZLEgX.js';
4
+ import { P as Plugin } from './Plugin-BojCB5ZJ.js';
3
5
  import './Project-B_Vppjgw.js';
4
6
  import './PROJECT_CATEGORY-BivLHtB6.js';
5
7
  import './Commit-PdsjrKSG.js';
@@ -19,19 +21,13 @@ declare class BBRelay {
19
21
  * It will let the app know which event to listen to and update the iframe
20
22
  * @param event the params that will be sent to the editor
21
23
  */
22
- declare function registerEvent<K extends keyof BBEvent>(event: {
23
- type: K;
24
- }): void;
24
+ declare function registerEvent<K extends keyof BBEvent>(event: EventParam<K>): void;
25
25
 
26
26
  /**
27
27
  * This will be used to send message (request) from the iframe to editor
28
28
  * @param request the params that will be sent to the editor
29
29
  */
30
- declare function registerRequest<K extends keyof BBRequest>(request: {
31
- id: string;
32
- type: K;
33
- arg: BBRequest[K]["args"];
34
- }): void;
30
+ declare function registerRequest<K extends keyof BBRequest>(request: RequestParam<K>): void;
35
31
 
36
32
  /**
37
33
  * This is the function to inject styles to the iframe from the parent window
@@ -41,11 +37,36 @@ declare function registerRequest<K extends keyof BBRequest>(request: {
41
37
  declare function injectStyles(css: string): () => void;
42
38
 
43
39
  type Manifest = {
44
- text: string;
45
40
  id: string;
41
+ name: string;
42
+ description?: string;
43
+ keyword?: string[];
44
+ sidebar?: {
45
+ icon: string;
46
+ title: string;
47
+ path: string;
48
+ };
49
+ main?: {
50
+ path: string;
51
+ type: FileContent["type"];
52
+ extensions: string[];
53
+ };
54
+ permissions: string[];
55
+ iconsPath?: string;
56
+ background?: string;
57
+ manifest_version: 1;
58
+ version: string;
59
+ author?: string;
60
+ homepage?: string;
61
+ repository?: string;
62
+ [key: string]: unknown;
46
63
  };
47
64
 
48
- declare const validateManifest: (manifestContent: string) => Manifest[];
65
+ declare const validateManifest: (manifestContent: string) => {
66
+ errors: string[];
67
+ fileChecks: string[];
68
+ content: Manifest;
69
+ };
49
70
 
50
71
  interface FileNode {
51
72
  name: string;
@@ -62,11 +83,8 @@ interface Zip {
62
83
  totalSize: number;
63
84
  }
64
85
 
65
- type Result<T = null> = {
66
- data: T | null;
67
- error: string | null;
68
- };
69
-
70
86
  declare function extractStyles(): string;
71
87
 
72
- export { type FileNode, type Manifest, type Result, type Zip, BBRelay as default, extractStyles, injectStyles, registerEvent, registerRequest, validateManifest };
88
+ declare function validateUpload(manifest: Manifest, plugin: Plugin["doc"]): boolean;
89
+
90
+ export { type FileNode, type Manifest, type Zip, BBRelay as default, extractStyles, injectStyles, registerEvent, registerRequest, validateManifest, validateUpload };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  function registerRequest(request) {
3
3
  if (!window) throw new Error("Window not found");
4
4
  if (window === window.parent) throw new Error("No parent window available");
5
- window.parent.postMessage({ ...request, source: "request" }, "*");
5
+ window.parent.postMessage(request, "*");
6
6
  }
7
7
 
8
8
  // src/relay/storage-bridge.ts
@@ -26,7 +26,8 @@ function storageBridge() {
26
26
  registerRequest({
27
27
  type: "storage:sync",
28
28
  id: crypto.randomUUID(),
29
- arg: snapshot(localStorage)
29
+ arg: snapshot(localStorage),
30
+ source: "request"
30
31
  });
31
32
  }
32
33
  proto.setItem = function(key, value) {
@@ -47,7 +48,8 @@ function storageBridge() {
47
48
  registerRequest({
48
49
  type: "storage:load",
49
50
  id: crypto.randomUUID(),
50
- arg: null
51
+ arg: null,
52
+ source: "request"
51
53
  });
52
54
  window.addEventListener("message", (event) => {
53
55
  const data = event.data;
@@ -104,7 +106,7 @@ var BBRelay = class {
104
106
  type,
105
107
  callback
106
108
  });
107
- registerRequest({ type, arg, id });
109
+ registerRequest({ type, arg, id, source: "request" });
108
110
  }
109
111
  subscribe(type, callback) {
110
112
  const id = crypto.randomUUID();
@@ -112,7 +114,7 @@ var BBRelay = class {
112
114
  type,
113
115
  callback
114
116
  });
115
- registerEvent({ type });
117
+ registerEvent({ type, id, source: "event" });
116
118
  return () => {
117
119
  this.eventCallbacks.delete(id);
118
120
  };
@@ -129,34 +131,71 @@ function injectStyles(css) {
129
131
  };
130
132
  }
131
133
 
132
- // src/lib/validate-manifest.ts
134
+ // src/lib/validate-manifest/index.ts
135
+ var supportedVersion = [1];
133
136
  var validateManifest = (manifestContent) => {
134
- const checks = [];
137
+ const errors = [];
138
+ const fileChecks = [];
135
139
  const content = JSON.parse(manifestContent);
136
140
  if (!content.id) {
137
- checks.push({
138
- text: "Manifest id is missing",
139
- id: "manifest-id"
140
- });
141
+ errors.push("Manifest id is missing");
142
+ }
143
+ if (!content.name) {
144
+ errors.push("Manifest name is missing");
141
145
  }
142
146
  if (!content.manifest_version) {
143
- checks.push({
144
- text: "Manifest manifest_version is missing",
145
- id: "manifest-version"
146
- });
147
- } else if (content.manifest_version !== 1) {
148
- checks.push({
149
- text: "Manifest manifest_version should be 1",
150
- id: "manifest-version"
151
- });
147
+ errors.push("Manifest manifest_version is missing");
148
+ } else if (!supportedVersion.includes(Number(content.manifest_version))) {
149
+ errors.push("Manifest manifest_version is not supported");
152
150
  }
153
151
  if (!content.version) {
154
- checks.push({
155
- text: "Plugin version not provided",
156
- id: "plugin-version"
157
- });
152
+ errors.push("Plugin version not provided");
158
153
  }
159
- return checks;
154
+ if (!content.permissions) {
155
+ errors.push("Manifest permissions is missing");
156
+ } else if (!Array.isArray(content.permissions)) {
157
+ errors.push("Manifest permissions is not an array");
158
+ } else if (content.permissions.length === 0) {
159
+ errors.push("Manifest permissions is empty");
160
+ }
161
+ if (content.main) {
162
+ if (!content.main.path) {
163
+ errors.push("Manifest main path is missing");
164
+ } else if (!content.main.type) {
165
+ errors.push("Manifest main type is missing");
166
+ } else if (!content.main.extensions) {
167
+ errors.push("Manifest main extensions is missing");
168
+ } else if (!Array.isArray(content.main.extensions)) {
169
+ errors.push("Manifest main extensions is not an array");
170
+ } else if (content.main.extensions.length === 0) {
171
+ errors.push("Manifest main extensions is empty");
172
+ } else {
173
+ fileChecks.push(content.main.path);
174
+ }
175
+ }
176
+ if (content.sidebar) {
177
+ if (!content.sidebar.icon) {
178
+ errors.push("Manifest sidebar icon is missing");
179
+ } else if (!content.sidebar.title) {
180
+ errors.push("Manifest sidebar title is missing");
181
+ } else if (!content.sidebar.path) {
182
+ errors.push("Manifest sidebar path is missing");
183
+ } else {
184
+ fileChecks.push(content.sidebar.path);
185
+ fileChecks.push(content.sidebar.icon);
186
+ }
187
+ }
188
+ if (content.iconsPath) {
189
+ fileChecks.push(content.iconsPath + "/bb.png");
190
+ }
191
+ if (content.background) {
192
+ fileChecks.push(content.background);
193
+ }
194
+ return {
195
+ errors,
196
+ fileChecks,
197
+ content
198
+ };
160
199
  };
161
200
  var validate_manifest_default = validateManifest;
162
201
 
@@ -178,6 +217,14 @@ function extractStyles() {
178
217
  }
179
218
  var extract_styles_default = extractStyles;
180
219
 
220
+ // src/lib/validate-upload/index.ts
221
+ function validateUpload(manifest, plugin) {
222
+ if (manifest.id !== plugin.id) {
223
+ return false;
224
+ }
225
+ return true;
226
+ }
227
+
181
228
  // src/index.ts
182
229
  var index_default = BBRelay;
183
230
 
@@ -187,4 +234,5 @@ var index_default = BBRelay;
187
234
 
188
235
 
189
236
 
190
- exports.default = index_default; exports.extractStyles = extract_styles_default; exports.injectStyles = injectStyles; exports.registerEvent = registerEvent; exports.registerRequest = registerRequest; exports.validateManifest = validate_manifest_default;
237
+
238
+ exports.default = index_default; exports.extractStyles = extract_styles_default; exports.injectStyles = injectStyles; exports.registerEvent = registerEvent; exports.registerRequest = registerRequest; exports.validateManifest = validate_manifest_default; exports.validateUpload = validateUpload;
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  function registerRequest(request) {
3
3
  if (!window) throw new Error("Window not found");
4
4
  if (window === window.parent) throw new Error("No parent window available");
5
- window.parent.postMessage({ ...request, source: "request" }, "*");
5
+ window.parent.postMessage(request, "*");
6
6
  }
7
7
 
8
8
  // src/relay/storage-bridge.ts
@@ -26,7 +26,8 @@ function storageBridge() {
26
26
  registerRequest({
27
27
  type: "storage:sync",
28
28
  id: crypto.randomUUID(),
29
- arg: snapshot(localStorage)
29
+ arg: snapshot(localStorage),
30
+ source: "request"
30
31
  });
31
32
  }
32
33
  proto.setItem = function(key, value) {
@@ -47,7 +48,8 @@ function storageBridge() {
47
48
  registerRequest({
48
49
  type: "storage:load",
49
50
  id: crypto.randomUUID(),
50
- arg: null
51
+ arg: null,
52
+ source: "request"
51
53
  });
52
54
  window.addEventListener("message", (event) => {
53
55
  const data = event.data;
@@ -104,7 +106,7 @@ var BBRelay = class {
104
106
  type,
105
107
  callback
106
108
  });
107
- registerRequest({ type, arg, id });
109
+ registerRequest({ type, arg, id, source: "request" });
108
110
  }
109
111
  subscribe(type, callback) {
110
112
  const id = crypto.randomUUID();
@@ -112,7 +114,7 @@ var BBRelay = class {
112
114
  type,
113
115
  callback
114
116
  });
115
- registerEvent({ type });
117
+ registerEvent({ type, id, source: "event" });
116
118
  return () => {
117
119
  this.eventCallbacks.delete(id);
118
120
  };
@@ -129,34 +131,71 @@ function injectStyles(css) {
129
131
  };
130
132
  }
131
133
 
132
- // src/lib/validate-manifest.ts
134
+ // src/lib/validate-manifest/index.ts
135
+ var supportedVersion = [1];
133
136
  var validateManifest = (manifestContent) => {
134
- const checks = [];
137
+ const errors = [];
138
+ const fileChecks = [];
135
139
  const content = JSON.parse(manifestContent);
136
140
  if (!content.id) {
137
- checks.push({
138
- text: "Manifest id is missing",
139
- id: "manifest-id"
140
- });
141
+ errors.push("Manifest id is missing");
142
+ }
143
+ if (!content.name) {
144
+ errors.push("Manifest name is missing");
141
145
  }
142
146
  if (!content.manifest_version) {
143
- checks.push({
144
- text: "Manifest manifest_version is missing",
145
- id: "manifest-version"
146
- });
147
- } else if (content.manifest_version !== 1) {
148
- checks.push({
149
- text: "Manifest manifest_version should be 1",
150
- id: "manifest-version"
151
- });
147
+ errors.push("Manifest manifest_version is missing");
148
+ } else if (!supportedVersion.includes(Number(content.manifest_version))) {
149
+ errors.push("Manifest manifest_version is not supported");
152
150
  }
153
151
  if (!content.version) {
154
- checks.push({
155
- text: "Plugin version not provided",
156
- id: "plugin-version"
157
- });
152
+ errors.push("Plugin version not provided");
153
+ }
154
+ if (!content.permissions) {
155
+ errors.push("Manifest permissions is missing");
156
+ } else if (!Array.isArray(content.permissions)) {
157
+ errors.push("Manifest permissions is not an array");
158
+ } else if (content.permissions.length === 0) {
159
+ errors.push("Manifest permissions is empty");
160
+ }
161
+ if (content.main) {
162
+ if (!content.main.path) {
163
+ errors.push("Manifest main path is missing");
164
+ } else if (!content.main.type) {
165
+ errors.push("Manifest main type is missing");
166
+ } else if (!content.main.extensions) {
167
+ errors.push("Manifest main extensions is missing");
168
+ } else if (!Array.isArray(content.main.extensions)) {
169
+ errors.push("Manifest main extensions is not an array");
170
+ } else if (content.main.extensions.length === 0) {
171
+ errors.push("Manifest main extensions is empty");
172
+ } else {
173
+ fileChecks.push(content.main.path);
174
+ }
158
175
  }
159
- return checks;
176
+ if (content.sidebar) {
177
+ if (!content.sidebar.icon) {
178
+ errors.push("Manifest sidebar icon is missing");
179
+ } else if (!content.sidebar.title) {
180
+ errors.push("Manifest sidebar title is missing");
181
+ } else if (!content.sidebar.path) {
182
+ errors.push("Manifest sidebar path is missing");
183
+ } else {
184
+ fileChecks.push(content.sidebar.path);
185
+ fileChecks.push(content.sidebar.icon);
186
+ }
187
+ }
188
+ if (content.iconsPath) {
189
+ fileChecks.push(content.iconsPath + "/bb.png");
190
+ }
191
+ if (content.background) {
192
+ fileChecks.push(content.background);
193
+ }
194
+ return {
195
+ errors,
196
+ fileChecks,
197
+ content
198
+ };
160
199
  };
161
200
  var validate_manifest_default = validateManifest;
162
201
 
@@ -178,6 +217,14 @@ function extractStyles() {
178
217
  }
179
218
  var extract_styles_default = extractStyles;
180
219
 
220
+ // src/lib/validate-upload/index.ts
221
+ function validateUpload(manifest, plugin) {
222
+ if (manifest.id !== plugin.id) {
223
+ return false;
224
+ }
225
+ return true;
226
+ }
227
+
181
228
  // src/index.ts
182
229
  var index_default = BBRelay;
183
230
  export {
@@ -186,5 +233,6 @@ export {
186
233
  injectStyles,
187
234
  registerEvent,
188
235
  registerRequest,
189
- validate_manifest_default as validateManifest
236
+ validate_manifest_default as validateManifest,
237
+ validateUpload
190
238
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bb-relay",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "description": "For managing bb-editor extension",
5
5
  "license": "ISC",
6
6
  "author": "Ade Adeola",
package/src/api.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  import BBEvent from "./types/api/BBEvent";
2
2
  import BBRequest from "./types/api/BBRequest";
3
+ import EventParam from "./types/api/EventParam";
3
4
  import EventReturn from "./types/api/EventReturn";
5
+ import RequestParam from "./types/api/RequestParam";
4
6
  import RequestReturn from "./types/api/RequestReturn";
5
7
 
6
- export type { BBRequest, BBEvent, RequestReturn, EventReturn };
8
+ export type {
9
+ BBRequest,
10
+ BBEvent,
11
+ RequestReturn,
12
+ EventReturn,
13
+ RequestParam,
14
+ EventParam,
15
+ };
package/src/editor.ts CHANGED
@@ -11,6 +11,7 @@ import { Settings } from "./types/editor/Settings";
11
11
  import { TutorialHeader } from "./types/editor/TutorialHeader";
12
12
  import { WatchFSEvent } from "./types/editor/WatchFSEvent";
13
13
  import FileStat from "./types/requests/file/FileStat";
14
+ import Result from "./types/editor/Result";
14
15
 
15
16
  export type {
16
17
  Commit,
@@ -26,4 +27,5 @@ export type {
26
27
  TutorialHeader,
27
28
  WatchFSEvent,
28
29
  FileStat,
30
+ Result,
29
31
  };
package/src/index.ts CHANGED
@@ -7,11 +7,12 @@ import { Manifest } from "./types/editor/Manifest";
7
7
  import { FileNode, Zip } from "./types/editor/Zip";
8
8
  import Result from "./types/editor/Result";
9
9
  import extractStyles from "./utils/extract-styles";
10
+ import validateUpload from "./lib/validate-upload";
10
11
 
11
12
  export default BBRelay;
12
13
 
13
14
  export { registerRequest, injectStyles, registerEvent, extractStyles };
14
- export { validateManifest };
15
+ export { validateManifest, validateUpload };
15
16
 
16
17
  export type { Result, FileNode, Zip };
17
18
 
@@ -0,0 +1,76 @@
1
+ import { Manifest } from "@/types/editor/Manifest";
2
+
3
+ const supportedVersion = [1];
4
+
5
+ const validateManifest = (manifestContent: string) => {
6
+ const errors: string[] = [];
7
+ const fileChecks: string[] = [];
8
+ const content: Manifest = JSON.parse(manifestContent);
9
+
10
+ if (!content.id) {
11
+ errors.push("Manifest id is missing");
12
+ }
13
+ if (!content.name) {
14
+ errors.push("Manifest name is missing");
15
+ }
16
+ if (!content.manifest_version) {
17
+ errors.push("Manifest manifest_version is missing");
18
+ } else if (!supportedVersion.includes(Number(content.manifest_version))) {
19
+ errors.push("Manifest manifest_version is not supported");
20
+ }
21
+ if (!content.version) {
22
+ errors.push("Plugin version not provided");
23
+ }
24
+ if (!content.permissions) {
25
+ errors.push("Manifest permissions is missing");
26
+ } else if (!Array.isArray(content.permissions)) {
27
+ errors.push("Manifest permissions is not an array");
28
+ } else if (content.permissions.length === 0) {
29
+ errors.push("Manifest permissions is empty");
30
+ }
31
+
32
+ if (content.main) {
33
+ if (!content.main.path) {
34
+ errors.push("Manifest main path is missing");
35
+ } else if (!content.main.type) {
36
+ errors.push("Manifest main type is missing");
37
+ } else if (!content.main.extensions) {
38
+ errors.push("Manifest main extensions is missing");
39
+ } else if (!Array.isArray(content.main.extensions)) {
40
+ errors.push("Manifest main extensions is not an array");
41
+ } else if (content.main.extensions.length === 0) {
42
+ errors.push("Manifest main extensions is empty");
43
+ } else {
44
+ fileChecks.push(content.main.path);
45
+ }
46
+ }
47
+
48
+ if (content.sidebar) {
49
+ if (!content.sidebar.icon) {
50
+ errors.push("Manifest sidebar icon is missing");
51
+ } else if (!content.sidebar.title) {
52
+ errors.push("Manifest sidebar title is missing");
53
+ } else if (!content.sidebar.path) {
54
+ errors.push("Manifest sidebar path is missing");
55
+ } else {
56
+ fileChecks.push(content.sidebar.path);
57
+ fileChecks.push(content.sidebar.icon);
58
+ }
59
+ }
60
+
61
+ if (content.iconsPath) {
62
+ fileChecks.push(content.iconsPath + "/bb.png");
63
+ }
64
+
65
+ if (content.background) {
66
+ fileChecks.push(content.background);
67
+ }
68
+
69
+ return {
70
+ errors,
71
+ fileChecks,
72
+ content,
73
+ };
74
+ };
75
+
76
+ export default validateManifest;
@@ -0,0 +1,12 @@
1
+ import { Plugin } from "@/database";
2
+ import { Manifest } from "@/types/editor/Manifest";
3
+
4
+ export default function validateUpload(
5
+ manifest: Manifest,
6
+ plugin: Plugin["doc"]
7
+ ) {
8
+ if (manifest.id !== plugin.id) {
9
+ return false;
10
+ }
11
+ return true;
12
+ }
@@ -34,9 +34,7 @@ export default class BBRelay {
34
34
  constructor() {
35
35
  storageBridge();
36
36
  window.addEventListener("message", (event: MessageEvent) => {
37
- const data = event.data as (RequestReturn<any> | EventReturn<any>) & {
38
- id: string;
39
- };
37
+ const data = event.data as RequestReturn<any> | EventReturn<any>;
40
38
  if (!data?.type) return;
41
39
  if (this.responseIds.includes(data.responseId)) return;
42
40
  this.responseIds.push(data.responseId);
@@ -70,7 +68,7 @@ export default class BBRelay {
70
68
  type,
71
69
  callback: callback as (result: unknown) => void,
72
70
  });
73
- registerRequest({ type, arg, id });
71
+ registerRequest({ type, arg, id, source: "request" });
74
72
  }
75
73
 
76
74
  subscribe<K extends keyof BBEvent>(
@@ -82,7 +80,7 @@ export default class BBRelay {
82
80
  type,
83
81
  callback: callback as (result: unknown) => void,
84
82
  });
85
- registerEvent({ type });
83
+ registerEvent({ type, id, source: "event" });
86
84
 
87
85
  return () => {
88
86
  this.eventCallbacks.delete(id);
@@ -1,3 +1,4 @@
1
+ import EventParam from "@/types/api/EventParam";
1
2
  import BBEvent from "../types/api/BBEvent";
2
3
 
3
4
  /**
@@ -6,9 +7,9 @@ import BBEvent from "../types/api/BBEvent";
6
7
  * It will let the app know which event to listen to and update the iframe
7
8
  * @param event the params that will be sent to the editor
8
9
  */
9
- export default function registerEvent<K extends keyof BBEvent>(event: {
10
- type: K;
11
- }) {
10
+ export default function registerEvent<K extends keyof BBEvent>(
11
+ event: EventParam<K>
12
+ ) {
12
13
  if (!window) throw new Error("Window not found");
13
14
  if (window === window.parent) throw new Error("No parent window available");
14
15
 
@@ -1,16 +1,15 @@
1
+ import RequestParam from "@/types/api/RequestParam";
1
2
  import BBRequest from "../types/api/BBRequest";
2
3
 
3
4
  /**
4
5
  * This will be used to send message (request) from the iframe to editor
5
6
  * @param request the params that will be sent to the editor
6
7
  */
7
- export default function registerRequest<K extends keyof BBRequest>(request: {
8
- id: string;
9
- type: K;
10
- arg: BBRequest[K]["args"];
11
- }) {
8
+ export default function registerRequest<K extends keyof BBRequest>(
9
+ request: RequestParam<K>
10
+ ) {
12
11
  if (!window) throw new Error("Window not found");
13
12
  if (window === window.parent) throw new Error("No parent window available");
14
13
 
15
- window.parent.postMessage({ ...request, source: "request" }, "*");
14
+ window.parent.postMessage(request, "*");
16
15
  }
@@ -26,6 +26,7 @@ export default function storageBridge() {
26
26
  type: "storage:sync",
27
27
  id: crypto.randomUUID(),
28
28
  arg: snapshot(localStorage),
29
+ source: "request",
29
30
  });
30
31
  }
31
32
 
@@ -54,6 +55,7 @@ export default function storageBridge() {
54
55
  type: "storage:load",
55
56
  id: crypto.randomUUID(),
56
57
  arg: null,
58
+ source: "request",
57
59
  });
58
60
  window.addEventListener("message", (event) => {
59
61
  const data = event.data as RequestReturn<"storage:load">;
@@ -3,6 +3,7 @@ import BBEvent from "./BBEvent";
3
3
  type EventParam<K extends keyof BBEvent> = {
4
4
  id: string;
5
5
  type: K;
6
+ source: "event";
6
7
  };
7
8
 
8
9
  export default EventParam;
@@ -1,6 +1,7 @@
1
1
  import BBEvent from "./BBEvent";
2
2
 
3
3
  interface EventReturn<K extends keyof BBEvent> {
4
+ id: string;
4
5
  type: K;
5
6
  response: BBEvent[K]["response"];
6
7
  responseId: string;
@@ -4,6 +4,7 @@ type RequestParam<K extends keyof BBRequest> = {
4
4
  id: string;
5
5
  type: K;
6
6
  arg: BBRequest[K]["args"];
7
+ source: "request";
7
8
  };
8
9
 
9
10
  export default RequestParam;
@@ -1,4 +1,27 @@
1
+ import { FileContent } from "@/editor";
2
+
1
3
  export type Manifest = {
2
- text: string;
3
4
  id: string;
5
+ name: string;
6
+ description?: string;
7
+ keyword?: string[];
8
+ sidebar?: {
9
+ icon: string;
10
+ title: string;
11
+ path: string;
12
+ };
13
+ main?: {
14
+ path: string;
15
+ type: FileContent["type"];
16
+ extensions: string[];
17
+ };
18
+ permissions: string[];
19
+ iconsPath?: string;
20
+ background?: string;
21
+ manifest_version: 1;
22
+ version: string;
23
+ author?: string;
24
+ homepage?: string;
25
+ repository?: string;
26
+ [key: string]: unknown;
4
27
  };
@@ -1,34 +0,0 @@
1
- import { Manifest } from "../types/editor/Manifest";
2
-
3
- const validateManifest = (manifestContent: string) => {
4
- const checks: Manifest[] = [];
5
- const content: Record<string, unknown> = JSON.parse(manifestContent);
6
-
7
- if (!content.id) {
8
- checks.push({
9
- text: "Manifest id is missing",
10
- id: "manifest-id",
11
- });
12
- }
13
- if (!content.manifest_version) {
14
- checks.push({
15
- text: "Manifest manifest_version is missing",
16
- id: "manifest-version",
17
- });
18
- } else if (content.manifest_version !== 1) {
19
- checks.push({
20
- text: "Manifest manifest_version should be 1",
21
- id: "manifest-version",
22
- });
23
- }
24
- if (!content.version) {
25
- checks.push({
26
- text: "Plugin version not provided",
27
- id: "plugin-version",
28
- });
29
- }
30
-
31
- return checks;
32
- };
33
-
34
- export default validateManifest;