@did-space/core 0.3.5 → 0.3.6

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.
@@ -19,5 +19,11 @@ export interface Object {
19
19
  * @memberof Object
20
20
  */
21
21
  mimeType: string;
22
+ /**
23
+ * @description 对象的 hash 值(ipfs CID v1)
24
+ * @type {string}
25
+ * @memberof Object
26
+ */
27
+ hash?: string;
22
28
  [key: string]: any;
23
29
  }
@@ -10,7 +10,7 @@ export interface WriteOptions extends AppSpaceOptions {
10
10
  key: string;
11
11
  data: Data;
12
12
  hash?: string;
13
- size?: string;
13
+ size?: number;
14
14
  }
15
15
  export interface DeleteOptions extends AppSpaceOptions {
16
16
  key: string;
@@ -19,6 +19,7 @@ export declare class ObjectSpace implements SpaceProtocol {
19
19
  readonly treeRepository: TreeRepository;
20
20
  readonly objectCollectionRepository: ObjectCollectionRepository;
21
21
  readonly globalSpace: GlobalSpace;
22
+ static readonly READONLY_OBJECT_KEYS: string[];
22
23
  constructor(options: ObjectSpaceOptions);
23
24
  createSpace(spaceConfig: SpaceConfig): Promise<void>;
24
25
  isSpaceCreated(): Promise<boolean>;
@@ -39,6 +40,7 @@ export declare class ObjectSpace implements SpaceProtocol {
39
40
  */
40
41
  destroyAppSpace(options: AppSpaceOptions): Promise<void>;
41
42
  getAppSpacePath(options: AppSpaceOptions): Promise<string>;
43
+ private verifySpace;
42
44
  write(options: WriteOptions): Promise<void>;
43
45
  delete(options: DeleteOptions): Promise<void>;
44
46
  read(options: ReadOptions): Promise<Stream>;
@@ -108,4 +110,5 @@ export declare class ObjectSpace implements SpaceProtocol {
108
110
  isListable(options: PermissionOptions): Promise<boolean>;
109
111
  isReadable(options: PermissionOptions): Promise<boolean>;
110
112
  isWritable(options: PermissionOptions): Promise<boolean>;
113
+ static editable(key: string): boolean;
111
114
  }
@@ -18,6 +18,7 @@ const skypesky_sequelize_1 = require("skypesky-sequelize");
18
18
  const js_yaml_1 = __importDefault(require("js-yaml"));
19
19
  const path_1 = require("path");
20
20
  const lodash_1 = require("lodash");
21
+ const xbytes_1 = __importDefault(require("xbytes"));
21
22
  const configuration_1 = require("../configuration");
22
23
  const model_1 = require("../model");
23
24
  const utils_1 = require("../utils");
@@ -102,6 +103,13 @@ class ObjectSpace {
102
103
  destroyAppSpace(options) {
103
104
  return __awaiter(this, void 0, void 0, function* () {
104
105
  debug('destroyAppSpace.before', JSON.stringify({ options }));
106
+ const permissionOptions = {
107
+ fromAppDid: options.appDid,
108
+ toAppDid: options.appDid,
109
+ };
110
+ yield this.setListable(permissionOptions, false);
111
+ yield this.setReadable(permissionOptions, false);
112
+ yield this.setWritable(permissionOptions, false);
105
113
  yield this.deleteAsOwner(yield this.getAppSpacePath(options));
106
114
  debug('destroyAppSpace.after', JSON.stringify({ options }));
107
115
  });
@@ -110,6 +118,25 @@ class ObjectSpace {
110
118
  // @ts-expect-error
111
119
  return (0, path_1.join)(`/${constants_1.APPS}`, `${options.appDid}/`);
112
120
  }
121
+ verifySpace(size = 0) {
122
+ var _a, _b;
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ debug('verifySpace.before', { size });
125
+ const [did, capacity, usedCapacity] = yield Promise.all([
126
+ this.get('did'),
127
+ this.get('size'),
128
+ this.getSpaceSize(),
129
+ ]);
130
+ const whiteList = ((_b = (_a = process.env) === null || _a === void 0 ? void 0 : _a.SPACE_WHITE_LIST) !== null && _b !== void 0 ? _b : '')
131
+ .split(',')
132
+ .map((s) => s.trim())
133
+ .filter(Boolean);
134
+ debug('verifySpace.before', { did, capacity, usedCapacity });
135
+ if (capacity && usedCapacity + size >= capacity && !whiteList.includes(did)) {
136
+ throw new Error(`Insufficient free space, total capacity is ${(0, xbytes_1.default)(capacity)}, used capacity is ${(0, xbytes_1.default)(usedCapacity)}`);
137
+ }
138
+ });
139
+ }
113
140
  write(options) {
114
141
  return __awaiter(this, void 0, void 0, function* () {
115
142
  debug('write.before', JSON.stringify((0, lodash_1.omit)(options, 'data')));
@@ -120,10 +147,13 @@ class ObjectSpace {
120
147
  if (error) {
121
148
  throw error;
122
149
  }
123
- const { data } = options;
150
+ // @note: 只有新增的时候才会触发检测
151
+ if (!(yield this.exists(options))) {
152
+ yield this.verifySpace(options.size);
153
+ }
124
154
  const key = (0, path_1.join)(yield this.getAppSpacePath(options), options.key);
125
155
  // @ts-expect-error
126
- yield this.writeAsOwner(key, data, options);
156
+ yield this.writeAsOwner(key, options.data, options);
127
157
  debug('write.after', JSON.stringify({ key }));
128
158
  });
129
159
  }
@@ -202,11 +232,12 @@ class ObjectSpace {
202
232
  return {
203
233
  key: x.key,
204
234
  name: (0, path_1.basename)(x.key),
205
- isDir: x.type === model_1.TreeModelType.FOLDER,
235
+ isDir: false,
206
236
  size: x.Object.size,
207
237
  lastModified: new Date(x.updatedAt).getTime(),
208
238
  editable: true,
209
239
  mimeType: x.Object.meta.mimeType,
240
+ hash: x.objectId,
210
241
  };
211
242
  })));
212
243
  });
@@ -234,6 +265,7 @@ class ObjectSpace {
234
265
  lastModified: new Date(x.updatedAt).getTime(),
235
266
  editable: true,
236
267
  mimeType: x.Object.meta.mimeType,
268
+ hash: x.objectId,
237
269
  };
238
270
  });
239
271
  });
@@ -294,39 +326,9 @@ class ObjectSpace {
294
326
  };
295
327
  });
296
328
  }
297
- // private async _addToGlobalStorage(key: string, data: Data, options: WriteAsOwnerOptions): Promise<void> {
298
- // // @note: 注意此处必须存储到全局存储区
299
- // // eslint-disable-next-line no-param-reassign
300
- // options = merge(options, { useGlobal: true });
301
- // const where: WhereOptions<ObjectModel> = {
302
- // id: options.hash,
303
- // };
304
- // debug('_addToGlobalStorage.before', JSON.stringify({ key, options, where }));
305
- // const objectRecord: ObjectModel = await this.objectRepository.findOne({
306
- // where,
307
- // raw: true,
308
- // });
309
- // debug('_addToGlobalStorage.$objectRecord', JSON.stringify(objectRecord));
310
- // if (objectRecord) {
311
- // return;
312
- // }
313
- // // 存储新对象到全局存储区
314
- // const newKey = getHashPath(options.hash);
315
- // await this.driver.writeAsOwner(newKey, data, options);
316
- // // 添加 object 记录
317
- // await this.objectRepository.create({
318
- // id: options.hash,
319
- // size: options.size,
320
- // meta: {
321
- // mimeType: <string>mimeTypes.lookup(key) || 'unknown',
322
- // key,
323
- // },
324
- // });
325
- // debug('_addToGlobalStorage.after', JSON.stringify({ objectRecord }));
326
- // }
327
329
  _updateAsOwner(key, data, options) {
328
330
  return __awaiter(this, void 0, void 0, function* () {
329
- debug('_updateAsOwner.before', JSON.stringify({ key, options }));
331
+ debug('_updateAsOwner.before', { key, options: (0, lodash_1.omit)(options, 'data') });
330
332
  if ((0, utils_1.isDirectory)(key)) {
331
333
  return;
332
334
  }
@@ -334,7 +336,7 @@ class ObjectSpace {
334
336
  spaceDid: this.spaceDid,
335
337
  key,
336
338
  };
337
- debug('_updateAsOwner.before', JSON.stringify({ key, options, where }));
339
+ debug('_updateAsOwner.before', JSON.stringify({ key, options: (0, lodash_1.omit)(options, 'data'), where }));
338
340
  const oldTree = yield this.treeRepository.findOne({
339
341
  where,
340
342
  raw: true,
@@ -426,6 +428,8 @@ class ObjectSpace {
426
428
  yield this._updateAsOwner(key, data, options);
427
429
  }
428
430
  else {
431
+ // @note: 只有新增的时候才会触发检测
432
+ yield this.verifySpace(options.size);
429
433
  // 添加新对象
430
434
  yield this._createAsOwner(key, data, options);
431
435
  }
@@ -441,6 +445,9 @@ class ObjectSpace {
441
445
  if (error) {
442
446
  throw error;
443
447
  }
448
+ if (ObjectSpace.READONLY_OBJECT_KEYS.includes(key)) {
449
+ throw new Error(`Object ${key} cannot be deleted`);
450
+ }
444
451
  const isDir = key.endsWith('/');
445
452
  if (isDir) {
446
453
  // 删除文件夹
@@ -649,5 +656,9 @@ class ObjectSpace {
649
656
  return Boolean((permission & configuration_1.Scopes['write:object']) === configuration_1.Scopes['write:object']);
650
657
  });
651
658
  }
659
+ static editable(key) {
660
+ return !ObjectSpace.READONLY_OBJECT_KEYS.includes(key);
661
+ }
652
662
  }
653
663
  exports.ObjectSpace = ObjectSpace;
664
+ ObjectSpace.READONLY_OBJECT_KEYS = ['/config.yml'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@did-space/core",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -56,5 +56,5 @@
56
56
  "ts-jest": "^28.0.6",
57
57
  "typescript": "^4.9.5"
58
58
  },
59
- "gitHead": "a2de4336bf11be1fec7883a0bc1feb179ea1d865"
59
+ "gitHead": "232d56b265826f480351e9c111268a4b3cf3d355"
60
60
  }