aspect-sync 0.1.36 → 0.1.37

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.
Files changed (3) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +26 -26
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -65,6 +65,7 @@ Shared Aspect destination options:
65
65
  --shard-count <number>
66
66
  --shard-index <number>
67
67
  --progress <human|json>
68
+ --yes
68
69
  ```
69
70
 
70
71
  `--asp-api-key` is optional after login. Sync commands resolve the key from the flag first, then `ASPECT_API_KEY`, then `~/.config/aspect-sync/aspect-auth.json`.
@@ -84,9 +85,12 @@ Shared sync option details:
84
85
  - `--batch-size <size>`: Enable batched mode with max batch size, such as `500GB` or `1TB`.
85
86
  - `--shard-count <number>` and `--shard-index <number>`: Split the planned file list across multiple runner sessions. `--shard-index` is zero-based and both flags must be provided together.
86
87
  - `--progress <human|json>`: Progress output mode. `json` emits one NDJSON event per line. Defaults to `human`.
88
+ - `--yes`: Skip the interactive confirmation prompt.
87
89
 
88
90
  Size values accept `B`, `KB`, `MB`, `GB`, and `TB`.
89
91
 
92
+ Human sync runs print a confirmation summary after source listing and before downloads/uploads start. The summary includes the Aspect project and directory names, source path, file count, total size, and batch count when batched mode is enabled. Type `yes` to continue, or pass `--yes` for non-interactive runs.
93
+
90
94
  ## Source Options
91
95
 
92
96
  ### Rclone
package/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
1
  #!/usr/bin/env node
2
- import{Command as ri}from"commander";import dr from"node:path";import{readFileSync as si,realpathSync as ur}from"node:fs";import{fileURLToPath as oi}from"node:url";import ge from"node:fs/promises";import _t from"node:path";import fr from"fs/promises";import gr from"path";function Yt(n,e){let t=new Map;for(let c of n){let u=gr.dirname(c.targetPath??c.path);t.has(u)||t.set(u,[]),t.get(u).push(c)}let r=new Map;for(let[c,u]of t.entries()){let d=u.reduce((m,h)=>m+h.size,0);r.set(c,d)}let s=Array.from(t.keys()).sort(),o=[],i=[],a=0,l=1;for(let c of s){let u=t.get(c),d=r.get(c);if(d>e){if(i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),u.length===1)o.push({batchNumber:l++,files:u,totalSize:d});else for(let m of u)a+m.size>e&&i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),i.push(m),a+=m.size;continue}a+d>e&&i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),i.push(...u),a+=d}return i.length>0&&o.push({batchNumber:l++,files:i,totalSize:a}),o}async function Vt(n){try{await fr.unlink(n)}catch(e){if(e.code!=="ENOENT")throw e}}import{Readable as Lr}from"node:stream";import tn from"axios";function se(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 s of e)switch(s.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 r=e.length;return t.failed===r?"all-failed":t.failed>0?"some-failed":t.success===r?"success":t.paused>0&&t.queued===0&&t.inProgress===0?"paused":t.queued>0||t.inProgress>0?t.queued+t.paused===r?"queued":"in-progress":"cancelled"}function ct(n,e){let t=se(n,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function ut(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 dt(n){for(let e of Object.values(n))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function oe(n){let t=Object.values(n).reduce((r,s)=>{switch(s.status!=="failed"&&s.status!=="cancelled"&&(r.totalBytesToUpload+=s.totalBytesToUpload,r.totalBytesUploaded+=s.bytesUploaded),r.totalAssetCount+=1,s.status){case"queued":r.queuedAssetCount+=1;break;case"paused":r.pausedAssetCount+=1;break;case"in-progress":r.inProgressAssetCount+=1;break;case"success":r.successAssetCount+=1;break;case"failed":r.failedAssetCount+=1;break;case"cancelled":r.cancelledAssetCount+=1;break}return r},{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 Ie(n,e){if(e.length===0)return null;let t=e.reduce((r,s)=>(s.status!=="failed"&&s.status!=="cancelled"&&(r.totalBytes+=s.totalBytesToUpload,r.uploadedBytes+=s.bytesUploaded),s.status==="success"?r.filesSucceeded++:s.status==="failed"&&r.filesFailed++,(s.status==="success"||s.status==="failed"||s.status==="cancelled")&&r.filesCompleted++,r),{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 pt(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 mt(n){return Object.values(n).some(e=>e.status==="paused")}import Fi from"axios";var ie=class{#e;#s;#t;#o;#r;#n=0;#i=0;#c=0;#a=0;#u=0;#d=0;constructor(e){this.#e=e?.alphaFast??.1,this.#s=e?.alphaMax??.5,this.#t=e?.consecutiveForBoost??3,this.#o=e?.minSamples??3,this.#r=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#a===0){this.#a=t,this.#u=e;return}let s=(t-this.#a)/1e3,o=e-this.#u;if(s<=0||o<0)return;if(s>this.#r){this.#a=t,this.#u=e;return}let i=o/s;if(this.#d===0)this.#n=i;else{let l=i-this.#n>=0?1:-1;this.#c!==0&&l===this.#c?this.#i++:this.#i=0,this.#c=l;let c=Math.min(1,this.#i/this.#t),u=this.#e+(this.#s-this.#e)*c;this.#n=u*i+(1-u)*this.#n}this.#a=t,this.#u=e,this.#d++}etaSeconds(e){return!this.isWarmedUp||this.#n<=0?0:e/this.#n}adjustTotalBytes(e){this.#u+=e}reset(){this.#n=0,this.#i=0,this.#c=0,this.#a=0,this.#u=0,this.#d=0}serialize(){return{displaySpeedBps:this.#n,lastSampleTimestamp:this.#a,lastSampleTotalBytes:this.#u,sampleCount:this.#d}}get speedBps(){return this.#n}get speedMbps(){return this.#n*8/1e6}get isWarmedUp(){return this.#d>=this.#o}};function O(n){let e={"X-Aspect-Share-Id":n.shareId};return n.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=n.shareAuthentication),e}var ae=class{#e;#s;#t;#o;#r;#n;#i;#c;#a;#u;#d;#l;#R;#g;#P;#I;#C;#h;#b;#w;#T;#m;#y;#k;#p;#v;#f;#E;#L;#O;#D;#M;constructor(e){this.#s=e?.minConcurrency??1,this.#t=e?.maxConcurrency??8,this.#e=this.#j(e?.initialConcurrency??this.#s),this.#o=e?.errorThreshold??1,this.#r=(e?.cooldownSeconds??10)*1e3,this.#n=e?.plateauThreshold??.05,this.#i=Math.max(this.#t,Math.floor(e?.sampleWindowSize??64)),this.#c=Math.max(2,Math.floor(e?.minSamples??4)),this.#a=Math.max(1.1,e?.increaseFactor??1.5),this.#u=e?.onChange,this.#d=e?.now??Date.now,this.#l=this.#e,this.#R=0,this.#g=[],this.#P=0,this.#I=0,this.#C=-1,this.#h=0,this.#b=void 0,this.#w=0,this.#T=0,this.#m=0,this.#y=this.#l,this.#k=0,this.#p=1/0,this.#v=0,this.#f=6e4,this.#E=0,this.#L=1/0,this.#O=0,this.#D=0,this.#M=0}recordSuccess(e,t,r){if(e<=0)return;if(r?.generation!==void 0){if(r.generation!==this.#R){r.generation===this.#C&&this.#h>0&&(this.#h--,this.#h===0&&(this.#b=r.completedAtMs??this.#d()));return}if(this.#h>0||this.#b!==void 0&&r.startedAtMs!==void 0&&r.startedAtMs<this.#b)return}else if(this.#I>0){this.#I--;return}let s=r?.completedAtMs??this.#d();for(this.#g.push({bytes:e,completedAtMs:s,startedAtMs:r?.startedAtMs,durationMs:t!==void 0&&t>0?t:void 0});this.#g.length>this.#i;)this.#g.shift();this.#P++,this.#w=0;let o=this.#z();this.#D=o.throughputBps,this.#M=o.latencyMsPerMB,this.#x(o)}recordError(){if(this.#w++,this.#w<this.#o)return;let e=this.#l;e===this.#E&&(this.#L=Math.min(this.#L,e),this.#O=this.#d()+3e4),this.#E=e;let t=this.#j(Math.floor(e/2));this.#T=this.#d()+this.#r,this.#w=0,e<=this.#y&&(this.#y=t,this.#k=0),e>t&&(this.#p=Math.min(this.#p,e),this.#W()),this.#A(t)}get concurrency(){return this.#l}get generation(){return this.#R}get speedBps(){return this.#D}get latencyMsPerMB(){return this.#M}reset(){this.#l=this.#e,this.#R++,this.#g=[],this.#P=0,this.#I=0,this.#C=-1,this.#h=0,this.#b=void 0,this.#w=0,this.#T=0,this.#m=0,this.#y=this.#l,this.#k=0,this.#p=1/0,this.#v=0,this.#f=6e4,this.#E=0,this.#L=1/0,this.#O=0,this.#D=0,this.#M=0,this.#u?.(this.#l)}#x(e){if(this.#g.length<this.#K()||this.#P<this.#K()||e.throughputBps<=0)return;let t=this.#d();if(t<this.#T)return;if(e.averageDurationMs>=2e4&&this.#l>=4){this.#y=Math.max(this.#s,Math.floor(this.#l/2)),this.#k=0,this.#A(this.#y);return}if(this.#k===0){this.#N(e.throughputBps),this.#_(e);return}let r=(e.throughputBps-this.#k)/this.#k;if(r>=this.#n){this.#N(e.throughputBps),this.#_(e);return}if(this.#l>this.#y){let s=r<=-.08,o=r<this.#n;(s||o)&&(this.#p=Math.min(this.#p,this.#l),this.#W(),this.#A(this.#y));return}if(this.#l<this.#y){this.#_(e);return}this.#l===this.#y&&(this.#k=Math.max(this.#k,e.throughputBps),t>=this.#m&&this.#_(e))}#_(e){let t=this.#Y();if(this.#l>=t){this.#P=0;return}if(e.averageDurationMs>=5e3&&this.#l>=4&&this.#k>0){this.#P=0;return}if(this.#U()){let s=this.#d();if(this.#v===0){this.#v=s+this.#f,this.#m=this.#v,this.#P=0;return}if(s<this.#v){this.#P=0;return}}let r=this.#S(t);if(r===this.#l){this.#P=0;return}this.#A(r)}#N(e){this.#y=this.#l,this.#k=e,this.#p<=this.#l&&(this.#p=1/0),this.#v=0,this.#f=6e4,this.#m=0}#S(e){if(this.#p<1/0){let s=Math.floor((this.#l+this.#p)/2);return s>this.#l&&s<this.#p?Math.min(e,s):Math.min(e,this.#l+1)}if(this.#l<4)return Math.min(e,this.#l+1);let t=Math.ceil(this.#l*this.#a),r=this.#l+2;return Math.min(e,Math.max(r,t))}#A(e){let t=this.#l,r=this.#R,s=this.#j(e);s!==t&&(this.#B(),this.#l=s,this.#R++,this.#C=r,this.#h=Math.max(0,t-1),this.#b=this.#h===0?this.#d():void 0,this.#I=Math.max(0,t-1),this.#u?.(this.#l))}#B(){this.#g=[],this.#P=0,this.#I=0}#U(){return this.#p<1/0&&this.#l===this.#y&&this.#p<=this.#y+1}#W(){let e=this.#p<1/0&&this.#p<=this.#y+1,t=e?this.#f:1e4;this.#m=this.#d()+t,e&&(this.#v=this.#m,this.#f=Math.min(this.#f*2,3e5))}#K(){return Math.max(this.#c,this.#l)}#Y(){return this.#L<1/0&&this.#d()>=this.#O&&(this.#L=1/0,this.#O=0),Math.max(this.#s,Math.min(this.#t,this.#L-1))}#j(e){return Math.max(this.#s,Math.min(this.#t,e))}#z(){let e=0,t=0,r=0,s=0;for(let l of this.#g)e+=l.bytes,l.durationMs!==void 0&&(t+=l.durationMs,r++,s+=l.durationMs/(l.bytes/(1024*1024)));if(r>0&&t>0)return{throughputBps:e/(t/1e3)*this.#l,latencyMsPerMB:s/r,averageDurationMs:t/r,durationSampleCount:r};if(this.#g.length<2)return{throughputBps:0,latencyMsPerMB:0,averageDurationMs:0,durationSampleCount:0};let o=this.#g[0],a=this.#g[this.#g.length-1].completedAtMs-o.completedAtMs;return{throughputBps:a>0?e/a*1e3:0,latencyMsPerMB:0,averageDurationMs:a>0?a/Math.max(1,this.#g.length-1):0,durationSampleCount:0}}};var H=class{#e;#s;#t;#o;#r;#n;#i;#c;constructor(e,t){this.#n=t?.now??(()=>Date.now()),this.#i=t?.setTimer??((s,o)=>setTimeout(s,o)),this.#c=t?.clearTimer??(s=>clearTimeout(s));let r=e===0?null:e;this.#e=r,this.#s=r??0,this.#t=this.#n(),this.#o=[],this.#r=null}setLimit(e){let t=e===0?null:e;if(t===null){this.#e=null,this.#s=0,this.#R();let s=this.#o.splice(0);for(let o of s)o.resolve();return}let r=this.#e;this.#e=t,r===null?(this.#s=t,this.#t=this.#n()):(this.#a(),this.#s=Math.min(this.#s,t)),this.#l()}getLimit(){return this.#e}acquire(e){if(this.#e!==null){if(this.#a(),this.#o.length===0&&this.#s>=e){this.#s-=e;return}return this.#u(e)}}#a(){let e=this.#n(),t=(e-this.#t)/1e3;if(t<=0)return;let r=this.#e,s=t*r,o=this.#o.length>0?Math.max(r,this.#o[0].bytes):r;this.#s=Math.min(this.#s+s,o),this.#t=e}#u(e){return new Promise(t=>{this.#o.push({bytes:e,resolve:t}),this.#r===null&&this.#d()})}#d(){if(this.#o.length===0||this.#e===null){this.#r=null;return}let t=this.#o[0].bytes-this.#s,r=t>0?Math.ceil(t/this.#e*1e3):0;if(r<=0){this.#r=null,this.#l();return}this.#r=this.#i(()=>{this.#r=null,this.#a(),this.#l()},r)}#l(){for(;this.#o.length>0;){if(this.#e===null){let t=this.#o.splice(0);for(let r of t)r.resolve();return}this.#a();let e=this.#o[0];if(this.#s>=e.bytes)this.#s-=e.bytes,this.#o.shift(),e.resolve();else{this.#d();return}}}#R(){this.#r!==null&&(this.#c(this.#r),this.#r=null)}};function Qt(n){let e=`[${n}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var ht=Qt("transfer");var Zt="transportDiagnostics";function M(n){return typeof n=="string"&&n.length>0?n:null}function Xt(n){if(n===null||typeof n!="object")return null;let e=n,t=M(e.O),r=M(e.CN),s=[t,r].filter(o=>o!==null);return s.length>0?s.join(" / "):null}function yr(n){if(!n)return{};let e={remoteAddress:M(n.remoteAddress),remoteFamily:M(n.remoteFamily),tlsAuthorized:typeof n.authorized=="boolean"?n.authorized:null};if(typeof n.getProtocol=="function"&&(e.tlsProtocol=M(n.getProtocol())),typeof n.getCipher=="function"){let t=n.getCipher();t!==null&&typeof t=="object"&&(e.tlsCipher=M(t.name))}if(typeof n.getPeerCertificate=="function"){let t=n.getPeerCertificate();if(t!==null&&typeof t=="object"){let r=t;e.peerCertIssuer=Xt(r.issuer),e.peerCertSubject=Xt(r.subject)}}return e}function ft(n){let e={errorCode:null,hadResponse:!1,reusedSocket:null,remoteAddress:null,remoteFamily:null,tlsProtocol:null,tlsCipher:null,peerCertIssuer:null,peerCertSubject:null,tlsAuthorized:null};if(n===null||typeof n!="object")return e;let t=n;e.errorCode=M(t.code),e.hadResponse=t.response!=null;let r=t.request;if(r){e.reusedSocket=typeof r.reusedSocket=="boolean"?r.reusedSocket:null;let s=r.socket??r.res?.socket??null;Object.assign(e,yr(s))}return e}function gt(n,e){n===null||typeof n!="object"||(n[Zt]=e)}function yt(n){if(n===null||typeof n!="object")return null;let e=n[Zt];return e??null}var St=n=>!Number.isFinite(n)||n<=0?"Calculating...":n<1?`${(n*1e3).toFixed(0)} Kbps`:`${n.toFixed(1)} Mbps`,Ct=n=>{if(!Number.isFinite(n)||n<=0)return"Calculating...";let e=Math.floor(n/3600),t=Math.floor(n%3600/60),r=Math.floor(n%60);return e>0?`${e}h ${t}m left`:t>0?`${t}m ${r}s left`:`${r}s left`};var Re=class{uploadAssets={};uploadGroups={};#e=new ie;get uploadSpeedState(){return this.#e.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#s(e){e!==0&&this.#e.adjustTotalBytes(-e)}adjustSpeedBaselineForSkippedBytes(e){e!==0&&this.#e.adjustTotalBytes(e)}#t(){Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress")||this.#e.reset()}#o(e){this.dirtyAssetIds.add(e)}#r(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:r,parentId:s,projectId:o,groupId:i,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:s,projectId:o,groupId:i,retryCount:0,chunkSize:a??0,fileReader:t,abortController:r,shareContext:l},this.#o(e)}updateUploadProgress(e,t){let r=this.uploadAssets[e];if(!r||r.status==="paused"||r.status==="cancelled"||r.status==="success"||r.status==="failed")return;let s=t>0&&r.status==="queued"?"in-progress":r.status,o=Math.min(t,r.totalBytesToUpload);r.bytesUploaded=o,r.status=s,this.#o(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#o(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#o(e),this.#t(),this.cleanupOnCompletion(e))}markUploadFailed(e,t){let r=this.uploadAssets[e];if(!r)return;let s=r.bytesUploaded;r.status="failed",r.errorMessage=t,r.bytesUploaded=0,this.#o(e),this.#s(s),this.#t(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let r=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#o(e),this.#s(r),this.#t()}clearAllUploads(){this.uploadAssets={},this.#e.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.#e.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.#o(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#o(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let r=0;if(t.chunkedState){let{completedChunkIndices:o,chunkSize:i}=t.chunkedState;for(let a of o){let l=a*i,c=Math.min(l+i,t.totalBytesToUpload);r+=c-l}}let s=t.bytesUploaded-r;t.status="paused",t.bytesUploaded=r,this.#o(e),this.#s(s),this.#t(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#o(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#r(e);for(let r of t.assetIds)this.pauseUpload(r)}}unpauseUploadGroup(e){let t=this.uploadGroups[e];t&&(t.isPaused=!1,this.#r(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 r=t.bytesUploaded;t.status="cancelled",this.#o(e),this.#s(r),this.#t(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let r=this.uploadAssets[e];r&&(r.chunkedState=t,this.#o(e))}addCompletedChunkIndex(e,t){let r=this.uploadAssets[e];!r||!r.chunkedState||(r.chunkedState={...r.chunkedState,completedChunkIndices:[...r.chunkedState.completedChunkIndices,t]},this.#o(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#o(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return pt(this.uploadAssets)}hasPausedUploads(){return mt(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#n(t)}getUploadSummary(){return oe(this.#c())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#n(e)).sort((e,t)=>t.i-e.i)}getGroupAssets(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(r=>this.uploadAssets[r]).filter(Boolean).map(r=>this.#n(r))}getGroupAssetsInternal(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(r=>this.uploadAssets[r]).filter(Boolean)}addUploadGroup(e){let t=crypto.randomUUID();return this.uploadGroups[t]={...e,id:t,fileReaders:new Map},this.#r(t),t}updateUploadGroup(e,t){let r=this.uploadGroups[e];r&&(Object.assign(r,t),this.#r(e))}addAssetToGroup(e,t){let r=this.uploadGroups[e];r&&(r.assetIds.push(t),this.#r(e))}finalizeEmptyGroup({groupId:e,status:t,errorMessage:r}){let s=this.uploadGroups[e];s&&(s.assetIds.length>0||s.finalizedStatus||(s.finalizedStatus=t,s.errorMessage=r,s.isCreatingFolders=!1,s.completedAt=new Date().toISOString(),this.#r(e),this.dirtyHistoryGroupIds.add(e)))}removeUploadGroup(e){let t=this.uploadGroups[e];if(t)for(let r of t.assetIds)delete this.uploadAssets[r],this.#o(r);delete this.uploadGroups[e],this.#r(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#i(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#i(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return Ie(this.#i(t),r)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return se(this.#i(t),r)}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#n(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.#i(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let r=t.groupId;if(r){let o=this.uploadGroups[r];if(o){let i=this.getGroupAssets(r),a=this.#i(o);this.dirtyHistoryGroupIds.add(r),!i.some(c=>c.status==="queued"||c.status==="in-progress")&&!o.completedAt&&(o.completedAt=new Date().toISOString(),this.#r(r))}}let s=this.getUploadSummary();if(s.cancelledAssetCount+s.failedAssetCount+s.successAssetCount===s.totalAssetCount)for(let o of Object.keys(this.uploadAssets)){let i=this.uploadAssets[o];i&&(i.bytesUploaded=0,this.#o(o))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#e.sample(e.totalBytesUploaded);let r=this.#e.isWarmedUp?this.#e.speedMbps:0,s=t&&this.#e.isWarmedUp?this.#e.etaSeconds(e.totalBytesToUpload-e.totalBytesUploaded):0;this.uploadStats={uploadSpeedMbps:r,timeRemainingSeconds:s,formattedSpeed:St(r),formattedTime:Ct(s)}}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e),s=this.#i(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:ct(s,r),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#n({fileReader:e,abortController:t,shareContext:r,...s}){return s}#i({fileReaders:e,...t}){return t}#c(){let e={};for(let[t,r]of Object.entries(this.uploadAssets))e[t]=this.#n(r);return e}#a(){let e={};for(let[t,r]of Object.entries(this.uploadGroups))e[t]=this.#i(r);return e}getSerializableSnapshot(){return{uploadAssets:this.#c(),uploadGroups:this.#a(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let r of this.dirtyAssetIds){let s=this.uploadAssets[r];s&&(e[r]=this.#n(s))}let t={};for(let r of this.dirtyGroupIds){let s=this.uploadGroups[r];s&&(t[r]=this.#i(s))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function Cr(n,e){let t=new Date(n).getTime(),r=Date.now();return t-r<=e}var Te=class{#e;#s=new Map;#t=new Map;constructor(e){this.#e=e}seedToken(e,t,r){this.#s.set(e,{token:t,expiresAt:r})}async getToken(e,t){let r=this.#s.get(e);if(r&&!Cr(r.expiresAt,3e5))return r.token;let s=this.#t.get(e);if(s)return s;let o=t?O(t):void 0,i=this.#e.post(`/assets/${e}/token`,{},o).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.#t.delete(e),a.token}).catch(a=>{throw this.#t.delete(e),a});return this.#t.set(e,i),i}clearCache(e){e?this.#s.delete(e):this.#s.clear()}};var ke=class{#e=[];registerAsset(e){this.#e.push({assetId:e.assetId,totalChunks:e.totalChunks,nextChunkToClaim:0,completedChunkIndices:new Set(e.completedChunkIndices),isPaused:!1})}claimNextChunk(){for(let e of this.#e)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 r=this.#s(e);return r?(r.completedChunkIndices.add(t),r.completedChunkIndices.size>=r.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.#t(t))}removeAsset(e){this.#e=this.#e.filter(t=>t.assetId!==e)}hasAsset(e){return this.#e.some(t=>t.assetId===e)}isAssetComplete(e){let t=this.#s(e);return t?t.completedChunkIndices.size>=t.totalChunks:!1}clear(){this.#e=[]}#s(e){return this.#e.find(t=>t.assetId===e)}#t(e){for(let t=0;t<e.totalChunks;t++)if(!e.completedChunkIndices.has(t)){e.nextChunkToClaim=t;return}e.nextChunkToClaim=e.totalChunks}};var br=/[/\\:*?"<>|\x00-\x1F]/g,Ar=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function W(n){let e=n.replace(br,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;Ar.includes(t.toUpperCase())&&(e=`_${e}`);let r=new TextEncoder;if(r.encode(e).length>255){let s=e.lastIndexOf("."),o=s>0?e.substring(s):"",i=s>0?e.substring(0,s):e,l=255-r.encode(o).length;for(;r.encode(i).length>l&&i.length>0;)i=i.slice(0,-1);e=i+o}return e}var L=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function N(n){return n instanceof L||n instanceof Error&&n.name==="CancelledError"||n instanceof Error&&n.name==="CanceledError"||n instanceof Error&&n.name==="AbortError"}function Tr(n){return N(n)||n instanceof Error&&n.name==="NoAuthError"}function kr(n){return new Promise(e=>setTimeout(e,n))}function vr(n){return n instanceof Blob?n.size:n.byteLength}var ce=class{#e;#s;#t;#o;#r;#n;#i;#c;#a;#u;#d;#l;#R;#g=null;#P=0;#I=!1;#C=[];#h=new Set;#b=!1;#w=!1;#T=!1;#m=[];#y=!1;#k=!1;#p=new ke;#v=0;#f=new Map;#E=new Map;#L=[];#O=!1;#D=null;#M;#x="keep_both";#_=new Map;#N=null;#S=!1;#A=null;#B=!1;constructor(e){this.#e=e.httpClient,this.#s=new Te(e.httpClient),this.#t=new Re,this.#o=e.historyStore??null,this.#r=e.settingsStore??null,this.#n=e.analytics??null,this.#i=e.logger??ht,this.#c=e.onChange??null,this.#a=e.onClear??null,this.#u=e.onSummary??null,this.#d=e.onConcurrencyAdjusted??null,this.#R=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let r=e.adaptiveConcurrencyConfig;this.#A=new ae({initialConcurrency:r?.initialConcurrency??Math.min(4,t),minConcurrency:r?.minConcurrency??1,maxConcurrency:r?.maxConcurrency??t,errorThreshold:r?.errorThreshold,cooldownSeconds:r?.cooldownSeconds??10,plateauThreshold:r?.plateauThreshold,onChange:s=>{let o=this.#l;if(this.setMaxConcurrency(s),o===s)return;let i=this.#B?"reset":s>o?"probe_increase":"error_decrease",a=Math.round(this.#A.speedBps*8/1e6*100)/100,l=Math.round(this.#A.latencyMsPerMB*100)/100;this.#i.info(`Adaptive concurrency: ${o} \u2192 ${s} (${i}), measuredAt=${o}, speed=${a}Mbps, latency=${l}ms/MB`),this.#d?.({previousConcurrency:o,newConcurrency:s,reason:i,speedMbps:a,latencyMsPerMB:l})},now:r?.now}),this.#l=this.#A.concurrency}else this.#l=t;this.#o&&(this.#C=this.#o.load()),this.#r&&(this.#D=this.#r.getBandwidthLimitBps(),this.#x=this.#r.getConflictResolution()),this.#M=new H(this.#D),(this.#c||this.#u)&&(this.#g=setInterval(()=>{this.#ce()},this.#R)),this.#n&&(this.#N=setInterval(()=>{this.#de()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),r=!!e.assetId,s;if(r){let i=this.#t.getUploadAsset(t);if(!i)throw new Error(`Cannot retry: asset ${t} not found`);s=i.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");s=e.chunkSize}let o=new AbortController;if(r){if(this.#t.getUploadAsset(t).status==="cancelled")return t;e.resetRetryCount&&this.#t.resetAssetForRetrying(t);let a=this.#t.getUploadAsset(t);a.abortController=o,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#t.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:o,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:s,shareContext:e.shareContext});return this.#m.push(t),this.#U(),this.#F(),t}startGroupUpload(e){this.#t.clearTerminalState();let t=this.#t.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.#x});return this.#_.set(t,Date.now()),this.#n?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#t.dirtyHistoryGroupIds.add(t),this.#$(),this.#F(),t}pauseUpload(e){let t=this.#t.getUploadAsset(e);this.#t.pauseUpload(e),this.#m=this.#m.filter(r=>r!==e),this.#p.pauseAsset(e),!this.#S&&t&&this.#n&&this.#n("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#F()}unpauseUpload(e){this.#t.unpauseUpload(e),this.#F()}cancelUpload(e){let t=this.#t.getUploadAsset(e);if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let r=t.fileName,s=t.totalBytesToUpload,o=t.bytesUploaded,i=t.projectId,a=t.chunkedState?.assetId;(t.status==="queued"||t.status==="in-progress")&&t.abortController.abort(),this.#m=this.#m.filter(l=>l!==e),this.#p.removeAsset(e),this.#f.delete(e),this.#E.delete(e),this.#t.markUploadCancelled(e),this.#t.clearChunkedState(e),t.fileReader.close?.(),!this.#S&&this.#n&&this.#n("upload:file_cancelled",{file_name:r,file_size:s,bytes_uploaded:o,project_id:i??""}),this.#F(),this.#z(),this.#U(),this.#V(),a&&(this.#L.push(a),this.#X())}cancelAllUploads(){let e=this.#Q();this.#S=!0;try{let r=Object.values(this.#t.uploadAssets).filter(s=>s.status==="queued"||s.status==="in-progress"||s.status==="paused");for(let s of r)this.cancelUpload(s.assetId)}finally{this.#S=!1}this.#n?.("upload:all_cancelled",e)}retryUpload(e){let t=this.#t.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.#t.getUploadAsset(e);if(!t||t.status!=="paused")return;!this.#S&&this.#n&&this.#n("upload:file_resumed",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""});let r=new AbortController;t.abortController=r,this.#t.unpauseUpload(e),this.#p.hasAsset(e)?(this.#p.unpauseAsset(e),this.#F(),this.#p.isAssetComplete(e)?this.#J(e).catch(s=>{this.#G(e,s)}):this.#z()):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.#t.uploadGroups[e];if(!t)return;let r=this.#S;this.#S=!0,this.#t.pauseUploadGroup(e);for(let s of t.assetIds)this.#m=this.#m.filter(o=>o!==s),this.#p.pauseAsset(s);this.#S=r,this.#S||this.#te(e,t,"upload:group_paused"),this.#F()}unpauseUploadGroup(e){this.#t.unpauseUploadGroup(e),this.#F()}cancelUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;let{totalBytes:r,bytesUploaded:s,filesRemaining:o}=this.#ee(t),i=this.#S;this.#S=!0;for(let a of t.assetIds)this.cancelUpload(a);t.assetIds.length===0&&(this.#t.finalizeEmptyGroup({groupId:e,status:"cancelled"}),this.#$(),this.#F()),this.#S=i,this.#S||this.#n?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:o,total_bytes:r,bytes_uploaded:s,project_id:t.projectId}),this.#_.delete(e)}resumeUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;this.#S||this.#te(e,t,"upload:group_resumed");let r=this.#S;this.#S=!0,this.#t.unpauseUploadGroup(e);for(let s of t.assetIds){let o=this.#t.getUploadAsset(s);o&&o.status==="paused"&&this.resumeUpload(s)}this.#S=r}retryUploadGroup(e){let t=this.#t.uploadGroups[e];if(t)for(let r of t.assetIds){let s=this.#t.getUploadAsset(r);s&&s.status==="failed"&&this.retryUpload(r)}}setGroupCreatingFolders(e,t){this.#t.updateUploadGroup(e,{isCreatingFolders:t}),this.#F()}markEmptyGroupFailed(e,t){let r=this.#t.uploadGroups[e];r&&(r.assetIds.length>0||r.finalizedStatus||(this.#i.error("Empty group upload failed",{groupId:e,groupName:r.name,errorMessage:t}),this.#t.finalizeEmptyGroup({groupId:e,status:"all-failed",errorMessage:t}),this.#$(),this.#_.delete(e),this.#F()))}markEmptyGroupCompleted(e){this.#t.finalizeEmptyGroup({groupId:e,status:"success"}),this.#$(),this.#_.delete(e),this.#F()}addAssetToGroup(e,t){this.#t.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#Q();this.#S=!0;try{for(let t of Object.values(this.#t.uploadAssets))t.groupId||this.pauseUpload(t.assetId);for(let t of Object.values(this.#t.uploadGroups))t.isCreatingFolders||this.pauseUploadGroup(t.id)}finally{this.#S=!1}this.#n?.("upload:all_paused",e),this.#F()}resumeAllUploads(){let e=this.#Q();this.#S=!0;try{for(let t of Object.values(this.#t.uploadAssets))!t.groupId&&t.status==="paused"&&this.resumeUpload(t.assetId);for(let t of Object.values(this.#t.uploadGroups))t.isPaused&&this.resumeUploadGroup(t.id)}finally{this.#S=!1}this.#n?.("upload:all_resumed",e),this.#F()}clearAllUploads(){this.#m=[],this.#p.clear(),this.#f.clear(),this.#E.clear(),this.#t.clearAllUploads(),this.#t.uploadGroups={},this.#A&&(this.#B=!0,this.#A.reset(),this.#B=!1),this.#a?.({all:!0}),this.#u?.(this.#H())}clearHistory(){this.#C=[],this.#o?.clear(),this.#b=!0,this.#h.clear(),this.#T=!0,this.#F()}removeHistoryItem(e){this.#C=this.#C.filter(t=>t.groupId!==e),this.#o?.remove(e),this.#h.add(e),this.#T=!0,this.#F()}removeGroup(e){this.#t.removeUploadGroup(e),this.#C=this.#C.filter(t=>t.groupId!==e),this.#o?.remove(e),this.#h.add(e),this.#T=!0,this.#a?.({groupId:e}),this.#u?.(this.#H()),this.#F()}getHttpClient(){return this.#e}setBandwidthLimit(e){let t=e!==this.#D;this.#D=e,this.#M.setLimit(e),this.#r?.setBandwidthLimitBps(e),t&&this.#A&&(this.#B=!0,this.#A.reset(),this.#B=!1),this.#T=!0,this.#F()}getBandwidthLimit(){return this.#D}setConflictResolution(e){this.#x=e,this.#r?.setConflictResolution(e),this.#T=!0,this.#F()}getConflictResolution(){return this.#x}getGroupConflictResolution(e){return this.#t.getUploadGroup(e)?.conflictResolution??this.#x}setMaxConcurrency(e){this.#l=e,this.#z()}getSnapshot(){return this.#t.updateUploadStats(),{...this.#t.getSerializableSnapshot(),uploadHistory:[...this.#C??[]],uploadSummary:this.#H(),bandwidthLimitBps:this.#D,conflictResolution:this.#x}}getUploadAsset(e){return this.#t.getSerializableAsset(e)}getUploadSummary(){return this.#H()}getGroupAssets(e){return this.#t.getGroupAssets(e)}getUploadGroupStatus(e){return this.#t.getUploadGroupStatus(e)}getUploadGroupProgress(e){return this.#t.getUploadGroupProgress(e)}hasGroupsCreatingFolders(){return this.#t.hasGroupsCreatingFolders()}areAllUploadsPaused(){return this.#t.areAllUploadsPaused()}hasPausedUploads(){return this.#t.hasPausedUploads()}hasActiveUploads(){return dt(this.#t.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return ut(this.#t.getSerializableSnapshot().uploadAssets)}async cancelActiveServerUploads(){let e=this.getServerAssetIdsToCancel();if(e.length!==0)try{await this.#e.post("/assets/cancel-uploads",{asset_ids:e})}catch{await this.#e.post("/assets/cancel-uploads",{asset_ids:e})}}destroy(){this.#w=!0,this.#g&&(clearInterval(this.#g),this.#g=null),this.#N&&(clearInterval(this.#N),this.#N=null),this.#m=[],this.#p.clear();for(let e of Object.values(this.#t.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#U(){this.#k||(this.#k=!0,queueMicrotask(()=>{this.#k=!1,this.#W().catch(e=>{this.#i.error("Initiation pipeline error",{queueLength:this.#m.length},e)})}))}async#W(){if(!this.#y){this.#y=!0;try{await this.#K()}finally{this.#y=!1}}}async#K(){for(;this.#m.length>0&&!(this.#f.size>5);){let e=Math.min(this.#m.length,20-this.#f.size);if(e<=0)break;let t=[],r=[];for(let s=0;s<e&&this.#m.length>0;s++){let o=this.#m[0],i=this.#t.getUploadAsset(o);if(!i||i.status==="cancelled"){this.#m.shift(),s--;continue}if(this.#m.shift(),r.push(o),i.chunkedState)try{this.#Y(o,i),this.#z()}catch(a){N(a)||this.#G(o,a)}else t.push(o)}if(t.length>0){let s=new Map;for(let o of t){let a=this.#t.getUploadAsset(o)?.shareContext?.shareId??"",l=s.get(a);l||(l=[],s.set(a,l)),l.push(o)}for(let o of s.values())try{await this.#j(o)}catch(i){for(let a of o)this.#G(a,i instanceof Error?i:new Error(String(i)))}this.#z()}}}#Y(e,t){let r=t.chunkedState,s={serverAssetId:r.assetId,chunkIds:r.chunkIds,chunkSize:r.chunkSize,totalChunks:r.totalChunks,sizeBytes:r.sizeBytes},o=r.completedChunkIndices;this.#f.set(e,s);let i=new Array(s.totalChunks).fill(0);if(o.length>0){for(let l of o){let c=l*s.chunkSize,u=Math.min(c+s.chunkSize,t.totalBytesToUpload);i[l]=u-c}let a=i.reduce((l,c)=>l+c,0);this.#t.updateUploadProgress(e,a)}if(this.#E.set(e,i),s.totalChunks===0||o.length>=s.totalChunks){this.#J(e).catch(a=>{this.#G(e,a)});return}this.#p.registerAsset({assetId:e,totalChunks:s.totalChunks,completedChunkIndices:o})}async#j(e){let t=[],r=[];for(let a of e){let l=this.#t.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let c=W(l.fileName),u=l.groupId?this.#t.getUploadGroup(l.groupId)?.conflictResolution??this.#x:this.#x,d=(()=>{switch(u){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:c,size_bytes:l.totalBytesToUpload,...d}),r.push(a)}if(t.length===0)return;let s=this.#t.getUploadAsset(r[0]),o=s?.shareContext?O(s.shareContext):void 0,i=await this.#e.post("/assets/chunked/initiate",t,o);for(let a=0;a<r.length;a++){let l=r[a],c=i[a];if(!c||c.error){this.#G(l,new Error(c?.error??"Unknown batch initiation error"));continue}if(c.skipped){let C=this.#t.getUploadAsset(l);C&&(this.#t.adjustSpeedBaselineForSkippedBytes(C.totalBytesToUpload),this.#t.markUploadSuccess(l),this.#t.dirtyHistoryGroupIds.add(C.groupId??""),this.#$(),C.fileReader.close?.());continue}let u=c.result,d=this.#t.getUploadAsset(l);if(!d||d.status==="cancelled"||d.status==="paused"){(!d||d.status==="cancelled")&&(this.#L.push(u.asset_id),this.#X());continue}let m=Math.ceil(d.totalBytesToUpload/u.chunk_size),h=Array.from({length:m},()=>crypto.randomUUID());this.#s.seedToken(u.asset_id,u.token,u.token_expires_at);let p={serverAssetId:u.asset_id,chunkIds:h,chunkSize:u.chunk_size,totalChunks:m,sizeBytes:d.totalBytesToUpload};this.#t.setChunkedState(l,{assetId:p.serverAssetId,chunkIds:p.chunkIds,completedChunkIndices:[],chunkSize:p.chunkSize,totalChunks:p.totalChunks,sizeBytes:p.sizeBytes}),this.#f.set(l,p);let y=new Array(p.totalChunks).fill(0);if(this.#E.set(l,y),p.totalChunks===0){this.#J(l).catch(C=>{this.#G(l,C)});continue}this.#p.registerAsset({assetId:l,totalChunks:p.totalChunks,completedChunkIndices:[]})}}#z(){if(!this.#w)for(;this.#v<this.#l;){let e=this.#p.claimNextChunk();if(!e)break;this.#v++;let{assetId:t,chunkIndex:r}=e,s=this.#A?.generation;this.#re(t,r,s).then(o=>{this.#v--,this.#oe(t,r,o),this.#z()}).catch(o=>{if(this.#v--,N(o)){this.#z();return}this.#ie(t,r,o),this.#z()})}}async#re(e,t,r){let s;for(let o=0;o<3;o++)try{let i=this.#E.get(e);return i&&(i[t]=0,this.#q(e)),await this.#se(e,t,r)}catch(i){if(N(i))throw i;if(s=i instanceof Error?i:new Error(String(i)),this.#A?.recordError(),this.#ae(e,t,s,o),o===2)throw s;let a=this.#E.get(e);a&&(a[t]=0,this.#q(e));let l=1e3*Math.pow(2,o);await kr(l)}throw s||new Error("Unknown error during chunk upload")}async#se(e,t,r){let s=this.#t.getUploadAsset(e);if(!s)throw new L;if(s.abortController.signal.aborted)throw new L;let o=this.#f.get(e);if(!o)throw new Error(`No chunk metadata for asset ${e}`);let i=t*o.chunkSize,a=Math.min(i+o.chunkSize,s.totalBytesToUpload),l=await s.fileReader.readChunk(i,a),c=vr(l);if(s.abortController.signal.aborted)throw new L;let u=o.chunkIds[t],d=await this.#s.getToken(o.serverAssetId,s.shareContext),m=`/uploads/chunks/${u}`,h=Date.now(),p=await this.#e.putWithToken(m,l,d,{signal:s.abortController.signal,onProgress:k=>{let w=this.#E.get(e);w&&(w[t]=k,this.#q(e))},contentType:"application/octet-stream",limiter:this.#M}),y=Date.now(),C=p.uploadCompletedAtMs??y,S=C-h;if(!p.status||p.status<200||p.status>=300)throw this.#i.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:u,assetId:e,serverAssetId:o.serverAssetId,chunkSizeBytes:c,durationMs:S,httpStatus:p.status,statusText:p.statusText,responseBody:p.data,responseHeaders:p.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${p.status}`);let Ee=this.#E.get(e);return Ee&&(Ee[t]=c,this.#q(e)),{durationMs:S,startedAtMs:h,completedAtMs:C,adaptiveGeneration:r}}#q(e){let t=this.#E.get(e);if(!t)return;let r=t.reduce((s,o)=>s+o,0);this.#t.updateUploadProgress(e,r)}#oe(e,t,r){if(this.#A){let o=this.#f.get(e);if(o){let i=t*o.chunkSize,l=Math.min(i+o.chunkSize,o.sizeBytes)-i;this.#A.recordSuccess(l,r.durationMs,{generation:r.adaptiveGeneration,startedAtMs:r.startedAtMs,completedAtMs:r.completedAtMs})}}this.#t.addCompletedChunkIndex(e,t),this.#p.markChunkCompleted(e,t)&&this.#J(e).catch(o=>{this.#G(e,o)})}#ie(e,t,r){this.#G(e,r)}#ae(e,t,r,s){if(!this.#n)return;let o=this.#t.getUploadAsset(e);if(!o)return;let i=this.#f.get(e);if(!i)return;let a=t*i.chunkSize,c=Math.min(a+i.chunkSize,i.sizeBytes)-a,u=r,d=typeof u.code=="string"?u.code:null,m=u.response?.status,h=typeof m=="number"?m:null,p=r.cause?r.cause instanceof Error?r.cause.message:String(r.cause):null,y=yt(r);this.#n("upload:chunk_error",{file_name:o.fileName,file_size:o.totalBytesToUpload,chunk_index:t,chunk_size:c,chunks_total:i.totalChunks,attempt:s+1,max_attempts:3,is_final_attempt:s===2,error_type:r.name,error_message:r.message,error_code:d,http_status:h,error_stack:r.stack??null,error_cause:p,project_id:o.projectId??"",had_response:y?.hadResponse??null,reused_socket:y?.reusedSocket??null,remote_address:y?.remoteAddress??null,remote_family:y?.remoteFamily??null,tls_protocol:y?.tlsProtocol??null,tls_cipher:y?.tlsCipher??null,peer_cert_issuer:y?.peerCertIssuer??null,peer_cert_subject:y?.peerCertSubject??null,tls_authorized:y?.tlsAuthorized??null})}#le(e,t,r,s){if(!this.#n||N(t))return;let o=t instanceof Error?t.message:"Unknown error",i=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof i.code=="string"?i.code:null,c=i.response?.status,u=typeof c=="number"?c:null,d=this.#f.get(e.assetId);this.#n("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:r+1,max_attempts:4,is_final_attempt:s,error_type:t instanceof Error?t.name:"Unknown",error_message:o,error_code:l,http_status:u,error_stack:t instanceof Error?t.stack??null:null,error_cause:a,project_id:e.projectId??""})}async#J(e){let t=this.#t.getUploadAsset(e);if(!t)return;let r=this.#f.get(e);if(!r)return;if(t.abortController.signal.aborted)throw new L;let s=crypto.randomUUID(),o=JSON.stringify(r.chunkIds),i=new TextEncoder().encode(o),a=await this.#s.getToken(r.serverAssetId,t.shareContext),l=`/uploads/manifests/${s}`;try{await this.#e.putWithToken(l,i,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(c){throw N(c)||this.#i.error("Manifest upload failed",{assetId:e,serverAssetId:r.serverAssetId,manifestId:s},c),c}if(t.abortController.signal.aborted)throw new L;try{let c=t.shareContext?O(t.shareContext):void 0;await this.#e.post(`/assets/${r.serverAssetId}/revisions/commit`,{manifest_id:s,size_bytes:r.sizeBytes,is_initial_upload:!0,client_performed_at:new Date().toISOString()},c)}catch(c){throw this.#i.error("Commit revision failed",{assetId:e,serverAssetId:r.serverAssetId,manifestId:s,sizeBytes:r.sizeBytes},c),c}this.#t.markUploadSuccess(e),this.#t.clearChunkedState(e),this.#$(),this.#F(),this.#f.delete(e),this.#E.delete(e),this.#p.removeAsset(e),await t.fileReader.close?.(),this.#ne(e),this.#U(),this.#V()}#G(e,t){let r=this.#t.getUploadAsset(e);if(!r||N(t)||r.status==="paused"||r.status==="cancelled")return;let s=r.retryCount,o=s>=3||Tr(t);if(this.#le(r,t,s,o),o){let i=t instanceof Error?t.message:"Unknown error";this.#i.error("Asset upload permanently failed",{assetId:e,fileName:r.fileName,totalRetries:s,bytesUploaded:r.bytesUploaded,totalBytes:r.totalBytesToUpload,chunksCompleted:r.chunkedState?.completedChunkIndices.length??0},t),r.abortController.abort(),this.#t.markUploadFailed(e,i),this.#p.removeAsset(e),this.#f.delete(e),this.#E.delete(e),this.#$(),this.#F(),this.#ne(e),this.#U(),this.#V()}else{this.#i.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:r.fileName,retryAttempt:s+1,maxRetries:3},t);let i=r.chunkedState;r.abortController.abort(),this.#p.removeAsset(e),this.#f.delete(e),this.#E.delete(e),this.#t.resetAssetForRetryQueue(e),this.#F(),this.#U();let a=2e3*Math.pow(2,s);setTimeout(()=>{if(this.#w)return;let l=this.#t.getUploadAsset(e);!l||l.status!=="queued"||this.startUpload({fileReader:l.fileReader,directoryId:l.parentId??"",projectId:l.projectId,groupId:l.groupId,assetId:e,resumeChunked:i,shareContext:l.shareContext})},a)}}#V(){this.#A&&(this.hasActiveUploads()||(this.#B=!0,this.#A.reset(),this.#B=!1))}#X(){this.#O||(this.#O=!0,queueMicrotask(()=>{this.#O=!1;let e=this.#L.splice(0);e.length!==0&&this.#e.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#i.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#H(){return oe(this.#t.getSerializableSnapshot().uploadAssets)}#F(){this.#I||(this.#I=!0,queueMicrotask(()=>{this.#I=!1,this.#ue()}))}#ce(){this.#Z(!0)}#ue(){this.#Z(!1)}#Z(e){if(this.#w||!this.#c&&!this.#u)return;e?this.#t.updateUploadStats():(this.#P++,this.#P%3===0&&this.#t.updateUploadStats());let t=this.#t.getDirtyDelta();if(!this.#T&&Object.keys(t.assets).length===0&&Object.keys(t.groups).length===0&&this.#t.dirtyHistoryGroupIds.size===0)return;this.#T=!1,this.#t.dirtyHistoryGroupIds.size>0&&this.#$();let s=this.#t.dirtyHistoryGroupIds.size>0?this.#pe():void 0,o=this.#b?!0:void 0,i=this.#h.size>0?[...this.#h]:void 0;this.#b=!1,this.#h.clear();let a=this.#H(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#t.uploadStats},uploadSpeedState:this.#t.uploadSpeedState,historyItems:s,removedHistoryGroupIds:i,historyCleared:o,uploadSummary:a,bandwidthLimitBps:this.#D,conflictResolution:this.#x};this.#t.clearDirtyFlags(),this.#c?.(l),this.#u?.(a)}#ee(e){let t=0,r=0,s=0;for(let o of e.assetIds){let i=this.#t.getUploadAsset(o);i&&(t+=i.totalBytesToUpload,r+=i.bytesUploaded,i.status!=="success"&&i.status!=="failed"&&i.status!=="cancelled"&&s++)}return{totalBytes:t,bytesUploaded:r,filesRemaining:s}}#Q(){let e=0,t=0,r=0,s=0;for(let o of Object.values(this.#t.uploadGroups)){e++;for(let i of o.assetIds){let a=this.#t.getUploadAsset(i);a&&(a.status==="success"||a.status==="failed"||a.status==="cancelled"||(t++,r+=a.totalBytesToUpload,s+=a.bytesUploaded))}}return{group_count:e,file_count:t,total_bytes:r,bytes_uploaded:s}}#de(){if(!(!this.#n||this.#w))for(let e of Object.values(this.#t.uploadGroups)){let t=!1,r=0,s=0,o=0,i=0,a=0,l=0,c=0,u=0,d=0,m=0;for(let y of e.assetIds){let C=this.#t.getUploadAsset(y);if(!C)continue;let S=C.totalBytesToUpload;switch(r+=S,s+=C.bytesUploaded,C.status){case"success":o++,i+=S;break;case"failed":a++,l+=S;break;case"cancelled":c++,u+=S;break;case"in-progress":d++,t=!0;break;case"queued":m++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let h=this.#_.get(e.id),p=h?Date.now()-h:0;this.#n("upload:group_progress",{group_id:e.id,file_count:e.assetIds.length,total_bytes:r,bytes_uploaded:s,duration_ms:p,project_id:e.projectId,succeeded_count:o,succeeded_bytes:i,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u,in_progress_count:d,queued_count:m,progress:r>0?s/r:0,concurrency:this.#l,upload_speed_mbps:this.#t.uploadStats.uploadSpeedMbps})}}#te(e,t,r){if(!this.#n)return;let{totalBytes:s,bytesUploaded:o}=this.#ee(t);this.#n(r,{file_count:t.fileCount,total_bytes:s,bytes_uploaded:o,project_id:t.projectId})}#ne(e){if(!this.#n)return;let t=this.#t.getUploadAsset(e);if(!t?.groupId)return;let r=this.#t.uploadGroups[t.groupId];if(!r)return;let s=!0,o=0,i=0,a=0,l=0,c=0,u=0,d=0;for(let p of r.assetIds){let y=this.#t.getUploadAsset(p);if(!y)continue;let C=y.totalBytesToUpload;if(d+=C,y.status==="success")o++,i+=C;else if(y.status==="failed")a++,l+=C;else if(y.status==="cancelled")c++,u+=C;else{s=!1;break}}if(!s)return;let m=this.#_.get(r.id),h=m?Date.now()-m:0;this.#n("upload:group_completed",{file_count:r.assetIds.length,total_bytes:d,duration_ms:h,project_id:r.projectId,succeeded_count:o,succeeded_bytes:i,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u}),this.#_.delete(r.id)}#pe(){let e={};for(let t of this.#t.dirtyHistoryGroupIds){let r=this.#t.buildHistoryItem(t);r&&(e[t]=r)}return e}#$(){if(!this.#o)return;let e={};for(let t of this.#t.dirtyHistoryGroupIds){let r=this.#t.buildHistoryItem(t);if(r){e[t]=r;let s=this.#C.findIndex(o=>o.groupId===t);s>=0?this.#C[s]=r:this.#C.unshift(r)}}Object.keys(e).length>0&&this.#o.merge(e)}};var Ur={keep_both:"Keep Both",replace:"Replace",skip:"Skip"};var Wa=new Set(["success","all-failed","some-failed","cancelled"]),Ka=new Set(["all-failed","some-failed"]),qa=new Set(["queued","in-progress"]),Ja=new Set(["queued","creating-folders","in-progress"]),Ya=new Set(["queued","in-progress"]),Va=new Set(["queued","in-progress","paused"]);var de=class{#e=65536;#s=0;async*createIterator(e,t,r){let s=0,o=Math.max(65536,Math.min(e.byteLength,this.#e)),i=this.#s;for(;s<e.byteLength;){if(r?.aborted)return;let a=t?t.getLimit():null,l=a!==null&&a>0;if(l){let p=Math.round(a*50/1e3);o=Math.max(65536,Math.min(e.byteLength,p))}let c=Math.min(s+o,e.byteLength),u=e.subarray(s,c),d=u.byteLength;if(l&&(await t.acquire(d),r?.aborted))return;let m=performance.now();yield u;let h=performance.now()-m;if(s=c,!l){if(h>=.5){let p=d/h*1e3;i=i===0?p:i*(1-.3)+p*.3}else i===0&&(o=Math.min(e.byteLength,o*2));if(i>0){let p=Math.round(i*50/1e3);o=Math.max(65536,Math.min(e.byteLength,p))}}this.#e=o,this.#s=i}}};var x=class{#e;#s;#t;#o;#r=new de;#n=new Set;constructor(e){this.#e=tn.create({baseURL:e.apiUrl}),this.#s=tn.create({baseURL:e.edgeWorkerUrl}),this.#t=e.apiKey,this.#o=e.sessionId}get skippedAssetIds(){return this.#n}async post(e,t,r){let s=await this.#e.post(e,t,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,"Content-Type":"application/json",...r}});return this.#c(e,t,s.data),s.data}async get(e,t){return(await this.#e.get(e,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,...t}})).data}async delete(e,t){await this.#e.delete(e,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,...t}})}async putWithToken(e,t,r,s){let o=await this.#i(t),i=this.#r.createIterator(o,s.limiter??null,s.signal),a=Lr.from(i,{highWaterMark:1}),l;try{l=await this.#s.put(e,a,{timeout:0,signal:s.signal,headers:{"Content-Type":s.contentType??"","Content-Length":o.byteLength.toString(),Authorization:`Bearer ${r}`},transformRequest:[c=>c],maxRedirects:0,onUploadProgress:c=>s.onProgress?.(c.loaded)})}catch(c){throw gt(c,ft(c)),c}return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#i(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#c(e,t,r){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(r))return;let s=t;r.forEach((i,a)=>{let l=s[a];i.skipped===!0&&typeof l?.id=="string"&&this.#n.add(l.id)})}};import me from"node:path";import D from"node:path";function b(n){let e=n.replace(/\\/g,"/");if(e.split("/").some(o=>o===".."))throw new Error(`Remote path cannot contain parent directory segments: ${n}`);let s=D.posix.normalize(e).replace(/^\/+/,"");if(s===""||s===".")throw new Error(`Remote path must resolve to a file path: ${n}`);return s}function Ue(n){let e=new Map;for(let o of n){let i=b(o.targetPath??o.path);e.set(i,(e.get(i)??0)+1)}let t=new Set,r=[],s=[];for(let o of n){let i=b(o.path),a=b(o.targetPath??o.path),l=pe(a),c=bt(l,t),u=(e.get(a)??0)>1,d=c!==i;t.add(c),r.push({...o,targetPath:c,requiresIdentityDownload:o.requiresIdentityDownload===!0||u}),(d||u)&&s.push({sourcePath:o.path,targetPath:c,reason:u||c!==l?"duplicate":"sanitized"})}return{files:r,changes:s}}function A(n){return b(n.targetPath??n.path)}function Le(n,e){let t=A(n);return{relativePath:t,absolutePath:D.join(e,t),fileName:D.posix.basename(t),size:n.size}}function pe(n){return n.split("/").map(t=>W(t)).join("/")}function bt(n,e){if(!e.has(n))return n;let t=D.posix.dirname(n),r=D.posix.basename(n),s=D.posix.extname(r),o=s.length>0?r.slice(0,-s.length):r,i=2;for(;;){let a=`${o} (${i})${s}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;i+=1}}function At(n,e){if(!e.has(n))return n;let t=D.posix.dirname(n),r=D.posix.basename(n),s=2;for(;;){let o=`${r} ${s}`,i=t==="."?o:`${t}/${o}`;if(!e.has(i))return i;s+=1}}var nn=500,xr=8,xe=class{#e;#s;#t=new Map;constructor(e){this.#e=e.rootDirectoryId,this.#s=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#o(e);for(let r of t){if(this.#t.has(r))continue;let s=me.posix.dirname(r),o=me.posix.basename(r),i=s==="."?this.#e:this.#t.get(s);if(!i)throw new Error(`Parent directory ID not found for path: ${r}`);let a=await this.#a(i,o);if(a.name!==o)throw new Error(`Server created renamed directory "${a.name}" for planned path "${r}". Refusing to map uploads to an unexpected target path.`);this.#t.set(r,a.id)}return e.map(r=>({file:r,directoryId:this.getDirectoryIdForFile(r.relativePath)}))}async loadExistingDirectories(){let e=await this.#r(this.#e);this.#t.clear(),this.#c(e,"")}getDirectoryIdForFile(e){let t=b(e),r=me.posix.dirname(t);if(r===".")return this.#e;let s=this.#t.get(r);if(!s)throw new Error(`Directory ID not found for path: ${r}`);return s}getExistingDirectoryIdForFile(e){let t=b(e),r=me.posix.dirname(t);return r==="."?this.#e:this.#t.get(r)??null}async checkAssetsExistence(e,t=!0){if(e.length===0)return[];let r=[];for(let s=0;s<e.length;s+=nn){let o=e.slice(s,s+nn),i=await this.#s.post("/assets/check-exists-and-uploaded",{items:o,delete_if_not_exist:t});r.push(...i.items)}return r}async listFilesInSubtree(e={}){let t=[{id:this.#e,relativePath:""}],r=[],s=0;for(;s<t.length;){let o=t.slice(s,s+xr),i=await Promise.all(o.map(a=>this.#n(a)));s+=o.length;for(let a of i)t.push(...a.directories),r.push(...a.files);e.onProgress?.({scannedDirectoryCount:s,queuedDirectoryCount:t.length,fileCount:r.length})}return r}#o(e){let t=new Set;for(let r of e){let s=b(r.relativePath),o=me.posix.dirname(s);if(o===".")continue;let i=o.split("/");for(let a=0;a<i.length;a++)t.add(i.slice(0,a+1).join("/"))}return Array.from(t).sort((r,s)=>r.split("/").length-s.split("/").length)}async#r(e){return this.#s.get(`/directories/${e}/tree`)}async#n(e){let[t,r]=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(s=>({id:s.id,relativePath:this.#i(e.relativePath,s.name)})),files:r.map(s=>({assetId:s.id,relativePath:this.#i(e.relativePath,s.name),sizeBytes:s.size_bytes,isUploaded:s.is_uploaded??!0,uploadStateKnown:typeof s.is_uploaded=="boolean"}))}}#i(e,t){let r=e===""?t:`${e}/${t}`;return b(r)}#c(e,t){let r=t===""?"":t==="."?e.name:`${t}/${e.name}`;r!==""&&this.#t.set(r,e.id);for(let s of e.children){let o=t===""?".":r;this.#c(s,o)}}async#a(e,t){return this.#s.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as Dr}from"posthog-node";var z=null,De="",Ft={};function rn(n){z||n.config.analytics.disabled||!n.config.analytics.posthogKey||(De=n.user.id,Ft={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}:{}},z=new Dr(n.config.analytics.posthogKey,{host:n.config.analytics.posthogHost}),z.identify({distinctId:De,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 sn(n,e){z&&z.capture({distinctId:De,event:n,properties:{...Ft,...e}})}async function on(){let n=z;if(_r(),!!n)try{await n.flush()}catch{}}function _r(){z=null,De="",Ft={}}import{spawn as Be}from"child_process";import*as Oe from"fs";import*as q from"path";var Br=2e3,E=class extends Error{constructor(t,r){super(t);this.stderr=r;this.name="RcloneError"}stderr};function Or(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 Mr(n){let e=["lsjson",n.remoteSource,"--recursive","--fast-list"];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function Nr(n){let e=["backend","query",`${n.remote}:`,n.query];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function zr(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 Gr(n){let e=["backend","copyid",`${n.remote}:`,n.fileId,n.localTargetPath,"--progress","--stats","1s","--stats-one-line","-v"];return n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function K(n,e){let t=e.trim(),r={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*(r[t]||1)}function an(n){let e=0,t=n.match(/(\d+)h/),r=n.match(/(\d+)m/),s=n.match(/(\d+)s/);return t&&(e+=parseInt(t[1],10)*3600),r&&(e+=parseInt(r[1],10)*60),s&&(e+=parseInt(s[1],10)),e}function $r(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+(.+)$/,r=e.match(t);if(r){let l=r[8].trim(),c={bytesTransferred:K(parseFloat(r[1]),r[2]),totalBytes:K(parseFloat(r[3]),r[4]),percentComplete:parseFloat(r[5]),speed:K(parseFloat(r[6]),r[7]),eta:l==="-"?0:an(l)};return{...c,currentFile:c}}let s=e.match(/Transferred:\s+([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%/);if(!s)return null;let o=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),i=e.match(/ETA\s+([^\s]+)$/),a={bytesTransferred:K(parseFloat(s[1]),s[2]),totalBytes:K(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:o?K(parseFloat(o[1]),o[2]):0,eta:i&&i[1]!=="-"?an(i[1]):0};return{...a,aggregate:a}}function wt(n){return new Promise((e,t)=>{let r=Be("rclone",n.args,{stdio:["ignore","pipe","pipe"]}),s="",o=0,i,a,l=c=>{for(let u of c.split(`
3
- `)){if(u.trim().length===0)continue;let d=$r(u);if(!d)continue;i=d.currentFile??i,a=d.aggregate??a;let m=Date.now();if(!(d.percentComplete>=100)&&m-o<500)continue;o=m;let p=a?{...a,aggregate:a,currentFile:i}:{...d,currentFile:i};n.onProgress?.(p)}};r.stdout.on("data",c=>{l(c.toString())}),r.stderr.on("data",c=>{let u=c.toString();s+=u,l(u)}),r.on("close",async c=>{c===0?e():t(new E(`rclone exited with code ${c}`,s))}),r.on("error",c=>{t(new E(`Failed to start rclone: ${c.message}`,""))})})}async function Me(){return new Promise((n,e)=>{let t=Be("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",r=>{r===0?n():e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))})})}async function jr(n,e,t,r,s,o){let i=`${n}:${e}`;return wt({args:Or({remoteSource:i,localPath:t,rcloneOptions:s,batchFilePath:r}),remoteSource:i,onProgress:o})}async function ln(n,e,t=[]){let r=`${n}:${e}`;return new Promise((s,o)=>{let i=Be("rclone",Mr({remoteSource:r,extraArgs:t})),a="",l="";i.stdout.on("data",c=>{a+=c.toString()}),i.stderr.on("data",c=>{l+=c.toString()}),i.on("close",async c=>{if(c===0)try{let u=JSON.parse(a||"[]");if(!Array.isArray(u))throw new Error("rclone lsjson did not return an array");let d=Hr(u),m=await Wr({remote:n,files:d.files,directories:d.directories,extraArgs:t});s(m)}catch(u){o(new E(`Failed to parse file listing from ${r}: ${u instanceof Error?u.message:String(u)}`,l))}else o(new E(`Failed to list files from ${r}`,l))}),i.on("error",c=>{o(new E(`Failed to start rclone: ${c.message}`,""))})})}async function cn(n){let e=new Et({localPath:n.localPath,files:n.files,onProgress:n.onProgress});e.start();let t=r=>{e.updateCurrentFile(r.currentFile)};try{let r=[],s=[];for(let o of n.files)Qr(o)?s.push(o):r.push(o);r.length>0&&(await Oe.promises.writeFile(n.batchFilePath,`${r.map(o=>o.path).join(`
2
+ import{Command as li}from"commander";import hn from"node:path";import{readFileSync as ci,realpathSync as mn}from"node:fs";import{fileURLToPath as ui}from"node:url";import ge from"node:fs/promises";import Bt from"node:path";import{stdin as Tr,stdout as kr}from"node:process";import{createInterface as Gs}from"node:readline/promises";import Sn from"fs/promises";import Cn from"path";function Vt(r,e){let t=new Map;for(let c of r){let u=Cn.dirname(c.targetPath??c.path);t.has(u)||t.set(u,[]),t.get(u).push(c)}let n=new Map;for(let[c,u]of t.entries()){let d=u.reduce((m,h)=>m+h.size,0);n.set(c,d)}let s=Array.from(t.keys()).sort(),o=[],i=[],a=0,l=1;for(let c of s){let u=t.get(c),d=n.get(c);if(d>e){if(i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),u.length===1)o.push({batchNumber:l++,files:u,totalSize:d});else for(let m of u)a+m.size>e&&i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),i.push(m),a+=m.size;continue}a+d>e&&i.length>0&&(o.push({batchNumber:l++,files:i,totalSize:a}),i=[],a=0),i.push(...u),a+=d}return i.length>0&&o.push({batchNumber:l++,files:i,totalSize:a}),o}async function Qt(r){try{await Sn.unlink(r)}catch(e){if(e.code!=="ENOENT")throw e}}import{Readable as _n}from"node:stream";import rr from"axios";function se(r,e){if(e.length===0)return r.finalizedStatus?r.finalizedStatus:r.isCreatingFolders?"creating-folders":"queued";if(r.isCreatingFolders)return"creating-folders";let t={queued:0,paused:0,inProgress:0,success:0,failed:0,cancelled:0};for(let s of e)switch(s.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 n=e.length;return t.failed===n?"all-failed":t.failed>0?"some-failed":t.success===n?"success":t.paused>0&&t.queued===0&&t.inProgress===0?"paused":t.queued>0||t.inProgress>0?t.queued+t.paused===n?"queued":"in-progress":"cancelled"}function ut(r,e){let t=se(r,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function dt(r){let e=[];for(let t of Object.values(r))t.chunkedState&&(t.status==="queued"||t.status==="in-progress"||t.status==="paused")&&e.push(t.chunkedState.assetId);return e}function pt(r){for(let e of Object.values(r))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function oe(r){let t=Object.values(r).reduce((n,s)=>{switch(s.status!=="failed"&&s.status!=="cancelled"&&(n.totalBytesToUpload+=s.totalBytesToUpload,n.totalBytesUploaded+=s.bytesUploaded),n.totalAssetCount+=1,s.status){case"queued":n.queuedAssetCount+=1;break;case"paused":n.pausedAssetCount+=1;break;case"in-progress":n.inProgressAssetCount+=1;break;case"success":n.successAssetCount+=1;break;case"failed":n.failedAssetCount+=1;break;case"cancelled":n.cancelledAssetCount+=1;break}return n},{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(r,e){if(e.length===0)return null;let t=e.reduce((n,s)=>(s.status!=="failed"&&s.status!=="cancelled"&&(n.totalBytes+=s.totalBytesToUpload,n.uploadedBytes+=s.bytesUploaded),s.status==="success"?n.filesSucceeded++:s.status==="failed"&&n.filesFailed++,(s.status==="success"||s.status==="failed"||s.status==="cancelled")&&n.filesCompleted++,n),{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 mt(r){let e=Object.values(r).filter(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused");return e.length===0?!1:e.every(t=>t.status==="paused")}function ht(r){return Object.values(r).some(e=>e.status==="paused")}import Ri from"axios";var ie=class{#e;#s;#t;#o;#n;#r=0;#i=0;#c=0;#l=0;#d=0;#u=0;constructor(e){this.#e=e?.alphaFast??.1,this.#s=e?.alphaMax??.5,this.#t=e?.consecutiveForBoost??3,this.#o=e?.minSamples??3,this.#n=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#l===0){this.#l=t,this.#d=e;return}let s=(t-this.#l)/1e3,o=e-this.#d;if(s<=0||o<0)return;if(s>this.#n){this.#l=t,this.#d=e;return}let i=o/s;if(this.#u===0)this.#r=i;else{let l=i-this.#r>=0?1:-1;this.#c!==0&&l===this.#c?this.#i++:this.#i=0,this.#c=l;let c=Math.min(1,this.#i/this.#t),u=this.#e+(this.#s-this.#e)*c;this.#r=u*i+(1-u)*this.#r}this.#l=t,this.#d=e,this.#u++}etaSeconds(e){return!this.isWarmedUp||this.#r<=0?0:e/this.#r}adjustTotalBytes(e){this.#d+=e}reset(){this.#r=0,this.#i=0,this.#c=0,this.#l=0,this.#d=0,this.#u=0}serialize(){return{displaySpeedBps:this.#r,lastSampleTimestamp:this.#l,lastSampleTotalBytes:this.#d,sampleCount:this.#u}}get speedBps(){return this.#r}get speedMbps(){return this.#r*8/1e6}get isWarmedUp(){return this.#u>=this.#o}};function O(r){let e={"X-Aspect-Share-Id":r.shareId};return r.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=r.shareAuthentication),e}var ae=class{#e;#s;#t;#o;#n;#r;#i;#c;#l;#d;#u;#a;#F;#h;#R;#k;#b;#g;#w;#E;#T;#m;#f;#I;#p;#v;#y;#P;#L;#O;#U;#M;constructor(e){this.#s=e?.minConcurrency??1,this.#t=e?.maxConcurrency??8,this.#e=this.#x(e?.initialConcurrency??this.#s),this.#o=e?.errorThreshold??1,this.#n=(e?.cooldownSeconds??10)*1e3,this.#r=e?.plateauThreshold??.05,this.#i=Math.max(this.#t,Math.floor(e?.sampleWindowSize??64)),this.#c=Math.max(2,Math.floor(e?.minSamples??4)),this.#l=Math.max(1.1,e?.increaseFactor??1.5),this.#d=e?.onChange,this.#u=e?.now??Date.now,this.#a=this.#e,this.#F=0,this.#h=[],this.#R=0,this.#k=0,this.#b=-1,this.#g=0,this.#w=void 0,this.#E=0,this.#T=0,this.#m=0,this.#f=this.#a,this.#I=0,this.#p=1/0,this.#v=0,this.#y=6e4,this.#P=0,this.#L=1/0,this.#O=0,this.#U=0,this.#M=0}recordSuccess(e,t,n){if(e<=0)return;if(n?.generation!==void 0){if(n.generation!==this.#F){n.generation===this.#b&&this.#g>0&&(this.#g--,this.#g===0&&(this.#w=n.completedAtMs??this.#u()));return}if(this.#g>0||this.#w!==void 0&&n.startedAtMs!==void 0&&n.startedAtMs<this.#w)return}else if(this.#k>0){this.#k--;return}let s=n?.completedAtMs??this.#u();for(this.#h.push({bytes:e,completedAtMs:s,startedAtMs:n?.startedAtMs,durationMs:t!==void 0&&t>0?t:void 0});this.#h.length>this.#i;)this.#h.shift();this.#R++,this.#E=0;let o=this.#z();this.#U=o.throughputBps,this.#M=o.latencyMsPerMB,this.#_(o)}recordError(){if(this.#E++,this.#E<this.#o)return;let e=this.#a;e===this.#P&&(this.#L=Math.min(this.#L,e),this.#O=this.#u()+3e4),this.#P=e;let t=this.#x(Math.floor(e/2));this.#T=this.#u()+this.#n,this.#E=0,e<=this.#f&&(this.#f=t,this.#I=0),e>t&&(this.#p=Math.min(this.#p,e),this.#W()),this.#C(t)}get concurrency(){return this.#a}get generation(){return this.#F}get speedBps(){return this.#U}get latencyMsPerMB(){return this.#M}reset(){this.#a=this.#e,this.#F++,this.#h=[],this.#R=0,this.#k=0,this.#b=-1,this.#g=0,this.#w=void 0,this.#E=0,this.#T=0,this.#m=0,this.#f=this.#a,this.#I=0,this.#p=1/0,this.#v=0,this.#y=6e4,this.#P=0,this.#L=1/0,this.#O=0,this.#U=0,this.#M=0,this.#d?.(this.#a)}#_(e){if(this.#h.length<this.#K()||this.#R<this.#K()||e.throughputBps<=0)return;let t=this.#u();if(t<this.#T)return;if(e.averageDurationMs>=2e4&&this.#a>=4){this.#f=Math.max(this.#s,Math.floor(this.#a/2)),this.#I=0,this.#C(this.#f);return}if(this.#I===0){this.#$(e.throughputBps),this.#D(e);return}let n=(e.throughputBps-this.#I)/this.#I;if(n>=this.#r){this.#$(e.throughputBps),this.#D(e);return}if(this.#a>this.#f){let s=n<=-.08,o=n<this.#r;(s||o)&&(this.#p=Math.min(this.#p,this.#a),this.#W(),this.#C(this.#f));return}if(this.#a<this.#f){this.#D(e);return}this.#a===this.#f&&(this.#I=Math.max(this.#I,e.throughputBps),t>=this.#m&&this.#D(e))}#D(e){let t=this.#G();if(this.#a>=t){this.#R=0;return}if(e.averageDurationMs>=5e3&&this.#a>=4&&this.#I>0){this.#R=0;return}if(this.#N()){let s=this.#u();if(this.#v===0){this.#v=s+this.#y,this.#m=this.#v,this.#R=0;return}if(s<this.#v){this.#R=0;return}}let n=this.#S(t);if(n===this.#a){this.#R=0;return}this.#C(n)}#$(e){this.#f=this.#a,this.#I=e,this.#p<=this.#a&&(this.#p=1/0),this.#v=0,this.#y=6e4,this.#m=0}#S(e){if(this.#p<1/0){let s=Math.floor((this.#a+this.#p)/2);return s>this.#a&&s<this.#p?Math.min(e,s):Math.min(e,this.#a+1)}if(this.#a<4)return Math.min(e,this.#a+1);let t=Math.ceil(this.#a*this.#l),n=this.#a+2;return Math.min(e,Math.max(n,t))}#C(e){let t=this.#a,n=this.#F,s=this.#x(e);s!==t&&(this.#B(),this.#a=s,this.#F++,this.#b=n,this.#g=Math.max(0,t-1),this.#w=this.#g===0?this.#u():void 0,this.#k=Math.max(0,t-1),this.#d?.(this.#a))}#B(){this.#h=[],this.#R=0,this.#k=0}#N(){return this.#p<1/0&&this.#a===this.#f&&this.#p<=this.#f+1}#W(){let e=this.#p<1/0&&this.#p<=this.#f+1,t=e?this.#y:1e4;this.#m=this.#u()+t,e&&(this.#v=this.#m,this.#y=Math.min(this.#y*2,3e5))}#K(){return Math.max(this.#c,this.#a)}#G(){return this.#L<1/0&&this.#u()>=this.#O&&(this.#L=1/0,this.#O=0),Math.max(this.#s,Math.min(this.#t,this.#L-1))}#x(e){return Math.max(this.#s,Math.min(this.#t,e))}#z(){let e=0,t=0,n=0,s=0;for(let l of this.#h)e+=l.bytes,l.durationMs!==void 0&&(t+=l.durationMs,n++,s+=l.durationMs/(l.bytes/(1024*1024)));if(n>0&&t>0)return{throughputBps:e/(t/1e3)*this.#a,latencyMsPerMB:s/n,averageDurationMs:t/n,durationSampleCount:n};if(this.#h.length<2)return{throughputBps:0,latencyMsPerMB:0,averageDurationMs:0,durationSampleCount:0};let o=this.#h[0],a=this.#h[this.#h.length-1].completedAtMs-o.completedAtMs;return{throughputBps:a>0?e/a*1e3:0,latencyMsPerMB:0,averageDurationMs:a>0?a/Math.max(1,this.#h.length-1):0,durationSampleCount:0}}};var H=class{#e;#s;#t;#o;#n;#r;#i;#c;constructor(e,t){this.#r=t?.now??(()=>Date.now()),this.#i=t?.setTimer??((s,o)=>setTimeout(s,o)),this.#c=t?.clearTimer??(s=>clearTimeout(s));let n=e===0?null:e;this.#e=n,this.#s=n??0,this.#t=this.#r(),this.#o=[],this.#n=null}setLimit(e){let t=e===0?null:e;if(t===null){this.#e=null,this.#s=0,this.#F();let s=this.#o.splice(0);for(let o of s)o.resolve();return}let n=this.#e;this.#e=t,n===null?(this.#s=t,this.#t=this.#r()):(this.#l(),this.#s=Math.min(this.#s,t)),this.#a()}getLimit(){return this.#e}acquire(e){if(this.#e!==null){if(this.#l(),this.#o.length===0&&this.#s>=e){this.#s-=e;return}return this.#d(e)}}#l(){let e=this.#r(),t=(e-this.#t)/1e3;if(t<=0)return;let n=this.#e,s=t*n,o=this.#o.length>0?Math.max(n,this.#o[0].bytes):n;this.#s=Math.min(this.#s+s,o),this.#t=e}#d(e){return new Promise(t=>{this.#o.push({bytes:e,resolve:t}),this.#n===null&&this.#u()})}#u(){if(this.#o.length===0||this.#e===null){this.#n=null;return}let t=this.#o[0].bytes-this.#s,n=t>0?Math.ceil(t/this.#e*1e3):0;if(n<=0){this.#n=null,this.#a();return}this.#n=this.#i(()=>{this.#n=null,this.#l(),this.#a()},n)}#a(){for(;this.#o.length>0;){if(this.#e===null){let t=this.#o.splice(0);for(let n of t)n.resolve();return}this.#l();let e=this.#o[0];if(this.#s>=e.bytes)this.#s-=e.bytes,this.#o.shift(),e.resolve();else{this.#u();return}}}#F(){this.#n!==null&&(this.#c(this.#n),this.#n=null)}};function Xt(r){let e=`[${r}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var ft=Xt("transfer");var er="transportDiagnostics";function M(r){return typeof r=="string"&&r.length>0?r:null}function Zt(r){if(r===null||typeof r!="object")return null;let e=r,t=M(e.O),n=M(e.CN),s=[t,n].filter(o=>o!==null);return s.length>0?s.join(" / "):null}function bn(r){if(!r)return{};let e={remoteAddress:M(r.remoteAddress),remoteFamily:M(r.remoteFamily),tlsAuthorized:typeof r.authorized=="boolean"?r.authorized:null};if(typeof r.getProtocol=="function"&&(e.tlsProtocol=M(r.getProtocol())),typeof r.getCipher=="function"){let t=r.getCipher();t!==null&&typeof t=="object"&&(e.tlsCipher=M(t.name))}if(typeof r.getPeerCertificate=="function"){let t=r.getPeerCertificate();if(t!==null&&typeof t=="object"){let n=t;e.peerCertIssuer=Zt(n.issuer),e.peerCertSubject=Zt(n.subject)}}return e}function gt(r){let e={errorCode:null,hadResponse:!1,reusedSocket:null,remoteAddress:null,remoteFamily:null,tlsProtocol:null,tlsCipher:null,peerCertIssuer:null,peerCertSubject:null,tlsAuthorized:null};if(r===null||typeof r!="object")return e;let t=r;e.errorCode=M(t.code),e.hadResponse=t.response!=null;let n=t.request;if(n){e.reusedSocket=typeof n.reusedSocket=="boolean"?n.reusedSocket:null;let s=n.socket??n.res?.socket??null;Object.assign(e,bn(s))}return e}function yt(r,e){r===null||typeof r!="object"||(r[er]=e)}function St(r){if(r===null||typeof r!="object")return null;let e=r[er];return e??null}var Ct=r=>!Number.isFinite(r)||r<=0?"Calculating...":r<1?`${(r*1e3).toFixed(0)} Kbps`:`${r.toFixed(1)} Mbps`,bt=r=>{if(!Number.isFinite(r)||r<=0)return"Calculating...";let e=Math.floor(r/3600),t=Math.floor(r%3600/60),n=Math.floor(r%60);return e>0?`${e}h ${t}m left`:t>0?`${t}m ${n}s left`:`${n}s left`};var Re=class{uploadAssets={};uploadGroups={};#e=new ie;get uploadSpeedState(){return this.#e.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#s(e){e!==0&&this.#e.adjustTotalBytes(-e)}adjustSpeedBaselineForSkippedBytes(e){e!==0&&this.#e.adjustTotalBytes(e)}#t(){Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress")||this.#e.reset()}#o(e){this.dirtyAssetIds.add(e)}#n(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:n,parentId:s,projectId:o,groupId:i,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:s,projectId:o,groupId:i,retryCount:0,chunkSize:a??0,fileReader:t,abortController:n,shareContext:l},this.#o(e)}updateUploadProgress(e,t){let n=this.uploadAssets[e];if(!n||n.status==="paused"||n.status==="cancelled"||n.status==="success"||n.status==="failed")return;let s=t>0&&n.status==="queued"?"in-progress":n.status,o=Math.min(t,n.totalBytesToUpload);n.bytesUploaded=o,n.status=s,this.#o(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#o(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#o(e),this.#t(),this.cleanupOnCompletion(e))}markUploadFailed(e,t){let n=this.uploadAssets[e];if(!n)return;let s=n.bytesUploaded;n.status="failed",n.errorMessage=t,n.bytesUploaded=0,this.#o(e),this.#s(s),this.#t(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let n=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#o(e),this.#s(n),this.#t()}clearAllUploads(){this.uploadAssets={},this.#e.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.#e.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.#o(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#o(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let n=0;if(t.chunkedState){let{completedChunkIndices:o,chunkSize:i}=t.chunkedState;for(let a of o){let l=a*i,c=Math.min(l+i,t.totalBytesToUpload);n+=c-l}}let s=t.bytesUploaded-n;t.status="paused",t.bytesUploaded=n,this.#o(e),this.#s(s),this.#t(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#o(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#n(e);for(let n of t.assetIds)this.pauseUpload(n)}}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 n=t.bytesUploaded;t.status="cancelled",this.#o(e),this.#s(n),this.#t(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let n=this.uploadAssets[e];n&&(n.chunkedState=t,this.#o(e))}addCompletedChunkIndex(e,t){let n=this.uploadAssets[e];!n||!n.chunkedState||(n.chunkedState={...n.chunkedState,completedChunkIndices:[...n.chunkedState.completedChunkIndices,t]},this.#o(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#o(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return mt(this.uploadAssets)}hasPausedUploads(){return ht(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#r(t)}getUploadSummary(){return oe(this.#c())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#r(e)).sort((e,t)=>t.i-e.i)}getGroupAssets(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(n=>this.uploadAssets[n]).filter(Boolean).map(n=>this.#r(n))}getGroupAssetsInternal(e){let t=this.uploadGroups[e];return!t||!t.assetIds?[]:t.assetIds.map(n=>this.uploadAssets[n]).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 n=this.uploadGroups[e];n&&(Object.assign(n,t),this.#n(e))}addAssetToGroup(e,t){let n=this.uploadGroups[e];n&&(n.assetIds.push(t),this.#n(e))}finalizeEmptyGroup({groupId:e,status:t,errorMessage:n}){let s=this.uploadGroups[e];s&&(s.assetIds.length>0||s.finalizedStatus||(s.finalizedStatus=t,s.errorMessage=n,s.isCreatingFolders=!1,s.completedAt=new Date().toISOString(),this.#n(e),this.dirtyHistoryGroupIds.add(e)))}removeUploadGroup(e){let t=this.uploadGroups[e];if(t)for(let n of t.assetIds)delete this.uploadAssets[n],this.#o(n);delete this.uploadGroups[e],this.#n(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#i(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#i(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let n=this.getGroupAssets(e);return Pe(this.#i(t),n)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let n=this.getGroupAssets(e);return se(this.#i(t),n)}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#r(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.#i(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let n=t.groupId;if(n){let o=this.uploadGroups[n];if(o){let i=this.getGroupAssets(n),a=this.#i(o);this.dirtyHistoryGroupIds.add(n),!i.some(c=>c.status==="queued"||c.status==="in-progress")&&!o.completedAt&&(o.completedAt=new Date().toISOString(),this.#n(n))}}let s=this.getUploadSummary();if(s.cancelledAssetCount+s.failedAssetCount+s.successAssetCount===s.totalAssetCount)for(let o of Object.keys(this.uploadAssets)){let i=this.uploadAssets[o];i&&(i.bytesUploaded=0,this.#o(o))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#e.sample(e.totalBytesUploaded);let n=this.#e.isWarmedUp?this.#e.speedMbps:0,s=t&&this.#e.isWarmedUp?this.#e.etaSeconds(e.totalBytesToUpload-e.totalBytesUploaded):0;this.uploadStats={uploadSpeedMbps:n,timeRemainingSeconds:s,formattedSpeed:Ct(n),formattedTime:bt(s)}}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let n=this.getGroupAssets(e),s=this.#i(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:ut(s,n),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#r({fileReader:e,abortController:t,shareContext:n,...s}){return s}#i({fileReaders:e,...t}){return t}#c(){let e={};for(let[t,n]of Object.entries(this.uploadAssets))e[t]=this.#r(n);return e}#l(){let e={};for(let[t,n]of Object.entries(this.uploadGroups))e[t]=this.#i(n);return e}getSerializableSnapshot(){return{uploadAssets:this.#c(),uploadGroups:this.#l(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let n of this.dirtyAssetIds){let s=this.uploadAssets[n];s&&(e[n]=this.#r(s))}let t={};for(let n of this.dirtyGroupIds){let s=this.uploadGroups[n];s&&(t[n]=this.#i(s))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function Fn(r,e){let t=new Date(r).getTime(),n=Date.now();return t-n<=e}var Te=class{#e;#s=new Map;#t=new Map;constructor(e){this.#e=e}seedToken(e,t,n){this.#s.set(e,{token:t,expiresAt:n})}async getToken(e,t){let n=this.#s.get(e);if(n&&!Fn(n.expiresAt,3e5))return n.token;let s=this.#t.get(e);if(s)return s;let o=t?O(t):void 0,i=this.#e.post(`/assets/${e}/token`,{},o).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.#t.delete(e),a.token}).catch(a=>{throw this.#t.delete(e),a});return this.#t.set(e,i),i}clearCache(e){e?this.#s.delete(e):this.#s.clear()}};var ke=class{#e=[];registerAsset(e){this.#e.push({assetId:e.assetId,totalChunks:e.totalChunks,nextChunkToClaim:0,completedChunkIndices:new Set(e.completedChunkIndices),isPaused:!1})}claimNextChunk(){for(let e of this.#e)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 n=this.#s(e);return n?(n.completedChunkIndices.add(t),n.completedChunkIndices.size>=n.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.#t(t))}removeAsset(e){this.#e=this.#e.filter(t=>t.assetId!==e)}hasAsset(e){return this.#e.some(t=>t.assetId===e)}isAssetComplete(e){let t=this.#s(e);return t?t.completedChunkIndices.size>=t.totalChunks:!1}clear(){this.#e=[]}#s(e){return this.#e.find(t=>t.assetId===e)}#t(e){for(let t=0;t<e.totalChunks;t++)if(!e.completedChunkIndices.has(t)){e.nextChunkToClaim=t;return}e.nextChunkToClaim=e.totalChunks}};var wn=/[/\\:*?"<>|\x00-\x1F]/g,En=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function W(r){let e=r.replace(wn,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;En.includes(t.toUpperCase())&&(e=`_${e}`);let n=new TextEncoder;if(n.encode(e).length>255){let s=e.lastIndexOf("."),o=s>0?e.substring(s):"",i=s>0?e.substring(0,s):e,l=255-n.encode(o).length;for(;n.encode(i).length>l&&i.length>0;)i=i.slice(0,-1);e=i+o}return e}var U=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function N(r){return r instanceof U||r instanceof Error&&r.name==="CancelledError"||r instanceof Error&&r.name==="CanceledError"||r instanceof Error&&r.name==="AbortError"}function Ln(r){return N(r)||r instanceof Error&&r.name==="NoAuthError"}function Un(r){return new Promise(e=>setTimeout(e,r))}function xn(r){return r instanceof Blob?r.size:r.byteLength}var ce=class{#e;#s;#t;#o;#n;#r;#i;#c;#l;#d;#u;#a;#F;#h=null;#R=0;#k=!1;#b=[];#g=new Set;#w=!1;#E=!1;#T=!1;#m=[];#f=!1;#I=!1;#p=new ke;#v=0;#y=new Map;#P=new Map;#L=[];#O=!1;#U=null;#M;#_="keep_both";#D=new Map;#$=null;#S=!1;#C=null;#B=!1;constructor(e){this.#e=e.httpClient,this.#s=new Te(e.httpClient),this.#t=new Re,this.#o=e.historyStore??null,this.#n=e.settingsStore??null,this.#r=e.analytics??null,this.#i=e.logger??ft,this.#c=e.onChange??null,this.#l=e.onClear??null,this.#d=e.onSummary??null,this.#u=e.onConcurrencyAdjusted??null,this.#F=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let n=e.adaptiveConcurrencyConfig;this.#C=new ae({initialConcurrency:n?.initialConcurrency??Math.min(4,t),minConcurrency:n?.minConcurrency??1,maxConcurrency:n?.maxConcurrency??t,errorThreshold:n?.errorThreshold,cooldownSeconds:n?.cooldownSeconds??10,plateauThreshold:n?.plateauThreshold,onChange:s=>{let o=this.#a;if(this.setMaxConcurrency(s),o===s)return;let i=this.#B?"reset":s>o?"probe_increase":"error_decrease",a=Math.round(this.#C.speedBps*8/1e6*100)/100,l=Math.round(this.#C.latencyMsPerMB*100)/100;this.#i.info(`Adaptive concurrency: ${o} \u2192 ${s} (${i}), measuredAt=${o}, speed=${a}Mbps, latency=${l}ms/MB`),this.#u?.({previousConcurrency:o,newConcurrency:s,reason:i,speedMbps:a,latencyMsPerMB:l})},now:n?.now}),this.#a=this.#C.concurrency}else this.#a=t;this.#o&&(this.#b=this.#o.load()),this.#n&&(this.#U=this.#n.getBandwidthLimitBps(),this.#_=this.#n.getConflictResolution()),this.#M=new H(this.#U),(this.#c||this.#d)&&(this.#h=setInterval(()=>{this.#ce()},this.#F)),this.#r&&(this.#$=setInterval(()=>{this.#de()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),n=!!e.assetId,s;if(n){let i=this.#t.getUploadAsset(t);if(!i)throw new Error(`Cannot retry: asset ${t} not found`);s=i.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");s=e.chunkSize}let o=new AbortController;if(n){if(this.#t.getUploadAsset(t).status==="cancelled")return t;e.resetRetryCount&&this.#t.resetAssetForRetrying(t);let a=this.#t.getUploadAsset(t);a.abortController=o,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#t.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:o,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:s,shareContext:e.shareContext});return this.#m.push(t),this.#N(),this.#A(),t}startGroupUpload(e){this.#t.clearTerminalState();let t=this.#t.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.#D.set(t,Date.now()),this.#r?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#t.dirtyHistoryGroupIds.add(t),this.#H(),this.#A(),t}pauseUpload(e){let t=this.#t.getUploadAsset(e);this.#t.pauseUpload(e),this.#m=this.#m.filter(n=>n!==e),this.#p.pauseAsset(e),!this.#S&&t&&this.#r&&this.#r("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#A()}unpauseUpload(e){this.#t.unpauseUpload(e),this.#A()}cancelUpload(e){let t=this.#t.getUploadAsset(e);if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let n=t.fileName,s=t.totalBytesToUpload,o=t.bytesUploaded,i=t.projectId,a=t.chunkedState?.assetId;(t.status==="queued"||t.status==="in-progress")&&t.abortController.abort(),this.#m=this.#m.filter(l=>l!==e),this.#p.removeAsset(e),this.#y.delete(e),this.#P.delete(e),this.#t.markUploadCancelled(e),this.#t.clearChunkedState(e),t.fileReader.close?.(),!this.#S&&this.#r&&this.#r("upload:file_cancelled",{file_name:n,file_size:s,bytes_uploaded:o,project_id:i??""}),this.#A(),this.#z(),this.#N(),this.#V(),a&&(this.#L.push(a),this.#X())}cancelAllUploads(){let e=this.#Q();this.#S=!0;try{let n=Object.values(this.#t.uploadAssets).filter(s=>s.status==="queued"||s.status==="in-progress"||s.status==="paused");for(let s of n)this.cancelUpload(s.assetId)}finally{this.#S=!1}this.#r?.("upload:all_cancelled",e)}retryUpload(e){let t=this.#t.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.#t.getUploadAsset(e);if(!t||t.status!=="paused")return;!this.#S&&this.#r&&this.#r("upload:file_resumed",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""});let n=new AbortController;t.abortController=n,this.#t.unpauseUpload(e),this.#p.hasAsset(e)?(this.#p.unpauseAsset(e),this.#A(),this.#p.isAssetComplete(e)?this.#Y(e).catch(s=>{this.#j(e,s)}):this.#z()):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.#t.uploadGroups[e];if(!t)return;let n=this.#S;this.#S=!0,this.#t.pauseUploadGroup(e);for(let s of t.assetIds)this.#m=this.#m.filter(o=>o!==s),this.#p.pauseAsset(s);this.#S=n,this.#S||this.#te(e,t,"upload:group_paused"),this.#A()}unpauseUploadGroup(e){this.#t.unpauseUploadGroup(e),this.#A()}cancelUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;let{totalBytes:n,bytesUploaded:s,filesRemaining:o}=this.#ee(t),i=this.#S;this.#S=!0;for(let a of t.assetIds)this.cancelUpload(a);t.assetIds.length===0&&(this.#t.finalizeEmptyGroup({groupId:e,status:"cancelled"}),this.#H(),this.#A()),this.#S=i,this.#S||this.#r?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:o,total_bytes:n,bytes_uploaded:s,project_id:t.projectId}),this.#D.delete(e)}resumeUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;this.#S||this.#te(e,t,"upload:group_resumed");let n=this.#S;this.#S=!0,this.#t.unpauseUploadGroup(e);for(let s of t.assetIds){let o=this.#t.getUploadAsset(s);o&&o.status==="paused"&&this.resumeUpload(s)}this.#S=n}retryUploadGroup(e){let t=this.#t.uploadGroups[e];if(t)for(let n of t.assetIds){let s=this.#t.getUploadAsset(n);s&&s.status==="failed"&&this.retryUpload(n)}}setGroupCreatingFolders(e,t){this.#t.updateUploadGroup(e,{isCreatingFolders:t}),this.#A()}markEmptyGroupFailed(e,t){let n=this.#t.uploadGroups[e];n&&(n.assetIds.length>0||n.finalizedStatus||(this.#i.error("Empty group upload failed",{groupId:e,groupName:n.name,errorMessage:t}),this.#t.finalizeEmptyGroup({groupId:e,status:"all-failed",errorMessage:t}),this.#H(),this.#D.delete(e),this.#A()))}markEmptyGroupCompleted(e){this.#t.finalizeEmptyGroup({groupId:e,status:"success"}),this.#H(),this.#D.delete(e),this.#A()}addAssetToGroup(e,t){this.#t.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#Q();this.#S=!0;try{for(let t of Object.values(this.#t.uploadAssets))t.groupId||this.pauseUpload(t.assetId);for(let t of Object.values(this.#t.uploadGroups))t.isCreatingFolders||this.pauseUploadGroup(t.id)}finally{this.#S=!1}this.#r?.("upload:all_paused",e),this.#A()}resumeAllUploads(){let e=this.#Q();this.#S=!0;try{for(let t of Object.values(this.#t.uploadAssets))!t.groupId&&t.status==="paused"&&this.resumeUpload(t.assetId);for(let t of Object.values(this.#t.uploadGroups))t.isPaused&&this.resumeUploadGroup(t.id)}finally{this.#S=!1}this.#r?.("upload:all_resumed",e),this.#A()}clearAllUploads(){this.#m=[],this.#p.clear(),this.#y.clear(),this.#P.clear(),this.#t.clearAllUploads(),this.#t.uploadGroups={},this.#C&&(this.#B=!0,this.#C.reset(),this.#B=!1),this.#l?.({all:!0}),this.#d?.(this.#q())}clearHistory(){this.#b=[],this.#o?.clear(),this.#w=!0,this.#g.clear(),this.#T=!0,this.#A()}removeHistoryItem(e){this.#b=this.#b.filter(t=>t.groupId!==e),this.#o?.remove(e),this.#g.add(e),this.#T=!0,this.#A()}removeGroup(e){this.#t.removeUploadGroup(e),this.#b=this.#b.filter(t=>t.groupId!==e),this.#o?.remove(e),this.#g.add(e),this.#T=!0,this.#l?.({groupId:e}),this.#d?.(this.#q()),this.#A()}getHttpClient(){return this.#e}setBandwidthLimit(e){let t=e!==this.#U;this.#U=e,this.#M.setLimit(e),this.#n?.setBandwidthLimitBps(e),t&&this.#C&&(this.#B=!0,this.#C.reset(),this.#B=!1),this.#T=!0,this.#A()}getBandwidthLimit(){return this.#U}setConflictResolution(e){this.#_=e,this.#n?.setConflictResolution(e),this.#T=!0,this.#A()}getConflictResolution(){return this.#_}getGroupConflictResolution(e){return this.#t.getUploadGroup(e)?.conflictResolution??this.#_}setMaxConcurrency(e){this.#a=e,this.#z()}getSnapshot(){return this.#t.updateUploadStats(),{...this.#t.getSerializableSnapshot(),uploadHistory:[...this.#b??[]],uploadSummary:this.#q(),bandwidthLimitBps:this.#U,conflictResolution:this.#_}}getUploadAsset(e){return this.#t.getSerializableAsset(e)}getUploadSummary(){return this.#q()}getGroupAssets(e){return this.#t.getGroupAssets(e)}getUploadGroupStatus(e){return this.#t.getUploadGroupStatus(e)}getUploadGroupProgress(e){return this.#t.getUploadGroupProgress(e)}hasGroupsCreatingFolders(){return this.#t.hasGroupsCreatingFolders()}areAllUploadsPaused(){return this.#t.areAllUploadsPaused()}hasPausedUploads(){return this.#t.hasPausedUploads()}hasActiveUploads(){return pt(this.#t.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return dt(this.#t.getSerializableSnapshot().uploadAssets)}async cancelActiveServerUploads(){let e=this.getServerAssetIdsToCancel();if(e.length!==0)try{await this.#e.post("/assets/cancel-uploads",{asset_ids:e})}catch{await this.#e.post("/assets/cancel-uploads",{asset_ids:e})}}destroy(){this.#E=!0,this.#h&&(clearInterval(this.#h),this.#h=null),this.#$&&(clearInterval(this.#$),this.#$=null),this.#m=[],this.#p.clear();for(let e of Object.values(this.#t.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#N(){this.#I||(this.#I=!0,queueMicrotask(()=>{this.#I=!1,this.#W().catch(e=>{this.#i.error("Initiation pipeline error",{queueLength:this.#m.length},e)})}))}async#W(){if(!this.#f){this.#f=!0;try{await this.#K()}finally{this.#f=!1}}}async#K(){for(;this.#m.length>0&&!(this.#y.size>5);){let e=Math.min(this.#m.length,20-this.#y.size);if(e<=0)break;let t=[],n=[];for(let s=0;s<e&&this.#m.length>0;s++){let o=this.#m[0],i=this.#t.getUploadAsset(o);if(!i||i.status==="cancelled"){this.#m.shift(),s--;continue}if(this.#m.shift(),n.push(o),i.chunkedState)try{this.#G(o,i),this.#z()}catch(a){N(a)||this.#j(o,a)}else t.push(o)}if(t.length>0){let s=new Map;for(let o of t){let a=this.#t.getUploadAsset(o)?.shareContext?.shareId??"",l=s.get(a);l||(l=[],s.set(a,l)),l.push(o)}for(let o of s.values())try{await this.#x(o)}catch(i){for(let a of o)this.#j(a,i instanceof Error?i:new Error(String(i)))}this.#z()}}}#G(e,t){let n=t.chunkedState,s={serverAssetId:n.assetId,chunkIds:n.chunkIds,chunkSize:n.chunkSize,totalChunks:n.totalChunks,sizeBytes:n.sizeBytes},o=n.completedChunkIndices;this.#y.set(e,s);let i=new Array(s.totalChunks).fill(0);if(o.length>0){for(let l of o){let c=l*s.chunkSize,u=Math.min(c+s.chunkSize,t.totalBytesToUpload);i[l]=u-c}let a=i.reduce((l,c)=>l+c,0);this.#t.updateUploadProgress(e,a)}if(this.#P.set(e,i),s.totalChunks===0||o.length>=s.totalChunks){this.#Y(e).catch(a=>{this.#j(e,a)});return}this.#p.registerAsset({assetId:e,totalChunks:s.totalChunks,completedChunkIndices:o})}async#x(e){let t=[],n=[];for(let a of e){let l=this.#t.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let c=W(l.fileName),u=l.groupId?this.#t.getUploadGroup(l.groupId)?.conflictResolution??this.#_:this.#_,d=(()=>{switch(u){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:c,size_bytes:l.totalBytesToUpload,...d}),n.push(a)}if(t.length===0)return;let s=this.#t.getUploadAsset(n[0]),o=s?.shareContext?O(s.shareContext):void 0,i=await this.#e.post("/assets/chunked/initiate",t,o);for(let a=0;a<n.length;a++){let l=n[a],c=i[a];if(!c||c.error){this.#j(l,new Error(c?.error??"Unknown batch initiation error"));continue}if(c.skipped){let C=this.#t.getUploadAsset(l);C&&(this.#t.adjustSpeedBaselineForSkippedBytes(C.totalBytesToUpload),this.#t.markUploadSuccess(l),this.#t.dirtyHistoryGroupIds.add(C.groupId??""),this.#H(),C.fileReader.close?.());continue}let u=c.result,d=this.#t.getUploadAsset(l);if(!d||d.status==="cancelled"||d.status==="paused"){(!d||d.status==="cancelled")&&(this.#L.push(u.asset_id),this.#X());continue}let m=Math.ceil(d.totalBytesToUpload/u.chunk_size),h=Array.from({length:m},()=>crypto.randomUUID());this.#s.seedToken(u.asset_id,u.token,u.token_expires_at);let p={serverAssetId:u.asset_id,chunkIds:h,chunkSize:u.chunk_size,totalChunks:m,sizeBytes:d.totalBytesToUpload};this.#t.setChunkedState(l,{assetId:p.serverAssetId,chunkIds:p.chunkIds,completedChunkIndices:[],chunkSize:p.chunkSize,totalChunks:p.totalChunks,sizeBytes:p.sizeBytes}),this.#y.set(l,p);let y=new Array(p.totalChunks).fill(0);if(this.#P.set(l,y),p.totalChunks===0){this.#Y(l).catch(C=>{this.#j(l,C)});continue}this.#p.registerAsset({assetId:l,totalChunks:p.totalChunks,completedChunkIndices:[]})}}#z(){if(!this.#E)for(;this.#v<this.#a;){let e=this.#p.claimNextChunk();if(!e)break;this.#v++;let{assetId:t,chunkIndex:n}=e,s=this.#C?.generation;this.#ne(t,n,s).then(o=>{this.#v--,this.#oe(t,n,o),this.#z()}).catch(o=>{if(this.#v--,N(o)){this.#z();return}this.#ie(t,n,o),this.#z()})}}async#ne(e,t,n){let s;for(let o=0;o<3;o++)try{let i=this.#P.get(e);return i&&(i[t]=0,this.#J(e)),await this.#se(e,t,n)}catch(i){if(N(i))throw i;if(s=i instanceof Error?i:new Error(String(i)),this.#C?.recordError(),this.#ae(e,t,s,o),o===2)throw s;let a=this.#P.get(e);a&&(a[t]=0,this.#J(e));let l=1e3*Math.pow(2,o);await Un(l)}throw s||new Error("Unknown error during chunk upload")}async#se(e,t,n){let s=this.#t.getUploadAsset(e);if(!s)throw new U;if(s.abortController.signal.aborted)throw new U;let o=this.#y.get(e);if(!o)throw new Error(`No chunk metadata for asset ${e}`);let i=t*o.chunkSize,a=Math.min(i+o.chunkSize,s.totalBytesToUpload),l=await s.fileReader.readChunk(i,a),c=xn(l);if(s.abortController.signal.aborted)throw new U;let u=o.chunkIds[t],d=await this.#s.getToken(o.serverAssetId,s.shareContext),m=`/uploads/chunks/${u}`,h=Date.now(),p=await this.#e.putWithToken(m,l,d,{signal:s.abortController.signal,onProgress:k=>{let w=this.#P.get(e);w&&(w[t]=k,this.#J(e))},contentType:"application/octet-stream",limiter:this.#M}),y=Date.now(),C=p.uploadCompletedAtMs??y,S=C-h;if(!p.status||p.status<200||p.status>=300)throw this.#i.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:u,assetId:e,serverAssetId:o.serverAssetId,chunkSizeBytes:c,durationMs:S,httpStatus:p.status,statusText:p.statusText,responseBody:p.data,responseHeaders:p.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${p.status}`);let Ee=this.#P.get(e);return Ee&&(Ee[t]=c,this.#J(e)),{durationMs:S,startedAtMs:h,completedAtMs:C,adaptiveGeneration:n}}#J(e){let t=this.#P.get(e);if(!t)return;let n=t.reduce((s,o)=>s+o,0);this.#t.updateUploadProgress(e,n)}#oe(e,t,n){if(this.#C){let o=this.#y.get(e);if(o){let i=t*o.chunkSize,l=Math.min(i+o.chunkSize,o.sizeBytes)-i;this.#C.recordSuccess(l,n.durationMs,{generation:n.adaptiveGeneration,startedAtMs:n.startedAtMs,completedAtMs:n.completedAtMs})}}this.#t.addCompletedChunkIndex(e,t),this.#p.markChunkCompleted(e,t)&&this.#Y(e).catch(o=>{this.#j(e,o)})}#ie(e,t,n){this.#j(e,n)}#ae(e,t,n,s){if(!this.#r)return;let o=this.#t.getUploadAsset(e);if(!o)return;let i=this.#y.get(e);if(!i)return;let a=t*i.chunkSize,c=Math.min(a+i.chunkSize,i.sizeBytes)-a,u=n,d=typeof u.code=="string"?u.code:null,m=u.response?.status,h=typeof m=="number"?m:null,p=n.cause?n.cause instanceof Error?n.cause.message:String(n.cause):null,y=St(n);this.#r("upload:chunk_error",{file_name:o.fileName,file_size:o.totalBytesToUpload,chunk_index:t,chunk_size:c,chunks_total:i.totalChunks,attempt:s+1,max_attempts:3,is_final_attempt:s===2,error_type:n.name,error_message:n.message,error_code:d,http_status:h,error_stack:n.stack??null,error_cause:p,project_id:o.projectId??"",had_response:y?.hadResponse??null,reused_socket:y?.reusedSocket??null,remote_address:y?.remoteAddress??null,remote_family:y?.remoteFamily??null,tls_protocol:y?.tlsProtocol??null,tls_cipher:y?.tlsCipher??null,peer_cert_issuer:y?.peerCertIssuer??null,peer_cert_subject:y?.peerCertSubject??null,tls_authorized:y?.tlsAuthorized??null})}#le(e,t,n,s){if(!this.#r||N(t))return;let o=t instanceof Error?t.message:"Unknown error",i=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof i.code=="string"?i.code:null,c=i.response?.status,u=typeof c=="number"?c:null,d=this.#y.get(e.assetId);this.#r("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:n+1,max_attempts:4,is_final_attempt:s,error_type:t instanceof Error?t.name:"Unknown",error_message:o,error_code:l,http_status:u,error_stack:t instanceof Error?t.stack??null:null,error_cause:a,project_id:e.projectId??""})}async#Y(e){let t=this.#t.getUploadAsset(e);if(!t)return;let n=this.#y.get(e);if(!n)return;if(t.abortController.signal.aborted)throw new U;let s=crypto.randomUUID(),o=JSON.stringify(n.chunkIds),i=new TextEncoder().encode(o),a=await this.#s.getToken(n.serverAssetId,t.shareContext),l=`/uploads/manifests/${s}`;try{await this.#e.putWithToken(l,i,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(c){throw N(c)||this.#i.error("Manifest upload failed",{assetId:e,serverAssetId:n.serverAssetId,manifestId:s},c),c}if(t.abortController.signal.aborted)throw new U;try{let c=t.shareContext?O(t.shareContext):void 0;await this.#e.post(`/assets/${n.serverAssetId}/revisions/commit`,{manifest_id:s,size_bytes:n.sizeBytes,is_initial_upload:!0,client_performed_at:new Date().toISOString()},c)}catch(c){throw this.#i.error("Commit revision failed",{assetId:e,serverAssetId:n.serverAssetId,manifestId:s,sizeBytes:n.sizeBytes},c),c}this.#t.markUploadSuccess(e),this.#t.clearChunkedState(e),this.#H(),this.#A(),this.#y.delete(e),this.#P.delete(e),this.#p.removeAsset(e),await t.fileReader.close?.(),this.#re(e),this.#N(),this.#V()}#j(e,t){let n=this.#t.getUploadAsset(e);if(!n||N(t)||n.status==="paused"||n.status==="cancelled")return;let s=n.retryCount,o=s>=3||Ln(t);if(this.#le(n,t,s,o),o){let i=t instanceof Error?t.message:"Unknown error";this.#i.error("Asset upload permanently failed",{assetId:e,fileName:n.fileName,totalRetries:s,bytesUploaded:n.bytesUploaded,totalBytes:n.totalBytesToUpload,chunksCompleted:n.chunkedState?.completedChunkIndices.length??0},t),n.abortController.abort(),this.#t.markUploadFailed(e,i),this.#p.removeAsset(e),this.#y.delete(e),this.#P.delete(e),this.#H(),this.#A(),this.#re(e),this.#N(),this.#V()}else{this.#i.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:n.fileName,retryAttempt:s+1,maxRetries:3},t);let i=n.chunkedState;n.abortController.abort(),this.#p.removeAsset(e),this.#y.delete(e),this.#P.delete(e),this.#t.resetAssetForRetryQueue(e),this.#A(),this.#N();let a=2e3*Math.pow(2,s);setTimeout(()=>{if(this.#E)return;let l=this.#t.getUploadAsset(e);!l||l.status!=="queued"||this.startUpload({fileReader:l.fileReader,directoryId:l.parentId??"",projectId:l.projectId,groupId:l.groupId,assetId:e,resumeChunked:i,shareContext:l.shareContext})},a)}}#V(){this.#C&&(this.hasActiveUploads()||(this.#B=!0,this.#C.reset(),this.#B=!1))}#X(){this.#O||(this.#O=!0,queueMicrotask(()=>{this.#O=!1;let e=this.#L.splice(0);e.length!==0&&this.#e.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#i.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#q(){return oe(this.#t.getSerializableSnapshot().uploadAssets)}#A(){this.#k||(this.#k=!0,queueMicrotask(()=>{this.#k=!1,this.#ue()}))}#ce(){this.#Z(!0)}#ue(){this.#Z(!1)}#Z(e){if(this.#E||!this.#c&&!this.#d)return;e?this.#t.updateUploadStats():(this.#R++,this.#R%3===0&&this.#t.updateUploadStats());let t=this.#t.getDirtyDelta();if(!this.#T&&Object.keys(t.assets).length===0&&Object.keys(t.groups).length===0&&this.#t.dirtyHistoryGroupIds.size===0)return;this.#T=!1,this.#t.dirtyHistoryGroupIds.size>0&&this.#H();let s=this.#t.dirtyHistoryGroupIds.size>0?this.#pe():void 0,o=this.#w?!0:void 0,i=this.#g.size>0?[...this.#g]:void 0;this.#w=!1,this.#g.clear();let a=this.#q(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#t.uploadStats},uploadSpeedState:this.#t.uploadSpeedState,historyItems:s,removedHistoryGroupIds:i,historyCleared:o,uploadSummary:a,bandwidthLimitBps:this.#U,conflictResolution:this.#_};this.#t.clearDirtyFlags(),this.#c?.(l),this.#d?.(a)}#ee(e){let t=0,n=0,s=0;for(let o of e.assetIds){let i=this.#t.getUploadAsset(o);i&&(t+=i.totalBytesToUpload,n+=i.bytesUploaded,i.status!=="success"&&i.status!=="failed"&&i.status!=="cancelled"&&s++)}return{totalBytes:t,bytesUploaded:n,filesRemaining:s}}#Q(){let e=0,t=0,n=0,s=0;for(let o of Object.values(this.#t.uploadGroups)){e++;for(let i of o.assetIds){let a=this.#t.getUploadAsset(i);a&&(a.status==="success"||a.status==="failed"||a.status==="cancelled"||(t++,n+=a.totalBytesToUpload,s+=a.bytesUploaded))}}return{group_count:e,file_count:t,total_bytes:n,bytes_uploaded:s}}#de(){if(!(!this.#r||this.#E))for(let e of Object.values(this.#t.uploadGroups)){let t=!1,n=0,s=0,o=0,i=0,a=0,l=0,c=0,u=0,d=0,m=0;for(let y of e.assetIds){let C=this.#t.getUploadAsset(y);if(!C)continue;let S=C.totalBytesToUpload;switch(n+=S,s+=C.bytesUploaded,C.status){case"success":o++,i+=S;break;case"failed":a++,l+=S;break;case"cancelled":c++,u+=S;break;case"in-progress":d++,t=!0;break;case"queued":m++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let h=this.#D.get(e.id),p=h?Date.now()-h:0;this.#r("upload:group_progress",{group_id:e.id,file_count:e.assetIds.length,total_bytes:n,bytes_uploaded:s,duration_ms:p,project_id:e.projectId,succeeded_count:o,succeeded_bytes:i,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u,in_progress_count:d,queued_count:m,progress:n>0?s/n:0,concurrency:this.#a,upload_speed_mbps:this.#t.uploadStats.uploadSpeedMbps})}}#te(e,t,n){if(!this.#r)return;let{totalBytes:s,bytesUploaded:o}=this.#ee(t);this.#r(n,{file_count:t.fileCount,total_bytes:s,bytes_uploaded:o,project_id:t.projectId})}#re(e){if(!this.#r)return;let t=this.#t.getUploadAsset(e);if(!t?.groupId)return;let n=this.#t.uploadGroups[t.groupId];if(!n)return;let s=!0,o=0,i=0,a=0,l=0,c=0,u=0,d=0;for(let p of n.assetIds){let y=this.#t.getUploadAsset(p);if(!y)continue;let C=y.totalBytesToUpload;if(d+=C,y.status==="success")o++,i+=C;else if(y.status==="failed")a++,l+=C;else if(y.status==="cancelled")c++,u+=C;else{s=!1;break}}if(!s)return;let m=this.#D.get(n.id),h=m?Date.now()-m:0;this.#r("upload:group_completed",{file_count:n.assetIds.length,total_bytes:d,duration_ms:h,project_id:n.projectId,succeeded_count:o,succeeded_bytes:i,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u}),this.#D.delete(n.id)}#pe(){let e={};for(let t of this.#t.dirtyHistoryGroupIds){let n=this.#t.buildHistoryItem(t);n&&(e[t]=n)}return e}#H(){if(!this.#o)return;let e={};for(let t of this.#t.dirtyHistoryGroupIds){let n=this.#t.buildHistoryItem(t);if(n){e[t]=n;let s=this.#b.findIndex(o=>o.groupId===t);s>=0?this.#b[s]=n:this.#b.unshift(n)}}Object.keys(e).length>0&&this.#o.merge(e)}};var Dn={keep_both:"Keep Both",replace:"Replace",skip:"Skip"};var Va=new Set(["success","all-failed","some-failed","cancelled"]),Qa=new Set(["all-failed","some-failed"]),Xa=new Set(["queued","in-progress"]),Za=new Set(["queued","creating-folders","in-progress"]),el=new Set(["queued","in-progress"]),tl=new Set(["queued","in-progress","paused"]);var de=class{#e=65536;#s=0;async*createIterator(e,t,n){let s=0,o=Math.max(65536,Math.min(e.byteLength,this.#e)),i=this.#s;for(;s<e.byteLength;){if(n?.aborted)return;let a=t?t.getLimit():null,l=a!==null&&a>0;if(l){let p=Math.round(a*50/1e3);o=Math.max(65536,Math.min(e.byteLength,p))}let c=Math.min(s+o,e.byteLength),u=e.subarray(s,c),d=u.byteLength;if(l&&(await t.acquire(d),n?.aborted))return;let m=performance.now();yield u;let h=performance.now()-m;if(s=c,!l){if(h>=.5){let p=d/h*1e3;i=i===0?p:i*(1-.3)+p*.3}else i===0&&(o=Math.min(e.byteLength,o*2));if(i>0){let p=Math.round(i*50/1e3);o=Math.max(65536,Math.min(e.byteLength,p))}}this.#e=o,this.#s=i}}};var x=class{#e;#s;#t;#o;#n=new de;#r=new Set;constructor(e){this.#e=rr.create({baseURL:e.apiUrl}),this.#s=rr.create({baseURL:e.edgeWorkerUrl}),this.#t=e.apiKey,this.#o=e.sessionId}get skippedAssetIds(){return this.#r}async post(e,t,n){let s=await this.#e.post(e,t,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,"Content-Type":"application/json",...n}});return this.#c(e,t,s.data),s.data}async get(e,t){return(await this.#e.get(e,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,...t}})).data}async delete(e,t){await this.#e.delete(e,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#o,...t}})}async putWithToken(e,t,n,s){let o=await this.#i(t),i=this.#n.createIterator(o,s.limiter??null,s.signal),a=_n.from(i,{highWaterMark:1}),l;try{l=await this.#s.put(e,a,{timeout:0,signal:s.signal,headers:{"Content-Type":s.contentType??"","Content-Length":o.byteLength.toString(),Authorization:`Bearer ${n}`},transformRequest:[c=>c],maxRedirects:0,onUploadProgress:c=>s.onProgress?.(c.loaded)})}catch(c){throw yt(c,gt(c)),c}return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#i(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#c(e,t,n){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(n))return;let s=t;n.forEach((i,a)=>{let l=s[a];i.skipped===!0&&typeof l?.id=="string"&&this.#r.add(l.id)})}};import me from"node:path";import D from"node:path";function b(r){let e=r.replace(/\\/g,"/");if(e.split("/").some(o=>o===".."))throw new Error(`Remote path cannot contain parent directory segments: ${r}`);let s=D.posix.normalize(e).replace(/^\/+/,"");if(s===""||s===".")throw new Error(`Remote path must resolve to a file path: ${r}`);return s}function Le(r){let e=new Map;for(let o of r){let i=b(o.targetPath??o.path);e.set(i,(e.get(i)??0)+1)}let t=new Set,n=[],s=[];for(let o of r){let i=b(o.path),a=b(o.targetPath??o.path),l=pe(a),c=At(l,t),u=(e.get(a)??0)>1,d=c!==i;t.add(c),n.push({...o,targetPath:c,requiresIdentityDownload:o.requiresIdentityDownload===!0||u}),(d||u)&&s.push({sourcePath:o.path,targetPath:c,reason:u||c!==l?"duplicate":"sanitized"})}return{files:n,changes:s}}function A(r){return b(r.targetPath??r.path)}function Ue(r,e){let t=A(r);return{relativePath:t,absolutePath:D.join(e,t),fileName:D.posix.basename(t),size:r.size}}function pe(r){return r.split("/").map(t=>W(t)).join("/")}function At(r,e){if(!e.has(r))return r;let t=D.posix.dirname(r),n=D.posix.basename(r),s=D.posix.extname(n),o=s.length>0?n.slice(0,-s.length):n,i=2;for(;;){let a=`${o} (${i})${s}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;i+=1}}function Ft(r,e){if(!e.has(r))return r;let t=D.posix.dirname(r),n=D.posix.basename(r),s=2;for(;;){let o=`${n} ${s}`,i=t==="."?o:`${t}/${o}`;if(!e.has(i))return i;s+=1}}var nr=500,Bn=8,xe=class{#e;#s;#t=new Map;constructor(e){this.#e=e.rootDirectoryId,this.#s=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#o(e);for(let n of t){if(this.#t.has(n))continue;let s=me.posix.dirname(n),o=me.posix.basename(n),i=s==="."?this.#e:this.#t.get(s);if(!i)throw new Error(`Parent directory ID not found for path: ${n}`);let a=await this.#l(i,o);if(a.name!==o)throw new Error(`Server created renamed directory "${a.name}" for planned path "${n}". Refusing to map uploads to an unexpected target path.`);this.#t.set(n,a.id)}return e.map(n=>({file:n,directoryId:this.getDirectoryIdForFile(n.relativePath)}))}async loadExistingDirectories(){let e=await this.#n(this.#e);this.#t.clear(),this.#c(e,"")}getDirectoryIdForFile(e){let t=b(e),n=me.posix.dirname(t);if(n===".")return this.#e;let s=this.#t.get(n);if(!s)throw new Error(`Directory ID not found for path: ${n}`);return s}getExistingDirectoryIdForFile(e){let t=b(e),n=me.posix.dirname(t);return n==="."?this.#e:this.#t.get(n)??null}async checkAssetsExistence(e,t=!0){if(e.length===0)return[];let n=[];for(let s=0;s<e.length;s+=nr){let o=e.slice(s,s+nr),i=await this.#s.post("/assets/check-exists-and-uploaded",{items:o,delete_if_not_exist:t});n.push(...i.items)}return n}async listFilesInSubtree(e={}){let t=[{id:this.#e,relativePath:""}],n=[],s=0;for(;s<t.length;){let o=t.slice(s,s+Bn),i=await Promise.all(o.map(a=>this.#r(a)));s+=o.length;for(let a of i)t.push(...a.directories),n.push(...a.files);e.onProgress?.({scannedDirectoryCount:s,queuedDirectoryCount:t.length,fileCount:n.length})}return n}#o(e){let t=new Set;for(let n of e){let s=b(n.relativePath),o=me.posix.dirname(s);if(o===".")continue;let i=o.split("/");for(let a=0;a<i.length;a++)t.add(i.slice(0,a+1).join("/"))}return Array.from(t).sort((n,s)=>n.split("/").length-s.split("/").length)}async#n(e){return this.#s.get(`/directories/${e}/tree`)}async#r(e){let[t,n]=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(s=>({id:s.id,relativePath:this.#i(e.relativePath,s.name)})),files:n.map(s=>({assetId:s.id,relativePath:this.#i(e.relativePath,s.name),sizeBytes:s.size_bytes,isUploaded:s.is_uploaded??!0,uploadStateKnown:typeof s.is_uploaded=="boolean"}))}}#i(e,t){let n=e===""?t:`${e}/${t}`;return b(n)}#c(e,t){let n=t===""?"":t==="."?e.name:`${t}/${e.name}`;n!==""&&this.#t.set(n,e.id);for(let s of e.children){let o=t===""?".":n;this.#c(s,o)}}async#l(e,t){return this.#s.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as On}from"posthog-node";var z=null,De="",wt={};function sr(r){z||r.config.analytics.disabled||!r.config.analytics.posthogKey||(De=r.user.id,wt={service:"data-sync",package_version:r.packageVersion,platform:process.platform,arch:process.arch,node_version:process.version,max_concurrent:r.config.maxConcurrent,batch_mode:r.config.batchSizeBytes!==void 0,batch_size_bytes:r.config.batchSizeBytes??null,source_kind:r.config.source.kind,...r.config.source.kind==="rclone"?{rclone_transfers:r.config.source.rcloneOptions.transfers,rclone_multi_thread_streams:r.config.source.rcloneOptions.multiThreadStreams}:{}},z=new On(r.config.analytics.posthogKey,{host:r.config.analytics.posthogHost}),z.identify({distinctId:De,properties:{user_id:r.user.id,email:r.user.email,first_name:r.user.first_name,last_name:r.user.last_name,utm_source_latest:null,utm_medium_latest:null,utm_campaign_latest:null,utm_content_latest:null}}))}function or(r,e){z&&z.capture({distinctId:De,event:r,properties:{...wt,...e}})}async function ir(){let r=z;if(Mn(),!!r)try{await r.flush()}catch{}}function Mn(){z=null,De="",wt={}}import{spawn as Be}from"child_process";import*as Oe from"fs";import*as q from"path";var Nn=2e3,E=class extends Error{constructor(t,n){super(t);this.stderr=n;this.name="RcloneError"}stderr};function zn(r){let e=["sync",r.remoteSource,r.localPath];return r.batchFilePath&&e.push("--files-from",r.batchFilePath),e.push("--progress","--stats","1s","--stats-one-line","-v","--transfers",String(r.rcloneOptions.transfers),"--checkers",String(r.rcloneOptions.checkers),"--multi-thread-streams",String(r.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",r.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",r.rcloneOptions.multiThreadCutoff,"--fast-list","--buffer-size",r.rcloneOptions.bufferSize),r.rcloneOptions.useMmap&&e.push("--use-mmap"),r.rcloneOptions.extraRcloneArgs?.length&&e.push(...r.rcloneOptions.extraRcloneArgs),e}function $n(r){let e=["lsjson",r.remoteSource,"--recursive","--fast-list"];return r.extraArgs?.length&&e.push(...r.extraArgs),e}function Gn(r){let e=["backend","query",`${r.remote}:`,r.query];return r.extraArgs?.length&&e.push(...r.extraArgs),e}function jn(r){let e=["copyto",r.remoteFileSource,r.localTargetPath,"--progress","--stats","1s","--stats-one-line","-v","--multi-thread-streams",String(r.rcloneOptions.multiThreadStreams),"--multi-thread-chunk-size",r.rcloneOptions.multiThreadChunkSize,"--multi-thread-cutoff",r.rcloneOptions.multiThreadCutoff,"--buffer-size",r.rcloneOptions.bufferSize];return r.rcloneOptions.useMmap&&e.push("--use-mmap"),r.rcloneOptions.extraRcloneArgs?.length&&e.push(...r.rcloneOptions.extraRcloneArgs),e}function Hn(r){let e=["backend","copyid",`${r.remote}:`,r.fileId,r.localTargetPath,"--progress","--stats","1s","--stats-one-line","-v"];return r.rcloneOptions.extraRcloneArgs?.length&&e.push(...r.rcloneOptions.extraRcloneArgs),e}function K(r,e){let t=e.trim(),n={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 r*(n[t]||1)}function ar(r){let e=0,t=r.match(/(\d+)h/),n=r.match(/(\d+)m/),s=r.match(/(\d+)s/);return t&&(e+=parseInt(t[1],10)*3600),n&&(e+=parseInt(n[1],10)*60),s&&(e+=parseInt(s[1],10)),e}function Wn(r){let e=r.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+(.+)$/,n=e.match(t);if(n){let l=n[8].trim(),c={bytesTransferred:K(parseFloat(n[1]),n[2]),totalBytes:K(parseFloat(n[3]),n[4]),percentComplete:parseFloat(n[5]),speed:K(parseFloat(n[6]),n[7]),eta:l==="-"?0:ar(l)};return{...c,currentFile:c}}let s=e.match(/Transferred:\s+([\d.]+)\s*([A-Za-z]+)\s*\/\s*([\d.]+)\s*([A-Za-z]+),\s*([\d.]+)%/);if(!s)return null;let o=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),i=e.match(/ETA\s+([^\s]+)$/),a={bytesTransferred:K(parseFloat(s[1]),s[2]),totalBytes:K(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:o?K(parseFloat(o[1]),o[2]):0,eta:i&&i[1]!=="-"?ar(i[1]):0};return{...a,aggregate:a}}function Et(r){return new Promise((e,t)=>{let n=Be("rclone",r.args,{stdio:["ignore","pipe","pipe"]}),s="",o=0,i,a,l=c=>{for(let u of c.split(`
3
+ `)){if(u.trim().length===0)continue;let d=Wn(u);if(!d)continue;i=d.currentFile??i,a=d.aggregate??a;let m=Date.now();if(!(d.percentComplete>=100)&&m-o<500)continue;o=m;let p=a?{...a,aggregate:a,currentFile:i}:{...d,currentFile:i};r.onProgress?.(p)}};n.stdout.on("data",c=>{l(c.toString())}),n.stderr.on("data",c=>{let u=c.toString();s+=u,l(u)}),n.on("close",async c=>{c===0?e():t(new E(`rclone exited with code ${c}`,s))}),n.on("error",c=>{t(new E(`Failed to start rclone: ${c.message}`,""))})})}async function Me(){return new Promise((r,e)=>{let t=Be("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",n=>{n===0?r():e(new Error("rclone is not installed or not in PATH. Please install rclone first: https://rclone.org/install/"))})})}async function Kn(r,e,t,n,s,o){let i=`${r}:${e}`;return Et({args:zn({remoteSource:i,localPath:t,rcloneOptions:s,batchFilePath:n}),remoteSource:i,onProgress:o})}async function lr(r,e,t=[]){let n=`${r}:${e}`;return new Promise((s,o)=>{let i=Be("rclone",$n({remoteSource:n,extraArgs:t})),a="",l="";i.stdout.on("data",c=>{a+=c.toString()}),i.stderr.on("data",c=>{l+=c.toString()}),i.on("close",async c=>{if(c===0)try{let u=JSON.parse(a||"[]");if(!Array.isArray(u))throw new Error("rclone lsjson did not return an array");let d=qn(u),m=await Jn({remote:r,files:d.files,directories:d.directories,extraArgs:t});s(m)}catch(u){o(new E(`Failed to parse file listing from ${n}: ${u instanceof Error?u.message:String(u)}`,l))}else o(new E(`Failed to list files from ${n}`,l))}),i.on("error",c=>{o(new E(`Failed to start rclone: ${c.message}`,""))})})}async function cr(r){let e=new It({localPath:r.localPath,files:r.files,onProgress:r.onProgress});e.start();let t=n=>{e.updateCurrentFile(n.currentFile)};try{let n=[],s=[];for(let o of r.files)es(o)?s.push(o):n.push(o);n.length>0&&(await Oe.promises.writeFile(r.batchFilePath,`${n.map(o=>o.path).join(`
4
4
  `)}
5
- `,"utf-8"),await jr(n.remote,n.remotePath,n.localPath,n.batchFilePath,n.rcloneOptions,t));for(let o of s)await Xr({remote:n.remote,remotePath:n.remotePath,localPath:n.localPath,file:o,rcloneOptions:n.rcloneOptions,onProgress:t})}finally{await e.stop()}}var Et=class{#e;#s;#t;#o=null;#r=null;#n=null;#i;#c=!1;constructor(e){this.#e=e.localPath,this.#s=e.files,this.#t=e.onProgress}start(){this.#t&&(this.#a(),this.#o=setInterval(()=>{this.#a()},Br))}async stop(){this.#o&&(clearInterval(this.#o),this.#o=null),await this.#a()}updateCurrentFile(e){this.#i=e??this.#i,this.#i&&this.#r!==null&&this.#n!==null&&this.#a()}async#a(){if(!(!this.#t||this.#c)){this.#c=!0;try{let e=Date.now(),t=await this.#u(),r=this.#s.reduce((c,u)=>c+u.size,0),s=this.#n===null?0:Math.max((e-this.#n)/1e3,.001),o=this.#r===null?0:Math.max(t-this.#r,0),i=s>0?o/s:0,a=Math.max(r-t,0),l={bytesTransferred:t,totalBytes:r,percentComplete:r>0?t/r*100:100,speed:i,eta:i>0?Math.ceil(a/i):0};this.#r=t,this.#n=e,this.#t({...l,aggregate:l,currentFile:this.#i})}finally{this.#c=!1}}}async#u(){let e=0;for(let t of this.#s){let r=q.join(this.#e,A(t)),s=await Oe.promises.stat(r).then(o=>o.isFile()?o.size:0).catch(o=>{if(o.code==="ENOENT")return 0;throw o});e+=Math.min(s,t.size)}return e}};function Hr(n){let e=[],t=[];for(let r of n){let s=r;if(typeof s.Path!="string")continue;let o=typeof s.ID=="string"&&s.ID.length>0?s.ID:void 0;if(s.IsDir===!0){t.push({path:b(s.Path),id:o});continue}let i=typeof s.Size=="number"&&Number.isFinite(s.Size)?s.Size:0;e.push({path:b(s.Path),size:i,id:o})}return{files:e,directories:t}}async function Wr(n){let e=Kr(n.directories);if(e.length===0)return n.files;let t=e.map(i=>i[0].path),r=n.files.filter(i=>!t.some(a=>dn(i.path,a))),s=qr(n.directories),o=[];for(let i of e)for(let a of i){if(!a.id)throw new Error(`Cannot preserve duplicate remote folder without a stable rclone folder ID: ${a.path}`);let l=pe(a.path),c=At(l,s);s.add(c),o.push(...await un({remote:n.remote,parentId:a.id,sourcePrefix:a.path,targetPrefix:c,extraArgs:n.extraArgs}))}return[...r,...o]}function Kr(n){let e=new Map;for(let o of n){let i=e.get(o.path)??[];i.push(o),e.set(o.path,i)}let t=Array.from(e.values()).filter(o=>o.length>1).sort((o,i)=>o[0].path.split("/").length-i[0].path.split("/").length),r=[],s=[];for(let o of t){let i=o[0].path;s.some(a=>dn(i,a))||(s.push(i),r.push(o))}return r}function qr(n){let e=new Map;for(let r of n)e.set(r.path,(e.get(r.path)??0)+1);let t=new Set;for(let r of n)(e.get(r.path)??0)>1||t.add(pe(r.path));return t}async function un(n){let e=await Jr({remote:n.remote,parentId:n.parentId,extraArgs:n.extraArgs}),t=new Set,r=[];for(let s of e){if(typeof s.name!="string"||typeof s.id!="string")continue;let o=`${n.sourcePrefix}/${s.name}`,i=`${n.targetPrefix}/${pe(s.name)}`,a=s.mimeType==="application/vnd.google-apps.folder"?At(i,t):bt(i,t);if(t.add(a),s.mimeType==="application/vnd.google-apps.folder"){r.push(...await un({remote:n.remote,parentId:s.id,sourcePrefix:o,targetPrefix:a,extraArgs:n.extraArgs}));continue}r.push({path:o,targetPath:a,size:Yr(s.size),id:s.id,requiresIdentityDownload:!0})}return r}function Jr(n){let e=`'${Vr(n.parentId)}' in parents and trashed = false`;return new Promise((t,r)=>{let s=Be("rclone",Nr({remote:n.remote,query:e,extraArgs:n.extraArgs}),{stdio:["ignore","pipe","pipe"]}),o="",i="";s.stdout.on("data",a=>{o+=a.toString()}),s.stderr.on("data",a=>{i+=a.toString()}),s.on("close",a=>{if(a!==0){r(new E(`Failed to query children for Google Drive folder ${n.parentId}`,i));return}try{let l=JSON.parse(o.trim()||"[]");if(l===null){t([]);return}if(!Array.isArray(l))throw new Error("rclone backend query did not return an array");t(l)}catch(l){r(new E(`Failed to parse children for Google Drive folder ${n.parentId}: ${l instanceof Error?l.message:String(l)}`,i))}}),s.on("error",a=>{r(new E(`Failed to start rclone: ${a.message}`,""))})})}function Yr(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 dn(n,e){return n===e||n.startsWith(`${e}/`)}function Vr(n){return n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function Qr(n){let e=A(n),t=b(n.path);return n.requiresIdentityDownload===!0||e!==t}async function Xr(n){let e=q.join(n.localPath,A(n.file));if(await Oe.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 wt({args:Gr({remote:n.remote,fileId:n.file.id,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress});return}await wt({args:zr({remoteFileSource:`${n.remote}:${Zr(n.remotePath,n.file.path)}`,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress})}function Zr(n,e){let t=n.replace(/\/+$/,""),r=e.replace(/^\/+/,"");return t.length===0?r:`${t}/${r}`}var Ne=class{#e;constructor(e){this.#e=e}get displayName(){return`${this.#e.remote}:${this.#e.remotePath}`}async prepare(){await Me()}async listFiles(){return ln(this.#e.remote,this.#e.remotePath,this.#e.rcloneOptions.extraRcloneArgs??[])}resolveLocalFile(e,t){return Le(e,t)}async materializeBatch(e){await cn({remote:this.#e.remote,remotePath:this.#e.remotePath,localPath:e.batchDir,batchFilePath:e.batchFilePath,files:e.files,rcloneOptions:this.#e.rcloneOptions,onProgress:e.onProgress})}async shutdown(){}};import Pt from"node:fs/promises";import It from"node:path";var J=class{#e;constructor(e){this.#e=e}get displayName(){return this.#e.rootPath}async prepare(){let e=await Pt.stat(this.#e.rootPath).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Local source path is not a readable directory: ${this.#e.rootPath}`)}async listFiles(){let e=[];return await this.#s(this.#e.rootPath,"",e),e.sort((t,r)=>t.path.localeCompare(r.path)),e}resolveLocalFile(e,t){let r=A(e);return{relativePath:r,absolutePath:It.join(this.#e.rootPath,...e.path.split("/")),fileName:It.posix.basename(r),size:e.size}}async materializeBatch(e){}async shutdown(){}async#s(e,t,r){let s=await Pt.readdir(e,{withFileTypes:!0});for(let o of s){let i=It.join(e,o.name),a=t===""?o.name:`${t}/${o.name}`;if(o.isDirectory()){await this.#s(i,a,r);continue}if(!o.isFile())continue;let l=await Pt.stat(i);r.push({path:a,size:l.size})}}};import ze from"node:fs/promises";import is from"node:path";import{spawn as es}from"node:child_process";var ts=18e4,ns=2e3,rs=3e4,ss=4e3,Y=class{#e;#s;#t=null;#o="";#r=null;#n=!1;constructor(e){this.#e=e,this.#s=e.spawnFn??es}get isRunning(){return this.#t!==null&&this.#r===null}get daemonOutputTail(){return this.#o}async checkClientInstalled(){await this.#a({args:["list"],failureMessage:"LucidLink client is not installed or not in PATH. Install it from https://www.lucidlink.com/download before running aspect-sync sync lucidlink."})}async start(){if(this.#t)throw new Error("LucidLink daemon already started");let e=["--instance",String(this.#e.instanceId),"daemon","--fs",this.#e.filespace,"--user",this.#e.user,"--mount-point",this.#e.mountPoint,"--root-path",this.#e.cacheRootPath],t=this.#s("lucid",e,{stdio:["pipe","pipe","pipe"]});this.#t=t,t.stdout?.on("data",r=>this.#d(r)),t.stderr?.on("data",r=>this.#d(r)),t.on("exit",r=>{this.#r=r??-1,this.#n||console.error(`LucidLink daemon exited unexpectedly (code ${this.#r}). Recent output:
6
- ${this.#o}`)}),t.on("error",r=>{this.#r=-1,this.#d(Buffer.from(`spawn error: ${r.message}
5
+ `,"utf-8"),await Kn(r.remote,r.remotePath,r.localPath,r.batchFilePath,r.rcloneOptions,t));for(let o of s)await ts({remote:r.remote,remotePath:r.remotePath,localPath:r.localPath,file:o,rcloneOptions:r.rcloneOptions,onProgress:t})}finally{await e.stop()}}var It=class{#e;#s;#t;#o=null;#n=null;#r=null;#i;#c=!1;constructor(e){this.#e=e.localPath,this.#s=e.files,this.#t=e.onProgress}start(){this.#t&&(this.#l(),this.#o=setInterval(()=>{this.#l()},Nn))}async stop(){this.#o&&(clearInterval(this.#o),this.#o=null),await this.#l()}updateCurrentFile(e){this.#i=e??this.#i,this.#i&&this.#n!==null&&this.#r!==null&&this.#l()}async#l(){if(!(!this.#t||this.#c)){this.#c=!0;try{let e=Date.now(),t=await this.#d(),n=this.#s.reduce((c,u)=>c+u.size,0),s=this.#r===null?0:Math.max((e-this.#r)/1e3,.001),o=this.#n===null?0:Math.max(t-this.#n,0),i=s>0?o/s:0,a=Math.max(n-t,0),l={bytesTransferred:t,totalBytes:n,percentComplete:n>0?t/n*100:100,speed:i,eta:i>0?Math.ceil(a/i):0};this.#n=t,this.#r=e,this.#t({...l,aggregate:l,currentFile:this.#i})}finally{this.#c=!1}}}async#d(){let e=0;for(let t of this.#s){let n=q.join(this.#e,A(t)),s=await Oe.promises.stat(n).then(o=>o.isFile()?o.size:0).catch(o=>{if(o.code==="ENOENT")return 0;throw o});e+=Math.min(s,t.size)}return e}};function qn(r){let e=[],t=[];for(let n of r){let s=n;if(typeof s.Path!="string")continue;let o=typeof s.ID=="string"&&s.ID.length>0?s.ID:void 0;if(s.IsDir===!0){t.push({path:b(s.Path),id:o});continue}let i=typeof s.Size=="number"&&Number.isFinite(s.Size)?s.Size:0;e.push({path:b(s.Path),size:i,id:o})}return{files:e,directories:t}}async function Jn(r){let e=Yn(r.directories);if(e.length===0)return r.files;let t=e.map(i=>i[0].path),n=r.files.filter(i=>!t.some(a=>dr(i.path,a))),s=Vn(r.directories),o=[];for(let i of e)for(let a of i){if(!a.id)throw new Error(`Cannot preserve duplicate remote folder without a stable rclone folder ID: ${a.path}`);let l=pe(a.path),c=Ft(l,s);s.add(c),o.push(...await ur({remote:r.remote,parentId:a.id,sourcePrefix:a.path,targetPrefix:c,extraArgs:r.extraArgs}))}return[...n,...o]}function Yn(r){let e=new Map;for(let o of r){let i=e.get(o.path)??[];i.push(o),e.set(o.path,i)}let t=Array.from(e.values()).filter(o=>o.length>1).sort((o,i)=>o[0].path.split("/").length-i[0].path.split("/").length),n=[],s=[];for(let o of t){let i=o[0].path;s.some(a=>dr(i,a))||(s.push(i),n.push(o))}return n}function Vn(r){let e=new Map;for(let n of r)e.set(n.path,(e.get(n.path)??0)+1);let t=new Set;for(let n of r)(e.get(n.path)??0)>1||t.add(pe(n.path));return t}async function ur(r){let e=await Qn({remote:r.remote,parentId:r.parentId,extraArgs:r.extraArgs}),t=new Set,n=[];for(let s of e){if(typeof s.name!="string"||typeof s.id!="string")continue;let o=`${r.sourcePrefix}/${s.name}`,i=`${r.targetPrefix}/${pe(s.name)}`,a=s.mimeType==="application/vnd.google-apps.folder"?Ft(i,t):At(i,t);if(t.add(a),s.mimeType==="application/vnd.google-apps.folder"){n.push(...await ur({remote:r.remote,parentId:s.id,sourcePrefix:o,targetPrefix:a,extraArgs:r.extraArgs}));continue}n.push({path:o,targetPath:a,size:Xn(s.size),id:s.id,requiresIdentityDownload:!0})}return n}function Qn(r){let e=`'${Zn(r.parentId)}' in parents and trashed = false`;return new Promise((t,n)=>{let s=Be("rclone",Gn({remote:r.remote,query:e,extraArgs:r.extraArgs}),{stdio:["ignore","pipe","pipe"]}),o="",i="";s.stdout.on("data",a=>{o+=a.toString()}),s.stderr.on("data",a=>{i+=a.toString()}),s.on("close",a=>{if(a!==0){n(new E(`Failed to query children for Google Drive folder ${r.parentId}`,i));return}try{let l=JSON.parse(o.trim()||"[]");if(l===null){t([]);return}if(!Array.isArray(l))throw new Error("rclone backend query did not return an array");t(l)}catch(l){n(new E(`Failed to parse children for Google Drive folder ${r.parentId}: ${l instanceof Error?l.message:String(l)}`,i))}}),s.on("error",a=>{n(new E(`Failed to start rclone: ${a.message}`,""))})})}function Xn(r){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"){let e=Number(r);return Number.isFinite(e)?e:0}return 0}function dr(r,e){return r===e||r.startsWith(`${e}/`)}function Zn(r){return r.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function es(r){let e=A(r),t=b(r.path);return r.requiresIdentityDownload===!0||e!==t}async function ts(r){let e=q.join(r.localPath,A(r.file));if(await Oe.promises.mkdir(q.dirname(e),{recursive:!0}),r.file.requiresIdentityDownload===!0){if(!r.file.id)throw new Error(`Cannot preserve duplicate remote file without a stable rclone file ID: ${r.file.path}`);await Et({args:Hn({remote:r.remote,fileId:r.file.id,localTargetPath:e,rcloneOptions:r.rcloneOptions}),remoteSource:`${r.remote}:${r.file.path}`,onProgress:r.onProgress});return}await Et({args:jn({remoteFileSource:`${r.remote}:${rs(r.remotePath,r.file.path)}`,localTargetPath:e,rcloneOptions:r.rcloneOptions}),remoteSource:`${r.remote}:${r.file.path}`,onProgress:r.onProgress})}function rs(r,e){let t=r.replace(/\/+$/,""),n=e.replace(/^\/+/,"");return t.length===0?n:`${t}/${n}`}var Ne=class{#e;constructor(e){this.#e=e}get displayName(){return`${this.#e.remote}:${this.#e.remotePath}`}async prepare(){await Me()}async listFiles(){return lr(this.#e.remote,this.#e.remotePath,this.#e.rcloneOptions.extraRcloneArgs??[])}resolveLocalFile(e,t){return Ue(e,t)}async materializeBatch(e){await cr({remote:this.#e.remote,remotePath:this.#e.remotePath,localPath:e.batchDir,batchFilePath:e.batchFilePath,files:e.files,rcloneOptions:this.#e.rcloneOptions,onProgress:e.onProgress})}async shutdown(){}};import Pt from"node:fs/promises";import Rt from"node:path";var J=class{#e;constructor(e){this.#e=e}get displayName(){return this.#e.rootPath}async prepare(){let e=await Pt.stat(this.#e.rootPath).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Local source path is not a readable directory: ${this.#e.rootPath}`)}async listFiles(){let e=[];return await this.#s(this.#e.rootPath,"",e),e.sort((t,n)=>t.path.localeCompare(n.path)),e}resolveLocalFile(e,t){let n=A(e);return{relativePath:n,absolutePath:Rt.join(this.#e.rootPath,...e.path.split("/")),fileName:Rt.posix.basename(n),size:e.size}}async materializeBatch(e){}async shutdown(){}async#s(e,t,n){let s=await Pt.readdir(e,{withFileTypes:!0});for(let o of s){let i=Rt.join(e,o.name),a=t===""?o.name:`${t}/${o.name}`;if(o.isDirectory()){await this.#s(i,a,n);continue}if(!o.isFile())continue;let l=await Pt.stat(i);n.push({path:a,size:l.size})}}};import ze from"node:fs/promises";import cs from"node:path";import{spawn as ns}from"node:child_process";var ss=18e4,os=2e3,is=3e4,as=4e3,Y=class{#e;#s;#t=null;#o="";#n=null;#r=!1;constructor(e){this.#e=e,this.#s=e.spawnFn??ns}get isRunning(){return this.#t!==null&&this.#n===null}get daemonOutputTail(){return this.#o}async checkClientInstalled(){await this.#l({args:["list"],failureMessage:"LucidLink client is not installed or not in PATH. Install it from https://www.lucidlink.com/download before running aspect-sync sync lucidlink."})}async start(){if(this.#t)throw new Error("LucidLink daemon already started");let e=["--instance",String(this.#e.instanceId),"daemon","--fs",this.#e.filespace,"--user",this.#e.user,"--mount-point",this.#e.mountPoint,"--root-path",this.#e.cacheRootPath],t=this.#s("lucid",e,{stdio:["pipe","pipe","pipe"]});this.#t=t,t.stdout?.on("data",n=>this.#u(n)),t.stderr?.on("data",n=>this.#u(n)),t.on("exit",n=>{this.#n=n??-1,this.#r||console.error(`LucidLink daemon exited unexpectedly (code ${this.#n}). Recent output:
6
+ ${this.#o}`)}),t.on("error",n=>{this.#n=-1,this.#u(Buffer.from(`spawn error: ${n.message}
7
7
  `))}),t.stdin?.write(`${this.#e.password}
8
- `),t.stdin?.end(),await this.#i(),this.#e.cacheSize&&await this.#a({args:["--instance",String(this.#e.instanceId),"config","--set","--local","--DataCache.Size",this.#e.cacheSize],failureMessage:`Failed to set LucidLink DataCache.Size to ${this.#e.cacheSize}`})}async stop(){let e=this.#t;if(!e||this.#r!==null){this.#t=null;return}this.#n=!0,await this.#a({args:["--instance",String(this.#e.instanceId),"exit"],failureMessage:"Failed to request LucidLink daemon exit"}).catch(t=>{console.error(t.message)}),await this.#u(e),this.#t=null}assertHealthy(){if(this.#t&&this.#r!==null&&!this.#n)throw new Error(`LucidLink daemon exited unexpectedly (code ${this.#r}). Recent output:
9
- ${this.#o}`)}async#i(){let e=this.#e.linkTimeoutMs??ts,t=this.#e.linkPollIntervalMs??ns,r=Date.now();for(;Date.now()-r<e;){if(this.#r!==null)throw new Error(`LucidLink daemon exited before linking (code ${this.#r}). Check the filespace name and credentials. Recent output:
10
- `+this.#o);let s=await this.#c();if(s!==null&&/\bLinked\b/i.test(s))return;await os(t)}throw new Error(`Timed out after ${Math.round(e/1e3)}s waiting for LucidLink filespace "${this.#e.filespace}" to link. Recent daemon output:
11
- ${this.#o}`)}async#c(){return new Promise(e=>{let t=this.#s("lucid",["--instance",String(this.#e.instanceId),"status"],{stdio:["ignore","pipe","pipe"]}),r="";t.stdout?.on("data",s=>{r+=s.toString()}),t.on("exit",s=>{e(s===0?r:null)}),t.on("error",()=>{e(null)})})}#a(e){return new Promise((t,r)=>{let s=this.#s("lucid",e.args,{stdio:["ignore","pipe","pipe"]}),o="";s.stderr?.on("data",i=>{o+=i.toString()}),s.on("exit",i=>{i===0?t():r(new Error(`${e.failureMessage} (exit code ${i}): ${o.trim()}`))}),s.on("error",i=>{r(new Error(`${e.failureMessage}: ${i.message}`))})})}async#u(e){this.#r===null&&await new Promise(t=>{let r=setTimeout(()=>{e.kill("SIGKILL")},rs);e.on("exit",()=>{clearTimeout(r),t()}),this.#r!==null&&(clearTimeout(r),t())})}#d(e){this.#o=(this.#o+e.toString()).slice(-ss)}};function os(n){return new Promise(e=>setTimeout(e,n))}var Ge=class{#e;#s;#t;constructor(e,t){this.#e=e,this.#s=t??new Y({filespace:e.filespace,user:e.user,password:e.password,instanceId:e.instanceId,mountPoint:e.mountPoint,cacheRootPath:e.cacheRootPath,cacheSize:e.cacheSize}),this.#t=new J({kind:"local",rootPath:this.#o()})}get displayName(){let e=this.#e.filespacePath===""?"":`/${this.#e.filespacePath}`;return`lucidlink:${this.#e.filespace}${e}`}async prepare(){await this.#s.checkClientInstalled(),await ze.mkdir(this.#e.mountPoint,{recursive:!0}),await ze.mkdir(this.#e.cacheRootPath,{recursive:!0}),console.log(`Mounting LucidLink filespace ${this.#e.filespace} at ${this.#e.mountPoint}...`),await this.#s.start(),console.log("Filespace linked and mounted");let e=await ze.stat(this.#o()).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Path "${this.#e.filespacePath}" does not exist in filespace ${this.#e.filespace}`)}async listFiles(){return this.#s.assertHealthy(),this.#t.listFiles()}resolveLocalFile(e,t){return this.#t.resolveLocalFile(e,t)}async materializeBatch(e){this.#s.assertHealthy(),await this.#t.materializeBatch(e)}async shutdown(){await this.#s.stop(),await ze.rm(this.#e.workDir,{recursive:!0,force:!0})}#o(){return this.#e.filespacePath===""?this.#e.mountPoint:is.join(this.#e.mountPoint,...this.#e.filespacePath.split("/"))}};import vs from"node:path";import $e from"node:fs";import pn from"node:path";var as="https://api.frame.io/v4",ls="https://api.frame.io",he=4,cs=1e3,us=15e3,ds=64*1024*1024,G=class{#e;constructor(e){this.#e=e.token}async listAccounts(){return(await this.#s("/accounts")).data}async listWorkspaces(e){return(await this.#s(`/accounts/${e}/workspaces`)).data}async listProjects(e){let t=[],r=`/accounts/${e.accountId}/workspaces/${e.workspaceId}/projects`,s={page_size:String(e.pageSize??100)};for(;r;){let o=await this.#s(r,s);t.push(...o.data),r=o.links?.next??null,s=void 0}return t}async listAccountProjects(e){let t=[],r=`/accounts/${e.accountId}/projects`,s={page_size:String(e.pageSize??100)};for(;r;){let o=await this.#s(r,s,{"api-version":"experimental"});t.push(...o.data),r=o.links?.next??null,s=void 0}return t}async getProject(e){let t=await this.#s(`/accounts/${e.accountId}/projects/${e.projectId}`);return"data"in t&&t.data?t.data:t}async listFolderChildren(e){let t=[],r=`/accounts/${e.accountId}/folders/${e.folderId}/children`,s={page_size:String(e.pageSize),type:"file,folder,version_stack",...e.includeOriginalMediaLinks?{include:"media_links.original"}:{}};for(;r;){let o=await this.#s(r,s);t.push(...o.data),r=o.links?.next??null,s=void 0}return t}async validateFolderAccess(e){await this.#s(`/accounts/${e.accountId}/folders/${e.folderId}/children`,{page_size:"1"})}async getFileWithOriginalMediaLink(e){let t=await this.#s(`/accounts/${e.accountId}/files/${e.fileId}`,{include:"media_links.original"}),r="data"in t&&t.data?t.data:t;return Tt(r)}async#s(e,t,r={}){let s=ps(e);for(let[o,i]of Object.entries(t??{}))s.searchParams.set(o,i);for(let o=0;o<he;o+=1)try{let i=await fetch(s,{headers:{Authorization:`Bearer ${this.#e}`,Accept:"application/json",...r}});if(!i.ok){let a=await i.text().catch(()=>"");if(hn(i)&&o<he-1){await Rt(je(i.headers.get("retry-after"),o));continue}throw new Error(`Frame.io API ${i.status} ${i.statusText} for ${s.pathname}: ${a}`)}return await i.json()}catch(i){if(fn(i)&&o<he-1){await Rt(je(null,o));continue}throw i}throw new Error(`Frame.io API request failed for ${s.pathname}`)}};function ps(n){return n.startsWith("http")?new URL(n):n.startsWith("/v4/")?new URL(`${ls}${n}`):new URL(`${as}${n}`)}function Tt(n){return{id:n.id,name:n.name??n.id,sizeBytes:ms(n),downloadUrl:n.media_links?.original?.download_url??void 0}}function ms(n){let e=[n.file_size,n.filesize,n.size,n.size_bytes,n.bytes];for(let t of e){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"){let r=Number(t);if(Number.isFinite(r))return r}}return 0}async function mn(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);for(let e=0;e<he;e+=1)try{return await hs(n)}catch(t){if(gs(t)&&e<he-1){await Rt(Ss(t,e));continue}throw t}throw new Error(`Download failed for ${n.file.name}`)}async function hs(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);let e=n.fileDownloadConcurrency??1;if(e>1&&n.outputPath&&n.file.sizeBytes>0){let l=await fs({file:n.file,outputPath:n.outputPath,maxSeconds:n.maxSeconds,onProgress:n.onProgress,fileDownloadConcurrency:e,rangeChunkSizeBytes:n.rangeChunkSizeBytes??ds});if(l)return l}let t=new AbortController,r=n.maxSeconds===void 0?null:setTimeout(()=>t.abort(),n.maxSeconds*1e3),s=null,o=Date.now(),i=0;try{n.outputPath&&(await $e.promises.mkdir(pn.dirname(n.outputPath),{recursive:!0}),s=$e.createWriteStream(n.outputPath));let l=await fetch(n.file.downloadUrl,{signal:t.signal,headers:{Accept:"application/octet-stream"}});if(!l.ok||!l.body){let u=await l.text().catch(()=>"");throw new $(`Download failed for ${n.file.name}: ${l.status} ${l.statusText} ${u}`,l.status,l.headers.get("retry-after"))}let c=l.body.getReader();for(;;){let{done:u,value:d}=await c.read();if(u)break;i+=d.byteLength,n.onProgress?.(i),s&&await ws(s,d)}}catch(l){if(l.name!=="AbortError")throw l}finally{r&&clearTimeout(r),s&&await Es(s)}let a=Math.max((Date.now()-o)/1e3,.001);return{id:n.file.id,name:n.file.name,bytesRead:i,seconds:a,outputPath:n.outputPath}}async function fs(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);if(!await bs(n.file))return null;let t=new AbortController,r=n.maxSeconds===void 0?null:setTimeout(()=>t.abort(),n.maxSeconds*1e3),s=Date.now(),o=null,i=0;try{await $e.promises.mkdir(pn.dirname(n.outputPath),{recursive:!0}),o=await $e.promises.open(n.outputPath,"w"),await o.truncate(n.file.sizeBytes);let l=As({fileSize:n.file.sizeBytes,chunkSize:n.rangeChunkSizeBytes}),c=0,u=async()=>{for(;c<l.length;){let h=l[c];c+=1,await Fs({file:n.file,range:h,outputFile:o,signal:t.signal,onProgress:p=>{i+=p,n.onProgress?.(i)}})}},m=(await Promise.allSettled(Array.from({length:Math.min(n.fileDownloadConcurrency,l.length)},async()=>{try{await u()}catch(h){throw t.abort(),h}}))).find(h=>h.status==="rejected");if(m)throw m.reason}finally{r&&clearTimeout(r),o&&await o.close()}let a=Math.max((Date.now()-s)/1e3,.001);return{id:n.file.id,name:n.file.name,bytesRead:i,seconds:a,outputPath:n.outputPath}}var $=class extends Error{status;retryAfter;constructor(e,t,r){super(e),this.status=t,this.retryAfter=r}};function hn(n){return n.status===408||n.status===425||n.status===429||n.status>=500}function gs(n){return n instanceof $?ys(n.status):fn(n)}function ys(n){return n===408||n===425||n===429||n>=500}function fn(n){if(!(n instanceof Error)||n.name==="AbortError")return!1;if(n instanceof TypeError)return!0;let e=n.code;return e==="ECONNRESET"||e==="ETIMEDOUT"||e==="UND_ERR_SOCKET"}function Ss(n,e){return n instanceof $?je(n.retryAfter,e):je(null,e)}function je(n,e){let t=Cs(n);return t!==null?t:Math.min(cs*2**e,us)}function Cs(n){if(!n)return null;let e=Number(n);if(Number.isFinite(e))return Math.max(e*1e3,0);let t=Date.parse(n);return Number.isFinite(t)?Math.max(t-Date.now(),0):null}function Rt(n){return new Promise(e=>setTimeout(e,n))}async function bs(n){if(!n.downloadUrl)throw new Error(`Frame.io file ${n.id} has no original download URL`);let e=await fetch(n.downloadUrl,{headers:{Accept:"application/octet-stream",Range:"bytes=0-0"}});if(await e.body?.cancel().catch(()=>{}),e.status===206)return!0;if(e.ok)return!1;if(hn(e))throw new $(`Range support probe failed for ${n.name}: ${e.status} ${e.statusText}`,e.status,e.headers.get("retry-after"));return!1}function As(n){let e=[];for(let t=0;t<n.fileSize;t+=n.chunkSize)e.push({start:t,end:Math.min(t+n.chunkSize-1,n.fileSize-1)});return e}async function Fs(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);let e=await fetch(n.file.downloadUrl,{signal:n.signal,headers:{Accept:"application/octet-stream",Range:`bytes=${n.range.start}-${n.range.end}`}});if(e.status!==206||!e.body){let o=await e.text().catch(()=>"");throw new $(`Range download failed for ${n.file.name}: ${e.status} ${e.statusText} ${o}`,e.status,e.headers.get("retry-after"))}let t=e.body.getReader(),r=0;for(;;){let{done:o,value:i}=await t.read();if(o)break;await n.outputFile.write(i,0,i.byteLength,n.range.start+r),r+=i.byteLength,n.onProgress(i.byteLength)}let s=n.range.end-n.range.start+1;if(r!==s)throw new Error(`Range download for ${n.file.name} returned ${r} bytes, expected ${s}`)}function ws(n,e){return new Promise((t,r)=>{if(n.write(e)){t();return}let s=()=>{n.off("drain",o),n.off("error",i)},o=()=>{s(),t()},i=a=>{s(),r(a)};n.once("drain",o),n.once("error",i)})}function Es(n){return new Promise((e,t)=>{let r=()=>{n.off("error",s)},s=o=>{r(),t(o)};n.once("error",s),n.end(()=>{r(),e()})})}import kt from"node:crypto";import He from"node:fs/promises";import Ps from"node:os";import gn from"node:path";var Is="https://ims-na1.adobelogin.com/ims/authorize/v2",yn="https://ims-na1.adobelogin.com/ims/token/v3",Rs="eac24c58b3bb4e8ab26105ad17adf779",Ts=300*1e3;function Sn(){return process.env.FRAMEIO_CLIENT_ID||Rs}function V(){return gn.join(Ps.homedir(),".config","aspect-sync","frameio-auth.json")}function Cn(){let n=kt.randomBytes(32).toString("base64url"),e=kt.createHash("sha256").update(n).digest("base64url");return{verifier:n,challenge:e}}function bn(n){let e=new URL(Is);return e.searchParams.set("client_id",n.clientId),e.searchParams.set("scope","openid email profile offline_access additional_info.roles"),e.searchParams.set("response_type","code"),e.searchParams.set("code_challenge",n.codeChallenge),e.searchParams.set("code_challenge_method","S256"),e.searchParams.set("state",n.state??kt.randomBytes(16).toString("hex")),e.toString()}function An(n){let e=n.trim();if(!e)throw new Error("Authorization code cannot be empty");if(!e.includes("code="))return e;let r=new URL(e).searchParams.get("code");if(!r)throw new Error("Redirect URL did not include a code parameter");return r}async function Fn(n){let e=await fetch(`${yn}?client_id=${encodeURIComponent(n.clientId)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:n.code,grant_type:"authorization_code",code_verifier:n.codeVerifier})});return wn(e,"authorization code exchange")}async function ks(n){let e=await fetch(`${yn}?client_id=${encodeURIComponent(n.clientId)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:n.refreshToken})});return wn(e,"refresh token exchange")}async function We(){let n=V(),e=await vt(n),t=Date.parse(e.expiresAt);if(Number.isFinite(t)&&t-Date.now()>Ts)return e.accessToken;if(!e.refreshToken)throw new Error(`Frame.io auth file ${n} has no refresh token; run aspect-sync frameio login`);let r=await ks({clientId:e.clientId,refreshToken:e.refreshToken}),s=Lt({clientId:e.clientId,token:r,previousRefreshToken:e.refreshToken,defaultAccountId:e.defaultAccountId});return await Ut(n,s),s.accessToken}async function vt(n){let e=await He.readFile(n,"utf-8").catch(t=>{throw t.code==="ENOENT"?new Error(`Frame.io auth file not found at ${n}; run aspect-sync frameio login`):t});return JSON.parse(e)}async function Ut(n,e){await He.mkdir(gn.dirname(n),{recursive:!0}),await He.writeFile(n,`${JSON.stringify(e,null,2)}
12
- `,{encoding:"utf-8",mode:384}),await He.chmod(n,384)}function Lt(n){let e={clientId:n.clientId,accessToken:n.token.access_token,refreshToken:n.token.refresh_token??n.previousRefreshToken,expiresAt:new Date(Date.now()+n.token.expires_in*1e3).toISOString(),tokenType:n.token.token_type};return n.defaultAccountId&&(e.defaultAccountId=n.defaultAccountId),e}async function wn(n,e){let t=await n.text();if(!n.ok)throw new Error(`Adobe IMS ${e} failed: ${n.status} ${n.statusText} ${t}`);let s=JSON.parse(t);if(!s.access_token||typeof s.expires_in!="number")throw new Error(`Adobe IMS ${e} returned an invalid token response: ${t}`);return s}var Ke=class{#e;#s=null;#t=null;#o=null;#r=new Map;constructor(e){this.#e=e}get displayName(){return`frameio:${this.#e.accountId}/${this.#e.folderId}`}async prepare(){await(await this.#u()).validateFolderAccess({accountId:this.#e.accountId,folderId:this.#e.folderId})}async listFiles(){let e=await this.#u(),t=[];await this.#n({client:e,folderId:this.#e.folderId,relativePrefix:"",files:t}),t.sort((r,s)=>r.path.localeCompare(s.path)),this.#r.clear();for(let r of t)this.#r.set(r.id,r);return t}resolveLocalFile(e,t){return Le(e,t)}async materializeBatch(e){let t={bytesTransferred:0,totalBytes:e.files.reduce((o,i)=>o+i.size,0),startedAt:Date.now()},r=0,s=async()=>{for(;r<e.files.length;){let o=r;r+=1,await this.#i({file:e.files[o],batchDir:e.batchDir,totals:t,onProgress:e.onProgress})}};await Promise.all(Array.from({length:Math.min(this.#e.downloadConcurrency,e.files.length)},()=>s()))}async shutdown(){}async#n(e){let t=await e.client.listFolderChildren({accountId:this.#e.accountId,folderId:e.folderId,pageSize:this.#e.pageSize});for(let r of t){if(r.type==="folder"){let o=r;await this.#n({client:e.client,folderId:o.id,relativePrefix:this.#a(e.relativePrefix,o.name),files:e.files});continue}if(r.type!=="file")continue;let s=Tt(r);e.files.push({id:s.id,path:this.#a(e.relativePrefix,s.name),size:s.sizeBytes})}}async#i(e){if(!e.file.id)throw new Error(`Frame.io listing missing file ID for ${e.file.path}`);let t=vs.join(e.batchDir,A(e.file)),r=this.#r.get(e.file.id),o=await(await this.#u()).getFileWithOriginalMediaLink({accountId:this.#e.accountId,fileId:e.file.id}),i={...o,name:r?.path??o.name,sizeBytes:e.file.size},a=0;await mn({file:i,outputPath:t,fileDownloadConcurrency:this.#e.fileDownloadConcurrency,onProgress:l=>{e.totals.bytesTransferred+=Math.max(l-a,0),a=l,e.onProgress?.(this.#c(e.totals))}})}#c(e){let t=Math.max((Date.now()-e.startedAt)/1e3,.001),r=e.bytesTransferred/t,s=Math.max(e.totalBytes-e.bytesTransferred,0);return{bytesTransferred:e.bytesTransferred,totalBytes:e.totalBytes,speed:r,eta:r>0?Math.ceil(s/r):0,percentComplete:e.totalBytes>0?e.bytesTransferred/e.totalBytes*100:100,aggregate:{bytesTransferred:e.bytesTransferred,totalBytes:e.totalBytes,speed:r,eta:r>0?Math.ceil(s/r):0,percentComplete:e.totalBytes>0?e.bytesTransferred/e.totalBytes*100:100}}}#a(e,t){let r=e===""?t:`${e}/${t}`;return b(r)}async#u(){if(this.#o)return await this.#o;this.#o=this.#d();try{return await this.#o}finally{this.#o=null}}async#d(){let e=await We();return(!this.#s||this.#t!==e)&&(this.#s=new G({token:e}),this.#t=e),this.#s}};function Q(n){switch(n.kind){case"rclone":return new Ne(n);case"local":return new J(n);case"lucidlink":return new Ge(n);case"frameio":return new Ke(n);default:{let e=n;throw new Error(`Unsupported sync source: ${JSON.stringify(e)}`)}}}import*as Je from"fs/promises";import*as Ye from"path";var Us={".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 Ls(n){let e=Ye.extname(n).toLowerCase();return Us[e]??""}var qe=class n{#e;#s=null;#t=null;#o=!1;#r;#n;#i;constructor(e,t,r,s){this.#e=e,this.#r=t,this.#n=r,this.#i=s}static async create(e){let t=await Je.stat(e),r=Ye.basename(e),s=Ls(r);return new n(e,t.size,r,s)}get name(){return this.#n}get size(){return this.#r}get type(){return this.#i}async readChunk(e,t){if(!this.#s){this.#t||(this.#t=Je.open(this.#e,"r"));let o=await this.#t;if(this.#t=null,this.#o)return Buffer.alloc(0);this.#s=o}let r=t-e,s=Buffer.alloc(r);return await this.#s.read(s,0,r,e),s}async close(){this.#o=!0;let e=this.#t;await this.#s?.close(),this.#s=null,e&&await(await e.catch(()=>null))?.close(),this.#t=null}};var xs=new Set(["success","failed","cancelled"]),En=1e3,Ds=250,_s=4*1024*1024,xt=class{#e;name;constructor(e,t){this.#e=e,this.name=t}get size(){return this.#e.size}get type(){return this.#e.type}readChunk(e,t){return this.#e.readChunk(e,t)}async close(){await this.#e.close?.()}},Ve=class{#e;#s;#t;#o;#r;constructor(e){this.#e=e.config,this.#s=e.httpClient??new x({apiUrl:e.config.apiUrl,apiKey:e.config.apiKey,edgeWorkerUrl:e.config.edgeWorkerUrl,sessionId:e.config.sessionName}),this.#t=e.createFileReader??(t=>qe.create(t)),this.#o=e.onSnapshot,this.#r=e.analytics}async uploadFiles(e){let t=e.filter(a=>a.preSkipped===!0),r=e.filter(a=>a.preSkipped!==!0);if(r.length===0)return{totalFileCount:e.length,successFileCount:0,skippedFileCount:t.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};let s=new ce({httpClient:this.#s,maxConcurrency:this.#e.maxConcurrent,deltaIntervalMs:En,adaptiveConcurrency:!1,analytics:this.#r}),o=[],i=0;try{let a=s.startGroupUpload({name:`${r.length} files`,type:"files",fileCount:r.length,folderCount:0,topLevelFileCount:r.length,topLevelFolderCount:0,rootDirectoryId:this.#e.directoryId,projectId:this.#e.projectId,totalBytes:r.reduce((c,u)=>c+u.file.size,0),conflictResolutionOverride:"skip"});for(let c of r){let u=await this.#t(c.file.absolutePath),d=u.name===c.file.fileName?u:new xt(u,c.file.fileName),m=s.startUpload({fileReader:d,directoryId:c.directoryId,projectId:this.#e.projectId,groupId:a,chunkSize:_s});s.addAssetToGroup(a,m),o.push({assetId:m,file:c.file,fileReader:d});let h=Date.now();(o.length===1||o.length===r.length||h-i>=Ds)&&(i=h,this.#o?.(s.getSnapshot()))}await this.#n(s);let l=s.getSnapshot();return this.#o?.(l),this.#i({snapshot:l,startedUploads:o,preSkippedCount:t.length})}finally{s.destroy()}}async#n(e){let r=Date.now();for(;Date.now()-r<864e5;){let s=e.getSnapshot();this.#o?.(s);let o=Object.values(s.uploadAssets);if(o.length>0&&o.every(i=>xs.has(i.status)))return;await new Promise(i=>setTimeout(i,En))}throw new Error("Timed out waiting for upload session to finish")}#i(e){let t=[],r=0,s=0,o=0,i=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){o+=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)?s+=1:r+=1;continue}l.status==="cancelled"?i+=1:o+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:r,skippedFileCount:e.preSkippedCount+s,failedFileCount:o,cancelledFileCount:i,failedFiles:t}}};var f=(n,e=2)=>{if(n===0)return"0 B";let t=1e3,r=e<0?0:e,s=["B","KB","MB","GB","TB","PB","EB"],o=Math.floor(Math.log(n)/Math.log(t));return`${(n/Math.pow(t,o)).toFixed(r)} ${s[o]}`},Qe=n=>{if(n===null)return null;let t=n*8/(1e3*1e3);return t<1?`${(t*1e3).toFixed(0)} Kbps`:`${t.toFixed(1)} Mbps`},fe=n=>{if(n===null)return null;let e=Math.floor(n/3600),t=Math.floor(n%3600/60),r=Math.floor(n%60);return e>0?`${e}h ${t}m`:t>0?`${t}m ${r}s`:`${r}s`};function Pn(n,e){return!e||e.count===1?n:n.filter(t=>Bs(A(t),e.count)===e.index)}function Bs(n,e){let t=2166136261;for(let r=0;r<n.length;r+=1)t^=n.charCodeAt(r),t=Math.imul(t,16777619);return(t>>>0)%e}import g from"chalk";import In from"log-update";var Os=1e3,Dt=class{#e=null;#s=!1;#t=null;#o=null;#r=null;#n=new Map;#i=null;#c=null;#a=null;#u=null;start(){this.#s||(this.#s=!0,this.#n.clear(),this.#i=null,this.#c=null,this.#a=null,this.#u=null,this.#e=setInterval(()=>this.render(),Os))}stop(){this.#s&&(this.#s=!1,this.#e&&(clearInterval(this.#e),this.#e=null),this.render(),In.done())}updateSnapshot(e){this.#t=e}updateBatchState(e){this.#o=e}updateDownloadProgress(e){if(!e){this.#r=null;return}let t=e.percentComplete>=100||e.bytesTransferred>=e.totalBytes;!t&&e.speed>0&&(this.#a=e),this.#r=t&&this.#a?{...e,speed:this.#a.speed,eta:this.#a.eta}:e}persistCurrentBatchLine(){!this.#o||this.#o.currentPhase!=="complete"||this.#n.set(this.#o.currentBatch,this.#g(this.#o))}resetUploadSnapshot(){this.#t=null,this.#r=null,this.#a=null,this.#u=null}render(){if(!this.#s)return;let e=this.#o?this.#R(this.#o):this.#l();In(e.join(`
13
- `))}#d(e,t){let r=[`${g.green(f(t.bytesTransferred))} / ${g.gray(f(t.totalBytes))}`,g.cyan(`${t.percentComplete.toFixed(1)}%`),g.magenta(Qe(t.speed)??"..."),`${g.yellow("ETA")}: ${g.yellow(fe(t.eta)??"...")}`];return`${g.blue(e)}: ${r.join(" | ")}`}#l(){let e=this.#y();return[this.#T(e),this.#m(e)]}#R(e){let t=[];for(let r=1;r<e.currentBatch;r++){let s=this.#n.get(r);s&&t.push(s)}return t.push(this.#g(e)),t.push(this.#C(e)),t}#g(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#r?this.#P(t,this.#r):`${t}: ${g.blue("Downloading...")}`;case"scanning":return`${t}: ${g.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${g.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#I(t,e);case"cleaning":return`${t}: ${g.yellow("Cleaning...")}`;case"complete":return`${t}: ${g.green("Complete")} (${e.batchFilesTotal} files, ${f(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#P(e,t){let r=t.aggregate?[`${e}: ${this.#d("Downloading batch",t.aggregate)}`]:[`${e}: ${g.blue("Downloading...")}`];return t.currentFile&&r.push(this.#d("Downloading current file",t.currentFile)),r.join(`
14
- `)}#I(e,t){let r=this.#y(),s=r.successFileCount+r.failedFileCount+r.cancelledFileCount,o=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),i=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=i>0?(r.uploadedBytes/i*100).toFixed(1):"0.0",l=this.#w(t,r,i),c=l?.formattedSpeed??null,u=l?.formattedTime??null,d=r.totalFileCount>0&&r.totalFileCount<o?`, ${g.gray(`Enqueued: ${r.totalFileCount}/${o}`)}`:"",m=c&&u?`, ${c}, ETA: ${u}`:"",h=t.batchFilesSkipped>0?`, ${g.yellow(`Skipped: ${t.batchFilesSkipped} files / ${f(t.batchBytesSkipped)}`)}`:"",p=i>0&&r.uploadedBytes>=i&&s<o?"Finalizing":"Uploading";return`${e}: ${g.blue(p)} (${s}/${o} files, ${f(r.uploadedBytes)} / ${f(i)}, ${a}%${d}${m}${h})`}#C(e){let t=this.#y(),r=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,s=e.batchBytesSkipped+t.uploadedBytes,o=e.overallFilesCompleted+r,i=e.overallBytesCompleted+s,a=Math.max(e.overallBytesTotal-i,0),l=this.#h(e),c=this.#b(e,t),u=l!==null&&c!==null?l+c:null;return[`Completed: ${o}/${e.overallFilesTotal} files`,`${f(i)} / ${f(e.overallBytesTotal)}`,g.yellow(`${f(a)} remaining`),`Download ETA: ${fe(l)??"..."}`,`Upload ETA: ${fe(c)??"..."}`,`Total ETA: ${fe(u)??"..."}`].join(", ")}#h(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#r?.bytesTransferred??0),r=Math.max(e.overallBytesTotal-t,0);if(r===0)return e.currentPhase==="downloading"&&this.#r?(this.#i=this.#r.eta,this.#r.eta):(this.#i=0,0);if(this.#r&&this.#r.speed>0){let s=Math.ceil(r/this.#r.speed);return this.#i=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#i=0,0):this.#i}#b(e,t){let r=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,s=Math.max(e.overallBytesTotal-r,0),o=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),i=this.#w(e,t,o);if(s===0)return e.currentPhase==="uploading"&&i?(this.#c=i.timeRemainingSeconds,i.timeRemainingSeconds):(this.#c=0,0);if(i&&i.uploadSpeedMbps>0){let a=i.uploadSpeedMbps*1024*1024/8,l=Math.ceil(s/a);return this.#c=l,l}return this.#c}#w(e,t,r){let s=this.#t?.uploadStats,o=r>0&&t.uploadedBytes>=r;return s&&s.uploadSpeedMbps>0&&s.formattedSpeed!=="Calculating..."&&!o?(this.#u={uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds},this.#u):e.currentPhase==="uploading"&&o&&this.#u?this.#u:s?{uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds}:null}#T(e){return[`Total: ${e.totalFileCount}`,g.green(`Success: ${e.successFileCount}`),g.red(`Failed: ${e.failedFileCount}`),g.red(`Cancelled: ${e.cancelledFileCount}`),g.blue(`Active: ${e.activeFileCount}`),g.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#m(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),r=this.#t?` | ${g.cyan(`Speed: ${this.#t.uploadStats.formattedSpeed}`)} | ${g.magenta(`Time remaining: ${this.#t.uploadStats.formattedTime}`)}`:"";return[`Total: ${f(e.totalBytes)}`,g.green(`Uploaded: ${f(e.uploadedBytes)}`),g.yellow(`Remaining: ${f(t)}`)].join(" | ")+r}#y(){return this.#t?Object.values(this.#t.uploadAssets).reduce((t,r)=>{switch(t.totalFileCount+=1,t.totalBytes+=r.totalBytesToUpload,t.uploadedBytes+=r.status==="success"?r.totalBytesToUpload:r.bytesUploaded,r.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}}},I=new Dt;var Xe=class{#e;#s;#t;#o="sync";#r=null;#n=null;#i=null;#c=null;#a=null;#u;#d=[];#l=null;#R=null;constructor(e){this.#e=e.config,this.#s=e.sourceDisplayName,this.#t=e.writeJsonLine??(t=>{process.stdout.write(`${t}
15
- `)})}get isJsonMode(){return this.#e.progressMode==="json"}start({kind:e,title:t,extraLines:r=[],humanMode:s="banner"}){if(this.#o=e,!this.isJsonMode){if(s==="message"){console.log(t);return}console.log(t),console.log(`Session: ${this.#e.sessionName}`),console.log(`Source: ${this.#s}`),console.log(`Root directory ID: ${this.#e.directoryId}`),console.log(`Project ID: ${this.#e.projectId}`),console.log(`Temp directory: ${this.#e.localTempDir}`),console.log(`Edge worker URL: ${this.#e.edgeWorkerUrl}`),console.log(`Shard: ${this.#L()}`);for(let o of r)console.log(o);console.log("");return}this.#h({jobId:this.#e.sessionName,type:"start",emittedAt:new Date().toISOString(),sessionName:this.#e.sessionName,sourceDisplayName:this.#s,aspectProjectId:this.#e.projectId,aspectDirectoryId:this.#e.directoryId,tempDir:this.#e.localTempDir,edgeWorkerUrl:this.#e.edgeWorkerUrl,message:[t,...r].join(" ").trim()||void 0,snapshot:this.#b({status:"running"})})}log(e){if(!this.isJsonMode){console.log(e);return}this.#P(e)}warn(e){if(!this.isJsonMode){console.warn(e);return}this.#P(e)}blank(){this.isJsonMode||console.log("")}startLiveDisplay(){this.isJsonMode||I.start()}stopLiveDisplay(){this.isJsonMode||I.stop()}updateBatchState(e){if(this.#r=e,!this.isJsonMode){I.updateBatchState(e);return}this.#I(e.extraDetails)}updateDownloadProgress(e){if(this.#i=e,!this.isJsonMode){I.updateDownloadProgress(e);return}e&&this.#I()}updateUploadSnapshot(e){if(this.#n=e,!this.isJsonMode){I.updateSnapshot(e);return}this.#I()}resetUploadSnapshot(){this.#n=null,this.#i=null,this.isJsonMode||(I.resetUploadSnapshot(),I.updateDownloadProgress(null))}persistCurrentBatchLine(){if(!this.#r||this.#r.currentPhase!=="complete")return;let e={batchNumber:this.#r.currentBatch,filesCompleted:this.#r.batchFilesTotal,bytesCompleted:this.#r.batchBytesTotal},t=this.#d.findIndex(r=>r.batchNumber===e.batchNumber);if(t===-1?this.#d.push(e):this.#d[t]=e,!this.isJsonMode){I.persistCurrentBatchLine();return}this.#h({jobId:this.#e.sessionName,type:"batch_complete",emittedAt:new Date().toISOString(),batch:e,snapshot:this.#b({status:"running"})})}recordSourceListing({files:e,humanDescription:t="files",includeHumanTotal:r=!0}){this.#c=e.length,this.#a=Ms(e),this.isJsonMode||(console.log(`Found ${this.#c} ${t}`),r&&console.log(`Total size: ${f(this.#a)}`),console.log("")),this.#g()}recordPathRenameWarnings(e){if(this.#u=e,!this.isJsonMode){let t=e.sample.map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
16
- `),r=e.count-e.sample.length,s=r>0?`
17
- ...and ${r} more renamed target path(s)`:"";console.warn(`Warning: ${e.count} remote file path(s) were renamed for Aspect compatibility.
8
+ `),t.stdin?.end(),await this.#i(),this.#e.cacheSize&&await this.#l({args:["--instance",String(this.#e.instanceId),"config","--set","--local","--DataCache.Size",this.#e.cacheSize],failureMessage:`Failed to set LucidLink DataCache.Size to ${this.#e.cacheSize}`})}async stop(){let e=this.#t;if(!e||this.#n!==null){this.#t=null;return}this.#r=!0,await this.#l({args:["--instance",String(this.#e.instanceId),"exit"],failureMessage:"Failed to request LucidLink daemon exit"}).catch(t=>{console.error(t.message)}),await this.#d(e),this.#t=null}assertHealthy(){if(this.#t&&this.#n!==null&&!this.#r)throw new Error(`LucidLink daemon exited unexpectedly (code ${this.#n}). Recent output:
9
+ ${this.#o}`)}async#i(){let e=this.#e.linkTimeoutMs??ss,t=this.#e.linkPollIntervalMs??os,n=Date.now();for(;Date.now()-n<e;){if(this.#n!==null)throw new Error(`LucidLink daemon exited before linking (code ${this.#n}). Check the filespace name and credentials. Recent output:
10
+ `+this.#o);let s=await this.#c();if(s!==null&&/\bLinked\b/i.test(s))return;await ls(t)}throw new Error(`Timed out after ${Math.round(e/1e3)}s waiting for LucidLink filespace "${this.#e.filespace}" to link. Recent daemon output:
11
+ ${this.#o}`)}async#c(){return new Promise(e=>{let t=this.#s("lucid",["--instance",String(this.#e.instanceId),"status"],{stdio:["ignore","pipe","pipe"]}),n="";t.stdout?.on("data",s=>{n+=s.toString()}),t.on("exit",s=>{e(s===0?n:null)}),t.on("error",()=>{e(null)})})}#l(e){return new Promise((t,n)=>{let s=this.#s("lucid",e.args,{stdio:["ignore","pipe","pipe"]}),o="";s.stderr?.on("data",i=>{o+=i.toString()}),s.on("exit",i=>{i===0?t():n(new Error(`${e.failureMessage} (exit code ${i}): ${o.trim()}`))}),s.on("error",i=>{n(new Error(`${e.failureMessage}: ${i.message}`))})})}async#d(e){this.#n===null&&await new Promise(t=>{let n=setTimeout(()=>{e.kill("SIGKILL")},is);e.on("exit",()=>{clearTimeout(n),t()}),this.#n!==null&&(clearTimeout(n),t())})}#u(e){this.#o=(this.#o+e.toString()).slice(-as)}};function ls(r){return new Promise(e=>setTimeout(e,r))}var $e=class{#e;#s;#t;constructor(e,t){this.#e=e,this.#s=t??new Y({filespace:e.filespace,user:e.user,password:e.password,instanceId:e.instanceId,mountPoint:e.mountPoint,cacheRootPath:e.cacheRootPath,cacheSize:e.cacheSize}),this.#t=new J({kind:"local",rootPath:this.#o()})}get displayName(){let e=this.#e.filespacePath===""?"":`/${this.#e.filespacePath}`;return`lucidlink:${this.#e.filespace}${e}`}async prepare(){await this.#s.checkClientInstalled(),await ze.mkdir(this.#e.mountPoint,{recursive:!0}),await ze.mkdir(this.#e.cacheRootPath,{recursive:!0}),console.log(`Mounting LucidLink filespace ${this.#e.filespace} at ${this.#e.mountPoint}...`),await this.#s.start(),console.log("Filespace linked and mounted");let e=await ze.stat(this.#o()).catch(()=>null);if(!e||!e.isDirectory())throw new Error(`Path "${this.#e.filespacePath}" does not exist in filespace ${this.#e.filespace}`)}async listFiles(){return this.#s.assertHealthy(),this.#t.listFiles()}resolveLocalFile(e,t){return this.#t.resolveLocalFile(e,t)}async materializeBatch(e){this.#s.assertHealthy(),await this.#t.materializeBatch(e)}async shutdown(){await this.#s.stop(),await ze.rm(this.#e.workDir,{recursive:!0,force:!0})}#o(){return this.#e.filespacePath===""?this.#e.mountPoint:cs.join(this.#e.mountPoint,...this.#e.filespacePath.split("/"))}};import xt from"node:path";import Ge from"node:fs";import pr from"node:path";var us="https://api.frame.io/v4",ds="https://api.frame.io",he=4,ps=1e3,ms=15e3,hs=64*1024*1024,$=class{#e;constructor(e){this.#e=e.token}async listAccounts(){return(await this.#s("/accounts")).data}async listWorkspaces(e){return(await this.#s(`/accounts/${e}/workspaces`)).data}async listProjects(e){let t=[],n=`/accounts/${e.accountId}/workspaces/${e.workspaceId}/projects`,s={page_size:String(e.pageSize??100)};for(;n;){let o=await this.#s(n,s);t.push(...o.data),n=o.links?.next??null,s=void 0}return t}async listAccountProjects(e){let t=[],n=`/accounts/${e.accountId}/projects`,s={page_size:String(e.pageSize??100)};for(;n;){let o=await this.#s(n,s,{"api-version":"experimental"});t.push(...o.data),n=o.links?.next??null,s=void 0}return t}async getProject(e){let t=await this.#s(`/accounts/${e.accountId}/projects/${e.projectId}`);return"data"in t&&t.data?t.data:t}async listFolderChildren(e){let t=[],n=`/accounts/${e.accountId}/folders/${e.folderId}/children`,s={page_size:String(e.pageSize),type:"file,folder,version_stack",...e.includeOriginalMediaLinks?{include:"media_links.original"}:{}};for(;n;){let o=await this.#s(n,s);t.push(...o.data),n=o.links?.next??null,s=void 0}return t}async getFolderPath(e){let t=[],n=new Set,s=e.folderId;for(;s&&!n.has(s);){n.add(s);let o;try{o=await this.getFolder({accountId:e.accountId,folderId:s})}catch(i){if(t.length>0)break;throw i}t.push(o),s=o.parent_id}return t.reverse().map(o=>o.name).filter(o=>o.length>0).join("/")}async getFolder(e){let t=await this.#s(`/accounts/${e.accountId}/folders/${e.folderId}`);return"data"in t&&t.data?t.data:t}async getVersionStackHeadVersion(e){let t=await this.#s(`/accounts/${e.accountId}/version_stacks/${e.versionStackId}`,{include:"media_links.original"}),n="data"in t&&t.data?t.data:t;return n.head_version?je(n.head_version):null}async validateFolderAccess(e){await this.#s(`/accounts/${e.accountId}/folders/${e.folderId}/children`,{page_size:"1"})}async getFileWithOriginalMediaLink(e){let t=await this.#s(`/accounts/${e.accountId}/files/${e.fileId}`,{include:"media_links.original"}),n="data"in t&&t.data?t.data:t;return je(n)}async#s(e,t,n={}){let s=fs(e);for(let[o,i]of Object.entries(t??{}))s.searchParams.set(o,i);for(let o=0;o<he;o+=1)try{let i=await fetch(s,{headers:{Authorization:`Bearer ${this.#e}`,Accept:"application/json",...n}});if(!i.ok){let a=await i.text().catch(()=>"");if(hr(i)&&o<he-1){await Tt(He(i.headers.get("retry-after"),o));continue}throw new Error(`Frame.io API ${i.status} ${i.statusText} for ${s.pathname}: ${a}`)}return await i.json()}catch(i){if(fr(i)&&o<he-1){await Tt(He(null,o));continue}throw i}throw new Error(`Frame.io API request failed for ${s.pathname}`)}};function fs(r){return r.startsWith("http")?new URL(r):r.startsWith("/v4/")?new URL(`${ds}${r}`):new URL(`${us}${r}`)}function je(r){return{id:r.id,name:r.name??r.id,sizeBytes:gs(r),downloadUrl:r.media_links?.original?.download_url??void 0}}function gs(r){let e=[r.file_size,r.filesize,r.size,r.size_bytes,r.bytes];for(let t of e){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"){let n=Number(t);if(Number.isFinite(n))return n}}return 0}async function mr(r){if(!r.file.downloadUrl)throw new Error(`Frame.io file ${r.file.id} has no original download URL`);for(let e=0;e<he;e+=1)try{return await ys(r)}catch(t){if(Cs(t)&&e<he-1){await Tt(As(t,e));continue}throw t}throw new Error(`Download failed for ${r.file.name}`)}async function ys(r){if(!r.file.downloadUrl)throw new Error(`Frame.io file ${r.file.id} has no original download URL`);let e=r.fileDownloadConcurrency??1;if(e>1&&r.outputPath&&r.file.sizeBytes>0){let l=await Ss({file:r.file,outputPath:r.outputPath,maxSeconds:r.maxSeconds,onProgress:r.onProgress,fileDownloadConcurrency:e,rangeChunkSizeBytes:r.rangeChunkSizeBytes??hs});if(l)return l}let t=new AbortController,n=r.maxSeconds===void 0?null:setTimeout(()=>t.abort(),r.maxSeconds*1e3),s=null,o=Date.now(),i=0;try{r.outputPath&&(await Ge.promises.mkdir(pr.dirname(r.outputPath),{recursive:!0}),s=Ge.createWriteStream(r.outputPath));let l=await fetch(r.file.downloadUrl,{signal:t.signal,headers:{Accept:"application/octet-stream"}});if(!l.ok||!l.body){let u=await l.text().catch(()=>"");throw new G(`Download failed for ${r.file.name}: ${l.status} ${l.statusText} ${u}`,l.status,l.headers.get("retry-after"))}let c=l.body.getReader();for(;;){let{done:u,value:d}=await c.read();if(u)break;i+=d.byteLength,r.onProgress?.(i),s&&await Ps(s,d)}}catch(l){if(l.name!=="AbortError")throw l}finally{n&&clearTimeout(n),s&&await Rs(s)}let a=Math.max((Date.now()-o)/1e3,.001);return{id:r.file.id,name:r.file.name,bytesRead:i,seconds:a,outputPath:r.outputPath}}async function Ss(r){if(!r.file.downloadUrl)throw new Error(`Frame.io file ${r.file.id} has no original download URL`);if(!await ws(r.file))return null;let t=new AbortController,n=r.maxSeconds===void 0?null:setTimeout(()=>t.abort(),r.maxSeconds*1e3),s=Date.now(),o=null,i=0;try{await Ge.promises.mkdir(pr.dirname(r.outputPath),{recursive:!0}),o=await Ge.promises.open(r.outputPath,"w"),await o.truncate(r.file.sizeBytes);let l=Es({fileSize:r.file.sizeBytes,chunkSize:r.rangeChunkSizeBytes}),c=0,u=async()=>{for(;c<l.length;){let h=l[c];c+=1,await Is({file:r.file,range:h,outputFile:o,signal:t.signal,onProgress:p=>{i+=p,r.onProgress?.(i)}})}},m=(await Promise.allSettled(Array.from({length:Math.min(r.fileDownloadConcurrency,l.length)},async()=>{try{await u()}catch(h){throw t.abort(),h}}))).find(h=>h.status==="rejected");if(m)throw m.reason}finally{n&&clearTimeout(n),o&&await o.close()}let a=Math.max((Date.now()-s)/1e3,.001);return{id:r.file.id,name:r.file.name,bytesRead:i,seconds:a,outputPath:r.outputPath}}var G=class extends Error{status;retryAfter;constructor(e,t,n){super(e),this.status=t,this.retryAfter=n}};function hr(r){return r.status===408||r.status===425||r.status===429||r.status>=500}function Cs(r){return r instanceof G?bs(r.status):fr(r)}function bs(r){return r===408||r===425||r===429||r>=500}function fr(r){if(!(r instanceof Error)||r.name==="AbortError")return!1;if(r instanceof TypeError)return!0;let e=r.code;return e==="ECONNRESET"||e==="ETIMEDOUT"||e==="UND_ERR_SOCKET"}function As(r,e){return r instanceof G?He(r.retryAfter,e):He(null,e)}function He(r,e){let t=Fs(r);return t!==null?t:Math.min(ps*2**e,ms)}function Fs(r){if(!r)return null;let e=Number(r);if(Number.isFinite(e))return Math.max(e*1e3,0);let t=Date.parse(r);return Number.isFinite(t)?Math.max(t-Date.now(),0):null}function Tt(r){return new Promise(e=>setTimeout(e,r))}async function ws(r){if(!r.downloadUrl)throw new Error(`Frame.io file ${r.id} has no original download URL`);let e=await fetch(r.downloadUrl,{headers:{Accept:"application/octet-stream",Range:"bytes=0-0"}});if(await e.body?.cancel().catch(()=>{}),e.status===206)return!0;if(e.ok)return!1;if(hr(e))throw new G(`Range support probe failed for ${r.name}: ${e.status} ${e.statusText}`,e.status,e.headers.get("retry-after"));return!1}function Es(r){let e=[];for(let t=0;t<r.fileSize;t+=r.chunkSize)e.push({start:t,end:Math.min(t+r.chunkSize-1,r.fileSize-1)});return e}async function Is(r){if(!r.file.downloadUrl)throw new Error(`Frame.io file ${r.file.id} has no original download URL`);let e=await fetch(r.file.downloadUrl,{signal:r.signal,headers:{Accept:"application/octet-stream",Range:`bytes=${r.range.start}-${r.range.end}`}});if(e.status!==206||!e.body){let o=await e.text().catch(()=>"");throw new G(`Range download failed for ${r.file.name}: ${e.status} ${e.statusText} ${o}`,e.status,e.headers.get("retry-after"))}let t=e.body.getReader(),n=0;for(;;){let{done:o,value:i}=await t.read();if(o)break;await r.outputFile.write(i,0,i.byteLength,r.range.start+n),n+=i.byteLength,r.onProgress(i.byteLength)}let s=r.range.end-r.range.start+1;if(n!==s)throw new Error(`Range download for ${r.file.name} returned ${n} bytes, expected ${s}`)}function Ps(r,e){return new Promise((t,n)=>{if(r.write(e)){t();return}let s=()=>{r.off("drain",o),r.off("error",i)},o=()=>{s(),t()},i=a=>{s(),n(a)};r.once("drain",o),r.once("error",i)})}function Rs(r){return new Promise((e,t)=>{let n=()=>{r.off("error",s)},s=o=>{n(),t(o)};r.once("error",s),r.end(()=>{n(),e()})})}import kt from"node:crypto";import We from"node:fs/promises";import Ts from"node:os";import gr from"node:path";var ks="https://ims-na1.adobelogin.com/ims/authorize/v2",yr="https://ims-na1.adobelogin.com/ims/token/v3",vs="eac24c58b3bb4e8ab26105ad17adf779",Ls=300*1e3;function Sr(){return process.env.FRAMEIO_CLIENT_ID||vs}function V(){return gr.join(Ts.homedir(),".config","aspect-sync","frameio-auth.json")}function Cr(){let r=kt.randomBytes(32).toString("base64url"),e=kt.createHash("sha256").update(r).digest("base64url");return{verifier:r,challenge:e}}function br(r){let e=new URL(ks);return e.searchParams.set("client_id",r.clientId),e.searchParams.set("scope","openid email profile offline_access additional_info.roles"),e.searchParams.set("response_type","code"),e.searchParams.set("code_challenge",r.codeChallenge),e.searchParams.set("code_challenge_method","S256"),e.searchParams.set("state",r.state??kt.randomBytes(16).toString("hex")),e.toString()}function Ar(r){let e=r.trim();if(!e)throw new Error("Authorization code cannot be empty");if(!e.includes("code="))return e;let n=new URL(e).searchParams.get("code");if(!n)throw new Error("Redirect URL did not include a code parameter");return n}async function Fr(r){let e=await fetch(`${yr}?client_id=${encodeURIComponent(r.clientId)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:r.code,grant_type:"authorization_code",code_verifier:r.codeVerifier})});return wr(e,"authorization code exchange")}async function Us(r){let e=await fetch(`${yr}?client_id=${encodeURIComponent(r.clientId)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:r.refreshToken})});return wr(e,"refresh token exchange")}async function Ke(){let r=V(),e=await vt(r),t=Date.parse(e.expiresAt);if(Number.isFinite(t)&&t-Date.now()>Ls)return e.accessToken;if(!e.refreshToken)throw new Error(`Frame.io auth file ${r} has no refresh token; run aspect-sync frameio login`);let n=await Us({clientId:e.clientId,refreshToken:e.refreshToken}),s=Ut({clientId:e.clientId,token:n,previousRefreshToken:e.refreshToken,defaultAccountId:e.defaultAccountId});return await Lt(r,s),s.accessToken}async function vt(r){let e=await We.readFile(r,"utf-8").catch(t=>{throw t.code==="ENOENT"?new Error(`Frame.io auth file not found at ${r}; run aspect-sync frameio login`):t});return JSON.parse(e)}async function Lt(r,e){await We.mkdir(gr.dirname(r),{recursive:!0}),await We.writeFile(r,`${JSON.stringify(e,null,2)}
12
+ `,{encoding:"utf-8",mode:384}),await We.chmod(r,384)}function Ut(r){let e={clientId:r.clientId,accessToken:r.token.access_token,refreshToken:r.token.refresh_token??r.previousRefreshToken,expiresAt:new Date(Date.now()+r.token.expires_in*1e3).toISOString(),tokenType:r.token.token_type};return r.defaultAccountId&&(e.defaultAccountId=r.defaultAccountId),e}async function wr(r,e){let t=await r.text();if(!r.ok)throw new Error(`Adobe IMS ${e} failed: ${r.status} ${r.statusText} ${t}`);let s=JSON.parse(t);if(!s.access_token||typeof s.expires_in!="number")throw new Error(`Adobe IMS ${e} returned an invalid token response: ${t}`);return s}var xs=4,qe=class{#e;#s=null;#t=null;#o=null;#n=new Map;constructor(e){this.#e=e}get displayName(){return`frameio:${this.#e.accountId}/${this.#e.folderId}`}async getConfirmationSourcePath(){return await(await this.#a()).getFolderPath({accountId:this.#e.accountId,folderId:this.#e.folderId})||this.#e.folderId}async prepare(){await(await this.#a()).validateFolderAccess({accountId:this.#e.accountId,folderId:this.#e.folderId})}async listFiles(){let e=await this.#a(),t=[];await this.#r({client:e,folderId:this.#e.folderId,relativePrefix:"",files:t}),t.sort((n,s)=>n.path.localeCompare(s.path)),this.#n.clear();for(let n of t)this.#n.set(n.id,n);return t}resolveLocalFile(e,t){return Ue(e,t)}async materializeBatch(e){let t={bytesTransferred:0,totalBytes:e.files.reduce((o,i)=>o+i.size,0),startedAt:Date.now()},n=0,s=async()=>{for(;n<e.files.length;){let o=n;n+=1,await this.#l({file:e.files[o],batchDir:e.batchDir,totals:t,onProgress:e.onProgress})}};await Promise.all(Array.from({length:Math.min(this.#e.downloadConcurrency,e.files.length)},()=>s()))}async shutdown(){}async#r(e){let t=await e.client.listFolderChildren({accountId:this.#e.accountId,folderId:e.folderId,pageSize:this.#e.pageSize}),n=[];for(let s of t){if(s.type==="folder"){let i=s;await this.#r({client:e.client,folderId:i.id,relativePrefix:this.#u(e.relativePrefix,i.name),files:e.files});continue}if(s.type==="version_stack"){n.push(s);continue}if(s.type!=="file")continue;let o=je(s);e.files.push({id:o.id,path:this.#u(e.relativePrefix,o.name),size:o.sizeBytes})}e.files.push(...await this.#i({client:e.client,relativePrefix:e.relativePrefix,versionStacks:n}))}async#i(e){let t=[],n=0,s=async()=>{for(;n<e.versionStacks.length;){let o=e.versionStacks[n];n+=1;let i=await e.client.getVersionStackHeadVersion({accountId:this.#e.accountId,versionStackId:o.id});i&&t.push({id:i.id,path:this.#u(e.relativePrefix,this.#c({versionStackName:o.name,headVersionName:i.name})),size:i.sizeBytes})}};return await Promise.all(Array.from({length:Math.min(xs,e.versionStacks.length)},()=>s())),t}#c(e){let t=xt.posix.extname(e.versionStackName);if(t&&t!==".")return e.versionStackName;let n=xt.posix.extname(e.headVersionName);return!n||n==="."?e.versionStackName:`${e.versionStackName}${n}`}async#l(e){if(!e.file.id)throw new Error(`Frame.io listing missing file ID for ${e.file.path}`);let t=xt.join(e.batchDir,A(e.file)),n=this.#n.get(e.file.id),o=await(await this.#a()).getFileWithOriginalMediaLink({accountId:this.#e.accountId,fileId:e.file.id}),i={...o,name:n?.path??o.name,sizeBytes:e.file.size},a=0;await mr({file:i,outputPath:t,fileDownloadConcurrency:this.#e.fileDownloadConcurrency,onProgress:l=>{e.totals.bytesTransferred+=Math.max(l-a,0),a=l,e.onProgress?.(this.#d(e.totals))}})}#d(e){let t=Math.max((Date.now()-e.startedAt)/1e3,.001),n=e.bytesTransferred/t,s=Math.max(e.totalBytes-e.bytesTransferred,0);return{bytesTransferred:e.bytesTransferred,totalBytes:e.totalBytes,speed:n,eta:n>0?Math.ceil(s/n):0,percentComplete:e.totalBytes>0?e.bytesTransferred/e.totalBytes*100:100,aggregate:{bytesTransferred:e.bytesTransferred,totalBytes:e.totalBytes,speed:n,eta:n>0?Math.ceil(s/n):0,percentComplete:e.totalBytes>0?e.bytesTransferred/e.totalBytes*100:100}}}#u(e,t){let n=e===""?t:`${e}/${t}`;return b(n)}async#a(){if(this.#o)return await this.#o;this.#o=this.#F();try{return await this.#o}finally{this.#o=null}}async#F(){let e=await Ke();return(!this.#s||this.#t!==e)&&(this.#s=new $({token:e}),this.#t=e),this.#s}};function Q(r){switch(r.kind){case"rclone":return new Ne(r);case"local":return new J(r);case"lucidlink":return new $e(r);case"frameio":return new qe(r);default:{let e=r;throw new Error(`Unsupported sync source: ${JSON.stringify(e)}`)}}}import*as Ye from"fs/promises";import*as Ve from"path";var Ds={".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 _s(r){let e=Ve.extname(r).toLowerCase();return Ds[e]??""}var Je=class r{#e;#s=null;#t=null;#o=!1;#n;#r;#i;constructor(e,t,n,s){this.#e=e,this.#n=t,this.#r=n,this.#i=s}static async create(e){let t=await Ye.stat(e),n=Ve.basename(e),s=_s(n);return new r(e,t.size,n,s)}get name(){return this.#r}get size(){return this.#n}get type(){return this.#i}async readChunk(e,t){if(!this.#s){this.#t||(this.#t=Ye.open(this.#e,"r"));let o=await this.#t;if(this.#t=null,this.#o)return Buffer.alloc(0);this.#s=o}let n=t-e,s=Buffer.alloc(n);return await this.#s.read(s,0,n,e),s}async close(){this.#o=!0;let e=this.#t;await this.#s?.close(),this.#s=null,e&&await(await e.catch(()=>null))?.close(),this.#t=null}};var Bs=new Set(["success","failed","cancelled"]),Er=1e3,Os=250,Ms=4*1024*1024,Dt=class{#e;name;constructor(e,t){this.#e=e,this.name=t}get size(){return this.#e.size}get type(){return this.#e.type}readChunk(e,t){return this.#e.readChunk(e,t)}async close(){await this.#e.close?.()}},Qe=class{#e;#s;#t;#o;#n;constructor(e){this.#e=e.config,this.#s=e.httpClient??new x({apiUrl:e.config.apiUrl,apiKey:e.config.apiKey,edgeWorkerUrl:e.config.edgeWorkerUrl,sessionId:e.config.sessionName}),this.#t=e.createFileReader??(t=>Je.create(t)),this.#o=e.onSnapshot,this.#n=e.analytics}async uploadFiles(e){let t=e.filter(a=>a.preSkipped===!0),n=e.filter(a=>a.preSkipped!==!0);if(n.length===0)return{totalFileCount:e.length,successFileCount:0,skippedFileCount:t.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};let s=new ce({httpClient:this.#s,maxConcurrency:this.#e.maxConcurrent,deltaIntervalMs:Er,adaptiveConcurrency:!1,analytics:this.#n}),o=[],i=0;try{let a=s.startGroupUpload({name:`${n.length} files`,type:"files",fileCount:n.length,folderCount:0,topLevelFileCount:n.length,topLevelFolderCount:0,rootDirectoryId:this.#e.directoryId,projectId:this.#e.projectId,totalBytes:n.reduce((c,u)=>c+u.file.size,0),conflictResolutionOverride:"skip"});for(let c of n){let u=await this.#t(c.file.absolutePath),d=u.name===c.file.fileName?u:new Dt(u,c.file.fileName),m=s.startUpload({fileReader:d,directoryId:c.directoryId,projectId:this.#e.projectId,groupId:a,chunkSize:Ms});s.addAssetToGroup(a,m),o.push({assetId:m,file:c.file,fileReader:d});let h=Date.now();(o.length===1||o.length===n.length||h-i>=Os)&&(i=h,this.#o?.(s.getSnapshot()))}await this.#r(s);let l=s.getSnapshot();return this.#o?.(l),this.#i({snapshot:l,startedUploads:o,preSkippedCount:t.length})}finally{s.destroy()}}async#r(e){let n=Date.now();for(;Date.now()-n<864e5;){let s=e.getSnapshot();this.#o?.(s);let o=Object.values(s.uploadAssets);if(o.length>0&&o.every(i=>Bs.has(i.status)))return;await new Promise(i=>setTimeout(i,Er))}throw new Error("Timed out waiting for upload session to finish")}#i(e){let t=[],n=0,s=0,o=0,i=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){o+=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)?s+=1:n+=1;continue}l.status==="cancelled"?i+=1:o+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:n,skippedFileCount:e.preSkippedCount+s,failedFileCount:o,cancelledFileCount:i,failedFiles:t}}};var f=(r,e=2)=>{if(r===0)return"0 B";let t=1e3,n=e<0?0:e,s=["B","KB","MB","GB","TB","PB","EB"],o=Math.floor(Math.log(r)/Math.log(t));return`${(r/Math.pow(t,o)).toFixed(n)} ${s[o]}`},Xe=r=>{if(r===null)return null;let t=r*8/(1e3*1e3);return t<1?`${(t*1e3).toFixed(0)} Kbps`:`${t.toFixed(1)} Mbps`},fe=r=>{if(r===null)return null;let e=Math.floor(r/3600),t=Math.floor(r%3600/60),n=Math.floor(r%60);return e>0?`${e}h ${t}m`:t>0?`${t}m ${n}s`:`${n}s`};function Ir(r,e){return!e||e.count===1?r:r.filter(t=>Ns(A(t),e.count)===e.index)}function Ns(r,e){let t=2166136261;for(let n=0;n<r.length;n+=1)t^=r.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0)%e}import g from"chalk";import Pr from"log-update";var zs=1e3,_t=class{#e=null;#s=!1;#t=null;#o=null;#n=null;#r=new Map;#i=null;#c=null;#l=null;#d=null;start(){this.#s||(this.#s=!0,this.#r.clear(),this.#i=null,this.#c=null,this.#l=null,this.#d=null,this.#e=setInterval(()=>this.render(),zs))}stop(){this.#s&&(this.#s=!1,this.#e&&(clearInterval(this.#e),this.#e=null),this.render(),Pr.done())}updateSnapshot(e){this.#t=e}updateBatchState(e){this.#o=e}updateDownloadProgress(e){if(!e){this.#n=null;return}let t=e.percentComplete>=100||e.bytesTransferred>=e.totalBytes;!t&&e.speed>0&&(this.#l=e),this.#n=t&&this.#l?{...e,speed:this.#l.speed,eta:this.#l.eta}:e}persistCurrentBatchLine(){!this.#o||this.#o.currentPhase!=="complete"||this.#r.set(this.#o.currentBatch,this.#h(this.#o))}resetUploadSnapshot(){this.#t=null,this.#n=null,this.#l=null,this.#d=null}render(){if(!this.#s)return;let e=this.#o?this.#F(this.#o):this.#a();Pr(e.join(`
13
+ `))}#u(e,t){let n=[`${g.green(f(t.bytesTransferred))} / ${g.gray(f(t.totalBytes))}`,g.cyan(`${t.percentComplete.toFixed(1)}%`),g.magenta(Xe(t.speed)??"..."),`${g.yellow("ETA")}: ${g.yellow(fe(t.eta)??"...")}`];return`${g.blue(e)}: ${n.join(" | ")}`}#a(){let e=this.#f();return[this.#T(e),this.#m(e)]}#F(e){let t=[];for(let n=1;n<e.currentBatch;n++){let s=this.#r.get(n);s&&t.push(s)}return t.push(this.#h(e)),t.push(this.#b(e)),t}#h(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#n?this.#R(t,this.#n):`${t}: ${g.blue("Downloading...")}`;case"scanning":return`${t}: ${g.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${g.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#k(t,e);case"cleaning":return`${t}: ${g.yellow("Cleaning...")}`;case"complete":return`${t}: ${g.green("Complete")} (${e.batchFilesTotal} files, ${f(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#R(e,t){let n=t.aggregate?[`${e}: ${this.#u("Downloading batch",t.aggregate)}`]:[`${e}: ${g.blue("Downloading...")}`];return t.currentFile&&n.push(this.#u("Downloading current file",t.currentFile)),n.join(`
14
+ `)}#k(e,t){let n=this.#f(),s=n.successFileCount+n.failedFileCount+n.cancelledFileCount,o=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),i=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=i>0?(n.uploadedBytes/i*100).toFixed(1):"0.0",l=this.#E(t,n,i),c=l?.formattedSpeed??null,u=l?.formattedTime??null,d=n.totalFileCount>0&&n.totalFileCount<o?`, ${g.gray(`Enqueued: ${n.totalFileCount}/${o}`)}`:"",m=c&&u?`, ${c}, ETA: ${u}`:"",h=t.batchFilesSkipped>0?`, ${g.yellow(`Skipped: ${t.batchFilesSkipped} files / ${f(t.batchBytesSkipped)}`)}`:"",p=i>0&&n.uploadedBytes>=i&&s<o?"Finalizing":"Uploading";return`${e}: ${g.blue(p)} (${s}/${o} files, ${f(n.uploadedBytes)} / ${f(i)}, ${a}%${d}${m}${h})`}#b(e){let t=this.#f(),n=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,s=e.batchBytesSkipped+t.uploadedBytes,o=e.overallFilesCompleted+n,i=e.overallBytesCompleted+s,a=Math.max(e.overallBytesTotal-i,0),l=this.#g(e),c=this.#w(e,t),u=l!==null&&c!==null?l+c:null;return[`Completed: ${o}/${e.overallFilesTotal} files`,`${f(i)} / ${f(e.overallBytesTotal)}`,g.yellow(`${f(a)} remaining`),`Download ETA: ${fe(l)??"..."}`,`Upload ETA: ${fe(c)??"..."}`,`Total ETA: ${fe(u)??"..."}`].join(", ")}#g(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#n?.bytesTransferred??0),n=Math.max(e.overallBytesTotal-t,0);if(n===0)return e.currentPhase==="downloading"&&this.#n?(this.#i=this.#n.eta,this.#n.eta):(this.#i=0,0);if(this.#n&&this.#n.speed>0){let s=Math.ceil(n/this.#n.speed);return this.#i=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#i=0,0):this.#i}#w(e,t){let n=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,s=Math.max(e.overallBytesTotal-n,0),o=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),i=this.#E(e,t,o);if(s===0)return e.currentPhase==="uploading"&&i?(this.#c=i.timeRemainingSeconds,i.timeRemainingSeconds):(this.#c=0,0);if(i&&i.uploadSpeedMbps>0){let a=i.uploadSpeedMbps*1024*1024/8,l=Math.ceil(s/a);return this.#c=l,l}return this.#c}#E(e,t,n){let s=this.#t?.uploadStats,o=n>0&&t.uploadedBytes>=n;return s&&s.uploadSpeedMbps>0&&s.formattedSpeed!=="Calculating..."&&!o?(this.#d={uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds},this.#d):e.currentPhase==="uploading"&&o&&this.#d?this.#d:s?{uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds}:null}#T(e){return[`Total: ${e.totalFileCount}`,g.green(`Success: ${e.successFileCount}`),g.red(`Failed: ${e.failedFileCount}`),g.red(`Cancelled: ${e.cancelledFileCount}`),g.blue(`Active: ${e.activeFileCount}`),g.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#m(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),n=this.#t?` | ${g.cyan(`Speed: ${this.#t.uploadStats.formattedSpeed}`)} | ${g.magenta(`Time remaining: ${this.#t.uploadStats.formattedTime}`)}`:"";return[`Total: ${f(e.totalBytes)}`,g.green(`Uploaded: ${f(e.uploadedBytes)}`),g.yellow(`Remaining: ${f(t)}`)].join(" | ")+n}#f(){return this.#t?Object.values(this.#t.uploadAssets).reduce((t,n)=>{switch(t.totalFileCount+=1,t.totalBytes+=n.totalBytesToUpload,t.uploadedBytes+=n.status==="success"?n.totalBytesToUpload:n.bytesUploaded,n.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}}},P=new _t;var Ze=class{#e;#s;#t;#o="sync";#n=null;#r=null;#i=null;#c=null;#l=null;#d;#u=[];#a=null;#F=null;constructor(e){this.#e=e.config,this.#s=e.sourceDisplayName,this.#t=e.writeJsonLine??(t=>{process.stdout.write(`${t}
15
+ `)})}get isJsonMode(){return this.#e.progressMode==="json"}start({kind:e,title:t,extraLines:n=[],humanMode:s="banner"}){if(this.#o=e,!this.isJsonMode){if(s==="message"){console.log(t);return}console.log(t),console.log(`Session: ${this.#e.sessionName}`),console.log(`Source: ${this.#s}`),console.log(`Root directory ID: ${this.#e.directoryId}`),console.log(`Project ID: ${this.#e.projectId}`),console.log(`Temp directory: ${this.#e.localTempDir}`),console.log(`Edge worker URL: ${this.#e.edgeWorkerUrl}`),console.log(`Shard: ${this.#L()}`);for(let o of n)console.log(o);console.log("");return}this.#g({jobId:this.#e.sessionName,type:"start",emittedAt:new Date().toISOString(),sessionName:this.#e.sessionName,sourceDisplayName:this.#s,aspectProjectId:this.#e.projectId,aspectDirectoryId:this.#e.directoryId,tempDir:this.#e.localTempDir,edgeWorkerUrl:this.#e.edgeWorkerUrl,message:[t,...n].join(" ").trim()||void 0,snapshot:this.#w({status:"running"})})}log(e){if(!this.isJsonMode){console.log(e);return}this.#R(e)}warn(e){if(!this.isJsonMode){console.warn(e);return}this.#R(e)}blank(){this.isJsonMode||console.log("")}startLiveDisplay(){this.isJsonMode||P.start()}stopLiveDisplay(){this.isJsonMode||P.stop()}updateBatchState(e){if(this.#n=e,!this.isJsonMode){P.updateBatchState(e);return}this.#k(e.extraDetails)}updateDownloadProgress(e){if(this.#i=e,!this.isJsonMode){P.updateDownloadProgress(e);return}e&&this.#k()}updateUploadSnapshot(e){if(this.#r=e,!this.isJsonMode){P.updateSnapshot(e);return}this.#k()}resetUploadSnapshot(){this.#r=null,this.#i=null,this.isJsonMode||(P.resetUploadSnapshot(),P.updateDownloadProgress(null))}persistCurrentBatchLine(){if(!this.#n||this.#n.currentPhase!=="complete")return;let e={batchNumber:this.#n.currentBatch,filesCompleted:this.#n.batchFilesTotal,bytesCompleted:this.#n.batchBytesTotal},t=this.#u.findIndex(n=>n.batchNumber===e.batchNumber);if(t===-1?this.#u.push(e):this.#u[t]=e,!this.isJsonMode){P.persistCurrentBatchLine();return}this.#g({jobId:this.#e.sessionName,type:"batch_complete",emittedAt:new Date().toISOString(),batch:e,snapshot:this.#w({status:"running"})})}recordSourceListing({files:e,humanDescription:t="files",includeHumanTotal:n=!0}){this.#c=e.length,this.#l=$s(e),this.isJsonMode||(console.log(`Found ${this.#c} ${t}`),n&&console.log(`Total size: ${f(this.#l)}`),console.log("")),this.#h()}recordPathRenameWarnings(e){if(this.#d=e,!this.isJsonMode){let t=e.sample.map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
16
+ `),n=e.count-e.sample.length,s=n>0?`
17
+ ...and ${n} more renamed target path(s)`:"";console.warn(`Warning: ${e.count} remote file path(s) were renamed for Aspect compatibility.
18
18
  ${t}${s}
19
- `),console.log("")}this.#g()}printSummary({summary:e,extraLines:t=[]}){if(!this.isJsonMode){console.log(""),console.log("=".repeat(60)),console.log("Sync Summary"),console.log("=".repeat(60)),console.log(`Total files: ${e.totalFileCount}`),console.log(`Successful: ${e.successFileCount}`),console.log(`Skipped: ${e.skippedFileCount}`),console.log(`Failed: ${e.failedFileCount}`),console.log(`Cancelled: ${e.cancelledFileCount}`);for(let r of t)console.log(r);if(console.log("=".repeat(60)),e.failedFiles.length>0){console.log(""),console.log("Failed files:");for(let r of e.failedFiles)console.log(` - ${r.relativePath}: ${r.errorMessage??"Unknown error"}`)}}this.#C({result:this.#E(e),message:t.join(" ")||void 0})}printCheckSummary(e){let t=[...e.missingFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Missing on server"})),...e.sizeMismatches.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:`Size mismatch: source ${o.remoteSizeBytes}, server ${o.serverSizeBytes}`})),...e.extraUploadedFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Extra uploaded file on server"})),...e.incompleteServerFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Incomplete upload on server"}))],r=e.existingCount+e.pathOnlyMatchCount,s={jobId:this.#e.sessionName,status:t.length>0?"failed":"succeeded",successCount:r,skippedCount:0,failedCount:t.length,cancelledCount:0,completedBytes:0,failedFiles:t,completedAt:new Date().toISOString()};this.#C({result:s,stateOverrides:{overall:{filesCompleted:r,filesTotal:e.totalRemoteCount,bytesCompleted:0,bytesTotal:0,bytesRemaining:0,downloadEtaSeconds:0,uploadEtaSeconds:0,totalEtaSeconds:0},counts:{total:e.totalRemoteCount,success:r,failed:t.length,cancelled:0,active:0,queued:0,skipped:0},failedFiles:t}})}#g(){if(!this.isJsonMode||this.#c===null||this.#a===null)return;let e={jobId:this.#e.sessionName,type:"listing",emittedAt:new Date().toISOString(),filesTotal:this.#c,bytesTotal:this.#a,pathRenameWarnings:this.#u,snapshot:this.#b({status:"running",stateOverrides:{overall:{filesCompleted:0,filesTotal:this.#c,bytesCompleted:0,bytesTotal:this.#a,bytesRemaining:this.#a,downloadEtaSeconds:0,uploadEtaSeconds:0,totalEtaSeconds:0}}})};this.#h(e)}#P(e){this.#h({jobId:this.#e.sessionName,type:"progress",emittedAt:new Date().toISOString(),phase:this.#p(),message:e,snapshot:this.#b({status:"running"})})}#I(e){this.#h({jobId:this.#e.sessionName,type:"progress",emittedAt:new Date().toISOString(),phase:this.#p(),message:e,snapshot:this.#b({status:"running"})})}#C({result:e,message:t,stateOverrides:r}){this.isJsonMode&&this.#h({jobId:this.#e.sessionName,type:"summary",emittedAt:e.completedAt,result:e,message:t,snapshot:this.#b({status:e.status,stateOverrides:r})})}#h(e){this.#t(JSON.stringify(e))}#b({status:e,stateOverrides:t}){let r=this.#v(),s=this.#r?{current:this.#r.currentBatch,total:this.#r.totalBatches,filesTotal:this.#r.batchFilesTotal,bytesTotal:this.#r.batchBytesTotal,filesSkipped:this.#r.batchFilesSkipped,bytesSkipped:this.#r.batchBytesSkipped}:void 0,o=this.#r?this.#w({batchState:this.#r,counts:r}):void 0,i=this.#i?{bytesTransferred:this.#i.bytesTransferred,bytesTotal:this.#i.totalBytes,percent:this.#i.percentComplete,speedBps:this.#i.speed,etaSeconds:this.#i.eta}:void 0,a=this.#i?.currentFile?{bytesTransferred:this.#i.currentFile.bytesTransferred,bytesTotal:this.#i.currentFile.totalBytes,percent:this.#i.currentFile.percentComplete,speedBps:this.#i.currentFile.speed,etaSeconds:this.#i.currentFile.eta}:void 0,l={downloadBps:i?.speedBps??0,uploadBps:o?.speedBps??0};return{jobId:this.#e.sessionName,kind:this.#o,status:e,phase:this.#p(),sessionName:this.#e.sessionName,sourceDisplayName:this.#s,aspectProjectId:this.#e.projectId,aspectDirectoryId:this.#e.directoryId,tempDir:this.#e.localTempDir,edgeWorkerUrl:this.#e.edgeWorkerUrl,batch:s,download:i,downloadCurrentFile:a,upload:o,counts:this.#T(r),overall:this.#r?this.#m({batchState:this.#r,counts:r,uploadProgress:o}):void 0,throughput:l,pathRenameWarnings:this.#u,completedBatches:this.#d,failedFiles:[],cancelRequested:!1,discardStagingRequested:!1,updatedAt:new Date().toISOString(),...t}}#w({batchState:e,counts:t}){let r=Math.max(e.batchFilesTotal-e.batchFilesSkipped,0),s=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=s>0?t.uploadedBytes/s*100:0,i=this.#f();return{filesCompleted:t.successFileCount+t.failedFileCount+t.cancelledFileCount,filesTotal:r,bytesUploaded:t.uploadedBytes,bytesTotal:s,percent:o,enqueued:t.totalFileCount,speedBps:i,etaSeconds:this.#k({batchState:e,counts:t,uploadBytesTotal:s,speedBps:i})}}#T(e){return{total:e.totalFileCount,success:e.successFileCount,failed:e.failedFileCount,cancelled:e.cancelledFileCount,active:e.activeFileCount,queued:e.queuedFileCount,skipped:this.#r?.batchFilesSkipped??0}}#m({batchState:e,counts:t,uploadProgress:r}){let s=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,o=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+s,a=e.overallBytesCompleted+o,l=Math.max(e.overallBytesTotal-a,0),c=this.#y(e),u=r?.etaSeconds??0;return{filesCompleted:i,filesTotal:e.overallFilesTotal,bytesCompleted:a,bytesTotal:e.overallBytesTotal,bytesRemaining:l,downloadEtaSeconds:c,uploadEtaSeconds:u,totalEtaSeconds:c+u}}#y(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#i?.bytesTransferred??0),r=Math.max(e.overallBytesTotal-t,0);if(r===0)return this.#l=0,0;if(this.#i&&this.#i.speed>0){let s=Math.ceil(r/this.#i.speed);return this.#l=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#l=0,0):this.#l??0}#k({batchState:e,counts:t,uploadBytesTotal:r,speedBps:s}){let o=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,i=Math.max(e.overallBytesTotal-o,0);if(i===0)return this.#R=0,0;if(s>0&&r>0){let a=Math.ceil(i/s);return this.#R=a,a}return this.#R??0}#p(){if(!this.#r)return"scanning";if(this.#r.currentPhase==="uploading"){let e=this.#v(),t=Math.max(this.#r.batchFilesTotal-this.#r.batchFilesSkipped,0),r=Math.max(this.#r.batchBytesTotal-this.#r.batchBytesSkipped,0),s=e.successFileCount+e.failedFileCount+e.cancelledFileCount;if(r>0&&e.uploadedBytes>=r&&s<t)return"finalizing"}switch(this.#r.currentPhase){case"downloading":return"downloading";case"scanning":return"scanning";case"syncing_folders":return"syncing_folders";case"uploading":return"uploading";case"cleaning":return"cleaning";case"complete":return"complete";default:return this.#r.currentPhase}}#v(){return this.#n?Object.values(this.#n.uploadAssets).reduce((t,r)=>{switch(t.totalFileCount+=1,t.totalBytes+=r.totalBytesToUpload,t.uploadedBytes+=r.status==="success"?r.totalBytesToUpload:r.bytesUploaded,r.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}}#f(){let e=this.#n?.uploadStats.uploadSpeedMbps;return e===void 0||e<=0||!Number.isFinite(e)?0:e*1024*1024/8}#E(e){let t=e.failedFiles.map(s=>({name:s.fileName??s.relativePath.split("/").at(-1)??s.relativePath,relativePath:s.relativePath,errorMessage:s.errorMessage??"Unknown error"})),r=e.cancelledFileCount>0&&e.failedFileCount===0?"cancelled":e.failedFileCount>0?"failed":"succeeded";return{jobId:this.#e.sessionName,status:r,successCount:e.successFileCount,skippedCount:e.skippedFileCount,failedCount:e.failedFileCount,cancelledCount:e.cancelledFileCount,completedBytes:e.completedByteCount??this.#r?.overallBytesCompleted??0,failedFiles:t,completedAt:new Date().toISOString()}}#L(){return this.#e.shard?`${this.#e.shard.index+1}/${this.#e.shard.count} (index ${this.#e.shard.index})`:"disabled"}};function Ms(n){return n.reduce((e,t)=>e+(Number.isFinite(t.size)?t.size:0),0)}var Ze=200,et=class{#e;#s;#t;#o;#r;#n;constructor(e,t,r){this.#e=e,this.#s=t??new x({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#t=new xe({rootDirectoryId:e.directoryId,httpClient:this.#s}),this.#r=r??Q(e.source),this.#n=new Xe({config:e,sourceDisplayName:this.#r.displayName}),this.#o=new Ve({config:e,httpClient:this.#s,onSnapshot:s=>this.#n.updateUploadSnapshot(s),analytics:sn})}async run(){try{await this.#i()}finally{await this.#r.shutdown()}}async runBatched(){try{await this.#c()}finally{await this.#r.shutdown()}}async runCheckOnly(){try{await this.#a()}finally{await this.#r.shutdown()}}async#i(){this.#p("Starting data sync..."),await this.#b();let e=this.#C(this.#I(await this.#u()));if(e.length===0){this.#n.log("No files to sync. Exiting."),await this.#w();return}let t={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},r=[],s={batchNumber:1,files:e,totalSize:this.#B(e)};this.#n.startLiveDisplay();try{let i=await this.#h({batch:s,totalBatches:1,overallFilesTotal:e.length,overallBytesTotal:s.totalSize,completedTotals:t,batchDir:this.#e.localTempDir});this.#N(t,r,i,s.totalSize)}finally{this.#n.stopLiveDisplay()}let o={...t,failedFiles:r};this.#f({summary:o}),await this.#T(o),this.#S(o)}async#c(){if(!this.#e.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#p("Starting batched data sync...",[`Batch size: ${f(this.#e.batchSizeBytes)}`,`Max concurrent chunks: ${this.#e.maxConcurrent}`]),await this.#b();let e=this.#C(this.#I(await this.#u()));if(e.length===0){this.#n.log("No files to sync. Exiting."),await this.#w();return}let t=Yt(e,this.#e.batchSizeBytes);await this.#k(t);let r={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},s=[],o=this.#B(e);this.#n.startLiveDisplay();try{for(let a of t){let l=await this.#h({batch:a,totalBatches:t.length,overallFilesTotal:e.length,overallBytesTotal:o,completedTotals:r});this.#N(r,s,l,a.totalSize)}}finally{this.#n.stopLiveDisplay()}this.#f({summary:{...r,failedFiles:s},extraLines:[`Batches: ${t.length}`]});let i={...r,failedFiles:s};await this.#T(i),this.#S(i)}async#a(){this.#n.start({kind:"check",title:"Running in check-only mode (no downloads/uploads)...",humanMode:"message"}),await this.#r.prepare(),this.#n.log(`Listing source files from ${this.#r.displayName}...`);let e=await this.#r.listFiles();this.#n.recordSourceListing({files:e,humanDescription:"source files to check",includeHumanTotal:!1});let t=this.#C(this.#I(e));if(t.length===0){this.#n.log("No source files to check. Exiting.");return}this.#n.log("Fetching Aspect project summary...");let r=await this.#d();this.#n.log("Fetching existing Aspect files...");let s=await this.#t.listFilesInSubtree({onProgress:i=>this.#E(i)}),o=this.#l(t,s,r);this.#L(o),this.#n.printCheckSummary(o)}async#u(){this.#n.log("Listing all source files...");let e=await this.#r.listFiles();return this.#n.recordSourceListing({files:e}),e}async#d(){return await this.#s.get(`/projects/${this.#e.projectId}`)}#l(e,t,r){let s=e.map(S=>({relativePath:A(S),sizeBytes:this.#P(S.size)})),o=s.filter(S=>S.sizeBytes===null).length,i=t.filter(S=>S.isUploaded),a=t.filter(S=>S.uploadStateKnown&&!S.isUploaded),l=t.filter(S=>!S.uploadStateKnown).length;l>0&&(this.#n.warn(`Warning: ${l} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),this.#n.blank());let c=this.#R(s),u=this.#g(i),d=new Set([...c.keys(),...u.keys()]),m=0,h=0,p=[],y=[],C=[];for(let S of d){let Ee=c.get(S)??[],k=u.get(S)??[],w=new Set,lt=[];for(let F of Ee){if(F.sizeBytes===null){lt.push(F);continue}let j=k.findIndex((v,Pe)=>!w.has(Pe)&&v.sizeBytes===F.sizeBytes);j>=0?(m+=1,w.add(j)):lt.push(F)}for(let F of lt){if(F.sizeBytes===null){let v=k.findIndex((Pe,hr)=>!w.has(hr));v>=0?(w.add(v),h+=1):p.push(F);continue}let j=k.findIndex((v,Pe)=>!w.has(Pe));if(j>=0){let v=k[j];w.add(j),y.push({relativePath:S,remoteSizeBytes:F.sizeBytes,serverSizeBytes:v.sizeBytes,assetId:v.assetId})}else p.push(F)}for(let F=0;F<k.length;F++)w.has(F)||C.push(k[F])}return{totalRemoteCount:e.length,totalServerCount:t.length,projectAssetCount:r.num_assets,projectRootDirectoryId:r.root_directory_id,uploadedServerCount:i.length,unknownUploadStateCount:l,unknownRemoteSizeCount:o,pathOnlyMatchCount:h,existingCount:m,missingFiles:p,sizeMismatches:y,extraUploadedFiles:C,incompleteServerFiles:a}}#R(e){let t=new Map;for(let r of e){let s=b(r.relativePath),o=t.get(s)??[];o.push({...r,relativePath:s}),t.set(s,o)}return t}#g(e){let t=new Map;for(let r of e){let s=b(r.relativePath),o=t.get(s)??[];o.push({...r,relativePath:s}),t.set(s,o)}return t}#P(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:null}#I(e){let t=Ue(e);return t.changes.length===0||this.#n.recordPathRenameWarnings({count:t.changes.length,sample:t.changes.slice(0,10).map(r=>({sourcePath:r.sourcePath,targetPath:r.targetPath}))}),t.files}#C(e){let t=Pn(e,this.#e.shard);return this.#e.shard&&(this.#n.log(`Shard ${this.#e.shard.index+1}/${this.#e.shard.count}: ${t.length} of ${e.length} planned file(s)`),this.#n.log(`Shard size: ${f(this.#B(t))}`),this.#n.blank()),t}async#h(e){let t=e.batchDir??_t.join(this.#e.localTempDir,`batch${e.batch.batchNumber}`);await ge.mkdir(t,{recursive:!0});let r=e.batch.files.map(d=>this.#r.resolveLocalFile(d,t));this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:`Preparing ${r.length} files...`}),this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"syncing_folders",extraDetails:"Ensuring target directories exist..."});let s=await this.#t.ensureDirectories(r);this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:"Checking existing assets..."});let o=await this.#m(s),i=this.#y(o),a=e.batch.files.filter((d,m)=>o[m]?.preSkipped!==!0),l=_t.join(this.#e.localTempDir,`batch${e.batch.batchNumber}.txt`),c=async()=>{await Vt(l),this.#e.keepLocal||await ge.rm(t,{recursive:!0,force:!0}),this.#n.resetUploadSnapshot()};if(a.length===0){let d={totalFileCount:o.length,successFileCount:0,skippedFileCount:o.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};return this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+d.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"everything already synced"}),this.#n.persistCurrentBatchLine(),await c(),d}this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"downloading"}),await this.#r.materializeBatch({files:a,batchDir:t,batchFilePath:l,onProgress:d=>this.#n.updateDownloadProgress(d)}),this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"uploading"});let u=await this.#o.uploadFiles(o);return this.#A(u)?(this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"failed; local files preserved"}),this.#n.persistCurrentBatchLine(),u):(this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"cleaning"}),await c(),this.#n.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#U(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete"}),this.#n.persistCurrentBatchLine(),u)}async#b(){this.#n.log("Preparing source..."),await this.#r.prepare(),this.#n.log("Source ready"),this.#n.blank(),this.#n.log("Creating session directory..."),await ge.mkdir(this.#e.localTempDir,{recursive:!0}),this.#n.log(`Session directory: ${this.#e.localTempDir}`),this.#n.blank()}async#w(){this.#e.keepLocal||(this.#n.blank(),this.#n.log("Cleaning up session directory..."),await ge.rm(this.#e.localTempDir,{recursive:!0,force:!0}),this.#n.log(`Deleted session directory: ${this.#e.localTempDir}`))}async#T(e){if(this.#A(e)){this.#n.blank(),this.#n.log(`Preserving session directory for retry/debugging: ${this.#e.localTempDir}`);return}await this.#w()}async#m(e){let t=await this.#t.checkAssetsExistence(e.map(r=>({directory_id:r.directoryId,name:r.file.fileName,size_bytes:r.file.size})));return e.map((r,s)=>({file:r.file,directoryId:r.directoryId,preSkipped:t[s]?.exists===!0}))}#y(e){return e.reduce((t,r)=>(r.preSkipped===!0&&(t.skippedFileCount+=1,t.skippedByteCount+=r.file.size),t),{skippedFileCount:0,skippedByteCount:0})}async#k(e){this.#n.log("Creating batches..."),this.#n.log(`Created ${e.length} batches`);let t=[];for(let r of e){let s=`Batch ${r.batchNumber}: ${r.files.length} files, ${f(r.totalSize)}`;t.push(s),this.#n.log(s)}await ge.writeFile(_t.join(this.#e.localTempDir,"batches.txt"),`${t.join(`
19
+ `),console.log("")}this.#h()}printSummary({summary:e,extraLines:t=[]}){if(!this.isJsonMode){console.log(""),console.log("=".repeat(60)),console.log("Sync Summary"),console.log("=".repeat(60)),console.log(`Total files: ${e.totalFileCount}`),console.log(`Successful: ${e.successFileCount}`),console.log(`Skipped: ${e.skippedFileCount}`),console.log(`Failed: ${e.failedFileCount}`),console.log(`Cancelled: ${e.cancelledFileCount}`);for(let n of t)console.log(n);if(console.log("=".repeat(60)),e.failedFiles.length>0){console.log(""),console.log("Failed files:");for(let n of e.failedFiles)console.log(` - ${n.relativePath}: ${n.errorMessage??"Unknown error"}`)}}this.#b({result:this.#P(e),message:t.join(" ")||void 0})}printCheckSummary(e){let t=[...e.missingFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Missing on server"})),...e.sizeMismatches.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:`Size mismatch: source ${o.remoteSizeBytes}, server ${o.serverSizeBytes}`})),...e.extraUploadedFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Extra uploaded file on server"})),...e.incompleteServerFiles.map(o=>({name:o.relativePath.split("/").at(-1)??o.relativePath,relativePath:o.relativePath,errorMessage:"Incomplete upload on server"}))],n=e.existingCount+e.pathOnlyMatchCount,s={jobId:this.#e.sessionName,status:t.length>0?"failed":"succeeded",successCount:n,skippedCount:0,failedCount:t.length,cancelledCount:0,completedBytes:0,failedFiles:t,completedAt:new Date().toISOString()};this.#b({result:s,stateOverrides:{overall:{filesCompleted:n,filesTotal:e.totalRemoteCount,bytesCompleted:0,bytesTotal:0,bytesRemaining:0,downloadEtaSeconds:0,uploadEtaSeconds:0,totalEtaSeconds:0},counts:{total:e.totalRemoteCount,success:n,failed:t.length,cancelled:0,active:0,queued:0,skipped:0},failedFiles:t}})}#h(){if(!this.isJsonMode||this.#c===null||this.#l===null)return;let e={jobId:this.#e.sessionName,type:"listing",emittedAt:new Date().toISOString(),filesTotal:this.#c,bytesTotal:this.#l,pathRenameWarnings:this.#d,snapshot:this.#w({status:"running",stateOverrides:{overall:{filesCompleted:0,filesTotal:this.#c,bytesCompleted:0,bytesTotal:this.#l,bytesRemaining:this.#l,downloadEtaSeconds:0,uploadEtaSeconds:0,totalEtaSeconds:0}}})};this.#g(e)}#R(e){this.#g({jobId:this.#e.sessionName,type:"progress",emittedAt:new Date().toISOString(),phase:this.#p(),message:e,snapshot:this.#w({status:"running"})})}#k(e){this.#g({jobId:this.#e.sessionName,type:"progress",emittedAt:new Date().toISOString(),phase:this.#p(),message:e,snapshot:this.#w({status:"running"})})}#b({result:e,message:t,stateOverrides:n}){this.isJsonMode&&this.#g({jobId:this.#e.sessionName,type:"summary",emittedAt:e.completedAt,result:e,message:t,snapshot:this.#w({status:e.status,stateOverrides:n})})}#g(e){this.#t(JSON.stringify(e))}#w({status:e,stateOverrides:t}){let n=this.#v(),s=this.#n?{current:this.#n.currentBatch,total:this.#n.totalBatches,filesTotal:this.#n.batchFilesTotal,bytesTotal:this.#n.batchBytesTotal,filesSkipped:this.#n.batchFilesSkipped,bytesSkipped:this.#n.batchBytesSkipped}:void 0,o=this.#n?this.#E({batchState:this.#n,counts:n}):void 0,i=this.#i?{bytesTransferred:this.#i.bytesTransferred,bytesTotal:this.#i.totalBytes,percent:this.#i.percentComplete,speedBps:this.#i.speed,etaSeconds:this.#i.eta}:void 0,a=this.#i?.currentFile?{bytesTransferred:this.#i.currentFile.bytesTransferred,bytesTotal:this.#i.currentFile.totalBytes,percent:this.#i.currentFile.percentComplete,speedBps:this.#i.currentFile.speed,etaSeconds:this.#i.currentFile.eta}:void 0,l={downloadBps:i?.speedBps??0,uploadBps:o?.speedBps??0};return{jobId:this.#e.sessionName,kind:this.#o,status:e,phase:this.#p(),sessionName:this.#e.sessionName,sourceDisplayName:this.#s,aspectProjectId:this.#e.projectId,aspectDirectoryId:this.#e.directoryId,tempDir:this.#e.localTempDir,edgeWorkerUrl:this.#e.edgeWorkerUrl,batch:s,download:i,downloadCurrentFile:a,upload:o,counts:this.#T(n),overall:this.#n?this.#m({batchState:this.#n,counts:n,uploadProgress:o}):void 0,throughput:l,pathRenameWarnings:this.#d,completedBatches:this.#u,failedFiles:[],cancelRequested:!1,discardStagingRequested:!1,updatedAt:new Date().toISOString(),...t}}#E({batchState:e,counts:t}){let n=Math.max(e.batchFilesTotal-e.batchFilesSkipped,0),s=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=s>0?t.uploadedBytes/s*100:0,i=this.#y();return{filesCompleted:t.successFileCount+t.failedFileCount+t.cancelledFileCount,filesTotal:n,bytesUploaded:t.uploadedBytes,bytesTotal:s,percent:o,enqueued:t.totalFileCount,speedBps:i,etaSeconds:this.#I({batchState:e,counts:t,uploadBytesTotal:s,speedBps:i})}}#T(e){return{total:e.totalFileCount,success:e.successFileCount,failed:e.failedFileCount,cancelled:e.cancelledFileCount,active:e.activeFileCount,queued:e.queuedFileCount,skipped:this.#n?.batchFilesSkipped??0}}#m({batchState:e,counts:t,uploadProgress:n}){let s=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,o=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+s,a=e.overallBytesCompleted+o,l=Math.max(e.overallBytesTotal-a,0),c=this.#f(e),u=n?.etaSeconds??0;return{filesCompleted:i,filesTotal:e.overallFilesTotal,bytesCompleted:a,bytesTotal:e.overallBytesTotal,bytesRemaining:l,downloadEtaSeconds:c,uploadEtaSeconds:u,totalEtaSeconds:c+u}}#f(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#i?.bytesTransferred??0),n=Math.max(e.overallBytesTotal-t,0);if(n===0)return this.#a=0,0;if(this.#i&&this.#i.speed>0){let s=Math.ceil(n/this.#i.speed);return this.#a=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#a=0,0):this.#a??0}#I({batchState:e,counts:t,uploadBytesTotal:n,speedBps:s}){let o=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,i=Math.max(e.overallBytesTotal-o,0);if(i===0)return this.#F=0,0;if(s>0&&n>0){let a=Math.ceil(i/s);return this.#F=a,a}return this.#F??0}#p(){if(!this.#n)return"scanning";if(this.#n.currentPhase==="uploading"){let e=this.#v(),t=Math.max(this.#n.batchFilesTotal-this.#n.batchFilesSkipped,0),n=Math.max(this.#n.batchBytesTotal-this.#n.batchBytesSkipped,0),s=e.successFileCount+e.failedFileCount+e.cancelledFileCount;if(n>0&&e.uploadedBytes>=n&&s<t)return"finalizing"}switch(this.#n.currentPhase){case"downloading":return"downloading";case"scanning":return"scanning";case"syncing_folders":return"syncing_folders";case"uploading":return"uploading";case"cleaning":return"cleaning";case"complete":return"complete";default:return this.#n.currentPhase}}#v(){return this.#r?Object.values(this.#r.uploadAssets).reduce((t,n)=>{switch(t.totalFileCount+=1,t.totalBytes+=n.totalBytesToUpload,t.uploadedBytes+=n.status==="success"?n.totalBytesToUpload:n.bytesUploaded,n.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}}#y(){let e=this.#r?.uploadStats.uploadSpeedMbps;return e===void 0||e<=0||!Number.isFinite(e)?0:e*1024*1024/8}#P(e){let t=e.failedFiles.map(s=>({name:s.fileName??s.relativePath.split("/").at(-1)??s.relativePath,relativePath:s.relativePath,errorMessage:s.errorMessage??"Unknown error"})),n=e.cancelledFileCount>0&&e.failedFileCount===0?"cancelled":e.failedFileCount>0?"failed":"succeeded";return{jobId:this.#e.sessionName,status:n,successCount:e.successFileCount,skippedCount:e.skippedFileCount,failedCount:e.failedFileCount,cancelledCount:e.cancelledFileCount,completedBytes:e.completedByteCount??this.#n?.overallBytesCompleted??0,failedFiles:t,completedAt:new Date().toISOString()}}#L(){return this.#e.shard?`${this.#e.shard.index+1}/${this.#e.shard.count} (index ${this.#e.shard.index})`:"disabled"}};function $s(r){return r.reduce((e,t)=>e+(Number.isFinite(t.size)?t.size:0),0)}var et=200,tt=class{#e;#s;#t;#o;#n;#r;#i;constructor(e,t,n,s=js){this.#e=e,this.#s=t??new x({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#t=new xe({rootDirectoryId:e.directoryId,httpClient:this.#s}),this.#n=n??Q(e.source),this.#r=new Ze({config:e,sourceDisplayName:this.#n.displayName}),this.#o=new Qe({config:e,httpClient:this.#s,onSnapshot:o=>this.#r.updateUploadSnapshot(o),analytics:or}),this.#i=s}async run(){try{await this.#c()}finally{await this.#n.shutdown()}}async runBatched(){try{await this.#l()}finally{await this.#n.shutdown()}}async runCheckOnly(){try{await this.#d()}finally{await this.#n.shutdown()}}async#c(){this.#L("Starting data sync..."),await this.#f();let e=this.#T(this.#E(await this.#h()));if(e.length===0){this.#r.log("No files to sync. Exiting."),await this.#I();return}await this.#u({files:e});let t={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},n=[],s={batchNumber:1,files:e,totalSize:this.#G(e)};this.#r.startLiveDisplay();try{let i=await this.#m({batch:s,totalBatches:1,overallFilesTotal:e.length,overallBytesTotal:s.totalSize,completedTotals:t,batchDir:this.#e.localTempDir});this.#N(t,n,i,s.totalSize)}finally{this.#r.stopLiveDisplay()}let o={...t,failedFiles:n};this.#U({summary:o}),await this.#p(o),this.#W(o)}async#l(){if(!this.#e.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#L("Starting batched data sync...",[`Batch size: ${f(this.#e.batchSizeBytes)}`,`Max concurrent chunks: ${this.#e.maxConcurrent}`]),await this.#f();let e=this.#T(this.#E(await this.#h()));if(e.length===0){this.#r.log("No files to sync. Exiting."),await this.#I();return}let t=Vt(e,this.#e.batchSizeBytes);await this.#P(t),await this.#u({files:e,batchCount:t.length,batchSizeBytes:this.#e.batchSizeBytes});let n={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},s=[],o=this.#G(e);this.#r.startLiveDisplay();try{for(let a of t){let l=await this.#m({batch:a,totalBatches:t.length,overallFilesTotal:e.length,overallBytesTotal:o,completedTotals:n});this.#N(n,s,l,a.totalSize)}}finally{this.#r.stopLiveDisplay()}this.#U({summary:{...n,failedFiles:s},extraLines:[`Batches: ${t.length}`]});let i={...n,failedFiles:s};await this.#p(i),this.#W(i)}async#d(){this.#r.start({kind:"check",title:"Running in check-only mode (no downloads/uploads)...",humanMode:"message"}),await this.#n.prepare(),this.#r.log(`Listing source files from ${this.#n.displayName}...`);let e=await this.#n.listFiles();this.#r.recordSourceListing({files:e,humanDescription:"source files to check",includeHumanTotal:!1});let t=this.#T(this.#E(e));if(t.length===0){this.#r.log("No source files to check. Exiting.");return}this.#r.log("Fetching Aspect project summary...");let n=await this.#R();this.#r.log("Fetching existing Aspect files...");let s=await this.#t.listFilesInSubtree({onProgress:i=>this.#M(i)}),o=this.#k(t,s,n);this.#_(o),this.#r.printCheckSummary(o)}async#u(e){if(this.#e.skipConfirmation||this.#r.isJsonMode)return;let t=await this.#a(),n=await this.#s.get(`/directories/${this.#e.directoryId}/tree`),s=t.root_directory_id===this.#e.directoryId,o=s?`${t.name} (project root)`:n.name,i=await this.#F();if(!await this.#i({sourcePath:i,projectId:t.id,projectName:t.name,directoryId:this.#e.directoryId,directoryName:o,isRootDirectory:s,fileCount:e.files.length,totalBytes:this.#G(e.files),batchCount:e.batchCount,batchSizeBytes:e.batchSizeBytes}))throw new Error("Sync cancelled by user")}async#a(){return await this.#s.get(`/projects/${this.#e.projectId}`)}async#F(){return this.#n.getConfirmationSourcePath?await this.#n.getConfirmationSourcePath():this.#n.displayName}async#h(){this.#r.log("Listing all source files...");let e=await this.#n.listFiles();return this.#r.recordSourceListing({files:e}),e}async#R(){return await this.#s.get(`/projects/${this.#e.projectId}`)}#k(e,t,n){let s=e.map(S=>({relativePath:A(S),sizeBytes:this.#w(S.size)})),o=s.filter(S=>S.sizeBytes===null).length,i=t.filter(S=>S.isUploaded),a=t.filter(S=>S.uploadStateKnown&&!S.isUploaded),l=t.filter(S=>!S.uploadStateKnown).length;l>0&&(this.#r.warn(`Warning: ${l} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),this.#r.blank());let c=this.#b(s),u=this.#g(i),d=new Set([...c.keys(),...u.keys()]),m=0,h=0,p=[],y=[],C=[];for(let S of d){let Ee=c.get(S)??[],k=u.get(S)??[],w=new Set,ct=[];for(let F of Ee){if(F.sizeBytes===null){ct.push(F);continue}let j=k.findIndex((v,Ie)=>!w.has(Ie)&&v.sizeBytes===F.sizeBytes);j>=0?(m+=1,w.add(j)):ct.push(F)}for(let F of ct){if(F.sizeBytes===null){let v=k.findIndex((Ie,yn)=>!w.has(yn));v>=0?(w.add(v),h+=1):p.push(F);continue}let j=k.findIndex((v,Ie)=>!w.has(Ie));if(j>=0){let v=k[j];w.add(j),y.push({relativePath:S,remoteSizeBytes:F.sizeBytes,serverSizeBytes:v.sizeBytes,assetId:v.assetId})}else p.push(F)}for(let F=0;F<k.length;F++)w.has(F)||C.push(k[F])}return{totalRemoteCount:e.length,totalServerCount:t.length,projectAssetCount:n.num_assets,projectRootDirectoryId:n.root_directory_id,uploadedServerCount:i.length,unknownUploadStateCount:l,unknownRemoteSizeCount:o,pathOnlyMatchCount:h,existingCount:m,missingFiles:p,sizeMismatches:y,extraUploadedFiles:C,incompleteServerFiles:a}}#b(e){let t=new Map;for(let n of e){let s=b(n.relativePath),o=t.get(s)??[];o.push({...n,relativePath:s}),t.set(s,o)}return t}#g(e){let t=new Map;for(let n of e){let s=b(n.relativePath),o=t.get(s)??[];o.push({...n,relativePath:s}),t.set(s,o)}return t}#w(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:null}#E(e){let t=Le(e);return t.changes.length===0||this.#r.recordPathRenameWarnings({count:t.changes.length,sample:t.changes.slice(0,10).map(n=>({sourcePath:n.sourcePath,targetPath:n.targetPath}))}),t.files}#T(e){let t=Ir(e,this.#e.shard);return this.#e.shard&&(this.#r.log(`Shard ${this.#e.shard.index+1}/${this.#e.shard.count}: ${t.length} of ${e.length} planned file(s)`),this.#r.log(`Shard size: ${f(this.#G(t))}`),this.#r.blank()),t}async#m(e){let t=e.batchDir??Bt.join(this.#e.localTempDir,`batch${e.batch.batchNumber}`);await ge.mkdir(t,{recursive:!0});let n=e.batch.files.map(d=>this.#n.resolveLocalFile(d,t));this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:`Preparing ${n.length} files...`}),this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"syncing_folders",extraDetails:"Ensuring target directories exist..."});let s=await this.#t.ensureDirectories(n);this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:0,batchBytesSkipped:0,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:"Checking existing assets..."});let o=await this.#v(s),i=this.#y(o),a=e.batch.files.filter((d,m)=>o[m]?.preSkipped!==!0),l=Bt.join(this.#e.localTempDir,`batch${e.batch.batchNumber}.txt`),c=async()=>{await Qt(l),this.#e.keepLocal||await ge.rm(t,{recursive:!0,force:!0}),this.#r.resetUploadSnapshot()};if(a.length===0){let d={totalFileCount:o.length,successFileCount:0,skippedFileCount:o.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};return this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+d.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"everything already synced"}),this.#r.persistCurrentBatchLine(),await c(),d}this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"downloading"}),await this.#n.materializeBatch({files:a,batchDir:t,batchFilePath:l,onProgress:d=>this.#r.updateDownloadProgress(d)}),this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"uploading"});let u=await this.#o.uploadFiles(o);return this.#K(u)?(this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"failed; local files preserved"}),this.#r.persistCurrentBatchLine(),u):(this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"cleaning"}),await c(),this.#r.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:n.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:i.skippedFileCount,batchBytesSkipped:i.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#x(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete"}),this.#r.persistCurrentBatchLine(),u)}async#f(){this.#r.log("Preparing source..."),await this.#n.prepare(),this.#r.log("Source ready"),this.#r.blank(),this.#r.log("Creating session directory..."),await ge.mkdir(this.#e.localTempDir,{recursive:!0}),this.#r.log(`Session directory: ${this.#e.localTempDir}`),this.#r.blank()}async#I(){this.#e.keepLocal||(this.#r.blank(),this.#r.log("Cleaning up session directory..."),await ge.rm(this.#e.localTempDir,{recursive:!0,force:!0}),this.#r.log(`Deleted session directory: ${this.#e.localTempDir}`))}async#p(e){if(this.#K(e)){this.#r.blank(),this.#r.log(`Preserving session directory for retry/debugging: ${this.#e.localTempDir}`);return}await this.#I()}async#v(e){let t=await this.#t.checkAssetsExistence(e.map(n=>({directory_id:n.directoryId,name:n.file.fileName,size_bytes:n.file.size})));return e.map((n,s)=>({file:n.file,directoryId:n.directoryId,preSkipped:t[s]?.exists===!0}))}#y(e){return e.reduce((t,n)=>(n.preSkipped===!0&&(t.skippedFileCount+=1,t.skippedByteCount+=n.file.size),t),{skippedFileCount:0,skippedByteCount:0})}async#P(e){this.#r.log("Creating batches..."),this.#r.log(`Created ${e.length} batches`);let t=[];for(let n of e){let s=`Batch ${n.batchNumber}: ${n.files.length} files, ${f(n.totalSize)}`;t.push(s),this.#r.log(s)}await ge.writeFile(Bt.join(this.#e.localTempDir,"batches.txt"),`${t.join(`
20
20
  `)}
21
- `,"utf-8"),this.#n.blank()}#p(e,t=[]){this.#n.start({kind:"sync",title:e,extraLines:t})}#v(){return this.#e.shard?`${this.#e.shard.index+1}/${this.#e.shard.count} (index ${this.#e.shard.index})`:"disabled"}#f(e){this.#n.printSummary({summary:e.summary,extraLines:e.extraLines})}#E(e){this.#n.log(`Aspect scan: ${e.scannedDirectoryCount}/${e.queuedDirectoryCount} directories, ${e.fileCount} files found`)}#L(e){if(this.#n.isJsonMode)return;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.#e.directoryId?(console.log(""),console.log(`Warning: --asp-directory-id (${this.#e.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.#O("Files missing on server:",e.missingFiles),this.#D(e.sizeMismatches),this.#M("Extra files on server:",e.extraUploadedFiles),this.#M("Incomplete uploads on server:",e.incompleteServerFiles)}#O(e,t){if(t.length!==0){console.log(""),console.log(e);for(let r of t.slice(0,Ze))console.log(` - ${r.relativePath} (${this.#_(r.sizeBytes)})`);this.#x(t.length)}}#D(e){if(e.length!==0){console.log(""),console.log("Files with size mismatches:");for(let t of e.slice(0,Ze))console.log(` - ${t.relativePath} (remote ${f(t.remoteSizeBytes)}, server ${f(t.serverSizeBytes)}, asset ${t.assetId})`);this.#x(e.length)}}#M(e,t){if(t.length!==0){console.log(""),console.log(e);for(let r of t.slice(0,Ze))console.log(` - ${r.relativePath} (${f(r.sizeBytes)}, asset ${r.assetId})`);this.#x(t.length)}}#x(e){let t=e-Ze;t>0&&console.log(` ...and ${t} more`)}#_(e){return e===null?"unknown remote size":f(e)}#N(e,t,r,s){e.totalFileCount+=r.totalFileCount,e.successFileCount+=r.successFileCount,e.skippedFileCount+=r.skippedFileCount,e.failedFileCount+=r.failedFileCount,e.cancelledFileCount+=r.cancelledFileCount,e.completedByteCount+=s,t.push(...r.failedFiles)}#S(e){let t=e.failedFileCount+e.cancelledFileCount;if(t>0)throw new Error(`Sync completed with ${t} unsuccessful upload(s)`)}#A(e){return e.failedFileCount+e.cancelledFileCount>0}#B(e){return e.reduce((t,r)=>t+r.size,0)}#U(e,t){return Math.min(e.completedByteCount,t)}};import Ns from"node:fs";import{chmod as Tn,mkdir as zs,writeFile as Gs}from"node:fs/promises";import{stdin as _,stdout as tt}from"node:process";import $s from"node:os";import Ln from"node:path";var kn=448,vn=384,js="https://api.aspect.inc";function Bt(){return Ln.join($s.homedir(),".config","aspect-sync","aspect-auth.json")}function Hs(n=Bt()){let e;try{e=Ns.readFileSync(n,"utf-8")}catch(r){throw r.code==="ENOENT"?qs(n):r}let t;try{t=JSON.parse(e)}catch(r){throw new Error(`Aspect auth file ${n} is not valid JSON: ${r.message}`)}return _n({authFilePath:n,value:t})}function xn(n=Bt()){try{return Hs(n)}catch(e){if(e.code==="ENOENT")return null;throw e}}async function Ws(n,e){_n({authFilePath:n,value:e});let t=Ln.dirname(n);await zs(t,{recursive:!0,mode:kn}),await Tn(t,kn),await Gs(n,`${JSON.stringify(e,null,2)}
22
- `,{encoding:"utf-8",mode:vn}),await Tn(n,vn)}async function Dn(n,e={}){let t=e.prompts??{promptPassword:Vs},s=(n.aspApiKey??await t.promptPassword("Aspect API key: ")).trim();if(!s)throw new Error("--asp-api-key or API key prompt cannot be empty");let o=n.aspApiUrl??js;await(e.validateApiKey??Ks)({apiUrl:o,apiKey:s});let i={apiKey:s};n.aspApiUrl&&(i.apiUrl=n.aspApiUrl),n.aspEdgeWorkerUrl&&(i.edgeWorkerUrl=n.aspEdgeWorkerUrl);let a=n.authFile??Bt();await Ws(a,i),console.log(`Saved Aspect auth to ${a}`)}async function Ks(n){let e=await fetch(new URL("/users/me",n.apiUrl),{headers:{Authorization:`Bearer ${n.apiKey}`}});if(e.ok)return;let t=await e.text();throw new Error(`Aspect API key validation failed: ${e.status} ${e.statusText}${t?` ${t}`:""}`)}function qs(n){let e=new Error(`Error: Aspect API key not found; pass --asp-api-key, set ASPECT_API_KEY, or run aspect-sync login to create ${n}`);return e.code="ENOENT",e}function _n(n){if(!Js(n.value))throw new Error(`Aspect auth file ${n.authFilePath} must contain a non-empty apiKey string`);return n.value}function Js(n){if(!n||typeof n!="object")return!1;let e=n;return Ys(e.apiKey)&&Un(e.apiUrl)&&Un(e.edgeWorkerUrl)}function Ys(n){return typeof n=="string"&&n.length>0}function Un(n){return n===void 0||typeof n=="string"}function Vs(n){if(!_.isTTY||!tt.isTTY)throw new Error("Interactive Aspect API key prompt requires a TTY; provide --asp-api-key");return new Promise((e,t)=>{let r=[],s=_.isRaw,o=()=>{_.off("data",i),_.setRawMode(s),_.pause()},i=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){o(),tt.write(`
21
+ `,"utf-8"),this.#r.blank()}#L(e,t=[]){this.#r.start({kind:"sync",title:e,extraLines:t})}#O(){return this.#e.shard?`${this.#e.shard.index+1}/${this.#e.shard.count} (index ${this.#e.shard.index})`:"disabled"}#U(e){this.#r.printSummary({summary:e.summary,extraLines:e.extraLines})}#M(e){this.#r.log(`Aspect scan: ${e.scannedDirectoryCount}/${e.queuedDirectoryCount} directories, ${e.fileCount} files found`)}#_(e){if(this.#r.isJsonMode)return;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.#e.directoryId?(console.log(""),console.log(`Warning: --asp-directory-id (${this.#e.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.#D("Files missing on server:",e.missingFiles),this.#$(e.sizeMismatches),this.#S("Extra files on server:",e.extraUploadedFiles),this.#S("Incomplete uploads on server:",e.incompleteServerFiles)}#D(e,t){if(t.length!==0){console.log(""),console.log(e);for(let n of t.slice(0,et))console.log(` - ${n.relativePath} (${this.#B(n.sizeBytes)})`);this.#C(t.length)}}#$(e){if(e.length!==0){console.log(""),console.log("Files with size mismatches:");for(let t of e.slice(0,et))console.log(` - ${t.relativePath} (remote ${f(t.remoteSizeBytes)}, server ${f(t.serverSizeBytes)}, asset ${t.assetId})`);this.#C(e.length)}}#S(e,t){if(t.length!==0){console.log(""),console.log(e);for(let n of t.slice(0,et))console.log(` - ${n.relativePath} (${f(n.sizeBytes)}, asset ${n.assetId})`);this.#C(t.length)}}#C(e){let t=e-et;t>0&&console.log(` ...and ${t} more`)}#B(e){return e===null?"unknown remote size":f(e)}#N(e,t,n,s){e.totalFileCount+=n.totalFileCount,e.successFileCount+=n.successFileCount,e.skippedFileCount+=n.skippedFileCount,e.failedFileCount+=n.failedFileCount,e.cancelledFileCount+=n.cancelledFileCount,e.completedByteCount+=s,t.push(...n.failedFiles)}#W(e){let t=e.failedFileCount+e.cancelledFileCount;if(t>0)throw new Error(`Sync completed with ${t} unsuccessful upload(s)`)}#K(e){return e.failedFileCount+e.cancelledFileCount>0}#G(e){return e.reduce((t,n)=>t+n.size,0)}#x(e,t){return Math.min(e.completedByteCount,t)}};async function js(r){if(!Tr.isTTY||!kr.isTTY)return console.warn("Skipping sync confirmation because stdin/stdout is not interactive. Use --yes for non-interactive runs."),!0;console.log(""),console.log("=".repeat(60)),console.log("Confirm Aspect Sync"),console.log("=".repeat(60)),console.log(`Project: ${r.projectName} (${r.projectId})`),console.log(`Directory: ${r.directoryName} (${r.directoryId})`),console.log(`Source: ${r.sourcePath}`),console.log(`Files: ${r.fileCount}`),console.log(`Total size: ${f(r.totalBytes)}`),r.batchCount!==void 0&&r.batchSizeBytes!==void 0&&console.log(`Batches: ${r.batchCount} (max ${f(r.batchSizeBytes)})`),console.log("=".repeat(60));let e=Gs({input:Tr,output:kr});try{return(await e.question("Type 'yes' to start this sync: ")).trim().toLowerCase()==="yes"}finally{e.close()}}import Hs from"node:fs";import{chmod as vr,mkdir as Ws,writeFile as Ks}from"node:fs/promises";import{stdin as _,stdout as rt}from"node:process";import qs from"node:os";import Dr from"node:path";var Lr=448,Ur=384,Js="https://api.aspect.inc";function Ot(){return Dr.join(qs.homedir(),".config","aspect-sync","aspect-auth.json")}function Ys(r=Ot()){let e;try{e=Hs.readFileSync(r,"utf-8")}catch(n){throw n.code==="ENOENT"?Xs(r):n}let t;try{t=JSON.parse(e)}catch(n){throw new Error(`Aspect auth file ${r} is not valid JSON: ${n.message}`)}return Or({authFilePath:r,value:t})}function _r(r=Ot()){try{return Ys(r)}catch(e){if(e.code==="ENOENT")return null;throw e}}async function Vs(r,e){Or({authFilePath:r,value:e});let t=Dr.dirname(r);await Ws(t,{recursive:!0,mode:Lr}),await vr(t,Lr),await Ks(r,`${JSON.stringify(e,null,2)}
22
+ `,{encoding:"utf-8",mode:Ur}),await vr(r,Ur)}async function Br(r,e={}){let t=e.prompts??{promptPassword:to},s=(r.aspApiKey??await t.promptPassword("Aspect API key: ")).trim();if(!s)throw new Error("--asp-api-key or API key prompt cannot be empty");let o=r.aspApiUrl??Js;await(e.validateApiKey??Qs)({apiUrl:o,apiKey:s});let i={apiKey:s};r.aspApiUrl&&(i.apiUrl=r.aspApiUrl),r.aspEdgeWorkerUrl&&(i.edgeWorkerUrl=r.aspEdgeWorkerUrl);let a=r.authFile??Ot();await Vs(a,i),console.log(`Saved Aspect auth to ${a}`)}async function Qs(r){let e=await fetch(new URL("/users/me",r.apiUrl),{headers:{Authorization:`Bearer ${r.apiKey}`}});if(e.ok)return;let t=await e.text();throw new Error(`Aspect API key validation failed: ${e.status} ${e.statusText}${t?` ${t}`:""}`)}function Xs(r){let e=new Error(`Error: Aspect API key not found; pass --asp-api-key, set ASPECT_API_KEY, or run aspect-sync login to create ${r}`);return e.code="ENOENT",e}function Or(r){if(!Zs(r.value))throw new Error(`Aspect auth file ${r.authFilePath} must contain a non-empty apiKey string`);return r.value}function Zs(r){if(!r||typeof r!="object")return!1;let e=r;return eo(e.apiKey)&&xr(e.apiUrl)&&xr(e.edgeWorkerUrl)}function eo(r){return typeof r=="string"&&r.length>0}function xr(r){return r===void 0||typeof r=="string"}function to(r){if(!_.isTTY||!rt.isTTY)throw new Error("Interactive Aspect API key prompt requires a TTY; provide --asp-api-key");return new Promise((e,t)=>{let n=[],s=_.isRaw,o=()=>{_.off("data",i),_.setRawMode(s),_.pause()},i=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){o(),rt.write(`
23
23
  `),t(new Error("Aspect API key prompt cancelled"));return}if(c==="\r"||c===`
24
- `){o(),tt.write(`
25
- `),e(r.join(""));return}if(c==="\x7F"){r.pop();continue}c>=" "&&r.push(c)}};tt.write(n),_.setRawMode(!0),_.resume(),_.on("data",i)})}import{createInterface as vo}from"node:readline/promises";import{stdin as Uo,stdout as Lo}from"node:process";import{Option as Xn}from"commander";import no from"node:fs";import ro from"node:os";import Se from"node:path";import Nn from"node:fs";import{chmod as Bn,mkdir as Qs,writeFile as Xs}from"node:fs/promises";import Zs from"node:os";import zn from"node:path";var On=448,Mn=384;function ye(){return zn.join(Zs.homedir(),".config","aspect-sync","lucidlink-auth.json")}function Gn(n=ye()){let e;try{e=Nn.readFileSync(n,"utf-8")}catch(r){throw r.code==="ENOENT"?eo(n):r}let t;try{t=JSON.parse(e)}catch(r){throw new Error(`LucidLink auth file ${n} is not valid JSON: ${r.message}`)}return Hn({authFilePath:n,value:t})}async function $n(n,e){Hn({authFilePath:n,value:e});let t=zn.dirname(n);await Qs(t,{recursive:!0,mode:On}),await Bn(t,On),await Xs(n,`${JSON.stringify(e,null,2)}
26
- `,{encoding:"utf-8",mode:Mn}),await Bn(n,Mn)}function jn(n){let e=Nn.readFileSync(n,"utf-8").replace(/\r?\n$/,"");if(e.length===0)throw new Error(`Error: LucidLink password file is empty: ${n}`);return e}function eo(n){let e=new Error(`Error: LucidLink auth file not found at ${n}; run aspect-sync lucidlink login before syncing`);return e.code="ENOENT",e}function Hn(n){if(!to(n.value))throw new Error(`LucidLink auth file ${n.authFilePath} must contain non-empty filespace, user, and password strings`);return n.value}function to(n){if(!n||typeof n!="object")return!1;let e=n;return Ot(e.filespace)&&Ot(e.user)&&Ot(e.password)}function Ot(n){return typeof n=="string"&&n.length>0}var so=void 0,oo=void 0,io="https://t.aspect.inc";function Mt(n){let e=n.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);if(!e)return null;let t=parseFloat(e[1]),r=e[2].toUpperCase(),s={B:1,KB:1e3,MB:1e3*1e3,GB:1e3*1e3*1e3,TB:1e3*1e3*1e3*1e3};return t*(s[r]||1)}function Kn(n){return nt({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>Ce(n.options)})}function qn(n){return nt({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>co(n.options)})}function Jn(n){return nt({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:e=>be({options:n.options,localTempDir:e.localTempDir})})}function Yn(n){return nt({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>Ae({options:n.options})})}function nt(n){let e=X({value:n.options.aspDirectoryId,optionName:"--asp-directory-id"}),t=X({value:n.options.aspProjectId,optionName:"--asp-project-id"}),r=lo({options:n.options,environment:n.environment})?xn():null,s=n.options.aspApiKey||n.environment.ASPECT_API_KEY||r?.apiKey||"";if(!s)throw new Error("Error: --asp-api-key is required (or set ASPECT_API_KEY env variable or run aspect-sync login)");let o=B({value:n.options.uploadConcurrent,optionName:"--upload-concurrent"}),i=fo(n.options.batchSize),a=go({shardCount:n.options.shardCount,shardIndex:n.options.shardIndex}),l=n.options.session??yo({now:n.now??new Date,highResolutionTime:n.highResolutionTime??process.hrtime.bigint()}),c=n.options.tempDir||Se.join(ro.homedir(),".aspect","sync"),u=Se.join(c,l);return{source:n.buildSourceConfig({localTempDir:u}),directoryId:e,projectId:t,apiUrl:n.options.aspApiUrl||n.environment.ASPECT_API_URL||r?.apiUrl||"https://api.aspect.inc",edgeWorkerUrl:n.options.aspEdgeWorkerUrl||n.environment.ASPECT_EDGE_WORKER_URL||r?.edgeWorkerUrl||"https://mackinac.aspect.inc",apiKey:s,maxConcurrent:o,keepLocal:n.options.keepLocal,localTempDir:u,sessionName:l,batchSizeBytes:i,shard:a,progressMode:ao(n.options.progress),analytics:{posthogKey:n.environment.ASPECT_POSTHOG_KEY||n.environment.POSTHOG_KEY||n.environment.POSTHOG_API_KEY||so,posthogHost:n.environment.ASPECT_POSTHOG_HOST||n.environment.POSTHOG_HOST||oo||io,disabled:Wn(n.environment.ASPECT_DISABLE_POSTHOG)||Wn(n.environment.POSTHOG_DISABLED)}}}function ao(n){if(n===void 0)return"human";if(n==="human"||n==="json")return n;throw new Error("--progress must be either human or json")}function lo(n){if(!!!(n.options.aspApiKey||n.environment.ASPECT_API_KEY))return!0;let t=!!(n.options.aspApiUrl||n.environment.ASPECT_API_URL),r=!!(n.options.aspEdgeWorkerUrl||n.environment.ASPECT_EDGE_WORKER_URL);return!t||!r}function Ce(n){let e=X({value:n.sourcePath,optionName:"--source-path"});if(!n.remote)throw new Error("Error: --remote is required for rclone");let t=B({value:n.rcloneConcurrentFiles??n.rcloneTransfers??"4",optionName:"--rclone-concurrent-files"}),r=B({value:n.rcloneConcurrentPartsPerFile??n.rcloneMultiThreadStreams??"4",optionName:"--rclone-concurrent-parts-per-file"});return{kind:"rclone",remote:n.remote,remotePath:e,rcloneOptions:{transfers:t,checkers:t>=16?Math.floor(t/4):t,multiThreadStreams:r,multiThreadChunkSize:n.rcloneMultiThreadChunkSize??"64MiB",multiThreadCutoff:n.rcloneMultiThreadCutoff??"64MiB",bufferSize:n.rcloneBufferSize??"64M",useMmap:n.rcloneNoMmap!==!0,extraRcloneArgs:n.rcloneExtra??[]}}}function co(n){let e=X({value:n.sourcePath,optionName:"--source-path"});return{kind:"local",rootPath:Se.resolve(e)}}function be(n){let e=X({value:n.options.sourcePath,optionName:"--source-path"}),t=ye(),r=Gn(t),s=B({value:n.options.lucidInstance??"9001",optionName:"--lucid-instance"}),o=`${n.localTempDir}-lucid`;return{kind:"lucidlink",filespace:r.filespace,user:r.user,password:r.password,filespacePath:mo(e),instanceId:s,workDir:o,mountPoint:Se.join(o,"mnt"),cacheRootPath:Se.join(o,"cache"),cacheSize:n.options.lucidCacheSize}}function Ae(n){let e=X({value:n.options.sourceFolderId,optionName:"--source-folder-id"}),t=V(),r=uo(t);return{kind:"frameio",accountId:r,folderId:e,downloadConcurrency:B({value:n.options.frameioConcurrentFiles??n.options.frameioDownloadConcurrent??"4",optionName:"--frameio-concurrent-files"}),fileDownloadConcurrency:B({value:n.options.frameioConcurrentPartsPerFile??n.options.frameioFileDownloadConcurrent??"1",optionName:"--frameio-concurrent-parts-per-file"}),pageSize:B({value:n.options.frameioPageSize??"100",optionName:"--frameio-page-size"})}}function X(n){if(!n.value)throw new Error(`Error: ${n.optionName} is required`);return n.value}function uo(n){let e;try{e=no.readFileSync(n,"utf-8")}catch(r){throw r.code==="ENOENT"?new Error(`Error: Frame.io auth file not found at ${n}; run aspect-sync frameio login before syncing`):r}let t=JSON.parse(e);if(!po(t))throw new Error(`Error: Frame.io sync requires a default account ID in ${n}; run aspect-sync frameio login to select a default account, or add defaultAccountId to the auth file.`);return t.defaultAccountId}function po(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.defaultAccountId=="string"&&e.defaultAccountId.length>0}function mo(n){let e=n.replace(/^\/+/,"").replace(/\/+$/,"");if(e.split("/").some(t=>t===".."))throw new Error(`Error: --source-path cannot contain parent directory segments: ${n}`);return e}function B(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 ho(n){let e=parseInt(n.value,10);if(Number.isNaN(e)||e<0)throw new Error(`Error: ${n.optionName} must be a non-negative integer`);return e}function fo(n){if(!n)return;let e=Mt(n);if(e===null)throw new Error(`Error: Invalid batch size format: ${n}`);return e}function go(n){if(!n.shardCount&&!n.shardIndex)return;if(!n.shardCount||!n.shardIndex)throw new Error("Error: --shard-count and --shard-index must be provided together");let e=B({value:n.shardCount,optionName:"--shard-count"}),t=ho({value:n.shardIndex,optionName:"--shard-index"});if(t>=e)throw new Error("Error: --shard-index must be less than --shard-count");return{count:e,index:t}}function Wn(n){return n?["1","true","yes"].includes(n.toLowerCase()):!1}function yo(n){let e=n.now.getFullYear(),t=String(n.now.getMonth()+1).padStart(2,"0"),r=String(n.now.getDate()).padStart(2,"0"),s=String(n.now.getHours()).padStart(2,"0"),o=String(n.now.getMinutes()).padStart(2,"0"),i=String(n.now.getSeconds()).padStart(2,"0"),a=n.highResolutionTime%1000000000n,l=String(a).padStart(9,"0");return`${e}-${t}-${r}_${s}h-${o}m-${i}s-${l}ns`}import{createReadStream as So}from"node:fs";import{mkdir as Nt,rm as zt,writeFile as Co}from"node:fs/promises";import bo from"node:os";import Fe from"node:path";var Ao=20;function P(n){let e=n.session??ko(n.commandName),t=n.tempDir??Fe.join(bo.homedir(),".aspect","sync");return{sessionName:e,localTempDir:Fe.join(t,e)}}function R(n,e){let t=parseInt(n,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function Z(n,e){if(!n)return;let t=Mt(n);if(t===null)throw new Error(`${e} must be a size like 500MB, 10GB, or 1TB`);return t}async function ee(n){let e=Q(n.sourceConfig);try{console.log(`Doctor: ${e.displayName}`),await Vn(n.localTempDir),console.log(`Writable temp path: ${n.localTempDir}`);for(let r of Ro(n.sourceConfig))await Vn(r),console.log(`Writable cache path: ${r}`);for(let r of n.tuningWarnings??[])console.warn(`Warning: ${r}`);await e.prepare(),console.log("Source prepared");let t=await Gt(e);Qn(t.changes),console.log(`Source root access: OK (${t.files.length} files, ${f(rt(t.files))})`),console.log("Doctor checks passed")}finally{try{await zt(n.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function te(n){let e=Q(n.sourceConfig);try{await e.prepare();let t=await Gt(e);Qn(t.changes),Fo({source:e,files:t.files,sampleSize:n.sampleSize??Ao})}finally{await e.shutdown()}}async function ne(n){let e=Q(n.sourceConfig);try{await e.prepare();let t=await Gt(e),r=Io({files:t.files,maxFiles:n.maxFiles,maxBytes:n.maxBytes});if(r.length===0)throw new Error("No source files available to probe");console.log(`Probe source: ${e.displayName}`),console.log(`Probe files: ${r.length}`),console.log(`Probe size: ${f(rt(r))}`);let s=Date.now(),o=await wo({source:e,sourceConfig:n.sourceConfig,files:r,localTempDir:n.localTempDir}),i=Math.max((Date.now()-s)/1e3,.001);console.log(`Probe complete: ${f(o)} in ${i.toFixed(2)}s (${Qe(o/i)})`)}finally{try{n.keepLocal!==!0&&await zt(n.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function Gt(n){console.log(`Listing source files from ${n.displayName}...`);let e=await n.listFiles();return Ue(e)}function Fo(n){console.log(`Source: ${n.source.displayName}`),console.log(`Files: ${n.files.length}`),console.log(`Total size: ${f(rt(n.files))}`);let e=n.files.slice(0,n.sampleSize);if(e.length===0)return;console.log("Sample paths:");for(let r of e)console.log(`- ${To(r)} (${f(r.size)})`);let t=n.files.length-e.length;t>0&&console.log(`...and ${t} more`)}function Qn(n){if(n.length===0)return;let e=n.slice(0,10).map(s=>`${s.sourcePath} -> ${s.targetPath}`).join(`
27
- `),t=n.length-10,r=t>0?`
28
- ...and ${t} more renamed target path(s)`:"";console.warn(`Warning: ${n.length} remote file path(s) were renamed for Aspect compatibility.
29
- ${e}${r}
30
- `)}async function wo(n){await Nt(n.localTempDir,{recursive:!0});let e=Fe.join(n.localTempDir,"probe"),t=Fe.join(n.localTempDir,"probe-files.txt");if(Eo(n.sourceConfig))return await Nt(e,{recursive:!0}),await n.source.materializeBatch({files:n.files,batchDir:e,batchFilePath:t}),rt(n.files);let r=0;for(let s of n.files){let o=n.source.resolveLocalFile(s,e);r+=await Po(o.absolutePath)}return r}function Eo(n){switch(n.kind){case"rclone":case"frameio":return!0;case"local":case"lucidlink":return!1;default:{let e=n;throw new Error(`Unsupported source kind: ${JSON.stringify(e)}`)}}}async function Po(n){return await new Promise((e,t)=>{let r=So(n),s=0;r.on("data",o=>{s+=Buffer.isBuffer(o)?o.length:Buffer.byteLength(o)}),r.on("error",t),r.on("end",()=>e(s))})}function Io(n){let e=[],t=0;for(let r of n.files){if(e.length>=n.maxFiles||n.maxBytes!==void 0&&e.length>0&&t+r.size>n.maxBytes)break;e.push(r),t+=r.size}return e}async function Vn(n){await Nt(n,{recursive:!0});let e=Fe.join(n,`.aspect-sync-write-test-${process.pid}-${Date.now()}`);await Co(e,"","utf-8"),await zt(e,{force:!0})}function Ro(n){return n.kind!=="lucidlink"?[]:[n.cacheRootPath]}function To(n){let e=A(n);return e===n.path?e:`${n.path} -> ${e}`}function rt(n){return n.reduce((e,t)=>e+t.size,0)}function ko(n){let e=new Date().toISOString().replace(/[:.]/g,"-");return`${n}-${e}`}function tr(n){let e=n.command("frameio").description("Frame.io auth, discovery, and bandwidth diagnostics");e.command("login").description("Authenticate to Frame.io V4 via Adobe OAuth PKCE and store refresh credentials").option("--client-id <id>","Adobe OAuth client ID",Sn()).action(async s=>{await xo(s)}),e.command("accounts").description("List Frame.io accounts accessible to the current token").action(async s=>{let i=await(await st(s)).listAccounts();ot(i)}),e.command("workspaces").description("List workspaces in the login-selected Frame.io account").action(async s=>{let o=await st(s),i=await jt(s),a=await o.listWorkspaces(i);ot(a)}),e.command("projects").description("List Frame.io projects in the login-selected account").option("--workspace-id <id>","Optionally scope projects to a Frame.io workspace ID").option("--page-size <number>","Frame.io page size","100").action(async s=>{let o=await st(s),i=await jt(s),a=er(s.pageSize,"--page-size"),l=s.workspaceId?await o.listProjects({accountId:i,workspaceId:s.workspaceId,pageSize:a}):await o.listAccountProjects({accountId:i,pageSize:a});ot(l)}),e.command("folders").description("List children in a Frame.io folder in the login-selected account").requiredOption("--folder-id <id>","Frame.io folder ID").option("--page-size <number>","Frame.io page size","100").action(async s=>{let o=await st(s),i=await jt(s),a=await o.listFolderChildren({accountId:i,folderId:s.folderId,pageSize:er(s.pageSize,"--page-size")});ot(a)});let t=$t(e.command("doctor").description("Check Frame.io auth, account, and source folder access"));Zn(t).action(async s=>{let o=P({tempDir:s.tempDir,session:s.session,commandName:"frameio-doctor"});await ee({sourceConfig:Ae({options:s}),localTempDir:o.localTempDir})}),$t(e.command("list").description("List planned Frame.io source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20").action(async s=>{await te({sourceConfig:Ae({options:s}),sampleSize:R(s.sampleSize,"--sample-size")})});let r=$t(e.command("probe").description("Measure Frame.io original download throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to download for the probe","1").option("--max-bytes <size>","Soft maximum bytes to download for the probe").option("--keep-local","Keep downloaded probe files in the temp directory",!1);Zn(r).action(async s=>{let o=P({tempDir:s.tempDir,session:s.session,commandName:"frameio-probe"});await ne({sourceConfig:Ae({options:s}),localTempDir:o.localTempDir,maxFiles:R(s.maxFiles,"--max-files"),maxBytes:Z(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}function $t(n){return n.requiredOption("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-concurrent-files <number>","Concurrent Frame.io file downloads").option("--frameio-concurrent-parts-per-file <number>","Concurrent range downloads per Frame.io file when supported").option("--frameio-page-size <number>","Frame.io folder listing page size","100").addOption(new Xn("--frameio-download-concurrent <number>").hideHelp()).addOption(new Xn("--frameio-file-download-concurrent <number>").hideHelp())}function Zn(n){return n.option("--temp-dir <path>","Local temporary directory for helper downloads and checks").option("--session <name>","Session name for helper temp paths")}async function xo(n){let e=Cn(),t=bn({clientId:n.clientId,codeChallenge:e.challenge});console.log("Open this URL in a browser and approve access:"),console.log(t),console.log("");let r=await nr("Paste the full redirected URL or code: "),s=An(r),o=await Fn({clientId:n.clientId,code:s,codeVerifier:e.verifier}),a=await new G({token:o.access_token}).listAccounts(),l=await Do({accounts:a}),c=V();await Ut(c,Lt({clientId:n.clientId,token:o,defaultAccountId:l})),console.log(`Saved Frame.io auth to ${c}`)}async function st(n){let e=await We();return new G({token:e})}async function jt(n){let e=V(),t=await vt(e);if(t.defaultAccountId)return t.defaultAccountId;throw new Error("Frame.io default account ID is missing; run aspect-sync frameio login.")}async function Do(n){if(n.accounts.length===0)throw new Error("Frame.io login did not return any accessible accounts");let e=n.writeOutput??(r=>console.log(r));if(n.accounts.length===1){let r=n.accounts[0];return e(`Selected default Frame.io account: ${Ht(r)}`),r.id}let t=n.promptForInput??nr;for(e("Select the default Frame.io account for sync:"),n.accounts.forEach((r,s)=>{e(`${s+1}. ${Ht(r)}`)});;){let r=(await t("Account number or ID: ")).trim(),s=_o(n.accounts,r);if(s)return e(`Selected default Frame.io account: ${Ht(s)}`),s.id;e("Invalid account selection. Enter a listed number or account ID.")}}async function nr(n){let e=vo({input:Uo,output:Lo});try{return await e.question(n)}finally{e.close()}}function _o(n,e){let t=Number.parseInt(e,10);return String(t)===e&&t>=1&&t<=n.length?n[t-1]:n.find(r=>r.id===e)}function Ht(n){let e=n.display_name?.trim();return e?`${e} (${n.id})`:n.id}function er(n,e){let t=parseInt(n,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function ot(n){console.log(JSON.stringify(n,null,2))}import{stdin as T,stdout as we}from"node:process";import{createInterface as Bo}from"node:readline/promises";import{mkdir as rr,mkdtemp as Oo,rm as Mo}from"node:fs/promises";import No from"node:os";import Wt from"node:path";function or(n){let e=n.command("lucidlink").description("LucidLink auth and diagnostics");e.command("login").description("Validate LucidLink credentials and store reusable auth").option("--filespace <filespace>","LucidLink filespace identifier: <filespace>.<workspace>").option("--user <user>","LucidLink filespace user").option("--password-file <path>","File containing the LucidLink password").option("--instance <number>","LucidLink daemon instance ID for validation","9001").action(async o=>{await zo(o)});let t=Kt(e.command("doctor").description("Check LucidLink runner readiness and source access"));qt(t).action(async o=>{let i=P({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-doctor"});await ee({sourceConfig:be({options:o,localTempDir:i.localTempDir}),localTempDir:i.localTempDir,tuningWarnings:Jo(o)})});let r=Kt(e.command("list").description("List planned LucidLink source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20");qt(r).action(async o=>{let i=P({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-list"});await te({sourceConfig:be({options:o,localTempDir:i.localTempDir}),sampleSize:R(o.sampleSize,"--sample-size")})});let s=Kt(e.command("probe").description("Measure LucidLink source read throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to read for the probe","1").option("--max-bytes <size>","Soft maximum bytes to read for the probe").option("--keep-local","Keep helper temp files in the temp directory",!1);qt(s).action(async o=>{let i=P({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-probe"});await ne({sourceConfig:be({options:o,localTempDir:i.localTempDir}),localTempDir:i.localTempDir,maxFiles:R(o.maxFiles,"--max-files"),maxBytes:Z(o.maxBytes,"--max-bytes"),keepLocal:o.keepLocal})})}async function zo(n,e={}){let t=e.prompts??Ho(),r=await sr({value:n.filespace,optionName:"--filespace",promptMessage:"LucidLink filespace (<filespace>.<workspace>): ",promptText:t.promptText}),s=await sr({value:n.user,optionName:"--user",promptMessage:"LucidLink user: ",promptText:t.promptText}),o=n.passwordFile?jn(n.passwordFile):await jo(t.promptPassword),i={filespace:r,user:s,password:o},a=n.authFile??ye(),l=qo(n.instance,"--instance");console.log(`Validating LucidLink filespace ${r}...`),await Go({authFile:i,instanceId:l,createDaemon:e.createDaemon}),await $n(a,i),console.log(`Saved LucidLink auth to ${a}`)}async function Go(n){let e=await Oo(Wt.join(No.tmpdir(),"aspect-sync-lucidlink-login-")),t=Wt.join(e,"mnt"),r=Wt.join(e,"cache"),o=(n.createDaemon??(a=>new Y(a)))({filespace:n.authFile.filespace,user:n.authFile.user,password:n.authFile.password,instanceId:n.instanceId,mountPoint:t,cacheRootPath:r}),i;try{await o.checkClientInstalled(),await rr(t,{recursive:!0}),await rr(r,{recursive:!0}),await o.start()}catch(a){throw i=a,a}finally{try{await $o({daemon:o,validationError:i})}finally{await Mo(e,{recursive:!0,force:!0})}}}async function $o(n){try{await n.daemon.stop()}catch(e){if(!n.validationError)throw e;console.error(`Failed to stop LucidLink validation daemon: ${e.message}`)}}async function sr(n){let t=(n.value??await n.promptText(n.promptMessage)).trim();if(!t)throw new Error(`${n.optionName} cannot be empty`);return t}async function jo(n){let e=await n("LucidLink password: ");if(!e)throw new Error("--password-file or password prompt cannot be empty");return e}function Ho(){return{promptText:Wo,promptPassword:Ko}}async function Wo(n){let e=Bo({input:T,output:we});try{return await e.question(n)}finally{e.close()}}function Ko(n){if(!T.isTTY||!we.isTTY)throw new Error("Interactive LucidLink password prompt requires a TTY; provide --password-file");return new Promise((e,t)=>{let r=[],s=T.isRaw,o=()=>{T.off("data",i),T.setRawMode(s),T.pause()},i=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){o(),we.write(`
24
+ `){o(),rt.write(`
25
+ `),e(n.join(""));return}if(c==="\x7F"){n.pop();continue}c>=" "&&n.push(c)}};rt.write(r),_.setRawMode(!0),_.resume(),_.on("data",i)})}import{createInterface as _o}from"node:readline/promises";import{stdin as Bo,stdout as Oo}from"node:process";import{Option as en}from"commander";import ao from"node:fs";import lo from"node:os";import Se from"node:path";import $r from"node:fs";import{chmod as Mr,mkdir as ro,writeFile as no}from"node:fs/promises";import so from"node:os";import Gr from"node:path";var Nr=448,zr=384;function ye(){return Gr.join(so.homedir(),".config","aspect-sync","lucidlink-auth.json")}function jr(r=ye()){let e;try{e=$r.readFileSync(r,"utf-8")}catch(n){throw n.code==="ENOENT"?oo(r):n}let t;try{t=JSON.parse(e)}catch(n){throw new Error(`LucidLink auth file ${r} is not valid JSON: ${n.message}`)}return Kr({authFilePath:r,value:t})}async function Hr(r,e){Kr({authFilePath:r,value:e});let t=Gr.dirname(r);await ro(t,{recursive:!0,mode:Nr}),await Mr(t,Nr),await no(r,`${JSON.stringify(e,null,2)}
26
+ `,{encoding:"utf-8",mode:zr}),await Mr(r,zr)}function Wr(r){let e=$r.readFileSync(r,"utf-8").replace(/\r?\n$/,"");if(e.length===0)throw new Error(`Error: LucidLink password file is empty: ${r}`);return e}function oo(r){let e=new Error(`Error: LucidLink auth file not found at ${r}; run aspect-sync lucidlink login before syncing`);return e.code="ENOENT",e}function Kr(r){if(!io(r.value))throw new Error(`LucidLink auth file ${r.authFilePath} must contain non-empty filespace, user, and password strings`);return r.value}function io(r){if(!r||typeof r!="object")return!1;let e=r;return Mt(e.filespace)&&Mt(e.user)&&Mt(e.password)}function Mt(r){return typeof r=="string"&&r.length>0}var co=void 0,uo=void 0,po="https://t.aspect.inc";function Nt(r){let e=r.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);if(!e)return null;let t=parseFloat(e[1]),n=e[2].toUpperCase(),s={B:1,KB:1e3,MB:1e3*1e3,GB:1e3*1e3*1e3,TB:1e3*1e3*1e3*1e3};return t*(s[n]||1)}function Jr(r){return nt({options:r.options,environment:r.environment,now:r.now,highResolutionTime:r.highResolutionTime,buildSourceConfig:()=>Ce(r.options)})}function Yr(r){return nt({options:r.options,environment:r.environment,now:r.now,highResolutionTime:r.highResolutionTime,buildSourceConfig:()=>fo(r.options)})}function Vr(r){return nt({options:r.options,environment:r.environment,now:r.now,highResolutionTime:r.highResolutionTime,buildSourceConfig:e=>be({options:r.options,localTempDir:e.localTempDir})})}function Qr(r){return nt({options:r.options,environment:r.environment,now:r.now,highResolutionTime:r.highResolutionTime,buildSourceConfig:()=>Ae({options:r.options})})}function nt(r){let e=X({value:r.options.aspDirectoryId,optionName:"--asp-directory-id"}),t=X({value:r.options.aspProjectId,optionName:"--asp-project-id"}),n=ho({options:r.options,environment:r.environment})?_r():null,s=r.options.aspApiKey||r.environment.ASPECT_API_KEY||n?.apiKey||"";if(!s)throw new Error("Error: --asp-api-key is required (or set ASPECT_API_KEY env variable or run aspect-sync login)");let o=B({value:r.options.uploadConcurrent,optionName:"--upload-concurrent"}),i=bo(r.options.batchSize),a=Ao({shardCount:r.options.shardCount,shardIndex:r.options.shardIndex}),l=r.options.session??Fo({now:r.now??new Date,highResolutionTime:r.highResolutionTime??process.hrtime.bigint()}),c=r.options.tempDir||Se.join(lo.homedir(),".aspect","sync"),u=Se.join(c,l);return{source:r.buildSourceConfig({localTempDir:u}),directoryId:e,projectId:t,apiUrl:r.options.aspApiUrl||r.environment.ASPECT_API_URL||n?.apiUrl||"https://api.aspect.inc",edgeWorkerUrl:r.options.aspEdgeWorkerUrl||r.environment.ASPECT_EDGE_WORKER_URL||n?.edgeWorkerUrl||"https://mackinac.aspect.inc",apiKey:s,maxConcurrent:o,keepLocal:r.options.keepLocal,localTempDir:u,sessionName:l,batchSizeBytes:i,shard:a,skipConfirmation:r.options.yes===!0,progressMode:mo(r.options.progress),analytics:{posthogKey:r.environment.ASPECT_POSTHOG_KEY||r.environment.POSTHOG_KEY||r.environment.POSTHOG_API_KEY||co,posthogHost:r.environment.ASPECT_POSTHOG_HOST||r.environment.POSTHOG_HOST||uo||po,disabled:qr(r.environment.ASPECT_DISABLE_POSTHOG)||qr(r.environment.POSTHOG_DISABLED)}}}function mo(r){if(r===void 0)return"human";if(r==="human"||r==="json")return r;throw new Error("--progress must be either human or json")}function ho(r){if(!!!(r.options.aspApiKey||r.environment.ASPECT_API_KEY))return!0;let t=!!(r.options.aspApiUrl||r.environment.ASPECT_API_URL),n=!!(r.options.aspEdgeWorkerUrl||r.environment.ASPECT_EDGE_WORKER_URL);return!t||!n}function Ce(r){let e=X({value:r.sourcePath,optionName:"--source-path"});if(!r.remote)throw new Error("Error: --remote is required for rclone");let t=B({value:r.rcloneConcurrentFiles??r.rcloneTransfers??"4",optionName:"--rclone-concurrent-files"}),n=B({value:r.rcloneConcurrentPartsPerFile??r.rcloneMultiThreadStreams??"4",optionName:"--rclone-concurrent-parts-per-file"});return{kind:"rclone",remote:r.remote,remotePath:e,rcloneOptions:{transfers:t,checkers:t>=16?Math.floor(t/4):t,multiThreadStreams:n,multiThreadChunkSize:r.rcloneMultiThreadChunkSize??"64MiB",multiThreadCutoff:r.rcloneMultiThreadCutoff??"64MiB",bufferSize:r.rcloneBufferSize??"64M",useMmap:r.rcloneNoMmap!==!0,extraRcloneArgs:r.rcloneExtra??[]}}}function fo(r){let e=X({value:r.sourcePath,optionName:"--source-path"});return{kind:"local",rootPath:Se.resolve(e)}}function be(r){let e=X({value:r.options.sourcePath,optionName:"--source-path"}),t=ye(),n=jr(t),s=B({value:r.options.lucidInstance??"9001",optionName:"--lucid-instance"}),o=`${r.localTempDir}-lucid`;return{kind:"lucidlink",filespace:n.filespace,user:n.user,password:n.password,filespacePath:So(e),instanceId:s,workDir:o,mountPoint:Se.join(o,"mnt"),cacheRootPath:Se.join(o,"cache"),cacheSize:r.options.lucidCacheSize}}function Ae(r){let e=X({value:r.options.sourceFolderId,optionName:"--source-folder-id"}),t=V(),n=go(t);return{kind:"frameio",accountId:n,folderId:e,downloadConcurrency:B({value:r.options.frameioConcurrentFiles??r.options.frameioDownloadConcurrent??"4",optionName:"--frameio-concurrent-files"}),fileDownloadConcurrency:B({value:r.options.frameioConcurrentPartsPerFile??r.options.frameioFileDownloadConcurrent??"1",optionName:"--frameio-concurrent-parts-per-file"}),pageSize:B({value:r.options.frameioPageSize??"100",optionName:"--frameio-page-size"})}}function X(r){if(!r.value)throw new Error(`Error: ${r.optionName} is required`);return r.value}function go(r){let e;try{e=ao.readFileSync(r,"utf-8")}catch(n){throw n.code==="ENOENT"?new Error(`Error: Frame.io auth file not found at ${r}; run aspect-sync frameio login before syncing`):n}let t=JSON.parse(e);if(!yo(t))throw new Error(`Error: Frame.io sync requires a default account ID in ${r}; run aspect-sync frameio login to select a default account, or add defaultAccountId to the auth file.`);return t.defaultAccountId}function yo(r){if(!r||typeof r!="object")return!1;let e=r;return typeof e.defaultAccountId=="string"&&e.defaultAccountId.length>0}function So(r){let e=r.replace(/^\/+/,"").replace(/\/+$/,"");if(e.split("/").some(t=>t===".."))throw new Error(`Error: --source-path cannot contain parent directory segments: ${r}`);return e}function B(r){let e=parseInt(r.value,10);if(Number.isNaN(e)||e<1)throw new Error(`Error: ${r.optionName} must be a positive integer`);return e}function Co(r){let e=parseInt(r.value,10);if(Number.isNaN(e)||e<0)throw new Error(`Error: ${r.optionName} must be a non-negative integer`);return e}function bo(r){if(!r)return;let e=Nt(r);if(e===null)throw new Error(`Error: Invalid batch size format: ${r}`);return e}function Ao(r){if(!r.shardCount&&!r.shardIndex)return;if(!r.shardCount||!r.shardIndex)throw new Error("Error: --shard-count and --shard-index must be provided together");let e=B({value:r.shardCount,optionName:"--shard-count"}),t=Co({value:r.shardIndex,optionName:"--shard-index"});if(t>=e)throw new Error("Error: --shard-index must be less than --shard-count");return{count:e,index:t}}function qr(r){return r?["1","true","yes"].includes(r.toLowerCase()):!1}function Fo(r){let e=r.now.getFullYear(),t=String(r.now.getMonth()+1).padStart(2,"0"),n=String(r.now.getDate()).padStart(2,"0"),s=String(r.now.getHours()).padStart(2,"0"),o=String(r.now.getMinutes()).padStart(2,"0"),i=String(r.now.getSeconds()).padStart(2,"0"),a=r.highResolutionTime%1000000000n,l=String(a).padStart(9,"0");return`${e}-${t}-${n}_${s}h-${o}m-${i}s-${l}ns`}import{createReadStream as wo}from"node:fs";import{mkdir as zt,rm as $t,writeFile as Eo}from"node:fs/promises";import Io from"node:os";import Fe from"node:path";var Po=20;function I(r){let e=r.session??Do(r.commandName),t=r.tempDir??Fe.join(Io.homedir(),".aspect","sync");return{sessionName:e,localTempDir:Fe.join(t,e)}}function R(r,e){let t=parseInt(r,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function Z(r,e){if(!r)return;let t=Nt(r);if(t===null)throw new Error(`${e} must be a size like 500MB, 10GB, or 1TB`);return t}async function ee(r){let e=Q(r.sourceConfig);try{console.log(`Doctor: ${e.displayName}`),await Xr(r.localTempDir),console.log(`Writable temp path: ${r.localTempDir}`);for(let n of Uo(r.sourceConfig))await Xr(n),console.log(`Writable cache path: ${n}`);for(let n of r.tuningWarnings??[])console.warn(`Warning: ${n}`);await e.prepare(),console.log("Source prepared");let t=await Gt(e);Zr(t.changes),console.log(`Source root access: OK (${t.files.length} files, ${f(st(t.files))})`),console.log("Doctor checks passed")}finally{try{await $t(r.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function te(r){let e=Q(r.sourceConfig);try{await e.prepare();let t=await Gt(e);Zr(t.changes),Ro({source:e,files:t.files,sampleSize:r.sampleSize??Po})}finally{await e.shutdown()}}async function re(r){let e=Q(r.sourceConfig);try{await e.prepare();let t=await Gt(e),n=Lo({files:t.files,maxFiles:r.maxFiles,maxBytes:r.maxBytes});if(n.length===0)throw new Error("No source files available to probe");console.log(`Probe source: ${e.displayName}`),console.log(`Probe files: ${n.length}`),console.log(`Probe size: ${f(st(n))}`);let s=Date.now(),o=await To({source:e,sourceConfig:r.sourceConfig,files:n,localTempDir:r.localTempDir}),i=Math.max((Date.now()-s)/1e3,.001);console.log(`Probe complete: ${f(o)} in ${i.toFixed(2)}s (${Xe(o/i)})`)}finally{try{r.keepLocal!==!0&&await $t(r.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function Gt(r){console.log(`Listing source files from ${r.displayName}...`);let e=await r.listFiles();return Le(e)}function Ro(r){console.log(`Source: ${r.source.displayName}`),console.log(`Files: ${r.files.length}`),console.log(`Total size: ${f(st(r.files))}`);let e=r.files.slice(0,r.sampleSize);if(e.length===0)return;console.log("Sample paths:");for(let n of e)console.log(`- ${xo(n)} (${f(n.size)})`);let t=r.files.length-e.length;t>0&&console.log(`...and ${t} more`)}function Zr(r){if(r.length===0)return;let e=r.slice(0,10).map(s=>`${s.sourcePath} -> ${s.targetPath}`).join(`
27
+ `),t=r.length-10,n=t>0?`
28
+ ...and ${t} more renamed target path(s)`:"";console.warn(`Warning: ${r.length} remote file path(s) were renamed for Aspect compatibility.
29
+ ${e}${n}
30
+ `)}async function To(r){await zt(r.localTempDir,{recursive:!0});let e=Fe.join(r.localTempDir,"probe"),t=Fe.join(r.localTempDir,"probe-files.txt");if(ko(r.sourceConfig))return await zt(e,{recursive:!0}),await r.source.materializeBatch({files:r.files,batchDir:e,batchFilePath:t}),st(r.files);let n=0;for(let s of r.files){let o=r.source.resolveLocalFile(s,e);n+=await vo(o.absolutePath)}return n}function ko(r){switch(r.kind){case"rclone":case"frameio":return!0;case"local":case"lucidlink":return!1;default:{let e=r;throw new Error(`Unsupported source kind: ${JSON.stringify(e)}`)}}}async function vo(r){return await new Promise((e,t)=>{let n=wo(r),s=0;n.on("data",o=>{s+=Buffer.isBuffer(o)?o.length:Buffer.byteLength(o)}),n.on("error",t),n.on("end",()=>e(s))})}function Lo(r){let e=[],t=0;for(let n of r.files){if(e.length>=r.maxFiles||r.maxBytes!==void 0&&e.length>0&&t+n.size>r.maxBytes)break;e.push(n),t+=n.size}return e}async function Xr(r){await zt(r,{recursive:!0});let e=Fe.join(r,`.aspect-sync-write-test-${process.pid}-${Date.now()}`);await Eo(e,"","utf-8"),await $t(e,{force:!0})}function Uo(r){return r.kind!=="lucidlink"?[]:[r.cacheRootPath]}function xo(r){let e=A(r);return e===r.path?e:`${r.path} -> ${e}`}function st(r){return r.reduce((e,t)=>e+t.size,0)}function Do(r){let e=new Date().toISOString().replace(/[:.]/g,"-");return`${r}-${e}`}function nn(r){let e=r.command("frameio").description("Frame.io auth, discovery, and bandwidth diagnostics");e.command("login").description("Authenticate to Frame.io V4 via Adobe OAuth PKCE and store refresh credentials").option("--client-id <id>","Adobe OAuth client ID",Sr()).action(async s=>{await Mo(s)}),e.command("accounts").description("List Frame.io accounts accessible to the current token").action(async s=>{let i=await(await ot(s)).listAccounts();it(i)}),e.command("workspaces").description("List workspaces in the login-selected Frame.io account").action(async s=>{let o=await ot(s),i=await Ht(s),a=await o.listWorkspaces(i);it(a)}),e.command("projects").description("List Frame.io projects in the login-selected account").option("--workspace-id <id>","Optionally scope projects to a Frame.io workspace ID").option("--page-size <number>","Frame.io page size","100").action(async s=>{let o=await ot(s),i=await Ht(s),a=rn(s.pageSize,"--page-size"),l=s.workspaceId?await o.listProjects({accountId:i,workspaceId:s.workspaceId,pageSize:a}):await o.listAccountProjects({accountId:i,pageSize:a});it(l)}),e.command("folders").description("List children in a Frame.io folder in the login-selected account").requiredOption("--folder-id <id>","Frame.io folder ID").option("--page-size <number>","Frame.io page size","100").action(async s=>{let o=await ot(s),i=await Ht(s),a=await o.listFolderChildren({accountId:i,folderId:s.folderId,pageSize:rn(s.pageSize,"--page-size")});it(a)});let t=jt(e.command("doctor").description("Check Frame.io auth, account, and source folder access"));tn(t).action(async s=>{let o=I({tempDir:s.tempDir,session:s.session,commandName:"frameio-doctor"});await ee({sourceConfig:Ae({options:s}),localTempDir:o.localTempDir})}),jt(e.command("list").description("List planned Frame.io source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20").action(async s=>{await te({sourceConfig:Ae({options:s}),sampleSize:R(s.sampleSize,"--sample-size")})});let n=jt(e.command("probe").description("Measure Frame.io original download throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to download for the probe","1").option("--max-bytes <size>","Soft maximum bytes to download for the probe").option("--keep-local","Keep downloaded probe files in the temp directory",!1);tn(n).action(async s=>{let o=I({tempDir:s.tempDir,session:s.session,commandName:"frameio-probe"});await re({sourceConfig:Ae({options:s}),localTempDir:o.localTempDir,maxFiles:R(s.maxFiles,"--max-files"),maxBytes:Z(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}function jt(r){return r.requiredOption("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-concurrent-files <number>","Concurrent Frame.io file downloads").option("--frameio-concurrent-parts-per-file <number>","Concurrent range downloads per Frame.io file when supported").option("--frameio-page-size <number>","Frame.io folder listing page size","100").addOption(new en("--frameio-download-concurrent <number>").hideHelp()).addOption(new en("--frameio-file-download-concurrent <number>").hideHelp())}function tn(r){return r.option("--temp-dir <path>","Local temporary directory for helper downloads and checks").option("--session <name>","Session name for helper temp paths")}async function Mo(r){let e=Cr(),t=br({clientId:r.clientId,codeChallenge:e.challenge});console.log("Open this URL in a browser and approve access:"),console.log(t),console.log("");let n=await sn("Paste the full redirected URL or code: "),s=Ar(n),o=await Fr({clientId:r.clientId,code:s,codeVerifier:e.verifier}),a=await new $({token:o.access_token}).listAccounts(),l=await No({accounts:a}),c=V();await Lt(c,Ut({clientId:r.clientId,token:o,defaultAccountId:l})),console.log(`Saved Frame.io auth to ${c}`)}async function ot(r){let e=await Ke();return new $({token:e})}async function Ht(r){let e=V(),t=await vt(e);if(t.defaultAccountId)return t.defaultAccountId;throw new Error("Frame.io default account ID is missing; run aspect-sync frameio login.")}async function No(r){if(r.accounts.length===0)throw new Error("Frame.io login did not return any accessible accounts");let e=r.writeOutput??(n=>console.log(n));if(r.accounts.length===1){let n=r.accounts[0];return e(`Selected default Frame.io account: ${Wt(n)}`),n.id}let t=r.promptForInput??sn;for(e("Select the default Frame.io account for sync:"),r.accounts.forEach((n,s)=>{e(`${s+1}. ${Wt(n)}`)});;){let n=(await t("Account number or ID: ")).trim(),s=zo(r.accounts,n);if(s)return e(`Selected default Frame.io account: ${Wt(s)}`),s.id;e("Invalid account selection. Enter a listed number or account ID.")}}async function sn(r){let e=_o({input:Bo,output:Oo});try{return await e.question(r)}finally{e.close()}}function zo(r,e){let t=Number.parseInt(e,10);return String(t)===e&&t>=1&&t<=r.length?r[t-1]:r.find(n=>n.id===e)}function Wt(r){let e=r.display_name?.trim();return e?`${e} (${r.id})`:r.id}function rn(r,e){let t=parseInt(r,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function it(r){console.log(JSON.stringify(r,null,2))}import{stdin as T,stdout as we}from"node:process";import{createInterface as $o}from"node:readline/promises";import{mkdir as on,mkdtemp as Go,rm as jo}from"node:fs/promises";import Ho from"node:os";import Kt from"node:path";function ln(r){let e=r.command("lucidlink").description("LucidLink auth and diagnostics");e.command("login").description("Validate LucidLink credentials and store reusable auth").option("--filespace <filespace>","LucidLink filespace identifier: <filespace>.<workspace>").option("--user <user>","LucidLink filespace user").option("--password-file <path>","File containing the LucidLink password").option("--instance <number>","LucidLink daemon instance ID for validation","9001").action(async o=>{await Wo(o)});let t=qt(e.command("doctor").description("Check LucidLink runner readiness and source access"));Jt(t).action(async o=>{let i=I({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-doctor"});await ee({sourceConfig:be({options:o,localTempDir:i.localTempDir}),localTempDir:i.localTempDir,tuningWarnings:Zo(o)})});let n=qt(e.command("list").description("List planned LucidLink source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20");Jt(n).action(async o=>{let i=I({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-list"});await te({sourceConfig:be({options:o,localTempDir:i.localTempDir}),sampleSize:R(o.sampleSize,"--sample-size")})});let s=qt(e.command("probe").description("Measure LucidLink source read throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to read for the probe","1").option("--max-bytes <size>","Soft maximum bytes to read for the probe").option("--keep-local","Keep helper temp files in the temp directory",!1);Jt(s).action(async o=>{let i=I({tempDir:o.tempDir,session:o.session,commandName:"lucidlink-probe"});await re({sourceConfig:be({options:o,localTempDir:i.localTempDir}),localTempDir:i.localTempDir,maxFiles:R(o.maxFiles,"--max-files"),maxBytes:Z(o.maxBytes,"--max-bytes"),keepLocal:o.keepLocal})})}async function Wo(r,e={}){let t=e.prompts??Yo(),n=await an({value:r.filespace,optionName:"--filespace",promptMessage:"LucidLink filespace (<filespace>.<workspace>): ",promptText:t.promptText}),s=await an({value:r.user,optionName:"--user",promptMessage:"LucidLink user: ",promptText:t.promptText}),o=r.passwordFile?Wr(r.passwordFile):await Jo(t.promptPassword),i={filespace:n,user:s,password:o},a=r.authFile??ye(),l=Xo(r.instance,"--instance");console.log(`Validating LucidLink filespace ${n}...`),await Ko({authFile:i,instanceId:l,createDaemon:e.createDaemon}),await Hr(a,i),console.log(`Saved LucidLink auth to ${a}`)}async function Ko(r){let e=await Go(Kt.join(Ho.tmpdir(),"aspect-sync-lucidlink-login-")),t=Kt.join(e,"mnt"),n=Kt.join(e,"cache"),o=(r.createDaemon??(a=>new Y(a)))({filespace:r.authFile.filespace,user:r.authFile.user,password:r.authFile.password,instanceId:r.instanceId,mountPoint:t,cacheRootPath:n}),i;try{await o.checkClientInstalled(),await on(t,{recursive:!0}),await on(n,{recursive:!0}),await o.start()}catch(a){throw i=a,a}finally{try{await qo({daemon:o,validationError:i})}finally{await jo(e,{recursive:!0,force:!0})}}}async function qo(r){try{await r.daemon.stop()}catch(e){if(!r.validationError)throw e;console.error(`Failed to stop LucidLink validation daemon: ${e.message}`)}}async function an(r){let t=(r.value??await r.promptText(r.promptMessage)).trim();if(!t)throw new Error(`${r.optionName} cannot be empty`);return t}async function Jo(r){let e=await r("LucidLink password: ");if(!e)throw new Error("--password-file or password prompt cannot be empty");return e}function Yo(){return{promptText:Vo,promptPassword:Qo}}async function Vo(r){let e=$o({input:T,output:we});try{return await e.question(r)}finally{e.close()}}function Qo(r){if(!T.isTTY||!we.isTTY)throw new Error("Interactive LucidLink password prompt requires a TTY; provide --password-file");return new Promise((e,t)=>{let n=[],s=T.isRaw,o=()=>{T.off("data",i),T.setRawMode(s),T.pause()},i=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){o(),we.write(`
31
31
  `),t(new Error("LucidLink password prompt cancelled"));return}if(c==="\r"||c===`
32
32
  `){o(),we.write(`
33
- `),e(r.join(""));return}if(c==="\x7F"){r.pop();continue}c>=" "&&r.push(c)}};we.write(n),T.setRawMode(!0),T.resume(),T.on("data",i)})}function qo(n,e){let t=parseInt(n,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function Kt(n){return n.requiredOption("--source-path <path>","path within the LucidLink filespace").option("--lucid-instance <number>","LucidLink daemon instance ID","9001").option("--lucid-cache-size <size>","LucidLink DataCache.Size applied after mount")}function qt(n){return n.option("--temp-dir <path>","Local temporary directory for helper reads and checks").option("--session <name>","Session name for helper temp paths")}function Jo(n){return n.lucidCacheSize?[]:["--lucid-cache-size is not set; LucidLink will use its current local cache configuration."]}import{spawn as Yo}from"node:child_process";import{Option as ir}from"commander";function lr(n){let e=n.command("rclone").description("rclone auth validation and source diagnostics");e.command("login").description("Validate a native rclone remote for reuse by aspect-sync").requiredOption("--remote <remote>","rclone remote name (e.g., dropbox)").action(async s=>{await Vo(s)});let t=Jt(e.command("doctor").description("Check rclone runner readiness and source access"));ar(t).action(async s=>{let o=P({tempDir:s.tempDir,session:s.session,commandName:"rclone-doctor"});await ee({sourceConfig:Ce(s),localTempDir:o.localTempDir,tuningWarnings:Qo(s)})}),Jt(e.command("list").description("List planned rclone source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20").action(async s=>{await te({sourceConfig:Ce(s),sampleSize:R(s.sampleSize,"--sample-size")})});let r=Jt(e.command("probe").description("Measure rclone source download throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to download for the probe","1").option("--max-bytes <size>","Soft maximum bytes to download for the probe").option("--keep-local","Keep downloaded probe files in the temp directory",!1);ar(r).action(async s=>{let o=P({tempDir:s.tempDir,session:s.session,commandName:"rclone-probe"});await ne({sourceConfig:Ce(s),localTempDir:o.localTempDir,maxFiles:R(s.maxFiles,"--max-files"),maxBytes:Z(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}async function Vo(n){await Me(),await Xo(n.remote),console.log(`rclone remote "${n.remote}" is configured and ready for aspect-sync.`)}function Jt(n){return n.requiredOption("--remote <remote>","rclone remote name (e.g., dropbox)").requiredOption("--source-path <path>","path within the rclone remote").option("--rclone-concurrent-files <number>","Concurrent rclone file downloads").option("--rclone-concurrent-parts-per-file <number>","Concurrent rclone streams per large file").option("--rclone-multi-thread-chunk-size <size>","Chunk size for multi-threading","64MiB").option("--rclone-multi-thread-cutoff <size>","Minimum file size for multi-threading","64MiB").option("--rclone-buffer-size <size>","Buffer size per transfer","64M").option("--rclone-no-mmap","Disable memory-mapped I/O",!1).option("--rclone-extra <arg>","Additional rclone argument to append (repeatable)",(e,t)=>(t??[]).concat(e),[]).addOption(new ir("--rclone-transfers <number>").hideHelp()).addOption(new ir("--rclone-multi-thread-streams <number>").hideHelp())}function ar(n){return n.option("--temp-dir <path>","Local temporary directory for helper downloads and checks").option("--session <name>","Session name for helper temp paths")}function Qo(n){let e=[],t=Number.parseInt(n.rcloneConcurrentFiles??n.rcloneTransfers??"4",10);return Number.isFinite(t)&&t>=32&&e.push("--rclone-concurrent-files is high; confirm the source provider and runner network can sustain this concurrency."),n.rcloneNoMmap===!0&&e.push("--rclone-no-mmap reduces memory efficiency and should only be used for known mmap issues."),e}function Xo(n){return new Promise((e,t)=>{let r=Yo("rclone",["config","show",n],{stdio:["ignore","pipe","pipe"]}),s="";r.stderr?.on("data",o=>{s+=o.toString()}),r.on("close",o=>{if(o===0){e();return}t(new Error(`rclone remote "${n}" is not configured or could not be loaded. Run "rclone config" to create or repair the remote, then rerun "aspect-sync rclone login --remote ${n}".`+(s.trim()?`
34
- ${s.trim()}`:"")))}),r.on("error",o=>{t(new Error(`Failed to start rclone config validation: ${o.message}`))})})}import{Option as it}from"commander";function cr(n,e){let t=n.command("sync").description("Sync files from a source into Aspect");Zo(t,e),ei(t,e),ti(t,e),ni(t,e)}function Zo(n,e){at(n.command("rclone").description("Sync from an rclone remote")).option("--remote <remote>","rclone remote name (e.g., dropbox)").option("--source-path <path>","path within the rclone remote to sync").option("--rclone-concurrent-files <number>","Concurrent rclone file downloads (default: 4)").option("--rclone-concurrent-parts-per-file <number>","Concurrent rclone streams per large file (default: 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 x 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)",(r,s)=>(s??[]).concat(r),[]).addOption(new it("--rclone-transfers <number>").hideHelp()).addOption(new it("--rclone-multi-thread-streams <number>").hideHelp()).action(async r=>{await e({commandOptions:r,buildConfig:s=>Kn({options:r,environment:s})})})}function ei(n,e){at(n.command("local").description("Sync from a local directory")).option("--source-path <path>","local directory to sync").action(async r=>{await e({commandOptions:r,buildConfig:s=>qn({options:r,environment:s})})})}function ti(n,e){at(n.command("lucidlink").description("Sync from a LucidLink filespace")).option("--source-path <path>","path within the LucidLink filespace to sync").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)").action(async r=>{await e({commandOptions:r,buildConfig:s=>Jn({options:r,environment:s})})})}function ni(n,e){at(n.command("frameio").description("Sync from a Frame.io folder")).option("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-concurrent-files <number>","Concurrent Frame.io file downloads (default: 4)").option("--frameio-concurrent-parts-per-file <number>","Concurrent range downloads per Frame.io file when supported (default: 1)").option("--frameio-page-size <number>","Frame.io folder listing page size (default: 100)","100").addOption(new it("--frameio-download-concurrent <number>").hideHelp()).addOption(new it("--frameio-file-download-concurrent <number>").hideHelp()).action(async r=>{await e({commandOptions:r,buildConfig:s=>Yn({options:r,environment:s})})})}function at(n){return n.option("--asp-directory-id <id>","Aspect directory ID to upload to").option("--asp-project-id <id>","Aspect project ID").option("--asp-api-url <url>","Aspect API URL").option("--asp-edge-worker-url <url>","Aspect edge worker URL").option("--asp-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("--shard-count <number>","Split the planned file list across this many concurrent sessions").option("--shard-index <number>","Zero-based shard index for this session").option("--progress <human|json>","Progress output mode. json emits one NDJSON event per line.","human")}var pr=oi(import.meta.url),ii=dr.dirname(pr),mr=JSON.parse(si(dr.join(ii,"..","package.json"),"utf-8"));function ai(n={}){let e=new ri;return e.name("aspect-sync").description("Sync files from external services to Aspect").version(n.packageVersion??mr.version),e.command("login").description("Store Aspect API credentials for sync commands").option("--asp-api-key <key>","Aspect API key").option("--asp-api-url <url>","Aspect API URL").option("--asp-edge-worker-url <url>","Aspect edge worker URL").action(async t=>{await Dn(t)}),tr(e),or(e),lr(e),cr(e,n.executeSyncCommand??li(n)),e}function li(n){return async e=>{await ci({execution:e,environment:n.getEnvironment?.()??ui()})}}async function ci(n){let e=0;try{let t=n.execution.buildConfig(n.environment),r=di(t),s=await pi(t,r);s&&rn({config:t,packageVersion:mr.version,user:s});let o=new et(t,r);n.execution.commandOptions.check?await o.runCheckOnly():t.batchSizeBytes!==void 0?await o.runBatched():await o.run()}catch(t){console.error("Fatal error:",t),e=1}finally{await on()}process.exit(e)}function ui(){return{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,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}}mi()&&await ai().parseAsync();function di(n){return new x({apiUrl:n.apiUrl,apiKey:n.apiKey,edgeWorkerUrl:n.edgeWorkerUrl,sessionId:n.sessionName})}async function pi(n,e){return n.analytics.disabled||!n.analytics.posthogKey?null:await e.get("/users/me")}function mi(){let n=process.argv[1];return n===void 0?!1:ur(n)===ur(pr)}export{ai as createProgram};
33
+ `),e(n.join(""));return}if(c==="\x7F"){n.pop();continue}c>=" "&&n.push(c)}};we.write(r),T.setRawMode(!0),T.resume(),T.on("data",i)})}function Xo(r,e){let t=parseInt(r,10);if(Number.isNaN(t)||t<1)throw new Error(`${e} must be a positive integer`);return t}function qt(r){return r.requiredOption("--source-path <path>","path within the LucidLink filespace").option("--lucid-instance <number>","LucidLink daemon instance ID","9001").option("--lucid-cache-size <size>","LucidLink DataCache.Size applied after mount")}function Jt(r){return r.option("--temp-dir <path>","Local temporary directory for helper reads and checks").option("--session <name>","Session name for helper temp paths")}function Zo(r){return r.lucidCacheSize?[]:["--lucid-cache-size is not set; LucidLink will use its current local cache configuration."]}import{spawn as ei}from"node:child_process";import{Option as cn}from"commander";function dn(r){let e=r.command("rclone").description("rclone auth validation and source diagnostics");e.command("login").description("Validate a native rclone remote for reuse by aspect-sync").requiredOption("--remote <remote>","rclone remote name (e.g., dropbox)").action(async s=>{await ti(s)});let t=Yt(e.command("doctor").description("Check rclone runner readiness and source access"));un(t).action(async s=>{let o=I({tempDir:s.tempDir,session:s.session,commandName:"rclone-doctor"});await ee({sourceConfig:Ce(s),localTempDir:o.localTempDir,tuningWarnings:ri(s)})}),Yt(e.command("list").description("List planned rclone source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20").action(async s=>{await te({sourceConfig:Ce(s),sampleSize:R(s.sampleSize,"--sample-size")})});let n=Yt(e.command("probe").description("Measure rclone source download throughput without uploading to Aspect")).option("--max-files <number>","Maximum files to download for the probe","1").option("--max-bytes <size>","Soft maximum bytes to download for the probe").option("--keep-local","Keep downloaded probe files in the temp directory",!1);un(n).action(async s=>{let o=I({tempDir:s.tempDir,session:s.session,commandName:"rclone-probe"});await re({sourceConfig:Ce(s),localTempDir:o.localTempDir,maxFiles:R(s.maxFiles,"--max-files"),maxBytes:Z(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}async function ti(r){await Me(),await ni(r.remote),console.log(`rclone remote "${r.remote}" is configured and ready for aspect-sync.`)}function Yt(r){return r.requiredOption("--remote <remote>","rclone remote name (e.g., dropbox)").requiredOption("--source-path <path>","path within the rclone remote").option("--rclone-concurrent-files <number>","Concurrent rclone file downloads").option("--rclone-concurrent-parts-per-file <number>","Concurrent rclone streams per large file").option("--rclone-multi-thread-chunk-size <size>","Chunk size for multi-threading","64MiB").option("--rclone-multi-thread-cutoff <size>","Minimum file size for multi-threading","64MiB").option("--rclone-buffer-size <size>","Buffer size per transfer","64M").option("--rclone-no-mmap","Disable memory-mapped I/O",!1).option("--rclone-extra <arg>","Additional rclone argument to append (repeatable)",(e,t)=>(t??[]).concat(e),[]).addOption(new cn("--rclone-transfers <number>").hideHelp()).addOption(new cn("--rclone-multi-thread-streams <number>").hideHelp())}function un(r){return r.option("--temp-dir <path>","Local temporary directory for helper downloads and checks").option("--session <name>","Session name for helper temp paths")}function ri(r){let e=[],t=Number.parseInt(r.rcloneConcurrentFiles??r.rcloneTransfers??"4",10);return Number.isFinite(t)&&t>=32&&e.push("--rclone-concurrent-files is high; confirm the source provider and runner network can sustain this concurrency."),r.rcloneNoMmap===!0&&e.push("--rclone-no-mmap reduces memory efficiency and should only be used for known mmap issues."),e}function ni(r){return new Promise((e,t)=>{let n=ei("rclone",["config","show",r],{stdio:["ignore","pipe","pipe"]}),s="";n.stderr?.on("data",o=>{s+=o.toString()}),n.on("close",o=>{if(o===0){e();return}t(new Error(`rclone remote "${r}" is not configured or could not be loaded. Run "rclone config" to create or repair the remote, then rerun "aspect-sync rclone login --remote ${r}".`+(s.trim()?`
34
+ ${s.trim()}`:"")))}),n.on("error",o=>{t(new Error(`Failed to start rclone config validation: ${o.message}`))})})}import{Option as at}from"commander";function pn(r,e){let t=r.command("sync").description("Sync files from a source into Aspect");si(t,e),oi(t,e),ii(t,e),ai(t,e)}function si(r,e){lt(r.command("rclone").description("Sync from an rclone remote")).option("--remote <remote>","rclone remote name (e.g., dropbox)").option("--source-path <path>","path within the rclone remote to sync").option("--rclone-concurrent-files <number>","Concurrent rclone file downloads (default: 4)").option("--rclone-concurrent-parts-per-file <number>","Concurrent rclone streams per large file (default: 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 x 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,s)=>(s??[]).concat(n),[]).addOption(new at("--rclone-transfers <number>").hideHelp()).addOption(new at("--rclone-multi-thread-streams <number>").hideHelp()).action(async n=>{await e({commandOptions:n,buildConfig:s=>Jr({options:n,environment:s})})})}function oi(r,e){lt(r.command("local").description("Sync from a local directory")).option("--source-path <path>","local directory to sync").action(async n=>{await e({commandOptions:n,buildConfig:s=>Yr({options:n,environment:s})})})}function ii(r,e){lt(r.command("lucidlink").description("Sync from a LucidLink filespace")).option("--source-path <path>","path within the LucidLink filespace to sync").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)").action(async n=>{await e({commandOptions:n,buildConfig:s=>Vr({options:n,environment:s})})})}function ai(r,e){lt(r.command("frameio").description("Sync from a Frame.io folder")).option("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-concurrent-files <number>","Concurrent Frame.io file downloads (default: 4)").option("--frameio-concurrent-parts-per-file <number>","Concurrent range downloads per Frame.io file when supported (default: 1)").option("--frameio-page-size <number>","Frame.io folder listing page size (default: 100)","100").addOption(new at("--frameio-download-concurrent <number>").hideHelp()).addOption(new at("--frameio-file-download-concurrent <number>").hideHelp()).action(async n=>{await e({commandOptions:n,buildConfig:s=>Qr({options:n,environment:s})})})}function lt(r){return r.option("--asp-directory-id <id>","Aspect directory ID to upload to").option("--asp-project-id <id>","Aspect project ID").option("--asp-api-url <url>","Aspect API URL").option("--asp-edge-worker-url <url>","Aspect edge worker URL").option("--asp-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("--shard-count <number>","Split the planned file list across this many concurrent sessions").option("--shard-index <number>","Zero-based shard index for this session").option("--progress <human|json>","Progress output mode. json emits one NDJSON event per line.","human").option("--yes","Skip the interactive sync confirmation prompt",!1)}var fn=ui(import.meta.url),di=hn.dirname(fn),gn=JSON.parse(ci(hn.join(di,"..","package.json"),"utf-8"));function pi(r={}){let e=new li;return e.name("aspect-sync").description("Sync files from external services to Aspect").version(r.packageVersion??gn.version),e.command("login").description("Store Aspect API credentials for sync commands").option("--asp-api-key <key>","Aspect API key").option("--asp-api-url <url>","Aspect API URL").option("--asp-edge-worker-url <url>","Aspect edge worker URL").action(async t=>{await Br(t)}),nn(e),ln(e),dn(e),pn(e,r.executeSyncCommand??mi(r)),e}function mi(r){return async e=>{await hi({execution:e,environment:r.getEnvironment?.()??fi()})}}async function hi(r){let e=0;try{let t=r.execution.buildConfig(r.environment),n=gi(t),s=await yi(t,n);s&&sr({config:t,packageVersion:gn.version,user:s});let o=new tt(t,n);r.execution.commandOptions.check?await o.runCheckOnly():t.batchSizeBytes!==void 0?await o.runBatched():await o.run()}catch(t){console.error("Fatal error:",t),e=1}finally{await ir()}process.exit(e)}function fi(){return{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,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}}Si()&&await pi().parseAsync();function gi(r){return new x({apiUrl:r.apiUrl,apiKey:r.apiKey,edgeWorkerUrl:r.edgeWorkerUrl,sessionId:r.sessionName})}async function yi(r,e){return r.analytics.disabled||!r.analytics.posthogKey?null:await e.get("/users/me")}function Si(){let r=process.argv[1];return r===void 0?!1:mn(r)===mn(fn)}export{pi as createProgram};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aspect-sync",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "CLI tool to sync files from external services to Aspect via rclone",
5
5
  "main": "dist/index.js",
6
6
  "bin": {