aspect-sync 0.1.24 → 0.1.26
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 +50 -3
- package/dist/index.js +12 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,42 @@
|
|
|
1
1
|
# Aspect Data Sync
|
|
2
2
|
|
|
3
|
-
A CLI tool to sync files from external services
|
|
3
|
+
A CLI tool to sync files from external services to the Aspect platform.
|
|
4
|
+
|
|
5
|
+
## Sources
|
|
6
|
+
|
|
7
|
+
The `--source` flag selects where files come from:
|
|
8
|
+
|
|
9
|
+
| Source | Description | Data path |
|
|
10
|
+
|--------|-------------|-----------|
|
|
11
|
+
| `rclone` (default) | Any rclone-supported remote (Dropbox, Google Drive, S3, ...) | Downloaded to local staging, then uploaded |
|
|
12
|
+
| `local` | A local directory (including externally mounted filesystems) | Uploaded in place, no staging copy |
|
|
13
|
+
| `lucidlink` | A LucidLink filespace, mounted headlessly for the duration of the sync | Mounted via `lucid daemon`, uploaded in place |
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# rclone remote (default; --source rclone is implied)
|
|
17
|
+
aspect-sync --remote dropbox --path /videos ...
|
|
18
|
+
aspect-sync --source rclone --remote gdrive ...
|
|
19
|
+
|
|
20
|
+
# local directory
|
|
21
|
+
aspect-sync --source local --path /data/staged-customer-files ...
|
|
22
|
+
|
|
23
|
+
# LucidLink filespace (requires the LucidLink client installed and a password
|
|
24
|
+
# via --lucid-password-file or the LUCID_PASSWORD env variable)
|
|
25
|
+
aspect-sync --source lucidlink \
|
|
26
|
+
--lucid-fs filespace.domain \
|
|
27
|
+
--lucid-user user@example.com \
|
|
28
|
+
--lucid-password-file ~/.lucid_pwd \
|
|
29
|
+
--lucid-cache-size 100GB \
|
|
30
|
+
--path /Projects/Customer ...
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For `lucidlink`, the filespace is mounted at a session-scoped mount point with its cache on the sync temp volume, linked before listing starts, and unmounted (and its cache deleted) when the sync finishes or fails. `--path` is the folder within the filespace ("/" syncs the whole filespace).
|
|
4
34
|
|
|
5
35
|
## Features
|
|
6
36
|
|
|
7
37
|
- **Rclone integration**: Lists and downloads from any rclone-supported remote.
|
|
38
|
+
- **In-place local sources**: Local directories and mounted filespaces upload directly with no staging copy.
|
|
39
|
+
- **LucidLink lifecycle management**: Mounts and unmounts filespaces headlessly around the sync.
|
|
8
40
|
- **Aspect-compatible path planning**: Preserves source hierarchy while sanitizing names that Aspect rejects.
|
|
9
41
|
- **Duplicate preservation when supported**: Preserves duplicate file and folder names when the rclone provider exposes stable IDs.
|
|
10
42
|
- **Idempotent reruns**: Reuses existing directories and skips assets that are already uploaded.
|
|
@@ -115,12 +147,27 @@ Required:
|
|
|
115
147
|
|
|
116
148
|
| Option | Description |
|
|
117
149
|
|--------|-------------|
|
|
118
|
-
| `--
|
|
119
|
-
| `--path <path>` | Remote path to sync from. |
|
|
150
|
+
| `--path <path>` | Path to sync from: remote path (`rclone`), local directory (`local`), or path within the filespace (`lucidlink`). |
|
|
120
151
|
| `--directory-id <id>` | Aspect directory ID to upload into. |
|
|
121
152
|
| `--project-id <id>` | Aspect project ID. |
|
|
122
153
|
| `--api-key <key>` | Aspect API key. Can also be set with `ASPECT_API_KEY`. |
|
|
123
154
|
|
|
155
|
+
Source selection:
|
|
156
|
+
|
|
157
|
+
| Option | Description | Default |
|
|
158
|
+
|--------|-------------|---------|
|
|
159
|
+
| `--source <kind>` | Source kind: `rclone`, `local`, or `lucidlink`. | `rclone` |
|
|
160
|
+
| `--remote <name>` | rclone remote name from your rclone config, without the trailing colon. Required for `--source rclone`. | Not set |
|
|
161
|
+
|
|
162
|
+
LucidLink options:
|
|
163
|
+
| Option | Description | Default |
|
|
164
|
+
| ------ | ----------- | ------- |
|
|
165
|
+
| `--lucid-fs <filespace>` | LucidLink filespace (e.g. `myspace.mydomain`). Required for `--source lucidlink`. | Not set |
|
|
166
|
+
| `--lucid-user <user>` | LucidLink filespace user. Required for `--source lucidlink`. | Not set |
|
|
167
|
+
| `--lucid-password-file <path>` | File containing the LucidLink password. Alternatively set `LUCID_PASSWORD`. | Not set |
|
|
168
|
+
| `--lucid-instance <number>` | LucidLink daemon instance ID. | `9001` |
|
|
169
|
+
| `--lucid-cache-size <size>` | LucidLink `DataCache.Size` applied after mount (e.g. `100GB`). | Client default |
|
|
170
|
+
|
|
124
171
|
Aspect API options:
|
|
125
172
|
|
|
126
173
|
| Option | Description | Default |
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as Wt}from"commander";import Qe from"node:path";import{readFileSync as Yt}from"node:fs";import{fileURLToPath as Qt}from"node:url";import Ve from"node:os";import Ie from"node:path";var Je="phc_rDzmwduU3NzHyELgLEg7nMjqpTgaSpC2a6tMKL8VyjN",Ze="https://t.aspect.inc",et="https://t.aspect.inc";function tt(n){let e=n.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);if(!e)return null;let t=parseFloat(e[1]),s=e[2].toUpperCase(),r={B:1,KB:1024,MB:1024*1024,GB:1024*1024*1024,TB:1024*1024*1024*1024};return t*(r[s]||1)}function ke(n){let e=n.options.apiKey||n.environment.ASPECT_API_KEY||"";if(!e)throw new Error("Error: --api-key is required (or set ASPECT_API_KEY env variable)");let t=ue({value:n.options.rcloneTransfers,optionName:"--rclone-transfers"}),s=ue({value:n.options.rcloneMultiThreadStreams,optionName:"--rclone-multi-thread-streams"}),r=ue({value:n.options.uploadConcurrent,optionName:"--upload-concurrent"}),i=st(n.options.batchSize),o=n.options.session??rt({now:n.now??new Date,highResolutionTime:n.highResolutionTime??process.hrtime.bigint()}),a=n.options.tempDir||Ie.join(Ve.homedir(),".aspect","sync");return{remote:n.options.remote,remotePath:n.options.path,directoryId:n.options.directoryId,projectId:n.options.projectId,apiUrl:n.options.apiUrl||n.environment.ASPECT_API_URL||"https://api.aspect.inc",edgeWorkerUrl:n.options.edgeWorkerUrl||n.environment.ASPECT_EDGE_WORKER_URL||"https://mackinac.aspect.inc",apiKey:e,maxConcurrent:r,keepLocal:n.options.keepLocal,localTempDir:Ie.join(a,o),sessionName:o,rcloneOptions:{transfers:t,checkers:t>=16?Math.floor(t/4):t,multiThreadStreams:s,multiThreadChunkSize:n.options.rcloneMultiThreadChunkSize,multiThreadCutoff:n.options.rcloneMultiThreadCutoff,bufferSize:n.options.rcloneBufferSize,useMmap:!n.options.rcloneNoMmap,extraRcloneArgs:n.options.rcloneExtra},batchSizeBytes:i,analytics:{posthogKey:n.environment.ASPECT_POSTHOG_KEY||n.environment.POSTHOG_KEY||n.environment.POSTHOG_API_KEY||Je,posthogHost:n.environment.ASPECT_POSTHOG_HOST||n.environment.POSTHOG_HOST||Ze||et,disabled:ve(n.environment.ASPECT_DISABLE_POSTHOG)||ve(n.environment.POSTHOG_DISABLED)}}}function ue(n){let e=parseInt(n.value,10);if(Number.isNaN(e)||e<1)throw new Error(`Error: ${n.optionName} must be a positive integer`);return e}function st(n){if(!n)return;let e=tt(n);if(e===null)throw new Error(`Error: Invalid batch size format: ${n}`);return e}function ve(n){return n?["1","true","yes"].includes(n.toLowerCase()):!1}function rt(n){let e=n.now.getFullYear(),t=String(n.now.getMonth()+1).padStart(2,"0"),s=String(n.now.getDate()).padStart(2,"0"),r=String(n.now.getHours()).padStart(2,"0"),i=String(n.now.getMinutes()).padStart(2,"0"),o=String(n.now.getSeconds()).padStart(2,"0"),a=n.highResolutionTime%1000000000n,l=String(a).padStart(9,"0");return`${e}-${t}-${s}_${r}h-${i}m-${o}s-${l}ns`}import q from"node:fs/promises";import Ue from"node:path";import{spawn as J}from"child_process";import*as Ae from"fs";import*as H from"path";import U from"node:path";function K(n,e){if(e.length===0)return"queued";if(n.isCreatingFolders)return"creating-folders";let t={queued:0,paused:0,inProgress:0,success:0,failed:0,cancelled:0};for(let r of e)switch(r.status){case"queued":t.queued++;break;case"paused":t.paused++;break;case"in-progress":t.inProgress++;break;case"success":t.success++;break;case"failed":t.failed++;break;case"cancelled":t.cancelled++;break}let s=e.length;return t.failed===s?"all-failed":t.failed>0?"some-failed":t.success===s?"success":t.paused>0&&t.queued===0&&t.inProgress===0?"paused":t.queued>0||t.inProgress>0?t.queued+t.paused===s?"queued":"in-progress":"cancelled"}function ce(n,e){let t=K(n,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function de(n){let e=[];for(let t of Object.values(n))t.chunkedState&&(t.status==="queued"||t.status==="in-progress"||t.status==="paused")&&e.push(t.chunkedState.assetId);return e}function he(n){for(let e of Object.values(n))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function D(n){let t=Object.values(n).reduce((s,r)=>{switch(r.status!=="failed"&&r.status!=="cancelled"&&(s.totalBytesToUpload+=r.totalBytesToUpload,s.totalBytesUploaded+=r.bytesUploaded),s.totalAssetCount+=1,r.status){case"queued":s.queuedAssetCount+=1;break;case"paused":s.pausedAssetCount+=1;break;case"in-progress":s.inProgressAssetCount+=1;break;case"success":s.successAssetCount+=1;break;case"failed":s.failedAssetCount+=1;break;case"cancelled":s.cancelledAssetCount+=1;break}return s},{totalBytesToUpload:0,totalBytesUploaded:0,totalAssetCount:0,queuedAssetCount:0,pausedAssetCount:0,inProgressAssetCount:0,successAssetCount:0,failedAssetCount:0,cancelledAssetCount:0,hasActiveUploads:!1,progress:0});return t.hasActiveUploads=t.totalAssetCount-t.successAssetCount-t.failedAssetCount-t.cancelledAssetCount>0,t.progress=t.hasActiveUploads?t.totalBytesUploaded/t.totalBytesToUpload:0,t}function pe(n,e){if(e.length===0)return null;let t=e.reduce((s,r)=>(r.status!=="failed"&&r.status!=="cancelled"&&(s.totalBytes+=r.totalBytesToUpload,s.uploadedBytes+=r.bytesUploaded),r.status==="success"?s.filesSucceeded++:r.status==="failed"&&s.filesFailed++,(r.status==="success"||r.status==="failed"||r.status==="cancelled")&&s.filesCompleted++,s),{totalBytes:0,uploadedBytes:0,filesCompleted:0,filesSucceeded:0,filesTotal:e.length,filesFailed:0,percentage:0});return t.percentage=t.totalBytes>0?t.uploadedBytes/t.totalBytes*100:0,t}function me(n){let e=Object.values(n).filter(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused");return e.length===0?!1:e.every(t=>t.status==="paused")}function ge(n){return Object.values(n).some(e=>e.status==="paused")}import ls from"axios";var B=class{#t;#s;#e;#n;#o;#i=0;#a=0;#l=0;#r=0;#u=0;#y=0;constructor(e){this.#t=e?.alphaFast??.1,this.#s=e?.alphaMax??.5,this.#e=e?.consecutiveForBoost??3,this.#n=e?.minSamples??3,this.#o=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#r===0){this.#r=t,this.#u=e;return}let r=(t-this.#r)/1e3,i=e-this.#u;if(r<=0||i<0)return;if(r>this.#o){this.#r=t,this.#u=e;return}let o=i/r;if(this.#y===0)this.#i=o;else{let l=o-this.#i>=0?1:-1;this.#l!==0&&l===this.#l?this.#a++:this.#a=0,this.#l=l;let u=Math.min(1,this.#a/this.#e),c=this.#t+(this.#s-this.#t)*u;this.#i=c*o+(1-c)*this.#i}this.#r=t,this.#u=e,this.#y++}etaSeconds(e){return!this.isWarmedUp||this.#i<=0?0:e/this.#i}adjustTotalBytes(e){this.#u+=e}reset(){this.#i=0,this.#a=0,this.#l=0,this.#r=0,this.#u=0,this.#y=0}serialize(){return{displaySpeedBps:this.#i,lastSampleTimestamp:this.#r,lastSampleTotalBytes:this.#u,sampleCount:this.#y}}get speedBps(){return this.#i}get speedMbps(){return this.#i*8/1e6}get isWarmedUp(){return this.#y>=this.#n}};function F(n){let e={"X-Aspect-Share-Id":n.shareId};return n.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=n.shareAuthentication),e}var L=class{#t;#s;#e;#n;#o;#i;#a;#l;#r;#u;#y;#f;#x;#g;#D;#P;#A;#v;#S;#R;#C;#d;#U;#k;#h;#F;#p;#c;#_;#w;#I;#m;#E;constructor(e){this.#s=e?.minConcurrency??1,this.#e=e?.maxConcurrency??8,this.#t=e?.initialConcurrency??this.#s,this.#n=e?.errorThreshold??1,this.#o=(e?.cooldownSeconds??10)*1e3,this.#i=e?.plateauThreshold??.05,this.#a=e?.onChange,this.#l=e?.now??Date.now,this.#r=this.#t,this.#u="probing",this.#y=0,this.#f=0,this.#x=0,this.#g=0,this.#D=!1,this.#P=0,this.#A=0,this.#v=1/0,this.#w=0,this.#I=0,this.#m=0,this.#E=0,this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0,this.#k=0,this.#h=0,this.#F=0,this.#p=0,this.#c=0,this.#_=0}recordSuccess(e,t){if(e<=0)return;if(this.#P>0){this.#P--;return}this.#g++,this.#w+=e;let s=this.#l();if(this.#I===0){this.#I=s;return}let r=s-this.#I;if(r>=200){let c=this.#w/r*1e3;this.#E===0?this.#m=c:this.#m=.3*c+(1-.3)*this.#m,this.#E++,this.#E>=5&&(this.#k=Math.max(this.#k,this.#m)),this.#w=0,this.#I=s}if(t!==void 0&&t>0&&e>0){let c=t/(e/1048576);this.#F===0?this.#h=c:this.#h=.3*c+(1-.3)*this.#h,this.#F++}if(this.#u==="cooldown"&&s>=this.#y&&(this.#u="probing"),this.#u!=="probing")return;if(this.#f>0){let c;if(this.#E>=25?c=.03:this.#E>=15?c=.04:this.#E>=5&&(c=.07),c!==void 0&&(this.#m-this.#f)/this.#f<=-c){this.#c=0,this.#_=0,this.#L();return}}let i=this.#D?this.#r*2:this.#r;if(this.#g<i)return;if(this.#x=0,this.#E<5){this.#g=0;return}let o=this.#S<1/0&&this.#l()<this.#R?this.#S-1:this.#e,a=Math.min(this.#e,this.#v-1,o);if(this.#r>=a){if(this.#S<1/0&&this.#m>0&&this.#d>0){let c=(this.#m-this.#d)/this.#d;if(c>.2){this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0,this.#g=0;return}if(c<=-.07){this.#g=0;return}}if(this.#k>0&&this.#m>0&&this.#E>=5&&(this.#k-this.#m)/this.#k>.07){this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0,this.#k=this.#m,this.#g=0;return}if(this.#U>0&&this.#h>0&&this.#F>=2&&(this.#U-this.#h)/this.#U>.2){this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0,this.#g=0;return}this.#g=0;return}let l=this.#m;if(this.#f>0){let c=Math.max(.02,this.#i*3/this.#r),d=(l-this.#f)/this.#f;if(d<=-.07){this.#c=0,this.#_=0,this.#L();return}else if(d<c){if(this.#F>=2&&this.#p>0){let h=this.#h/this.#p,p=this.#r/(this.#r-1);if(h<p*.9){this.#g=0;return}}if(this.#c++,this.#c<3){this.#g=0;return}this.#c=0,this.#_=0,this.#L();return}else if(d<c*2){if(this.#_++,this.#_<2){this.#g=0;return}this.#c=0,this.#_=0}else this.#c=0,this.#_=0;this.#S<1/0&&(this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0)}this.#p=this.#h,this.#c=0,this.#_=0;let u=this.#r;this.#r++,this.#f=l,this.#g=0,this.#P=Math.max(0,u-1),this.#w=0,this.#I=0,this.#m=0,this.#E=0,this.#h=0,this.#F=0,this.#a?.(this.#r)}#L(){let e=Math.max(this.#s,this.#r-1);e<this.#r&&(this.#S=Math.min(this.#S,this.#r),this.#R=this.#l()+this.#C,this.#C=Math.min(this.#C*2,12e4),this.#d=this.#f,this.#U=this.#p,this.#r=e,this.#f=0,this.#w=0,this.#I=0,this.#m=0,this.#E=0,this.#h=0,this.#F=0,this.#a?.(this.#r)),this.#g=0}recordError(){if(this.#P>0&&this.#P--,this.#x++,this.#x<this.#n)return;this.#r===this.#A&&(this.#v=Math.min(this.#v,this.#r)),this.#A=this.#r;let e=this.#r;this.#r=Math.max(this.#s,Math.floor(this.#r/2)),this.#u="cooldown",this.#y=this.#l()+this.#o,this.#D=!0,this.#x=0,this.#g=0,this.#P=0,this.#f=0,this.#w=0,this.#I=0,this.#m=0,this.#E=0,this.#h=0,this.#F=0,this.#p=0,this.#c=0,this.#_=0,this.#r!==e&&this.#a?.(this.#r)}get concurrency(){return this.#r}get speedBps(){return this.#m}get latencyMsPerMB(){return this.#h}reset(){this.#r=this.#t,this.#u="probing",this.#y=0,this.#f=0,this.#x=0,this.#g=0,this.#D=!1,this.#P=0,this.#A=0,this.#v=1/0,this.#S=1/0,this.#R=0,this.#C=3e4,this.#d=0,this.#U=0,this.#k=0,this.#h=0,this.#F=0,this.#p=0,this.#c=0,this.#_=0,this.#w=0,this.#I=0,this.#m=0,this.#E=0,this.#a?.(this.#r)}};function xe(n){let e=`[${n}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var fe=xe("transfer");var W=class{uploadAssets={};uploadGroups={};#t=new B;get uploadSpeedState(){return this.#t.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#s(e){e!==0&&this.#t.adjustTotalBytes(-e)}adjustSpeedBaselineForSkippedBytes(e){e!==0&&this.#t.adjustTotalBytes(e)}#e(){Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress")||this.#t.reset()}#n(e){this.dirtyAssetIds.add(e)}#o(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:s,parentId:r,projectId:i,groupId:o,chunkSize:a,shareContext:l}){this.uploadAssets[e]={assetId:e,totalBytesToUpload:t.size,bytesUploaded:0,status:"queued",fileName:t.name,createdAt:new Date().toISOString(),i:Object.keys(this.uploadAssets).length,parentId:r,projectId:i,groupId:o,retryCount:0,chunkSize:a??0,fileReader:t,abortController:s,shareContext:l},this.#n(e)}updateUploadProgress(e,t){let s=this.uploadAssets[e];if(!s||s.status==="paused"||s.status==="cancelled"||s.status==="success"||s.status==="failed")return;let r=t>0&&s.status==="queued"?"in-progress":s.status,i=Math.min(t,s.totalBytesToUpload);s.bytesUploaded=i,s.status=r,this.#n(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#n(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#n(e),this.#e(),this.cleanupOnCompletion(e))}markUploadFailed(e,t){let s=this.uploadAssets[e];if(!s)return;let r=s.bytesUploaded;s.status="failed",s.errorMessage=t,s.bytesUploaded=0,this.#n(e),this.#s(r),this.#e(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let s=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#n(e),this.#s(s),this.#e()}clearAllUploads(){this.uploadAssets={},this.#t.reset()}clearTerminalState(){if(!Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused")){for(let t of Object.keys(this.uploadAssets))delete this.uploadAssets[t];for(let t of Object.keys(this.uploadGroups))delete this.uploadGroups[t];this.#t.reset()}}resetAssetForRetryQueue(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.errorMessage=void 0,t.retryCount=t.retryCount+1,this.#n(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#n(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let s=0;if(t.chunkedState){let{completedChunkIndices:i,chunkSize:o}=t.chunkedState;for(let a of i){let l=a*o,u=Math.min(l+o,t.totalBytesToUpload);s+=u-l}}let r=t.bytesUploaded-s;t.status="paused",t.bytesUploaded=s,this.#n(e),this.#s(r),this.#e(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#n(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#o(e);for(let s of t.assetIds)this.pauseUpload(s)}}unpauseUploadGroup(e){let t=this.uploadGroups[e];t&&(t.isPaused=!1,this.#o(e))}pauseAllUploads(){for(let e of Object.values(this.uploadGroups))e.isCreatingFolders||this.pauseUploadGroup(e.id)}resumeAllUploads(){for(let e of Object.values(this.uploadGroups))e.isPaused&&this.unpauseUploadGroup(e.id)}markUploadCancelled(e){let t=this.uploadAssets[e];if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let s=t.bytesUploaded;t.status="cancelled",this.#n(e),this.#s(s),this.#e(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let s=this.uploadAssets[e];s&&(s.chunkedState=t,this.#n(e))}addCompletedChunkIndex(e,t){let s=this.uploadAssets[e];!s||!s.chunkedState||(s.chunkedState={...s.chunkedState,completedChunkIndices:[...s.chunkedState.completedChunkIndices,t]},this.#n(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#n(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return me(this.uploadAssets)}hasPausedUploads(){return ge(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#l(t)}getUploadSummary(){return D(this.#u())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#l(e)).sort((e,t)=>t.i-e.i)}getGroupAssets(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(s=>this.uploadAssets[s]).filter(Boolean).map(s=>this.#l(s))}getGroupAssetsInternal(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(s=>this.uploadAssets[s]).filter(Boolean)}addUploadGroup(e){let t=crypto.randomUUID();return this.uploadGroups[t]={...e,id:t,fileReaders:new Map},this.#o(t),t}updateUploadGroup(e,t){let s=this.uploadGroups[e];s&&(Object.assign(s,t),this.#o(e))}addAssetToGroup(e,t){let s=this.uploadGroups[e];s&&(s.assetIds.push(t),this.#o(e))}removeUploadGroup(e){let t=this.uploadGroups[e];if(t)for(let s of t.assetIds)delete this.uploadAssets[s],this.#n(s);delete this.uploadGroups[e],this.#o(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#r(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#r(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e);return pe(this.#r(t),s)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e);return s.length>0?K(this.#r(t),s):null}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#l(t))}getActiveUploadGroups(){return Object.values(this.uploadGroups).filter(e=>{let t=this.getUploadGroupStatus(e.id);return t&&["queued","creating-folders","in-progress"].includes(t)}).map(e=>this.#r(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let s=t.groupId;if(s){let i=this.uploadGroups[s];if(i){let o=this.getGroupAssets(s),a=this.#r(i);this.dirtyHistoryGroupIds.add(s),!o.some(u=>u.status==="queued"||u.status==="in-progress")&&!i.completedAt&&(i.completedAt=new Date().toISOString(),this.#o(s))}}let r=this.getUploadSummary();if(r.cancelledAssetCount+r.failedAssetCount+r.successAssetCount===r.totalAssetCount)for(let i of Object.keys(this.uploadAssets)){let o=this.uploadAssets[i];o&&(o.bytesUploaded=0,this.#n(i))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#t.sample(e.totalBytesUploaded);let s=this.#t.isWarmedUp?this.#t.speedMbps:0,r=t&&this.#t.isWarmedUp?this.#t.etaSeconds(e.totalBytesToUpload-e.totalBytesUploaded):0;this.uploadStats={uploadSpeedMbps:s,timeRemainingSeconds:r,formattedSpeed:this.#i(s),formattedTime:this.#a(r)}}#i(e){return!Number.isFinite(e)||e<=0?"Calculating...":e<1?`${(e*1e3).toFixed(0)} Kbps`:`${e.toFixed(1)} Mbps`}#a(e){if(!Number.isFinite(e)||e<=0)return"Calculating...";let t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60);return t>0?`${t}h ${s}m left`:s>0?`${s}m ${r}s left`:`${r}s left`}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e),r=this.#r(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:ce(r,s),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#l({fileReader:e,abortController:t,shareContext:s,...r}){return r}#r({fileReaders:e,...t}){return t}#u(){let e={};for(let[t,s]of Object.entries(this.uploadAssets))e[t]=this.#l(s);return e}#y(){let e={};for(let[t,s]of Object.entries(this.uploadGroups))e[t]=this.#r(s);return e}getSerializableSnapshot(){return{uploadAssets:this.#u(),uploadGroups:this.#y(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let s of this.dirtyAssetIds){let r=this.uploadAssets[s];r&&(e[s]=this.#l(r))}let t={};for(let s of this.dirtyGroupIds){let r=this.uploadGroups[s];r&&(t[s]=this.#r(r))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function ot(n,e){let t=new Date(n).getTime(),s=Date.now();return t-s<=e}var Y=class{#t;#s=new Map;#e=new Map;constructor(e){this.#t=e}seedToken(e,t,s){this.#s.set(e,{token:t,expiresAt:s})}async getToken(e,t){let s=this.#s.get(e);if(s&&!ot(s.expiresAt,3e5))return s.token;let r=this.#e.get(e);if(r)return r;let i=t?F(t):void 0,o=this.#t.post(`/assets/${e}/token`,{},i).then(a=>{if(!a.token)throw new Error("Token refresh failed: no token in response");return this.#s.set(e,{token:a.token,expiresAt:a.token_expires_at}),this.#e.delete(e),a.token}).catch(a=>{throw this.#e.delete(e),a});return this.#e.set(e,o),o}clearCache(e){e?this.#s.delete(e):this.#s.clear()}};var Q=class{#t=[];registerAsset(e){this.#t.push({assetId:e.assetId,totalChunks:e.totalChunks,nextChunkToClaim:0,completedChunkIndices:new Set(e.completedChunkIndices),isPaused:!1})}claimNextChunk(){for(let e of this.#t)if(!e.isPaused)for(;e.nextChunkToClaim<e.totalChunks;){let t=e.nextChunkToClaim;if(e.nextChunkToClaim++,!e.completedChunkIndices.has(t))return{assetId:e.assetId,chunkIndex:t}}return null}markChunkCompleted(e,t){let s=this.#s(e);return s?(s.completedChunkIndices.add(t),s.completedChunkIndices.size>=s.totalChunks):!1}pauseAsset(e){let t=this.#s(e);t&&(t.isPaused=!0)}unpauseAsset(e){let t=this.#s(e);t&&(t.isPaused=!1,this.#e(t))}removeAsset(e){this.#t=this.#t.filter(t=>t.assetId!==e)}hasAsset(e){return this.#t.some(t=>t.assetId===e)}clear(){this.#t=[]}#s(e){return this.#t.find(t=>t.assetId===e)}#e(e){for(let t=0;t<e.totalChunks;t++)if(!e.completedChunkIndices.has(t)){e.nextChunkToClaim=t;return}e.nextChunkToClaim=e.totalChunks}};var at=/[/\\:*?"<>|\x00-\x1F]/g,lt=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function O(n){let e=n.replace(at,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;lt.includes(t.toUpperCase())&&(e=`_${e}`);let s=new TextEncoder;if(s.encode(e).length>255){let r=e.lastIndexOf("."),i=r>0?e.substring(r):"",o=r>0?e.substring(0,r):e,l=255-s.encode(i).length;for(;s.encode(o).length>l&&o.length>0;)o=o.slice(0,-1);e=o+i}return e}var R=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function M(n){return n instanceof R||n instanceof Error&&n.name==="CancelledError"||n instanceof Error&&n.name==="CanceledError"||n instanceof Error&&n.name==="AbortError"}function gt(n){return M(n)||n instanceof Error&&n.name==="NoAuthError"}function ft(n){return new Promise(e=>setTimeout(e,n))}function yt(n){return n instanceof Blob?n.size:n.byteLength}var N=class{#t;#s;#e;#n;#o;#i;#a;#l;#r;#u;#y;#f;#x;#g=null;#D=0;#P=!1;#A=[];#v=new Set;#S=!1;#R=!1;#C=!1;#d=[];#U=!1;#k=!1;#h=new Q;#F=0;#p=new Map;#c=new Map;#_=[];#w=!1;#I=null;#m="keep_both";#E=new Map;#L=null;#b=!1;#B=null;#N=!1;constructor(e){this.#t=e.httpClient,this.#s=new Y(e.httpClient),this.#e=new W,this.#n=e.historyStore??null,this.#o=e.settingsStore??null,this.#i=e.analytics??null,this.#a=e.logger??fe,this.#l=e.onChange??null,this.#r=e.onClear??null,this.#u=e.onSummary??null,this.#y=e.onConcurrencyAdjusted??null,this.#x=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let s=e.adaptiveConcurrencyConfig;this.#B=new L({initialConcurrency:s?.initialConcurrency??Math.min(2,t),minConcurrency:s?.minConcurrency??1,maxConcurrency:s?.maxConcurrency??t,errorThreshold:s?.errorThreshold,cooldownSeconds:s?.cooldownSeconds??10,plateauThreshold:s?.plateauThreshold,onChange:r=>{let i=this.#f;if(this.setMaxConcurrency(r),i===r)return;let o=this.#N?"reset":r>i?"probe_increase":"error_decrease",a=Math.round(this.#B.speedBps/(1024*1024)*100)/100,l=Math.round(this.#B.latencyMsPerMB*100)/100;this.#a.info(`Adaptive concurrency: ${i} \u2192 ${r} (${o}), speed=${a}MB/s, latency=${l}ms/MB`),this.#y?.({previousConcurrency:i,newConcurrency:r,reason:o,speedMbps:a,latencyMsPerMB:l})},now:s?.now}),this.#f=this.#B.concurrency}else this.#f=t;this.#n&&(this.#A=this.#n.load()),this.#o&&(this.#I=this.#o.getBandwidthLimitBps(),this.#m=this.#o.getConflictResolution()),(this.#l||this.#u)&&(this.#g=setInterval(()=>{this.#le()},this.#x)),this.#i&&(this.#L=setInterval(()=>{this.#ce()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),s=!!e.assetId,r;if(s){let o=this.#e.getUploadAsset(t);if(!o)throw new Error(`Cannot retry: asset ${t} not found`);r=o.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");r=e.chunkSize}let i=new AbortController;if(s){if(this.#e.getUploadAsset(t).status==="cancelled")return t;e.resetRetryCount&&this.#e.resetAssetForRetrying(t);let a=this.#e.getUploadAsset(t);a.abortController=i,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#e.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:i,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:r,shareContext:e.shareContext});return this.#d.push(t),this.#G(),this.#T(),t}startGroupUpload(e){this.#e.clearTerminalState();let t=this.#e.addUploadGroup({type:e.type,name:e.name,assetIds:[],fileCount:e.fileCount,folderCount:e.folderCount,topLevelFileCount:e.topLevelFileCount,topLevelFolderCount:e.topLevelFolderCount,isCreatingFolders:!1,isPaused:!1,createdAt:new Date().toISOString(),rootDirectoryId:e.rootDirectoryId,projectId:e.projectId,retryCount:0,conflictResolution:e.conflictResolutionOverride??this.#m});return this.#E.set(t,Date.now()),this.#i?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#e.dirtyHistoryGroupIds.add(t),this.#H(),this.#T(),t}pauseUpload(e){let t=this.#e.getUploadAsset(e);this.#e.pauseUpload(e),this.#d=this.#d.filter(s=>s!==e),this.#h.pauseAsset(e),!this.#b&&t&&this.#i&&this.#i("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#T()}unpauseUpload(e){this.#e.unpauseUpload(e),this.#T()}cancelUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let s=t.fileName,r=t.totalBytesToUpload,i=t.bytesUploaded,o=t.projectId,a=t.chunkedState?.assetId;(t.status==="queued"||t.status==="in-progress")&&t.abortController.abort(),this.#d=this.#d.filter(l=>l!==e),this.#h.removeAsset(e),this.#p.delete(e),this.#c.delete(e),this.#e.markUploadCancelled(e),this.#e.clearChunkedState(e),t.fileReader.close?.(),!this.#b&&this.#i&&this.#i("upload:file_cancelled",{file_name:s,file_size:r,bytes_uploaded:i,project_id:o??""}),this.#T(),this.#O(),this.#G(),this.#q(),a&&(this.#_.push(a),this.#W())}cancelAllUploads(){let e=this.#K();this.#b=!0;try{let s=Object.values(this.#e.uploadAssets).filter(r=>r.status==="queued"||r.status==="in-progress"||r.status==="paused");for(let r of s)this.cancelUpload(r.assetId)}finally{this.#b=!1}this.#i?.("upload:all_cancelled",e)}retryUpload(e){let t=this.#e.getUploadAsset(e);t&&t.status==="failed"&&this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,resetRetryCount:!0,shareContext:t.shareContext})}resumeUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status!=="paused")return;!this.#b&&this.#i&&this.#i("upload:file_resumed",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""});let s=new AbortController;t.abortController=s,this.#e.unpauseUpload(e),this.#h.hasAsset(e)?(this.#h.unpauseAsset(e),this.#T(),this.#O()):this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,shareContext:t.shareContext})}pauseUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let s=this.#b;this.#b=!0,this.#e.pauseUploadGroup(e);for(let r of t.assetIds)this.#d=this.#d.filter(i=>i!==r),this.#h.pauseAsset(r);this.#b=s,this.#b||this.#X(e,t,"upload:group_paused"),this.#T()}unpauseUploadGroup(e){this.#e.unpauseUploadGroup(e),this.#T()}cancelUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let{totalBytes:s,bytesUploaded:r,filesRemaining:i}=this.#Q(t),o=this.#b;this.#b=!0;for(let a of t.assetIds)this.cancelUpload(a);this.#b=o,this.#b||this.#i?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:i,total_bytes:s,bytes_uploaded:r,project_id:t.projectId}),this.#E.delete(e)}resumeUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;this.#b||this.#X(e,t,"upload:group_resumed");let s=this.#b;this.#b=!0,this.#e.unpauseUploadGroup(e);for(let r of t.assetIds){let i=this.#e.getUploadAsset(r);i&&i.status==="paused"&&this.resumeUpload(r)}this.#b=s}retryUploadGroup(e){let t=this.#e.uploadGroups[e];if(t)for(let s of t.assetIds){let r=this.#e.getUploadAsset(s);r&&r.status==="failed"&&this.retryUpload(s)}}setGroupCreatingFolders(e,t){this.#e.updateUploadGroup(e,{isCreatingFolders:t}),this.#T()}addAssetToGroup(e,t){this.#e.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#K();this.#b=!0;try{for(let t of Object.values(this.#e.uploadAssets))t.groupId||this.pauseUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isCreatingFolders||this.pauseUploadGroup(t.id)}finally{this.#b=!1}this.#i?.("upload:all_paused",e),this.#T()}resumeAllUploads(){let e=this.#K();this.#b=!0;try{for(let t of Object.values(this.#e.uploadAssets))!t.groupId&&t.status==="paused"&&this.resumeUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isPaused&&this.resumeUploadGroup(t.id)}finally{this.#b=!1}this.#i?.("upload:all_resumed",e),this.#T()}clearAllUploads(){this.#d=[],this.#h.clear(),this.#p.clear(),this.#c.clear(),this.#e.clearAllUploads(),this.#e.uploadGroups={},this.#B&&(this.#N=!0,this.#B.reset(),this.#N=!1),this.#r?.({all:!0}),this.#u?.(this.#z())}clearHistory(){this.#A=[],this.#n?.clear(),this.#S=!0,this.#v.clear(),this.#C=!0,this.#T()}removeHistoryItem(e){this.#A=this.#A.filter(t=>t.groupId!==e),this.#n?.remove(e),this.#v.add(e),this.#C=!0,this.#T()}removeGroup(e){this.#e.removeUploadGroup(e),this.#A=this.#A.filter(t=>t.groupId!==e),this.#n?.remove(e),this.#v.add(e),this.#C=!0,this.#r?.({groupId:e}),this.#u?.(this.#z()),this.#T()}getHttpClient(){return this.#t}setBandwidthLimit(e){this.#I=e,this.#o?.setBandwidthLimitBps(e),this.#C=!0,this.#T()}getBandwidthLimit(){return this.#I}setConflictResolution(e){this.#m=e,this.#o?.setConflictResolution(e),this.#C=!0,this.#T()}getConflictResolution(){return this.#m}getGroupConflictResolution(e){return this.#e.getUploadGroup(e)?.conflictResolution??this.#m}setMaxConcurrency(e){this.#f=e,this.#O()}#J(){return this.#I===null?null:Math.floor(this.#I/Math.max(1,this.#f))}getSnapshot(){return this.#e.updateUploadStats(),{...this.#e.getSerializableSnapshot(),uploadHistory:[...this.#A??[]],uploadSummary:this.#z(),bandwidthLimitBps:this.#I,conflictResolution:this.#m}}getUploadAsset(e){return this.#e.getSerializableAsset(e)}getUploadSummary(){return this.#z()}getGroupAssets(e){return this.#e.getGroupAssets(e)}getUploadGroupStatus(e){return this.#e.getUploadGroupStatus(e)}getUploadGroupProgress(e){return this.#e.getUploadGroupProgress(e)}hasGroupsCreatingFolders(){return this.#e.hasGroupsCreatingFolders()}areAllUploadsPaused(){return this.#e.areAllUploadsPaused()}hasPausedUploads(){return this.#e.hasPausedUploads()}hasActiveUploads(){return he(this.#e.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return de(this.#e.getSerializableSnapshot().uploadAssets)}async cancelActiveServerUploads(){let e=this.getServerAssetIdsToCancel();if(e.length!==0)try{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}catch{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}}destroy(){this.#R=!0,this.#g&&(clearInterval(this.#g),this.#g=null),this.#L&&(clearInterval(this.#L),this.#L=null),this.#d=[],this.#h.clear();for(let e of Object.values(this.#e.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#G(){this.#k||(this.#k=!0,queueMicrotask(()=>{this.#k=!1,this.#Z()}))}async#Z(){if(!this.#U){for(this.#U=!0;this.#d.length>0&&!(this.#p.size>5);){let e=Math.min(this.#d.length,20-this.#p.size);if(e<=0)break;let t=[],s=[];for(let r=0;r<e&&this.#d.length>0;r++){let i=this.#d[0],o=this.#e.getUploadAsset(i);if(!o||o.status==="cancelled"){this.#d.shift(),r--;continue}if(this.#d.shift(),s.push(i),o.chunkedState)try{this.#ee(i,o),this.#O()}catch(a){M(a)||this.#M(i,a)}else t.push(i)}if(t.length>0){let r=new Map;for(let i of t){let a=this.#e.getUploadAsset(i)?.shareContext?.shareId??"",l=r.get(a);l||(l=[],r.set(a,l)),l.push(i)}for(let i of r.values())try{await this.#te(i)}catch(o){for(let a of i)this.#M(a,o instanceof Error?o:new Error(String(o)))}this.#O()}}this.#U=!1}}#ee(e,t){let s=t.chunkedState,r={serverAssetId:s.assetId,chunkIds:s.chunkIds,chunkSize:s.chunkSize,totalChunks:s.totalChunks,sizeBytes:s.sizeBytes},i=s.completedChunkIndices;this.#p.set(e,r);let o=new Array(r.totalChunks).fill(0);if(i.length>0){for(let l of i){let u=l*r.chunkSize,c=Math.min(u+r.chunkSize,t.totalBytesToUpload);o[l]=c-u}let a=o.reduce((l,u)=>l+u,0);this.#e.updateUploadProgress(e,a)}if(this.#c.set(e,o),r.totalChunks===0||i.length>=r.totalChunks){this.#j(e).catch(a=>{this.#M(e,a)});return}this.#h.registerAsset({assetId:e,totalChunks:r.totalChunks,completedChunkIndices:i})}async#te(e){let t=[],s=[];for(let a of e){let l=this.#e.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let u=O(l.fileName),c=l.groupId?this.#e.getUploadGroup(l.groupId)?.conflictResolution??this.#m:this.#m,d=(()=>{switch(c){case"keep_both":return{auto_rename:"parenthesized"};case"replace":return{conflict_resolution:"replace"};case"skip":return{conflict_resolution:"skip"}}})();t.push({directory_id:l.parentId,id:a,name:u,size_bytes:l.totalBytesToUpload,...d}),s.push(a)}if(t.length===0)return;let r=this.#e.getUploadAsset(s[0]),i=r?.shareContext?F(r.shareContext):void 0,o=await this.#t.post("/assets/chunked/initiate",t,i);for(let a=0;a<s.length;a++){let l=s[a],u=o[a];if(!u||u.error){this.#M(l,new Error(u?.error??"Unknown batch initiation error"));continue}if(u.skipped){let g=this.#e.getUploadAsset(l);g&&(this.#e.adjustSpeedBaselineForSkippedBytes(g.totalBytesToUpload),this.#e.markUploadSuccess(l),this.#e.dirtyHistoryGroupIds.add(g.groupId??""),this.#H(),g.fileReader.close?.());continue}let c=u.result,d=this.#e.getUploadAsset(l);if(!d||d.status==="cancelled"||d.status==="paused"){(!d||d.status==="cancelled")&&(this.#_.push(c.asset_id),this.#W());continue}let h=Math.ceil(d.totalBytesToUpload/c.chunk_size),p=Array.from({length:h},()=>crypto.randomUUID());this.#s.seedToken(c.asset_id,c.token,c.token_expires_at);let m={serverAssetId:c.asset_id,chunkIds:p,chunkSize:c.chunk_size,totalChunks:h,sizeBytes:d.totalBytesToUpload};this.#e.setChunkedState(l,{assetId:m.serverAssetId,chunkIds:m.chunkIds,completedChunkIndices:[],chunkSize:m.chunkSize,totalChunks:m.totalChunks,sizeBytes:m.sizeBytes}),this.#p.set(l,m);let C=new Array(m.totalChunks).fill(0);if(this.#c.set(l,C),m.totalChunks===0){this.#j(l).catch(g=>{this.#M(l,g)});continue}this.#h.registerAsset({assetId:l,totalChunks:m.totalChunks,completedChunkIndices:[]})}}#O(){if(!this.#R)for(;this.#F<this.#f;){let e=this.#h.claimNextChunk();if(!e)break;this.#F++;let{assetId:t,chunkIndex:s}=e;this.#se(t,s).then(r=>{this.#F--,this.#ne(t,s,r),this.#O()}).catch(r=>{if(this.#F--,M(r)){this.#O();return}this.#ie(t,s,r),this.#O()})}}async#se(e,t){let s;for(let r=0;r<3;r++)try{let i=this.#c.get(e);return i&&(i[t]=0,this.#$(e)),await this.#re(e,t)}catch(i){if(M(i))throw i;if(s=i instanceof Error?i:new Error(String(i)),this.#B?.recordError(),this.#oe(e,t,s,r),r===2)throw s;let o=this.#c.get(e);o&&(o[t]=0,this.#$(e));let a=1e3*Math.pow(2,r);await ft(a)}throw s||new Error("Unknown error during chunk upload")}async#re(e,t){let s=this.#e.getUploadAsset(e);if(!s)throw new R;if(s.abortController.signal.aborted)throw new R;let r=this.#p.get(e);if(!r)throw new Error(`No chunk metadata for asset ${e}`);let i=t*r.chunkSize,o=Math.min(i+r.chunkSize,s.totalBytesToUpload),a=await s.fileReader.readChunk(i,o),l=yt(a);if(s.abortController.signal.aborted)throw new R;let u=r.chunkIds[t],c=await this.#s.getToken(r.serverAssetId,s.shareContext),d=`/uploads/chunks/${u}`,h=Date.now(),p=await this.#t.putWithToken(d,a,c,{signal:s.abortController.signal,onProgress:g=>{let A=this.#c.get(e);A&&(A[t]=g,this.#$(e))},contentType:"application/octet-stream",getMaxUploadRate:()=>this.#J()}),m=Date.now()-h;if(!p.status||p.status<200||p.status>=300)throw this.#a.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:u,assetId:e,serverAssetId:r.serverAssetId,chunkSizeBytes:l,durationMs:m,httpStatus:p.status,statusText:p.statusText,responseBody:p.data,responseHeaders:p.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${p.status}`);let C=this.#c.get(e);return C&&(C[t]=l,this.#$(e)),m}#$(e){let t=this.#c.get(e);if(!t)return;let s=t.reduce((r,i)=>r+i,0);this.#e.updateUploadProgress(e,s)}#ne(e,t,s){if(this.#B){let i=this.#p.get(e);if(i){let o=t*i.chunkSize,l=Math.min(o+i.chunkSize,i.sizeBytes)-o;this.#B.recordSuccess(l,s)}}this.#e.addCompletedChunkIndex(e,t),this.#h.markChunkCompleted(e,t)&&this.#j(e).catch(i=>{this.#M(e,i)})}#ie(e,t,s){this.#M(e,s)}#oe(e,t,s,r){if(!this.#i)return;let i=this.#e.getUploadAsset(e);if(!i)return;let o=this.#p.get(e);if(!o)return;let a=t*o.chunkSize,u=Math.min(a+o.chunkSize,o.sizeBytes)-a,c=s,d=typeof c.code=="string"?c.code:null,h=c.response?.status,p=typeof h=="number"?h:null,m=s.cause?s.cause instanceof Error?s.cause.message:String(s.cause):null;this.#i("upload:chunk_error",{file_name:i.fileName,file_size:i.totalBytesToUpload,chunk_index:t,chunk_size:u,chunks_total:o.totalChunks,attempt:r+1,max_attempts:3,is_final_attempt:r===2,error_type:s.name,error_message:s.message,error_code:d,http_status:p,error_stack:s.stack??null,error_cause:m,project_id:i.projectId??""})}#ae(e,t,s,r){if(!this.#i||M(t))return;let i=t instanceof Error?t.message:"Unknown error",o=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof o.code=="string"?o.code:null,u=o.response?.status,c=typeof u=="number"?u:null,d=this.#p.get(e.assetId);this.#i("upload:file_error",{file_name:e.fileName,file_size:e.totalBytesToUpload,bytes_uploaded:e.bytesUploaded,chunks_completed:e.chunkedState?.completedChunkIndices.length??0,chunks_total:d?.totalChunks??0,attempt:s+1,max_attempts:4,is_final_attempt:r,error_type:t instanceof Error?t.name:"Unknown",error_message:i,error_code:l,http_status:c,error_stack:t instanceof Error?t.stack??null:null,error_cause:a,project_id:e.projectId??""})}async#j(e){let t=this.#e.getUploadAsset(e);if(!t)return;let s=this.#p.get(e);if(!s)return;if(t.abortController.signal.aborted)throw new R;let r=crypto.randomUUID(),i=JSON.stringify(s.chunkIds),o=new TextEncoder().encode(i),a=await this.#s.getToken(s.serverAssetId,t.shareContext),l=`/uploads/manifests/${r}`;try{await this.#t.putWithToken(l,o,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(u){throw this.#a.error("Manifest upload failed",{assetId:e,serverAssetId:s.serverAssetId,manifestId:r},u),u}if(t.abortController.signal.aborted)throw new R;try{let u=t.shareContext?F(t.shareContext):void 0;await this.#t.post(`/assets/${s.serverAssetId}/revisions/commit`,{manifest_id:r,size_bytes:s.sizeBytes,is_initial_upload:!0,client_performed_at:new Date().toISOString()},u)}catch(u){throw this.#a.error("Commit revision failed",{assetId:e,serverAssetId:s.serverAssetId,manifestId:r,sizeBytes:s.sizeBytes},u),u}this.#e.markUploadSuccess(e),this.#e.clearChunkedState(e),this.#H(),this.#T(),this.#p.delete(e),this.#c.delete(e),this.#h.removeAsset(e),await t.fileReader.close?.(),this.#V(e),this.#G(),this.#q()}#M(e,t){let s=this.#e.getUploadAsset(e);if(!s||s.status==="paused"||s.status==="cancelled")return;let r=s.retryCount,i=r>=3||gt(t);if(this.#ae(s,t,r,i),i){let o=t instanceof Error?t.message:"Unknown error";this.#a.error("Asset upload permanently failed",{assetId:e,fileName:s.fileName,totalRetries:r,bytesUploaded:s.bytesUploaded,totalBytes:s.totalBytesToUpload,chunksCompleted:s.chunkedState?.completedChunkIndices.length??0},t),s.abortController.abort(),this.#e.markUploadFailed(e,o),this.#h.removeAsset(e),this.#p.delete(e),this.#c.delete(e),this.#H(),this.#T(),this.#V(e),this.#G(),this.#q()}else{this.#a.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:s.fileName,retryAttempt:r+1,maxRetries:3},t);let o=s.chunkedState;s.abortController.abort(),this.#h.removeAsset(e),this.#p.delete(e),this.#c.delete(e),this.#e.resetAssetForRetryQueue(e),this.#T(),this.#G();let a=2e3*Math.pow(2,r);setTimeout(()=>{if(this.#R)return;let l=this.#e.getUploadAsset(e);!l||l.status!=="queued"||this.startUpload({fileReader:l.fileReader,directoryId:l.parentId??"",projectId:l.projectId,groupId:l.groupId,assetId:e,resumeChunked:o,shareContext:l.shareContext})},a)}}#q(){this.#B&&(this.hasActiveUploads()||(this.#N=!0,this.#B.reset(),this.#N=!1))}#W(){this.#w||(this.#w=!0,queueMicrotask(()=>{this.#w=!1;let e=this.#_.splice(0);e.length!==0&&this.#t.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#a.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#z(){return D(this.#e.getSerializableSnapshot().uploadAssets)}#T(){this.#P||(this.#P=!0,queueMicrotask(()=>{this.#P=!1,this.#ue()}))}#le(){this.#Y(!0)}#ue(){this.#Y(!1)}#Y(e){if(this.#R||!this.#l&&!this.#u)return;e?this.#e.updateUploadStats():(this.#D++,this.#D%3===0&&this.#e.updateUploadStats());let t=this.#e.getDirtyDelta();if(!this.#C&&Object.keys(t.assets).length===0&&Object.keys(t.groups).length===0&&this.#e.dirtyHistoryGroupIds.size===0)return;this.#C=!1,this.#e.dirtyHistoryGroupIds.size>0&&this.#H();let r=this.#e.dirtyHistoryGroupIds.size>0?this.#de():void 0,i=this.#S?!0:void 0,o=this.#v.size>0?[...this.#v]:void 0;this.#S=!1,this.#v.clear();let a=this.#z(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#e.uploadStats},uploadSpeedState:this.#e.uploadSpeedState,historyItems:r,removedHistoryGroupIds:o,historyCleared:i,uploadSummary:a,bandwidthLimitBps:this.#I,conflictResolution:this.#m};this.#e.clearDirtyFlags(),this.#l?.(l),this.#u?.(a)}#Q(e){let t=0,s=0,r=0;for(let i of e.assetIds){let o=this.#e.getUploadAsset(i);o&&(t+=o.totalBytesToUpload,s+=o.bytesUploaded,o.status!=="success"&&o.status!=="failed"&&o.status!=="cancelled"&&r++)}return{totalBytes:t,bytesUploaded:s,filesRemaining:r}}#K(){let e=0,t=0,s=0,r=0;for(let i of Object.values(this.#e.uploadGroups)){e++;for(let o of i.assetIds){let a=this.#e.getUploadAsset(o);a&&(a.status==="success"||a.status==="failed"||a.status==="cancelled"||(t++,s+=a.totalBytesToUpload,r+=a.bytesUploaded))}}return{group_count:e,file_count:t,total_bytes:s,bytes_uploaded:r}}#ce(){if(!(!this.#i||this.#R))for(let e of Object.values(this.#e.uploadGroups)){let t=!1,s=0,r=0,i=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0;for(let C of e.assetIds){let g=this.#e.getUploadAsset(C);if(!g)continue;let A=g.totalBytesToUpload;switch(s+=A,r+=g.bytesUploaded,g.status){case"success":i++,o+=A;break;case"failed":a++,l+=A;break;case"cancelled":u++,c+=A;break;case"in-progress":d++,t=!0;break;case"queued":h++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let p=this.#E.get(e.id),m=p?Date.now()-p:0;this.#i("upload:group_progress",{group_id:e.id,file_count:e.assetIds.length,total_bytes:s,bytes_uploaded:r,duration_ms:m,project_id:e.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:u,cancelled_bytes:c,in_progress_count:d,queued_count:h,progress:s>0?r/s:0,concurrency:this.#f,upload_speed_mbps:this.#e.uploadStats.uploadSpeedMbps})}}#X(e,t,s){if(!this.#i)return;let{totalBytes:r,bytesUploaded:i}=this.#Q(t);this.#i(s,{file_count:t.fileCount,total_bytes:r,bytes_uploaded:i,project_id:t.projectId})}#V(e){if(!this.#i)return;let t=this.#e.getUploadAsset(e);if(!t?.groupId)return;let s=this.#e.uploadGroups[t.groupId];if(!s)return;let r=!0,i=0,o=0,a=0,l=0,u=0,c=0,d=0;for(let m of s.assetIds){let C=this.#e.getUploadAsset(m);if(!C)continue;let g=C.totalBytesToUpload;if(d+=g,C.status==="success")i++,o+=g;else if(C.status==="failed")a++,l+=g;else if(C.status==="cancelled")u++,c+=g;else{r=!1;break}}if(!r)return;let h=this.#E.get(s.id),p=h?Date.now()-h:0;this.#i("upload:group_completed",{file_count:s.assetIds.length,total_bytes:d,duration_ms:p,project_id:s.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:u,cancelled_bytes:c}),this.#E.delete(s.id)}#de(){let e={};for(let t of this.#e.dirtyHistoryGroupIds){let s=this.#e.buildHistoryItem(t);s&&(e[t]=s)}return e}#H(){if(!this.#n)return;let e={};for(let t of this.#e.dirtyHistoryGroupIds){let s=this.#e.buildHistoryItem(t);if(s){e[t]=s;let r=this.#A.findIndex(i=>i.groupId===t);r>=0?this.#A[r]=s:this.#A.unshift(s)}}Object.keys(e).length>0&&this.#n.merge(e)}};var G=class{#t=65536;#s=0;async*createIterator(e,t,s){let r=0,i=Math.max(65536,Math.min(e.byteLength,this.#t)),o=this.#s;for(;r<e.byteLength;){if(s?.aborted)return;let a=Math.min(r+i,e.byteLength),l=e.subarray(r,a),u=l.byteLength,c=performance.now();yield l;let d=performance.now()-c;r=a;let h=t();if(h!==null&&h>0){let p=Math.round(h*50/1e3);if(i=Math.max(65536,Math.min(e.byteLength,p)),r<e.byteLength){let C=u/h*1e3-d;C>1&&await new Promise(g=>setTimeout(g,C))}}else{if(d>=.5){let p=u/d*1e3;o=o===0?p:o*(1-.3)+p*.3}else o===0&&(i=Math.min(e.byteLength,i*2));if(o>0){let p=Math.round(o*50/1e3);i=Math.max(65536,Math.min(e.byteLength,p))}}this.#t=i,this.#s=o}}};function b(n){let e=n.replace(/\\/g,"/");if(e.split("/").some(i=>i===".."))throw new Error(`Remote path cannot contain parent directory segments: ${n}`);let r=U.posix.normalize(e).replace(/^\/+/,"");if(r===""||r===".")throw new Error(`Remote path must resolve to a file path: ${n}`);return r}function we(n){let e=new Map;for(let i of n){let o=b(i.targetPath??i.path);e.set(o,(e.get(o)??0)+1)}let t=new Set,s=[],r=[];for(let i of n){let o=b(i.path),a=b(i.targetPath??i.path),l=z(a),u=Se(l,t),c=(e.get(a)??0)>1,d=u!==o;t.add(u),s.push({...i,targetPath:u,requiresIdentityDownload:i.requiresIdentityDownload===!0||c}),(d||c)&&r.push({sourcePath:i.path,targetPath:u,reason:c||u!==l?"duplicate":"sanitized"})}return{files:s,changes:r}}function k(n){return b(n.targetPath??n.path)}function De(n,e){let t=k(n);return{relativePath:t,absolutePath:U.join(e,t),fileName:U.posix.basename(t),size:n.size}}function z(n){return n.split("/").map(t=>O(t)).join("/")}function Se(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),s=U.posix.basename(n),r=U.posix.extname(s),i=r.length>0?s.slice(0,-r.length):s,o=2;for(;;){let a=`${i} (${o})${r}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;o+=1}}function Ce(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),s=U.posix.basename(n),r=2;for(;;){let i=`${s} ${r}`,o=t==="."?i:`${t}/${i}`;if(!e.has(o))return o;r+=1}}var T=class extends Error{constructor(t,s){super(t);this.stderr=s;this.name="RcloneError"}stderr};function St(n){let e=["sync",n.remoteSource,n.localPath];return n.batchFilePath&&e.push("--files-from",n.batchFilePath),e.push("--progress","--stats","1s","--stats-one-line","-v","--transfers",String(n.rcloneOptions.transfers),"--checkers",String(n.rcloneOptions.checkers),"--multi-thread-streams",String(n.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",n.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",n.rcloneOptions.multiThreadCutoff,"--fast-list","--buffer-size",n.rcloneOptions.bufferSize),n.rcloneOptions.useMmap&&e.push("--use-mmap"),n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function Ct(n){let e=["lsjson",n.remoteSource,"--recursive","--fast-list"];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function bt(n){let e=["backend","query",`${n.remote}:`,n.query];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function At(n){let e=["copyto",n.remoteFileSource,n.localTargetPath,"--progress","--stats","1s","--stats-one-line","-v","--multi-thread-streams",String(n.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",n.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",n.rcloneOptions.multiThreadCutoff,"--buffer-size",n.rcloneOptions.bufferSize];return n.rcloneOptions.useMmap&&e.push("--use-mmap"),n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function Et(n){let e=["backend","copyid",`${n.remote}:`,n.fileId,n.localTargetPath];return n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function _(n,e){let t=e.trim(),s={B:1,k:1024,Ki:1024,KiB:1024,kB:1e3,M:1024*1024,Mi:1024*1024,MiB:1024*1024,MB:1e3*1e3,G:1024*1024*1024,Gi:1024*1024*1024,GiB:1024*1024*1024,GB:1e3*1e3*1e3,T:1024*1024*1024*1024,Ti:1024*1024*1024*1024,TiB:1024*1024*1024*1024,TB:1e3*1e3*1e3*1e3};return n*(s[t]||1)}function Be(n){let e=0,t=n.match(/(\d+)h/),s=n.match(/(\d+)m/),r=n.match(/(\d+)s/);return t&&(e+=parseInt(t[1],10)*3600),s&&(e+=parseInt(s[1],10)*60),r&&(e+=parseInt(r[1],10)),e}function Tt(n){let e=n.trim(),t=/^([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%?,\s*([\d.]+)\s*([A-Za-z]+)\/s,\s*ETA\s+(.+)$/,s=e.match(t);if(s){let a=s[8].trim();return{bytesTransferred:_(parseFloat(s[1]),s[2]),totalBytes:_(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:_(parseFloat(s[6]),s[7]),eta:a==="-"?0:Be(a)}}let r=e.match(/Transferred:\s+([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%/);if(!r)return null;let i=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),o=e.match(/ETA\s+([^\s]+)$/);return{bytesTransferred:_(parseFloat(r[1]),r[2]),totalBytes:_(parseFloat(r[3]),r[4]),percentComplete:parseFloat(r[5]),speed:i?_(parseFloat(i[1]),i[2]):0,eta:o&&o[1]!=="-"?Be(o[1]):0}}function be(n){return new Promise((e,t)=>{let s=J("rclone",n.args,{stdio:["ignore","pipe","pipe"]}),r="",i=0,o=a=>{for(let l of a.split(`
|
|
3
|
-
`)){if(l.trim().length===0)continue;let u=Tt(l);if(!u)continue;let c=Date.now();!(u.percentComplete>=100)&&c-i<500||(i=c,n.onProgress?.(u))}};s.stdout.on("data",a=>{o(a.toString())}),s.stderr.on("data",a=>{let l=a.toString();r+=l,o(l)}),s.on("close",async a=>{a===0?e():t(new T(`rclone exited with code ${a}`,r))}),s.on("error",a=>{t(new T(`Failed to start rclone: ${a.message}`,""))})})}async function Ee(){return new Promise((n,e)=>{let t=J("rclone",["version"]);t.on("error",()=>{e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))}),t.on("close",s=>{s===0?n():e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))})})}async function Rt(n,e,t,s,r,i){let o=`${n}:${e}`;return be({args:St({remoteSource:o,localPath:t,rcloneOptions:r,batchFilePath:s}),remoteSource:o,onProgress:i})}async function Z(n,e,t=[]){let s=`${n}:${e}`;return new Promise((r,i)=>{let o=J("rclone",Ct({remoteSource:s,extraArgs:t})),a="",l="";o.stdout.on("data",u=>{a+=u.toString()}),o.stderr.on("data",u=>{l+=u.toString()}),o.on("close",async u=>{if(u===0)try{let c=JSON.parse(a||"[]");if(!Array.isArray(c))throw new Error("rclone lsjson did not return an array");let d=Ut(c),h=await Pt({remote:n,files:d.files,directories:d.directories,extraArgs:t});r(h)}catch(c){i(new T(`Failed to parse file listing from ${s}: ${c instanceof Error?c.message:String(c)}`,l))}else i(new T(`Failed to list files from ${s}`,l))}),o.on("error",u=>{i(new T(`Failed to start rclone: ${u.message}`,""))})})}async function Le(n){let e=[],t=[];for(let s of n.files)xt(s)?t.push(s):e.push(s);e.length>0&&(await Ae.promises.writeFile(n.batchFilePath,`${e.map(s=>s.path).join(`
|
|
2
|
+
import{Command as Rs}from"commander";import ut from"node:path";import{readFileSync as Ts}from"node:fs";import{fileURLToPath as Ps}from"node:url";import ht from"node:fs";import pt from"node:os";import N from"node:path";var mt="phc_rDzmwduU3NzHyELgLEg7nMjqpTgaSpC2a6tMKL8VyjN",gt="https://t.aspect.inc",ft="https://t.aspect.inc";function yt(n){let e=n.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);if(!e)return null;let t=parseFloat(e[1]),s=e[2].toUpperCase(),r={B:1,KB:1024,MB:1024*1024,GB:1024*1024*1024,TB:1024*1024*1024*1024};return t*(r[s]||1)}function $e(n){let e=n.options.apiKey||n.environment.ASPECT_API_KEY||"";if(!e)throw new Error("Error: --api-key is required (or set ASPECT_API_KEY env variable)");let t=Z({value:n.options.uploadConcurrent,optionName:"--upload-concurrent"}),s=Tt(n.options.batchSize),r=n.options.session??Pt({now:n.now??new Date,highResolutionTime:n.highResolutionTime??process.hrtime.bigint()}),i=n.options.tempDir||N.join(pt.homedir(),".aspect","sync"),o=N.join(i,r);return{source:St({options:n.options,environment:n.environment,localTempDir:o}),directoryId:n.options.directoryId,projectId:n.options.projectId,apiUrl:n.options.apiUrl||n.environment.ASPECT_API_URL||"https://api.aspect.inc",edgeWorkerUrl:n.options.edgeWorkerUrl||n.environment.ASPECT_EDGE_WORKER_URL||"https://mackinac.aspect.inc",apiKey:e,maxConcurrent:t,keepLocal:n.options.keepLocal,localTempDir:o,sessionName:r,batchSizeBytes:s,analytics:{posthogKey:n.environment.ASPECT_POSTHOG_KEY||n.environment.POSTHOG_KEY||n.environment.POSTHOG_API_KEY||mt,posthogHost:n.environment.ASPECT_POSTHOG_HOST||n.environment.POSTHOG_HOST||gt||ft,disabled:Ge(n.environment.ASPECT_DISABLE_POSTHOG)||Ge(n.environment.POSTHOG_DISABLED)}}}function St(n){let e=n.options.source;switch(e){case"rclone":return Ct(n.options);case"local":return bt(n.options);case"lucidlink":return At({options:n.options,environment:n.environment,localTempDir:n.localTempDir});default:throw new Error(`Error: unknown --source "${e}". Supported sources: rclone, local, lucidlink`)}}function Ct(n){if(!n.remote)throw new Error("Error: --remote is required when using --source rclone");let e=Z({value:n.rcloneTransfers,optionName:"--rclone-transfers"}),t=Z({value:n.rcloneMultiThreadStreams,optionName:"--rclone-multi-thread-streams"});return{kind:"rclone",remote:n.remote,remotePath:n.path,rcloneOptions:{transfers:e,checkers:e>=16?Math.floor(e/4):e,multiThreadStreams:t,multiThreadChunkSize:n.rcloneMultiThreadChunkSize,multiThreadCutoff:n.rcloneMultiThreadCutoff,bufferSize:n.rcloneBufferSize,useMmap:!n.rcloneNoMmap,extraRcloneArgs:n.rcloneExtra}}}function bt(n){return{kind:"local",rootPath:N.resolve(n.path)}}function At(n){let e=n.options.lucidFs;if(!e)throw new Error("Error: --lucid-fs is required when using --source lucidlink");let t=n.options.lucidUser;if(!t)throw new Error("Error: --lucid-user is required when using --source lucidlink");let s=Et({passwordFile:n.options.lucidPasswordFile,environment:n.environment}),r=Z({value:n.options.lucidInstance,optionName:"--lucid-instance"}),i=`${n.localTempDir}-lucid`;return{kind:"lucidlink",filespace:e,user:t,password:s,filespacePath:Rt(n.options.path),instanceId:r,workDir:i,mountPoint:N.join(i,"mnt"),cacheRootPath:N.join(i,"cache"),cacheSize:n.options.lucidCacheSize}}function Et(n){if(n.passwordFile){let t=ht.readFileSync(n.passwordFile,"utf-8").replace(/\r?\n$/,"");if(t.length===0)throw new Error(`Error: LucidLink password file is empty: ${n.passwordFile}`);return t}let e=n.environment.LUCID_PASSWORD;if(e)return e;throw new Error("Error: LucidLink password is required. Provide --lucid-password-file or set LUCID_PASSWORD.")}function Rt(n){let e=n.replace(/^\/+/,"").replace(/\/+$/,"");if(e.split("/").some(t=>t===".."))throw new Error(`Error: --path cannot contain parent directory segments: ${n}`);return e}function Z(n){let e=parseInt(n.value,10);if(Number.isNaN(e)||e<1)throw new Error(`Error: ${n.optionName} must be a positive integer`);return e}function Tt(n){if(!n)return;let e=yt(n);if(e===null)throw new Error(`Error: Invalid batch size format: ${n}`);return e}function Ge(n){return n?["1","true","yes"].includes(n.toLowerCase()):!1}function Pt(n){let e=n.now.getFullYear(),t=String(n.now.getMonth()+1).padStart(2,"0"),s=String(n.now.getDate()).padStart(2,"0"),r=String(n.now.getHours()).padStart(2,"0"),i=String(n.now.getMinutes()).padStart(2,"0"),o=String(n.now.getSeconds()).padStart(2,"0"),a=n.highResolutionTime%1000000000n,l=String(a).padStart(9,"0");return`${e}-${t}-${s}_${r}h-${i}m-${o}s-${l}ns`}import X from"node:fs/promises";import Ne from"node:path";import Ut from"fs/promises";import Ft from"path";function He(n,e){let t=new Map;for(let u of n){let c=Ft.dirname(u.targetPath??u.path);t.has(c)||t.set(c,[]),t.get(c).push(u)}let s=new Map;for(let[u,c]of t.entries()){let d=c.reduce((p,g)=>p+g.size,0);s.set(u,d)}let r=Array.from(t.keys()).sort(),i=[],o=[],a=0,l=1;for(let u of r){let c=t.get(u),d=s.get(u);if(d>e){if(o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),c.length===1)i.push({batchNumber:l++,files:c,totalSize:d});else for(let p of c)a+p.size>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(p),a+=p.size;continue}a+d>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(...c),a+=d}return o.length>0&&i.push({batchNumber:l++,files:o,totalSize:a}),i}async function je(n){try{await Ut.unlink(n)}catch(e){if(e.code!=="ENOENT")throw e}}import m from"chalk";import Ke from"log-update";function ee(n,e){if(e.length===0)return n.finalizedStatus?n.finalizedStatus:n.isCreatingFolders?"creating-folders":"queued";if(n.isCreatingFolders)return"creating-folders";let t={queued:0,paused:0,inProgress:0,success:0,failed:0,cancelled:0};for(let r of e)switch(r.status){case"queued":t.queued++;break;case"paused":t.paused++;break;case"in-progress":t.inProgress++;break;case"success":t.success++;break;case"failed":t.failed++;break;case"cancelled":t.cancelled++;break}let s=e.length;return t.failed===s?"all-failed":t.failed>0?"some-failed":t.success===s?"success":t.paused>0&&t.queued===0&&t.inProgress===0?"paused":t.queued>0||t.inProgress>0?t.queued+t.paused===s?"queued":"in-progress":"cancelled"}function Ee(n,e){let t=ee(n,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function Re(n){let e=[];for(let t of Object.values(n))t.chunkedState&&(t.status==="queued"||t.status==="in-progress"||t.status==="paused")&&e.push(t.chunkedState.assetId);return e}function Te(n){for(let e of Object.values(n))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function G(n){let t=Object.values(n).reduce((s,r)=>{switch(r.status!=="failed"&&r.status!=="cancelled"&&(s.totalBytesToUpload+=r.totalBytesToUpload,s.totalBytesUploaded+=r.bytesUploaded),s.totalAssetCount+=1,r.status){case"queued":s.queuedAssetCount+=1;break;case"paused":s.pausedAssetCount+=1;break;case"in-progress":s.inProgressAssetCount+=1;break;case"success":s.successAssetCount+=1;break;case"failed":s.failedAssetCount+=1;break;case"cancelled":s.cancelledAssetCount+=1;break}return s},{totalBytesToUpload:0,totalBytesUploaded:0,totalAssetCount:0,queuedAssetCount:0,pausedAssetCount:0,inProgressAssetCount:0,successAssetCount:0,failedAssetCount:0,cancelledAssetCount:0,hasActiveUploads:!1,progress:0});return t.hasActiveUploads=t.totalAssetCount-t.successAssetCount-t.failedAssetCount-t.cancelledAssetCount>0,t.progress=t.hasActiveUploads?t.totalBytesUploaded/t.totalBytesToUpload:0,t}function Pe(n,e){if(e.length===0)return null;let t=e.reduce((s,r)=>(r.status!=="failed"&&r.status!=="cancelled"&&(s.totalBytes+=r.totalBytesToUpload,s.uploadedBytes+=r.bytesUploaded),r.status==="success"?s.filesSucceeded++:r.status==="failed"&&s.filesFailed++,(r.status==="success"||r.status==="failed"||r.status==="cancelled")&&s.filesCompleted++,s),{totalBytes:0,uploadedBytes:0,filesCompleted:0,filesSucceeded:0,filesTotal:e.length,filesFailed:0,percentage:0});return t.percentage=t.totalBytes>0?t.uploadedBytes/t.totalBytes*100:0,t}function Ue(n){let e=Object.values(n).filter(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused");return e.length===0?!1:e.every(t=>t.status==="paused")}function Fe(n){return Object.values(n).some(e=>e.status==="paused")}import js from"axios";var $=class{#t;#s;#e;#r;#n;#i=0;#a=0;#u=0;#o=0;#c=0;#m=0;constructor(e){this.#t=e?.alphaFast??.1,this.#s=e?.alphaMax??.5,this.#e=e?.consecutiveForBoost??3,this.#r=e?.minSamples??3,this.#n=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#o===0){this.#o=t,this.#c=e;return}let r=(t-this.#o)/1e3,i=e-this.#c;if(r<=0||i<0)return;if(r>this.#n){this.#o=t,this.#c=e;return}let o=i/r;if(this.#m===0)this.#i=o;else{let l=o-this.#i>=0?1:-1;this.#u!==0&&l===this.#u?this.#a++:this.#a=0,this.#u=l;let u=Math.min(1,this.#a/this.#e),c=this.#t+(this.#s-this.#t)*u;this.#i=c*o+(1-c)*this.#i}this.#o=t,this.#c=e,this.#m++}etaSeconds(e){return!this.isWarmedUp||this.#i<=0?0:e/this.#i}adjustTotalBytes(e){this.#c+=e}reset(){this.#i=0,this.#a=0,this.#u=0,this.#o=0,this.#c=0,this.#m=0}serialize(){return{displaySpeedBps:this.#i,lastSampleTimestamp:this.#o,lastSampleTotalBytes:this.#c,sampleCount:this.#m}}get speedBps(){return this.#i}get speedMbps(){return this.#i*8/1e6}get isWarmedUp(){return this.#m>=this.#r}};function I(n){let e={"X-Aspect-Share-Id":n.shareId};return n.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=n.shareAuthentication),e}var H=class{#t;#s;#e;#r;#n;#i;#a;#u;#o;#c;#m;#l;#D;#f;#A;#v;#b;#S;#P;#U;#F;#p;#C;#T;#d;#k;#g;#E;#I;#L;#x;#B;constructor(e){this.#s=e?.minConcurrency??1,this.#e=e?.maxConcurrency??8,this.#t=this.#H(e?.initialConcurrency??this.#s),this.#r=e?.errorThreshold??1,this.#n=(e?.cooldownSeconds??10)*1e3,this.#i=e?.plateauThreshold??.05,this.#a=Math.max(this.#e,Math.floor(e?.sampleWindowSize??64)),this.#u=Math.max(2,Math.floor(e?.minSamples??4)),this.#o=Math.max(1.1,e?.increaseFactor??1.5),this.#c=e?.onChange,this.#m=e?.now??Date.now,this.#l=this.#t,this.#D=0,this.#f=[],this.#A=0,this.#v=0,this.#b=-1,this.#S=0,this.#P=void 0,this.#U=0,this.#F=0,this.#p=0,this.#C=this.#l,this.#T=0,this.#d=1/0,this.#k=0,this.#g=6e4,this.#E=0,this.#I=1/0,this.#L=0,this.#x=0,this.#B=0}recordSuccess(e,t,s){if(e<=0)return;if(s?.generation!==void 0){if(s.generation!==this.#D){s.generation===this.#b&&this.#S>0&&(this.#S--,this.#S===0&&(this.#P=s.completedAtMs??this.#m()));return}if(this.#S>0||this.#P!==void 0&&s.startedAtMs!==void 0&&s.startedAtMs<this.#P)return}else if(this.#v>0){this.#v--;return}let r=s?.completedAtMs??this.#m();for(this.#f.push({bytes:e,completedAtMs:r,startedAtMs:s?.startedAtMs,durationMs:t!==void 0&&t>0?t:void 0});this.#f.length>this.#a;)this.#f.shift();this.#A++,this.#U=0;let i=this.#M();this.#x=i.throughputBps,this.#B=i.latencyMsPerMB,this.#_(i)}recordError(){if(this.#U++,this.#U<this.#r)return;let e=this.#l;e===this.#E&&(this.#I=Math.min(this.#I,e),this.#L=this.#m()+3e4),this.#E=e;let t=this.#H(Math.floor(e/2));this.#F=this.#m()+this.#n,this.#U=0,e<=this.#C&&(this.#C=t,this.#T=0),e>t&&(this.#d=Math.min(this.#d,e),this.#q()),this.#R(t)}get concurrency(){return this.#l}get generation(){return this.#D}get speedBps(){return this.#x}get latencyMsPerMB(){return this.#B}reset(){this.#l=this.#t,this.#D++,this.#f=[],this.#A=0,this.#v=0,this.#b=-1,this.#S=0,this.#P=void 0,this.#U=0,this.#F=0,this.#p=0,this.#C=this.#l,this.#T=0,this.#d=1/0,this.#k=0,this.#g=6e4,this.#E=0,this.#I=1/0,this.#L=0,this.#x=0,this.#B=0,this.#c?.(this.#l)}#_(e){if(this.#f.length<this.#W()||this.#A<this.#W()||e.throughputBps<=0)return;let t=this.#m();if(t<this.#F)return;if(e.averageDurationMs>=2e4&&this.#l>=4){this.#C=Math.max(this.#s,Math.floor(this.#l/2)),this.#T=0,this.#R(this.#C);return}if(this.#T===0){this.#O(e.throughputBps),this.#w(e);return}let s=(e.throughputBps-this.#T)/this.#T;if(s>=this.#i){this.#O(e.throughputBps),this.#w(e);return}if(this.#l>this.#C){let r=s<=-.08,i=s<this.#i;(r||i)&&(this.#d=Math.min(this.#d,this.#l),this.#q(),this.#R(this.#C));return}if(this.#l<this.#C){this.#w(e);return}this.#l===this.#C&&(this.#T=Math.max(this.#T,e.throughputBps),t>=this.#p&&this.#w(e))}#w(e){let t=this.#Q();if(this.#l>=t){this.#A=0;return}if(e.averageDurationMs>=5e3&&this.#l>=4&&this.#T>0){this.#A=0;return}if(this.#$()){let r=this.#m();if(this.#k===0){this.#k=r+this.#g,this.#p=this.#k,this.#A=0;return}if(r<this.#k){this.#A=0;return}}let s=this.#h(t);if(s===this.#l){this.#A=0;return}this.#R(s)}#O(e){this.#C=this.#l,this.#T=e,this.#d<=this.#l&&(this.#d=1/0),this.#k=0,this.#g=6e4,this.#p=0}#h(e){if(this.#d<1/0){let r=Math.floor((this.#l+this.#d)/2);return r>this.#l&&r<this.#d?Math.min(e,r):Math.min(e,this.#l+1)}if(this.#l<4)return Math.min(e,this.#l+1);let t=Math.ceil(this.#l*this.#o),s=this.#l+2;return Math.min(e,Math.max(s,t))}#R(e){let t=this.#l,s=this.#D,r=this.#H(e);r!==t&&(this.#N(),this.#l=r,this.#D++,this.#b=s,this.#S=Math.max(0,t-1),this.#P=this.#S===0?this.#m():void 0,this.#v=Math.max(0,t-1),this.#c?.(this.#l))}#N(){this.#f=[],this.#A=0,this.#v=0}#$(){return this.#d<1/0&&this.#l===this.#C&&this.#d<=this.#C+1}#q(){let e=this.#d<1/0&&this.#d<=this.#C+1,t=e?this.#g:1e4;this.#p=this.#m()+t,e&&(this.#k=this.#p,this.#g=Math.min(this.#g*2,3e5))}#W(){return Math.max(this.#u,this.#l)}#Q(){return this.#I<1/0&&this.#m()>=this.#L&&(this.#I=1/0,this.#L=0),Math.max(this.#s,Math.min(this.#e,this.#I-1))}#H(e){return Math.max(this.#s,Math.min(this.#e,e))}#M(){let e=0,t=0,s=0,r=0;for(let l of this.#f)e+=l.bytes,l.durationMs!==void 0&&(t+=l.durationMs,s++,r+=l.durationMs/(l.bytes/(1024*1024)));if(s>0&&t>0)return{throughputBps:e/(t/1e3)*this.#l,latencyMsPerMB:r/s,averageDurationMs:t/s,durationSampleCount:s};if(this.#f.length<2)return{throughputBps:0,latencyMsPerMB:0,averageDurationMs:0,durationSampleCount:0};let i=this.#f[0],a=this.#f[this.#f.length-1].completedAtMs-i.completedAtMs;return{throughputBps:a>0?e/a*1e3:0,latencyMsPerMB:0,averageDurationMs:a>0?a/Math.max(1,this.#f.length-1):0,durationSampleCount:0}}};var L=class{#t;#s;#e;#r;#n;constructor(e){let t=e===0?null:e;this.#t=t,this.#s=t??0,this.#e=Date.now(),this.#r=[],this.#n=null}setLimit(e){let t=e===0?null:e;if(t===null){this.#t=null,this.#s=0,this.#c();let r=this.#r.splice(0);for(let i of r)i.resolve();return}let s=this.#t;this.#t=t,s===null?(this.#s=t,this.#e=Date.now()):(this.#i(),this.#s=Math.min(this.#s,t)),this.#o()}getLimit(){return this.#t}acquire(e){if(this.#t!==null){if(this.#i(),this.#r.length===0&&this.#s>=e){this.#s-=e;return}return this.#a(e)}}#i(){let e=Date.now(),t=(e-this.#e)/1e3;if(t<=0)return;let s=this.#t,r=t*s,i=this.#r.length>0?Math.max(s,this.#r[0].bytes):s;this.#s=Math.min(this.#s+r,i),this.#e=e}#a(e){return new Promise(t=>{this.#r.push({bytes:e,resolve:t}),this.#n===null&&this.#u()})}#u(){if(this.#r.length===0||this.#t===null){this.#n=null;return}let t=this.#r[0].bytes-this.#s,s=t>0?Math.ceil(t/this.#t*1e3):0;if(s<=0){this.#n=null,this.#o();return}this.#n=setTimeout(()=>{this.#n=null,this.#i(),this.#o()},s)}#o(){for(;this.#r.length>0;){if(this.#t===null){let t=this.#r.splice(0);for(let s of t)s.resolve();return}this.#i();let e=this.#r[0];if(this.#s>=e.bytes)this.#s-=e.bytes,this.#r.shift(),e.resolve();else{this.#u();return}}}#c(){this.#n!==null&&(clearTimeout(this.#n),this.#n=null)}};function qe(n){let e=`[${n}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var ve=qe("transfer");var te=class{uploadAssets={};uploadGroups={};#t=new $;get uploadSpeedState(){return this.#t.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#s(e){e!==0&&this.#t.adjustTotalBytes(-e)}adjustSpeedBaselineForSkippedBytes(e){e!==0&&this.#t.adjustTotalBytes(e)}#e(){Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress")||this.#t.reset()}#r(e){this.dirtyAssetIds.add(e)}#n(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:s,parentId:r,projectId:i,groupId:o,chunkSize:a,shareContext:l}){this.uploadAssets[e]={assetId:e,totalBytesToUpload:t.size,bytesUploaded:0,status:"queued",fileName:t.name,createdAt:new Date().toISOString(),i:Object.keys(this.uploadAssets).length,parentId:r,projectId:i,groupId:o,retryCount:0,chunkSize:a??0,fileReader:t,abortController:s,shareContext:l},this.#r(e)}updateUploadProgress(e,t){let s=this.uploadAssets[e];if(!s||s.status==="paused"||s.status==="cancelled"||s.status==="success"||s.status==="failed")return;let r=t>0&&s.status==="queued"?"in-progress":s.status,i=Math.min(t,s.totalBytesToUpload);s.bytesUploaded=i,s.status=r,this.#r(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#r(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#r(e),this.#e(),this.cleanupOnCompletion(e))}markUploadFailed(e,t){let s=this.uploadAssets[e];if(!s)return;let r=s.bytesUploaded;s.status="failed",s.errorMessage=t,s.bytesUploaded=0,this.#r(e),this.#s(r),this.#e(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let s=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#r(e),this.#s(s),this.#e()}clearAllUploads(){this.uploadAssets={},this.#t.reset()}clearTerminalState(){if(!Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused")){for(let t of Object.keys(this.uploadAssets))delete this.uploadAssets[t];for(let t of Object.keys(this.uploadGroups))delete this.uploadGroups[t];this.#t.reset()}}resetAssetForRetryQueue(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.errorMessage=void 0,t.retryCount=t.retryCount+1,this.#r(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#r(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let s=0;if(t.chunkedState){let{completedChunkIndices:i,chunkSize:o}=t.chunkedState;for(let a of i){let l=a*o,u=Math.min(l+o,t.totalBytesToUpload);s+=u-l}}let r=t.bytesUploaded-s;t.status="paused",t.bytesUploaded=s,this.#r(e),this.#s(r),this.#e(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#r(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#n(e);for(let s of t.assetIds)this.pauseUpload(s)}}unpauseUploadGroup(e){let t=this.uploadGroups[e];t&&(t.isPaused=!1,this.#n(e))}pauseAllUploads(){for(let e of Object.values(this.uploadGroups))e.isCreatingFolders||this.pauseUploadGroup(e.id)}resumeAllUploads(){for(let e of Object.values(this.uploadGroups))e.isPaused&&this.unpauseUploadGroup(e.id)}markUploadCancelled(e){let t=this.uploadAssets[e];if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let s=t.bytesUploaded;t.status="cancelled",this.#r(e),this.#s(s),this.#e(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let s=this.uploadAssets[e];s&&(s.chunkedState=t,this.#r(e))}addCompletedChunkIndex(e,t){let s=this.uploadAssets[e];!s||!s.chunkedState||(s.chunkedState={...s.chunkedState,completedChunkIndices:[...s.chunkedState.completedChunkIndices,t]},this.#r(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#r(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return Ue(this.uploadAssets)}hasPausedUploads(){return Fe(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#u(t)}getUploadSummary(){return G(this.#c())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#u(e)).sort((e,t)=>t.i-e.i)}getGroupAssets(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(s=>this.uploadAssets[s]).filter(Boolean).map(s=>this.#u(s))}getGroupAssetsInternal(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(s=>this.uploadAssets[s]).filter(Boolean)}addUploadGroup(e){let t=crypto.randomUUID();return this.uploadGroups[t]={...e,id:t,fileReaders:new Map},this.#n(t),t}updateUploadGroup(e,t){let s=this.uploadGroups[e];s&&(Object.assign(s,t),this.#n(e))}addAssetToGroup(e,t){let s=this.uploadGroups[e];s&&(s.assetIds.push(t),this.#n(e))}finalizeEmptyGroup({groupId:e,status:t,errorMessage:s}){let r=this.uploadGroups[e];r&&(r.assetIds.length>0||r.finalizedStatus||(r.finalizedStatus=t,r.errorMessage=s,r.isCreatingFolders=!1,r.completedAt=new Date().toISOString(),this.#n(e),this.dirtyHistoryGroupIds.add(e)))}removeUploadGroup(e){let t=this.uploadGroups[e];if(t)for(let s of t.assetIds)delete this.uploadAssets[s],this.#r(s);delete this.uploadGroups[e],this.#n(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#o(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#o(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e);return Pe(this.#o(t),s)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e);return ee(this.#o(t),s)}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#u(t))}getActiveUploadGroups(){return Object.values(this.uploadGroups).filter(e=>{let t=this.getUploadGroupStatus(e.id);return t&&["queued","creating-folders","in-progress"].includes(t)}).map(e=>this.#o(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let s=t.groupId;if(s){let i=this.uploadGroups[s];if(i){let o=this.getGroupAssets(s),a=this.#o(i);this.dirtyHistoryGroupIds.add(s),!o.some(u=>u.status==="queued"||u.status==="in-progress")&&!i.completedAt&&(i.completedAt=new Date().toISOString(),this.#n(s))}}let r=this.getUploadSummary();if(r.cancelledAssetCount+r.failedAssetCount+r.successAssetCount===r.totalAssetCount)for(let i of Object.keys(this.uploadAssets)){let o=this.uploadAssets[i];o&&(o.bytesUploaded=0,this.#r(i))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#t.sample(e.totalBytesUploaded);let s=this.#t.isWarmedUp?this.#t.speedMbps:0,r=t&&this.#t.isWarmedUp?this.#t.etaSeconds(e.totalBytesToUpload-e.totalBytesUploaded):0;this.uploadStats={uploadSpeedMbps:s,timeRemainingSeconds:r,formattedSpeed:this.#i(s),formattedTime:this.#a(r)}}#i(e){return!Number.isFinite(e)||e<=0?"Calculating...":e<1?`${(e*1e3).toFixed(0)} Kbps`:`${e.toFixed(1)} Mbps`}#a(e){if(!Number.isFinite(e)||e<=0)return"Calculating...";let t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60);return t>0?`${t}h ${s}m left`:s>0?`${s}m ${r}s left`:`${r}s left`}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let s=this.getGroupAssets(e),r=this.#o(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:Ee(r,s),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#u({fileReader:e,abortController:t,shareContext:s,...r}){return r}#o({fileReaders:e,...t}){return t}#c(){let e={};for(let[t,s]of Object.entries(this.uploadAssets))e[t]=this.#u(s);return e}#m(){let e={};for(let[t,s]of Object.entries(this.uploadGroups))e[t]=this.#o(s);return e}getSerializableSnapshot(){return{uploadAssets:this.#c(),uploadGroups:this.#m(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let s of this.dirtyAssetIds){let r=this.uploadAssets[s];r&&(e[s]=this.#u(r))}let t={};for(let s of this.dirtyGroupIds){let r=this.uploadGroups[s];r&&(t[s]=this.#o(r))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function wt(n,e){let t=new Date(n).getTime(),s=Date.now();return t-s<=e}var se=class{#t;#s=new Map;#e=new Map;constructor(e){this.#t=e}seedToken(e,t,s){this.#s.set(e,{token:t,expiresAt:s})}async getToken(e,t){let s=this.#s.get(e);if(s&&!wt(s.expiresAt,3e5))return s.token;let r=this.#e.get(e);if(r)return r;let i=t?I(t):void 0,o=this.#t.post(`/assets/${e}/token`,{},i).then(a=>{if(!a.token)throw new Error("Token refresh failed: no token in response");return this.#s.set(e,{token:a.token,expiresAt:a.token_expires_at}),this.#e.delete(e),a.token}).catch(a=>{throw this.#e.delete(e),a});return this.#e.set(e,o),o}clearCache(e){e?this.#s.delete(e):this.#s.clear()}};var re=class{#t=[];registerAsset(e){this.#t.push({assetId:e.assetId,totalChunks:e.totalChunks,nextChunkToClaim:0,completedChunkIndices:new Set(e.completedChunkIndices),isPaused:!1})}claimNextChunk(){for(let e of this.#t)if(!e.isPaused)for(;e.nextChunkToClaim<e.totalChunks;){let t=e.nextChunkToClaim;if(e.nextChunkToClaim++,!e.completedChunkIndices.has(t))return{assetId:e.assetId,chunkIndex:t}}return null}markChunkCompleted(e,t){let s=this.#s(e);return s?(s.completedChunkIndices.add(t),s.completedChunkIndices.size>=s.totalChunks):!1}pauseAsset(e){let t=this.#s(e);t&&(t.isPaused=!0)}unpauseAsset(e){let t=this.#s(e);t&&(t.isPaused=!1,this.#e(t))}removeAsset(e){this.#t=this.#t.filter(t=>t.assetId!==e)}hasAsset(e){return this.#t.some(t=>t.assetId===e)}isAssetComplete(e){let t=this.#s(e);return t?t.completedChunkIndices.size>=t.totalChunks:!1}clear(){this.#t=[]}#s(e){return this.#t.find(t=>t.assetId===e)}#e(e){for(let t=0;t<e.totalChunks;t++)if(!e.completedChunkIndices.has(t)){e.nextChunkToClaim=t;return}e.nextChunkToClaim=e.totalChunks}};var It=/[/\\:*?"<>|\x00-\x1F]/g,xt=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function B(n){let e=n.replace(It,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;xt.includes(t.toUpperCase())&&(e=`_${e}`);let s=new TextEncoder;if(s.encode(e).length>255){let r=e.lastIndexOf("."),i=r>0?e.substring(r):"",o=r>0?e.substring(0,r):e,l=255-s.encode(i).length;for(;s.encode(o).length>l&&o.length>0;)o=o.slice(0,-1);e=o+i}return e}var F=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function x(n){return n instanceof F||n instanceof Error&&n.name==="CancelledError"||n instanceof Error&&n.name==="CanceledError"||n instanceof Error&&n.name==="AbortError"}function Nt(n){return x(n)||n instanceof Error&&n.name==="NoAuthError"}function zt(n){return new Promise(e=>setTimeout(e,n))}function Gt(n){return n instanceof Blob?n.size:n.byteLength}var j=class{#t;#s;#e;#r;#n;#i;#a;#u;#o;#c;#m;#l;#D;#f=null;#A=0;#v=!1;#b=[];#S=new Set;#P=!1;#U=!1;#F=!1;#p=[];#C=!1;#T=!1;#d=new re;#k=0;#g=new Map;#E=new Map;#I=[];#L=!1;#x=null;#B;#_="keep_both";#w=new Map;#O=null;#h=!1;#R=null;#N=!1;constructor(e){this.#t=e.httpClient,this.#s=new se(e.httpClient),this.#e=new te,this.#r=e.historyStore??null,this.#n=e.settingsStore??null,this.#i=e.analytics??null,this.#a=e.logger??ve,this.#u=e.onChange??null,this.#o=e.onClear??null,this.#c=e.onSummary??null,this.#m=e.onConcurrencyAdjusted??null,this.#D=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let s=e.adaptiveConcurrencyConfig;this.#R=new H({initialConcurrency:s?.initialConcurrency??Math.min(4,t),minConcurrency:s?.minConcurrency??1,maxConcurrency:s?.maxConcurrency??t,errorThreshold:s?.errorThreshold,cooldownSeconds:s?.cooldownSeconds??10,plateauThreshold:s?.plateauThreshold,onChange:r=>{let i=this.#l;if(this.setMaxConcurrency(r),i===r)return;let o=this.#N?"reset":r>i?"probe_increase":"error_decrease",a=Math.round(this.#R.speedBps*8/1e6*100)/100,l=Math.round(this.#R.latencyMsPerMB*100)/100;this.#a.info(`Adaptive concurrency: ${i} \u2192 ${r} (${o}), measuredAt=${i}, speed=${a}Mbps, latency=${l}ms/MB`),this.#m?.({previousConcurrency:i,newConcurrency:r,reason:o,speedMbps:a,latencyMsPerMB:l})},now:s?.now}),this.#l=this.#R.concurrency}else this.#l=t;this.#r&&(this.#b=this.#r.load()),this.#n&&(this.#x=this.#n.getBandwidthLimitBps(),this.#_=this.#n.getConflictResolution()),this.#B=new L(this.#x),(this.#u||this.#c)&&(this.#f=setInterval(()=>{this.#ue()},this.#D)),this.#i&&(this.#O=setInterval(()=>{this.#de()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),s=!!e.assetId,r;if(s){let o=this.#e.getUploadAsset(t);if(!o)throw new Error(`Cannot retry: asset ${t} not found`);r=o.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");r=e.chunkSize}let i=new AbortController;if(s){if(this.#e.getUploadAsset(t).status==="cancelled")return t;e.resetRetryCount&&this.#e.resetAssetForRetrying(t);let a=this.#e.getUploadAsset(t);a.abortController=i,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#e.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:i,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:r,shareContext:e.shareContext});return this.#p.push(t),this.#$(),this.#y(),t}startGroupUpload(e){this.#e.clearTerminalState();let t=this.#e.addUploadGroup({type:e.type,name:e.name,assetIds:[],fileCount:e.fileCount,folderCount:e.folderCount,topLevelFileCount:e.topLevelFileCount,topLevelFolderCount:e.topLevelFolderCount,isCreatingFolders:!1,isPaused:!1,createdAt:new Date().toISOString(),rootDirectoryId:e.rootDirectoryId,projectId:e.projectId,retryCount:0,conflictResolution:e.conflictResolutionOverride??this.#_});return this.#w.set(t,Date.now()),this.#i?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#e.dirtyHistoryGroupIds.add(t),this.#G(),this.#y(),t}pauseUpload(e){let t=this.#e.getUploadAsset(e);this.#e.pauseUpload(e),this.#p=this.#p.filter(s=>s!==e),this.#d.pauseAsset(e),!this.#h&&t&&this.#i&&this.#i("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#y()}unpauseUpload(e){this.#e.unpauseUpload(e),this.#y()}cancelUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let s=t.fileName,r=t.totalBytesToUpload,i=t.bytesUploaded,o=t.projectId,a=t.chunkedState?.assetId;(t.status==="queued"||t.status==="in-progress")&&t.abortController.abort(),this.#p=this.#p.filter(l=>l!==e),this.#d.removeAsset(e),this.#g.delete(e),this.#E.delete(e),this.#e.markUploadCancelled(e),this.#e.clearChunkedState(e),t.fileReader.close?.(),!this.#h&&this.#i&&this.#i("upload:file_cancelled",{file_name:s,file_size:r,bytes_uploaded:i,project_id:o??""}),this.#y(),this.#M(),this.#$(),this.#X(),a&&(this.#I.push(a),this.#J())}cancelAllUploads(){let e=this.#V();this.#h=!0;try{let s=Object.values(this.#e.uploadAssets).filter(r=>r.status==="queued"||r.status==="in-progress"||r.status==="paused");for(let r of s)this.cancelUpload(r.assetId)}finally{this.#h=!1}this.#i?.("upload:all_cancelled",e)}retryUpload(e){let t=this.#e.getUploadAsset(e);t&&t.status==="failed"&&this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,resetRetryCount:!0,shareContext:t.shareContext})}resumeUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status!=="paused")return;!this.#h&&this.#i&&this.#i("upload:file_resumed",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""});let s=new AbortController;t.abortController=s,this.#e.unpauseUpload(e),this.#d.hasAsset(e)?(this.#d.unpauseAsset(e),this.#y(),this.#d.isAssetComplete(e)?this.#Y(e).catch(r=>{this.#z(e,r)}):this.#M()):this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,shareContext:t.shareContext})}pauseUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let s=this.#h;this.#h=!0,this.#e.pauseUploadGroup(e);for(let r of t.assetIds)this.#p=this.#p.filter(i=>i!==r),this.#d.pauseAsset(r);this.#h=s,this.#h||this.#te(e,t,"upload:group_paused"),this.#y()}unpauseUploadGroup(e){this.#e.unpauseUploadGroup(e),this.#y()}cancelUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let{totalBytes:s,bytesUploaded:r,filesRemaining:i}=this.#ee(t),o=this.#h;this.#h=!0;for(let a of t.assetIds)this.cancelUpload(a);t.assetIds.length===0&&(this.#e.finalizeEmptyGroup({groupId:e,status:"cancelled"}),this.#G(),this.#y()),this.#h=o,this.#h||this.#i?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:i,total_bytes:s,bytes_uploaded:r,project_id:t.projectId}),this.#w.delete(e)}resumeUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;this.#h||this.#te(e,t,"upload:group_resumed");let s=this.#h;this.#h=!0,this.#e.unpauseUploadGroup(e);for(let r of t.assetIds){let i=this.#e.getUploadAsset(r);i&&i.status==="paused"&&this.resumeUpload(r)}this.#h=s}retryUploadGroup(e){let t=this.#e.uploadGroups[e];if(t)for(let s of t.assetIds){let r=this.#e.getUploadAsset(s);r&&r.status==="failed"&&this.retryUpload(s)}}setGroupCreatingFolders(e,t){this.#e.updateUploadGroup(e,{isCreatingFolders:t}),this.#y()}markEmptyGroupFailed(e,t){let s=this.#e.uploadGroups[e];s&&(s.assetIds.length>0||s.finalizedStatus||(this.#a.error("Empty group upload failed",{groupId:e,groupName:s.name,errorMessage:t}),this.#e.finalizeEmptyGroup({groupId:e,status:"all-failed",errorMessage:t}),this.#G(),this.#w.delete(e),this.#y()))}markEmptyGroupCompleted(e){this.#e.finalizeEmptyGroup({groupId:e,status:"success"}),this.#G(),this.#w.delete(e),this.#y()}addAssetToGroup(e,t){this.#e.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#V();this.#h=!0;try{for(let t of Object.values(this.#e.uploadAssets))t.groupId||this.pauseUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isCreatingFolders||this.pauseUploadGroup(t.id)}finally{this.#h=!1}this.#i?.("upload:all_paused",e),this.#y()}resumeAllUploads(){let e=this.#V();this.#h=!0;try{for(let t of Object.values(this.#e.uploadAssets))!t.groupId&&t.status==="paused"&&this.resumeUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isPaused&&this.resumeUploadGroup(t.id)}finally{this.#h=!1}this.#i?.("upload:all_resumed",e),this.#y()}clearAllUploads(){this.#p=[],this.#d.clear(),this.#g.clear(),this.#E.clear(),this.#e.clearAllUploads(),this.#e.uploadGroups={},this.#R&&(this.#N=!0,this.#R.reset(),this.#N=!1),this.#o?.({all:!0}),this.#c?.(this.#j())}clearHistory(){this.#b=[],this.#r?.clear(),this.#P=!0,this.#S.clear(),this.#F=!0,this.#y()}removeHistoryItem(e){this.#b=this.#b.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#S.add(e),this.#F=!0,this.#y()}removeGroup(e){this.#e.removeUploadGroup(e),this.#b=this.#b.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#S.add(e),this.#F=!0,this.#o?.({groupId:e}),this.#c?.(this.#j()),this.#y()}getHttpClient(){return this.#t}setBandwidthLimit(e){let t=e!==this.#x;this.#x=e,this.#B.setLimit(e),this.#n?.setBandwidthLimitBps(e),t&&this.#R&&(this.#N=!0,this.#R.reset(),this.#N=!1),this.#F=!0,this.#y()}getBandwidthLimit(){return this.#x}setConflictResolution(e){this.#_=e,this.#n?.setConflictResolution(e),this.#F=!0,this.#y()}getConflictResolution(){return this.#_}getGroupConflictResolution(e){return this.#e.getUploadGroup(e)?.conflictResolution??this.#_}setMaxConcurrency(e){this.#l=e,this.#M()}getSnapshot(){return this.#e.updateUploadStats(),{...this.#e.getSerializableSnapshot(),uploadHistory:[...this.#b??[]],uploadSummary:this.#j(),bandwidthLimitBps:this.#x,conflictResolution:this.#_}}getUploadAsset(e){return this.#e.getSerializableAsset(e)}getUploadSummary(){return this.#j()}getGroupAssets(e){return this.#e.getGroupAssets(e)}getUploadGroupStatus(e){return this.#e.getUploadGroupStatus(e)}getUploadGroupProgress(e){return this.#e.getUploadGroupProgress(e)}hasGroupsCreatingFolders(){return this.#e.hasGroupsCreatingFolders()}areAllUploadsPaused(){return this.#e.areAllUploadsPaused()}hasPausedUploads(){return this.#e.hasPausedUploads()}hasActiveUploads(){return Te(this.#e.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return Re(this.#e.getSerializableSnapshot().uploadAssets)}async cancelActiveServerUploads(){let e=this.getServerAssetIdsToCancel();if(e.length!==0)try{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}catch{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}}destroy(){this.#U=!0,this.#f&&(clearInterval(this.#f),this.#f=null),this.#O&&(clearInterval(this.#O),this.#O=null),this.#p=[],this.#d.clear();for(let e of Object.values(this.#e.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#$(){this.#T||(this.#T=!0,queueMicrotask(()=>{this.#T=!1,this.#q().catch(e=>{this.#a.error("Initiation pipeline error",{queueLength:this.#p.length},e)})}))}async#q(){if(!this.#C){this.#C=!0;try{await this.#W()}finally{this.#C=!1}}}async#W(){for(;this.#p.length>0&&!(this.#g.size>5);){let e=Math.min(this.#p.length,20-this.#g.size);if(e<=0)break;let t=[],s=[];for(let r=0;r<e&&this.#p.length>0;r++){let i=this.#p[0],o=this.#e.getUploadAsset(i);if(!o||o.status==="cancelled"){this.#p.shift(),r--;continue}if(this.#p.shift(),s.push(i),o.chunkedState)try{this.#Q(i,o),this.#M()}catch(a){x(a)||this.#z(i,a)}else t.push(i)}if(t.length>0){let r=new Map;for(let i of t){let a=this.#e.getUploadAsset(i)?.shareContext?.shareId??"",l=r.get(a);l||(l=[],r.set(a,l)),l.push(i)}for(let i of r.values())try{await this.#H(i)}catch(o){for(let a of i)this.#z(a,o instanceof Error?o:new Error(String(o)))}this.#M()}}}#Q(e,t){let s=t.chunkedState,r={serverAssetId:s.assetId,chunkIds:s.chunkIds,chunkSize:s.chunkSize,totalChunks:s.totalChunks,sizeBytes:s.sizeBytes},i=s.completedChunkIndices;this.#g.set(e,r);let o=new Array(r.totalChunks).fill(0);if(i.length>0){for(let l of i){let u=l*r.chunkSize,c=Math.min(u+r.chunkSize,t.totalBytesToUpload);o[l]=c-u}let a=o.reduce((l,u)=>l+u,0);this.#e.updateUploadProgress(e,a)}if(this.#E.set(e,o),r.totalChunks===0||i.length>=r.totalChunks){this.#Y(e).catch(a=>{this.#z(e,a)});return}this.#d.registerAsset({assetId:e,totalChunks:r.totalChunks,completedChunkIndices:i})}async#H(e){let t=[],s=[];for(let a of e){let l=this.#e.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let u=B(l.fileName),c=l.groupId?this.#e.getUploadGroup(l.groupId)?.conflictResolution??this.#_:this.#_,d=(()=>{switch(c){case"keep_both":return{auto_rename:"parenthesized"};case"replace":return{conflict_resolution:"replace"};case"skip":return{conflict_resolution:"skip"}}})();t.push({directory_id:l.parentId,id:a,name:u,size_bytes:l.totalBytesToUpload,...d}),s.push(a)}if(t.length===0)return;let r=this.#e.getUploadAsset(s[0]),i=r?.shareContext?I(r.shareContext):void 0,o=await this.#t.post("/assets/chunked/initiate",t,i);for(let a=0;a<s.length;a++){let l=s[a],u=o[a];if(!u||u.error){this.#z(l,new Error(u?.error??"Unknown batch initiation error"));continue}if(u.skipped){let y=this.#e.getUploadAsset(l);y&&(this.#e.adjustSpeedBaselineForSkippedBytes(y.totalBytesToUpload),this.#e.markUploadSuccess(l),this.#e.dirtyHistoryGroupIds.add(y.groupId??""),this.#G(),y.fileReader.close?.());continue}let c=u.result,d=this.#e.getUploadAsset(l);if(!d||d.status==="cancelled"||d.status==="paused"){(!d||d.status==="cancelled")&&(this.#I.push(c.asset_id),this.#J());continue}let p=Math.ceil(d.totalBytesToUpload/c.chunk_size),g=Array.from({length:p},()=>crypto.randomUUID());this.#s.seedToken(c.asset_id,c.token,c.token_expires_at);let h={serverAssetId:c.asset_id,chunkIds:g,chunkSize:c.chunk_size,totalChunks:p,sizeBytes:d.totalBytesToUpload};this.#e.setChunkedState(l,{assetId:h.serverAssetId,chunkIds:h.chunkIds,completedChunkIndices:[],chunkSize:h.chunkSize,totalChunks:h.totalChunks,sizeBytes:h.sizeBytes}),this.#g.set(l,h);let A=new Array(h.totalChunks).fill(0);if(this.#E.set(l,A),h.totalChunks===0){this.#Y(l).catch(y=>{this.#z(l,y)});continue}this.#d.registerAsset({assetId:l,totalChunks:h.totalChunks,completedChunkIndices:[]})}}#M(){if(!this.#U)for(;this.#k<this.#l;){let e=this.#d.claimNextChunk();if(!e)break;this.#k++;let{assetId:t,chunkIndex:s}=e,r=this.#R?.generation;this.#re(t,s,r).then(i=>{this.#k--,this.#ie(t,s,i),this.#M()}).catch(i=>{if(this.#k--,x(i)){this.#M();return}this.#oe(t,s,i),this.#M()})}}async#re(e,t,s){let r;for(let i=0;i<3;i++)try{let o=this.#E.get(e);return o&&(o[t]=0,this.#K(e)),await this.#ne(e,t,s)}catch(o){if(x(o))throw o;if(r=o instanceof Error?o:new Error(String(o)),this.#R?.recordError(),this.#ae(e,t,r,i),i===2)throw r;let a=this.#E.get(e);a&&(a[t]=0,this.#K(e));let l=1e3*Math.pow(2,i);await zt(l)}throw r||new Error("Unknown error during chunk upload")}async#ne(e,t,s){let r=this.#e.getUploadAsset(e);if(!r)throw new F;if(r.abortController.signal.aborted)throw new F;let i=this.#g.get(e);if(!i)throw new Error(`No chunk metadata for asset ${e}`);let o=t*i.chunkSize,a=Math.min(o+i.chunkSize,r.totalBytesToUpload),l=await r.fileReader.readChunk(o,a),u=Gt(l);if(r.abortController.signal.aborted)throw new F;let c=i.chunkIds[t],d=await this.#s.getToken(i.serverAssetId,r.shareContext),p=`/uploads/chunks/${c}`,g=Date.now(),h=await this.#t.putWithToken(p,l,d,{signal:r.abortController.signal,onProgress:P=>{let R=this.#E.get(e);R&&(R[t]=P,this.#K(e))},contentType:"application/octet-stream",limiter:this.#B}),A=Date.now(),y=h.uploadCompletedAtMs??A,f=y-g;if(!h.status||h.status<200||h.status>=300)throw this.#a.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:c,assetId:e,serverAssetId:i.serverAssetId,chunkSizeBytes:u,durationMs:f,httpStatus:h.status,statusText:h.statusText,responseBody:h.data,responseHeaders:h.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${h.status}`);let V=this.#E.get(e);return V&&(V[t]=u,this.#K(e)),{durationMs:f,startedAtMs:g,completedAtMs:y,adaptiveGeneration:s}}#K(e){let t=this.#E.get(e);if(!t)return;let s=t.reduce((r,i)=>r+i,0);this.#e.updateUploadProgress(e,s)}#ie(e,t,s){if(this.#R){let i=this.#g.get(e);if(i){let o=t*i.chunkSize,l=Math.min(o+i.chunkSize,i.sizeBytes)-o;this.#R.recordSuccess(l,s.durationMs,{generation:s.adaptiveGeneration,startedAtMs:s.startedAtMs,completedAtMs:s.completedAtMs})}}this.#e.addCompletedChunkIndex(e,t),this.#d.markChunkCompleted(e,t)&&this.#Y(e).catch(i=>{this.#z(e,i)})}#oe(e,t,s){this.#z(e,s)}#ae(e,t,s,r){if(!this.#i)return;let i=this.#e.getUploadAsset(e);if(!i)return;let o=this.#g.get(e);if(!o)return;let a=t*o.chunkSize,u=Math.min(a+o.chunkSize,o.sizeBytes)-a,c=s,d=typeof c.code=="string"?c.code:null,p=c.response?.status,g=typeof p=="number"?p:null,h=s.cause?s.cause instanceof Error?s.cause.message:String(s.cause):null;this.#i("upload:chunk_error",{file_name:i.fileName,file_size:i.totalBytesToUpload,chunk_index:t,chunk_size:u,chunks_total:o.totalChunks,attempt:r+1,max_attempts:3,is_final_attempt:r===2,error_type:s.name,error_message:s.message,error_code:d,http_status:g,error_stack:s.stack??null,error_cause:h,project_id:i.projectId??""})}#le(e,t,s,r){if(!this.#i||x(t))return;let i=t instanceof Error?t.message:"Unknown error",o=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof o.code=="string"?o.code:null,u=o.response?.status,c=typeof u=="number"?u:null,d=this.#g.get(e.assetId);this.#i("upload:file_error",{file_name:e.fileName,file_size:e.totalBytesToUpload,bytes_uploaded:e.bytesUploaded,chunks_completed:e.chunkedState?.completedChunkIndices.length??0,chunks_total:d?.totalChunks??0,attempt:s+1,max_attempts:4,is_final_attempt:r,error_type:t instanceof Error?t.name:"Unknown",error_message:i,error_code:l,http_status:c,error_stack:t instanceof Error?t.stack??null:null,error_cause:a,project_id:e.projectId??""})}async#Y(e){let t=this.#e.getUploadAsset(e);if(!t)return;let s=this.#g.get(e);if(!s)return;if(t.abortController.signal.aborted)throw new F;let r=crypto.randomUUID(),i=JSON.stringify(s.chunkIds),o=new TextEncoder().encode(i),a=await this.#s.getToken(s.serverAssetId,t.shareContext),l=`/uploads/manifests/${r}`;try{await this.#t.putWithToken(l,o,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(u){throw x(u)||this.#a.error("Manifest upload failed",{assetId:e,serverAssetId:s.serverAssetId,manifestId:r},u),u}if(t.abortController.signal.aborted)throw new F;try{let u=t.shareContext?I(t.shareContext):void 0;await this.#t.post(`/assets/${s.serverAssetId}/revisions/commit`,{manifest_id:r,size_bytes:s.sizeBytes,is_initial_upload:!0,client_performed_at:new Date().toISOString()},u)}catch(u){throw this.#a.error("Commit revision failed",{assetId:e,serverAssetId:s.serverAssetId,manifestId:r,sizeBytes:s.sizeBytes},u),u}this.#e.markUploadSuccess(e),this.#e.clearChunkedState(e),this.#G(),this.#y(),this.#g.delete(e),this.#E.delete(e),this.#d.removeAsset(e),await t.fileReader.close?.(),this.#se(e),this.#$(),this.#X()}#z(e,t){let s=this.#e.getUploadAsset(e);if(!s||x(t)||s.status==="paused"||s.status==="cancelled")return;let r=s.retryCount,i=r>=3||Nt(t);if(this.#le(s,t,r,i),i){let o=t instanceof Error?t.message:"Unknown error";this.#a.error("Asset upload permanently failed",{assetId:e,fileName:s.fileName,totalRetries:r,bytesUploaded:s.bytesUploaded,totalBytes:s.totalBytesToUpload,chunksCompleted:s.chunkedState?.completedChunkIndices.length??0},t),s.abortController.abort(),this.#e.markUploadFailed(e,o),this.#d.removeAsset(e),this.#g.delete(e),this.#E.delete(e),this.#G(),this.#y(),this.#se(e),this.#$(),this.#X()}else{this.#a.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:s.fileName,retryAttempt:r+1,maxRetries:3},t);let o=s.chunkedState;s.abortController.abort(),this.#d.removeAsset(e),this.#g.delete(e),this.#E.delete(e),this.#e.resetAssetForRetryQueue(e),this.#y(),this.#$();let a=2e3*Math.pow(2,r);setTimeout(()=>{if(this.#U)return;let l=this.#e.getUploadAsset(e);!l||l.status!=="queued"||this.startUpload({fileReader:l.fileReader,directoryId:l.parentId??"",projectId:l.projectId,groupId:l.groupId,assetId:e,resumeChunked:o,shareContext:l.shareContext})},a)}}#X(){this.#R&&(this.hasActiveUploads()||(this.#N=!0,this.#R.reset(),this.#N=!1))}#J(){this.#L||(this.#L=!0,queueMicrotask(()=>{this.#L=!1;let e=this.#I.splice(0);e.length!==0&&this.#t.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#a.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#j(){return G(this.#e.getSerializableSnapshot().uploadAssets)}#y(){this.#v||(this.#v=!0,queueMicrotask(()=>{this.#v=!1,this.#ce()}))}#ue(){this.#Z(!0)}#ce(){this.#Z(!1)}#Z(e){if(this.#U||!this.#u&&!this.#c)return;e?this.#e.updateUploadStats():(this.#A++,this.#A%3===0&&this.#e.updateUploadStats());let t=this.#e.getDirtyDelta();if(!this.#F&&Object.keys(t.assets).length===0&&Object.keys(t.groups).length===0&&this.#e.dirtyHistoryGroupIds.size===0)return;this.#F=!1,this.#e.dirtyHistoryGroupIds.size>0&&this.#G();let r=this.#e.dirtyHistoryGroupIds.size>0?this.#he():void 0,i=this.#P?!0:void 0,o=this.#S.size>0?[...this.#S]:void 0;this.#P=!1,this.#S.clear();let a=this.#j(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#e.uploadStats},uploadSpeedState:this.#e.uploadSpeedState,historyItems:r,removedHistoryGroupIds:o,historyCleared:i,uploadSummary:a,bandwidthLimitBps:this.#x,conflictResolution:this.#_};this.#e.clearDirtyFlags(),this.#u?.(l),this.#c?.(a)}#ee(e){let t=0,s=0,r=0;for(let i of e.assetIds){let o=this.#e.getUploadAsset(i);o&&(t+=o.totalBytesToUpload,s+=o.bytesUploaded,o.status!=="success"&&o.status!=="failed"&&o.status!=="cancelled"&&r++)}return{totalBytes:t,bytesUploaded:s,filesRemaining:r}}#V(){let e=0,t=0,s=0,r=0;for(let i of Object.values(this.#e.uploadGroups)){e++;for(let o of i.assetIds){let a=this.#e.getUploadAsset(o);a&&(a.status==="success"||a.status==="failed"||a.status==="cancelled"||(t++,s+=a.totalBytesToUpload,r+=a.bytesUploaded))}}return{group_count:e,file_count:t,total_bytes:s,bytes_uploaded:r}}#de(){if(!(!this.#i||this.#U))for(let e of Object.values(this.#e.uploadGroups)){let t=!1,s=0,r=0,i=0,o=0,a=0,l=0,u=0,c=0,d=0,p=0;for(let A of e.assetIds){let y=this.#e.getUploadAsset(A);if(!y)continue;let f=y.totalBytesToUpload;switch(s+=f,r+=y.bytesUploaded,y.status){case"success":i++,o+=f;break;case"failed":a++,l+=f;break;case"cancelled":u++,c+=f;break;case"in-progress":d++,t=!0;break;case"queued":p++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let g=this.#w.get(e.id),h=g?Date.now()-g:0;this.#i("upload:group_progress",{group_id:e.id,file_count:e.assetIds.length,total_bytes:s,bytes_uploaded:r,duration_ms:h,project_id:e.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:u,cancelled_bytes:c,in_progress_count:d,queued_count:p,progress:s>0?r/s:0,concurrency:this.#l,upload_speed_mbps:this.#e.uploadStats.uploadSpeedMbps})}}#te(e,t,s){if(!this.#i)return;let{totalBytes:r,bytesUploaded:i}=this.#ee(t);this.#i(s,{file_count:t.fileCount,total_bytes:r,bytes_uploaded:i,project_id:t.projectId})}#se(e){if(!this.#i)return;let t=this.#e.getUploadAsset(e);if(!t?.groupId)return;let s=this.#e.uploadGroups[t.groupId];if(!s)return;let r=!0,i=0,o=0,a=0,l=0,u=0,c=0,d=0;for(let h of s.assetIds){let A=this.#e.getUploadAsset(h);if(!A)continue;let y=A.totalBytesToUpload;if(d+=y,A.status==="success")i++,o+=y;else if(A.status==="failed")a++,l+=y;else if(A.status==="cancelled")u++,c+=y;else{r=!1;break}}if(!r)return;let p=this.#w.get(s.id),g=p?Date.now()-p:0;this.#i("upload:group_completed",{file_count:s.assetIds.length,total_bytes:d,duration_ms:g,project_id:s.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:u,cancelled_bytes:c}),this.#w.delete(s.id)}#he(){let e={};for(let t of this.#e.dirtyHistoryGroupIds){let s=this.#e.buildHistoryItem(t);s&&(e[t]=s)}return e}#G(){if(!this.#r)return;let e={};for(let t of this.#e.dirtyHistoryGroupIds){let s=this.#e.buildHistoryItem(t);if(s){e[t]=s;let r=this.#b.findIndex(i=>i.groupId===t);r>=0?this.#b[r]=s:this.#b.unshift(s)}}Object.keys(e).length>0&&this.#r.merge(e)}};var q=class{#t=65536;#s=0;async*createIterator(e,t,s){let r=0,i=Math.max(65536,Math.min(e.byteLength,this.#t)),o=this.#s;for(;r<e.byteLength;){if(s?.aborted)return;let a=t?t.getLimit():null,l=a!==null&&a>0;if(l){let h=Math.round(a*50/1e3);i=Math.max(65536,Math.min(e.byteLength,h))}let u=Math.min(r+i,e.byteLength),c=e.subarray(r,u),d=c.byteLength;if(l&&(await t.acquire(d),s?.aborted))return;let p=performance.now();yield c;let g=performance.now()-p;if(r=u,!l){if(g>=.5){let h=d/g*1e3;o=o===0?h:o*(1-.3)+h*.3}else o===0&&(i=Math.min(e.byteLength,i*2));if(o>0){let h=Math.round(o*50/1e3);i=Math.max(65536,Math.min(e.byteLength,h))}}this.#t=i,this.#s=o}}};var S=(n,e=2)=>{if(n===0)return"0 B";let t=1024,s=e<0?0:e,r=["B","KB","MB","GB","TB","PB","EB"],i=Math.floor(Math.log(n)/Math.log(t));return`${(n/Math.pow(t,i)).toFixed(s)} ${r[i]}`},We=n=>{if(n===null)return null;let t=n*8/(1024*1024);return t<1?`${(t*1024).toFixed(0)} Kbps`:`${t.toFixed(1)} Mbps`},W=n=>{if(n===null)return null;let e=Math.floor(n/3600),t=Math.floor(n%3600/60),s=Math.floor(n%60);return e>0?`${e}h ${t}m`:t>0?`${t}m ${s}s`:`${s}s`};var Ht=1e3,we=class{#t=null;#s=!1;#e=null;#r=null;#n=null;#i=new Map;#a=null;#u=null;#o=null;#c=null;start(){this.#s||(this.#s=!0,this.#i.clear(),this.#a=null,this.#u=null,this.#o=null,this.#c=null,this.#t=setInterval(()=>this.render(),Ht))}stop(){this.#s&&(this.#s=!1,this.#t&&(clearInterval(this.#t),this.#t=null),this.render(),Ke.done())}updateSnapshot(e){this.#e=e}updateBatchState(e){this.#r=e}updateDownloadProgress(e){if(!e){this.#n=null;return}let t=e.percentComplete>=100||e.bytesTransferred>=e.totalBytes;!t&&e.speed>0&&(this.#o=e),this.#n=t&&this.#o?{...e,speed:this.#o.speed,eta:this.#o.eta}:e}persistCurrentBatchLine(){!this.#r||this.#r.currentPhase!=="complete"||this.#i.set(this.#r.currentBatch,this.#f(this.#r))}resetUploadSnapshot(){this.#e=null,this.#n=null,this.#o=null,this.#c=null}render(){if(!this.#s)return;let e=this.#r?this.#D(this.#r):this.#l();Ke(e.join(`
|
|
3
|
+
`))}#m(e,t){let s=[`${m.green(S(t.bytesTransferred))} / ${m.gray(S(t.totalBytes))}`,m.cyan(`${t.percentComplete.toFixed(1)}%`),m.magenta(We(t.speed)??"..."),`${m.yellow("ETA")}: ${m.yellow(W(t.eta)??"...")}`];return`${m.blue(e)}: ${s.join(" | ")}`}#l(){let e=this.#p();return[this.#U(e),this.#F(e)]}#D(e){let t=[];for(let s=1;s<e.currentBatch;s++){let r=this.#i.get(s);r&&t.push(r)}return t.push(this.#f(e)),t.push(this.#v(e)),t}#f(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#n?`${t}: ${this.#m("Downloading",this.#n)}`:`${t}: ${m.blue("Downloading...")}`;case"scanning":return`${t}: ${m.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${m.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#A(t,e);case"cleaning":return`${t}: ${m.yellow("Cleaning...")}`;case"complete":return`${t}: ${m.green("Complete")} (${e.batchFilesTotal} files, ${S(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#A(e,t){let s=this.#p(),r=s.successFileCount+s.failedFileCount+s.cancelledFileCount,i=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),o=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=o>0?(s.uploadedBytes/o*100).toFixed(1):"0.0",l=this.#P(t,s,o),u=l?.formattedSpeed??null,c=l?.formattedTime??null,d=s.totalFileCount>0&&s.totalFileCount<i?`, ${m.gray(`Enqueued: ${s.totalFileCount}/${i}`)}`:"",p=u&&c?`, ${u}, ETA: ${c}`:"",g=t.batchFilesSkipped>0?`, ${m.yellow(`Skipped: ${t.batchFilesSkipped} files / ${S(t.batchBytesSkipped)}`)}`:"",h=o>0&&s.uploadedBytes>=o&&r<i?"Finalizing":"Uploading";return`${e}: ${m.blue(h)} (${r}/${i} files, ${S(s.uploadedBytes)} / ${S(o)}, ${a}%${d}${p}${g})`}#v(e){let t=this.#p(),s=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,r=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+s,o=e.overallBytesCompleted+r,a=Math.max(e.overallBytesTotal-o,0),l=this.#b(e),u=this.#S(e,t),c=l!==null&&u!==null?l+u:null;return[`Total: ${i}/${e.overallFilesTotal} files`,`${S(o)} / ${S(e.overallBytesTotal)}`,m.yellow(`${S(a)} remaining`),`Download ETA: ${W(l)??"..."}`,`Upload ETA: ${W(u)??"..."}`,`Total ETA: ${W(c)??"..."}`].join(", ")}#b(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#n?.bytesTransferred??0),s=Math.max(e.overallBytesTotal-t,0);if(s===0)return e.currentPhase==="downloading"&&this.#n?(this.#a=this.#n.eta,this.#n.eta):(this.#a=0,0);if(this.#n&&this.#n.speed>0){let r=Math.ceil(s/this.#n.speed);return this.#a=r,r}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#a=0,0):this.#a}#S(e,t){let s=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,r=Math.max(e.overallBytesTotal-s,0),i=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=this.#P(e,t,i);if(r===0)return e.currentPhase==="uploading"&&o?(this.#u=o.timeRemainingSeconds,o.timeRemainingSeconds):(this.#u=0,0);if(o&&o.uploadSpeedMbps>0){let a=o.uploadSpeedMbps*1024*1024/8,l=Math.ceil(r/a);return this.#u=l,l}return this.#u}#P(e,t,s){let r=this.#e?.uploadStats,i=s>0&&t.uploadedBytes>=s;return r&&r.uploadSpeedMbps>0&&r.formattedSpeed!=="Calculating..."&&!i?(this.#c={uploadSpeedMbps:r.uploadSpeedMbps,formattedSpeed:r.formattedSpeed,formattedTime:r.formattedTime,timeRemainingSeconds:r.timeRemainingSeconds},this.#c):e.currentPhase==="uploading"&&i&&this.#c?this.#c:r?{uploadSpeedMbps:r.uploadSpeedMbps,formattedSpeed:r.formattedSpeed,formattedTime:r.formattedTime,timeRemainingSeconds:r.timeRemainingSeconds}:null}#U(e){return[`Total: ${e.totalFileCount}`,m.green(`Success: ${e.successFileCount}`),m.red(`Failed: ${e.failedFileCount}`),m.red(`Cancelled: ${e.cancelledFileCount}`),m.blue(`Active: ${e.activeFileCount}`),m.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#F(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),s=this.#e?` | ${m.cyan(`Speed: ${this.#e.uploadStats.formattedSpeed}`)} | ${m.magenta(`Time remaining: ${this.#e.uploadStats.formattedTime}`)}`:"";return[`Total: ${S(e.totalBytes)}`,m.green(`Uploaded: ${S(e.uploadedBytes)}`),m.yellow(`Remaining: ${S(t)}`)].join(" | ")+s}#p(){return this.#e?Object.values(this.#e.uploadAssets).reduce((t,s)=>{switch(t.totalFileCount+=1,t.totalBytes+=s.totalBytesToUpload,t.uploadedBytes+=s.status==="success"?s.totalBytesToUpload:s.bytesUploaded,s.status){case"success":t.successFileCount+=1;break;case"failed":t.failedFileCount+=1;break;case"cancelled":t.cancelledFileCount+=1;break;case"in-progress":t.activeFileCount+=1;break;default:t.queuedFileCount+=1;break}return t},{totalFileCount:0,successFileCount:0,failedFileCount:0,cancelledFileCount:0,activeFileCount:0,queuedFileCount:0,uploadedBytes:0,totalBytes:0}):{totalFileCount:0,successFileCount:0,failedFileCount:0,cancelledFileCount:0,activeFileCount:0,queuedFileCount:0,uploadedBytes:0,totalBytes:0}}},C=new we;import{Readable as jt}from"node:stream";import Ye from"axios";var v=class{#t;#s;#e;#r;#n=new q;#i=new Set;constructor(e){this.#t=Ye.create({baseURL:e.apiUrl}),this.#s=Ye.create({baseURL:e.edgeWorkerUrl}),this.#e=e.apiKey,this.#r=e.sessionId}get skippedAssetIds(){return this.#i}async post(e,t,s){let r=await this.#t.post(e,t,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,"Content-Type":"application/json",...s}});return this.#u(e,t,r.data),r.data}async get(e,t){return(await this.#t.get(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,...t}})).data}async delete(e,t){await this.#t.delete(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,...t}})}async putWithToken(e,t,s,r){let i=await this.#a(t),o=this.#n.createIterator(i,r.limiter??null,r.signal),a=jt.from(o,{highWaterMark:1}),l=await this.#s.put(e,a,{timeout:0,signal:r.signal,headers:{"Content-Type":r.contentType??"","Content-Length":i.byteLength.toString(),Authorization:`Bearer ${s}`},transformRequest:[u=>u],maxRedirects:0,onUploadProgress:u=>r.onProgress?.(u.loaded)});return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#a(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#u(e,t,s){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(s))return;let r=t;s.forEach((o,a)=>{let l=r[a];o.skipped===!0&&typeof l?.id=="string"&&this.#i.add(l.id)})}};import Y from"node:path";import k from"node:path";function b(n){let e=n.replace(/\\/g,"/");if(e.split("/").some(i=>i===".."))throw new Error(`Remote path cannot contain parent directory segments: ${n}`);let r=k.posix.normalize(e).replace(/^\/+/,"");if(r===""||r===".")throw new Error(`Remote path must resolve to a file path: ${n}`);return r}function Qe(n){let e=new Map;for(let i of n){let o=b(i.targetPath??i.path);e.set(o,(e.get(o)??0)+1)}let t=new Set,s=[],r=[];for(let i of n){let o=b(i.path),a=b(i.targetPath??i.path),l=K(a),u=Ie(l,t),c=(e.get(a)??0)>1,d=u!==o;t.add(u),s.push({...i,targetPath:u,requiresIdentityDownload:i.requiresIdentityDownload===!0||c}),(d||c)&&r.push({sourcePath:i.path,targetPath:u,reason:c||u!==l?"duplicate":"sanitized"})}return{files:s,changes:r}}function w(n){return b(n.targetPath??n.path)}function Xe(n,e){let t=w(n);return{relativePath:t,absolutePath:k.join(e,t),fileName:k.posix.basename(t),size:n.size}}function K(n){return n.split("/").map(t=>B(t)).join("/")}function Ie(n,e){if(!e.has(n))return n;let t=k.posix.dirname(n),s=k.posix.basename(n),r=k.posix.extname(s),i=r.length>0?s.slice(0,-r.length):s,o=2;for(;;){let a=`${i} (${o})${r}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;o+=1}}function xe(n,e){if(!e.has(n))return n;let t=k.posix.dirname(n),s=k.posix.basename(n),r=2;for(;;){let i=`${s} ${r}`,o=t==="."?i:`${t}/${i}`;if(!e.has(o))return o;r+=1}}var Ve=500,qt=8,oe=class{#t;#s;#e=new Map;constructor(e){this.#t=e.rootDirectoryId,this.#s=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#r(e);for(let s of t){if(this.#e.has(s))continue;let r=Y.posix.dirname(s),i=Y.posix.basename(s),o=r==="."?this.#t:this.#e.get(r);if(!o)throw new Error(`Parent directory ID not found for path: ${s}`);let a=await this.#o(o,i);if(a.name!==i)throw new Error(`Server created renamed directory "${a.name}" for planned path "${s}". Refusing to map uploads to an unexpected target path.`);this.#e.set(s,a.id)}return e.map(s=>({file:s,directoryId:this.getDirectoryIdForFile(s.relativePath)}))}async loadExistingDirectories(){let e=await this.#n(this.#t);this.#e.clear(),this.#u(e,"")}getDirectoryIdForFile(e){let t=b(e),s=Y.posix.dirname(t);if(s===".")return this.#t;let r=this.#e.get(s);if(!r)throw new Error(`Directory ID not found for path: ${s}`);return r}getExistingDirectoryIdForFile(e){let t=b(e),s=Y.posix.dirname(t);return s==="."?this.#t:this.#e.get(s)??null}async checkAssetsExistence(e,t=!0){if(e.length===0)return[];let s=[];for(let r=0;r<e.length;r+=Ve){let i=e.slice(r,r+Ve),o=await this.#s.post("/assets/check-exists-and-uploaded",{items:i,delete_if_not_exist:t});s.push(...o.items)}return s}async listFilesInSubtree(e={}){let t=[{id:this.#t,relativePath:""}],s=[],r=0;for(;r<t.length;){let i=t.slice(r,r+qt),o=await Promise.all(i.map(a=>this.#i(a)));r+=i.length;for(let a of o)t.push(...a.directories),s.push(...a.files);e.onProgress?.({scannedDirectoryCount:r,queuedDirectoryCount:t.length,fileCount:s.length})}return s}#r(e){let t=new Set;for(let s of e){let r=b(s.relativePath),i=Y.posix.dirname(r);if(i===".")continue;let o=i.split("/");for(let a=0;a<o.length;a++)t.add(o.slice(0,a+1).join("/"))}return Array.from(t).sort((s,r)=>s.split("/").length-r.split("/").length)}async#n(e){return this.#s.get(`/directories/${e}/tree`)}async#i(e){let[t,s]=await Promise.all([this.#s.post("/fs/list/directories",{parent_id:e.id}),this.#s.post("/fs/list/assets",{parent_id:e.id})]);return{directories:t.map(r=>({id:r.id,relativePath:this.#a(e.relativePath,r.name)})),files:s.map(r=>({assetId:r.id,relativePath:this.#a(e.relativePath,r.name),sizeBytes:r.size_bytes,isUploaded:r.is_uploaded??!0,uploadStateKnown:typeof r.is_uploaded=="boolean"}))}}#a(e,t){let s=e===""?t:`${e}/${t}`;return b(s)}#u(e,t){let s=t===""?"":t==="."?e.name:`${t}/${e.name}`;s!==""&&this.#e.set(s,e.id);for(let r of e.children){let i=t===""?".":s;this.#u(r,i)}}async#o(e,t){return this.#s.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as Wt}from"posthog-node";var _=null,ae="",_e={};function Je(n){_||n.config.analytics.disabled||!n.config.analytics.posthogKey||(ae=n.user.id,_e={service:"data-sync",package_version:n.packageVersion,platform:process.platform,arch:process.arch,node_version:process.version,max_concurrent:n.config.maxConcurrent,batch_mode:n.config.batchSizeBytes!==void 0,batch_size_bytes:n.config.batchSizeBytes??null,source_kind:n.config.source.kind,...n.config.source.kind==="rclone"?{rclone_transfers:n.config.source.rcloneOptions.transfers,rclone_multi_thread_streams:n.config.source.rcloneOptions.multiThreadStreams}:{}},_=new Wt(n.config.analytics.posthogKey,{host:n.config.analytics.posthogHost}),_.identify({distinctId:ae,properties:{user_id:n.user.id,email:n.user.email,first_name:n.user.first_name,last_name:n.user.last_name,utm_source_latest:null,utm_medium_latest:null,utm_campaign_latest:null,utm_content_latest:null}}))}function Ze(n,e){_&&_.capture({distinctId:ae,event:n,properties:{..._e,...e}})}async function et(){let n=_;if(Kt(),!!n)try{await n.flush()}catch{}}function Kt(){_=null,ae="",_e={}}import{spawn as le}from"child_process";import*as Le from"fs";import*as Q from"path";var T=class extends Error{constructor(t,s){super(t);this.stderr=s;this.name="RcloneError"}stderr};function Yt(n){let e=["sync",n.remoteSource,n.localPath];return n.batchFilePath&&e.push("--files-from",n.batchFilePath),e.push("--progress","--stats","1s","--stats-one-line","-v","--transfers",String(n.rcloneOptions.transfers),"--checkers",String(n.rcloneOptions.checkers),"--multi-thread-streams",String(n.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",n.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",n.rcloneOptions.multiThreadCutoff,"--fast-list","--buffer-size",n.rcloneOptions.bufferSize),n.rcloneOptions.useMmap&&e.push("--use-mmap"),n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function Qt(n){let e=["lsjson",n.remoteSource,"--recursive","--fast-list"];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function Xt(n){let e=["backend","query",`${n.remote}:`,n.query];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function Vt(n){let e=["copyto",n.remoteFileSource,n.localTargetPath,"--progress","--stats","1s","--stats-one-line","-v","--multi-thread-streams",String(n.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",n.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",n.rcloneOptions.multiThreadCutoff,"--buffer-size",n.rcloneOptions.bufferSize];return n.rcloneOptions.useMmap&&e.push("--use-mmap"),n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function Jt(n){let e=["backend","copyid",`${n.remote}:`,n.fileId,n.localTargetPath];return n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function O(n,e){let t=e.trim(),s={B:1,k:1024,Ki:1024,KiB:1024,kB:1e3,M:1024*1024,Mi:1024*1024,MiB:1024*1024,MB:1e3*1e3,G:1024*1024*1024,Gi:1024*1024*1024,GiB:1024*1024*1024,GB:1e3*1e3*1e3,T:1024*1024*1024*1024,Ti:1024*1024*1024*1024,TiB:1024*1024*1024*1024,TB:1e3*1e3*1e3*1e3};return n*(s[t]||1)}function tt(n){let e=0,t=n.match(/(\d+)h/),s=n.match(/(\d+)m/),r=n.match(/(\d+)s/);return t&&(e+=parseInt(t[1],10)*3600),s&&(e+=parseInt(s[1],10)*60),r&&(e+=parseInt(r[1],10)),e}function Zt(n){let e=n.trim(),t=/^([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%?,\s*([\d.]+)\s*([A-Za-z]+)\/s,\s*ETA\s+(.+)$/,s=e.match(t);if(s){let a=s[8].trim();return{bytesTransferred:O(parseFloat(s[1]),s[2]),totalBytes:O(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:O(parseFloat(s[6]),s[7]),eta:a==="-"?0:tt(a)}}let r=e.match(/Transferred:\s+([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%/);if(!r)return null;let i=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),o=e.match(/ETA\s+([^\s]+)$/);return{bytesTransferred:O(parseFloat(r[1]),r[2]),totalBytes:O(parseFloat(r[3]),r[4]),percentComplete:parseFloat(r[5]),speed:i?O(parseFloat(i[1]),i[2]):0,eta:o&&o[1]!=="-"?tt(o[1]):0}}function De(n){return new Promise((e,t)=>{let s=le("rclone",n.args,{stdio:["ignore","pipe","pipe"]}),r="",i=0,o=a=>{for(let l of a.split(`
|
|
4
|
+
`)){if(l.trim().length===0)continue;let u=Zt(l);if(!u)continue;let c=Date.now();!(u.percentComplete>=100)&&c-i<500||(i=c,n.onProgress?.(u))}};s.stdout.on("data",a=>{o(a.toString())}),s.stderr.on("data",a=>{let l=a.toString();r+=l,o(l)}),s.on("close",async a=>{a===0?e():t(new T(`rclone exited with code ${a}`,r))}),s.on("error",a=>{t(new T(`Failed to start rclone: ${a.message}`,""))})})}async function st(){return new Promise((n,e)=>{let t=le("rclone",["version"]);t.on("error",()=>{e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))}),t.on("close",s=>{s===0?n():e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))})})}async function es(n,e,t,s,r,i){let o=`${n}:${e}`;return De({args:Yt({remoteSource:o,localPath:t,rcloneOptions:r,batchFilePath:s}),remoteSource:o,onProgress:i})}async function rt(n,e,t=[]){let s=`${n}:${e}`;return new Promise((r,i)=>{let o=le("rclone",Qt({remoteSource:s,extraArgs:t})),a="",l="";o.stdout.on("data",u=>{a+=u.toString()}),o.stderr.on("data",u=>{l+=u.toString()}),o.on("close",async u=>{if(u===0)try{let c=JSON.parse(a||"[]");if(!Array.isArray(c))throw new Error("rclone lsjson did not return an array");let d=ts(c),p=await ss({remote:n,files:d.files,directories:d.directories,extraArgs:t});r(p)}catch(c){i(new T(`Failed to parse file listing from ${s}: ${c instanceof Error?c.message:String(c)}`,l))}else i(new T(`Failed to list files from ${s}`,l))}),o.on("error",u=>{i(new T(`Failed to start rclone: ${u.message}`,""))})})}async function nt(n){let e=[],t=[];for(let s of n.files)ls(s)?t.push(s):e.push(s);e.length>0&&(await Le.promises.writeFile(n.batchFilePath,`${e.map(s=>s.path).join(`
|
|
4
5
|
`)}
|
|
5
|
-
`,"utf-8"),await
|
|
6
|
-
`))}#y(e,t){let s=[`${f.green(y(t.bytesTransferred))} / ${f.gray(y(t.totalBytes))}`,f.cyan(`${t.percentComplete.toFixed(1)}%`),f.magenta(ze(t.speed)??"..."),`${f.yellow("ETA")}: ${f.yellow($(t.eta)??"...")}`];return`${f.blue(e)}: ${s.join(" | ")}`}#f(){let e=this.#d();return[this.#R(e),this.#C(e)]}#x(e){let t=[];for(let s=1;s<e.currentBatch;s++){let r=this.#i.get(s);r&&t.push(r)}return t.push(this.#g(e)),t.push(this.#P(e)),t}#g(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#o?`${t}: ${this.#y("Downloading",this.#o)}`:`${t}: ${f.blue("Downloading...")}`;case"scanning":return`${t}: ${f.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${f.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#D(t,e);case"cleaning":return`${t}: ${f.yellow("Cleaning...")}`;case"complete":return`${t}: ${f.green("Complete")} (${e.batchFilesTotal} files, ${y(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#D(e,t){let s=this.#d(),r=s.successFileCount+s.failedFileCount+s.cancelledFileCount,i=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),o=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=o>0?(s.uploadedBytes/o*100).toFixed(1):"0.0",l=this.#S(t,s,o),u=l?.formattedSpeed??null,c=l?.formattedTime??null,d=u&&c?`, ${u}, ETA: ${c}`:"",h=t.batchFilesSkipped>0?`, ${f.yellow(`Skipped: ${t.batchFilesSkipped} files / ${y(t.batchBytesSkipped)}`)}`:"",p=o>0&&s.uploadedBytes>=o&&r<i?"Finalizing":"Uploading";return`${e}: ${f.blue(p)} (${r}/${i} files, ${y(s.uploadedBytes)} / ${y(o)}, ${a}%${d}${h})`}#P(e){let t=this.#d(),s=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,r=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+s,o=e.overallBytesCompleted+r,a=Math.max(e.overallBytesTotal-o,0),l=this.#A(e),u=this.#v(e,t),c=l!==null&&u!==null?l+u:null;return[`Total: ${i}/${e.overallFilesTotal} files`,`${y(o)} / ${y(e.overallBytesTotal)}`,f.yellow(`${y(a)} remaining`),`Download ETA: ${$(l)??"..."}`,`Upload ETA: ${$(u)??"..."}`,`Total ETA: ${$(c)??"..."}`].join(", ")}#A(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#o?.bytesTransferred??0),s=Math.max(e.overallBytesTotal-t,0);if(s===0)return e.currentPhase==="downloading"&&this.#o?(this.#a=this.#o.eta,this.#o.eta):(this.#a=0,0);if(this.#o&&this.#o.speed>0){let r=Math.ceil(s/this.#o.speed);return this.#a=r,r}return this.#a}#v(e,t){let s=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,r=Math.max(e.overallBytesTotal-s,0),i=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=this.#S(e,t,i);if(r===0)return e.currentPhase==="uploading"&&o?(this.#l=o.timeRemainingSeconds,o.timeRemainingSeconds):(this.#l=0,0);if(o&&o.uploadSpeedMbps>0){let a=o.uploadSpeedMbps*1024*1024/8,l=Math.ceil(r/a);return this.#l=l,l}return this.#l}#S(e,t,s){let r=this.#e?.uploadStats,i=s>0&&t.uploadedBytes>=s;return r&&r.uploadSpeedMbps>0&&r.formattedSpeed!=="Calculating..."&&!i?(this.#u={uploadSpeedMbps:r.uploadSpeedMbps,formattedSpeed:r.formattedSpeed,formattedTime:r.formattedTime,timeRemainingSeconds:r.timeRemainingSeconds},this.#u):e.currentPhase==="uploading"&&i&&this.#u?this.#u:r?{uploadSpeedMbps:r.uploadSpeedMbps,formattedSpeed:r.formattedSpeed,formattedTime:r.formattedTime,timeRemainingSeconds:r.timeRemainingSeconds}:null}#R(e){return[`Total: ${e.totalFileCount}`,f.green(`Success: ${e.successFileCount}`),f.red(`Failed: ${e.failedFileCount}`),f.red(`Cancelled: ${e.cancelledFileCount}`),f.blue(`Active: ${e.activeFileCount}`),f.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#C(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),s=this.#e?` | ${f.cyan(`Speed: ${this.#e.uploadStats.formattedSpeed}`)} | ${f.magenta(`Time remaining: ${this.#e.uploadStats.formattedTime}`)}`:"";return[`Total: ${y(e.totalBytes)}`,f.green(`Uploaded: ${y(e.uploadedBytes)}`),f.yellow(`Remaining: ${y(t)}`)].join(" | ")+s}#d(){return this.#e?Object.values(this.#e.uploadAssets).reduce((t,s)=>{switch(t.totalFileCount+=1,t.totalBytes+=s.totalBytesToUpload,t.uploadedBytes+=s.status==="success"?s.totalBytesToUpload:s.bytesUploaded,s.status){case"success":t.successFileCount+=1;break;case"failed":t.failedFileCount+=1;break;case"cancelled":t.cancelledFileCount+=1;break;case"in-progress":t.activeFileCount+=1;break;default:t.queuedFileCount+=1;break}return t},{totalFileCount:0,successFileCount:0,failedFileCount:0,cancelledFileCount:0,activeFileCount:0,queuedFileCount:0,uploadedBytes:0,totalBytes:0}):{totalFileCount:0,successFileCount:0,failedFileCount:0,cancelledFileCount:0,activeFileCount:0,queuedFileCount:0,uploadedBytes:0,totalBytes:0}}},S=new Te;import{Readable as Nt}from"node:stream";import $e from"axios";var P=class{#t;#s;#e;#n;#o=new G;#i=new Set;constructor(e){this.#t=$e.create({baseURL:e.apiUrl}),this.#s=$e.create({baseURL:e.edgeWorkerUrl}),this.#e=e.apiKey,this.#n=e.sessionId}get skippedAssetIds(){return this.#i}async post(e,t,s){let r=await this.#t.post(e,t,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#n,"Content-Type":"application/json",...s}});return this.#l(e,t,r.data),r.data}async get(e,t){return(await this.#t.get(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#n,...t}})).data}async delete(e,t){await this.#t.delete(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#n,...t}})}async putWithToken(e,t,s,r){let i=await this.#a(t),o=this.#o.createIterator(i,r.getMaxUploadRate??(()=>null),r.signal),a=Nt.from(o,{highWaterMark:1}),l=await this.#s.put(e,a,{timeout:0,signal:r.signal,headers:{"Content-Type":r.contentType??"","Content-Length":i.byteLength.toString(),Authorization:`Bearer ${s}`},transformRequest:[u=>u],maxRedirects:0,onUploadProgress:u=>r.onProgress?.(u.loaded)});return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#a(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#l(e,t,s){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(s))return;let r=t;s.forEach((o,a)=>{let l=r[a];o.skipped===!0&&typeof l?.id=="string"&&this.#i.add(l.id)})}};import j from"node:path";var je=500,Gt=8,ee=class{#t;#s;#e=new Map;constructor(e){this.#t=e.rootDirectoryId,this.#s=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#n(e);for(let s of t){if(this.#e.has(s))continue;let r=j.posix.dirname(s),i=j.posix.basename(s),o=r==="."?this.#t:this.#e.get(r);if(!o)throw new Error(`Parent directory ID not found for path: ${s}`);let a=await this.#r(o,i);if(a.name!==i)throw new Error(`Server created renamed directory "${a.name}" for planned path "${s}". Refusing to map uploads to an unexpected target path.`);this.#e.set(s,a.id)}return e.map(s=>({file:s,directoryId:this.getDirectoryIdForFile(s.relativePath)}))}async loadExistingDirectories(){let e=await this.#o(this.#t);this.#e.clear(),this.#l(e,"")}getDirectoryIdForFile(e){let t=b(e),s=j.posix.dirname(t);if(s===".")return this.#t;let r=this.#e.get(s);if(!r)throw new Error(`Directory ID not found for path: ${s}`);return r}getExistingDirectoryIdForFile(e){let t=b(e),s=j.posix.dirname(t);return s==="."?this.#t:this.#e.get(s)??null}async checkAssetsExistence(e,t=!0){if(e.length===0)return[];let s=[];for(let r=0;r<e.length;r+=je){let i=e.slice(r,r+je),o=await this.#s.post("/assets/check-exists-and-uploaded",{items:i,delete_if_not_exist:t});s.push(...o.items)}return s}async listFilesInSubtree(e={}){let t=[{id:this.#t,relativePath:""}],s=[],r=0;for(;r<t.length;){let i=t.slice(r,r+Gt),o=await Promise.all(i.map(a=>this.#i(a)));r+=i.length;for(let a of o)t.push(...a.directories),s.push(...a.files);e.onProgress?.({scannedDirectoryCount:r,queuedDirectoryCount:t.length,fileCount:s.length})}return s}#n(e){let t=new Set;for(let s of e){let r=b(s.relativePath),i=j.posix.dirname(r);if(i===".")continue;let o=i.split("/");for(let a=0;a<o.length;a++)t.add(o.slice(0,a+1).join("/"))}return Array.from(t).sort((s,r)=>s.split("/").length-r.split("/").length)}async#o(e){return this.#s.get(`/directories/${e}/tree`)}async#i(e){let[t,s]=await Promise.all([this.#s.post("/fs/list/directories",{parent_id:e.id}),this.#s.post("/fs/list/assets",{parent_id:e.id})]);return{directories:t.map(r=>({id:r.id,relativePath:this.#a(e.relativePath,r.name)})),files:s.map(r=>({assetId:r.id,relativePath:this.#a(e.relativePath,r.name),sizeBytes:r.size_bytes,isUploaded:r.is_uploaded??!0,uploadStateKnown:typeof r.is_uploaded=="boolean"}))}}#a(e,t){let s=e===""?t:`${e}/${t}`;return b(s)}#l(e,t){let s=t===""?"":t==="."?e.name:`${t}/${e.name}`;s!==""&&this.#e.set(s,e.id);for(let r of e.children){let i=t===""?".":s;this.#l(r,i)}}async#r(e,t){return this.#s.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as zt}from"posthog-node";var I=null,te="",Re={};function qe(n){I||n.config.analytics.disabled||!n.config.analytics.posthogKey||(te=n.user.id,Re={service:"data-sync",package_version:n.packageVersion,platform:process.platform,arch:process.arch,node_version:process.version,max_concurrent:n.config.maxConcurrent,batch_mode:n.config.batchSizeBytes!==void 0,batch_size_bytes:n.config.batchSizeBytes??null,rclone_transfers:n.config.rcloneOptions.transfers,rclone_multi_thread_streams:n.config.rcloneOptions.multiThreadStreams},I=new zt(n.config.analytics.posthogKey,{host:n.config.analytics.posthogHost}),I.identify({distinctId:te,properties:{user_id:n.user.id,email:n.user.email,first_name:n.user.first_name,last_name:n.user.last_name,utm_source_latest:null,utm_medium_latest:null,utm_campaign_latest:null,utm_content_latest:null}}))}function Ke(n,e){I&&I.capture({distinctId:te,event:n,properties:{...Re,...e}})}async function We(){let n=I;if(Ht(),!!n)try{await n.flush()}catch{}}function Ht(){I=null,te="",Re={}}import*as re from"fs/promises";import*as ne from"path";var $t={".mp4":"video/mp4",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".webm":"video/webm",".wmv":"video/x-ms-wmv",".flv":"video/x-flv",".m4v":"video/x-m4v",".mpg":"video/mpeg",".mpeg":"video/mpeg",".3gp":"video/3gpp",".ts":"video/mp2t",".mts":"video/mp2t",".mxf":"application/mxf",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".svg":"image/svg+xml",".heic":"image/heic",".heif":"image/heif",".avif":"image/avif",".mp3":"audio/mpeg",".wav":"audio/wav",".aac":"audio/aac",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".wma":"audio/x-ms-wma",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".rtf":"application/rtf",".json":"application/json",".xml":"application/xml"};function jt(n){let e=ne.extname(n).toLowerCase();return $t[e]??""}var se=class n{#t;#s=null;#e=null;#n=!1;#o;#i;#a;constructor(e,t,s,r){this.#t=e,this.#o=t,this.#i=s,this.#a=r}static async create(e){let t=await re.stat(e),s=ne.basename(e),r=jt(s);return new n(e,t.size,s,r)}get name(){return this.#i}get size(){return this.#o}get type(){return this.#a}async readChunk(e,t){if(!this.#s){this.#e||(this.#e=re.open(this.#t,"r"));let i=await this.#e;if(this.#e=null,this.#n)return Buffer.alloc(0);this.#s=i}let s=t-e,r=Buffer.alloc(s);return await this.#s.read(r,0,s,e),r}async close(){this.#n=!0;let e=this.#e;await this.#s?.close(),this.#s=null,e&&await(await e.catch(()=>null))?.close(),this.#e=null}};var qt=new Set(["success","failed","cancelled"]),Ye=1e3,Kt=4*1024*1024,ie=class{#t;#s;#e;#n;#o;constructor(e){this.#t=e.config,this.#s=e.httpClient??new P({apiUrl:e.config.apiUrl,apiKey:e.config.apiKey,edgeWorkerUrl:e.config.edgeWorkerUrl,sessionId:e.config.sessionName}),this.#e=e.createFileReader??(t=>se.create(t)),this.#n=e.onSnapshot,this.#o=e.analytics}async uploadFiles(e){let t=e.filter(o=>o.preSkipped===!0),s=e.filter(o=>o.preSkipped!==!0);if(s.length===0)return{totalFileCount:e.length,successFileCount:0,skippedFileCount:t.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};let r=new N({httpClient:this.#s,maxConcurrency:this.#t.maxConcurrent,deltaIntervalMs:Ye,adaptiveConcurrency:!1,analytics:this.#o}),i=[];try{let o=r.startGroupUpload({name:`${s.length} files`,type:"files",fileCount:s.length,folderCount:0,topLevelFileCount:s.length,topLevelFolderCount:0,rootDirectoryId:this.#t.directoryId,projectId:this.#t.projectId,totalBytes:s.reduce((l,u)=>l+u.file.size,0),conflictResolutionOverride:"skip"});for(let l of s){let u=await this.#e(l.file.absolutePath),c=r.startUpload({fileReader:u,directoryId:l.directoryId,projectId:this.#t.projectId,groupId:o,chunkSize:Kt});r.addAssetToGroup(o,c),i.push({assetId:c,file:l.file,fileReader:u})}await this.#i(r);let a=r.getSnapshot();return this.#n?.(a),this.#a({snapshot:a,startedUploads:i,preSkippedCount:t.length})}finally{r.destroy()}}async#i(e){let s=Date.now();for(;Date.now()-s<864e5;){let r=e.getSnapshot();this.#n?.(r);let i=Object.values(r.uploadAssets);if(i.length>0&&i.every(o=>qt.has(o.status)))return;await new Promise(o=>setTimeout(o,Ye))}throw new Error("Timed out waiting for upload session to finish")}#a(e){let t=[],s=0,r=0,i=0,o=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:"Upload state missing from upload engine"});continue}if(l.status==="success"){this.#s.skippedAssetIds.has(a.assetId)?r+=1:s+=1;continue}l.status==="cancelled"?o+=1:i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:s,skippedFileCount:e.preSkippedCount+r,failedFileCount:i,cancelledFileCount:o,failedFiles:t}}};var oe=200,ae=class{#t;#s;#e;#n;constructor(e,t){this.#t=e,this.#s=t??new P({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#e=new ee({rootDirectoryId:e.directoryId,httpClient:this.#s}),this.#n=new ie({config:e,httpClient:this.#s,onSnapshot:s=>S.updateSnapshot(s),analytics:Ke})}async run(){this.#P("Starting data sync..."),await this.#u(),console.log("Listing all remote files...");let e=await Z(this.#t.remote,this.#t.remotePath,this.#t.rcloneOptions.extraRcloneArgs??[]);console.log(`Found ${e.length} files`),console.log(`Total size: ${y(this.#p(e))}`),console.log("");let t=this.#l(e);if(t.length===0){console.log("No files to sync. Exiting."),await this.#y();return}let s={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},r=[],i={batchNumber:1,files:t,totalSize:this.#p(t)};S.start();try{let a=await this.#r({batch:i,totalBatches:1,overallFilesTotal:t.length,overallBytesTotal:i.totalSize,completedTotals:s,batchDir:this.#t.localTempDir});this.#k(s,r,a,i.totalSize)}finally{S.stop()}let o={...s,failedFiles:r};this.#A({summary:o}),await this.#f(o),this.#h(o)}async runBatched(){if(!this.#t.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#P("Starting batched data sync...",[`Batch size: ${y(this.#t.batchSizeBytes)}`,`Max concurrent chunks: ${this.#t.maxConcurrent}`]),await this.#u(),console.log("Listing all remote files...");let e=await Z(this.#t.remote,this.#t.remotePath,this.#t.rcloneOptions.extraRcloneArgs??[]);console.log(`Found ${e.length} files`),console.log(`Total size: ${y(this.#p(e))}`),console.log("");let t=this.#l(e);if(t.length===0){console.log("No files to sync. Exiting."),await this.#y();return}let s=Ne(t,this.#t.batchSizeBytes);await this.#D(s);let r={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},i=[],o=this.#p(t);S.start();try{for(let l of s){let u=await this.#r({batch:l,totalBatches:s.length,overallFilesTotal:t.length,overallBytesTotal:o,completedTotals:r});this.#k(r,i,u,l.totalSize)}}finally{S.stop()}this.#A({summary:{...r,failedFiles:i},extraLines:[`Batches: ${s.length}`]});let a={...r,failedFiles:i};await this.#f(a),this.#h(a)}async runCheckOnly(){console.log("Running in check-only mode (no downloads/uploads)..."),await Ee(),console.log(`Listing remote files from ${this.#t.remote}:${this.#t.remotePath}...`);let e=await Z(this.#t.remote,this.#t.remotePath,this.#t.rcloneOptions.extraRcloneArgs??[]);console.log(`Found ${e.length} remote files to check`);let t=this.#l(e);if(t.length===0){console.log("No remote files to check. Exiting.");return}console.log("Fetching existing Aspect files...");let s=await this.#e.listFilesInSubtree({onProgress:i=>this.#v(i)}),r=this.#o(t,s);this.#S(r)}#o(e,t){let s=e.map(m=>({relativePath:k(m),sizeBytes:m.size})),r=t.filter(m=>m.isUploaded),i=t.filter(m=>m.uploadStateKnown&&!m.isUploaded),o=t.filter(m=>!m.uploadStateKnown).length;o>0&&(console.warn(`Warning: ${o} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),console.log(""));let a=this.#i(s),l=this.#a(r),u=new Set([...a.keys(),...l.keys()]),c=0,d=[],h=[],p=[];for(let m of u){let C=a.get(m)??[],g=l.get(m)??[],A=new Set,Fe=[];for(let E of C){let v=g.findIndex((x,le)=>!A.has(le)&&x.sizeBytes===E.sizeBytes);v>=0?(c+=1,A.add(v)):Fe.push(E)}for(let E of Fe){let v=g.findIndex((x,le)=>!A.has(le));if(v>=0){let x=g[v];A.add(v),h.push({relativePath:m,remoteSizeBytes:E.sizeBytes,serverSizeBytes:x.sizeBytes,assetId:x.assetId})}else d.push(E)}for(let E=0;E<g.length;E++)A.has(E)||p.push(g[E])}return{totalRemoteCount:e.length,totalServerCount:t.length,uploadedServerCount:r.length,unknownUploadStateCount:o,existingCount:c,missingFiles:d,sizeMismatches:h,extraUploadedFiles:p,incompleteServerFiles:i}}#i(e){let t=new Map;for(let s of e){let r=b(s.relativePath),i=t.get(r)??[];i.push({...s,relativePath:r}),t.set(r,i)}return t}#a(e){let t=new Map;for(let s of e){let r=b(s.relativePath),i=t.get(r)??[];i.push({...s,relativePath:r}),t.set(r,i)}return t}#l(e){let t=we(e);if(t.changes.length===0)return t.files;let s=t.changes.slice(0,10).map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
|
|
6
|
+
`,"utf-8"),await es(n.remote,n.remotePath,n.localPath,n.batchFilePath,n.rcloneOptions,n.onProgress));for(let s of t)await us({remote:n.remote,remotePath:n.remotePath,localPath:n.localPath,file:s,rcloneOptions:n.rcloneOptions,onProgress:n.onProgress})}function ts(n){let e=[],t=[];for(let s of n){let r=s;if(typeof r.Path!="string")continue;let i=typeof r.ID=="string"&&r.ID.length>0?r.ID:void 0;if(r.IsDir===!0){t.push({path:b(r.Path),id:i});continue}let o=typeof r.Size=="number"&&Number.isFinite(r.Size)?r.Size:0;e.push({path:b(r.Path),size:o,id:i})}return{files:e,directories:t}}async function ss(n){let e=rs(n.directories);if(e.length===0)return n.files;let t=e.map(o=>o[0].path),s=n.files.filter(o=>!t.some(a=>ot(o.path,a))),r=ns(n.directories),i=[];for(let o of e)for(let a of o){if(!a.id)throw new Error(`Cannot preserve duplicate remote folder without a stable rclone folder ID: ${a.path}`);let l=K(a.path),u=xe(l,r);r.add(u),i.push(...await it({remote:n.remote,parentId:a.id,sourcePrefix:a.path,targetPrefix:u,extraArgs:n.extraArgs}))}return[...s,...i]}function rs(n){let e=new Map;for(let i of n){let o=e.get(i.path)??[];o.push(i),e.set(i.path,o)}let t=Array.from(e.values()).filter(i=>i.length>1).sort((i,o)=>i[0].path.split("/").length-o[0].path.split("/").length),s=[],r=[];for(let i of t){let o=i[0].path;r.some(a=>ot(o,a))||(r.push(o),s.push(i))}return s}function ns(n){let e=new Map;for(let s of n)e.set(s.path,(e.get(s.path)??0)+1);let t=new Set;for(let s of n)(e.get(s.path)??0)>1||t.add(K(s.path));return t}async function it(n){let e=await is({remote:n.remote,parentId:n.parentId,extraArgs:n.extraArgs}),t=new Set,s=[];for(let r of e){if(typeof r.name!="string"||typeof r.id!="string")continue;let i=`${n.sourcePrefix}/${r.name}`,o=`${n.targetPrefix}/${K(r.name)}`,a=r.mimeType==="application/vnd.google-apps.folder"?xe(o,t):Ie(o,t);if(t.add(a),r.mimeType==="application/vnd.google-apps.folder"){s.push(...await it({remote:n.remote,parentId:r.id,sourcePrefix:i,targetPrefix:a,extraArgs:n.extraArgs}));continue}s.push({path:i,targetPath:a,size:os(r.size),id:r.id,requiresIdentityDownload:!0})}return s}function is(n){let e=`'${as(n.parentId)}' in parents and trashed = false`;return new Promise((t,s)=>{let r=le("rclone",Xt({remote:n.remote,query:e,extraArgs:n.extraArgs}),{stdio:["ignore","pipe","pipe"]}),i="",o="";r.stdout.on("data",a=>{i+=a.toString()}),r.stderr.on("data",a=>{o+=a.toString()}),r.on("close",a=>{if(a!==0){s(new T(`Failed to query children for Google Drive folder ${n.parentId}`,o));return}try{let l=JSON.parse(i||"[]");if(!Array.isArray(l))throw new Error("rclone backend query did not return an array");t(l)}catch(l){s(new T(`Failed to parse children for Google Drive folder ${n.parentId}: ${l instanceof Error?l.message:String(l)}`,o))}}),r.on("error",a=>{s(new T(`Failed to start rclone: ${a.message}`,""))})})}function os(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n=="string"){let e=Number(n);return Number.isFinite(e)?e:0}return 0}function ot(n,e){return n===e||n.startsWith(`${e}/`)}function as(n){return n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function ls(n){let e=w(n),t=b(n.path);return n.requiresIdentityDownload===!0||e!==t}async function us(n){let e=Q.join(n.localPath,w(n.file));if(await Le.promises.mkdir(Q.dirname(e),{recursive:!0}),n.file.requiresIdentityDownload===!0){if(!n.file.id)throw new Error(`Cannot preserve duplicate remote file without a stable rclone file ID: ${n.file.path}`);await De({args:Jt({remote:n.remote,fileId:n.file.id,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress});return}await De({args:Vt({remoteFileSource:`${n.remote}:${cs(n.remotePath,n.file.path)}`,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress})}function cs(n,e){let t=n.replace(/\/+$/,""),s=e.replace(/^\/+/,"");return t.length===0?s:`${t}/${s}`}var ue=class{#t;constructor(e){this.#t=e}get displayName(){return`${this.#t.remote}:${this.#t.remotePath}`}async prepare(){await st()}async listFiles(){return rt(this.#t.remote,this.#t.remotePath,this.#t.rcloneOptions.extraRcloneArgs??[])}resolveLocalFile(e,t){return Xe(e,t)}async materializeBatch(e){await nt({remote:this.#t.remote,remotePath:this.#t.remotePath,localPath:e.batchDir,batchFilePath:e.batchFilePath,files:e.files,rcloneOptions:this.#t.rcloneOptions,onProgress:e.onProgress})}async shutdown(){}};import Be from"node:fs/promises";import Oe from"node:path";var M=class{#t;constructor(e){this.#t=e}get displayName(){return this.#t.rootPath}async prepare(){let e=await Be.stat(this.#t.rootPath).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Local source path is not a readable directory: ${this.#t.rootPath}`)}async listFiles(){let e=[];return await this.#s(this.#t.rootPath,"",e),e.sort((t,s)=>t.path.localeCompare(s.path)),e}resolveLocalFile(e,t){let s=w(e);return{relativePath:s,absolutePath:Oe.join(this.#t.rootPath,...e.path.split("/")),fileName:Oe.posix.basename(s),size:e.size}}async materializeBatch(e){}async shutdown(){}async#s(e,t,s){let r=await Be.readdir(e,{withFileTypes:!0});for(let i of r){let o=Oe.join(e,i.name),a=t===""?i.name:`${t}/${i.name}`;if(i.isDirectory()){await this.#s(o,a,s);continue}if(!i.isFile())continue;let l=await Be.stat(o);s.push({path:a,size:l.size})}}};import de from"node:fs/promises";import ys from"node:path";import{spawn as ds}from"node:child_process";var hs=18e4,ps=2e3,ms=3e4,gs=4e3,ce=class{#t;#s;#e=null;#r="";#n=null;#i=!1;constructor(e){this.#t=e,this.#s=e.spawnFn??ds}get isRunning(){return this.#e!==null&&this.#n===null}get daemonOutputTail(){return this.#r}async checkClientInstalled(){await this.#o({args:["list"],failureMessage:"LucidLink client is not installed or not in PATH. Install it from https://www.lucidlink.com/download before using --source lucidlink."})}async start(){if(this.#e)throw new Error("LucidLink daemon already started");let e=["--instance",String(this.#t.instanceId),"daemon","--fs",this.#t.filespace,"--user",this.#t.user,"--mount-point",this.#t.mountPoint,"--root-path",this.#t.cacheRootPath],t=this.#s("lucid",e,{stdio:["pipe","pipe","pipe"]});this.#e=t,t.stdout?.on("data",s=>this.#m(s)),t.stderr?.on("data",s=>this.#m(s)),t.on("exit",s=>{this.#n=s??-1,this.#i||console.error(`LucidLink daemon exited unexpectedly (code ${this.#n}). Recent output:
|
|
7
|
+
${this.#r}`)}),t.on("error",s=>{this.#n=-1,this.#m(Buffer.from(`spawn error: ${s.message}
|
|
8
|
+
`))}),t.stdin?.write(`${this.#t.password}
|
|
9
|
+
`),t.stdin?.end(),await this.#a(),this.#t.cacheSize&&await this.#o({args:["--instance",String(this.#t.instanceId),"config","--set","--local","--DataCache.Size",this.#t.cacheSize],failureMessage:`Failed to set LucidLink DataCache.Size to ${this.#t.cacheSize}`})}async stop(){let e=this.#e;if(!e||this.#n!==null){this.#e=null;return}this.#i=!0,await this.#o({args:["--instance",String(this.#t.instanceId),"exit"],failureMessage:"Failed to request LucidLink daemon exit"}).catch(t=>{console.error(t.message)}),await this.#c(e),this.#e=null}assertHealthy(){if(this.#e&&this.#n!==null&&!this.#i)throw new Error(`LucidLink daemon exited unexpectedly (code ${this.#n}). Recent output:
|
|
10
|
+
${this.#r}`)}async#a(){let e=this.#t.linkTimeoutMs??hs,t=this.#t.linkPollIntervalMs??ps,s=Date.now();for(;Date.now()-s<e;){if(this.#n!==null)throw new Error(`LucidLink daemon exited before linking (code ${this.#n}). Check the filespace name and credentials. Recent output:
|
|
11
|
+
`+this.#r);let r=await this.#u();if(r!==null&&/\bLinked\b/i.test(r))return;await fs(t)}throw new Error(`Timed out after ${Math.round(e/1e3)}s waiting for LucidLink filespace "${this.#t.filespace}" to link. Recent daemon output:
|
|
12
|
+
${this.#r}`)}async#u(){return new Promise(e=>{let t=this.#s("lucid",["--instance",String(this.#t.instanceId),"status"],{stdio:["ignore","pipe","pipe"]}),s="";t.stdout?.on("data",r=>{s+=r.toString()}),t.on("exit",r=>{e(r===0?s:null)}),t.on("error",()=>{e(null)})})}#o(e){return new Promise((t,s)=>{let r=this.#s("lucid",e.args,{stdio:["ignore","pipe","pipe"]}),i="";r.stderr?.on("data",o=>{i+=o.toString()}),r.on("exit",o=>{o===0?t():s(new Error(`${e.failureMessage} (exit code ${o}): ${i.trim()}`))}),r.on("error",o=>{s(new Error(`${e.failureMessage}: ${o.message}`))})})}async#c(e){this.#n===null&&await new Promise(t=>{let s=setTimeout(()=>{e.kill("SIGKILL")},ms);e.on("exit",()=>{clearTimeout(s),t()}),this.#n!==null&&(clearTimeout(s),t())})}#m(e){this.#r=(this.#r+e.toString()).slice(-gs)}};function fs(n){return new Promise(e=>setTimeout(e,n))}var he=class{#t;#s;#e;constructor(e,t){this.#t=e,this.#s=t??new ce({filespace:e.filespace,user:e.user,password:e.password,instanceId:e.instanceId,mountPoint:e.mountPoint,cacheRootPath:e.cacheRootPath,cacheSize:e.cacheSize}),this.#e=new M({kind:"local",rootPath:this.#r()})}get displayName(){let e=this.#t.filespacePath===""?"":`/${this.#t.filespacePath}`;return`lucidlink:${this.#t.filespace}${e}`}async prepare(){await this.#s.checkClientInstalled(),await de.mkdir(this.#t.mountPoint,{recursive:!0}),await de.mkdir(this.#t.cacheRootPath,{recursive:!0}),console.log(`Mounting LucidLink filespace ${this.#t.filespace} at ${this.#t.mountPoint}...`),await this.#s.start(),console.log("Filespace linked and mounted");let e=await de.stat(this.#r()).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Path "${this.#t.filespacePath}" does not exist in filespace ${this.#t.filespace}`)}async listFiles(){return this.#s.assertHealthy(),this.#e.listFiles()}resolveLocalFile(e,t){return this.#e.resolveLocalFile(e,t)}async materializeBatch(e){this.#s.assertHealthy(),await this.#e.materializeBatch(e)}async shutdown(){await this.#s.stop(),await de.rm(this.#t.workDir,{recursive:!0,force:!0})}#r(){return this.#t.filespacePath===""?this.#t.mountPoint:ys.join(this.#t.mountPoint,...this.#t.filespacePath.split("/"))}};function at(n){switch(n.kind){case"rclone":return new ue(n);case"local":return new M(n);case"lucidlink":return new he(n);default:{let e=n;throw new Error(`Unsupported sync source: ${JSON.stringify(e)}`)}}}import*as me from"fs/promises";import*as ge from"path";var Ss={".mp4":"video/mp4",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".webm":"video/webm",".wmv":"video/x-ms-wmv",".flv":"video/x-flv",".m4v":"video/x-m4v",".mpg":"video/mpeg",".mpeg":"video/mpeg",".3gp":"video/3gpp",".ts":"video/mp2t",".mts":"video/mp2t",".mxf":"application/mxf",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".svg":"image/svg+xml",".heic":"image/heic",".heif":"image/heif",".avif":"image/avif",".mp3":"audio/mpeg",".wav":"audio/wav",".aac":"audio/aac",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".wma":"audio/x-ms-wma",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".rtf":"application/rtf",".json":"application/json",".xml":"application/xml"};function Cs(n){let e=ge.extname(n).toLowerCase();return Ss[e]??""}var pe=class n{#t;#s=null;#e=null;#r=!1;#n;#i;#a;constructor(e,t,s,r){this.#t=e,this.#n=t,this.#i=s,this.#a=r}static async create(e){let t=await me.stat(e),s=ge.basename(e),r=Cs(s);return new n(e,t.size,s,r)}get name(){return this.#i}get size(){return this.#n}get type(){return this.#a}async readChunk(e,t){if(!this.#s){this.#e||(this.#e=me.open(this.#t,"r"));let i=await this.#e;if(this.#e=null,this.#r)return Buffer.alloc(0);this.#s=i}let s=t-e,r=Buffer.alloc(s);return await this.#s.read(r,0,s,e),r}async close(){this.#r=!0;let e=this.#e;await this.#s?.close(),this.#s=null,e&&await(await e.catch(()=>null))?.close(),this.#e=null}};var bs=new Set(["success","failed","cancelled"]),lt=1e3,As=250,Es=4*1024*1024,Me=class{#t;name;constructor(e,t){this.#t=e,this.name=t}get size(){return this.#t.size}get type(){return this.#t.type}readChunk(e,t){return this.#t.readChunk(e,t)}async close(){await this.#t.close?.()}},fe=class{#t;#s;#e;#r;#n;constructor(e){this.#t=e.config,this.#s=e.httpClient??new v({apiUrl:e.config.apiUrl,apiKey:e.config.apiKey,edgeWorkerUrl:e.config.edgeWorkerUrl,sessionId:e.config.sessionName}),this.#e=e.createFileReader??(t=>pe.create(t)),this.#r=e.onSnapshot,this.#n=e.analytics}async uploadFiles(e){let t=e.filter(a=>a.preSkipped===!0),s=e.filter(a=>a.preSkipped!==!0);if(s.length===0)return{totalFileCount:e.length,successFileCount:0,skippedFileCount:t.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};let r=new j({httpClient:this.#s,maxConcurrency:this.#t.maxConcurrent,deltaIntervalMs:lt,adaptiveConcurrency:!1,analytics:this.#n}),i=[],o=0;try{let a=r.startGroupUpload({name:`${s.length} files`,type:"files",fileCount:s.length,folderCount:0,topLevelFileCount:s.length,topLevelFolderCount:0,rootDirectoryId:this.#t.directoryId,projectId:this.#t.projectId,totalBytes:s.reduce((u,c)=>u+c.file.size,0),conflictResolutionOverride:"skip"});for(let u of s){let c=await this.#e(u.file.absolutePath),d=c.name===u.file.fileName?c:new Me(c,u.file.fileName),p=r.startUpload({fileReader:d,directoryId:u.directoryId,projectId:this.#t.projectId,groupId:a,chunkSize:Es});r.addAssetToGroup(a,p),i.push({assetId:p,file:u.file,fileReader:d});let g=Date.now();(i.length===1||i.length===s.length||g-o>=As)&&(o=g,this.#r?.(r.getSnapshot()))}await this.#i(r);let l=r.getSnapshot();return this.#r?.(l),this.#a({snapshot:l,startedUploads:i,preSkippedCount:t.length})}finally{r.destroy()}}async#i(e){let s=Date.now();for(;Date.now()-s<864e5;){let r=e.getSnapshot();this.#r?.(r);let i=Object.values(r.uploadAssets);if(i.length>0&&i.every(o=>bs.has(o.status)))return;await new Promise(o=>setTimeout(o,lt))}throw new Error("Timed out waiting for upload session to finish")}#a(e){let t=[],s=0,r=0,i=0,o=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:"Upload state missing from upload engine"});continue}if(l.status==="success"){this.#s.skippedAssetIds.has(a.assetId)?r+=1:s+=1;continue}l.status==="cancelled"?o+=1:i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:s,skippedFileCount:e.preSkippedCount+r,failedFileCount:i,cancelledFileCount:o,failedFiles:t}}};var ye=200,Se=class{#t;#s;#e;#r;#n;constructor(e,t,s){this.#t=e,this.#s=t??new v({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#e=new oe({rootDirectoryId:e.directoryId,httpClient:this.#s}),this.#r=new fe({config:e,httpClient:this.#s,onSnapshot:r=>C.updateSnapshot(r),analytics:Ze}),this.#n=s??at(e.source)}async run(){try{await this.#i()}finally{await this.#n.shutdown()}}async runBatched(){try{await this.#a()}finally{await this.#n.shutdown()}}async runCheckOnly(){try{await this.#u()}finally{await this.#n.shutdown()}}async#i(){this.#C("Starting data sync..."),await this.#b();let e=this.#A(await this.#o());if(e.length===0){console.log("No files to sync. Exiting."),await this.#S();return}let t={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},s=[],r={batchNumber:1,files:e,totalSize:this.#O(e)};C.start();try{let o=await this.#v({batch:r,totalBatches:1,overallFilesTotal:e.length,overallBytesTotal:r.totalSize,completedTotals:t,batchDir:this.#t.localTempDir});this.#B(t,s,o,r.totalSize)}finally{C.stop()}let i={...t,failedFiles:s};this.#T({summary:i}),await this.#P(i),this.#_(i)}async#a(){if(!this.#t.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#C("Starting batched data sync...",[`Batch size: ${S(this.#t.batchSizeBytes)}`,`Max concurrent chunks: ${this.#t.maxConcurrent}`]),await this.#b();let e=this.#A(await this.#o());if(e.length===0){console.log("No files to sync. Exiting."),await this.#S();return}let t=He(e,this.#t.batchSizeBytes);await this.#p(t);let s={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},r=[],i=this.#O(e);C.start();try{for(let a of t){let l=await this.#v({batch:a,totalBatches:t.length,overallFilesTotal:e.length,overallBytesTotal:i,completedTotals:s});this.#B(s,r,l,a.totalSize)}}finally{C.stop()}this.#T({summary:{...s,failedFiles:r},extraLines:[`Batches: ${t.length}`]});let o={...s,failedFiles:r};await this.#P(o),this.#_(o)}async#u(){console.log("Running in check-only mode (no downloads/uploads)..."),await this.#n.prepare(),console.log(`Listing source files from ${this.#n.displayName}...`);let e=await this.#n.listFiles();console.log(`Found ${e.length} source files to check`);let t=this.#A(e);if(t.length===0){console.log("No source files to check. Exiting.");return}console.log("Fetching Aspect project summary...");let s=await this.#c();console.log("Fetching existing Aspect files...");let r=await this.#e.listFilesInSubtree({onProgress:o=>this.#d(o)}),i=this.#m(t,r,s);this.#k(i)}async#o(){console.log("Listing all source files...");let e=await this.#n.listFiles();return console.log(`Found ${e.length} files`),console.log(`Total size: ${S(this.#O(e))}`),console.log(""),e}async#c(){return await this.#s.get(`/projects/${this.#t.projectId}`)}#m(e,t,s){let r=e.map(f=>({relativePath:w(f),sizeBytes:this.#f(f.size)})),i=r.filter(f=>f.sizeBytes===null).length,o=t.filter(f=>f.isUploaded),a=t.filter(f=>f.uploadStateKnown&&!f.isUploaded),l=t.filter(f=>!f.uploadStateKnown).length;l>0&&(console.warn(`Warning: ${l} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),console.log(""));let u=this.#l(r),c=this.#D(o),d=new Set([...u.keys(),...c.keys()]),p=0,g=0,h=[],A=[],y=[];for(let f of d){let V=u.get(f)??[],P=c.get(f)??[],R=new Set,Ce=[];for(let E of V){if(E.sizeBytes===null){Ce.push(E);continue}let D=P.findIndex((U,J)=>!R.has(J)&&U.sizeBytes===E.sizeBytes);D>=0?(p+=1,R.add(D)):Ce.push(E)}for(let E of Ce){if(E.sizeBytes===null){let U=P.findIndex((J,dt)=>!R.has(dt));U>=0?(R.add(U),g+=1):h.push(E);continue}let D=P.findIndex((U,J)=>!R.has(J));if(D>=0){let U=P[D];R.add(D),A.push({relativePath:f,remoteSizeBytes:E.sizeBytes,serverSizeBytes:U.sizeBytes,assetId:U.assetId})}else h.push(E)}for(let E=0;E<P.length;E++)R.has(E)||y.push(P[E])}return{totalRemoteCount:e.length,totalServerCount:t.length,projectAssetCount:s.num_assets,projectRootDirectoryId:s.root_directory_id,uploadedServerCount:o.length,unknownUploadStateCount:l,unknownRemoteSizeCount:i,pathOnlyMatchCount:g,existingCount:p,missingFiles:h,sizeMismatches:A,extraUploadedFiles:y,incompleteServerFiles:a}}#l(e){let t=new Map;for(let s of e){let r=b(s.relativePath),i=t.get(r)??[];i.push({...s,relativePath:r}),t.set(r,i)}return t}#D(e){let t=new Map;for(let s of e){let r=b(s.relativePath),i=t.get(r)??[];i.push({...s,relativePath:r}),t.set(r,i)}return t}#f(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:null}#A(e){let t=Qe(e);if(t.changes.length===0)return t.files;let s=t.changes.slice(0,10).map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
|
|
7
13
|
`),r=t.changes.length-10,i=r>0?`
|
|
8
14
|
...and ${r} more renamed target path(s)`:"";return console.warn(`Warning: ${t.changes.length} remote file path(s) were renamed for Aspect compatibility.
|
|
9
15
|
${s}${i}
|
|
10
|
-
`),console.log(""),t.files}async#
|
|
16
|
+
`),console.log(""),t.files}async#v(e){let t=e.batchDir??Ne.join(this.#t.localTempDir,`batch${e.batch.batchNumber}`);await X.mkdir(t,{recursive:!0});let s=e.batch.files.map(d=>this.#n.resolveLocalFile(d,t));C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:`Preparing ${s.length} files...`}),C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"syncing_folders",extraDetails:"Ensuring target directories exist..."});let r=await this.#e.ensureDirectories(s);C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:"Checking existing assets..."});let i=await this.#U(r),o=this.#F(i),a=e.batch.files.filter((d,p)=>i[p]?.preSkipped!==!0),l=Ne.join(this.#t.localTempDir,`batch${e.batch.batchNumber}.txt`),u=async()=>{await je(l),this.#t.keepLocal||await X.rm(t,{recursive:!0,force:!0}),C.resetUploadSnapshot(),C.updateDownloadProgress(null)};if(a.length===0){let d={totalFileCount:i.length,successFileCount:0,skippedFileCount:i.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};return C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+d.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"everything already synced"}),C.persistCurrentBatchLine(),await u(),d}C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"downloading"}),await this.#n.materializeBatch({files:a,batchDir:t,batchFilePath:l,onProgress:d=>C.updateDownloadProgress(d)}),C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"uploading"});let c=await this.#r.uploadFiles(i);return this.#w(c)?(C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+c.successFileCount+c.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"failed; local files preserved"}),C.persistCurrentBatchLine(),c):(C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+c.successFileCount+c.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"cleaning"}),await u(),C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:s.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+c.successFileCount+c.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#h(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete"}),C.persistCurrentBatchLine(),c)}async#b(){console.log("Preparing source..."),await this.#n.prepare(),console.log("Source ready"),console.log(""),console.log("Creating session directory..."),await X.mkdir(this.#t.localTempDir,{recursive:!0}),console.log(`Session directory: ${this.#t.localTempDir}`),console.log("")}async#S(){this.#t.keepLocal||(console.log(""),console.log("Cleaning up session directory..."),await X.rm(this.#t.localTempDir,{recursive:!0,force:!0}),console.log(`Deleted session directory: ${this.#t.localTempDir}`))}async#P(e){if(this.#w(e)){console.log(""),console.log(`Preserving session directory for retry/debugging: ${this.#t.localTempDir}`);return}await this.#S()}async#U(e){let t=await this.#e.checkAssetsExistence(e.map(s=>({directory_id:s.directoryId,name:s.file.fileName,size_bytes:s.file.size})));return e.map((s,r)=>({file:s.file,directoryId:s.directoryId,preSkipped:t[r]?.exists===!0}))}#F(e){return e.reduce((t,s)=>(s.preSkipped===!0&&(t.skippedFileCount+=1,t.skippedByteCount+=s.file.size),t),{skippedFileCount:0,skippedByteCount:0})}async#p(e){console.log("Creating batches..."),console.log(`Created ${e.length} batches`);let t=[];for(let s of e){let r=`Batch ${s.batchNumber}: ${s.files.length} files, ${S(s.totalSize)}`;t.push(r),console.log(r)}await X.writeFile(Ne.join(this.#t.localTempDir,"batches.txt"),`${t.join(`
|
|
11
17
|
`)}
|
|
12
|
-
`,"utf-8"),console.log("")}#
|
|
18
|
+
`,"utf-8"),console.log("")}#C(e,t=[]){console.log(e),console.log(`Session: ${this.#t.sessionName}`),console.log(`Source: ${this.#n.displayName}`),console.log(`Root directory ID: ${this.#t.directoryId}`),console.log(`Project ID: ${this.#t.projectId}`),console.log(`Temp directory: ${this.#t.localTempDir}`),console.log(`Edge worker URL: ${this.#t.edgeWorkerUrl}`);for(let s of t)console.log(s);console.log("")}#T(e){console.log(""),console.log("=".repeat(60)),console.log("Sync Summary"),console.log("=".repeat(60)),console.log(`Total files: ${e.summary.totalFileCount}`),console.log(`Successful: ${e.summary.successFileCount}`),console.log(`Skipped: ${e.summary.skippedFileCount}`),console.log(`Failed: ${e.summary.failedFileCount}`),console.log(`Cancelled: ${e.summary.cancelledFileCount}`);for(let t of e.extraLines??[])console.log(t);if(console.log("=".repeat(60)),e.summary.failedFiles.length>0){console.log(""),console.log("Failed files:");for(let t of e.summary.failedFiles)console.log(` - ${t.relativePath}: ${t.errorMessage??"Unknown error"}`)}}#d(e){console.log(`Aspect scan: ${e.scannedDirectoryCount}/${e.queuedDirectoryCount} directories, ${e.fileCount} files found`)}#k(e){let t=e.missingFiles.length+e.sizeMismatches.length+e.extraUploadedFiles.length+e.incompleteServerFiles.length;console.log(""),console.log("=".repeat(60)),console.log("Check Summary"),console.log("=".repeat(60)),console.log(`Total (remote): ${e.totalRemoteCount}`),console.log(`Total (server): ${e.totalServerCount}`),console.log(`Project asset count: ${e.projectAssetCount}`),console.log(`Project count vs scanned server: ${e.projectAssetCount-e.totalServerCount}`),console.log(`Uploaded (server): ${e.uploadedServerCount}`),console.log(`Upload status unknown: ${e.unknownUploadStateCount}`),console.log(`Exact matches: ${e.existingCount}`),console.log(`Path-only matches (unknown remote size): ${e.pathOnlyMatchCount}`),console.log(`Remote sizes unknown: ${e.unknownRemoteSizeCount}`),console.log(`Missing on server: ${e.missingFiles.length}`),console.log(`Size mismatches: ${e.sizeMismatches.length}`),console.log(`Extra on server: ${e.extraUploadedFiles.length}`),console.log(`Incomplete uploads on server: ${e.incompleteServerFiles.length}`),console.log(`Total mismatches: ${t}`),console.log("=".repeat(60)),e.projectRootDirectoryId!==this.#t.directoryId?(console.log(""),console.log(`Warning: --directory-id (${this.#t.directoryId}) is not the project root directory (${e.projectRootDirectoryId}), so --check is comparing only that directory subtree.`)):e.projectAssetCount!==e.totalServerCount&&(console.log(""),console.log("Warning: project asset count differs from the live filesystem subtree scan. The project card uses cached project stats; the subtree scan is what --check compared against Drive.")),this.#g("Files missing on server:",e.missingFiles),this.#E(e.sizeMismatches),this.#I("Extra files on server:",e.extraUploadedFiles),this.#I("Incomplete uploads on server:",e.incompleteServerFiles)}#g(e,t){if(t.length!==0){console.log(""),console.log(e);for(let s of t.slice(0,ye))console.log(` - ${s.relativePath} (${this.#x(s.sizeBytes)})`);this.#L(t.length)}}#E(e){if(e.length!==0){console.log(""),console.log("Files with size mismatches:");for(let t of e.slice(0,ye))console.log(` - ${t.relativePath} (remote ${S(t.remoteSizeBytes)}, server ${S(t.serverSizeBytes)}, asset ${t.assetId})`);this.#L(e.length)}}#I(e,t){if(t.length!==0){console.log(""),console.log(e);for(let s of t.slice(0,ye))console.log(` - ${s.relativePath} (${S(s.sizeBytes)}, asset ${s.assetId})`);this.#L(t.length)}}#L(e){let t=e-ye;t>0&&console.log(` ...and ${t} more`)}#x(e){return e===null?"unknown remote size":S(e)}#B(e,t,s,r){e.totalFileCount+=s.totalFileCount,e.successFileCount+=s.successFileCount,e.skippedFileCount+=s.skippedFileCount,e.failedFileCount+=s.failedFileCount,e.cancelledFileCount+=s.cancelledFileCount,e.completedByteCount+=r,t.push(...s.failedFiles)}#_(e){let t=e.failedFileCount+e.cancelledFileCount;if(t>0)throw new Error(`Sync completed with ${t} unsuccessful upload(s)`)}#w(e){return e.failedFileCount+e.cancelledFileCount>0}#O(e){return e.reduce((t,s)=>t+s.size,0)}#h(e,t){return Math.min(e.completedByteCount,t)}};var Us=Ps(import.meta.url),Fs=ut.dirname(Us),ct=JSON.parse(Ts(ut.join(Fs,"..","package.json"),"utf-8")),ze=new Rs;ze.name("aspect-sync").description("Sync files from external services to Aspect").version(ct.version);ze.option("--source <kind>","source kind: rclone, local, or lucidlink (default: rclone)","rclone").option("--remote <remote>","rclone remote name (e.g., dropbox); required for --source rclone").requiredOption("--path <path>","path to sync from: remote path (rclone), local directory (local), or path within the filespace (lucidlink)").requiredOption("--directory-id <id>","Aspect directory ID to upload to").requiredOption("--project-id <id>","Aspect project ID").option("--api-url <url>","Aspect API URL").option("--edge-worker-url <url>","Aspect edge worker URL").option("--api-key <key>","Aspect API key").option("--upload-concurrent <number>","Maximum concurrent chunk uploads to Aspect (default: 16)","16").option("--keep-local","Keep local files after upload (for debugging)",!1).option("--temp-dir <path>","Local temporary directory for synced files").option("--session <name>","Session name for isolation (default: auto-generated timestamp)").option("--check","Check remote files against Aspect without downloading/uploading",!1).option("--batch-size <size>","Enable batched mode with max batch size (e.g., 500GB, 1TB). Helps with large migrations.","").option("--lucid-fs <filespace>","LucidLink filespace (e.g., myspace.mydomain); required for --source lucidlink").option("--lucid-user <user>","LucidLink filespace user; required for --source lucidlink").option("--lucid-password-file <path>","File containing the LucidLink password (or set LUCID_PASSWORD)").option("--lucid-instance <number>","LucidLink daemon instance ID (default: 9001)","9001").option("--lucid-cache-size <size>","LucidLink DataCache.Size applied after mount (e.g., 100GB)").option("--rclone-transfers <number>","Number of parallel file transfers (default: 4)","4").option("--rclone-multi-thread-streams <number>","Streams per large file (default: 4, higher = faster large files)","4").option("--rclone-multi-thread-chunk-size <size>","Chunk size for multi-threading (default: 64MiB)","64MiB").option("--rclone-multi-thread-cutoff <size>","Minimum file size for multi-threading (default: 64MiB)","64MiB").option("--rclone-buffer-size <size>","Buffer size per transfer (default: 64M, memory = transfers \xD7 buffer-size)","64M").option("--rclone-no-mmap","Disable memory-mapped I/O (reduces memory efficiency)",!1).option("--rclone-extra <arg>","Additional rclone argument to append (repeatable)",(n,e)=>(e??[]).concat(n),[]).action(async n=>{let e=0;try{let t={ASPECT_API_URL:process.env.ASPECT_API_URL,ASPECT_EDGE_WORKER_URL:process.env.ASPECT_EDGE_WORKER_URL,ASPECT_API_KEY:process.env.ASPECT_API_KEY,ASPECT_POSTHOG_KEY:process.env.ASPECT_POSTHOG_KEY,ASPECT_POSTHOG_HOST:process.env.ASPECT_POSTHOG_HOST,ASPECT_DISABLE_POSTHOG:process.env.ASPECT_DISABLE_POSTHOG,LUCID_PASSWORD:process.env.LUCID_PASSWORD,POSTHOG_KEY:process.env.POSTHOG_KEY,POSTHOG_API_KEY:process.env.POSTHOG_API_KEY,POSTHOG_HOST:process.env.POSTHOG_HOST,POSTHOG_DISABLED:process.env.POSTHOG_DISABLED},s=$e({options:n,environment:t}),r=vs(s),i=await ks(s,r);i&&Je({config:s,packageVersion:ct.version,user:i});let o=new Se(s,r);n.check?await o.runCheckOnly():s.batchSizeBytes!==void 0?await o.runBatched():await o.run()}catch(t){console.error("Fatal error:",t),e=1}finally{await et()}process.exit(e)});ze.parse();function vs(n){return new v({apiUrl:n.apiUrl,apiKey:n.apiKey,edgeWorkerUrl:n.edgeWorkerUrl,sessionId:n.sessionName})}async function ks(n,e){return n.analytics.disabled||!n.analytics.posthogKey?null:await e.get("/users/me")}
|