@secrecy/lib 1.68.0-feat-anonymous-upload.2 → 1.69.0-feat-anonymous-upload.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.
@@ -1,4 +1,3 @@
1
- import axios from 'axios';
2
1
  import ky from 'ky';
3
2
  import { nodesCache, dataCache, dataContentCache, nodesEncryptionCache, } from '../cache.js';
4
3
  import { secretStreamKeygen } from '../crypto/data.js';
@@ -15,6 +14,7 @@ import { kiloToBytes } from '../utils.js';
15
14
  import { fileTypeFromBuffer } from 'file-type';
16
15
  import { encryptName, generateAndEncryptNameAndKey } from '../crypto/domain.js';
17
16
  import { chunkByTotalItems } from '../utils/object.js';
17
+ import axios from 'axios';
18
18
  export class SecrecyCloudClient {
19
19
  #client;
20
20
  #keys;
@@ -25,10 +25,7 @@ export class SecrecyCloudClient {
25
25
  this.#apiClient = apiClient;
26
26
  }
27
27
  async addDataToHistory({ dataId, nodeId, }) {
28
- const addDataToHistory = await this.#apiClient.cloud.addDataToHistory.mutate({
29
- dataId,
30
- nodeId,
31
- });
28
+ const addDataToHistory = await this.#apiClient.cloud.addDataToHistory.mutate({ dataId, nodeId });
32
29
  const node = await apiNodeFullToInternalFull(addDataToHistory, this.#keys);
33
30
  const data = node.history.find((d) => d.id === dataId);
34
31
  if (data !== undefined) {
@@ -74,10 +71,7 @@ export class SecrecyCloudClient {
74
71
  const dataKey = encrypted ? secretStreamKeygen() : null;
75
72
  const { data: encryptedData, md5: md5Data, md5Encrypted, } = dataKey
76
73
  ? await encrypt(dataKey, compressed, encryptProgress, signal)
77
- : {
78
- data: compressed,
79
- md5: await md5(compressed),
80
- };
74
+ : { data: compressed, md5: await md5(compressed) };
81
75
  const encryptedDataKey = dataKey
82
76
  ? encryptCryptoBox(dataKey, this.#keys.publicKey, this.#keys.privateKey)
83
77
  : null;
@@ -169,11 +163,7 @@ export class SecrecyCloudClient {
169
163
  return localData;
170
164
  }
171
165
  const uploadDataPartEnd = async (md5, order) => {
172
- return this.#apiClient.cloud.uploadDataPartEnd.mutate({
173
- dataId: uploadData.id,
174
- md5,
175
- order,
176
- }, { signal });
166
+ return this.#apiClient.cloud.uploadDataPartEnd.mutate({ dataId: uploadData.id, md5, order }, { signal });
177
167
  };
178
168
  const chunkParts = new Array();
179
169
  for (const [index, chunk] of enumerate(chunks(encryptedData, Number(uploadData.partSize)))) {
@@ -186,7 +176,7 @@ export class SecrecyCloudClient {
186
176
  const progressParts = {};
187
177
  const onProgress = (part, progressEvent) => {
188
178
  progressParts[part] = progressEvent;
189
- const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.loaded, 0);
179
+ const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.transferredBytes, 0);
190
180
  void uploadProgress?.({
191
181
  percent: current / encryptedData.byteLength,
192
182
  total: encryptedData.byteLength,
@@ -203,11 +193,21 @@ export class SecrecyCloudClient {
203
193
  formData.append(key, value);
204
194
  }
205
195
  formData.append('file', new Blob([chunk.data], { type: filetype?.mime }), `${uploadData.id}-${chunk.order}`);
196
+ // await ky.post(part.url, {
197
+ // signal,
198
+ // body: formData,
199
+ // onUploadProgress: (progressEvent) => {
200
+ // onProgress(part.order, progressEvent)
201
+ // },
202
+ // })
206
203
  await axios.post(part.url, formData, {
207
204
  onUploadProgress: (progressEvent) => {
208
- onProgress(part.order, progressEvent);
205
+ onProgress(part.order, {
206
+ percent: progressEvent.progress ?? 0,
207
+ totalBytes: progressEvent.total ?? 0,
208
+ transferredBytes: progressEvent.loaded,
209
+ });
209
210
  },
210
- signal,
211
211
  });
212
212
  return uploadDataPartEnd(chunk.md5, chunk.order);
213
213
  };
@@ -235,11 +235,7 @@ export class SecrecyCloudClient {
235
235
  uploadProgress,
236
236
  signal,
237
237
  });
238
- return await this.saveInCloud({
239
- dataId: uploadedData.id,
240
- name,
241
- nodeId,
242
- });
238
+ return await this.saveInCloud({ dataId: uploadedData.id, name, nodeId });
243
239
  }
244
240
  async deletedNodes() {
245
241
  const deletedNodes = await this.#apiClient.cloud.nodesDeleted.query({});
@@ -250,9 +246,7 @@ export class SecrecyCloudClient {
250
246
  return await Promise.all(nodesShared.map(async (node) => await apiNodeToExternal(node, this.#keys)));
251
247
  }
252
248
  async nodesSharedWithMe(type = 'FOLDER') {
253
- const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({
254
- type,
255
- });
249
+ const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({ type });
256
250
  return await Promise.all(nodesSharedWithMe.map(async (node) => await apiNodeToExternal(node, this.#keys)));
257
251
  }
258
252
  async deleteNodeSharing({ nodeId, userId, }) {
@@ -286,9 +280,7 @@ export class SecrecyCloudClient {
286
280
  return isDuplicated;
287
281
  }
288
282
  async deleteNodeCloudTrash({ ids }) {
289
- const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({
290
- ids,
291
- });
283
+ const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({ ids });
292
284
  return isDeleted;
293
285
  }
294
286
  async createFolder({ name, parentFolderId, }) {
@@ -319,16 +311,11 @@ export class SecrecyCloudClient {
319
311
  return folder;
320
312
  }
321
313
  async node({ id, deleted, } = {}) {
322
- const node = await this.#apiClient.cloud.nodeFullById.query({
323
- id,
324
- deleted,
325
- });
314
+ const node = await this.#apiClient.cloud.nodeFullById.query({ id, deleted });
326
315
  return await apiNodeToExternalNodeFull(node, this.#keys);
327
316
  }
328
317
  async dataMetadata({ id }) {
329
- const data = await this.#apiClient.cloud.dataById.query({
330
- id,
331
- });
318
+ const data = await this.#apiClient.cloud.dataById.query({ id });
332
319
  return apiDataToExternal(data, this.#keys);
333
320
  }
334
321
  async shareNode(input, progress) {
@@ -340,11 +327,7 @@ export class SecrecyCloudClient {
340
327
  const publicKeysMap = await this.#client.app.userPublicKey(neededUserKey);
341
328
  const maxNodesBatchSize = 1000;
342
329
  const totalNodesToShare = Object.values(nodesMap).reduce((size, ids) => size + ids.length, 0);
343
- progress?.({
344
- total: totalNodesToShare,
345
- current: 0,
346
- percent: 0,
347
- });
330
+ progress?.({ total: totalNodesToShare, current: 0, percent: 0 });
348
331
  const chunks = totalNodesToShare > maxNodesBatchSize
349
332
  ? chunkByTotalItems(nodesMap, maxNodesBatchSize)
350
333
  : [nodesMap];
@@ -465,13 +448,7 @@ export class SecrecyCloudClient {
465
448
  for (const [userId, nodes] of Object.entries(nodesToUpdateRights)) {
466
449
  finishInput.push(...nodes.map((node) => ({
467
450
  userId,
468
- nodes: [
469
- {
470
- id: node.nodeId,
471
- data: [],
472
- ...node.permissions,
473
- },
474
- ],
451
+ nodes: [{ id: node.nodeId, data: [], ...node.permissions }],
475
452
  })));
476
453
  }
477
454
  const subState = await this.#apiClient.cloud.shareNodeFinish.mutate(finishInput);
@@ -509,10 +486,7 @@ export class SecrecyCloudClient {
509
486
  const errorDetailsLength = details.invalidRightsAccesses.length +
510
487
  details.missingDataAccesses.length +
511
488
  details.missingNodeAccesses.length;
512
- return {
513
- isFinished: errorDetailsLength === 0,
514
- details: details,
515
- };
489
+ return { isFinished: errorDetailsLength === 0, details: details };
516
490
  }
517
491
  async updateNode({ nodeId, name, isFavorite, deletedAt, }) {
518
492
  let node = nodesCache.get(nodeId);
@@ -595,9 +569,7 @@ export class SecrecyCloudClient {
595
569
  }));
596
570
  }
597
571
  async deleteNodes({ nodeIds, }) {
598
- return this.#apiClient.cloud.deleteNodes.mutate({
599
- ids: nodeIds,
600
- });
572
+ return this.#apiClient.cloud.deleteNodes.mutate({ ids: nodeIds });
601
573
  }
602
574
  async deleteData({ dataId, nodeId, }) {
603
575
  const { isDeleted } = await this.#apiClient.cloud.deleteData.mutate({
@@ -1,16 +1,10 @@
1
- import { httpBatchLink, loggerLink, createTRPCProxyClient, TRPCClientError, } from '@trpc/client';
2
- import superjson from 'superjson';
1
+ import { httpBatchLink, loggerLink, createTRPCClient as innerCreateTRPCClient, TRPCClientError, } from '@trpc/client';
3
2
  import { SECRECY_LIB_VERSION } from './versioning.js';
3
+ import { transformer } from './transformer.js';
4
4
  export function isTRPCClientError(cause) {
5
5
  return cause instanceof TRPCClientError;
6
6
  }
7
- superjson.registerCustom({
8
- isApplicable: (v) => v instanceof Buffer,
9
- serialize: (v) => [...v],
10
- deserialize: (v) => Buffer.from(v),
11
- }, 'buffer');
12
- export const createTRPCClient = (opts) => createTRPCProxyClient({
13
- transformer: superjson,
7
+ export const createTRPCClient = (opts) => innerCreateTRPCClient({
14
8
  links: [
15
9
  loggerLink({
16
10
  enabled: (op) => {
@@ -24,6 +18,7 @@ export const createTRPCClient = (opts) => createTRPCProxyClient({
24
18
  },
25
19
  }),
26
20
  httpBatchLink({
21
+ transformer,
27
22
  url: opts.apiUrl
28
23
  ? `${opts.apiUrl}/trpc`
29
24
  : 'https://api.secrecy.tech/trpc',
@@ -0,0 +1,18 @@
1
+ import { Temporal } from '@js-temporal/polyfill';
2
+ import superjson from 'superjson';
3
+ superjson.registerCustom({
4
+ isApplicable: (v) => v instanceof Temporal.PlainDate,
5
+ serialize: (v) => v.toJSON(),
6
+ deserialize: (v) => Temporal.PlainDate.from(v),
7
+ }, 'Temporal.PlainDate');
8
+ superjson.registerCustom({
9
+ isApplicable: (v) => v instanceof Temporal.PlainDateTime,
10
+ serialize: (v) => v.toJSON(),
11
+ deserialize: (v) => Temporal.PlainDateTime.from(v),
12
+ }, 'Temporal.PlainDateTime');
13
+ superjson.registerCustom({
14
+ isApplicable: (v) => v instanceof Buffer,
15
+ serialize: (v) => [...v],
16
+ deserialize: (v) => Buffer.from(v),
17
+ }, 'buffer');
18
+ export const transformer = superjson;
@@ -4,9 +4,9 @@ export declare const dataCache: Map<string, InternalData>;
4
4
  export declare const nodesCache: Map<string, InternalNode | InternalNodeFull>;
5
5
  export declare const nodesEncryptionCache: Map<string, InternalMinimalNodeForEncryption>;
6
6
  export declare const usersCache: Map<string, {
7
- id: string;
8
- lastname: string;
9
7
  firstname: string;
8
+ lastname: string;
9
+ id: string;
10
10
  avatar: string | null;
11
11
  isSearchable: boolean;
12
12
  }>;
@@ -1,7 +1,7 @@
1
1
  import type { ProgressCallback, SecrecyClient } from '../index.js';
2
2
  import type { DataMetadata, DataStorageType, KeyPair, LocalData, Node, NodeFull, NodeType } from './types/index.js';
3
3
  import { type RouterInputs, type ApiClient, type RouterOutputs } from '../client.js';
4
- import { type DownloadProgress } from '../types.js';
4
+ import { type Progress } from '../types.js';
5
5
  import { FileTypeResult } from 'file-type';
6
6
  export declare class SecrecyCloudClient {
7
7
  #private;
@@ -12,7 +12,7 @@ export declare class SecrecyCloudClient {
12
12
  }): Promise<NodeFull>;
13
13
  uploadData({ storageType, data, encrypted, encryptProgress, uploadProgress, signal, meta, }: {
14
14
  storageType: DataStorageType;
15
- data: globalThis.File | Uint8Array;
15
+ data: globalThis.File | Uint8Array<ArrayBuffer>;
16
16
  encrypted?: boolean;
17
17
  encryptProgress?: ProgressCallback;
18
18
  uploadProgress?: ProgressCallback;
@@ -20,7 +20,7 @@ export declare class SecrecyCloudClient {
20
20
  meta?: FileTypeResult | true;
21
21
  }): Promise<LocalData>;
22
22
  uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storageType, signal, }: {
23
- data: globalThis.File | Uint8Array;
23
+ data: globalThis.File | Uint8Array<ArrayBuffer>;
24
24
  name: string;
25
25
  nodeId?: string;
26
26
  encryptProgress?: ProgressCallback;
@@ -63,13 +63,13 @@ export declare class SecrecyCloudClient {
63
63
  }): Promise<NodeFull>;
64
64
  dataContent({ dataId, onDownloadProgress, progressDecrypt, signal, }: {
65
65
  dataId: string;
66
- onDownloadProgress?: (progress: DownloadProgress) => void;
66
+ onDownloadProgress?: (progress: Progress) => void;
67
67
  progressDecrypt?: ProgressCallback;
68
68
  signal?: AbortSignal;
69
69
  }): Promise<LocalData>;
70
70
  dataContents({ dataIds, onDownloadProgress, progressDecrypt, signal, }: {
71
71
  dataIds: string[];
72
- onDownloadProgress?: (progress: DownloadProgress) => void;
72
+ onDownloadProgress?: (progress: Progress) => void;
73
73
  progressDecrypt?: ProgressCallback;
74
74
  signal?: AbortSignal;
75
75
  }): Promise<LocalData[]>;
@@ -104,28 +104,29 @@ export declare class SecrecyCloudClient {
104
104
  toType: "s3" | "cold" | "lite";
105
105
  }>;
106
106
  getPublicDataLink(input: RouterInputs['cloud']['dataLink']): Promise<{
107
- name: string;
108
107
  id: string;
109
- createdByUserId: string | null;
110
- createdByAppId: string | null;
111
- createdByOrgId: string | null;
108
+ name: string;
112
109
  slug: string;
113
110
  expireAt: Date | null;
114
111
  dataId: string;
112
+ createdByUserId: string | null;
113
+ createdByOrgId: string | null;
114
+ createdByAppId: string | null;
115
115
  }>;
116
116
  getPublicDataLinks(input: RouterInputs['cloud']['dataLinks']): Promise<{
117
- name: string;
118
117
  id: string;
119
- createdByUserId: string | null;
120
- createdByAppId: string | null;
121
- createdByOrgId: string | null;
118
+ name: string;
122
119
  slug: string;
123
120
  expireAt: Date | null;
124
121
  dataId: string;
122
+ createdByUserId: string | null;
123
+ createdByOrgId: string | null;
124
+ createdByAppId: string | null;
125
125
  }[]>;
126
126
  checkAccesses(input: RouterInputs['cloud']['checkAccesses']): Promise<{
127
127
  isMatching: true;
128
128
  } | {
129
+ isMatching: false;
129
130
  details: {
130
131
  missingNodeAccesses: {
131
132
  userId: string;
@@ -133,61 +134,60 @@ export declare class SecrecyCloudClient {
133
134
  }[];
134
135
  missingDataAccesses: {
135
136
  userId: string;
136
- dataId: string;
137
137
  nodeId: string;
138
+ dataId: string;
138
139
  }[];
139
140
  invalidRightsAccesses: {
140
141
  userId: string;
141
- current: {
142
- rights: "delete" | "write" | "read";
143
- } & {
144
- addAccess?: "delete" | "write" | "read" | null | undefined;
145
- sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
146
- delAccess?: "delete" | "write" | "read" | null | undefined;
147
- sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
148
- };
149
142
  nodeId: string;
150
143
  expect: {
151
- rights: "delete" | "write" | "read";
144
+ rights: "delete" | "read" | "write";
145
+ } & {
146
+ addAccess?: "delete" | "read" | "write" | null | undefined;
147
+ sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
148
+ delAccess?: "delete" | "read" | "write" | null | undefined;
149
+ sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
150
+ };
151
+ current: {
152
+ rights: "delete" | "read" | "write";
152
153
  } & {
153
- addAccess?: "delete" | "write" | "read" | null | undefined;
154
- sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
155
- delAccess?: "delete" | "write" | "read" | null | undefined;
156
- sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
154
+ addAccess?: "delete" | "read" | "write" | null | undefined;
155
+ sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
156
+ delAccess?: "delete" | "read" | "write" | null | undefined;
157
+ sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
157
158
  };
158
159
  }[];
159
160
  };
160
- isMatching: false;
161
161
  }>;
162
162
  createPublicDataLink(input: RouterInputs['cloud']['createDataLink']): Promise<{
163
- name: string;
164
163
  id: string;
165
- createdByUserId: string | null;
166
- createdByAppId: string | null;
167
- createdByOrgId: string | null;
164
+ name: string;
168
165
  slug: string;
169
166
  expireAt: Date | null;
170
167
  dataId: string;
168
+ createdByUserId: string | null;
169
+ createdByOrgId: string | null;
170
+ createdByAppId: string | null;
171
171
  }>;
172
172
  updatePublicDataLink(input: RouterInputs['cloud']['updateDataLink']): Promise<{
173
- name: string;
174
173
  id: string;
175
- createdByUserId: string | null;
176
- createdByAppId: string | null;
177
- createdByOrgId: string | null;
174
+ name: string;
178
175
  slug: string;
179
176
  expireAt: Date | null;
180
177
  dataId: string;
178
+ createdByUserId: string | null;
179
+ createdByOrgId: string | null;
180
+ createdByAppId: string | null;
181
181
  }>;
182
182
  deletePublicDataLink(input: RouterInputs['cloud']['deleteDataLink']): Promise<{
183
- name: string;
184
183
  id: string;
185
- createdByUserId: string | null;
186
- createdByAppId: string | null;
187
- createdByOrgId: string | null;
184
+ name: string;
188
185
  slug: string;
189
186
  expireAt: Date | null;
190
187
  dataId: string;
188
+ createdByUserId: string | null;
189
+ createdByOrgId: string | null;
190
+ createdByAppId: string | null;
191
191
  }>;
192
192
  private _handleDataContent;
193
193
  }
@@ -1,5 +1,5 @@
1
1
  import { BaseClient, type SecrecyUrls } from '../base-client.js';
2
- import type { Progress } from '../crypto/data.js';
2
+ import type { SecretStreamProgress } from '../crypto/data.js';
3
3
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
4
4
  import { SecrecyMailClient } from './SecrecyMailClient.js';
5
5
  import { SecrecyAppClient } from './SecrecyAppClient.js';
@@ -12,7 +12,7 @@ import { SecrecyUserClient } from './SecrecyUserClient.js';
12
12
  import { SecrecyPseudonymClient } from './SecrecyPseudonymClient.js';
13
13
  import { SecrecyOrganizationClient } from './SecrecyOrganizationClient.js';
14
14
  export type NewMail = Pick<RouterInputs['mail']['createDraft'], 'body' | 'subject' | 'senderFiles' | 'recipients' | 'replyToId'>;
15
- export type ProgressCallback = (progress: Progress) => Promise<void>;
15
+ export type ProgressCallback = (progress: SecretStreamProgress) => Promise<void>;
16
16
  export interface SecrecyClientOptions {
17
17
  uaSession: string;
18
18
  uaKeys: KeyPair;
@@ -7,7 +7,7 @@ export type LocalData = {
7
7
  storageType: DataStorageType;
8
8
  size: bigint;
9
9
  sizeEncrypted: bigint | null;
10
- data: Uint8Array;
10
+ data: Uint8Array<ArrayBuffer>;
11
11
  mime?: string;
12
12
  ext?: string;
13
13
  };
@@ -7,40 +7,14 @@ export type * from './user.js';
7
7
  declare const keyPair: z.ZodObject<{
8
8
  publicKey: z.ZodString;
9
9
  privateKey: z.ZodString;
10
- }, "strict", z.ZodTypeAny, {
11
- publicKey: string;
12
- privateKey: string;
13
- }, {
14
- publicKey: string;
15
- privateKey: string;
16
- }>;
10
+ }, z.core.$strict>;
17
11
  export type KeyPair = z.infer<typeof keyPair>;
18
12
  export declare const secrecyUserApp: z.ZodReadonly<z.ZodObject<{
19
13
  keys: z.ZodObject<{
20
14
  publicKey: z.ZodString;
21
15
  privateKey: z.ZodString;
22
- }, "strict", z.ZodTypeAny, {
23
- publicKey: string;
24
- privateKey: string;
25
- }, {
26
- publicKey: string;
27
- privateKey: string;
28
- }>;
16
+ }, z.core.$strict>;
29
17
  jwt: z.ZodString;
30
18
  uaSession: z.ZodString;
31
- }, "strict", z.ZodTypeAny, {
32
- keys: {
33
- publicKey: string;
34
- privateKey: string;
35
- };
36
- jwt: string;
37
- uaSession: string;
38
- }, {
39
- keys: {
40
- publicKey: string;
41
- privateKey: string;
42
- };
43
- jwt: string;
44
- uaSession: string;
45
- }>>;
19
+ }, z.core.$strict>>;
46
20
  export type SecrecyUserApp = z.infer<typeof secrecyUserApp>;