@or-sdk/files-sync-node 0.0.1 → 0.0.2
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/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# FilesSync SDK (for Node.js)
|
|
2
|
+
|
|
3
|
+
This SDK is designed to be used with Node.js only.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i @or-sdk/files-sync-node
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { FilesSyncNode } from '@or-sdk/files-sync-node'
|
|
15
|
+
|
|
16
|
+
// with direct api url
|
|
17
|
+
const files = new FilesSyncNode({
|
|
18
|
+
token: 'my-account-token-string',
|
|
19
|
+
filesApiUrl: 'https://example.files/endpoint'
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// with service discovery (slower)
|
|
23
|
+
const files = new FilesSyncNode({
|
|
24
|
+
token: 'my-account-token-string',
|
|
25
|
+
discoveryUrl: 'https://example.discovery/endpoint'
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Push local directory to remote Files directory
|
|
30
|
+
|
|
31
|
+
Push local directory `./my-data` (could be relative or absolute path) into remote directory `sync-local`
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// create sdk instance
|
|
35
|
+
import { FilesSyncNode } from '@or-sdk/files-sync-node'
|
|
36
|
+
const client = new FilesSyncNode({...})
|
|
37
|
+
|
|
38
|
+
// push directory
|
|
39
|
+
await client.pushLocalPathToFiles('./my-data', 'sync-local')
|
|
40
|
+
|
|
41
|
+
// set uploaded files as public
|
|
42
|
+
await client.pushLocalPathToFiles('./my-data', 'sync-local', {
|
|
43
|
+
isPublic: true,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// set uploaded to expire in 1 hour
|
|
47
|
+
await client.pushLocalPathToFiles('./my-data', 'sync-local', {
|
|
48
|
+
ttl: Date.now() + 3_600_000,
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Debugging
|
|
53
|
+
|
|
54
|
+
To see debug logs of synching define environment variable `DEBUG` with value `files-sync`:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
DEBUG='files-sync' node ./run_logic.js
|
|
58
|
+
```
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var q=Object.create;var g=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var R=(i,e)=>{for(var t in e)g(i,t,{get:e[t],enumerable:!0})},P=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of I(e))!D.call(i,s)&&s!==t&&g(i,s,{get:()=>e[s],enumerable:!(o=z(e,s))||o.enumerable});return i};var j=(i,e,t)=>(t=i!=null?q(N(i)):{},P(e||!i||!i.__esModule?g(t,"default",{value:i,enumerable:!0}):t,i)),E=i=>P(g({},"__esModule",{value:!0}),i);var M={};R(M,{FilesSyncNode:()=>w});module.exports=E(M);var n=require("path"),v=j(require("fs/promises")
|
|
1
|
+
"use strict";var q=Object.create;var g=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var R=(i,e)=>{for(var t in e)g(i,t,{get:e[t],enumerable:!0})},P=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of I(e))!D.call(i,s)&&s!==t&&g(i,s,{get:()=>e[s],enumerable:!(o=z(e,s))||o.enumerable});return i};var j=(i,e,t)=>(t=i!=null?q(N(i)):{},P(e||!i||!i.__esModule?g(t,"default",{value:i,enumerable:!0}):t,i)),E=i=>P(g({},"__esModule",{value:!0}),i);var M={};R(M,{FilesSyncNode:()=>w});module.exports=E(M);var n=require("path"),v=j(require("fs/promises")),T=j(require("debug")),S=require("@or-sdk/files"),U=require("mime-types");var x=class{value;next;constructor(e){this.value=e}},f=class{#e;#t;#i;constructor(){this.clear()}enqueue(e){let t=new x(e);this.#e?(this.#t.next=t,this.#t=t):(this.#e=t,this.#t=t),this.#i++}dequeue(){let e=this.#e;if(e)return this.#e=this.#e.next,this.#i--,e.value}peek(){if(this.#e)return this.#e.value}clear(){this.#e=void 0,this.#t=void 0,this.#i=0}get size(){return this.#i}*[Symbol.iterator](){let e=this.#e;for(;e;)yield e.value,e=e.next}*drain(){for(;this.#e;)yield this.dequeue()}};function F(i){k(i);let e=new f,t=0,o=()=>{t<i&&e.size>0&&(t++,e.dequeue()())},s=()=>{t--,o()},l=async(a,p,c)=>{let r=(async()=>a(...c))();p(r);try{await r}catch{}s()},u=(a,p,c)=>{new Promise(r=>{e.enqueue(r)}).then(l.bind(void 0,a,p,c)),t<i&&o()},d=(a,...p)=>new Promise(c=>{u(a,c,p)});return Object.defineProperties(d,{activeCount:{get:()=>t},pendingCount:{get:()=>e.size},clearQueue:{value(){e.clear()}},concurrency:{get:()=>i,set(a){k(a),i=a,queueMicrotask(()=>{for(;t<i&&e.size>0;)o()})}},map:{async value(a,p){let c=Array.from(a,(r,b)=>this(p,r,b));return Promise.all(c)}}}),d}function k(i){if(!((Number.isInteger(i)||i===Number.POSITIVE_INFINITY)&&i>0))throw new TypeError("Expected `concurrency` to be a number from 1 and up")}var h=(0,T.default)("files-sync"),w=class{filesClient;constructor({token:e,discoveryUrl:t,filesApiUrl:o,accountId:s}){this.filesClient=new S.Files({token:e,discoveryUrl:t,filesApiUrl:o,accountId:s})}async pushLocalPathToFiles(e,t,o={}){let s=await this.listLocalObjects(e);if(s.files.length){let l=Date.now();h("Found %d local files. Starting upload.",s.files.length),await this.uploadFiles({remotePathPrefix:t,localFiles:s.files},o),h("Finished uploading local files (%d ms)",Date.now()-l)}}async uploadFiles({localFiles:e,remotePathPrefix:t},o={}){let{concurrencyLimit:s=5,isPublic:l=!1,...u}=o,d=F(s),a=e.map(r=>d(async()=>{let b=Date.now();h("Starting upload: %s",r.relative);let O=await v.default.open(r.full,"r"),L=await O.stat();try{let m=(0,n.basename)(r.relative),y=(0,n.join)(t??"",(0,n.dirname)(r.relative)),C={...u,name:m,type:(0,U.lookup)(m)||"application/octet-stream",maxFileSize:L.size,prefix:y==="."?"":`${y}/`,isPublic:l,fileModel:O.createReadStream({autoClose:!0,signal:u.abortSignal}),knownLength:L.size};await this.filesClient.uploadFile(C),h("Finished upload: %s (%d ms)",r.relative,Date.now()-b)}catch(m){let y=m.response?.data??m.stack;throw h("Failed to upload: %s. Error: %j",r.relative,y),m}})),c=(await Promise.allSettled(a)).find(r=>r.status==="rejected");if(c)throw c.reason}async listLocalObjects(e){let{dirs:t,files:o}=await this.walkLocal(e);return{dirs:t.map(s=>({full:s,relative:(0,n.relative)(e,s)})),files:o.map(s=>({full:s,relative:(0,n.relative)(e,s)}))}}async walkLocal(e){let t=await v.default.readdir(e,{withFileTypes:!0}),o=[],s=[];for(let l of t){let u=(0,n.join)(e,l.name);if(l.isDirectory()){o.push((0,n.join)(e,l.name));let d=await this.walkLocal(u);s.push(...d.files),o.push(...d.dirs)}else l.isFile()&&s.push(u)}return{dirs:o,files:s}}};0&&(module.exports={FilesSyncNode});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/FilesSyncNode.ts","../../node_modules/.pnpm/yocto-queue@1.2.1/node_modules/yocto-queue/index.js","../../node_modules/.pnpm/p-limit@7.2.0/node_modules/p-limit/index.js"],"sourcesContent":["export { FilesSyncNode } from './FilesSyncNode.ts';\nexport * from './types.ts';\n","import { basename, dirname, join, relative } from 'node:path';\nimport fs from 'node:fs/promises';\nimport debug from 'debug';\nimport { Files } from '@or-sdk/files';\nimport { lookup as mimeLookup } from 'mime-types';\nimport pLimit from 'p-limit';\nimport type {\n FilesSyncNodeConfig,\n FileUploadOptions,\n LocalObjects,\n PushLocalPathToFilesOptions,\n UploadFilesParameters,\n} from './types.ts';\n\nconst log = debug('files-sync');\n\n/**\n * SDK for synchronizing local directory and directory in Onereach Files service. \n * This SDK is designed to be used with Node.js\n * \n * @example \n * Create client instance with service discovery URL\n * \n * ```typescript\n * const client = new FilesSyncNode({\n * token: process.env.OR_TOKEN,\n * discoveryUrl: process.env.OR_DISCOVERY_URL\n * });\n * ```\n *\n * @example \n * Create client instance with files service URL\n * \n * ```typescript\n * const client = new FilesSyncNode({\n * token: process.env.OR_TOKEN,\n * filesApiUrl: process.env.OR_FILES_API_URL\n * });\n * ```\n * \n * To see debug logs of synching define environment variable `DEBUG` with value `files-sync`:\n * \n * ```sh\n * DEBUG='files-sync' node ./run_logic.js\n * ```\n*/\nexport class FilesSyncNode {\n private readonly filesClient: Files;\n\n public constructor({\n token,\n discoveryUrl,\n filesApiUrl,\n accountId,\n }: FilesSyncNodeConfig) {\n this.filesClient = new Files({ token, discoveryUrl, filesApiUrl, accountId })\n }\n\n /**\n * Push local directory to Files service.\n * - All local files would be remote directory;\n * - Extra files in remote directory will remain;\n * - If remote file has the same name as local file, it would be replaced.\n * - Any required remote subdirectories would be created automatically.\n * \n * @param localPath local directory path\n * @param remotePathPrefix path in Files service where to push files. If not set would be synched into root directory.\n * @param options upload params\n * @param options.ttl Timestamp in ms when file should expire\n * @param options.isPublic if `true` uploaded files would be publicly available (access without authentication). Default `false`.\n * @param options.concurrencyLimit how many files can be uploaded at the same time. Default `5`.\n * \n * @example\n * Push local directory `./my-data` (path relative to current working directory of the process)\n * into remote directory `sync-local`\n * ```typescript\n * await client.pushLocalPathToFiles('./my-data', 'sync-local')\n * ```\n */\n public async pushLocalPathToFiles(localPath: string, remotePathPrefix?: string, options: PushLocalPathToFilesOptions = {}) {\n const localObjects = await this.listLocalObjects(localPath)\n\n if (localObjects.files.length) {\n const start = Date.now();\n log('Found %d local files. Starting upload.', localObjects.files.length);\n await this.uploadFiles({ remotePathPrefix, localFiles: localObjects.files }, options);\n log('Finished uploading local files (%d ms)', Date.now() - start);\n }\n }\n\n // private getDiff(localObjects: LocalObjects, remoteObjects: RemoteObjects) {\n // const uploadLocalFiles = localObjects.files.filter(localFile => {\n // return !remoteObjects.files.some(file => file.relative === localFile.relative);\n // });\n\n // const deleteRemoteFiles = remoteObjects.files.filter(remoteFile => {\n // return !localObjects.files.some(file => file.relative === remoteFile.relative);\n // });\n\n // const createRemoteDirs = localObjects.dirs.filter(localDir => {\n // return !remoteObjects.dirs.some(dir => dir.relative === localDir.relative);\n // })\n // const deleteRemoteDirs = remoteObjects.dirs.filter(remoteDir => {\n // return !localObjects.dirs.some(dir => dir.relative === remoteDir.relative);\n // })\n\n // return { uploadLocalFiles, deleteRemoteFiles, createRemoteDirs, deleteRemoteDirs };\n // }\n\n // private async listRemoteObjects(remotePathPrefix?: string): Promise<RemoteObjects> {\n // const result: RemoteObjects = { files: [], dirs: [] }\n // const objects = await this.filesClient.getItemsList(remotePathPrefix ?? '');\n\n // for (const object of objects) {\n // // TODO: test if it works with objects in root without prefix\n // const relativePath = relative(object.parentFolder, object.key)\n // if (object.key.endsWith('/')) result.dirs.push({ relative: relativePath, key: object.key })\n // else result.files.push({ relative: relativePath, key: object.key })\n // }\n\n // return result;\n // }\n\n private async uploadFiles({ localFiles, remotePathPrefix }: UploadFilesParameters, uploadOptions: FileUploadOptions = {}) {\n const { concurrencyLimit = 5, isPublic = false, ...options } = uploadOptions;\n\n const limit = pLimit(concurrencyLimit);\n const uploadTasks = localFiles.map(localFile => limit(async () => {\n const start = Date.now();\n log('Starting upload: %s', localFile.relative);\n\n const handle = await fs.open(localFile.full, 'r');\n const stats = await handle.stat();\n try {\n const name = basename(localFile.relative);\n const prefix = join(remotePathPrefix ?? '', dirname(localFile.relative))\n const request = {\n ...options,\n name,\n type: mimeLookup(name) || 'application/octet-stream',\n maxFileSize: stats.size,\n prefix: prefix === '.' ? '' : `${prefix}/`,\n isPublic,\n fileModel: handle.createReadStream({ autoClose: true, signal: options.abortSignal }),\n knownLength: stats.size,\n }\n\n await this.filesClient.uploadFile(request)\n log('Finished upload: %s (%d ms)', localFile.relative, Date.now() - start)\n } catch (error) {\n const errorMessage = (error as any).response?.data ?? (error as any).stack\n log('Failed to upload: %s. Error: %j', localFile.relative, errorMessage);\n throw error;\n }\n }));\n\n const result = await Promise.allSettled(uploadTasks);\n const rejected = result.find(item => item.status === 'rejected')\n\n if (rejected) throw rejected.reason;\n }\n\n private async listLocalObjects(localPath: string): Promise<LocalObjects> {\n const { dirs, files } = await this.walkLocal(localPath);\n\n return {\n dirs: dirs.map(full => ({ full, relative: relative(localPath, full) })),\n files: files.map(full => ({ full, relative: relative(localPath, full) })),\n }\n }\n\n /**\n * Recursively collect all file paths under a directory.\n */\n private async walkLocal(localPath: string) {\n const entries = await fs.readdir(localPath, { withFileTypes: true });\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = join(localPath, entry.name);\n if (entry.isDirectory()) {\n dirs.push(join(localPath, entry.name))\n const child = await this.walkLocal(fullPath);\n files.push(...child.files)\n dirs.push(...child.dirs)\n } else if (entry.isFile()) {\n files.push(fullPath);\n // } else {\n // files.push(fullPath);\n }\n }\n return { dirs, files };\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tvalidateConcurrency(concurrency);\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue()();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, arguments_) => {\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueue.enqueue(internalResolve);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise(resolve => {\n\t\tenqueue(function_, resolve, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tqueue.clear();\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = Array.from(iterable, (value, index) => this(function_, value, index));\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst {concurrency} = options;\n\tconst limit = pLimit(concurrency);\n\n\treturn (...arguments_) => limit(() => function_(...arguments_));\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n"],"mappings":"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","names":["index_exports","__export","FilesSyncNode","__toCommonJS","import_node_path","import_promises","import_debug","import_files","import_mime_types","Node","value","Queue","#head","#tail","#size","node","current","pLimit","concurrency","validateConcurrency","queue","Queue","activeCount","resumeNext","next","run","function_","resolve","arguments_","result","enqueue","internalResolve","generator","newConcurrency","iterable","promises","value","index","validateConcurrency","concurrency","log","debug","FilesSyncNode","token","discoveryUrl","filesApiUrl","accountId","localPath","remotePathPrefix","options","localObjects","start","localFiles","uploadOptions","concurrencyLimit","isPublic","limit","pLimit","uploadTasks","localFile","handle","fs","stats","name","prefix","request","mimeLookup","error","errorMessage","rejected","item","dirs","files","full","entries","entry","fullPath","child"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/FilesSyncNode.ts","../../node_modules/.pnpm/yocto-queue@1.2.1/node_modules/yocto-queue/index.js","../../node_modules/.pnpm/p-limit@7.2.0/node_modules/p-limit/index.js"],"sourcesContent":["export { FilesSyncNode } from './FilesSyncNode.ts';\nexport * from './types.ts';\n","import { basename, dirname, join, relative } from 'node:path';\nimport fs from 'node:fs/promises';\nimport debug from 'debug';\nimport { Files } from '@or-sdk/files';\nimport { lookup as mimeLookup } from 'mime-types';\nimport pLimit from 'p-limit';\nimport type {\n FilesSyncNodeConfig,\n FileUploadOptions,\n LocalObjects,\n PushLocalPathToFilesOptions,\n UploadFilesParameters,\n} from './types.ts';\n\nconst log = debug('files-sync');\n\n/**\n * SDK for synchronizing local directory and directory in Onereach Files service. \n * This SDK is designed to be used with Node.js\n * \n * @example \n * Create client instance with service discovery URL\n * \n * ```typescript\n * const client = new FilesSyncNode({\n * token: process.env.OR_TOKEN,\n * discoveryUrl: process.env.OR_DISCOVERY_URL\n * });\n * ```\n *\n * @example \n * Create client instance with files service URL\n * \n * ```typescript\n * const client = new FilesSyncNode({\n * token: process.env.OR_TOKEN,\n * filesApiUrl: process.env.OR_FILES_API_URL\n * });\n * ```\n * \n * To see debug logs of synching define environment variable `DEBUG` with value `files-sync`:\n * \n * ```sh\n * DEBUG='files-sync' node ./run_logic.js\n * ```\n*/\nexport class FilesSyncNode {\n private readonly filesClient: Files;\n\n public constructor({\n token,\n discoveryUrl,\n filesApiUrl,\n accountId,\n }: FilesSyncNodeConfig) {\n this.filesClient = new Files({ token, discoveryUrl, filesApiUrl, accountId })\n }\n\n /**\n * Push local directory to Files service.\n * - All local files would be remote directory;\n * - Extra files in remote directory will remain;\n * - If remote file has the same name as local file, it would be replaced.\n * - Any required remote subdirectories would be created automatically.\n * \n * @param localPath local directory path\n * @param remotePathPrefix path in Files service where to push files. If not set would be synched into root directory.\n * @param options upload params\n * @param options.ttl Timestamp in ms when file should expire\n * @param options.isPublic if `true` uploaded files would be publicly available (access without authentication). Default `false`.\n * @param options.concurrencyLimit how many files can be uploaded at the same time. Default `5`.\n * \n * @example\n * Push local directory `./my-data` (path relative to current working directory of the process)\n * into remote directory `sync-local`\n * ```typescript\n * await client.pushLocalPathToFiles('./my-data', 'sync-local')\n * ```\n */\n public async pushLocalPathToFiles(localPath: string, remotePathPrefix?: string, options: PushLocalPathToFilesOptions = {}) {\n const localObjects = await this.listLocalObjects(localPath)\n\n if (localObjects.files.length) {\n const start = Date.now();\n log('Found %d local files. Starting upload.', localObjects.files.length);\n await this.uploadFiles({ remotePathPrefix, localFiles: localObjects.files }, options);\n log('Finished uploading local files (%d ms)', Date.now() - start);\n }\n }\n\n // private getDiff(localObjects: LocalObjects, remoteObjects: RemoteObjects) {\n // const uploadLocalFiles = localObjects.files.filter(localFile => {\n // return !remoteObjects.files.some(file => file.relative === localFile.relative);\n // });\n\n // const deleteRemoteFiles = remoteObjects.files.filter(remoteFile => {\n // return !localObjects.files.some(file => file.relative === remoteFile.relative);\n // });\n\n // const createRemoteDirs = localObjects.dirs.filter(localDir => {\n // return !remoteObjects.dirs.some(dir => dir.relative === localDir.relative);\n // })\n // const deleteRemoteDirs = remoteObjects.dirs.filter(remoteDir => {\n // return !localObjects.dirs.some(dir => dir.relative === remoteDir.relative);\n // })\n\n // return { uploadLocalFiles, deleteRemoteFiles, createRemoteDirs, deleteRemoteDirs };\n // }\n\n // private async listRemoteObjects(remotePathPrefix?: string): Promise<RemoteObjects> {\n // const result: RemoteObjects = { files: [], dirs: [] }\n // const objects = await this.filesClient.getItemsList(remotePathPrefix ?? '');\n\n // for (const object of objects) {\n // // TODO: test if it works with objects in root without prefix\n // const relativePath = relative(object.parentFolder, object.key)\n // if (object.key.endsWith('/')) result.dirs.push({ relative: relativePath, key: object.key })\n // else result.files.push({ relative: relativePath, key: object.key })\n // }\n\n // return result;\n // }\n\n private async uploadFiles({ localFiles, remotePathPrefix }: UploadFilesParameters, uploadOptions: FileUploadOptions = {}) {\n const { concurrencyLimit = 5, isPublic = false, ...options } = uploadOptions;\n\n const limit = pLimit(concurrencyLimit);\n const uploadTasks = localFiles.map(localFile => limit(async () => {\n const start = Date.now();\n log('Starting upload: %s', localFile.relative);\n\n const handle = await fs.open(localFile.full, 'r');\n const stats = await handle.stat();\n try {\n const name = basename(localFile.relative);\n const prefix = join(remotePathPrefix ?? '', dirname(localFile.relative))\n const request = {\n ...options,\n name,\n type: mimeLookup(name) || 'application/octet-stream',\n maxFileSize: stats.size,\n prefix: prefix === '.' ? '' : `${prefix}/`,\n isPublic,\n fileModel: handle.createReadStream({ autoClose: true, signal: options.abortSignal }),\n knownLength: stats.size,\n }\n\n await this.filesClient.uploadFile(request)\n log('Finished upload: %s (%d ms)', localFile.relative, Date.now() - start)\n } catch (error) {\n const errorMessage = (error as any).response?.data ?? (error as any).stack\n log('Failed to upload: %s. Error: %j', localFile.relative, errorMessage);\n throw error;\n }\n }));\n\n const result = await Promise.allSettled(uploadTasks);\n const rejected = result.find(item => item.status === 'rejected')\n\n if (rejected) throw rejected.reason;\n }\n\n private async listLocalObjects(localPath: string): Promise<LocalObjects> {\n const { dirs, files } = await this.walkLocal(localPath);\n\n return {\n dirs: dirs.map(full => ({ full, relative: relative(localPath, full) })),\n files: files.map(full => ({ full, relative: relative(localPath, full) })),\n }\n }\n\n /**\n * Recursively collect all file paths under a directory.\n */\n private async walkLocal(localPath: string) {\n const entries = await fs.readdir(localPath, { withFileTypes: true });\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n const fullPath = join(localPath, entry.name);\n if (entry.isDirectory()) {\n dirs.push(join(localPath, entry.name))\n const child = await this.walkLocal(fullPath);\n files.push(...child.files)\n dirs.push(...child.dirs)\n } else if (entry.isFile()) {\n files.push(fullPath);\n // } else {\n // files.push(fullPath);\n }\n }\n return { dirs, files };\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tvalidateConcurrency(concurrency);\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue()();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, arguments_) => {\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueue.enqueue(internalResolve);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise(resolve => {\n\t\tenqueue(function_, resolve, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tqueue.clear();\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = Array.from(iterable, (value, index) => this(function_, value, index));\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst {concurrency} = options;\n\tconst limit = pLimit(concurrency);\n\n\treturn (...arguments_) => limit(() => function_(...arguments_));\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,IAAA,eAAAC,EAAAH,GCAA,IAAAI,EAAkD,gBAClDC,EAAe,0BACfC,EAAkB,oBAClBC,EAAsB,yBACtBC,EAAqC,sBCCrC,IAAMC,EAAN,KAAW,CACV,MACA,KAEA,YAAYC,EAAO,CAClB,KAAK,MAAQA,CACd,CACD,EAEqBC,EAArB,KAA2B,CAC1BC,GACAC,GACAC,GAEA,aAAc,CACb,KAAK,MAAM,CACZ,CAEA,QAAQJ,EAAO,CACd,IAAMK,EAAO,IAAIN,EAAKC,CAAK,EAEvB,KAAKE,IACR,KAAKC,GAAM,KAAOE,EAClB,KAAKF,GAAQE,IAEb,KAAKH,GAAQG,EACb,KAAKF,GAAQE,GAGd,KAAKD,IACN,CAEA,SAAU,CACT,IAAME,EAAU,KAAKJ,GACrB,GAAKI,EAIL,YAAKJ,GAAQ,KAAKA,GAAM,KACxB,KAAKE,KACEE,EAAQ,KAChB,CAEA,MAAO,CACN,GAAK,KAAKJ,GAIV,OAAO,KAAKA,GAAM,KAInB,CAEA,OAAQ,CACP,KAAKA,GAAQ,OACb,KAAKC,GAAQ,OACb,KAAKC,GAAQ,CACd,CAEA,IAAI,MAAO,CACV,OAAO,KAAKA,EACb,CAEA,EAAG,OAAO,QAAQ,GAAI,CACrB,IAAIE,EAAU,KAAKJ,GAEnB,KAAOI,GACN,MAAMA,EAAQ,MACdA,EAAUA,EAAQ,IAEpB,CAEA,CAAE,OAAQ,CACT,KAAO,KAAKJ,IACX,MAAM,KAAK,QAAQ,CAErB,CACD,ECjFe,SAARK,EAAwBC,EAAa,CAC3CC,EAAoBD,CAAW,EAE/B,IAAME,EAAQ,IAAIC,EACdC,EAAc,EAEZC,EAAa,IAAM,CAEpBD,EAAcJ,GAAeE,EAAM,KAAO,IAC7CE,IACAF,EAAM,QAAQ,EAAE,EAElB,EAEMI,EAAO,IAAM,CAClBF,IACAC,EAAW,CACZ,EAEME,EAAM,MAAOC,EAAWC,EAASC,IAAe,CAErD,IAAMC,GAAU,SAAYH,EAAU,GAAGE,CAAU,GAAG,EAGtDD,EAAQE,CAAM,EAKd,GAAI,CACH,MAAMA,CACP,MAAQ,CAAC,CAGTL,EAAK,CACN,EAEMM,EAAU,CAACJ,EAAWC,EAASC,IAAe,CAGnD,IAAI,QAAQG,GAAmB,CAC9BX,EAAM,QAAQW,CAAe,CAC9B,CAAC,EAAE,KAAKN,EAAI,KAAK,OAAWC,EAAWC,EAASC,CAAU,CAAC,EAGvDN,EAAcJ,GACjBK,EAAW,CAEb,EAEMS,EAAY,CAACN,KAAcE,IAAe,IAAI,QAAQD,GAAW,CACtEG,EAAQJ,EAAWC,EAASC,CAAU,CACvC,CAAC,EAED,cAAO,iBAAiBI,EAAW,CAClC,YAAa,CACZ,IAAK,IAAMV,CACZ,EACA,aAAc,CACb,IAAK,IAAMF,EAAM,IAClB,EACA,WAAY,CACX,OAAQ,CACPA,EAAM,MAAM,CACb,CACD,EACA,YAAa,CACZ,IAAK,IAAMF,EAEX,IAAIe,EAAgB,CACnBd,EAAoBc,CAAc,EAClCf,EAAce,EAEd,eAAe,IAAM,CAEpB,KAAOX,EAAcJ,GAAeE,EAAM,KAAO,GAChDG,EAAW,CAEb,CAAC,CACF,CACD,EACA,IAAK,CACJ,MAAM,MAAMW,EAAUR,EAAW,CAChC,IAAMS,EAAW,MAAM,KAAKD,EAAU,CAACE,EAAOC,IAAU,KAAKX,EAAWU,EAAOC,CAAK,CAAC,EACrF,OAAO,QAAQ,IAAIF,CAAQ,CAC5B,CACD,CACD,CAAC,EAEMH,CACR,CASA,SAASM,EAAoBC,EAAa,CACzC,GAAI,GAAG,OAAO,UAAUA,CAAW,GAAKA,IAAgB,OAAO,oBAAsBA,EAAc,GAClG,MAAM,IAAI,UAAU,qDAAqD,CAE3E,CF3FA,IAAMC,KAAM,EAAAC,SAAM,YAAY,EAgCjBC,EAAN,KAAoB,CACR,YAEV,YAAY,CACjB,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,UAAAC,CACF,EAAwB,CACtB,KAAK,YAAc,IAAI,QAAM,CAAE,MAAAH,EAAO,aAAAC,EAAc,YAAAC,EAAa,UAAAC,CAAU,CAAC,CAC9E,CAuBA,MAAa,qBAAqBC,EAAmBC,EAA2BC,EAAuC,CAAC,EAAG,CACzH,IAAMC,EAAe,MAAM,KAAK,iBAAiBH,CAAS,EAE1D,GAAIG,EAAa,MAAM,OAAQ,CAC7B,IAAMC,EAAQ,KAAK,IAAI,EACvBX,EAAI,yCAA0CU,EAAa,MAAM,MAAM,EACvE,MAAM,KAAK,YAAY,CAAE,iBAAAF,EAAkB,WAAYE,EAAa,KAAM,EAAGD,CAAO,EACpFT,EAAI,yCAA0C,KAAK,IAAI,EAAIW,CAAK,CAClE,CACF,CAmCA,MAAc,YAAY,CAAE,WAAAC,EAAY,iBAAAJ,CAAiB,EAA0BK,EAAmC,CAAC,EAAG,CACxH,GAAM,CAAE,iBAAAC,EAAmB,EAAG,SAAAC,EAAW,GAAO,GAAGN,CAAQ,EAAII,EAEzDG,EAAQC,EAAOH,CAAgB,EAC/BI,EAAcN,EAAW,IAAIO,GAAaH,EAAM,SAAY,CAChE,IAAML,EAAQ,KAAK,IAAI,EACvBX,EAAI,sBAAuBmB,EAAU,QAAQ,EAE7C,IAAMC,EAAS,MAAM,EAAAC,QAAG,KAAKF,EAAU,KAAM,GAAG,EAC1CG,EAAQ,MAAMF,EAAO,KAAK,EAChC,GAAI,CACF,IAAMG,KAAO,YAASJ,EAAU,QAAQ,EAClCK,KAAS,QAAKhB,GAAoB,MAAI,WAAQW,EAAU,QAAQ,CAAC,EACjEM,EAAU,CACd,GAAGhB,EACH,KAAAc,EACA,QAAM,EAAAG,QAAWH,CAAI,GAAK,2BAC1B,YAAaD,EAAM,KACnB,OAAQE,IAAW,IAAM,GAAK,GAAGA,CAAM,IACvC,SAAAT,EACA,UAAWK,EAAO,iBAAiB,CAAE,UAAW,GAAM,OAAQX,EAAQ,WAAY,CAAC,EACnF,YAAaa,EAAM,IACrB,EAEA,MAAM,KAAK,YAAY,WAAWG,CAAO,EACzCzB,EAAI,8BAA+BmB,EAAU,SAAU,KAAK,IAAI,EAAIR,CAAK,CAC3E,OAASgB,EAAO,CACd,IAAMC,EAAgBD,EAAc,UAAU,MAASA,EAAc,MACrE,MAAA3B,EAAI,kCAAmCmB,EAAU,SAAUS,CAAY,EACjED,CACR,CACF,CAAC,CAAC,EAGIE,GADS,MAAM,QAAQ,WAAWX,CAAW,GAC3B,KAAKY,GAAQA,EAAK,SAAW,UAAU,EAE/D,GAAID,EAAU,MAAMA,EAAS,MAC/B,CAEA,MAAc,iBAAiBtB,EAA0C,CACvE,GAAM,CAAE,KAAAwB,EAAM,MAAAC,CAAM,EAAI,MAAM,KAAK,UAAUzB,CAAS,EAEtD,MAAO,CACL,KAAMwB,EAAK,IAAIE,IAAS,CAAE,KAAAA,EAAM,YAAU,YAAS1B,EAAW0B,CAAI,CAAE,EAAE,EACtE,MAAOD,EAAM,IAAIC,IAAS,CAAE,KAAAA,EAAM,YAAU,YAAS1B,EAAW0B,CAAI,CAAE,EAAE,CAC1E,CACF,CAKA,MAAc,UAAU1B,EAAmB,CACzC,IAAM2B,EAAU,MAAM,EAAAb,QAAG,QAAQd,EAAW,CAAE,cAAe,EAAK,CAAC,EAC7DwB,EAAiB,CAAC,EAClBC,EAAkB,CAAC,EAEzB,QAAWG,KAASD,EAAS,CAC3B,IAAME,KAAW,QAAK7B,EAAW4B,EAAM,IAAI,EAC3C,GAAIA,EAAM,YAAY,EAAG,CACvBJ,EAAK,QAAK,QAAKxB,EAAW4B,EAAM,IAAI,CAAC,EACrC,IAAME,EAAQ,MAAM,KAAK,UAAUD,CAAQ,EAC3CJ,EAAM,KAAK,GAAGK,EAAM,KAAK,EACzBN,EAAK,KAAK,GAAGM,EAAM,IAAI,CACzB,MAAWF,EAAM,OAAO,GACtBH,EAAM,KAAKI,CAAQ,CAIvB,CACA,MAAO,CAAE,KAAAL,EAAM,MAAAC,CAAM,CACvB,CACF","names":["index_exports","__export","FilesSyncNode","__toCommonJS","import_node_path","import_promises","import_debug","import_files","import_mime_types","Node","value","Queue","#head","#tail","#size","node","current","pLimit","concurrency","validateConcurrency","queue","Queue","activeCount","resumeNext","next","run","function_","resolve","arguments_","result","enqueue","internalResolve","generator","newConcurrency","iterable","promises","value","index","validateConcurrency","concurrency","log","debug","FilesSyncNode","token","discoveryUrl","filesApiUrl","accountId","localPath","remotePathPrefix","options","localObjects","start","localFiles","uploadOptions","concurrencyLimit","isPublic","limit","pLimit","uploadTasks","localFile","handle","fs","stats","name","prefix","request","mimeLookup","error","errorMessage","rejected","item","dirs","files","full","entries","entry","fullPath","child"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@or-sdk/files-sync-node",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"type": "module",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "SDK for synchronization of local directory with Files service",
|
|
6
5
|
"main": "dist/cjs/index.cjs",
|
|
7
6
|
"module": "dist/esm/index.mjs",
|
|
8
7
|
"types": "dist/esm/index.d.ts",
|
|
@@ -42,5 +41,8 @@
|
|
|
42
41
|
"tsup": "^8.5.0",
|
|
43
42
|
"typescript": "^5.9.3"
|
|
44
43
|
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
45
47
|
"packageManager": "pnpm@10.19.0"
|
|
46
48
|
}
|
|
File without changes
|
|
File without changes
|