@secrecy/lib 1.61.3 → 1.62.0-feat-storage-providers.1

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.
@@ -50,7 +50,7 @@ export class SecrecyCloudClient {
50
50
  }
51
51
  return internalNodeFullToNodeFull(node);
52
52
  }
53
- async uploadData({ storageType, data, encrypted = true, encryptProgress, uploadProgress, signal, meta, }) {
53
+ async uploadData({ storage, data, encrypted = true, encryptProgress, uploadProgress, signal, meta, }) {
54
54
  const dataBuffer = data instanceof File ? new Uint8Array(await data.arrayBuffer()) : data;
55
55
  let filetype;
56
56
  if (meta === true) {
@@ -62,7 +62,8 @@ export class SecrecyCloudClient {
62
62
  else if (!encrypted) {
63
63
  filetype = await fileTypeFromBuffer(dataBuffer);
64
64
  }
65
- if (storageType === 'lite' && dataBuffer.byteLength > kiloToBytes(1024)) {
65
+ if (storage.protocol === 'mongo' &&
66
+ dataBuffer.byteLength > kiloToBytes(1024)) {
66
67
  throw new Error('The data is too big for lite upload!');
67
68
  }
68
69
  const compressed = encrypted ? compress(dataBuffer) : dataBuffer;
@@ -81,11 +82,11 @@ export class SecrecyCloudClient {
81
82
  current: 0,
82
83
  percent: 0,
83
84
  });
84
- if (storageType === 'lite') {
85
+ if (storage.protocol === 'mongo') {
85
86
  const uploadDataArgs = encryptedDataKey && md5Encrypted
86
87
  ? {
87
88
  type: 'encrypted',
88
- content: Buffer.from(encryptedData),
89
+ bytes: Buffer.from(encryptedData),
89
90
  sizeEncrypted: BigInt(encryptedData.byteLength),
90
91
  size: BigInt(dataBuffer.byteLength),
91
92
  key: sodium.to_hex(encryptedDataKey),
@@ -95,13 +96,13 @@ export class SecrecyCloudClient {
95
96
  }
96
97
  : {
97
98
  type: 'unencrypted',
98
- content: Buffer.from(encryptedData),
99
+ bytes: Buffer.from(encryptedData),
99
100
  md5: md5Data,
100
101
  sizeEncrypted: undefined,
101
102
  size: BigInt(dataBuffer.byteLength),
102
103
  ...filetype,
103
104
  };
104
- const uploadData = await this.#apiClient.cloud.uploadLiteData.mutate(uploadDataArgs, { signal });
105
+ const uploadData = await this.#apiClient.cloud.uploadMongoData.mutate(uploadDataArgs, { signal });
105
106
  await uploadProgress?.({
106
107
  total: encryptedData.byteLength,
107
108
  current: encryptedData.byteLength,
@@ -109,7 +110,7 @@ export class SecrecyCloudClient {
109
110
  });
110
111
  const localData = {
111
112
  id: uploadData.id,
112
- storageType: 'lite',
113
+ storage: storage,
113
114
  size: uploadDataArgs.size,
114
115
  sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
115
116
  data: dataBuffer,
@@ -118,7 +119,7 @@ export class SecrecyCloudClient {
118
119
  dataContentCache.set(uploadData.id, localData);
119
120
  return localData;
120
121
  }
121
- if (storageType === 's3' || storageType === 'cold') {
122
+ if (storage.protocol === 's3') {
122
123
  const uploadDataArgs = encryptedDataKey && md5Encrypted
123
124
  ? {
124
125
  type: 'encrypted',
@@ -136,7 +137,7 @@ export class SecrecyCloudClient {
136
137
  sizeEncrypted: undefined,
137
138
  ...filetype,
138
139
  };
139
- const uploadDataCaller = storageType === 's3'
140
+ const uploadDataCaller = storage.protocol === 's3'
140
141
  ? this.#apiClient.cloud.uploadData
141
142
  : this.#apiClient.cloud.uploadColdData;
142
143
  const uploadData = await uploadDataCaller.mutate(uploadDataArgs, {
@@ -153,7 +154,7 @@ export class SecrecyCloudClient {
153
154
  });
154
155
  const localData = {
155
156
  id: uploadData.id,
156
- storageType: storageType,
157
+ storage: storage,
157
158
  size: uploadDataArgs.size,
158
159
  sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
159
160
  data: dataBuffer,
@@ -210,7 +211,7 @@ export class SecrecyCloudClient {
210
211
  }));
211
212
  const localData = {
212
213
  id: uploadData.id,
213
- storageType: storageType,
214
+ storage: storage,
214
215
  size: uploadDataArgs.size,
215
216
  sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
216
217
  data: dataBuffer,
@@ -219,11 +220,11 @@ export class SecrecyCloudClient {
219
220
  dataContentCache.set(uploadData.id, localData);
220
221
  return localData;
221
222
  }
222
- throw new Error(`The "${storageType}" is not implemented yet!`);
223
+ throw new Error(`Not implemented yet!`);
223
224
  }
224
- async uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storageType = 's3', signal, }) {
225
+ async uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storage, signal, }) {
225
226
  const uploadedData = await this.uploadData({
226
- storageType,
227
+ storage,
227
228
  data,
228
229
  encryptProgress,
229
230
  uploadProgress,
@@ -397,13 +398,13 @@ export class SecrecyCloudClient {
397
398
  id: data.id,
398
399
  size: data.size,
399
400
  sizeEncrypted: data.sizeEncrypted,
400
- storageType: data.storageType,
401
+ storage: data.storage,
401
402
  })),
402
403
  ...cachedData.map((data) => ({
403
404
  id: data.id,
404
405
  size: data.size,
405
406
  sizeEncrypted: data.sizeEncrypted,
406
- storageType: data.storageType,
407
+ storage: data.storage,
407
408
  })),
408
409
  ];
409
410
  const allDataContentsBytes = Number(allDataContents.reduce((curr, next) => curr + (next.sizeEncrypted ?? next.size), 0n));
@@ -573,13 +574,18 @@ export class SecrecyCloudClient {
573
574
  : null,
574
575
  });
575
576
  }
576
- async updateDataStorageType(input) {
577
+ async updateDataStorage(input) {
577
578
  const data = dataContentCache.get(input.dataId);
578
579
  if (data) {
579
- if (data.storageType === input.storageType) {
580
- throw new Error(`The data is already on "${data.storageType}`);
580
+ if (data.storage.protocol === input.protocol &&
581
+ data.storage.provider === input.provider &&
582
+ data.storage.mode === input.mode &&
583
+ data.storage.region === input.region) {
584
+ throw new Error(`The data is already on "${data.storage}`);
581
585
  }
582
- if (data.storageType === 'cold' && input.storageType === 'lite') {
586
+ if (data.storage.protocol === 's3' &&
587
+ data.storage.mode === 'glacier' &&
588
+ input.protocol === 'mongo') {
583
589
  throw new Error("It's not possible to transfer a cold stored data to a lite storage!");
584
590
  }
585
591
  }
@@ -641,19 +647,25 @@ export class SecrecyCloudClient {
641
647
  .sort((a, b) => a.order - b.order)
642
648
  .map((p) => p.data));
643
649
  };
644
- const encryptedContent = dataContent.type === 'lite'
645
- ? new Uint8Array(dataContent.content)
646
- : dataContent.type === 'cloud'
650
+ const encryptedContent = dataContent.type === 'mongo'
651
+ ? new Uint8Array(dataContent.bytes)
652
+ : dataContent.type === 's3'
647
653
  ? await encryptedContentFromParts({
648
654
  dataId: dataContent.id,
649
- dataParts: dataContent.parts,
655
+ dataParts: dataContent.parts.map(({ url, ...part }) => ({
656
+ ...part,
657
+ contentUrl: url,
658
+ })),
650
659
  })
651
- : dataContent.maybeContent !== null
652
- ? new Uint8Array(dataContent.maybeContent)
660
+ : dataContent.maybeBytes !== null
661
+ ? new Uint8Array(dataContent.maybeBytes)
653
662
  : dataContent.maybeParts !== null
654
663
  ? await encryptedContentFromParts({
655
664
  dataId: dataContent.id,
656
- dataParts: dataContent.maybeParts,
665
+ dataParts: dataContent.maybeParts.map(({ url, ...part }) => ({
666
+ ...part,
667
+ contentUrl: url,
668
+ })),
657
669
  })
658
670
  : null;
659
671
  if (encryptedContent === null) {
@@ -666,7 +678,7 @@ export class SecrecyCloudClient {
666
678
  const key = dataContent.key
667
679
  ? decryptCryptoBox(sodium.from_hex(dataContent.key), dataContent.type === 'received_mail'
668
680
  ? dataContent.senderPublicKey
669
- : dataContent.type === 'cloud'
681
+ : dataContent.type === 's3'
670
682
  ? dataContent.publicKey
671
683
  : this.#keys.publicKey, this.#keys.privateKey)
672
684
  : null;
@@ -678,11 +690,20 @@ export class SecrecyCloudClient {
678
690
  throw new Error(`Content does not match`);
679
691
  }
680
692
  const decompressed = decompress(src);
693
+ const storageOptions = dataContent.storage.protocol === 'mongo'
694
+ ? dataContent.storage.mongoStorageOptions
695
+ : dataContent.storage.s3StorageOptions;
696
+ const storage = {
697
+ protocol: dataContent.storage.protocol,
698
+ provider: dataContent.storage.provider,
699
+ mode: storageOptions.mode,
700
+ region: storageOptions.region,
701
+ };
681
702
  dataContentCache.set(dataContent.id, {
682
703
  id: dataContent.id,
683
704
  size: dataContent.size,
684
705
  sizeEncrypted: dataContent.sizeEncrypted,
685
- storageType: dataContent.storageType,
706
+ storage: storage,
686
707
  data: decompressed,
687
708
  mime: dataContent.mime ?? undefined,
688
709
  ext: dataContent.ext ?? undefined,
@@ -691,7 +712,7 @@ export class SecrecyCloudClient {
691
712
  id: dataContent.id,
692
713
  size: dataContent.size,
693
714
  sizeEncrypted: dataContent.sizeEncrypted,
694
- storageType: dataContent.storageType,
715
+ storage: storage,
695
716
  data: decompressed,
696
717
  mime: dataContent.mime ?? undefined,
697
718
  ext: dataContent.ext ?? undefined,
@@ -1,5 +1,5 @@
1
1
  import type { ProgressCallback, SecrecyClient } from '../index.js';
2
- import type { DataMetadata, DataStorageType, KeyPair, LocalData, Node, NodeFull, NodeType, Rights } from './types/index.js';
2
+ import type { DataMetadata, DataStorageInput, KeyPair, LocalData, Node, NodeFull, NodeType, Rights } from './types/index.js';
3
3
  import { type RouterInputs, type ApiClient, type RouterOutputs } from '../client.js';
4
4
  import { type DownloadProgress } from '../types.js';
5
5
  import { FileTypeResult } from 'file-type';
@@ -10,8 +10,8 @@ export declare class SecrecyCloudClient {
10
10
  dataId: string;
11
11
  nodeId: string;
12
12
  }): Promise<NodeFull>;
13
- uploadData({ storageType, data, encrypted, encryptProgress, uploadProgress, signal, meta, }: {
14
- storageType: DataStorageType;
13
+ uploadData({ storage, data, encrypted, encryptProgress, uploadProgress, signal, meta, }: {
14
+ storage: DataStorageInput;
15
15
  data: globalThis.File | Uint8Array;
16
16
  encrypted?: boolean;
17
17
  encryptProgress?: ProgressCallback;
@@ -19,14 +19,14 @@ export declare class SecrecyCloudClient {
19
19
  signal?: AbortSignal;
20
20
  meta?: FileTypeResult | true;
21
21
  }): Promise<LocalData>;
22
- uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storageType, signal, }: {
22
+ uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storage, signal, }: {
23
23
  data: globalThis.File | Uint8Array;
24
24
  name: string;
25
25
  nodeId?: string;
26
26
  encryptProgress?: ProgressCallback;
27
27
  uploadProgress?: ProgressCallback;
28
28
  signal?: AbortSignal;
29
- storageType?: DataStorageType;
29
+ storage: DataStorageInput;
30
30
  }): Promise<NodeFull>;
31
31
  deletedNodes(): Promise<Node[]>;
32
32
  sharedNodes(): Promise<Node[]>;
@@ -102,10 +102,14 @@ export declare class SecrecyCloudClient {
102
102
  }): Promise<NodeFull>;
103
103
  private readonly perNode;
104
104
  reportData({ id, reasons, }: Omit<RouterInputs['cloud']['reportData'], 'encryptedDataKey'>): Promise<RouterOutputs['cloud']['reportData']>;
105
- updateDataStorageType(input: RouterInputs['cloud']['moveToStorageType']): Promise<{
105
+ updateDataStorage(input: RouterInputs['cloud']['moveToStorageType']): Promise<{
106
106
  isMoved: boolean;
107
- fromType: "s3" | "cold" | "lite";
108
- toType: "s3" | "cold" | "lite";
107
+ fromProtocol?: "s3" | "mongo" | undefined;
108
+ fromMode?: "standard" | "glacier" | undefined;
109
+ fromRegion?: string | undefined;
110
+ toProtocol?: "s3" | "mongo" | undefined;
111
+ toMode?: "standard" | "glacier" | undefined;
112
+ toRegion?: string | undefined;
109
113
  }>;
110
114
  getPublicDataLink(input: RouterInputs['cloud']['dataLink']): Promise<{
111
115
  name: string;
@@ -1,10 +1,23 @@
1
1
  import { type RouterOutputs } from '../../client.js';
2
2
  export type ApiData = NonNullable<RouterOutputs['cloud']['dataById']>;
3
- export type ApiExtendedData = NonNullable<RouterOutputs['cloud']['dataContentByIds'][number]>;
4
- export type DataStorageType = ApiData['storageType'];
3
+ export type ApiExtendedData = NonNullable<RouterOutputs['cloud']['dataContentById']>;
4
+ export type DataStorageInput = {
5
+ protocol: 's3';
6
+ provider: 'scaleway' | 'ovh';
7
+ mode: 'standard' | 'glacier';
8
+ region: string;
9
+ } | {
10
+ protocol: 'mongo';
11
+ provider: 'secrecy';
12
+ mode: 'standard';
13
+ region: string;
14
+ };
15
+ export type DataStorage = ApiData['storage'];
16
+ export type DataStorageProtocol = ApiData['storage']['protocol'];
17
+ export type DataStorageProvider = ApiData['storage']['provider'];
5
18
  export type LocalData = {
6
19
  id: string;
7
- storageType: DataStorageType;
20
+ storage: DataStorageInput;
8
21
  size: bigint;
9
22
  sizeEncrypted: bigint | null;
10
23
  data: Uint8Array;