aspect-sync 0.1.29 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +17 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as si}from"commander";import Ot from"node:path";import{readFileSync as ii}from"node:fs";import{fileURLToPath as oi}from"node:url";import ue from"node:fs/promises";import wt from"node:path";import Nn from"fs/promises";import zn from"path";function Bt(n,e){let t=new Map;for(let c of n){let u=zn.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,g)=>m+g.size,0);r.set(c,d)}let s=Array.from(t.keys()).sort(),i=[],o=[],a=0,l=1;for(let c of s){let u=t.get(c),d=r.get(c);if(d>e){if(o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),u.length===1)i.push({batchNumber:l++,files:u,totalSize:d});else for(let m of u)a+m.size>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(m),a+=m.size;continue}a+d>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(...u),a+=d}return o.length>0&&i.push({batchNumber:l++,files:o,totalSize:a}),i}async function Mt(n){try{await Nn.unlink(n)}catch(e){if(e.code!=="ENOENT")throw e}}import f from"chalk";import zt from"log-update";function be(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 et(n,e){let t=be(n,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function tt(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 nt(n){for(let e of Object.values(n))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function Z(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 rt(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 st(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 it(n){return Object.values(n).some(e=>e.status==="paused")}import wi from"axios";var ee=class{#t;#n;#e;#r;#s;#i=0;#a=0;#c=0;#o=0;#u=0;#m=0;constructor(e){this.#t=e?.alphaFast??.1,this.#n=e?.alphaMax??.5,this.#e=e?.consecutiveForBoost??3,this.#r=e?.minSamples??3,this.#s=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#o===0){this.#o=t,this.#u=e;return}let s=(t-this.#o)/1e3,i=e-this.#u;if(s<=0||i<0)return;if(s>this.#s){this.#o=t,this.#u=e;return}let o=i/s;if(this.#m===0)this.#i=o;else{let l=o-this.#i>=0?1:-1;this.#c!==0&&l===this.#c?this.#a++:this.#a=0,this.#c=l;let c=Math.min(1,this.#a/this.#e),u=this.#t+(this.#n-this.#t)*c;this.#i=u*o+(1-u)*this.#i}this.#o=t,this.#u=e,this.#m++}etaSeconds(e){return!this.isWarmedUp||this.#i<=0?0:e/this.#i}adjustTotalBytes(e){this.#u+=e}reset(){this.#i=0,this.#a=0,this.#c=0,this.#o=0,this.#u=0,this.#m=0}serialize(){return{displaySpeedBps:this.#i,lastSampleTimestamp:this.#o,lastSampleTotalBytes:this.#u,sampleCount:this.#m}}get speedBps(){return this.#i}get speedMbps(){return this.#i*8/1e6}get isWarmedUp(){return this.#m>=this.#r}};function D(n){let e={"X-Aspect-Share-Id":n.shareId};return n.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=n.shareAuthentication),e}var te=class{#t;#n;#e;#r;#s;#i;#a;#c;#o;#u;#m;#l;#D;#g;#A;#k;#b;#S;#P;#R;#I;#h;#C;#E;#d;#T;#f;#F;#L;#_;#x;#O;constructor(e){this.#n=e?.minConcurrency??1,this.#e=e?.maxConcurrency??8,this.#t=this.#H(e?.initialConcurrency??this.#n),this.#r=e?.errorThreshold??1,this.#s=(e?.cooldownSeconds??10)*1e3,this.#i=e?.plateauThreshold??.05,this.#a=Math.max(this.#e,Math.floor(e?.sampleWindowSize??64)),this.#c=Math.max(2,Math.floor(e?.minSamples??4)),this.#o=Math.max(1.1,e?.increaseFactor??1.5),this.#u=e?.onChange,this.#m=e?.now??Date.now,this.#l=this.#t,this.#D=0,this.#g=[],this.#A=0,this.#k=0,this.#b=-1,this.#S=0,this.#P=void 0,this.#R=0,this.#I=0,this.#h=0,this.#C=this.#l,this.#E=0,this.#d=1/0,this.#T=0,this.#f=6e4,this.#F=0,this.#L=1/0,this.#_=0,this.#x=0,this.#O=0}recordSuccess(e,t,r){if(e<=0)return;if(r?.generation!==void 0){if(r.generation!==this.#D){r.generation===this.#b&&this.#S>0&&(this.#S--,this.#S===0&&(this.#P=r.completedAtMs??this.#m()));return}if(this.#S>0||this.#P!==void 0&&r.startedAtMs!==void 0&&r.startedAtMs<this.#P)return}else if(this.#k>0){this.#k--;return}let s=r?.completedAtMs??this.#m();for(this.#g.push({bytes:e,completedAtMs:s,startedAtMs:r?.startedAtMs,durationMs:t!==void 0&&t>0?t:void 0});this.#g.length>this.#a;)this.#g.shift();this.#A++,this.#R=0;let i=this.#M();this.#x=i.throughputBps,this.#O=i.latencyMsPerMB,this.#U(i)}recordError(){if(this.#R++,this.#R<this.#r)return;let e=this.#l;e===this.#F&&(this.#L=Math.min(this.#L,e),this.#_=this.#m()+3e4),this.#F=e;let t=this.#H(Math.floor(e/2));this.#I=this.#m()+this.#s,this.#R=0,e<=this.#C&&(this.#C=t,this.#E=0),e>t&&(this.#d=Math.min(this.#d,e),this.#W()),this.#w(t)}get concurrency(){return this.#l}get generation(){return this.#D}get speedBps(){return this.#x}get latencyMsPerMB(){return this.#O}reset(){this.#l=this.#t,this.#D++,this.#g=[],this.#A=0,this.#k=0,this.#b=-1,this.#S=0,this.#P=void 0,this.#R=0,this.#I=0,this.#h=0,this.#C=this.#l,this.#E=0,this.#d=1/0,this.#T=0,this.#f=6e4,this.#F=0,this.#L=1/0,this.#_=0,this.#x=0,this.#O=0,this.#u?.(this.#l)}#U(e){if(this.#g.length<this.#q()||this.#A<this.#q()||e.throughputBps<=0)return;let t=this.#m();if(t<this.#I)return;if(e.averageDurationMs>=2e4&&this.#l>=4){this.#C=Math.max(this.#n,Math.floor(this.#l/2)),this.#E=0,this.#w(this.#C);return}if(this.#E===0){this.#B(e.throughputBps),this.#v(e);return}let r=(e.throughputBps-this.#E)/this.#E;if(r>=this.#i){this.#B(e.throughputBps),this.#v(e);return}if(this.#l>this.#C){let s=r<=-.08,i=r<this.#i;(s||i)&&(this.#d=Math.min(this.#d,this.#l),this.#W(),this.#w(this.#C));return}if(this.#l<this.#C){this.#v(e);return}this.#l===this.#C&&(this.#E=Math.max(this.#E,e.throughputBps),t>=this.#h&&this.#v(e))}#v(e){let t=this.#V();if(this.#l>=t){this.#A=0;return}if(e.averageDurationMs>=5e3&&this.#l>=4&&this.#E>0){this.#A=0;return}if(this.#G()){let s=this.#m();if(this.#T===0){this.#T=s+this.#f,this.#h=this.#T,this.#A=0;return}if(s<this.#T){this.#A=0;return}}let r=this.#p(t);if(r===this.#l){this.#A=0;return}this.#w(r)}#B(e){this.#C=this.#l,this.#E=e,this.#d<=this.#l&&(this.#d=1/0),this.#T=0,this.#f=6e4,this.#h=0}#p(e){if(this.#d<1/0){let s=Math.floor((this.#l+this.#d)/2);return s>this.#l&&s<this.#d?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.#o),r=this.#l+2;return Math.min(e,Math.max(r,t))}#w(e){let t=this.#l,r=this.#D,s=this.#H(e);s!==t&&(this.#N(),this.#l=s,this.#D++,this.#b=r,this.#S=Math.max(0,t-1),this.#P=this.#S===0?this.#m():void 0,this.#k=Math.max(0,t-1),this.#u?.(this.#l))}#N(){this.#g=[],this.#A=0,this.#k=0}#G(){return this.#d<1/0&&this.#l===this.#C&&this.#d<=this.#C+1}#W(){let e=this.#d<1/0&&this.#d<=this.#C+1,t=e?this.#f:1e4;this.#h=this.#m()+t,e&&(this.#T=this.#h,this.#f=Math.min(this.#f*2,3e5))}#q(){return Math.max(this.#c,this.#l)}#V(){return this.#L<1/0&&this.#m()>=this.#_&&(this.#L=1/0,this.#_=0),Math.max(this.#n,Math.min(this.#e,this.#L-1))}#H(e){return Math.max(this.#n,Math.min(this.#e,e))}#M(){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 i=this.#g[0],a=this.#g[this.#g.length-1].completedAtMs-i.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 N=class{#t;#n;#e;#r;#s;constructor(e){let t=e===0?null:e;this.#t=t,this.#n=t??0,this.#e=Date.now(),this.#r=[],this.#s=null}setLimit(e){let t=e===0?null:e;if(t===null){this.#t=null,this.#n=0,this.#u();let s=this.#r.splice(0);for(let i of s)i.resolve();return}let r=this.#t;this.#t=t,r===null?(this.#n=t,this.#e=Date.now()):(this.#i(),this.#n=Math.min(this.#n,t)),this.#o()}getLimit(){return this.#t}acquire(e){if(this.#t!==null){if(this.#i(),this.#r.length===0&&this.#n>=e){this.#n-=e;return}return this.#a(e)}}#i(){let e=Date.now(),t=(e-this.#e)/1e3;if(t<=0)return;let r=this.#t,s=t*r,i=this.#r.length>0?Math.max(r,this.#r[0].bytes):r;this.#n=Math.min(this.#n+s,i),this.#e=e}#a(e){return new Promise(t=>{this.#r.push({bytes:e,resolve:t}),this.#s===null&&this.#c()})}#c(){if(this.#r.length===0||this.#t===null){this.#s=null;return}let t=this.#r[0].bytes-this.#n,r=t>0?Math.ceil(t/this.#t*1e3):0;if(r<=0){this.#s=null,this.#o();return}this.#s=setTimeout(()=>{this.#s=null,this.#i(),this.#o()},r)}#o(){for(;this.#r.length>0;){if(this.#t===null){let t=this.#r.splice(0);for(let r of t)r.resolve();return}this.#i();let e=this.#r[0];if(this.#n>=e.bytes)this.#n-=e.bytes,this.#r.shift(),e.resolve();else{this.#c();return}}}#u(){this.#s!==null&&(clearTimeout(this.#s),this.#s=null)}};function Nt(n){let e=`[${n}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var ot=Nt("transfer");var Ae=class{uploadAssets={};uploadGroups={};#t=new ee;get uploadSpeedState(){return this.#t.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#n(e){e!==0&&this.#t.adjustTotalBytes(-e)}adjustSpeedBaselineForSkippedBytes(e){e!==0&&this.#t.adjustTotalBytes(e)}#e(){Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress")||this.#t.reset()}#r(e){this.dirtyAssetIds.add(e)}#s(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:r,parentId:s,projectId:i,groupId:o,chunkSize:a,shareContext:l}){this.uploadAssets[e]={assetId:e,totalBytesToUpload:t.size,bytesUploaded:0,status:"queued",fileName:t.name,createdAt:new Date().toISOString(),i:Object.keys(this.uploadAssets).length,parentId:s,projectId:i,groupId:o,retryCount:0,chunkSize:a??0,fileReader:t,abortController:r,shareContext:l},this.#r(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,i=Math.min(t,r.totalBytesToUpload);r.bytesUploaded=i,r.status=s,this.#r(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#r(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#r(e),this.#e(),this.cleanupOnCompletion(e))}markUploadFailed(e,t){let r=this.uploadAssets[e];if(!r)return;let s=r.bytesUploaded;r.status="failed",r.errorMessage=t,r.bytesUploaded=0,this.#r(e),this.#n(s),this.#e(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let r=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#r(e),this.#n(r),this.#e()}clearAllUploads(){this.uploadAssets={},this.#t.reset()}clearTerminalState(){if(!Object.values(this.uploadAssets).some(t=>t.status==="queued"||t.status==="in-progress"||t.status==="paused")){for(let t of Object.keys(this.uploadAssets))delete this.uploadAssets[t];for(let t of Object.keys(this.uploadGroups))delete this.uploadGroups[t];this.#t.reset()}}resetAssetForRetryQueue(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.errorMessage=void 0,t.retryCount=t.retryCount+1,this.#r(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#r(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let r=0;if(t.chunkedState){let{completedChunkIndices:i,chunkSize:o}=t.chunkedState;for(let a of i){let l=a*o,c=Math.min(l+o,t.totalBytesToUpload);r+=c-l}}let s=t.bytesUploaded-r;t.status="paused",t.bytesUploaded=r,this.#r(e),this.#n(s),this.#e(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#r(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#s(e);for(let r of t.assetIds)this.pauseUpload(r)}}unpauseUploadGroup(e){let t=this.uploadGroups[e];t&&(t.isPaused=!1,this.#s(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.#r(e),this.#n(r),this.#e(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let r=this.uploadAssets[e];r&&(r.chunkedState=t,this.#r(e))}addCompletedChunkIndex(e,t){let r=this.uploadAssets[e];!r||!r.chunkedState||(r.chunkedState={...r.chunkedState,completedChunkIndices:[...r.chunkedState.completedChunkIndices,t]},this.#r(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#r(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return st(this.uploadAssets)}hasPausedUploads(){return it(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#c(t)}getUploadSummary(){return Z(this.#u())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#c(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.#c(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.#s(t),t}updateUploadGroup(e,t){let r=this.uploadGroups[e];r&&(Object.assign(r,t),this.#s(e))}addAssetToGroup(e,t){let r=this.uploadGroups[e];r&&(r.assetIds.push(t),this.#s(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.#s(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.#r(r);delete this.uploadGroups[e],this.#s(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#o(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#o(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return rt(this.#o(t),r)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return be(this.#o(t),r)}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#c(t))}getActiveUploadGroups(){return Object.values(this.uploadGroups).filter(e=>{let t=this.getUploadGroupStatus(e.id);return t&&["queued","creating-folders","in-progress"].includes(t)}).map(e=>this.#o(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let r=t.groupId;if(r){let i=this.uploadGroups[r];if(i){let o=this.getGroupAssets(r),a=this.#o(i);this.dirtyHistoryGroupIds.add(r),!o.some(c=>c.status==="queued"||c.status==="in-progress")&&!i.completedAt&&(i.completedAt=new Date().toISOString(),this.#s(r))}}let s=this.getUploadSummary();if(s.cancelledAssetCount+s.failedAssetCount+s.successAssetCount===s.totalAssetCount)for(let i of Object.keys(this.uploadAssets)){let o=this.uploadAssets[i];o&&(o.bytesUploaded=0,this.#r(i))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#t.sample(e.totalBytesUploaded);let r=this.#t.isWarmedUp?this.#t.speedMbps:0,s=t&&this.#t.isWarmedUp?this.#t.etaSeconds(e.totalBytesToUpload-e.totalBytesUploaded):0;this.uploadStats={uploadSpeedMbps:r,timeRemainingSeconds:s,formattedSpeed:this.#i(r),formattedTime:this.#a(s)}}#i(e){return!Number.isFinite(e)||e<=0?"Calculating...":e<1?`${(e*1e3).toFixed(0)} Kbps`:`${e.toFixed(1)} Mbps`}#a(e){if(!Number.isFinite(e)||e<=0)return"Calculating...";let t=Math.floor(e/3600),r=Math.floor(e%3600/60),s=Math.floor(e%60);return t>0?`${t}h ${r}m left`:r>0?`${r}m ${s}s left`:`${s}s left`}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e),s=this.#o(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:et(s,r),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#c({fileReader:e,abortController:t,shareContext:r,...s}){return s}#o({fileReaders:e,...t}){return t}#u(){let e={};for(let[t,r]of Object.entries(this.uploadAssets))e[t]=this.#c(r);return e}#m(){let e={};for(let[t,r]of Object.entries(this.uploadGroups))e[t]=this.#o(r);return e}getSerializableSnapshot(){return{uploadAssets:this.#u(),uploadGroups:this.#m(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let r of this.dirtyAssetIds){let s=this.uploadAssets[r];s&&(e[r]=this.#c(s))}let t={};for(let r of this.dirtyGroupIds){let s=this.uploadGroups[r];s&&(t[r]=this.#o(s))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function Hn(n,e){let t=new Date(n).getTime(),r=Date.now();return t-r<=e}var Fe=class{#t;#n=new Map;#e=new Map;constructor(e){this.#t=e}seedToken(e,t,r){this.#n.set(e,{token:t,expiresAt:r})}async getToken(e,t){let r=this.#n.get(e);if(r&&!Hn(r.expiresAt,3e5))return r.token;let s=this.#e.get(e);if(s)return s;let i=t?D(t):void 0,o=this.#t.post(`/assets/${e}/token`,{},i).then(a=>{if(!a.token)throw new Error("Token refresh failed: no token in response");return this.#n.set(e,{token:a.token,expiresAt:a.token_expires_at}),this.#e.delete(e),a.token}).catch(a=>{throw this.#e.delete(e),a});return this.#e.set(e,o),o}clearCache(e){e?this.#n.delete(e):this.#n.clear()}};var we=class{#t=[];registerAsset(e){this.#t.push({assetId:e.assetId,totalChunks:e.totalChunks,nextChunkToClaim:0,completedChunkIndices:new Set(e.completedChunkIndices),isPaused:!1})}claimNextChunk(){for(let e of this.#t)if(!e.isPaused)for(;e.nextChunkToClaim<e.totalChunks;){let t=e.nextChunkToClaim;if(e.nextChunkToClaim++,!e.completedChunkIndices.has(t))return{assetId:e.assetId,chunkIndex:t}}return null}markChunkCompleted(e,t){let r=this.#n(e);return r?(r.completedChunkIndices.add(t),r.completedChunkIndices.size>=r.totalChunks):!1}pauseAsset(e){let t=this.#n(e);t&&(t.isPaused=!0)}unpauseAsset(e){let t=this.#n(e);t&&(t.isPaused=!1,this.#e(t))}removeAsset(e){this.#t=this.#t.filter(t=>t.assetId!==e)}hasAsset(e){return this.#t.some(t=>t.assetId===e)}isAssetComplete(e){let t=this.#n(e);return t?t.completedChunkIndices.size>=t.totalChunks:!1}clear(){this.#t=[]}#n(e){return this.#t.find(t=>t.assetId===e)}#e(e){for(let t=0;t<e.totalChunks;t++)if(!e.completedChunkIndices.has(t)){e.nextChunkToClaim=t;return}e.nextChunkToClaim=e.totalChunks}};var jn=/[/\\:*?"<>|\x00-\x1F]/g,Wn=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function z(n){let e=n.replace(jn,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;Wn.includes(t.toUpperCase())&&(e=`_${e}`);let r=new TextEncoder;if(r.encode(e).length>255){let s=e.lastIndexOf("."),i=s>0?e.substring(s):"",o=s>0?e.substring(0,s):e,l=255-r.encode(i).length;for(;r.encode(o).length>l&&o.length>0;)o=o.slice(0,-1);e=o+i}return e}var L=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function _(n){return n instanceof L||n instanceof Error&&n.name==="CancelledError"||n instanceof Error&&n.name==="CanceledError"||n instanceof Error&&n.name==="AbortError"}function Xn(n){return _(n)||n instanceof Error&&n.name==="NoAuthError"}function Zn(n){return new Promise(e=>setTimeout(e,n))}function er(n){return n instanceof Blob?n.size:n.byteLength}var ne=class{#t;#n;#e;#r;#s;#i;#a;#c;#o;#u;#m;#l;#D;#g=null;#A=0;#k=!1;#b=[];#S=new Set;#P=!1;#R=!1;#I=!1;#h=[];#C=!1;#E=!1;#d=new we;#T=0;#f=new Map;#F=new Map;#L=[];#_=!1;#x=null;#O;#U="keep_both";#v=new Map;#B=null;#p=!1;#w=null;#N=!1;constructor(e){this.#t=e.httpClient,this.#n=new Fe(e.httpClient),this.#e=new Ae,this.#r=e.historyStore??null,this.#s=e.settingsStore??null,this.#i=e.analytics??null,this.#a=e.logger??ot,this.#c=e.onChange??null,this.#o=e.onClear??null,this.#u=e.onSummary??null,this.#m=e.onConcurrencyAdjusted??null,this.#D=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let r=e.adaptiveConcurrencyConfig;this.#w=new te({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 i=this.#l;if(this.setMaxConcurrency(s),i===s)return;let o=this.#N?"reset":s>i?"probe_increase":"error_decrease",a=Math.round(this.#w.speedBps*8/1e6*100)/100,l=Math.round(this.#w.latencyMsPerMB*100)/100;this.#a.info(`Adaptive concurrency: ${i} \u2192 ${s} (${o}), measuredAt=${i}, speed=${a}Mbps, latency=${l}ms/MB`),this.#m?.({previousConcurrency:i,newConcurrency:s,reason:o,speedMbps:a,latencyMsPerMB:l})},now:r?.now}),this.#l=this.#w.concurrency}else this.#l=t;this.#r&&(this.#b=this.#r.load()),this.#s&&(this.#x=this.#s.getBandwidthLimitBps(),this.#U=this.#s.getConflictResolution()),this.#O=new N(this.#x),(this.#c||this.#u)&&(this.#g=setInterval(()=>{this.#ce()},this.#D)),this.#i&&(this.#B=setInterval(()=>{this.#de()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),r=!!e.assetId,s;if(r){let o=this.#e.getUploadAsset(t);if(!o)throw new Error(`Cannot retry: asset ${t} not found`);s=o.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");s=e.chunkSize}let i=new AbortController;if(r){if(this.#e.getUploadAsset(t).status==="cancelled")return t;e.resetRetryCount&&this.#e.resetAssetForRetrying(t);let a=this.#e.getUploadAsset(t);a.abortController=i,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#e.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:i,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:s,shareContext:e.shareContext});return this.#h.push(t),this.#G(),this.#y(),t}startGroupUpload(e){this.#e.clearTerminalState();let t=this.#e.addUploadGroup({type:e.type,name:e.name,assetIds:[],fileCount:e.fileCount,folderCount:e.folderCount,topLevelFileCount:e.topLevelFileCount,topLevelFolderCount:e.topLevelFolderCount,isCreatingFolders:!1,isPaused:!1,createdAt:new Date().toISOString(),rootDirectoryId:e.rootDirectoryId,projectId:e.projectId,retryCount:0,conflictResolution:e.conflictResolutionOverride??this.#U});return this.#v.set(t,Date.now()),this.#i?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#e.dirtyHistoryGroupIds.add(t),this.#$(),this.#y(),t}pauseUpload(e){let t=this.#e.getUploadAsset(e);this.#e.pauseUpload(e),this.#h=this.#h.filter(r=>r!==e),this.#d.pauseAsset(e),!this.#p&&t&&this.#i&&this.#i("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#y()}unpauseUpload(e){this.#e.unpauseUpload(e),this.#y()}cancelUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status==="success"||t.status==="failed"||t.status==="cancelled")return;let r=t.fileName,s=t.totalBytesToUpload,i=t.bytesUploaded,o=t.projectId,a=t.chunkedState?.assetId;(t.status==="queued"||t.status==="in-progress")&&t.abortController.abort(),this.#h=this.#h.filter(l=>l!==e),this.#d.removeAsset(e),this.#f.delete(e),this.#F.delete(e),this.#e.markUploadCancelled(e),this.#e.clearChunkedState(e),t.fileReader.close?.(),!this.#p&&this.#i&&this.#i("upload:file_cancelled",{file_name:r,file_size:s,bytes_uploaded:i,project_id:o??""}),this.#y(),this.#M(),this.#G(),this.#Q(),a&&(this.#L.push(a),this.#X())}cancelAllUploads(){let e=this.#J();this.#p=!0;try{let r=Object.values(this.#e.uploadAssets).filter(s=>s.status==="queued"||s.status==="in-progress"||s.status==="paused");for(let s of r)this.cancelUpload(s.assetId)}finally{this.#p=!1}this.#i?.("upload:all_cancelled",e)}retryUpload(e){let t=this.#e.getUploadAsset(e);t&&t.status==="failed"&&this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,resetRetryCount:!0,shareContext:t.shareContext})}resumeUpload(e){let t=this.#e.getUploadAsset(e);if(!t||t.status!=="paused")return;!this.#p&&this.#i&&this.#i("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.#e.unpauseUpload(e),this.#d.hasAsset(e)?(this.#d.unpauseAsset(e),this.#y(),this.#d.isAssetComplete(e)?this.#Y(e).catch(s=>{this.#z(e,s)}):this.#M()):this.startUpload({fileReader:t.fileReader,directoryId:t.parentId??"",projectId:t.projectId,groupId:t.groupId,assetId:e,resumeChunked:t.chunkedState,shareContext:t.shareContext})}pauseUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let r=this.#p;this.#p=!0,this.#e.pauseUploadGroup(e);for(let s of t.assetIds)this.#h=this.#h.filter(i=>i!==s),this.#d.pauseAsset(s);this.#p=r,this.#p||this.#te(e,t,"upload:group_paused"),this.#y()}unpauseUploadGroup(e){this.#e.unpauseUploadGroup(e),this.#y()}cancelUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;let{totalBytes:r,bytesUploaded:s,filesRemaining:i}=this.#ee(t),o=this.#p;this.#p=!0;for(let a of t.assetIds)this.cancelUpload(a);t.assetIds.length===0&&(this.#e.finalizeEmptyGroup({groupId:e,status:"cancelled"}),this.#$(),this.#y()),this.#p=o,this.#p||this.#i?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:i,total_bytes:r,bytes_uploaded:s,project_id:t.projectId}),this.#v.delete(e)}resumeUploadGroup(e){let t=this.#e.uploadGroups[e];if(!t)return;this.#p||this.#te(e,t,"upload:group_resumed");let r=this.#p;this.#p=!0,this.#e.unpauseUploadGroup(e);for(let s of t.assetIds){let i=this.#e.getUploadAsset(s);i&&i.status==="paused"&&this.resumeUpload(s)}this.#p=r}retryUploadGroup(e){let t=this.#e.uploadGroups[e];if(t)for(let r of t.assetIds){let s=this.#e.getUploadAsset(r);s&&s.status==="failed"&&this.retryUpload(r)}}setGroupCreatingFolders(e,t){this.#e.updateUploadGroup(e,{isCreatingFolders:t}),this.#y()}markEmptyGroupFailed(e,t){let r=this.#e.uploadGroups[e];r&&(r.assetIds.length>0||r.finalizedStatus||(this.#a.error("Empty group upload failed",{groupId:e,groupName:r.name,errorMessage:t}),this.#e.finalizeEmptyGroup({groupId:e,status:"all-failed",errorMessage:t}),this.#$(),this.#v.delete(e),this.#y()))}markEmptyGroupCompleted(e){this.#e.finalizeEmptyGroup({groupId:e,status:"success"}),this.#$(),this.#v.delete(e),this.#y()}addAssetToGroup(e,t){this.#e.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#J();this.#p=!0;try{for(let t of Object.values(this.#e.uploadAssets))t.groupId||this.pauseUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isCreatingFolders||this.pauseUploadGroup(t.id)}finally{this.#p=!1}this.#i?.("upload:all_paused",e),this.#y()}resumeAllUploads(){let e=this.#J();this.#p=!0;try{for(let t of Object.values(this.#e.uploadAssets))!t.groupId&&t.status==="paused"&&this.resumeUpload(t.assetId);for(let t of Object.values(this.#e.uploadGroups))t.isPaused&&this.resumeUploadGroup(t.id)}finally{this.#p=!1}this.#i?.("upload:all_resumed",e),this.#y()}clearAllUploads(){this.#h=[],this.#d.clear(),this.#f.clear(),this.#F.clear(),this.#e.clearAllUploads(),this.#e.uploadGroups={},this.#w&&(this.#N=!0,this.#w.reset(),this.#N=!1),this.#o?.({all:!0}),this.#u?.(this.#j())}clearHistory(){this.#b=[],this.#r?.clear(),this.#P=!0,this.#S.clear(),this.#I=!0,this.#y()}removeHistoryItem(e){this.#b=this.#b.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#S.add(e),this.#I=!0,this.#y()}removeGroup(e){this.#e.removeUploadGroup(e),this.#b=this.#b.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#S.add(e),this.#I=!0,this.#o?.({groupId:e}),this.#u?.(this.#j()),this.#y()}getHttpClient(){return this.#t}setBandwidthLimit(e){let t=e!==this.#x;this.#x=e,this.#O.setLimit(e),this.#s?.setBandwidthLimitBps(e),t&&this.#w&&(this.#N=!0,this.#w.reset(),this.#N=!1),this.#I=!0,this.#y()}getBandwidthLimit(){return this.#x}setConflictResolution(e){this.#U=e,this.#s?.setConflictResolution(e),this.#I=!0,this.#y()}getConflictResolution(){return this.#U}getGroupConflictResolution(e){return this.#e.getUploadGroup(e)?.conflictResolution??this.#U}setMaxConcurrency(e){this.#l=e,this.#M()}getSnapshot(){return this.#e.updateUploadStats(),{...this.#e.getSerializableSnapshot(),uploadHistory:[...this.#b??[]],uploadSummary:this.#j(),bandwidthLimitBps:this.#x,conflictResolution:this.#U}}getUploadAsset(e){return this.#e.getSerializableAsset(e)}getUploadSummary(){return this.#j()}getGroupAssets(e){return this.#e.getGroupAssets(e)}getUploadGroupStatus(e){return this.#e.getUploadGroupStatus(e)}getUploadGroupProgress(e){return this.#e.getUploadGroupProgress(e)}hasGroupsCreatingFolders(){return this.#e.hasGroupsCreatingFolders()}areAllUploadsPaused(){return this.#e.areAllUploadsPaused()}hasPausedUploads(){return this.#e.hasPausedUploads()}hasActiveUploads(){return nt(this.#e.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return tt(this.#e.getSerializableSnapshot().uploadAssets)}async cancelActiveServerUploads(){let e=this.getServerAssetIdsToCancel();if(e.length!==0)try{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}catch{await this.#t.post("/assets/cancel-uploads",{asset_ids:e})}}destroy(){this.#R=!0,this.#g&&(clearInterval(this.#g),this.#g=null),this.#B&&(clearInterval(this.#B),this.#B=null),this.#h=[],this.#d.clear();for(let e of Object.values(this.#e.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#G(){this.#E||(this.#E=!0,queueMicrotask(()=>{this.#E=!1,this.#W().catch(e=>{this.#a.error("Initiation pipeline error",{queueLength:this.#h.length},e)})}))}async#W(){if(!this.#C){this.#C=!0;try{await this.#q()}finally{this.#C=!1}}}async#q(){for(;this.#h.length>0&&!(this.#f.size>5);){let e=Math.min(this.#h.length,20-this.#f.size);if(e<=0)break;let t=[],r=[];for(let s=0;s<e&&this.#h.length>0;s++){let i=this.#h[0],o=this.#e.getUploadAsset(i);if(!o||o.status==="cancelled"){this.#h.shift(),s--;continue}if(this.#h.shift(),r.push(i),o.chunkedState)try{this.#V(i,o),this.#M()}catch(a){_(a)||this.#z(i,a)}else t.push(i)}if(t.length>0){let s=new Map;for(let i of t){let a=this.#e.getUploadAsset(i)?.shareContext?.shareId??"",l=s.get(a);l||(l=[],s.set(a,l)),l.push(i)}for(let i of s.values())try{await this.#H(i)}catch(o){for(let a of i)this.#z(a,o instanceof Error?o:new Error(String(o)))}this.#M()}}}#V(e,t){let r=t.chunkedState,s={serverAssetId:r.assetId,chunkIds:r.chunkIds,chunkSize:r.chunkSize,totalChunks:r.totalChunks,sizeBytes:r.sizeBytes},i=r.completedChunkIndices;this.#f.set(e,s);let o=new Array(s.totalChunks).fill(0);if(i.length>0){for(let l of i){let c=l*s.chunkSize,u=Math.min(c+s.chunkSize,t.totalBytesToUpload);o[l]=u-c}let a=o.reduce((l,c)=>l+c,0);this.#e.updateUploadProgress(e,a)}if(this.#F.set(e,o),s.totalChunks===0||i.length>=s.totalChunks){this.#Y(e).catch(a=>{this.#z(e,a)});return}this.#d.registerAsset({assetId:e,totalChunks:s.totalChunks,completedChunkIndices:i})}async#H(e){let t=[],r=[];for(let a of e){let l=this.#e.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let c=z(l.fileName),u=l.groupId?this.#e.getUploadGroup(l.groupId)?.conflictResolution??this.#U:this.#U,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.#e.getUploadAsset(r[0]),i=s?.shareContext?D(s.shareContext):void 0,o=await this.#t.post("/assets/chunked/initiate",t,i);for(let a=0;a<r.length;a++){let l=r[a],c=o[a];if(!c||c.error){this.#z(l,new Error(c?.error??"Unknown batch initiation error"));continue}if(c.skipped){let S=this.#e.getUploadAsset(l);S&&(this.#e.adjustSpeedBaselineForSkippedBytes(S.totalBytesToUpload),this.#e.markUploadSuccess(l),this.#e.dirtyHistoryGroupIds.add(S.groupId??""),this.#$(),S.fileReader.close?.());continue}let u=c.result,d=this.#e.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),g=Array.from({length:m},()=>crypto.randomUUID());this.#n.seedToken(u.asset_id,u.token,u.token_expires_at);let p={serverAssetId:u.asset_id,chunkIds:g,chunkSize:u.chunk_size,totalChunks:m,sizeBytes:d.totalBytesToUpload};this.#e.setChunkedState(l,{assetId:p.serverAssetId,chunkIds:p.chunkIds,completedChunkIndices:[],chunkSize:p.chunkSize,totalChunks:p.totalChunks,sizeBytes:p.sizeBytes}),this.#f.set(l,p);let A=new Array(p.totalChunks).fill(0);if(this.#F.set(l,A),p.totalChunks===0){this.#Y(l).catch(S=>{this.#z(l,S)});continue}this.#d.registerAsset({assetId:l,totalChunks:p.totalChunks,completedChunkIndices:[]})}}#M(){if(!this.#R)for(;this.#T<this.#l;){let e=this.#d.claimNextChunk();if(!e)break;this.#T++;let{assetId:t,chunkIndex:r}=e,s=this.#w?.generation;this.#re(t,r,s).then(i=>{this.#T--,this.#ie(t,r,i),this.#M()}).catch(i=>{if(this.#T--,_(i)){this.#M();return}this.#oe(t,r,i),this.#M()})}}async#re(e,t,r){let s;for(let i=0;i<3;i++)try{let o=this.#F.get(e);return o&&(o[t]=0,this.#K(e)),await this.#se(e,t,r)}catch(o){if(_(o))throw o;if(s=o instanceof Error?o:new Error(String(o)),this.#w?.recordError(),this.#ae(e,t,s,i),i===2)throw s;let a=this.#F.get(e);a&&(a[t]=0,this.#K(e));let l=1e3*Math.pow(2,i);await Zn(l)}throw s||new Error("Unknown error during chunk upload")}async#se(e,t,r){let s=this.#e.getUploadAsset(e);if(!s)throw new L;if(s.abortController.signal.aborted)throw new L;let i=this.#f.get(e);if(!i)throw new Error(`No chunk metadata for asset ${e}`);let o=t*i.chunkSize,a=Math.min(o+i.chunkSize,s.totalBytesToUpload),l=await s.fileReader.readChunk(o,a),c=er(l);if(s.abortController.signal.aborted)throw new L;let u=i.chunkIds[t],d=await this.#n.getToken(i.serverAssetId,s.shareContext),m=`/uploads/chunks/${u}`,g=Date.now(),p=await this.#t.putWithToken(m,l,d,{signal:s.abortController.signal,onProgress:T=>{let E=this.#F.get(e);E&&(E[t]=T,this.#K(e))},contentType:"application/octet-stream",limiter:this.#O}),A=Date.now(),S=p.uploadCompletedAtMs??A,y=S-g;if(!p.status||p.status<200||p.status>=300)throw this.#a.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:u,assetId:e,serverAssetId:i.serverAssetId,chunkSizeBytes:c,durationMs:y,httpStatus:p.status,statusText:p.statusText,responseBody:p.data,responseHeaders:p.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${p.status}`);let Se=this.#F.get(e);return Se&&(Se[t]=c,this.#K(e)),{durationMs:y,startedAtMs:g,completedAtMs:S,adaptiveGeneration:r}}#K(e){let t=this.#F.get(e);if(!t)return;let r=t.reduce((s,i)=>s+i,0);this.#e.updateUploadProgress(e,r)}#ie(e,t,r){if(this.#w){let i=this.#f.get(e);if(i){let o=t*i.chunkSize,l=Math.min(o+i.chunkSize,i.sizeBytes)-o;this.#w.recordSuccess(l,r.durationMs,{generation:r.adaptiveGeneration,startedAtMs:r.startedAtMs,completedAtMs:r.completedAtMs})}}this.#e.addCompletedChunkIndex(e,t),this.#d.markChunkCompleted(e,t)&&this.#Y(e).catch(i=>{this.#z(e,i)})}#oe(e,t,r){this.#z(e,r)}#ae(e,t,r,s){if(!this.#i)return;let i=this.#e.getUploadAsset(e);if(!i)return;let o=this.#f.get(e);if(!o)return;let a=t*o.chunkSize,c=Math.min(a+o.chunkSize,o.sizeBytes)-a,u=r,d=typeof u.code=="string"?u.code:null,m=u.response?.status,g=typeof m=="number"?m:null,p=r.cause?r.cause instanceof Error?r.cause.message:String(r.cause):null;this.#i("upload:chunk_error",{file_name:i.fileName,file_size:i.totalBytesToUpload,chunk_index:t,chunk_size:c,chunks_total:o.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:g,error_stack:r.stack??null,error_cause:p,project_id:i.projectId??""})}#le(e,t,r,s){if(!this.#i||_(t))return;let i=t instanceof Error?t.message:"Unknown error",o=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof o.code=="string"?o.code:null,c=o.response?.status,u=typeof c=="number"?c:null,d=this.#f.get(e.assetId);this.#i("upload:file_error",{file_name:e.fileName,file_size:e.totalBytesToUpload,bytes_uploaded:e.bytesUploaded,chunks_completed:e.chunkedState?.completedChunkIndices.length??0,chunks_total:d?.totalChunks??0,attempt:r+1,max_attempts:4,is_final_attempt:s,error_type:t instanceof Error?t.name:"Unknown",error_message:i,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.#e.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(),i=JSON.stringify(r.chunkIds),o=new TextEncoder().encode(i),a=await this.#n.getToken(r.serverAssetId,t.shareContext),l=`/uploads/manifests/${s}`;try{await this.#t.putWithToken(l,o,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(c){throw _(c)||this.#a.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?D(t.shareContext):void 0;await this.#t.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.#a.error("Commit revision failed",{assetId:e,serverAssetId:r.serverAssetId,manifestId:s,sizeBytes:r.sizeBytes},c),c}this.#e.markUploadSuccess(e),this.#e.clearChunkedState(e),this.#$(),this.#y(),this.#f.delete(e),this.#F.delete(e),this.#d.removeAsset(e),await t.fileReader.close?.(),this.#ne(e),this.#G(),this.#Q()}#z(e,t){let r=this.#e.getUploadAsset(e);if(!r||_(t)||r.status==="paused"||r.status==="cancelled")return;let s=r.retryCount,i=s>=3||Xn(t);if(this.#le(r,t,s,i),i){let o=t instanceof Error?t.message:"Unknown error";this.#a.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.#e.markUploadFailed(e,o),this.#d.removeAsset(e),this.#f.delete(e),this.#F.delete(e),this.#$(),this.#y(),this.#ne(e),this.#G(),this.#Q()}else{this.#a.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:r.fileName,retryAttempt:s+1,maxRetries:3},t);let o=r.chunkedState;r.abortController.abort(),this.#d.removeAsset(e),this.#f.delete(e),this.#F.delete(e),this.#e.resetAssetForRetryQueue(e),this.#y(),this.#G();let a=2e3*Math.pow(2,s);setTimeout(()=>{if(this.#R)return;let l=this.#e.getUploadAsset(e);!l||l.status!=="queued"||this.startUpload({fileReader:l.fileReader,directoryId:l.parentId??"",projectId:l.projectId,groupId:l.groupId,assetId:e,resumeChunked:o,shareContext:l.shareContext})},a)}}#Q(){this.#w&&(this.hasActiveUploads()||(this.#N=!0,this.#w.reset(),this.#N=!1))}#X(){this.#_||(this.#_=!0,queueMicrotask(()=>{this.#_=!1;let e=this.#L.splice(0);e.length!==0&&this.#t.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#a.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#j(){return Z(this.#e.getSerializableSnapshot().uploadAssets)}#y(){this.#k||(this.#k=!0,queueMicrotask(()=>{this.#k=!1,this.#ue()}))}#ce(){this.#Z(!0)}#ue(){this.#Z(!1)}#Z(e){if(this.#R||!this.#c&&!this.#u)return;e?this.#e.updateUploadStats():(this.#A++,this.#A%3===0&&this.#e.updateUploadStats());let t=this.#e.getDirtyDelta();if(!this.#I&&Object.keys(t.assets).length===0&&Object.keys(t.groups).length===0&&this.#e.dirtyHistoryGroupIds.size===0)return;this.#I=!1,this.#e.dirtyHistoryGroupIds.size>0&&this.#$();let s=this.#e.dirtyHistoryGroupIds.size>0?this.#pe():void 0,i=this.#P?!0:void 0,o=this.#S.size>0?[...this.#S]:void 0;this.#P=!1,this.#S.clear();let a=this.#j(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#e.uploadStats},uploadSpeedState:this.#e.uploadSpeedState,historyItems:s,removedHistoryGroupIds:o,historyCleared:i,uploadSummary:a,bandwidthLimitBps:this.#x,conflictResolution:this.#U};this.#e.clearDirtyFlags(),this.#c?.(l),this.#u?.(a)}#ee(e){let t=0,r=0,s=0;for(let i of e.assetIds){let o=this.#e.getUploadAsset(i);o&&(t+=o.totalBytesToUpload,r+=o.bytesUploaded,o.status!=="success"&&o.status!=="failed"&&o.status!=="cancelled"&&s++)}return{totalBytes:t,bytesUploaded:r,filesRemaining:s}}#J(){let e=0,t=0,r=0,s=0;for(let i of Object.values(this.#e.uploadGroups)){e++;for(let o of i.assetIds){let a=this.#e.getUploadAsset(o);a&&(a.status==="success"||a.status==="failed"||a.status==="cancelled"||(t++,r+=a.totalBytesToUpload,s+=a.bytesUploaded))}}return{group_count:e,file_count:t,total_bytes:r,bytes_uploaded:s}}#de(){if(!(!this.#i||this.#R))for(let e of Object.values(this.#e.uploadGroups)){let t=!1,r=0,s=0,i=0,o=0,a=0,l=0,c=0,u=0,d=0,m=0;for(let A of e.assetIds){let S=this.#e.getUploadAsset(A);if(!S)continue;let y=S.totalBytesToUpload;switch(r+=y,s+=S.bytesUploaded,S.status){case"success":i++,o+=y;break;case"failed":a++,l+=y;break;case"cancelled":c++,u+=y;break;case"in-progress":d++,t=!0;break;case"queued":m++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let g=this.#v.get(e.id),p=g?Date.now()-g:0;this.#i("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:i,succeeded_bytes:o,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.#e.uploadStats.uploadSpeedMbps})}}#te(e,t,r){if(!this.#i)return;let{totalBytes:s,bytesUploaded:i}=this.#ee(t);this.#i(r,{file_count:t.fileCount,total_bytes:s,bytes_uploaded:i,project_id:t.projectId})}#ne(e){if(!this.#i)return;let t=this.#e.getUploadAsset(e);if(!t?.groupId)return;let r=this.#e.uploadGroups[t.groupId];if(!r)return;let s=!0,i=0,o=0,a=0,l=0,c=0,u=0,d=0;for(let p of r.assetIds){let A=this.#e.getUploadAsset(p);if(!A)continue;let S=A.totalBytesToUpload;if(d+=S,A.status==="success")i++,o+=S;else if(A.status==="failed")a++,l+=S;else if(A.status==="cancelled")c++,u+=S;else{s=!1;break}}if(!s)return;let m=this.#v.get(r.id),g=m?Date.now()-m:0;this.#i("upload:group_completed",{file_count:r.assetIds.length,total_bytes:d,duration_ms:g,project_id:r.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u}),this.#v.delete(r.id)}#pe(){let e={};for(let t of this.#e.dirtyHistoryGroupIds){let r=this.#e.buildHistoryItem(t);r&&(e[t]=r)}return e}#$(){if(!this.#r)return;let e={};for(let t of this.#e.dirtyHistoryGroupIds){let r=this.#e.buildHistoryItem(t);if(r){e[t]=r;let s=this.#b.findIndex(i=>i.groupId===t);s>=0?this.#b[s]=r:this.#b.unshift(r)}}Object.keys(e).length>0&&this.#r.merge(e)}};var re=class{#t=65536;#n=0;async*createIterator(e,t,r){let s=0,i=Math.max(65536,Math.min(e.byteLength,this.#t)),o=this.#n;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);i=Math.max(65536,Math.min(e.byteLength,p))}let c=Math.min(s+i,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 g=performance.now()-m;if(s=c,!l){if(g>=.5){let p=d/g*1e3;o=o===0?p:o*(1-.3)+p*.3}else o===0&&(i=Math.min(e.byteLength,i*2));if(o>0){let p=Math.round(o*50/1e3);i=Math.max(65536,Math.min(e.byteLength,p))}}this.#t=i,this.#n=o}}};var h=(n,e=2)=>{if(n===0)return"0 B";let t=1024,r=e<0?0:e,s=["B","KB","MB","GB","TB","PB","EB"],i=Math.floor(Math.log(n)/Math.log(t));return`${(n/Math.pow(t,i)).toFixed(r)} ${s[i]}`},Re=n=>{if(n===null)return null;let t=n*8/(1024*1024);return t<1?`${(t*1024).toFixed(0)} Kbps`:`${t.toFixed(1)} Mbps`},se=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`};var nr=1e3,lt=class{#t=null;#n=!1;#e=null;#r=null;#s=null;#i=new Map;#a=null;#c=null;#o=null;#u=null;start(){this.#n||(this.#n=!0,this.#i.clear(),this.#a=null,this.#c=null,this.#o=null,this.#u=null,this.#t=setInterval(()=>this.render(),nr))}stop(){this.#n&&(this.#n=!1,this.#t&&(clearInterval(this.#t),this.#t=null),this.render(),zt.done())}updateSnapshot(e){this.#e=e}updateBatchState(e){this.#r=e}updateDownloadProgress(e){if(!e){this.#s=null;return}let t=e.percentComplete>=100||e.bytesTransferred>=e.totalBytes;!t&&e.speed>0&&(this.#o=e),this.#s=t&&this.#o?{...e,speed:this.#o.speed,eta:this.#o.eta}:e}persistCurrentBatchLine(){!this.#r||this.#r.currentPhase!=="complete"||this.#i.set(this.#r.currentBatch,this.#g(this.#r))}resetUploadSnapshot(){this.#e=null,this.#s=null,this.#o=null,this.#u=null}render(){if(!this.#n)return;let e=this.#r?this.#D(this.#r):this.#l();zt(e.join(`
|
|
3
|
-
`))}#m(e,t){let r=[`${f.green(h(t.bytesTransferred))} / ${f.gray(h(t.totalBytes))}`,f.cyan(`${t.percentComplete.toFixed(1)}%`),f.magenta(Re(t.speed)??"..."),`${f.yellow("ETA")}: ${f.yellow(se(t.eta)??"...")}`];return`${f.blue(e)}: ${r.join(" | ")}`}#l(){let e=this.#h();return[this.#R(e),this.#I(e)]}#D(e){let t=[];for(let r=1;r<e.currentBatch;r++){let s=this.#i.get(r);s&&t.push(s)}return t.push(this.#g(e)),t.push(this.#k(e)),t}#g(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#s?`${t}: ${this.#m("Downloading",this.#s)}`:`${t}: ${f.blue("Downloading...")}`;case"scanning":return`${t}: ${f.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${f.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#A(t,e);case"cleaning":return`${t}: ${f.yellow("Cleaning...")}`;case"complete":return`${t}: ${f.green("Complete")} (${e.batchFilesTotal} files, ${h(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#A(e,t){let r=this.#h(),s=r.successFileCount+r.failedFileCount+r.cancelledFileCount,i=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),o=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=o>0?(r.uploadedBytes/o*100).toFixed(1):"0.0",l=this.#P(t,r,o),c=l?.formattedSpeed??null,u=l?.formattedTime??null,d=r.totalFileCount>0&&r.totalFileCount<i?`, ${f.gray(`Enqueued: ${r.totalFileCount}/${i}`)}`:"",m=c&&u?`, ${c}, ETA: ${u}`:"",g=t.batchFilesSkipped>0?`, ${f.yellow(`Skipped: ${t.batchFilesSkipped} files / ${h(t.batchBytesSkipped)}`)}`:"",p=o>0&&r.uploadedBytes>=o&&s<i?"Finalizing":"Uploading";return`${e}: ${f.blue(p)} (${s}/${i} files, ${h(r.uploadedBytes)} / ${h(o)}, ${a}%${d}${m}${g})`}#k(e){let t=this.#h(),r=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,s=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+r,o=e.overallBytesCompleted+s,a=Math.max(e.overallBytesTotal-o,0),l=this.#b(e),c=this.#S(e,t),u=l!==null&&c!==null?l+c:null;return[`Total: ${i}/${e.overallFilesTotal} files`,`${h(o)} / ${h(e.overallBytesTotal)}`,f.yellow(`${h(a)} remaining`),`Download ETA: ${se(l)??"..."}`,`Upload ETA: ${se(c)??"..."}`,`Total ETA: ${se(u)??"..."}`].join(", ")}#b(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#s?.bytesTransferred??0),r=Math.max(e.overallBytesTotal-t,0);if(r===0)return e.currentPhase==="downloading"&&this.#s?(this.#a=this.#s.eta,this.#s.eta):(this.#a=0,0);if(this.#s&&this.#s.speed>0){let s=Math.ceil(r/this.#s.speed);return this.#a=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#a=0,0):this.#a}#S(e,t){let r=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,s=Math.max(e.overallBytesTotal-r,0),i=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=this.#P(e,t,i);if(s===0)return e.currentPhase==="uploading"&&o?(this.#c=o.timeRemainingSeconds,o.timeRemainingSeconds):(this.#c=0,0);if(o&&o.uploadSpeedMbps>0){let a=o.uploadSpeedMbps*1024*1024/8,l=Math.ceil(s/a);return this.#c=l,l}return this.#c}#P(e,t,r){let s=this.#e?.uploadStats,i=r>0&&t.uploadedBytes>=r;return s&&s.uploadSpeedMbps>0&&s.formattedSpeed!=="Calculating..."&&!i?(this.#u={uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds},this.#u):e.currentPhase==="uploading"&&i&&this.#u?this.#u:s?{uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds}:null}#R(e){return[`Total: ${e.totalFileCount}`,f.green(`Success: ${e.successFileCount}`),f.red(`Failed: ${e.failedFileCount}`),f.red(`Cancelled: ${e.cancelledFileCount}`),f.blue(`Active: ${e.activeFileCount}`),f.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#I(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),r=this.#e?` | ${f.cyan(`Speed: ${this.#e.uploadStats.formattedSpeed}`)} | ${f.magenta(`Time remaining: ${this.#e.uploadStats.formattedTime}`)}`:"";return[`Total: ${h(e.totalBytes)}`,f.green(`Uploaded: ${h(e.uploadedBytes)}`),f.yellow(`Remaining: ${h(t)}`)].join(" | ")+r}#h(){return this.#e?Object.values(this.#e.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}}},C=new lt;import{Readable as rr}from"node:stream";import $t from"axios";var x=class{#t;#n;#e;#r;#s=new re;#i=new Set;constructor(e){this.#t=$t.create({baseURL:e.apiUrl}),this.#n=$t.create({baseURL:e.edgeWorkerUrl}),this.#e=e.apiKey,this.#r=e.sessionId}get skippedAssetIds(){return this.#i}async post(e,t,r){let s=await this.#t.post(e,t,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,"Content-Type":"application/json",...r}});return this.#c(e,t,s.data),s.data}async get(e,t){return(await this.#t.get(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,...t}})).data}async delete(e,t){await this.#t.delete(e,{headers:{Authorization:`Bearer ${this.#e}`,"X-Aspect-Session-Id":this.#r,...t}})}async putWithToken(e,t,r,s){let i=await this.#a(t),o=this.#s.createIterator(i,s.limiter??null,s.signal),a=rr.from(o,{highWaterMark:1}),l=await this.#n.put(e,a,{timeout:0,signal:s.signal,headers:{"Content-Type":s.contentType??"","Content-Length":i.byteLength.toString(),Authorization:`Bearer ${r}`},transformRequest:[c=>c],maxRedirects:0,onUploadProgress:c=>s.onProgress?.(c.loaded)});return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#a(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#c(e,t,r){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(r))return;let s=t;r.forEach((o,a)=>{let l=s[a];o.skipped===!0&&typeof l?.id=="string"&&this.#i.add(l.id)})}};import oe from"node:path";import U from"node:path";function b(n){let e=n.replace(/\\/g,"/");if(e.split("/").some(i=>i===".."))throw new Error(`Remote path cannot contain parent directory segments: ${n}`);let s=U.posix.normalize(e).replace(/^\/+/,"");if(s===""||s===".")throw new Error(`Remote path must resolve to a file path: ${n}`);return s}function Ie(n){let e=new Map;for(let i of n){let o=b(i.targetPath??i.path);e.set(o,(e.get(o)??0)+1)}let t=new Set,r=[],s=[];for(let i of n){let o=b(i.path),a=b(i.targetPath??i.path),l=ie(a),c=ct(l,t),u=(e.get(a)??0)>1,d=c!==o;t.add(c),r.push({...i,targetPath:c,requiresIdentityDownload:i.requiresIdentityDownload===!0||u}),(d||u)&&s.push({sourcePath:i.path,targetPath:c,reason:u||c!==l?"duplicate":"sanitized"})}return{files:r,changes:s}}function w(n){return b(n.targetPath??n.path)}function ke(n,e){let t=w(n);return{relativePath:t,absolutePath:U.join(e,t),fileName:U.posix.basename(t),size:n.size}}function ie(n){return n.split("/").map(t=>z(t)).join("/")}function ct(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),r=U.posix.basename(n),s=U.posix.extname(r),i=s.length>0?r.slice(0,-s.length):r,o=2;for(;;){let a=`${i} (${o})${s}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;o+=1}}function ut(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),r=U.posix.basename(n),s=2;for(;;){let i=`${r} ${s}`,o=t==="."?i:`${t}/${i}`;if(!e.has(o))return o;s+=1}}var Gt=500,sr=8,Te=class{#t;#n;#e=new Map;constructor(e){this.#t=e.rootDirectoryId,this.#n=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#r(e);for(let r of t){if(this.#e.has(r))continue;let s=oe.posix.dirname(r),i=oe.posix.basename(r),o=s==="."?this.#t:this.#e.get(s);if(!o)throw new Error(`Parent directory ID not found for path: ${r}`);let a=await this.#o(o,i);if(a.name!==i)throw new Error(`Server created renamed directory "${a.name}" for planned path "${r}". Refusing to map uploads to an unexpected target path.`);this.#e.set(r,a.id)}return e.map(r=>({file:r,directoryId:this.getDirectoryIdForFile(r.relativePath)}))}async loadExistingDirectories(){let e=await this.#s(this.#t);this.#e.clear(),this.#c(e,"")}getDirectoryIdForFile(e){let t=b(e),r=oe.posix.dirname(t);if(r===".")return this.#t;let s=this.#e.get(r);if(!s)throw new Error(`Directory ID not found for path: ${r}`);return s}getExistingDirectoryIdForFile(e){let t=b(e),r=oe.posix.dirname(t);return r==="."?this.#t:this.#e.get(r)??null}async checkAssetsExistence(e,t=!0){if(e.length===0)return[];let r=[];for(let s=0;s<e.length;s+=Gt){let i=e.slice(s,s+Gt),o=await this.#n.post("/assets/check-exists-and-uploaded",{items:i,delete_if_not_exist:t});r.push(...o.items)}return r}async listFilesInSubtree(e={}){let t=[{id:this.#t,relativePath:""}],r=[],s=0;for(;s<t.length;){let i=t.slice(s,s+sr),o=await Promise.all(i.map(a=>this.#i(a)));s+=i.length;for(let a of o)t.push(...a.directories),r.push(...a.files);e.onProgress?.({scannedDirectoryCount:s,queuedDirectoryCount:t.length,fileCount:r.length})}return r}#r(e){let t=new Set;for(let r of e){let s=b(r.relativePath),i=oe.posix.dirname(s);if(i===".")continue;let o=i.split("/");for(let a=0;a<o.length;a++)t.add(o.slice(0,a+1).join("/"))}return Array.from(t).sort((r,s)=>r.split("/").length-s.split("/").length)}async#s(e){return this.#n.get(`/directories/${e}/tree`)}async#i(e){let[t,r]=await Promise.all([this.#n.post("/fs/list/directories",{parent_id:e.id}),this.#n.post("/fs/list/assets",{parent_id:e.id})]);return{directories:t.map(s=>({id:s.id,relativePath:this.#a(e.relativePath,s.name)})),files:r.map(s=>({assetId:s.id,relativePath:this.#a(e.relativePath,s.name),sizeBytes:s.size_bytes,isUploaded:s.is_uploaded??!0,uploadStateKnown:typeof s.is_uploaded=="boolean"}))}}#a(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.#e.set(r,e.id);for(let s of e.children){let i=t===""?".":r;this.#c(s,i)}}async#o(e,t){return this.#n.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as ir}from"posthog-node";var O=null,ve="",dt={};function Ht(n){O||n.config.analytics.disabled||!n.config.analytics.posthogKey||(ve=n.user.id,dt={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}:{}},O=new ir(n.config.analytics.posthogKey,{host:n.config.analytics.posthogHost}),O.identify({distinctId:ve,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 jt(n,e){O&&O.capture({distinctId:ve,event:n,properties:{...dt,...e}})}async function Wt(){let n=O;if(or(),!!n)try{await n.flush()}catch{}}function or(){O=null,ve="",dt={}}import{spawn as xe}from"child_process";import*as mt from"fs";import*as ae from"path";var P=class extends Error{constructor(t,r){super(t);this.stderr=r;this.name="RcloneError"}stderr};function ar(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 lr(n){let e=["lsjson",n.remoteSource,"--recursive","--fast-list"];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function cr(n){let e=["backend","query",`${n.remote}:`,n.query];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function ur(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 dr(n){let e=["backend","copyid",`${n.remote}:`,n.fileId,n.localTargetPath];return n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function $(n,e){let t=e.trim(),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 qt(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 pr(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 a=r[8].trim();return{bytesTransferred:$(parseFloat(r[1]),r[2]),totalBytes:$(parseFloat(r[3]),r[4]),percentComplete:parseFloat(r[5]),speed:$(parseFloat(r[6]),r[7]),eta:a==="-"?0:qt(a)}}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 i=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),o=e.match(/ETA\s+([^\s]+)$/);return{bytesTransferred:$(parseFloat(s[1]),s[2]),totalBytes:$(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:i?$(parseFloat(i[1]),i[2]):0,eta:o&&o[1]!=="-"?qt(o[1]):0}}function pt(n){return new Promise((e,t)=>{let r=xe("rclone",n.args,{stdio:["ignore","pipe","pipe"]}),s="",i=0,o=a=>{for(let l of a.split(`
|
|
4
|
-
`)){if(l.trim().length===0)continue;let c=
|
|
2
|
+
import{Command as li}from"commander";import Ot from"node:path";import{readFileSync as ci}from"node:fs";import{fileURLToPath as ui}from"node:url";import ue from"node:fs/promises";import wt from"node:path";import zn from"fs/promises";import $n from"path";function Bt(n,e){let t=new Map;for(let c of n){let u=$n.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,g)=>m+g.size,0);r.set(c,d)}let s=Array.from(t.keys()).sort(),i=[],o=[],a=0,l=1;for(let c of s){let u=t.get(c),d=r.get(c);if(d>e){if(o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),u.length===1)i.push({batchNumber:l++,files:u,totalSize:d});else for(let m of u)a+m.size>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(m),a+=m.size;continue}a+d>e&&o.length>0&&(i.push({batchNumber:l++,files:o,totalSize:a}),o=[],a=0),o.push(...u),a+=d}return o.length>0&&i.push({batchNumber:l++,files:o,totalSize:a}),i}async function Mt(n){try{await zn.unlink(n)}catch(e){if(e.code!=="ENOENT")throw e}}import f from"chalk";import zt from"log-update";function be(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 et(n,e){let t=be(n,e);return t==="creating-folders"||t==="in-progress"||t==="queued"||t==="paused"?"cancelled":t}function tt(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 nt(n){for(let e of Object.values(n))if(e.status==="queued"||e.status==="in-progress"||e.status==="paused")return!0;return!1}function Z(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 rt(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 st(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 it(n){return Object.values(n).some(e=>e.status==="paused")}import Pi from"axios";var ee=class{#e;#n;#t;#r;#s;#i=0;#a=0;#c=0;#o=0;#u=0;#p=0;constructor(e){this.#e=e?.alphaFast??.1,this.#n=e?.alphaMax??.5,this.#t=e?.consecutiveForBoost??3,this.#r=e?.minSamples??3,this.#s=e?.maxGapSeconds??2}sample(e){let t=Date.now();if(this.#o===0){this.#o=t,this.#u=e;return}let s=(t-this.#o)/1e3,i=e-this.#u;if(s<=0||i<0)return;if(s>this.#s){this.#o=t,this.#u=e;return}let o=i/s;if(this.#p===0)this.#i=o;else{let l=o-this.#i>=0?1:-1;this.#c!==0&&l===this.#c?this.#a++:this.#a=0,this.#c=l;let c=Math.min(1,this.#a/this.#t),u=this.#e+(this.#n-this.#e)*c;this.#i=u*o+(1-u)*this.#i}this.#o=t,this.#u=e,this.#p++}etaSeconds(e){return!this.isWarmedUp||this.#i<=0?0:e/this.#i}adjustTotalBytes(e){this.#u+=e}reset(){this.#i=0,this.#a=0,this.#c=0,this.#o=0,this.#u=0,this.#p=0}serialize(){return{displaySpeedBps:this.#i,lastSampleTimestamp:this.#o,lastSampleTotalBytes:this.#u,sampleCount:this.#p}}get speedBps(){return this.#i}get speedMbps(){return this.#i*8/1e6}get isWarmedUp(){return this.#p>=this.#r}};function D(n){let e={"X-Aspect-Share-Id":n.shareId};return n.shareAuthentication&&(e["X-Aspect-Share-Authentication"]=n.shareAuthentication),e}var te=class{#e;#n;#t;#r;#s;#i;#a;#c;#o;#u;#p;#l;#U;#y;#F;#k;#C;#b;#R;#P;#T;#m;#A;#I;#d;#v;#f;#w;#D;#B;#L;#O;constructor(e){this.#n=e?.minConcurrency??1,this.#t=e?.maxConcurrency??8,this.#e=this.#H(e?.initialConcurrency??this.#n),this.#r=e?.errorThreshold??1,this.#s=(e?.cooldownSeconds??10)*1e3,this.#i=e?.plateauThreshold??.05,this.#a=Math.max(this.#t,Math.floor(e?.sampleWindowSize??64)),this.#c=Math.max(2,Math.floor(e?.minSamples??4)),this.#o=Math.max(1.1,e?.increaseFactor??1.5),this.#u=e?.onChange,this.#p=e?.now??Date.now,this.#l=this.#e,this.#U=0,this.#y=[],this.#F=0,this.#k=0,this.#C=-1,this.#b=0,this.#R=void 0,this.#P=0,this.#T=0,this.#m=0,this.#A=this.#l,this.#I=0,this.#d=1/0,this.#v=0,this.#f=6e4,this.#w=0,this.#D=1/0,this.#B=0,this.#L=0,this.#O=0}recordSuccess(e,t,r){if(e<=0)return;if(r?.generation!==void 0){if(r.generation!==this.#U){r.generation===this.#C&&this.#b>0&&(this.#b--,this.#b===0&&(this.#R=r.completedAtMs??this.#p()));return}if(this.#b>0||this.#R!==void 0&&r.startedAtMs!==void 0&&r.startedAtMs<this.#R)return}else if(this.#k>0){this.#k--;return}let s=r?.completedAtMs??this.#p();for(this.#y.push({bytes:e,completedAtMs:s,startedAtMs:r?.startedAtMs,durationMs:t!==void 0&&t>0?t:void 0});this.#y.length>this.#a;)this.#y.shift();this.#F++,this.#P=0;let i=this.#N();this.#L=i.throughputBps,this.#O=i.latencyMsPerMB,this.#_(i)}recordError(){if(this.#P++,this.#P<this.#r)return;let e=this.#l;e===this.#w&&(this.#D=Math.min(this.#D,e),this.#B=this.#p()+3e4),this.#w=e;let t=this.#H(Math.floor(e/2));this.#T=this.#p()+this.#s,this.#P=0,e<=this.#A&&(this.#A=t,this.#I=0),e>t&&(this.#d=Math.min(this.#d,e),this.#W()),this.#g(t)}get concurrency(){return this.#l}get generation(){return this.#U}get speedBps(){return this.#L}get latencyMsPerMB(){return this.#O}reset(){this.#l=this.#e,this.#U++,this.#y=[],this.#F=0,this.#k=0,this.#C=-1,this.#b=0,this.#R=void 0,this.#P=0,this.#T=0,this.#m=0,this.#A=this.#l,this.#I=0,this.#d=1/0,this.#v=0,this.#f=6e4,this.#w=0,this.#D=1/0,this.#B=0,this.#L=0,this.#O=0,this.#u?.(this.#l)}#_(e){if(this.#y.length<this.#q()||this.#F<this.#q()||e.throughputBps<=0)return;let t=this.#p();if(t<this.#T)return;if(e.averageDurationMs>=2e4&&this.#l>=4){this.#A=Math.max(this.#n,Math.floor(this.#l/2)),this.#I=0,this.#g(this.#A);return}if(this.#I===0){this.#M(e.throughputBps),this.#x(e);return}let r=(e.throughputBps-this.#I)/this.#I;if(r>=this.#i){this.#M(e.throughputBps),this.#x(e);return}if(this.#l>this.#A){let s=r<=-.08,i=r<this.#i;(s||i)&&(this.#d=Math.min(this.#d,this.#l),this.#W(),this.#g(this.#A));return}if(this.#l<this.#A){this.#x(e);return}this.#l===this.#A&&(this.#I=Math.max(this.#I,e.throughputBps),t>=this.#m&&this.#x(e))}#x(e){let t=this.#V();if(this.#l>=t){this.#F=0;return}if(e.averageDurationMs>=5e3&&this.#l>=4&&this.#I>0){this.#F=0;return}if(this.#G()){let s=this.#p();if(this.#v===0){this.#v=s+this.#f,this.#m=this.#v,this.#F=0;return}if(s<this.#v){this.#F=0;return}}let r=this.#h(t);if(r===this.#l){this.#F=0;return}this.#g(r)}#M(e){this.#A=this.#l,this.#I=e,this.#d<=this.#l&&(this.#d=1/0),this.#v=0,this.#f=6e4,this.#m=0}#h(e){if(this.#d<1/0){let s=Math.floor((this.#l+this.#d)/2);return s>this.#l&&s<this.#d?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.#o),r=this.#l+2;return Math.min(e,Math.max(r,t))}#g(e){let t=this.#l,r=this.#U,s=this.#H(e);s!==t&&(this.#E(),this.#l=s,this.#U++,this.#C=r,this.#b=Math.max(0,t-1),this.#R=this.#b===0?this.#p():void 0,this.#k=Math.max(0,t-1),this.#u?.(this.#l))}#E(){this.#y=[],this.#F=0,this.#k=0}#G(){return this.#d<1/0&&this.#l===this.#A&&this.#d<=this.#A+1}#W(){let e=this.#d<1/0&&this.#d<=this.#A+1,t=e?this.#f:1e4;this.#m=this.#p()+t,e&&(this.#v=this.#m,this.#f=Math.min(this.#f*2,3e5))}#q(){return Math.max(this.#c,this.#l)}#V(){return this.#D<1/0&&this.#p()>=this.#B&&(this.#D=1/0,this.#B=0),Math.max(this.#n,Math.min(this.#t,this.#D-1))}#H(e){return Math.max(this.#n,Math.min(this.#t,e))}#N(){let e=0,t=0,r=0,s=0;for(let l of this.#y)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.#y.length<2)return{throughputBps:0,latencyMsPerMB:0,averageDurationMs:0,durationSampleCount:0};let i=this.#y[0],a=this.#y[this.#y.length-1].completedAtMs-i.completedAtMs;return{throughputBps:a>0?e/a*1e3:0,latencyMsPerMB:0,averageDurationMs:a>0?a/Math.max(1,this.#y.length-1):0,durationSampleCount:0}}};var z=class{#e;#n;#t;#r;#s;constructor(e){let t=e===0?null:e;this.#e=t,this.#n=t??0,this.#t=Date.now(),this.#r=[],this.#s=null}setLimit(e){let t=e===0?null:e;if(t===null){this.#e=null,this.#n=0,this.#u();let s=this.#r.splice(0);for(let i of s)i.resolve();return}let r=this.#e;this.#e=t,r===null?(this.#n=t,this.#t=Date.now()):(this.#i(),this.#n=Math.min(this.#n,t)),this.#o()}getLimit(){return this.#e}acquire(e){if(this.#e!==null){if(this.#i(),this.#r.length===0&&this.#n>=e){this.#n-=e;return}return this.#a(e)}}#i(){let e=Date.now(),t=(e-this.#t)/1e3;if(t<=0)return;let r=this.#e,s=t*r,i=this.#r.length>0?Math.max(r,this.#r[0].bytes):r;this.#n=Math.min(this.#n+s,i),this.#t=e}#a(e){return new Promise(t=>{this.#r.push({bytes:e,resolve:t}),this.#s===null&&this.#c()})}#c(){if(this.#r.length===0||this.#e===null){this.#s=null;return}let t=this.#r[0].bytes-this.#n,r=t>0?Math.ceil(t/this.#e*1e3):0;if(r<=0){this.#s=null,this.#o();return}this.#s=setTimeout(()=>{this.#s=null,this.#i(),this.#o()},r)}#o(){for(;this.#r.length>0;){if(this.#e===null){let t=this.#r.splice(0);for(let r of t)r.resolve();return}this.#i();let e=this.#r[0];if(this.#n>=e.bytes)this.#n-=e.bytes,this.#r.shift(),e.resolve();else{this.#c();return}}}#u(){this.#s!==null&&(clearTimeout(this.#s),this.#s=null)}};function Nt(n){let e=`[${n}]`;return{info:(...t)=>console.info(e,...t),warn:(...t)=>console.warn(e,...t),error:(...t)=>console.error(e,...t)}}var ot=Nt("transfer");var Ae=class{uploadAssets={};uploadGroups={};#e=new ee;get uploadSpeedState(){return this.#e.serialize()}uploadStats={uploadSpeedMbps:0,timeRemainingSeconds:0,formattedSpeed:"Calculating...",formattedTime:"Calculating..."};dirtyAssetIds=new Set;dirtyGroupIds=new Set;dirtyHistoryGroupIds=new Set;#n(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()}#r(e){this.dirtyAssetIds.add(e)}#s(e){this.dirtyGroupIds.add(e)}addUploadAsset({assetId:e,fileReader:t,abortController:r,parentId:s,projectId:i,groupId:o,chunkSize:a,shareContext:l}){this.uploadAssets[e]={assetId:e,totalBytesToUpload:t.size,bytesUploaded:0,status:"queued",fileName:t.name,createdAt:new Date().toISOString(),i:Object.keys(this.uploadAssets).length,parentId:s,projectId:i,groupId:o,retryCount:0,chunkSize:a??0,fileReader:t,abortController:r,shareContext:l},this.#r(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,i=Math.min(t,r.totalBytesToUpload);r.bytesUploaded=i,r.status=s,this.#r(e)}markUploadInProgress(e){let t=this.uploadAssets[e];t&&(t.status="in-progress",this.#r(e))}markUploadSuccess(e){let t=this.uploadAssets[e];t&&(t.status="success",t.bytesUploaded=t.totalBytesToUpload,this.#r(e),this.#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.#r(e),this.#n(s),this.#t(),this.cleanupOnCompletion(e)}removeUploadAsset(e){let r=this.uploadAssets[e]?.bytesUploaded??0;delete this.uploadAssets[e],this.#r(e),this.#n(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.#r(e))}resetAssetForRetrying(e){let t=this.uploadAssets[e];t&&(t.status="queued",t.bytesUploaded=0,t.retryCount=0,this.#r(e))}pauseUpload(e){let t=this.uploadAssets[e];if(!t||t.status!=="queued"&&t.status!=="in-progress")return;let r=0;if(t.chunkedState){let{completedChunkIndices:i,chunkSize:o}=t.chunkedState;for(let a of i){let l=a*o,c=Math.min(l+o,t.totalBytesToUpload);r+=c-l}}let s=t.bytesUploaded-r;t.status="paused",t.bytesUploaded=r,this.#r(e),this.#n(s),this.#t(),t.abortController.abort()}unpauseUpload(e){let t=this.uploadAssets[e];t&&t.status==="paused"&&(t.status="queued",this.#r(e))}pauseUploadGroup(e){let t=this.uploadGroups[e];if(t&&!t.isCreatingFolders){t.isPaused=!0,this.#s(e);for(let r of t.assetIds)this.pauseUpload(r)}}unpauseUploadGroup(e){let t=this.uploadGroups[e];t&&(t.isPaused=!1,this.#s(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.#r(e),this.#n(r),this.#t(),this.cleanupOnCompletion(e)}setChunkedState(e,t){let r=this.uploadAssets[e];r&&(r.chunkedState=t,this.#r(e))}addCompletedChunkIndex(e,t){let r=this.uploadAssets[e];!r||!r.chunkedState||(r.chunkedState={...r.chunkedState,completedChunkIndices:[...r.chunkedState.completedChunkIndices,t]},this.#r(e))}clearChunkedState(e){let t=this.uploadAssets[e];t&&(t.chunkedState=void 0,this.#r(e))}hasGroupsCreatingFolders(){return Object.values(this.uploadGroups).some(e=>e.isCreatingFolders===!0)}areAllUploadsPaused(){return st(this.uploadAssets)}hasPausedUploads(){return it(this.uploadAssets)}getUploadAsset(e){return this.uploadAssets[e]}getSerializableAsset(e){let t=this.uploadAssets[e];if(t)return this.#c(t)}getUploadSummary(){return Z(this.#u())}getAllUploadAssetsSortedByRecent(){return Object.values(this.uploadAssets).map(e=>this.#c(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.#c(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.#s(t),t}updateUploadGroup(e,t){let r=this.uploadGroups[e];r&&(Object.assign(r,t),this.#s(e))}addAssetToGroup(e,t){let r=this.uploadGroups[e];r&&(r.assetIds.push(t),this.#s(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.#s(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.#r(r);delete this.uploadGroups[e],this.#s(e)}getUploadGroup(e){let t=this.uploadGroups[e];if(t)return this.#o(t)}getAllUploadGroups(){return Object.values(this.uploadGroups).map(e=>this.#o(e)).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}getUploadGroupProgress(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return rt(this.#o(t),r)}getUploadGroupStatus(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e);return be(this.#o(t),r)}getAssetsByParentId(e){return Object.values(this.uploadAssets).filter(t=>t.parentId===e).map(t=>this.#c(t))}getActiveUploadGroups(){return Object.values(this.uploadGroups).filter(e=>{let t=this.getUploadGroupStatus(e.id);return t&&["queued","creating-folders","in-progress"].includes(t)}).map(e=>this.#o(e))}cleanupOnCompletion(e){let t=this.uploadAssets[e];if(!t)return;let r=t.groupId;if(r){let i=this.uploadGroups[r];if(i){let o=this.getGroupAssets(r),a=this.#o(i);this.dirtyHistoryGroupIds.add(r),!o.some(c=>c.status==="queued"||c.status==="in-progress")&&!i.completedAt&&(i.completedAt=new Date().toISOString(),this.#s(r))}}let s=this.getUploadSummary();if(s.cancelledAssetCount+s.failedAssetCount+s.successAssetCount===s.totalAssetCount)for(let i of Object.keys(this.uploadAssets)){let o=this.uploadAssets[i];o&&(o.bytesUploaded=0,this.#r(i))}}updateUploadStats(){let e=this.getUploadSummary(),t=e.queuedAssetCount>0||e.inProgressAssetCount>0;t&&this.#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:this.#i(r),formattedTime:this.#a(s)}}#i(e){return!Number.isFinite(e)||e<=0?"Calculating...":e<1?`${(e*1e3).toFixed(0)} Kbps`:`${e.toFixed(1)} Mbps`}#a(e){if(!Number.isFinite(e)||e<=0)return"Calculating...";let t=Math.floor(e/3600),r=Math.floor(e%3600/60),s=Math.floor(e%60);return t>0?`${t}h ${r}m left`:r>0?`${r}m ${s}s left`:`${s}s left`}buildHistoryItem(e){let t=this.uploadGroups[e];if(!t)return null;let r=this.getGroupAssets(e),s=this.#o(t);return{groupId:t.id,name:t.name,type:t.type,fileCount:t.fileCount,folderCount:t.folderCount,topLevelFileCount:t.topLevelFileCount,topLevelFolderCount:t.topLevelFolderCount,status:et(s,r),createdAt:t.createdAt,completedAt:t.completedAt,rootDirectoryId:t.rootDirectoryId,projectId:t.projectId,errorMessage:t.errorMessage,conflictResolution:t.conflictResolution}}#c({fileReader:e,abortController:t,shareContext:r,...s}){return s}#o({fileReaders:e,...t}){return t}#u(){let e={};for(let[t,r]of Object.entries(this.uploadAssets))e[t]=this.#c(r);return e}#p(){let e={};for(let[t,r]of Object.entries(this.uploadGroups))e[t]=this.#o(r);return e}getSerializableSnapshot(){return{uploadAssets:this.#u(),uploadGroups:this.#p(),uploadStats:{...this.uploadStats},uploadSpeedState:this.uploadSpeedState}}getDirtyDelta(){let e={};for(let r of this.dirtyAssetIds){let s=this.uploadAssets[r];s&&(e[r]=this.#c(s))}let t={};for(let r of this.dirtyGroupIds){let s=this.uploadGroups[r];s&&(t[r]=this.#o(s))}return{assets:e,groups:t}}clearDirtyFlags(){this.dirtyAssetIds.clear(),this.dirtyGroupIds.clear(),this.dirtyHistoryGroupIds.clear()}};function jn(n,e){let t=new Date(n).getTime(),r=Date.now();return t-r<=e}var Fe=class{#e;#n=new Map;#t=new Map;constructor(e){this.#e=e}seedToken(e,t,r){this.#n.set(e,{token:t,expiresAt:r})}async getToken(e,t){let r=this.#n.get(e);if(r&&!jn(r.expiresAt,3e5))return r.token;let s=this.#t.get(e);if(s)return s;let i=t?D(t):void 0,o=this.#e.post(`/assets/${e}/token`,{},i).then(a=>{if(!a.token)throw new Error("Token refresh failed: no token in response");return this.#n.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,o),o}clearCache(e){e?this.#n.delete(e):this.#n.clear()}};var we=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.#n(e);return r?(r.completedChunkIndices.add(t),r.completedChunkIndices.size>=r.totalChunks):!1}pauseAsset(e){let t=this.#n(e);t&&(t.isPaused=!0)}unpauseAsset(e){let t=this.#n(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.#n(e);return t?t.completedChunkIndices.size>=t.totalChunks:!1}clear(){this.#e=[]}#n(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,qn=["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"];function $(n){let e=n.replace(Wn,"_");e=e.replace(/[. ]+$/,""),(!e||e==="."||e==="..")&&(e="unnamed");let t=e.includes(".")?e.substring(0,e.lastIndexOf(".")):e;qn.includes(t.toUpperCase())&&(e=`_${e}`);let r=new TextEncoder;if(r.encode(e).length>255){let s=e.lastIndexOf("."),i=s>0?e.substring(s):"",o=s>0?e.substring(0,s):e,l=255-r.encode(i).length;for(;r.encode(o).length>l&&o.length>0;)o=o.slice(0,-1);e=o+i}return e}var L=class extends Error{constructor(){super("Upload cancelled"),this.name="CancelledError"}};function _(n){return n instanceof L||n instanceof Error&&n.name==="CancelledError"||n instanceof Error&&n.name==="CanceledError"||n instanceof Error&&n.name==="AbortError"}function Zn(n){return _(n)||n instanceof Error&&n.name==="NoAuthError"}function er(n){return new Promise(e=>setTimeout(e,n))}function tr(n){return n instanceof Blob?n.size:n.byteLength}var ne=class{#e;#n;#t;#r;#s;#i;#a;#c;#o;#u;#p;#l;#U;#y=null;#F=0;#k=!1;#C=[];#b=new Set;#R=!1;#P=!1;#T=!1;#m=[];#A=!1;#I=!1;#d=new we;#v=0;#f=new Map;#w=new Map;#D=[];#B=!1;#L=null;#O;#_="keep_both";#x=new Map;#M=null;#h=!1;#g=null;#E=!1;constructor(e){this.#e=e.httpClient,this.#n=new Fe(e.httpClient),this.#t=new Ae,this.#r=e.historyStore??null,this.#s=e.settingsStore??null,this.#i=e.analytics??null,this.#a=e.logger??ot,this.#c=e.onChange??null,this.#o=e.onClear??null,this.#u=e.onSummary??null,this.#p=e.onConcurrencyAdjusted??null,this.#U=e.deltaIntervalMs??333;let t=e.maxConcurrency??4;if(e.adaptiveConcurrency!==!1){let r=e.adaptiveConcurrencyConfig;this.#g=new te({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 i=this.#l;if(this.setMaxConcurrency(s),i===s)return;let o=this.#E?"reset":s>i?"probe_increase":"error_decrease",a=Math.round(this.#g.speedBps*8/1e6*100)/100,l=Math.round(this.#g.latencyMsPerMB*100)/100;this.#a.info(`Adaptive concurrency: ${i} \u2192 ${s} (${o}), measuredAt=${i}, speed=${a}Mbps, latency=${l}ms/MB`),this.#p?.({previousConcurrency:i,newConcurrency:s,reason:o,speedMbps:a,latencyMsPerMB:l})},now:r?.now}),this.#l=this.#g.concurrency}else this.#l=t;this.#r&&(this.#C=this.#r.load()),this.#s&&(this.#L=this.#s.getBandwidthLimitBps(),this.#_=this.#s.getConflictResolution()),this.#O=new z(this.#L),(this.#c||this.#u)&&(this.#y=setInterval(()=>{this.#ce()},this.#U)),this.#i&&(this.#M=setInterval(()=>{this.#de()},6e4))}startUpload(e){let t=e.assetId||crypto.randomUUID(),r=!!e.assetId,s;if(r){let o=this.#t.getUploadAsset(t);if(!o)throw new Error(`Cannot retry: asset ${t} not found`);s=o.chunkSize}else{if(e.chunkSize===void 0||e.chunkSize===null)throw new Error("chunkSize is required for new uploads");s=e.chunkSize}let i=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=i,a.fileReader=e.fileReader,e.shareContext&&(a.shareContext=e.shareContext)}else this.#t.addUploadAsset({assetId:t,fileReader:e.fileReader,abortController:i,parentId:e.directoryId,projectId:e.projectId,groupId:e.groupId,chunkSize:s,shareContext:e.shareContext});return this.#m.push(t),this.#G(),this.#S(),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.#x.set(t,Date.now()),this.#i?.("upload:started",{file_count:e.fileCount,total_bytes:e.totalBytes??0,has_folders:e.folderCount>0,project_id:e.projectId}),this.#t.dirtyHistoryGroupIds.add(t),this.#$(),this.#S(),t}pauseUpload(e){let t=this.#t.getUploadAsset(e);this.#t.pauseUpload(e),this.#m=this.#m.filter(r=>r!==e),this.#d.pauseAsset(e),!this.#h&&t&&this.#i&&this.#i("upload:file_paused",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""}),this.#S()}unpauseUpload(e){this.#t.unpauseUpload(e),this.#S()}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,i=t.bytesUploaded,o=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.#d.removeAsset(e),this.#f.delete(e),this.#w.delete(e),this.#t.markUploadCancelled(e),this.#t.clearChunkedState(e),t.fileReader.close?.(),!this.#h&&this.#i&&this.#i("upload:file_cancelled",{file_name:r,file_size:s,bytes_uploaded:i,project_id:o??""}),this.#S(),this.#N(),this.#G(),this.#Q(),a&&(this.#D.push(a),this.#X())}cancelAllUploads(){let e=this.#J();this.#h=!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.#h=!1}this.#i?.("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.#h&&this.#i&&this.#i("upload:file_resumed",{file_name:t.fileName,file_size:t.totalBytesToUpload,bytes_uploaded:t.bytesUploaded,project_id:t.projectId??""});let r=new AbortController;t.abortController=r,this.#t.unpauseUpload(e),this.#d.hasAsset(e)?(this.#d.unpauseAsset(e),this.#S(),this.#d.isAssetComplete(e)?this.#Y(e).catch(s=>{this.#z(e,s)}):this.#N()):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.#h;this.#h=!0,this.#t.pauseUploadGroup(e);for(let s of t.assetIds)this.#m=this.#m.filter(i=>i!==s),this.#d.pauseAsset(s);this.#h=r,this.#h||this.#te(e,t,"upload:group_paused"),this.#S()}unpauseUploadGroup(e){this.#t.unpauseUploadGroup(e),this.#S()}cancelUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;let{totalBytes:r,bytesUploaded:s,filesRemaining:i}=this.#ee(t),o=this.#h;this.#h=!0;for(let a of t.assetIds)this.cancelUpload(a);t.assetIds.length===0&&(this.#t.finalizeEmptyGroup({groupId:e,status:"cancelled"}),this.#$(),this.#S()),this.#h=o,this.#h||this.#i?.("upload:group_cancelled",{file_count:t.assetIds.length,files_remaining:i,total_bytes:r,bytes_uploaded:s,project_id:t.projectId}),this.#x.delete(e)}resumeUploadGroup(e){let t=this.#t.uploadGroups[e];if(!t)return;this.#h||this.#te(e,t,"upload:group_resumed");let r=this.#h;this.#h=!0,this.#t.unpauseUploadGroup(e);for(let s of t.assetIds){let i=this.#t.getUploadAsset(s);i&&i.status==="paused"&&this.resumeUpload(s)}this.#h=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.#S()}markEmptyGroupFailed(e,t){let r=this.#t.uploadGroups[e];r&&(r.assetIds.length>0||r.finalizedStatus||(this.#a.error("Empty group upload failed",{groupId:e,groupName:r.name,errorMessage:t}),this.#t.finalizeEmptyGroup({groupId:e,status:"all-failed",errorMessage:t}),this.#$(),this.#x.delete(e),this.#S()))}markEmptyGroupCompleted(e){this.#t.finalizeEmptyGroup({groupId:e,status:"success"}),this.#$(),this.#x.delete(e),this.#S()}addAssetToGroup(e,t){this.#t.addAssetToGroup(e,t)}pauseAllUploads(){let e=this.#J();this.#h=!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.#h=!1}this.#i?.("upload:all_paused",e),this.#S()}resumeAllUploads(){let e=this.#J();this.#h=!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.#h=!1}this.#i?.("upload:all_resumed",e),this.#S()}clearAllUploads(){this.#m=[],this.#d.clear(),this.#f.clear(),this.#w.clear(),this.#t.clearAllUploads(),this.#t.uploadGroups={},this.#g&&(this.#E=!0,this.#g.reset(),this.#E=!1),this.#o?.({all:!0}),this.#u?.(this.#j())}clearHistory(){this.#C=[],this.#r?.clear(),this.#R=!0,this.#b.clear(),this.#T=!0,this.#S()}removeHistoryItem(e){this.#C=this.#C.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#b.add(e),this.#T=!0,this.#S()}removeGroup(e){this.#t.removeUploadGroup(e),this.#C=this.#C.filter(t=>t.groupId!==e),this.#r?.remove(e),this.#b.add(e),this.#T=!0,this.#o?.({groupId:e}),this.#u?.(this.#j()),this.#S()}getHttpClient(){return this.#e}setBandwidthLimit(e){let t=e!==this.#L;this.#L=e,this.#O.setLimit(e),this.#s?.setBandwidthLimitBps(e),t&&this.#g&&(this.#E=!0,this.#g.reset(),this.#E=!1),this.#T=!0,this.#S()}getBandwidthLimit(){return this.#L}setConflictResolution(e){this.#_=e,this.#s?.setConflictResolution(e),this.#T=!0,this.#S()}getConflictResolution(){return this.#_}getGroupConflictResolution(e){return this.#t.getUploadGroup(e)?.conflictResolution??this.#_}setMaxConcurrency(e){this.#l=e,this.#N()}getSnapshot(){return this.#t.updateUploadStats(),{...this.#t.getSerializableSnapshot(),uploadHistory:[...this.#C??[]],uploadSummary:this.#j(),bandwidthLimitBps:this.#L,conflictResolution:this.#_}}getUploadAsset(e){return this.#t.getSerializableAsset(e)}getUploadSummary(){return this.#j()}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 nt(this.#t.getSerializableSnapshot().uploadAssets)}getServerAssetIdsToCancel(){return tt(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.#P=!0,this.#y&&(clearInterval(this.#y),this.#y=null),this.#M&&(clearInterval(this.#M),this.#M=null),this.#m=[],this.#d.clear();for(let e of Object.values(this.#t.uploadAssets))e.abortController.abort(),e.fileReader.close?.()}#G(){this.#I||(this.#I=!0,queueMicrotask(()=>{this.#I=!1,this.#W().catch(e=>{this.#a.error("Initiation pipeline error",{queueLength:this.#m.length},e)})}))}async#W(){if(!this.#A){this.#A=!0;try{await this.#q()}finally{this.#A=!1}}}async#q(){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 i=this.#m[0],o=this.#t.getUploadAsset(i);if(!o||o.status==="cancelled"){this.#m.shift(),s--;continue}if(this.#m.shift(),r.push(i),o.chunkedState)try{this.#V(i,o),this.#N()}catch(a){_(a)||this.#z(i,a)}else t.push(i)}if(t.length>0){let s=new Map;for(let i of t){let a=this.#t.getUploadAsset(i)?.shareContext?.shareId??"",l=s.get(a);l||(l=[],s.set(a,l)),l.push(i)}for(let i of s.values())try{await this.#H(i)}catch(o){for(let a of i)this.#z(a,o instanceof Error?o:new Error(String(o)))}this.#N()}}}#V(e,t){let r=t.chunkedState,s={serverAssetId:r.assetId,chunkIds:r.chunkIds,chunkSize:r.chunkSize,totalChunks:r.totalChunks,sizeBytes:r.sizeBytes},i=r.completedChunkIndices;this.#f.set(e,s);let o=new Array(s.totalChunks).fill(0);if(i.length>0){for(let l of i){let c=l*s.chunkSize,u=Math.min(c+s.chunkSize,t.totalBytesToUpload);o[l]=u-c}let a=o.reduce((l,c)=>l+c,0);this.#t.updateUploadProgress(e,a)}if(this.#w.set(e,o),s.totalChunks===0||i.length>=s.totalChunks){this.#Y(e).catch(a=>{this.#z(e,a)});return}this.#d.registerAsset({assetId:e,totalChunks:s.totalChunks,completedChunkIndices:i})}async#H(e){let t=[],r=[];for(let a of e){let l=this.#t.getUploadAsset(a);if(!l||l.status==="cancelled")continue;let c=$(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}),r.push(a)}if(t.length===0)return;let s=this.#t.getUploadAsset(r[0]),i=s?.shareContext?D(s.shareContext):void 0,o=await this.#e.post("/assets/chunked/initiate",t,i);for(let a=0;a<r.length;a++){let l=r[a],c=o[a];if(!c||c.error){this.#z(l,new Error(c?.error??"Unknown batch initiation error"));continue}if(c.skipped){let S=this.#t.getUploadAsset(l);S&&(this.#t.adjustSpeedBaselineForSkippedBytes(S.totalBytesToUpload),this.#t.markUploadSuccess(l),this.#t.dirtyHistoryGroupIds.add(S.groupId??""),this.#$(),S.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.#D.push(u.asset_id),this.#X());continue}let m=Math.ceil(d.totalBytesToUpload/u.chunk_size),g=Array.from({length:m},()=>crypto.randomUUID());this.#n.seedToken(u.asset_id,u.token,u.token_expires_at);let p={serverAssetId:u.asset_id,chunkIds:g,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 A=new Array(p.totalChunks).fill(0);if(this.#w.set(l,A),p.totalChunks===0){this.#Y(l).catch(S=>{this.#z(l,S)});continue}this.#d.registerAsset({assetId:l,totalChunks:p.totalChunks,completedChunkIndices:[]})}}#N(){if(!this.#P)for(;this.#v<this.#l;){let e=this.#d.claimNextChunk();if(!e)break;this.#v++;let{assetId:t,chunkIndex:r}=e,s=this.#g?.generation;this.#re(t,r,s).then(i=>{this.#v--,this.#ie(t,r,i),this.#N()}).catch(i=>{if(this.#v--,_(i)){this.#N();return}this.#oe(t,r,i),this.#N()})}}async#re(e,t,r){let s;for(let i=0;i<3;i++)try{let o=this.#w.get(e);return o&&(o[t]=0,this.#K(e)),await this.#se(e,t,r)}catch(o){if(_(o))throw o;if(s=o instanceof Error?o:new Error(String(o)),this.#g?.recordError(),this.#ae(e,t,s,i),i===2)throw s;let a=this.#w.get(e);a&&(a[t]=0,this.#K(e));let l=1e3*Math.pow(2,i);await er(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 i=this.#f.get(e);if(!i)throw new Error(`No chunk metadata for asset ${e}`);let o=t*i.chunkSize,a=Math.min(o+i.chunkSize,s.totalBytesToUpload),l=await s.fileReader.readChunk(o,a),c=tr(l);if(s.abortController.signal.aborted)throw new L;let u=i.chunkIds[t],d=await this.#n.getToken(i.serverAssetId,s.shareContext),m=`/uploads/chunks/${u}`,g=Date.now(),p=await this.#e.putWithToken(m,l,d,{signal:s.abortController.signal,onProgress:T=>{let E=this.#w.get(e);E&&(E[t]=T,this.#K(e))},contentType:"application/octet-stream",limiter:this.#O}),A=Date.now(),S=p.uploadCompletedAtMs??A,y=S-g;if(!p.status||p.status<200||p.status>=300)throw this.#a.error("Chunk upload returned unexpected status",{chunkIndex:t,chunkId:u,assetId:e,serverAssetId:i.serverAssetId,chunkSizeBytes:c,durationMs:y,httpStatus:p.status,statusText:p.statusText,responseBody:p.data,responseHeaders:p.headers}),new Error(`Chunk ${t} upload failed: unexpected status ${p.status}`);let Se=this.#w.get(e);return Se&&(Se[t]=c,this.#K(e)),{durationMs:y,startedAtMs:g,completedAtMs:S,adaptiveGeneration:r}}#K(e){let t=this.#w.get(e);if(!t)return;let r=t.reduce((s,i)=>s+i,0);this.#t.updateUploadProgress(e,r)}#ie(e,t,r){if(this.#g){let i=this.#f.get(e);if(i){let o=t*i.chunkSize,l=Math.min(o+i.chunkSize,i.sizeBytes)-o;this.#g.recordSuccess(l,r.durationMs,{generation:r.adaptiveGeneration,startedAtMs:r.startedAtMs,completedAtMs:r.completedAtMs})}}this.#t.addCompletedChunkIndex(e,t),this.#d.markChunkCompleted(e,t)&&this.#Y(e).catch(i=>{this.#z(e,i)})}#oe(e,t,r){this.#z(e,r)}#ae(e,t,r,s){if(!this.#i)return;let i=this.#t.getUploadAsset(e);if(!i)return;let o=this.#f.get(e);if(!o)return;let a=t*o.chunkSize,c=Math.min(a+o.chunkSize,o.sizeBytes)-a,u=r,d=typeof u.code=="string"?u.code:null,m=u.response?.status,g=typeof m=="number"?m:null,p=r.cause?r.cause instanceof Error?r.cause.message:String(r.cause):null;this.#i("upload:chunk_error",{file_name:i.fileName,file_size:i.totalBytesToUpload,chunk_index:t,chunk_size:c,chunks_total:o.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:g,error_stack:r.stack??null,error_cause:p,project_id:i.projectId??""})}#le(e,t,r,s){if(!this.#i||_(t))return;let i=t instanceof Error?t.message:"Unknown error",o=t,a=t instanceof Error&&t.cause?t.cause instanceof Error?t.cause.message:String(t.cause):null,l=typeof o.code=="string"?o.code:null,c=o.response?.status,u=typeof c=="number"?c:null,d=this.#f.get(e.assetId);this.#i("upload:file_error",{file_name:e.fileName,file_size:e.totalBytesToUpload,bytes_uploaded:e.bytesUploaded,chunks_completed:e.chunkedState?.completedChunkIndices.length??0,chunks_total:d?.totalChunks??0,attempt:r+1,max_attempts:4,is_final_attempt:s,error_type:t instanceof Error?t.name:"Unknown",error_message:i,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 r=this.#f.get(e);if(!r)return;if(t.abortController.signal.aborted)throw new L;let s=crypto.randomUUID(),i=JSON.stringify(r.chunkIds),o=new TextEncoder().encode(i),a=await this.#n.getToken(r.serverAssetId,t.shareContext),l=`/uploads/manifests/${s}`;try{await this.#e.putWithToken(l,o,a,{signal:t.abortController.signal,contentType:"application/json"})}catch(c){throw _(c)||this.#a.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?D(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.#a.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.#S(),this.#f.delete(e),this.#w.delete(e),this.#d.removeAsset(e),await t.fileReader.close?.(),this.#ne(e),this.#G(),this.#Q()}#z(e,t){let r=this.#t.getUploadAsset(e);if(!r||_(t)||r.status==="paused"||r.status==="cancelled")return;let s=r.retryCount,i=s>=3||Zn(t);if(this.#le(r,t,s,i),i){let o=t instanceof Error?t.message:"Unknown error";this.#a.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,o),this.#d.removeAsset(e),this.#f.delete(e),this.#w.delete(e),this.#$(),this.#S(),this.#ne(e),this.#G(),this.#Q()}else{this.#a.warn("Asset upload failed, scheduling retry",{assetId:e,fileName:r.fileName,retryAttempt:s+1,maxRetries:3},t);let o=r.chunkedState;r.abortController.abort(),this.#d.removeAsset(e),this.#f.delete(e),this.#w.delete(e),this.#t.resetAssetForRetryQueue(e),this.#S(),this.#G();let a=2e3*Math.pow(2,s);setTimeout(()=>{if(this.#P)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:o,shareContext:l.shareContext})},a)}}#Q(){this.#g&&(this.hasActiveUploads()||(this.#E=!0,this.#g.reset(),this.#E=!1))}#X(){this.#B||(this.#B=!0,queueMicrotask(()=>{this.#B=!1;let e=this.#D.splice(0);e.length!==0&&this.#e.post("/assets/cancel-uploads",{asset_ids:e}).catch(t=>{this.#a.error("Failed to batch abort uploads",{assetIds:e},t)})}))}#j(){return Z(this.#t.getSerializableSnapshot().uploadAssets)}#S(){this.#k||(this.#k=!0,queueMicrotask(()=>{this.#k=!1,this.#ue()}))}#ce(){this.#Z(!0)}#ue(){this.#Z(!1)}#Z(e){if(this.#P||!this.#c&&!this.#u)return;e?this.#t.updateUploadStats():(this.#F++,this.#F%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,i=this.#R?!0:void 0,o=this.#b.size>0?[...this.#b]:void 0;this.#R=!1,this.#b.clear();let a=this.#j(),l={assets:t.assets,groups:t.groups,uploadStats:{...this.#t.uploadStats},uploadSpeedState:this.#t.uploadSpeedState,historyItems:s,removedHistoryGroupIds:o,historyCleared:i,uploadSummary:a,bandwidthLimitBps:this.#L,conflictResolution:this.#_};this.#t.clearDirtyFlags(),this.#c?.(l),this.#u?.(a)}#ee(e){let t=0,r=0,s=0;for(let i of e.assetIds){let o=this.#t.getUploadAsset(i);o&&(t+=o.totalBytesToUpload,r+=o.bytesUploaded,o.status!=="success"&&o.status!=="failed"&&o.status!=="cancelled"&&s++)}return{totalBytes:t,bytesUploaded:r,filesRemaining:s}}#J(){let e=0,t=0,r=0,s=0;for(let i of Object.values(this.#t.uploadGroups)){e++;for(let o of i.assetIds){let a=this.#t.getUploadAsset(o);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.#i||this.#P))for(let e of Object.values(this.#t.uploadGroups)){let t=!1,r=0,s=0,i=0,o=0,a=0,l=0,c=0,u=0,d=0,m=0;for(let A of e.assetIds){let S=this.#t.getUploadAsset(A);if(!S)continue;let y=S.totalBytesToUpload;switch(r+=y,s+=S.bytesUploaded,S.status){case"success":i++,o+=y;break;case"failed":a++,l+=y;break;case"cancelled":c++,u+=y;break;case"in-progress":d++,t=!0;break;case"queued":m++,t=!0;break;case"paused":t=!0;break}}if(!t)continue;let g=this.#x.get(e.id),p=g?Date.now()-g:0;this.#i("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:i,succeeded_bytes:o,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.#i)return;let{totalBytes:s,bytesUploaded:i}=this.#ee(t);this.#i(r,{file_count:t.fileCount,total_bytes:s,bytes_uploaded:i,project_id:t.projectId})}#ne(e){if(!this.#i)return;let t=this.#t.getUploadAsset(e);if(!t?.groupId)return;let r=this.#t.uploadGroups[t.groupId];if(!r)return;let s=!0,i=0,o=0,a=0,l=0,c=0,u=0,d=0;for(let p of r.assetIds){let A=this.#t.getUploadAsset(p);if(!A)continue;let S=A.totalBytesToUpload;if(d+=S,A.status==="success")i++,o+=S;else if(A.status==="failed")a++,l+=S;else if(A.status==="cancelled")c++,u+=S;else{s=!1;break}}if(!s)return;let m=this.#x.get(r.id),g=m?Date.now()-m:0;this.#i("upload:group_completed",{file_count:r.assetIds.length,total_bytes:d,duration_ms:g,project_id:r.projectId,succeeded_count:i,succeeded_bytes:o,failed_count:a,failed_bytes:l,cancelled_count:c,cancelled_bytes:u}),this.#x.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.#r)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(i=>i.groupId===t);s>=0?this.#C[s]=r:this.#C.unshift(r)}}Object.keys(e).length>0&&this.#r.merge(e)}};var re=class{#e=65536;#n=0;async*createIterator(e,t,r){let s=0,i=Math.max(65536,Math.min(e.byteLength,this.#e)),o=this.#n;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);i=Math.max(65536,Math.min(e.byteLength,p))}let c=Math.min(s+i,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 g=performance.now()-m;if(s=c,!l){if(g>=.5){let p=d/g*1e3;o=o===0?p:o*(1-.3)+p*.3}else o===0&&(i=Math.min(e.byteLength,i*2));if(o>0){let p=Math.round(o*50/1e3);i=Math.max(65536,Math.min(e.byteLength,p))}}this.#e=i,this.#n=o}}};var h=(n,e=2)=>{if(n===0)return"0 B";let t=1024,r=e<0?0:e,s=["B","KB","MB","GB","TB","PB","EB"],i=Math.floor(Math.log(n)/Math.log(t));return`${(n/Math.pow(t,i)).toFixed(r)} ${s[i]}`},Re=n=>{if(n===null)return null;let t=n*8/(1024*1024);return t<1?`${(t*1024).toFixed(0)} Kbps`:`${t.toFixed(1)} Mbps`},se=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`};var rr=1e3,lt=class{#e=null;#n=!1;#t=null;#r=null;#s=null;#i=new Map;#a=null;#c=null;#o=null;#u=null;start(){this.#n||(this.#n=!0,this.#i.clear(),this.#a=null,this.#c=null,this.#o=null,this.#u=null,this.#e=setInterval(()=>this.render(),rr))}stop(){this.#n&&(this.#n=!1,this.#e&&(clearInterval(this.#e),this.#e=null),this.render(),zt.done())}updateSnapshot(e){this.#t=e}updateBatchState(e){this.#r=e}updateDownloadProgress(e){if(!e){this.#s=null;return}let t=e.percentComplete>=100||e.bytesTransferred>=e.totalBytes;!t&&e.speed>0&&(this.#o=e),this.#s=t&&this.#o?{...e,speed:this.#o.speed,eta:this.#o.eta}:e}persistCurrentBatchLine(){!this.#r||this.#r.currentPhase!=="complete"||this.#i.set(this.#r.currentBatch,this.#y(this.#r))}resetUploadSnapshot(){this.#t=null,this.#s=null,this.#o=null,this.#u=null}render(){if(!this.#n)return;let e=this.#r?this.#U(this.#r):this.#l();zt(e.join(`
|
|
3
|
+
`))}#p(e,t){let r=[`${f.green(h(t.bytesTransferred))} / ${f.gray(h(t.totalBytes))}`,f.cyan(`${t.percentComplete.toFixed(1)}%`),f.magenta(Re(t.speed)??"..."),`${f.yellow("ETA")}: ${f.yellow(se(t.eta)??"...")}`];return`${f.blue(e)}: ${r.join(" | ")}`}#l(){let e=this.#m();return[this.#P(e),this.#T(e)]}#U(e){let t=[];for(let r=1;r<e.currentBatch;r++){let s=this.#i.get(r);s&&t.push(s)}return t.push(this.#y(e)),t.push(this.#k(e)),t}#y(e){let t=`Batch ${e.currentBatch}/${e.totalBatches}`;switch(e.currentPhase){case"downloading":return this.#s?`${t}: ${this.#p("Downloading",this.#s)}`:`${t}: ${f.blue("Downloading...")}`;case"scanning":return`${t}: ${f.yellow(e.extraDetails??"Scanning...")}`;case"syncing_folders":return`${t}: ${f.yellow(e.extraDetails??"Syncing folders...")}`;case"uploading":return this.#F(t,e);case"cleaning":return`${t}: ${f.yellow("Cleaning...")}`;case"complete":return`${t}: ${f.green("Complete")} (${e.batchFilesTotal} files, ${h(e.batchBytesTotal)}${e.extraDetails?`, ${e.extraDetails}`:""})`}}#F(e,t){let r=this.#m(),s=r.successFileCount+r.failedFileCount+r.cancelledFileCount,i=Math.max(t.batchFilesTotal-t.batchFilesSkipped,0),o=Math.max(t.batchBytesTotal-t.batchBytesSkipped,0),a=o>0?(r.uploadedBytes/o*100).toFixed(1):"0.0",l=this.#R(t,r,o),c=l?.formattedSpeed??null,u=l?.formattedTime??null,d=r.totalFileCount>0&&r.totalFileCount<i?`, ${f.gray(`Enqueued: ${r.totalFileCount}/${i}`)}`:"",m=c&&u?`, ${c}, ETA: ${u}`:"",g=t.batchFilesSkipped>0?`, ${f.yellow(`Skipped: ${t.batchFilesSkipped} files / ${h(t.batchBytesSkipped)}`)}`:"",p=o>0&&r.uploadedBytes>=o&&s<i?"Finalizing":"Uploading";return`${e}: ${f.blue(p)} (${s}/${i} files, ${h(r.uploadedBytes)} / ${h(o)}, ${a}%${d}${m}${g})`}#k(e){let t=this.#m(),r=e.batchFilesSkipped+t.successFileCount+t.failedFileCount+t.cancelledFileCount,s=e.batchBytesSkipped+t.uploadedBytes,i=e.overallFilesCompleted+r,o=e.overallBytesCompleted+s,a=Math.max(e.overallBytesTotal-o,0),l=this.#C(e),c=this.#b(e,t),u=l!==null&&c!==null?l+c:null;return[`Total: ${i}/${e.overallFilesTotal} files`,`${h(o)} / ${h(e.overallBytesTotal)}`,f.yellow(`${h(a)} remaining`),`Download ETA: ${se(l)??"..."}`,`Upload ETA: ${se(c)??"..."}`,`Total ETA: ${se(u)??"..."}`].join(", ")}#C(e){let t=e.overallBytesCompleted+e.batchBytesSkipped+(this.#s?.bytesTransferred??0),r=Math.max(e.overallBytesTotal-t,0);if(r===0)return e.currentPhase==="downloading"&&this.#s?(this.#a=this.#s.eta,this.#s.eta):(this.#a=0,0);if(this.#s&&this.#s.speed>0){let s=Math.ceil(r/this.#s.speed);return this.#a=s,s}return e.currentPhase==="uploading"||e.currentPhase==="cleaning"||e.currentPhase==="complete"?(this.#a=0,0):this.#a}#b(e,t){let r=e.overallBytesCompleted+e.batchBytesSkipped+t.uploadedBytes,s=Math.max(e.overallBytesTotal-r,0),i=Math.max(e.batchBytesTotal-e.batchBytesSkipped,0),o=this.#R(e,t,i);if(s===0)return e.currentPhase==="uploading"&&o?(this.#c=o.timeRemainingSeconds,o.timeRemainingSeconds):(this.#c=0,0);if(o&&o.uploadSpeedMbps>0){let a=o.uploadSpeedMbps*1024*1024/8,l=Math.ceil(s/a);return this.#c=l,l}return this.#c}#R(e,t,r){let s=this.#t?.uploadStats,i=r>0&&t.uploadedBytes>=r;return s&&s.uploadSpeedMbps>0&&s.formattedSpeed!=="Calculating..."&&!i?(this.#u={uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds},this.#u):e.currentPhase==="uploading"&&i&&this.#u?this.#u:s?{uploadSpeedMbps:s.uploadSpeedMbps,formattedSpeed:s.formattedSpeed,formattedTime:s.formattedTime,timeRemainingSeconds:s.timeRemainingSeconds}:null}#P(e){return[`Total: ${e.totalFileCount}`,f.green(`Success: ${e.successFileCount}`),f.red(`Failed: ${e.failedFileCount}`),f.red(`Cancelled: ${e.cancelledFileCount}`),f.blue(`Active: ${e.activeFileCount}`),f.gray(`Queued: ${e.queuedFileCount}`)].join(" | ")}#T(e){let t=Math.max(e.totalBytes-e.uploadedBytes,0),r=this.#t?` | ${f.cyan(`Speed: ${this.#t.uploadStats.formattedSpeed}`)} | ${f.magenta(`Time remaining: ${this.#t.uploadStats.formattedTime}`)}`:"";return[`Total: ${h(e.totalBytes)}`,f.green(`Uploaded: ${h(e.uploadedBytes)}`),f.yellow(`Remaining: ${h(t)}`)].join(" | ")+r}#m(){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}}},C=new lt;import{Readable as sr}from"node:stream";import $t from"axios";var x=class{#e;#n;#t;#r;#s=new re;#i=new Set;constructor(e){this.#e=$t.create({baseURL:e.apiUrl}),this.#n=$t.create({baseURL:e.edgeWorkerUrl}),this.#t=e.apiKey,this.#r=e.sessionId}get skippedAssetIds(){return this.#i}async post(e,t,r){let s=await this.#e.post(e,t,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#r,"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.#r,...t}})).data}async delete(e,t){await this.#e.delete(e,{headers:{Authorization:`Bearer ${this.#t}`,"X-Aspect-Session-Id":this.#r,...t}})}async putWithToken(e,t,r,s){let i=await this.#a(t),o=this.#s.createIterator(i,s.limiter??null,s.signal),a=sr.from(o,{highWaterMark:1}),l=await this.#n.put(e,a,{timeout:0,signal:s.signal,headers:{"Content-Type":s.contentType??"","Content-Length":i.byteLength.toString(),Authorization:`Bearer ${r}`},transformRequest:[c=>c],maxRedirects:0,onUploadProgress:c=>s.onProgress?.(c.loaded)});return{status:l.status,statusText:l.statusText,headers:Object.fromEntries(Object.entries(l.headers)),data:l.data,raw:l}}async#a(e){if(e instanceof Uint8Array)return e;let t=await e.arrayBuffer();return new Uint8Array(t)}#c(e,t,r){if(e!=="/assets/chunked/initiate"||!Array.isArray(t)||!Array.isArray(r))return;let s=t;r.forEach((o,a)=>{let l=s[a];o.skipped===!0&&typeof l?.id=="string"&&this.#i.add(l.id)})}};import oe from"node:path";import U from"node:path";function b(n){let e=n.replace(/\\/g,"/");if(e.split("/").some(i=>i===".."))throw new Error(`Remote path cannot contain parent directory segments: ${n}`);let s=U.posix.normalize(e).replace(/^\/+/,"");if(s===""||s===".")throw new Error(`Remote path must resolve to a file path: ${n}`);return s}function Pe(n){let e=new Map;for(let i of n){let o=b(i.targetPath??i.path);e.set(o,(e.get(o)??0)+1)}let t=new Set,r=[],s=[];for(let i of n){let o=b(i.path),a=b(i.targetPath??i.path),l=ie(a),c=ct(l,t),u=(e.get(a)??0)>1,d=c!==o;t.add(c),r.push({...i,targetPath:c,requiresIdentityDownload:i.requiresIdentityDownload===!0||u}),(d||u)&&s.push({sourcePath:i.path,targetPath:c,reason:u||c!==l?"duplicate":"sanitized"})}return{files:r,changes:s}}function w(n){return b(n.targetPath??n.path)}function ke(n,e){let t=w(n);return{relativePath:t,absolutePath:U.join(e,t),fileName:U.posix.basename(t),size:n.size}}function ie(n){return n.split("/").map(t=>$(t)).join("/")}function ct(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),r=U.posix.basename(n),s=U.posix.extname(r),i=s.length>0?r.slice(0,-s.length):r,o=2;for(;;){let a=`${i} (${o})${s}`,l=t==="."?a:`${t}/${a}`;if(!e.has(l))return l;o+=1}}function ut(n,e){if(!e.has(n))return n;let t=U.posix.dirname(n),r=U.posix.basename(n),s=2;for(;;){let i=`${r} ${s}`,o=t==="."?i:`${t}/${i}`;if(!e.has(o))return o;s+=1}}var Gt=500,ir=8,Te=class{#e;#n;#t=new Map;constructor(e){this.#e=e.rootDirectoryId,this.#n=e.httpClient}async ensureDirectories(e){await this.loadExistingDirectories();let t=this.#r(e);for(let r of t){if(this.#t.has(r))continue;let s=oe.posix.dirname(r),i=oe.posix.basename(r),o=s==="."?this.#e:this.#t.get(s);if(!o)throw new Error(`Parent directory ID not found for path: ${r}`);let a=await this.#o(o,i);if(a.name!==i)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.#s(this.#e);this.#t.clear(),this.#c(e,"")}getDirectoryIdForFile(e){let t=b(e),r=oe.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=oe.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+=Gt){let i=e.slice(s,s+Gt),o=await this.#n.post("/assets/check-exists-and-uploaded",{items:i,delete_if_not_exist:t});r.push(...o.items)}return r}async listFilesInSubtree(e={}){let t=[{id:this.#e,relativePath:""}],r=[],s=0;for(;s<t.length;){let i=t.slice(s,s+ir),o=await Promise.all(i.map(a=>this.#i(a)));s+=i.length;for(let a of o)t.push(...a.directories),r.push(...a.files);e.onProgress?.({scannedDirectoryCount:s,queuedDirectoryCount:t.length,fileCount:r.length})}return r}#r(e){let t=new Set;for(let r of e){let s=b(r.relativePath),i=oe.posix.dirname(s);if(i===".")continue;let o=i.split("/");for(let a=0;a<o.length;a++)t.add(o.slice(0,a+1).join("/"))}return Array.from(t).sort((r,s)=>r.split("/").length-s.split("/").length)}async#s(e){return this.#n.get(`/directories/${e}/tree`)}async#i(e){let[t,r]=await Promise.all([this.#n.post("/fs/list/directories",{parent_id:e.id}),this.#n.post("/fs/list/assets",{parent_id:e.id})]);return{directories:t.map(s=>({id:s.id,relativePath:this.#a(e.relativePath,s.name)})),files:r.map(s=>({assetId:s.id,relativePath:this.#a(e.relativePath,s.name),sizeBytes:s.size_bytes,isUploaded:s.is_uploaded??!0,uploadStateKnown:typeof s.is_uploaded=="boolean"}))}}#a(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 i=t===""?".":r;this.#c(s,i)}}async#o(e,t){return this.#n.post(`/directories/${e}/directories`,{name:t,auto_rename:"numeric"})}};import{PostHog as or}from"posthog-node";var O=null,ve="",dt={};function Ht(n){O||n.config.analytics.disabled||!n.config.analytics.posthogKey||(ve=n.user.id,dt={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}:{}},O=new or(n.config.analytics.posthogKey,{host:n.config.analytics.posthogHost}),O.identify({distinctId:ve,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 jt(n,e){O&&O.capture({distinctId:ve,event:n,properties:{...dt,...e}})}async function Wt(){let n=O;if(ar(),!!n)try{await n.flush()}catch{}}function ar(){O=null,ve="",dt={}}import{spawn as xe}from"child_process";import*as mt from"fs";import*as ae from"path";var I=class extends Error{constructor(t,r){super(t);this.stderr=r;this.name="RcloneError"}stderr};function lr(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 cr(n){let e=["lsjson",n.remoteSource,"--recursive","--fast-list"];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function ur(n){let e=["backend","query",`${n.remote}:`,n.query];return n.extraArgs?.length&&e.push(...n.extraArgs),e}function dr(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 pr(n){let e=["backend","copyid",`${n.remote}:`,n.fileId,n.localTargetPath];return n.rcloneOptions.extraRcloneArgs?.length&&e.push(...n.rcloneOptions.extraRcloneArgs),e}function G(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 qt(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 mr(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 a=r[8].trim();return{bytesTransferred:G(parseFloat(r[1]),r[2]),totalBytes:G(parseFloat(r[3]),r[4]),percentComplete:parseFloat(r[5]),speed:G(parseFloat(r[6]),r[7]),eta:a==="-"?0:qt(a)}}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 i=e.match(/([\d.]+)\s*([A-Za-z]+)\/s/),o=e.match(/ETA\s+([^\s]+)$/);return{bytesTransferred:G(parseFloat(s[1]),s[2]),totalBytes:G(parseFloat(s[3]),s[4]),percentComplete:parseFloat(s[5]),speed:i?G(parseFloat(i[1]),i[2]):0,eta:o&&o[1]!=="-"?qt(o[1]):0}}function pt(n){return new Promise((e,t)=>{let r=xe("rclone",n.args,{stdio:["ignore","pipe","pipe"]}),s="",i=0,o=a=>{for(let l of a.split(`
|
|
4
|
+
`)){if(l.trim().length===0)continue;let c=mr(l);if(!c)continue;let u=Date.now();!(c.percentComplete>=100)&&u-i<500||(i=u,n.onProgress?.(c))}};r.stdout.on("data",a=>{o(a.toString())}),r.stderr.on("data",a=>{let l=a.toString();s+=l,o(l)}),r.on("close",async a=>{a===0?e():t(new I(`rclone exited with code ${a}`,s))}),r.on("error",a=>{t(new I(`Failed to start rclone: ${a.message}`,""))})})}async function Ue(){return new Promise((n,e)=>{let t=xe("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 hr(n,e,t,r,s,i){let o=`${n}:${e}`;return pt({args:lr({remoteSource:o,localPath:t,rcloneOptions:s,batchFilePath:r}),remoteSource:o,onProgress:i})}async function Kt(n,e,t=[]){let r=`${n}:${e}`;return new Promise((s,i)=>{let o=xe("rclone",cr({remoteSource:r,extraArgs:t})),a="",l="";o.stdout.on("data",c=>{a+=c.toString()}),o.stderr.on("data",c=>{l+=c.toString()}),o.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=fr(u),m=await gr({remote:n,files:d.files,directories:d.directories,extraArgs:t});s(m)}catch(u){i(new I(`Failed to parse file listing from ${r}: ${u instanceof Error?u.message:String(u)}`,l))}else i(new I(`Failed to list files from ${r}`,l))}),o.on("error",c=>{i(new I(`Failed to start rclone: ${c.message}`,""))})})}async function Yt(n){let e=[],t=[];for(let r of n.files)Fr(r)?t.push(r):e.push(r);e.length>0&&(await mt.promises.writeFile(n.batchFilePath,`${e.map(r=>r.path).join(`
|
|
5
5
|
`)}
|
|
6
|
-
`,"utf-8"),await
|
|
7
|
-
${this.#r}`)}),t.on("error",r=>{this.#s=-1,this.#
|
|
8
|
-
`))}),t.stdin?.write(`${this.#
|
|
9
|
-
`),t.stdin?.end(),await this.#a(),this.#
|
|
10
|
-
${this.#r}`)}async#a(){let e=this.#
|
|
11
|
-
`+this.#r);let s=await this.#c();if(s!==null&&/\bLinked\b/i.test(s))return;await
|
|
12
|
-
${this.#r}`)}async#c(){return new Promise(e=>{let t=this.#n("lucid",["--instance",String(this.#
|
|
13
|
-
`,{encoding:"utf-8",mode:384}),await Me.chmod(n,384)}function At(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 ln(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 ze=class{#t;#n=null;#e=null;#r=null;#s=new Map;constructor(e){this.#t=e}get displayName(){return`frameio:${this.#t.accountId}/${this.#t.folderId}`}async prepare(){await(await this.#u()).validateFolderAccess({accountId:this.#t.accountId,folderId:this.#t.folderId})}async listFiles(){let e=await this.#u(),t=[];await this.#i({client:e,folderId:this.#t.folderId,relativePrefix:"",files:t}),t.sort((r,s)=>r.path.localeCompare(s.path)),this.#s.clear();for(let r of t)this.#s.set(r.id,r);return t}resolveLocalFile(e,t){return ke(e,t)}async materializeBatch(e){let t={bytesTransferred:0,totalBytes:e.files.reduce((i,o)=>i+o.size,0),startedAt:Date.now()},r=0,s=async()=>{for(;r<e.files.length;){let i=r;r+=1,await this.#a({file:e.files[i],batchDir:e.batchDir,totals:t,onProgress:e.onProgress})}};await Promise.all(Array.from({length:Math.min(this.#t.downloadConcurrency,e.files.length)},()=>s()))}async shutdown(){}async#i(e){let t=await e.client.listFolderChildren({accountId:this.#t.accountId,folderId:e.folderId,pageSize:this.#t.pageSize});for(let r of t){if(r.type==="folder"){let i=r;await this.#i({client:e.client,folderId:i.id,relativePrefix:this.#o(e.relativePrefix,i.name),files:e.files});continue}if(r.type!=="file")continue;let s=yt(r);e.files.push({id:s.id,path:this.#o(e.relativePrefix,s.name),size:s.sizeBytes})}}async#a(e){if(!e.file.id)throw new Error(`Frame.io listing missing file ID for ${e.file.path}`);let t=Jr.join(e.batchDir,w(e.file)),r=this.#s.get(e.file.id),i=await(await this.#u()).getFileWithOriginalMediaLink({accountId:this.#t.accountId,fileId:e.file.id}),o={...i,name:r?.path??i.name,sizeBytes:e.file.size},a=0;await Xt({file:o,outputPath:t,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}}#o(e,t){let r=e===""?t:`${e}/${t}`;return b(r)}async#u(){if(this.#r)return await this.#r;this.#r=this.#m();try{return await this.#r}finally{this.#r=null}}async#m(){let e=await Ne();return(!this.#n||this.#e!==e)&&(this.#n=new B({token:e}),this.#e=e),this.#n}};function W(n){switch(n.kind){case"rclone":return new De(n);case"local":return new G(n);case"lucidlink":return new Oe(n);case"frameio":return new ze(n);default:{let e=n;throw new Error(`Unsupported sync source: ${JSON.stringify(e)}`)}}}import*as Ge from"fs/promises";import*as He from"path";var Xr={".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 Zr(n){let e=He.extname(n).toLowerCase();return Xr[e]??""}var $e=class n{#t;#n=null;#e=null;#r=!1;#s;#i;#a;constructor(e,t,r,s){this.#t=e,this.#s=t,this.#i=r,this.#a=s}static async create(e){let t=await Ge.stat(e),r=He.basename(e),s=Zr(r);return new n(e,t.size,r,s)}get name(){return this.#i}get size(){return this.#s}get type(){return this.#a}async readChunk(e,t){if(!this.#n){this.#e||(this.#e=Ge.open(this.#t,"r"));let i=await this.#e;if(this.#e=null,this.#r)return Buffer.alloc(0);this.#n=i}let r=t-e,s=Buffer.alloc(r);return await this.#n.read(s,0,r,e),s}async close(){this.#r=!0;let e=this.#e;await this.#n?.close(),this.#n=null,e&&await(await e.catch(()=>null))?.close(),this.#e=null}};var es=new Set(["success","failed","cancelled"]),cn=1e3,ts=250,ns=4*1024*1024,Ft=class{#t;name;constructor(e,t){this.#t=e,this.name=t}get size(){return this.#t.size}get type(){return this.#t.type}readChunk(e,t){return this.#t.readChunk(e,t)}async close(){await this.#t.close?.()}},je=class{#t;#n;#e;#r;#s;constructor(e){this.#t=e.config,this.#n=e.httpClient??new x({apiUrl:e.config.apiUrl,apiKey:e.config.apiKey,edgeWorkerUrl:e.config.edgeWorkerUrl,sessionId:e.config.sessionName}),this.#e=e.createFileReader??(t=>$e.create(t)),this.#r=e.onSnapshot,this.#s=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 ne({httpClient:this.#n,maxConcurrency:this.#t.maxConcurrent,deltaIntervalMs:cn,adaptiveConcurrency:!1,analytics:this.#s}),i=[],o=0;try{let a=s.startGroupUpload({name:`${r.length} files`,type:"files",fileCount:r.length,folderCount:0,topLevelFileCount:r.length,topLevelFolderCount:0,rootDirectoryId:this.#t.directoryId,projectId:this.#t.projectId,totalBytes:r.reduce((c,u)=>c+u.file.size,0),conflictResolutionOverride:"skip"});for(let c of r){let u=await this.#e(c.file.absolutePath),d=u.name===c.file.fileName?u:new Ft(u,c.file.fileName),m=s.startUpload({fileReader:d,directoryId:c.directoryId,projectId:this.#t.projectId,groupId:a,chunkSize:ns});s.addAssetToGroup(a,m),i.push({assetId:m,file:c.file,fileReader:d});let g=Date.now();(i.length===1||i.length===r.length||g-o>=ts)&&(o=g,this.#r?.(s.getSnapshot()))}await this.#i(s);let l=s.getSnapshot();return this.#r?.(l),this.#a({snapshot:l,startedUploads:i,preSkippedCount:t.length})}finally{s.destroy()}}async#i(e){let r=Date.now();for(;Date.now()-r<864e5;){let s=e.getSnapshot();this.#r?.(s);let i=Object.values(s.uploadAssets);if(i.length>0&&i.every(o=>es.has(o.status)))return;await new Promise(o=>setTimeout(o,cn))}throw new Error("Timed out waiting for upload session to finish")}#a(e){let t=[],r=0,s=0,i=0,o=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:"Upload state missing from upload engine"});continue}if(l.status==="success"){this.#n.skippedAssetIds.has(a.assetId)?s+=1:r+=1;continue}l.status==="cancelled"?o+=1:i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:r,skippedFileCount:e.preSkippedCount+s,failedFileCount:i,cancelledFileCount:o,failedFiles:t}}};var We=200,qe=class{#t;#n;#e;#r;#s;constructor(e,t,r){this.#t=e,this.#n=t??new x({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#e=new Te({rootDirectoryId:e.directoryId,httpClient:this.#n}),this.#r=new je({config:e,httpClient:this.#n,onSnapshot:s=>C.updateSnapshot(s),analytics:jt}),this.#s=r??W(e.source)}async run(){try{await this.#i()}finally{await this.#s.shutdown()}}async runBatched(){try{await this.#a()}finally{await this.#s.shutdown()}}async runCheckOnly(){try{await this.#c()}finally{await this.#s.shutdown()}}async#i(){this.#C("Starting data sync..."),await this.#b();let e=this.#A(await this.#o());if(e.length===0){console.log("No files to sync. Exiting."),await this.#S();return}let t={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},r=[],s={batchNumber:1,files:e,totalSize:this.#B(e)};C.start();try{let o=await this.#k({batch:s,totalBatches:1,overallFilesTotal:e.length,overallBytesTotal:s.totalSize,completedTotals:t,batchDir:this.#t.localTempDir});this.#O(t,r,o,s.totalSize)}finally{C.stop()}let i={...t,failedFiles:r};this.#E({summary:i}),await this.#P(i),this.#U(i)}async#a(){if(!this.#t.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#C("Starting batched data sync...",[`Batch size: ${h(this.#t.batchSizeBytes)}`,`Max concurrent chunks: ${this.#t.maxConcurrent}`]),await this.#b();let e=this.#A(await this.#o());if(e.length===0){console.log("No files to sync. Exiting."),await this.#S();return}let t=Bt(e,this.#t.batchSizeBytes);await this.#h(t);let r={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},s=[],i=this.#B(e);C.start();try{for(let a of t){let l=await this.#k({batch:a,totalBatches:t.length,overallFilesTotal:e.length,overallBytesTotal:i,completedTotals:r});this.#O(r,s,l,a.totalSize)}}finally{C.stop()}this.#E({summary:{...r,failedFiles:s},extraLines:[`Batches: ${t.length}`]});let o={...r,failedFiles:s};await this.#P(o),this.#U(o)}async#c(){console.log("Running in check-only mode (no downloads/uploads)..."),await this.#s.prepare(),console.log(`Listing source files from ${this.#s.displayName}...`);let e=await this.#s.listFiles();console.log(`Found ${e.length} source files to check`);let t=this.#A(e);if(t.length===0){console.log("No source files to check. Exiting.");return}console.log("Fetching Aspect project summary...");let r=await this.#u();console.log("Fetching existing Aspect files...");let s=await this.#e.listFilesInSubtree({onProgress:o=>this.#d(o)}),i=this.#m(t,s,r);this.#T(i)}async#o(){console.log("Listing all source files...");let e=await this.#s.listFiles();return console.log(`Found ${e.length} files`),console.log(`Total size: ${h(this.#B(e))}`),console.log(""),e}async#u(){return await this.#n.get(`/projects/${this.#t.projectId}`)}#m(e,t,r){let s=e.map(y=>({relativePath:w(y),sizeBytes:this.#g(y.size)})),i=s.filter(y=>y.sizeBytes===null).length,o=t.filter(y=>y.isUploaded),a=t.filter(y=>y.uploadStateKnown&&!y.isUploaded),l=t.filter(y=>!y.uploadStateKnown).length;l>0&&(console.warn(`Warning: ${l} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),console.log(""));let c=this.#l(s),u=this.#D(o),d=new Set([...c.keys(),...u.keys()]),m=0,g=0,p=[],A=[],S=[];for(let y of d){let Se=c.get(y)??[],T=u.get(y)??[],E=new Set,Xe=[];for(let F of Se){if(F.sizeBytes===null){Xe.push(F);continue}let M=T.findIndex((v,Ce)=>!E.has(Ce)&&v.sizeBytes===F.sizeBytes);M>=0?(m+=1,E.add(M)):Xe.push(F)}for(let F of Xe){if(F.sizeBytes===null){let v=T.findIndex((Ce,Mn)=>!E.has(Mn));v>=0?(E.add(v),g+=1):p.push(F);continue}let M=T.findIndex((v,Ce)=>!E.has(Ce));if(M>=0){let v=T[M];E.add(M),A.push({relativePath:y,remoteSizeBytes:F.sizeBytes,serverSizeBytes:v.sizeBytes,assetId:v.assetId})}else p.push(F)}for(let F=0;F<T.length;F++)E.has(F)||S.push(T[F])}return{totalRemoteCount:e.length,totalServerCount:t.length,projectAssetCount:r.num_assets,projectRootDirectoryId:r.root_directory_id,uploadedServerCount:o.length,unknownUploadStateCount:l,unknownRemoteSizeCount:i,pathOnlyMatchCount:g,existingCount:m,missingFiles:p,sizeMismatches:A,extraUploadedFiles:S,incompleteServerFiles:a}}#l(e){let t=new Map;for(let r of e){let s=b(r.relativePath),i=t.get(s)??[];i.push({...r,relativePath:s}),t.set(s,i)}return t}#D(e){let t=new Map;for(let r of e){let s=b(r.relativePath),i=t.get(s)??[];i.push({...r,relativePath:s}),t.set(s,i)}return t}#g(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:null}#A(e){let t=Ie(e);if(t.changes.length===0)return t.files;let r=t.changes.slice(0,10).map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
|
|
6
|
+
`,"utf-8"),await hr(n.remote,n.remotePath,n.localPath,n.batchFilePath,n.rcloneOptions,n.onProgress));for(let r of t)await wr({remote:n.remote,remotePath:n.remotePath,localPath:n.localPath,file:r,rcloneOptions:n.rcloneOptions,onProgress:n.onProgress})}function fr(n){let e=[],t=[];for(let r of n){let s=r;if(typeof s.Path!="string")continue;let i=typeof s.ID=="string"&&s.ID.length>0?s.ID:void 0;if(s.IsDir===!0){t.push({path:b(s.Path),id:i});continue}let o=typeof s.Size=="number"&&Number.isFinite(s.Size)?s.Size:0;e.push({path:b(s.Path),size:o,id:i})}return{files:e,directories:t}}async function gr(n){let e=yr(n.directories);if(e.length===0)return n.files;let t=e.map(o=>o[0].path),r=n.files.filter(o=>!t.some(a=>Qt(o.path,a))),s=Sr(n.directories),i=[];for(let o of e)for(let a of o){if(!a.id)throw new Error(`Cannot preserve duplicate remote folder without a stable rclone folder ID: ${a.path}`);let l=ie(a.path),c=ut(l,s);s.add(c),i.push(...await Vt({remote:n.remote,parentId:a.id,sourcePrefix:a.path,targetPrefix:c,extraArgs:n.extraArgs}))}return[...r,...i]}function yr(n){let e=new Map;for(let i of n){let o=e.get(i.path)??[];o.push(i),e.set(i.path,o)}let t=Array.from(e.values()).filter(i=>i.length>1).sort((i,o)=>i[0].path.split("/").length-o[0].path.split("/").length),r=[],s=[];for(let i of t){let o=i[0].path;s.some(a=>Qt(o,a))||(s.push(o),r.push(i))}return r}function Sr(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(ie(r.path));return t}async function Vt(n){let e=await Cr({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 i=`${n.sourcePrefix}/${s.name}`,o=`${n.targetPrefix}/${ie(s.name)}`,a=s.mimeType==="application/vnd.google-apps.folder"?ut(o,t):ct(o,t);if(t.add(a),s.mimeType==="application/vnd.google-apps.folder"){r.push(...await Vt({remote:n.remote,parentId:s.id,sourcePrefix:i,targetPrefix:a,extraArgs:n.extraArgs}));continue}r.push({path:i,targetPath:a,size:br(s.size),id:s.id,requiresIdentityDownload:!0})}return r}function Cr(n){let e=`'${Ar(n.parentId)}' in parents and trashed = false`;return new Promise((t,r)=>{let s=xe("rclone",ur({remote:n.remote,query:e,extraArgs:n.extraArgs}),{stdio:["ignore","pipe","pipe"]}),i="",o="";s.stdout.on("data",a=>{i+=a.toString()}),s.stderr.on("data",a=>{o+=a.toString()}),s.on("close",a=>{if(a!==0){r(new I(`Failed to query children for Google Drive folder ${n.parentId}`,o));return}try{let l=JSON.parse(i||"[]");if(!Array.isArray(l))throw new Error("rclone backend query did not return an array");t(l)}catch(l){r(new I(`Failed to parse children for Google Drive folder ${n.parentId}: ${l instanceof Error?l.message:String(l)}`,o))}}),s.on("error",a=>{r(new I(`Failed to start rclone: ${a.message}`,""))})})}function br(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 Qt(n,e){return n===e||n.startsWith(`${e}/`)}function Ar(n){return n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function Fr(n){let e=w(n),t=b(n.path);return n.requiresIdentityDownload===!0||e!==t}async function wr(n){let e=ae.join(n.localPath,w(n.file));if(await mt.promises.mkdir(ae.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 pt({args:pr({remote:n.remote,fileId:n.file.id,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress});return}await pt({args:dr({remoteFileSource:`${n.remote}:${Er(n.remotePath,n.file.path)}`,localTargetPath:e,rcloneOptions:n.rcloneOptions}),remoteSource:`${n.remote}:${n.file.path}`,onProgress:n.onProgress})}function Er(n,e){let t=n.replace(/\/+$/,""),r=e.replace(/^\/+/,"");return t.length===0?r:`${t}/${r}`}var De=class{#e;constructor(e){this.#e=e}get displayName(){return`${this.#e.remote}:${this.#e.remotePath}`}async prepare(){await Ue()}async listFiles(){return Kt(this.#e.remote,this.#e.remotePath,this.#e.rcloneOptions.extraRcloneArgs??[])}resolveLocalFile(e,t){return ke(e,t)}async materializeBatch(e){await Yt({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 ht from"node:fs/promises";import ft from"node:path";var H=class{#e;constructor(e){this.#e=e}get displayName(){return this.#e.rootPath}async prepare(){let e=await ht.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.#n(this.#e.rootPath,"",e),e.sort((t,r)=>t.path.localeCompare(r.path)),e}resolveLocalFile(e,t){let r=w(e);return{relativePath:r,absolutePath:ft.join(this.#e.rootPath,...e.path.split("/")),fileName:ft.posix.basename(r),size:e.size}}async materializeBatch(e){}async shutdown(){}async#n(e,t,r){let s=await ht.readdir(e,{withFileTypes:!0});for(let i of s){let o=ft.join(e,i.name),a=t===""?i.name:`${t}/${i.name}`;if(i.isDirectory()){await this.#n(o,a,r);continue}if(!i.isFile())continue;let l=await ht.stat(o);r.push({path:a,size:l.size})}}};import _e from"node:fs/promises";import Lr from"node:path";import{spawn as Ir}from"node:child_process";var Rr=18e4,Pr=2e3,kr=3e4,Tr=4e3,j=class{#e;#n;#t=null;#r="";#s=null;#i=!1;constructor(e){this.#e=e,this.#n=e.spawnFn??Ir}get isRunning(){return this.#t!==null&&this.#s===null}get daemonOutputTail(){return this.#r}async checkClientInstalled(){await this.#o({args:["list"],failureMessage:"LucidLink client is not installed or not in PATH. Install it from https://www.lucidlink.com/download before 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.#n("lucid",e,{stdio:["pipe","pipe","pipe"]});this.#t=t,t.stdout?.on("data",r=>this.#p(r)),t.stderr?.on("data",r=>this.#p(r)),t.on("exit",r=>{this.#s=r??-1,this.#i||console.error(`LucidLink daemon exited unexpectedly (code ${this.#s}). Recent output:
|
|
7
|
+
${this.#r}`)}),t.on("error",r=>{this.#s=-1,this.#p(Buffer.from(`spawn error: ${r.message}
|
|
8
|
+
`))}),t.stdin?.write(`${this.#e.password}
|
|
9
|
+
`),t.stdin?.end(),await this.#a(),this.#e.cacheSize&&await this.#o({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.#s!==null){this.#t=null;return}this.#i=!0,await this.#o({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.#s!==null&&!this.#i)throw new Error(`LucidLink daemon exited unexpectedly (code ${this.#s}). Recent output:
|
|
10
|
+
${this.#r}`)}async#a(){let e=this.#e.linkTimeoutMs??Rr,t=this.#e.linkPollIntervalMs??Pr,r=Date.now();for(;Date.now()-r<e;){if(this.#s!==null)throw new Error(`LucidLink daemon exited before linking (code ${this.#s}). Check the filespace name and credentials. Recent output:
|
|
11
|
+
`+this.#r);let s=await this.#c();if(s!==null&&/\bLinked\b/i.test(s))return;await vr(t)}throw new Error(`Timed out after ${Math.round(e/1e3)}s waiting for LucidLink filespace "${this.#e.filespace}" to link. Recent daemon output:
|
|
12
|
+
${this.#r}`)}async#c(){return new Promise(e=>{let t=this.#n("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)})})}#o(e){return new Promise((t,r)=>{let s=this.#n("lucid",e.args,{stdio:["ignore","pipe","pipe"]}),i="";s.stderr?.on("data",o=>{i+=o.toString()}),s.on("exit",o=>{o===0?t():r(new Error(`${e.failureMessage} (exit code ${o}): ${i.trim()}`))}),s.on("error",o=>{r(new Error(`${e.failureMessage}: ${o.message}`))})})}async#u(e){this.#s===null&&await new Promise(t=>{let r=setTimeout(()=>{e.kill("SIGKILL")},kr);e.on("exit",()=>{clearTimeout(r),t()}),this.#s!==null&&(clearTimeout(r),t())})}#p(e){this.#r=(this.#r+e.toString()).slice(-Tr)}};function vr(n){return new Promise(e=>setTimeout(e,n))}var Oe=class{#e;#n;#t;constructor(e,t){this.#e=e,this.#n=t??new j({filespace:e.filespace,user:e.user,password:e.password,instanceId:e.instanceId,mountPoint:e.mountPoint,cacheRootPath:e.cacheRootPath,cacheSize:e.cacheSize}),this.#t=new H({kind:"local",rootPath:this.#r()})}get displayName(){let e=this.#e.filespacePath===""?"":`/${this.#e.filespacePath}`;return`lucidlink:${this.#e.filespace}${e}`}async prepare(){await this.#n.checkClientInstalled(),await _e.mkdir(this.#e.mountPoint,{recursive:!0}),await _e.mkdir(this.#e.cacheRootPath,{recursive:!0}),console.log(`Mounting LucidLink filespace ${this.#e.filespace} at ${this.#e.mountPoint}...`),await this.#n.start(),console.log("Filespace linked and mounted");let e=await _e.stat(this.#r()).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.#n.assertHealthy(),this.#t.listFiles()}resolveLocalFile(e,t){return this.#t.resolveLocalFile(e,t)}async materializeBatch(e){this.#n.assertHealthy(),await this.#t.materializeBatch(e)}async shutdown(){await this.#n.stop(),await _e.rm(this.#e.workDir,{recursive:!0,force:!0})}#r(){return this.#e.filespacePath===""?this.#e.mountPoint:Lr.join(this.#e.mountPoint,...this.#e.filespacePath.split("/"))}};import Xr from"node:path";import Jt from"node:fs";import xr from"node:path";var Ur="https://api.frame.io/v4",Dr="https://api.frame.io",le=4,_r=1e3,Or=15e3,B=class{#e;constructor(e){this.#e=e.token}async listAccounts(){return(await this.#n("/accounts")).data}async listWorkspaces(e){return(await this.#n(`/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 i=await this.#n(r,s);t.push(...i.data),r=i.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 i=await this.#n(r,s,{"api-version":"experimental"});t.push(...i.data),r=i.links?.next??null,s=void 0}return t}async getProject(e){let t=await this.#n(`/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 i=await this.#n(r,s);t.push(...i.data),r=i.links?.next??null,s=void 0}return t}async validateFolderAccess(e){await this.#n(`/accounts/${e.accountId}/folders/${e.folderId}/children`,{page_size:"1"})}async getFileWithOriginalMediaLink(e){let t=await this.#n(`/accounts/${e.accountId}/files/${e.fileId}`,{include:"media_links.original"}),r="data"in t&&t.data?t.data:t;return yt(r)}async#n(e,t,r={}){let s=Br(e);for(let[i,o]of Object.entries(t??{}))s.searchParams.set(i,o);for(let i=0;i<le;i+=1)try{let o=await fetch(s,{headers:{Authorization:`Bearer ${this.#e}`,Accept:"application/json",...r}});if(!o.ok){let a=await o.text().catch(()=>"");if(zr(o)&&i<le-1){await gt(Be(o.headers.get("retry-after"),i));continue}throw new Error(`Frame.io API ${o.status} ${o.statusText} for ${s.pathname}: ${a}`)}return await o.json()}catch(o){if(Zt(o)&&i<le-1){await gt(Be(null,i));continue}throw o}throw new Error(`Frame.io API request failed for ${s.pathname}`)}};function Br(n){return n.startsWith("http")?new URL(n):n.startsWith("/v4/")?new URL(`${Dr}${n}`):new URL(`${Ur}${n}`)}function yt(n){return{id:n.id,name:n.name??n.id,sizeBytes:Mr(n),downloadUrl:n.media_links?.original?.download_url??void 0}}function Mr(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 Xt(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);for(let e=0;e<le;e+=1)try{return await Nr(n)}catch(t){if($r(t)&&e<le-1){await gt(Hr(t,e));continue}throw t}throw new Error(`Download failed for ${n.file.name}`)}async function Nr(n){if(!n.file.downloadUrl)throw new Error(`Frame.io file ${n.file.id} has no original download URL`);let e=new AbortController,t=n.maxSeconds===void 0?null:setTimeout(()=>e.abort(),n.maxSeconds*1e3),r=null,s=Date.now(),i=0;try{n.outputPath&&(await Jt.promises.mkdir(xr.dirname(n.outputPath),{recursive:!0}),r=Jt.createWriteStream(n.outputPath));let a=await fetch(n.file.downloadUrl,{signal:e.signal,headers:{Accept:"application/octet-stream"}});if(!a.ok||!a.body){let c=await a.text().catch(()=>"");throw new ce(`Download failed for ${n.file.name}: ${a.status} ${a.statusText} ${c}`,a.status,a.headers.get("retry-after"))}let l=a.body.getReader();for(;;){let{done:c,value:u}=await l.read();if(c)break;i+=u.byteLength,n.onProgress?.(i),r&&await Wr(r,u)}}catch(a){if(a.name!=="AbortError")throw a}finally{t&&clearTimeout(t),r&&await qr(r)}let o=Math.max((Date.now()-s)/1e3,.001);return{id:n.file.id,name:n.file.name,bytesRead:i,seconds:o,outputPath:n.outputPath}}var ce=class extends Error{status;retryAfter;constructor(e,t,r){super(e),this.status=t,this.retryAfter=r}};function zr(n){return n.status===408||n.status===425||n.status===429||n.status>=500}function $r(n){return n instanceof ce?Gr(n.status):Zt(n)}function Gr(n){return n===408||n===425||n===429||n>=500}function Zt(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 Hr(n,e){return n instanceof ce?Be(n.retryAfter,e):Be(null,e)}function Be(n,e){let t=jr(n);return t!==null?t:Math.min(_r*2**e,Or)}function jr(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 gt(n){return new Promise(e=>setTimeout(e,n))}function Wr(n,e){return new Promise((t,r)=>{if(n.write(e)){t();return}n.once("drain",t),n.once("error",r)})}function qr(n){return new Promise((e,t)=>{n.end(e),n.once("error",t)})}import St from"node:crypto";import Me from"node:fs/promises";import Kr from"node:os";import en from"node:path";var Yr="https://ims-na1.adobelogin.com/ims/authorize/v2",tn="https://ims-na1.adobelogin.com/ims/token/v3",Vr="eac24c58b3bb4e8ab26105ad17adf779",Qr=300*1e3;function nn(){return process.env.FRAMEIO_CLIENT_ID||Vr}function W(){return en.join(Kr.homedir(),".config","aspect-sync","frameio-auth.json")}function rn(){let n=St.randomBytes(32).toString("base64url"),e=St.createHash("sha256").update(n).digest("base64url");return{verifier:n,challenge:e}}function sn(n){let e=new URL(Yr);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??St.randomBytes(16).toString("hex")),e.toString()}function on(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 an(n){let e=await fetch(`${tn}?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 ln(e,"authorization code exchange")}async function Jr(n){let e=await fetch(`${tn}?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 ln(e,"refresh token exchange")}async function Ne(){let n=W(),e=await Ct(n),t=Date.parse(e.expiresAt);if(Number.isFinite(t)&&t-Date.now()>Qr)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 Jr({clientId:e.clientId,refreshToken:e.refreshToken}),s=At({clientId:e.clientId,token:r,previousRefreshToken:e.refreshToken,defaultAccountId:e.defaultAccountId});return await bt(n,s),s.accessToken}async function Ct(n){let e=await Me.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 bt(n,e){await Me.mkdir(en.dirname(n),{recursive:!0}),await Me.writeFile(n,`${JSON.stringify(e,null,2)}
|
|
13
|
+
`,{encoding:"utf-8",mode:384}),await Me.chmod(n,384)}function At(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 ln(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 ze=class{#e;#n=null;#t=null;#r=null;#s=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.#i({client:e,folderId:this.#e.folderId,relativePrefix:"",files:t}),t.sort((r,s)=>r.path.localeCompare(s.path)),this.#s.clear();for(let r of t)this.#s.set(r.id,r);return t}resolveLocalFile(e,t){return ke(e,t)}async materializeBatch(e){let t={bytesTransferred:0,totalBytes:e.files.reduce((i,o)=>i+o.size,0),startedAt:Date.now()},r=0,s=async()=>{for(;r<e.files.length;){let i=r;r+=1,await this.#a({file:e.files[i],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#i(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 i=r;await this.#i({client:e.client,folderId:i.id,relativePrefix:this.#o(e.relativePrefix,i.name),files:e.files});continue}if(r.type!=="file")continue;let s=yt(r);e.files.push({id:s.id,path:this.#o(e.relativePrefix,s.name),size:s.sizeBytes})}}async#a(e){if(!e.file.id)throw new Error(`Frame.io listing missing file ID for ${e.file.path}`);let t=Xr.join(e.batchDir,w(e.file)),r=this.#s.get(e.file.id),i=await(await this.#u()).getFileWithOriginalMediaLink({accountId:this.#e.accountId,fileId:e.file.id}),o={...i,name:r?.path??i.name,sizeBytes:e.file.size},a=0;await Xt({file:o,outputPath:t,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}}#o(e,t){let r=e===""?t:`${e}/${t}`;return b(r)}async#u(){if(this.#r)return await this.#r;this.#r=this.#p();try{return await this.#r}finally{this.#r=null}}async#p(){let e=await Ne();return(!this.#n||this.#t!==e)&&(this.#n=new B({token:e}),this.#t=e),this.#n}};function q(n){switch(n.kind){case"rclone":return new De(n);case"local":return new H(n);case"lucidlink":return new Oe(n);case"frameio":return new ze(n);default:{let e=n;throw new Error(`Unsupported sync source: ${JSON.stringify(e)}`)}}}import*as Ge from"fs/promises";import*as He from"path";var Zr={".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 es(n){let e=He.extname(n).toLowerCase();return Zr[e]??""}var $e=class n{#e;#n=null;#t=null;#r=!1;#s;#i;#a;constructor(e,t,r,s){this.#e=e,this.#s=t,this.#i=r,this.#a=s}static async create(e){let t=await Ge.stat(e),r=He.basename(e),s=es(r);return new n(e,t.size,r,s)}get name(){return this.#i}get size(){return this.#s}get type(){return this.#a}async readChunk(e,t){if(!this.#n){this.#t||(this.#t=Ge.open(this.#e,"r"));let i=await this.#t;if(this.#t=null,this.#r)return Buffer.alloc(0);this.#n=i}let r=t-e,s=Buffer.alloc(r);return await this.#n.read(s,0,r,e),s}async close(){this.#r=!0;let e=this.#t;await this.#n?.close(),this.#n=null,e&&await(await e.catch(()=>null))?.close(),this.#t=null}};var ts=new Set(["success","failed","cancelled"]),cn=1e3,ns=250,rs=4*1024*1024,Ft=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?.()}},je=class{#e;#n;#t;#r;#s;constructor(e){this.#e=e.config,this.#n=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=>$e.create(t)),this.#r=e.onSnapshot,this.#s=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 ne({httpClient:this.#n,maxConcurrency:this.#e.maxConcurrent,deltaIntervalMs:cn,adaptiveConcurrency:!1,analytics:this.#s}),i=[],o=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 Ft(u,c.file.fileName),m=s.startUpload({fileReader:d,directoryId:c.directoryId,projectId:this.#e.projectId,groupId:a,chunkSize:rs});s.addAssetToGroup(a,m),i.push({assetId:m,file:c.file,fileReader:d});let g=Date.now();(i.length===1||i.length===r.length||g-o>=ns)&&(o=g,this.#r?.(s.getSnapshot()))}await this.#i(s);let l=s.getSnapshot();return this.#r?.(l),this.#a({snapshot:l,startedUploads:i,preSkippedCount:t.length})}finally{s.destroy()}}async#i(e){let r=Date.now();for(;Date.now()-r<864e5;){let s=e.getSnapshot();this.#r?.(s);let i=Object.values(s.uploadAssets);if(i.length>0&&i.every(o=>ts.has(o.status)))return;await new Promise(o=>setTimeout(o,cn))}throw new Error("Timed out waiting for upload session to finish")}#a(e){let t=[],r=0,s=0,i=0,o=0;for(let a of e.startedUploads){let l=e.snapshot.uploadAssets[a.assetId];if(!l){i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:"Upload state missing from upload engine"});continue}if(l.status==="success"){this.#n.skippedAssetIds.has(a.assetId)?s+=1:r+=1;continue}l.status==="cancelled"?o+=1:i+=1,t.push({fileName:a.file.fileName,relativePath:a.file.relativePath,errorMessage:l.errorMessage})}return{totalFileCount:e.startedUploads.length+e.preSkippedCount,successFileCount:r,skippedFileCount:e.preSkippedCount+s,failedFileCount:i,cancelledFileCount:o,failedFiles:t}}};function un(n,e){return!e||e.count===1?n:n.filter(t=>ss(w(t),e.count)===e.index)}function ss(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}var We=200,qe=class{#e;#n;#t;#r;#s;constructor(e,t,r){this.#e=e,this.#n=t??new x({apiUrl:e.apiUrl,apiKey:e.apiKey,edgeWorkerUrl:e.edgeWorkerUrl,sessionId:e.sessionName}),this.#t=new Te({rootDirectoryId:e.directoryId,httpClient:this.#n}),this.#r=new je({config:e,httpClient:this.#n,onSnapshot:s=>C.updateSnapshot(s),analytics:jt}),this.#s=r??q(e.source)}async run(){try{await this.#i()}finally{await this.#s.shutdown()}}async runBatched(){try{await this.#a()}finally{await this.#s.shutdown()}}async runCheckOnly(){try{await this.#c()}finally{await this.#s.shutdown()}}async#i(){this.#I("Starting data sync..."),await this.#b();let e=this.#k(this.#F(await this.#o()));if(e.length===0){console.log("No files to sync. Exiting."),await this.#R();return}let t={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},r=[],s={batchNumber:1,files:e,totalSize:this.#g(e)};C.start();try{let o=await this.#C({batch:s,totalBatches:1,overallFilesTotal:e.length,overallBytesTotal:s.totalSize,completedTotals:t,batchDir:this.#e.localTempDir});this.#x(t,r,o,s.totalSize)}finally{C.stop()}let i={...t,failedFiles:r};this.#v({summary:i}),await this.#P(i),this.#M(i)}async#a(){if(!this.#e.batchSizeBytes)throw new Error("Batch size not configured. Use batchSizeBytes in config.");this.#I("Starting batched data sync...",[`Batch size: ${h(this.#e.batchSizeBytes)}`,`Max concurrent chunks: ${this.#e.maxConcurrent}`]),await this.#b();let e=this.#k(this.#F(await this.#o()));if(e.length===0){console.log("No files to sync. Exiting."),await this.#R();return}let t=Bt(e,this.#e.batchSizeBytes);await this.#A(t);let r={totalFileCount:0,successFileCount:0,skippedFileCount:0,failedFileCount:0,cancelledFileCount:0,completedByteCount:0},s=[],i=this.#g(e);C.start();try{for(let a of t){let l=await this.#C({batch:a,totalBatches:t.length,overallFilesTotal:e.length,overallBytesTotal:i,completedTotals:r});this.#x(r,s,l,a.totalSize)}}finally{C.stop()}this.#v({summary:{...r,failedFiles:s},extraLines:[`Batches: ${t.length}`]});let o={...r,failedFiles:s};await this.#P(o),this.#M(o)}async#c(){console.log("Running in check-only mode (no downloads/uploads)..."),await this.#s.prepare(),console.log(`Listing source files from ${this.#s.displayName}...`);let e=await this.#s.listFiles();console.log(`Found ${e.length} source files to check`);let t=this.#k(this.#F(e));if(t.length===0){console.log("No source files to check. Exiting.");return}console.log("Fetching Aspect project summary...");let r=await this.#u();console.log("Fetching existing Aspect files...");let s=await this.#t.listFilesInSubtree({onProgress:o=>this.#f(o)}),i=this.#p(t,s,r);this.#w(i)}async#o(){console.log("Listing all source files...");let e=await this.#s.listFiles();return console.log(`Found ${e.length} files`),console.log(`Total size: ${h(this.#g(e))}`),console.log(""),e}async#u(){return await this.#n.get(`/projects/${this.#e.projectId}`)}#p(e,t,r){let s=e.map(y=>({relativePath:w(y),sizeBytes:this.#y(y.size)})),i=s.filter(y=>y.sizeBytes===null).length,o=t.filter(y=>y.isUploaded),a=t.filter(y=>y.uploadStateKnown&&!y.isUploaded),l=t.filter(y=>!y.uploadStateKnown).length;l>0&&(console.warn(`Warning: ${l} server asset(s) did not include upload status; treating them as uploaded for check comparison.`),console.log(""));let c=this.#l(s),u=this.#U(o),d=new Set([...c.keys(),...u.keys()]),m=0,g=0,p=[],A=[],S=[];for(let y of d){let Se=c.get(y)??[],T=u.get(y)??[],E=new Set,Xe=[];for(let F of Se){if(F.sizeBytes===null){Xe.push(F);continue}let N=T.findIndex((v,Ce)=>!E.has(Ce)&&v.sizeBytes===F.sizeBytes);N>=0?(m+=1,E.add(N)):Xe.push(F)}for(let F of Xe){if(F.sizeBytes===null){let v=T.findIndex((Ce,Nn)=>!E.has(Nn));v>=0?(E.add(v),g+=1):p.push(F);continue}let N=T.findIndex((v,Ce)=>!E.has(Ce));if(N>=0){let v=T[N];E.add(N),A.push({relativePath:y,remoteSizeBytes:F.sizeBytes,serverSizeBytes:v.sizeBytes,assetId:v.assetId})}else p.push(F)}for(let F=0;F<T.length;F++)E.has(F)||S.push(T[F])}return{totalRemoteCount:e.length,totalServerCount:t.length,projectAssetCount:r.num_assets,projectRootDirectoryId:r.root_directory_id,uploadedServerCount:o.length,unknownUploadStateCount:l,unknownRemoteSizeCount:i,pathOnlyMatchCount:g,existingCount:m,missingFiles:p,sizeMismatches:A,extraUploadedFiles:S,incompleteServerFiles:a}}#l(e){let t=new Map;for(let r of e){let s=b(r.relativePath),i=t.get(s)??[];i.push({...r,relativePath:s}),t.set(s,i)}return t}#U(e){let t=new Map;for(let r of e){let s=b(r.relativePath),i=t.get(s)??[];i.push({...r,relativePath:s}),t.set(s,i)}return t}#y(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:null}#F(e){let t=Pe(e);if(t.changes.length===0)return t.files;let r=t.changes.slice(0,10).map(o=>`${o.sourcePath} -> ${o.targetPath}`).join(`
|
|
14
14
|
`),s=t.changes.length-10,i=s>0?`
|
|
15
15
|
...and ${s} more renamed target path(s)`:"";return console.warn(`Warning: ${t.changes.length} remote file path(s) were renamed for Aspect compatibility.
|
|
16
16
|
${r}${i}
|
|
17
|
-
`),console.log(""),t.files}
|
|
17
|
+
`),console.log(""),t.files}#k(e){let t=un(e,this.#e.shard);return this.#e.shard&&(console.log(`Shard ${this.#e.shard.index+1}/${this.#e.shard.count}: ${t.length} of ${e.length} planned file(s)`),console.log(`Shard size: ${h(this.#g(t))}`),console.log("")),t}async#C(e){let t=e.batchDir??wt.join(this.#e.localTempDir,`batch${e.batch.batchNumber}`);await ue.mkdir(t,{recursive:!0});let r=e.batch.files.map(d=>this.#s.resolveLocalFile(d,t));C.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.#E(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:`Preparing ${r.length} files...`}),C.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.#E(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"syncing_folders",extraDetails:"Ensuring target directories exist..."});let s=await this.#t.ensureDirectories(r);C.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.#E(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"scanning",extraDetails:"Checking existing assets..."});let i=await this.#T(s),o=this.#m(i),a=e.batch.files.filter((d,m)=>i[m]?.preSkipped!==!0),l=wt.join(this.#e.localTempDir,`batch${e.batch.batchNumber}.txt`),c=async()=>{await Mt(l),this.#e.keepLocal||await ue.rm(t,{recursive:!0,force:!0}),C.resetUploadSnapshot(),C.updateDownloadProgress(null)};if(a.length===0){let d={totalFileCount:i.length,successFileCount:0,skippedFileCount:i.length,failedFileCount:0,cancelledFileCount:0,failedFiles:[]};return C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+d.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"everything already synced"}),C.persistCurrentBatchLine(),await c(),d}C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"downloading"}),await this.#s.materializeBatch({files:a,batchDir:t,batchFilePath:l,onProgress:d=>C.updateDownloadProgress(d)}),C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal),overallBytesTotal:e.overallBytesTotal,currentPhase:"uploading"});let u=await this.#r.uploadFiles(i);return this.#h(u)?(C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete",extraDetails:"failed; local files preserved"}),C.persistCurrentBatchLine(),u):(C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"cleaning"}),await c(),C.updateBatchState({currentBatch:e.batch.batchNumber,totalBatches:e.totalBatches,batchFilesTotal:r.length,batchBytesTotal:e.batch.totalSize,batchFilesSkipped:o.skippedFileCount,batchBytesSkipped:o.skippedByteCount,overallFilesCompleted:e.completedTotals.successFileCount+e.completedTotals.skippedFileCount+u.successFileCount+u.skippedFileCount,overallFilesTotal:e.overallFilesTotal,overallBytesCompleted:this.#E(e.completedTotals,e.overallBytesTotal)+e.batch.totalSize,overallBytesTotal:e.overallBytesTotal,currentPhase:"complete"}),C.persistCurrentBatchLine(),u)}async#b(){console.log("Preparing source..."),await this.#s.prepare(),console.log("Source ready"),console.log(""),console.log("Creating session directory..."),await ue.mkdir(this.#e.localTempDir,{recursive:!0}),console.log(`Session directory: ${this.#e.localTempDir}`),console.log("")}async#R(){this.#e.keepLocal||(console.log(""),console.log("Cleaning up session directory..."),await ue.rm(this.#e.localTempDir,{recursive:!0,force:!0}),console.log(`Deleted session directory: ${this.#e.localTempDir}`))}async#P(e){if(this.#h(e)){console.log(""),console.log(`Preserving session directory for retry/debugging: ${this.#e.localTempDir}`);return}await this.#R()}async#T(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}))}#m(e){return e.reduce((t,r)=>(r.preSkipped===!0&&(t.skippedFileCount+=1,t.skippedByteCount+=r.file.size),t),{skippedFileCount:0,skippedByteCount:0})}async#A(e){console.log("Creating batches..."),console.log(`Created ${e.length} batches`);let t=[];for(let r of e){let s=`Batch ${r.batchNumber}: ${r.files.length} files, ${h(r.totalSize)}`;t.push(s),console.log(s)}await ue.writeFile(wt.join(this.#e.localTempDir,"batches.txt"),`${t.join(`
|
|
18
18
|
`)}
|
|
19
|
-
`,"utf-8"),console.log("")}#
|
|
20
|
-
`,{encoding:"utf-8",mode:
|
|
19
|
+
`,"utf-8"),console.log("")}#I(e,t=[]){console.log(e),console.log(`Session: ${this.#e.sessionName}`),console.log(`Source: ${this.#s.displayName}`),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.#d()}`);for(let r of t)console.log(r);console.log("")}#d(){return this.#e.shard?`${this.#e.shard.index+1}/${this.#e.shard.count} (index ${this.#e.shard.index})`:"disabled"}#v(e){console.log(""),console.log("=".repeat(60)),console.log("Sync Summary"),console.log("=".repeat(60)),console.log(`Total files: ${e.summary.totalFileCount}`),console.log(`Successful: ${e.summary.successFileCount}`),console.log(`Skipped: ${e.summary.skippedFileCount}`),console.log(`Failed: ${e.summary.failedFileCount}`),console.log(`Cancelled: ${e.summary.cancelledFileCount}`);for(let t of e.extraLines??[])console.log(t);if(console.log("=".repeat(60)),e.summary.failedFiles.length>0){console.log(""),console.log("Failed files:");for(let t of e.summary.failedFiles)console.log(` - ${t.relativePath}: ${t.errorMessage??"Unknown error"}`)}}#f(e){console.log(`Aspect scan: ${e.scannedDirectoryCount}/${e.queuedDirectoryCount} directories, ${e.fileCount} files found`)}#w(e){let t=e.missingFiles.length+e.sizeMismatches.length+e.extraUploadedFiles.length+e.incompleteServerFiles.length;console.log(""),console.log("=".repeat(60)),console.log("Check Summary"),console.log("=".repeat(60)),console.log(`Total (remote): ${e.totalRemoteCount}`),console.log(`Total (server): ${e.totalServerCount}`),console.log(`Project asset count: ${e.projectAssetCount}`),console.log(`Project count vs scanned server: ${e.projectAssetCount-e.totalServerCount}`),console.log(`Uploaded (server): ${e.uploadedServerCount}`),console.log(`Upload status unknown: ${e.unknownUploadStateCount}`),console.log(`Exact matches: ${e.existingCount}`),console.log(`Path-only matches (unknown remote size): ${e.pathOnlyMatchCount}`),console.log(`Remote sizes unknown: ${e.unknownRemoteSizeCount}`),console.log(`Missing on server: ${e.missingFiles.length}`),console.log(`Size mismatches: ${e.sizeMismatches.length}`),console.log(`Extra on server: ${e.extraUploadedFiles.length}`),console.log(`Incomplete uploads on server: ${e.incompleteServerFiles.length}`),console.log(`Total mismatches: ${t}`),console.log("=".repeat(60)),e.projectRootDirectoryId!==this.#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.#B(e.sizeMismatches),this.#L("Extra files on server:",e.extraUploadedFiles),this.#L("Incomplete uploads on server:",e.incompleteServerFiles)}#D(e,t){if(t.length!==0){console.log(""),console.log(e);for(let r of t.slice(0,We))console.log(` - ${r.relativePath} (${this.#_(r.sizeBytes)})`);this.#O(t.length)}}#B(e){if(e.length!==0){console.log(""),console.log("Files with size mismatches:");for(let t of e.slice(0,We))console.log(` - ${t.relativePath} (remote ${h(t.remoteSizeBytes)}, server ${h(t.serverSizeBytes)}, asset ${t.assetId})`);this.#O(e.length)}}#L(e,t){if(t.length!==0){console.log(""),console.log(e);for(let r of t.slice(0,We))console.log(` - ${r.relativePath} (${h(r.sizeBytes)}, asset ${r.assetId})`);this.#O(t.length)}}#O(e){let t=e-We;t>0&&console.log(` ...and ${t} more`)}#_(e){return e===null?"unknown remote size":h(e)}#x(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)}#M(e){let t=e.failedFileCount+e.cancelledFileCount;if(t>0)throw new Error(`Sync completed with ${t} unsuccessful upload(s)`)}#h(e){return e.failedFileCount+e.cancelledFileCount>0}#g(e){return e.reduce((t,r)=>t+r.size,0)}#E(e,t){return Math.min(e.completedByteCount,t)}};import{createInterface as _s}from"node:readline/promises";import{stdin as Os,stdout as Bs}from"node:process";import us from"node:fs";import ds from"node:os";import pe from"node:path";import hn from"node:fs";import{chmod as dn,mkdir as is,writeFile as os}from"node:fs/promises";import as from"node:os";import fn from"node:path";var pn=448,mn=384;function de(){return fn.join(as.homedir(),".config","aspect-sync","lucidlink-auth.json")}function gn(n=de()){let e;try{e=hn.readFileSync(n,"utf-8")}catch(r){throw r.code==="ENOENT"?ls(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 Cn({authFilePath:n,value:t})}async function yn(n,e){Cn({authFilePath:n,value:e});let t=fn.dirname(n);await is(t,{recursive:!0,mode:pn}),await dn(t,pn),await os(n,`${JSON.stringify(e,null,2)}
|
|
20
|
+
`,{encoding:"utf-8",mode:mn}),await dn(n,mn)}function Sn(n){let e=hn.readFileSync(n,"utf-8").replace(/\r?\n$/,"");if(e.length===0)throw new Error(`Error: LucidLink password file is empty: ${n}`);return e}function ls(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 Cn(n){if(!cs(n.value))throw new Error(`LucidLink auth file ${n.authFilePath} must contain non-empty filespace, user, and password strings`);return n.value}function cs(n){if(!n||typeof n!="object")return!1;let e=n;return Et(e.filespace)&&Et(e.user)&&Et(e.password)}function Et(n){return typeof n=="string"&&n.length>0}var ps="phc_rDzmwduU3NzHyELgLEg7nMjqpTgaSpC2a6tMKL8VyjN",ms="https://t.aspect.inc",hs="https://t.aspect.inc";function It(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:1024,MB:1024*1024,GB:1024*1024*1024,TB:1024*1024*1024*1024};return t*(s[r]||1)}function An(n){return Ke({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>me(n.options)})}function Fn(n){return Ke({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>fs(n.options)})}function wn(n){return Ke({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:e=>he({options:n.options,localTempDir:e.localTempDir})})}function En(n){return Ke({options:n.options,environment:n.environment,now:n.now,highResolutionTime:n.highResolutionTime,buildSourceConfig:()=>fe({options:n.options})})}function Ke(n){let e=K({value:n.options.aspDirectoryId,optionName:"--asp-directory-id"}),t=K({value:n.options.aspProjectId,optionName:"--asp-project-id"}),r=n.options.aspApiKey||n.environment.ASPECT_API_KEY||"";if(!r)throw new Error("Error: --asp-api-key is required (or set ASPECT_API_KEY env variable)");let s=M({value:n.options.uploadConcurrent,optionName:"--upload-concurrent"}),i=bs(n.options.batchSize),o=As({shardCount:n.options.shardCount,shardIndex:n.options.shardIndex}),a=n.options.session??Fs({now:n.now??new Date,highResolutionTime:n.highResolutionTime??process.hrtime.bigint()}),l=n.options.tempDir||pe.join(ds.homedir(),".aspect","sync"),c=pe.join(l,a);return{source:n.buildSourceConfig({localTempDir:c}),directoryId:e,projectId:t,apiUrl:n.options.aspApiUrl||n.environment.ASPECT_API_URL||"https://api.aspect.inc",edgeWorkerUrl:n.options.aspEdgeWorkerUrl||n.environment.ASPECT_EDGE_WORKER_URL||"https://mackinac.aspect.inc",apiKey:r,maxConcurrent:s,keepLocal:n.options.keepLocal,localTempDir:c,sessionName:a,batchSizeBytes:i,shard:o,analytics:{posthogKey:n.environment.ASPECT_POSTHOG_KEY||n.environment.POSTHOG_KEY||n.environment.POSTHOG_API_KEY||ps,posthogHost:n.environment.ASPECT_POSTHOG_HOST||n.environment.POSTHOG_HOST||ms||hs,disabled:bn(n.environment.ASPECT_DISABLE_POSTHOG)||bn(n.environment.POSTHOG_DISABLED)}}}function me(n){let e=K({value:n.sourcePath,optionName:"--source-path"});if(!n.remote)throw new Error("Error: --remote is required for rclone");let t=M({value:n.rcloneTransfers??"4",optionName:"--rclone-transfers"}),r=M({value:n.rcloneMultiThreadStreams??"4",optionName:"--rclone-multi-thread-streams"});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 fs(n){let e=K({value:n.sourcePath,optionName:"--source-path"});return{kind:"local",rootPath:pe.resolve(e)}}function he(n){let e=K({value:n.options.sourcePath,optionName:"--source-path"}),t=de(),r=gn(t),s=M({value:n.options.lucidInstance??"9001",optionName:"--lucid-instance"}),i=`${n.localTempDir}-lucid`;return{kind:"lucidlink",filespace:r.filespace,user:r.user,password:r.password,filespacePath:Ss(e),instanceId:s,workDir:i,mountPoint:pe.join(i,"mnt"),cacheRootPath:pe.join(i,"cache"),cacheSize:n.options.lucidCacheSize}}function fe(n){let e=K({value:n.options.sourceFolderId,optionName:"--source-folder-id"}),t=W(),r=gs(t);return{kind:"frameio",accountId:r,folderId:e,downloadConcurrency:M({value:n.options.frameioDownloadConcurrent??"4",optionName:"--frameio-download-concurrent"}),pageSize:M({value:n.options.frameioPageSize??"100",optionName:"--frameio-page-size"})}}function K(n){if(!n.value)throw new Error(`Error: ${n.optionName} is required`);return n.value}function gs(n){let e;try{e=us.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(!ys(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 ys(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.defaultAccountId=="string"&&e.defaultAccountId.length>0}function Ss(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 M(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 Cs(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 bs(n){if(!n)return;let e=It(n);if(e===null)throw new Error(`Error: Invalid batch size format: ${n}`);return e}function As(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=M({value:n.shardCount,optionName:"--shard-count"}),t=Cs({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 bn(n){return n?["1","true","yes"].includes(n.toLowerCase()):!1}function Fs(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"),i=String(n.now.getMinutes()).padStart(2,"0"),o=String(n.now.getSeconds()).padStart(2,"0"),a=n.highResolutionTime%1000000000n,l=String(a).padStart(9,"0");return`${e}-${t}-${r}_${s}h-${i}m-${o}s-${l}ns`}import{createReadStream as ws}from"node:fs";import{mkdir as Rt,rm as Pt,writeFile as Es}from"node:fs/promises";import Is from"node:os";import ge from"node:path";var Rs=20;function R(n){let e=n.session??Ds(n.commandName),t=n.tempDir??ge.join(Is.homedir(),".aspect","sync");return{sessionName:e,localTempDir:ge.join(t,e)}}function P(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 Y(n,e){if(!n)return;let t=It(n);if(t===null)throw new Error(`${e} must be a size like 500MB, 10GB, or 1TB`);return t}async function V(n){let e=q(n.sourceConfig);try{console.log(`Doctor: ${e.displayName}`),await In(n.localTempDir),console.log(`Writable temp path: ${n.localTempDir}`);for(let r of xs(n.sourceConfig))await In(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 kt(e);Rn(t.changes),console.log(`Source root access: OK (${t.files.length} files, ${h(Ye(t.files))})`),console.log("Doctor checks passed")}finally{try{await Pt(n.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function Q(n){let e=q(n.sourceConfig);try{await e.prepare();let t=await kt(e);Rn(t.changes),Ps({source:e,files:t.files,sampleSize:n.sampleSize??Rs})}finally{await e.shutdown()}}async function J(n){let e=q(n.sourceConfig);try{await e.prepare();let t=await kt(e),r=Ls({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: ${h(Ye(r))}`);let s=Date.now(),i=await ks({source:e,sourceConfig:n.sourceConfig,files:r,localTempDir:n.localTempDir}),o=Math.max((Date.now()-s)/1e3,.001);console.log(`Probe complete: ${h(i)} in ${o.toFixed(2)}s (${Re(i/o)})`)}finally{try{n.keepLocal!==!0&&await Pt(n.localTempDir,{recursive:!0,force:!0})}finally{await e.shutdown()}}}async function kt(n){console.log(`Listing source files from ${n.displayName}...`);let e=await n.listFiles();return Pe(e)}function Ps(n){console.log(`Source: ${n.source.displayName}`),console.log(`Files: ${n.files.length}`),console.log(`Total size: ${h(Ye(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(`- ${Us(r)} (${h(r.size)})`);let t=n.files.length-e.length;t>0&&console.log(`...and ${t} more`)}function Rn(n){if(n.length===0)return;let e=n.slice(0,10).map(s=>`${s.sourcePath} -> ${s.targetPath}`).join(`
|
|
21
21
|
`),t=n.length-10,r=t>0?`
|
|
22
22
|
...and ${t} more renamed target path(s)`:"";console.warn(`Warning: ${n.length} remote file path(s) were renamed for Aspect compatibility.
|
|
23
23
|
${e}${r}
|
|
24
|
-
`)}async function Es(n){await Rt(n.localTempDir,{recursive:!0});let e=ge.join(n.localTempDir,"probe"),t=ge.join(n.localTempDir,"probe-files.txt");if(Ps(n.sourceConfig))return await Rt(e,{recursive:!0}),await n.source.materializeBatch({files:n.files,batchDir:e,batchFilePath:t}),Ye(n.files);let r=0;for(let s of n.files){let i=n.source.resolveLocalFile(s,e);r+=await Rs(i.absolutePath)}return r}function Ps(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 Rs(n){return await new Promise((e,t)=>{let r=Cs(n),s=0;r.on("data",i=>{s+=Buffer.isBuffer(i)?i.length:Buffer.byteLength(i)}),r.on("error",t),r.on("end",()=>e(s))})}function Is(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 En(n){await Rt(n,{recursive:!0});let e=ge.join(n,`.aspect-sync-write-test-${process.pid}-${Date.now()}`);await bs(e,"","utf-8"),await It(e,{force:!0})}function ks(n){return n.kind!=="lucidlink"?[]:[n.cacheRootPath]}function Ts(n){let e=w(n);return e===n.path?e:`${n.path} -> ${e}`}function Ye(n){return n.reduce((e,t)=>e+t.size,0)}function vs(n){let e=new Date().toISOString().replace(/[:.]/g,"-");return`${n}-${e}`}function kn(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",nn()).action(async s=>{await Ds(s)}),e.command("accounts").description("List Frame.io accounts accessible to the current token").action(async s=>{let o=await(await Ve(s)).listAccounts();Qe(o)}),e.command("workspaces").description("List workspaces in the login-selected Frame.io account").action(async s=>{let i=await Ve(s),o=await vt(s),a=await i.listWorkspaces(o);Qe(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 i=await Ve(s),o=await vt(s),a=In(s.pageSize,"--page-size"),l=s.workspaceId?await i.listProjects({accountId:o,workspaceId:s.workspaceId,pageSize:a}):await i.listAccountProjects({accountId:o,pageSize:a});Qe(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 i=await Ve(s),o=await vt(s),a=await i.listFolderChildren({accountId:o,folderId:s.folderId,pageSize:In(s.pageSize,"--page-size")});Qe(a)});let t=Tt(e.command("doctor").description("Check Frame.io auth, account, and source folder access"));Rn(t).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"frameio-doctor"});await V({sourceConfig:fe({options:s}),localTempDir:i.localTempDir})}),Tt(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 Q({sourceConfig:fe({options:s}),sampleSize:I(s.sampleSize,"--sample-size")})});let r=Tt(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);Rn(r).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"frameio-probe"});await J({sourceConfig:fe({options:s}),localTempDir:i.localTempDir,maxFiles:I(s.maxFiles,"--max-files"),maxBytes:Y(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}function Tt(n){return n.requiredOption("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-download-concurrent <number>","Concurrent Frame.io original downloads","4").option("--frameio-page-size <number>","Frame.io folder listing page size","100")}function Rn(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 Ds(n){let e=rn(),t=sn({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 Tn("Paste the full redirected URL or code: "),s=on(r),i=await an({clientId:n.clientId,code:s,codeVerifier:e.verifier}),a=await new B({token:i.access_token}).listAccounts(),l=await _s({accounts:a}),c=j();await bt(c,At({clientId:n.clientId,token:i,defaultAccountId:l})),console.log(`Saved Frame.io auth to ${c}`)}async function Ve(n){let e=await Ne();return new B({token:e})}async function vt(n){let e=j(),t=await Ct(e);if(t.defaultAccountId)return t.defaultAccountId;throw new Error("Frame.io default account ID is missing; run aspect-sync frameio login.")}async function _s(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: ${Lt(r)}`),r.id}let t=n.promptForInput??Tn;for(e("Select the default Frame.io account for sync:"),n.accounts.forEach((r,s)=>{e(`${s+1}. ${Lt(r)}`)});;){let r=(await t("Account number or ID: ")).trim(),s=Os(n.accounts,r);if(s)return e(`Selected default Frame.io account: ${Lt(s)}`),s.id;e("Invalid account selection. Enter a listed number or account ID.")}}async function Tn(n){let e=Ls({input:xs,output:Us});try{return await e.question(n)}finally{e.close()}}function Os(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 Lt(n){let e=n.display_name?.trim();return e?`${e} (${n.id})`:n.id}function In(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 Qe(n){console.log(JSON.stringify(n,null,2))}import{stdin as k,stdout as ye}from"node:process";import{createInterface as Bs}from"node:readline/promises";import{mkdir as vn,mkdtemp as Ms,rm as Ns}from"node:fs/promises";import zs from"node:os";import xt from"node:path";function xn(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 i=>{await $s(i)});let t=Ut(e.command("doctor").description("Check LucidLink runner readiness and source access"));Dt(t).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-doctor"});await V({sourceConfig:he({options:i,localTempDir:o.localTempDir}),localTempDir:o.localTempDir,tuningWarnings:Vs(i)})});let r=Ut(e.command("list").description("List planned LucidLink source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20");Dt(r).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-list"});await Q({sourceConfig:he({options:i,localTempDir:o.localTempDir}),sampleSize:I(i.sampleSize,"--sample-size")})});let s=Ut(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);Dt(s).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-probe"});await J({sourceConfig:he({options:i,localTempDir:o.localTempDir}),localTempDir:o.localTempDir,maxFiles:I(i.maxFiles,"--max-files"),maxBytes:Y(i.maxBytes,"--max-bytes"),keepLocal:i.keepLocal})})}async function $s(n,e={}){let t=e.prompts??Ws(),r=await Ln({value:n.filespace,optionName:"--filespace",promptMessage:"LucidLink filespace (<filespace>.<workspace>): ",promptText:t.promptText}),s=await Ln({value:n.user,optionName:"--user",promptMessage:"LucidLink user: ",promptText:t.promptText}),i=n.passwordFile?yn(n.passwordFile):await js(t.promptPassword),o={filespace:r,user:s,password:i},a=n.authFile??de(),l=Ys(n.instance,"--instance");console.log(`Validating LucidLink filespace ${r}...`),await Gs({authFile:o,instanceId:l,createDaemon:e.createDaemon}),await gn(a,o),console.log(`Saved LucidLink auth to ${a}`)}async function Gs(n){let e=await Ms(xt.join(zs.tmpdir(),"aspect-sync-lucidlink-login-")),t=xt.join(e,"mnt"),r=xt.join(e,"cache"),i=(n.createDaemon??(a=>new H(a)))({filespace:n.authFile.filespace,user:n.authFile.user,password:n.authFile.password,instanceId:n.instanceId,mountPoint:t,cacheRootPath:r}),o;try{await i.checkClientInstalled(),await vn(t,{recursive:!0}),await vn(r,{recursive:!0}),await i.start()}catch(a){throw o=a,a}finally{try{await Hs({daemon:i,validationError:o})}finally{await Ns(e,{recursive:!0,force:!0})}}}async function Hs(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 Ln(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 js(n){let e=await n("LucidLink password: ");if(!e)throw new Error("--password-file or password prompt cannot be empty");return e}function Ws(){return{promptText:qs,promptPassword:Ks}}async function qs(n){let e=Bs({input:k,output:ye});try{return await e.question(n)}finally{e.close()}}function Ks(n){if(!k.isTTY||!ye.isTTY)throw new Error("Interactive LucidLink password prompt requires a TTY; provide --password-file");return new Promise((e,t)=>{let r=[],s=k.isRaw,i=()=>{k.off("data",o),k.setRawMode(s),k.pause()},o=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){i(),ye.write(`
|
|
24
|
+
`)}async function ks(n){await Rt(n.localTempDir,{recursive:!0});let e=ge.join(n.localTempDir,"probe"),t=ge.join(n.localTempDir,"probe-files.txt");if(Ts(n.sourceConfig))return await Rt(e,{recursive:!0}),await n.source.materializeBatch({files:n.files,batchDir:e,batchFilePath:t}),Ye(n.files);let r=0;for(let s of n.files){let i=n.source.resolveLocalFile(s,e);r+=await vs(i.absolutePath)}return r}function Ts(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 vs(n){return await new Promise((e,t)=>{let r=ws(n),s=0;r.on("data",i=>{s+=Buffer.isBuffer(i)?i.length:Buffer.byteLength(i)}),r.on("error",t),r.on("end",()=>e(s))})}function Ls(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 In(n){await Rt(n,{recursive:!0});let e=ge.join(n,`.aspect-sync-write-test-${process.pid}-${Date.now()}`);await Es(e,"","utf-8"),await Pt(e,{force:!0})}function xs(n){return n.kind!=="lucidlink"?[]:[n.cacheRootPath]}function Us(n){let e=w(n);return e===n.path?e:`${n.path} -> ${e}`}function Ye(n){return n.reduce((e,t)=>e+t.size,0)}function Ds(n){let e=new Date().toISOString().replace(/[:.]/g,"-");return`${n}-${e}`}function Tn(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",nn()).action(async s=>{await Ms(s)}),e.command("accounts").description("List Frame.io accounts accessible to the current token").action(async s=>{let o=await(await Ve(s)).listAccounts();Qe(o)}),e.command("workspaces").description("List workspaces in the login-selected Frame.io account").action(async s=>{let i=await Ve(s),o=await vt(s),a=await i.listWorkspaces(o);Qe(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 i=await Ve(s),o=await vt(s),a=kn(s.pageSize,"--page-size"),l=s.workspaceId?await i.listProjects({accountId:o,workspaceId:s.workspaceId,pageSize:a}):await i.listAccountProjects({accountId:o,pageSize:a});Qe(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 i=await Ve(s),o=await vt(s),a=await i.listFolderChildren({accountId:o,folderId:s.folderId,pageSize:kn(s.pageSize,"--page-size")});Qe(a)});let t=Tt(e.command("doctor").description("Check Frame.io auth, account, and source folder access"));Pn(t).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"frameio-doctor"});await V({sourceConfig:fe({options:s}),localTempDir:i.localTempDir})}),Tt(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 Q({sourceConfig:fe({options:s}),sampleSize:P(s.sampleSize,"--sample-size")})});let r=Tt(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);Pn(r).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"frameio-probe"});await J({sourceConfig:fe({options:s}),localTempDir:i.localTempDir,maxFiles:P(s.maxFiles,"--max-files"),maxBytes:Y(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}function Tt(n){return n.requiredOption("--source-folder-id <id>","Frame.io folder ID to use as the source root").option("--frameio-download-concurrent <number>","Concurrent Frame.io original downloads","4").option("--frameio-page-size <number>","Frame.io folder listing page size","100")}function Pn(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 Ms(n){let e=rn(),t=sn({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 vn("Paste the full redirected URL or code: "),s=on(r),i=await an({clientId:n.clientId,code:s,codeVerifier:e.verifier}),a=await new B({token:i.access_token}).listAccounts(),l=await Ns({accounts:a}),c=W();await bt(c,At({clientId:n.clientId,token:i,defaultAccountId:l})),console.log(`Saved Frame.io auth to ${c}`)}async function Ve(n){let e=await Ne();return new B({token:e})}async function vt(n){let e=W(),t=await Ct(e);if(t.defaultAccountId)return t.defaultAccountId;throw new Error("Frame.io default account ID is missing; run aspect-sync frameio login.")}async function Ns(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: ${Lt(r)}`),r.id}let t=n.promptForInput??vn;for(e("Select the default Frame.io account for sync:"),n.accounts.forEach((r,s)=>{e(`${s+1}. ${Lt(r)}`)});;){let r=(await t("Account number or ID: ")).trim(),s=zs(n.accounts,r);if(s)return e(`Selected default Frame.io account: ${Lt(s)}`),s.id;e("Invalid account selection. Enter a listed number or account ID.")}}async function vn(n){let e=_s({input:Os,output:Bs});try{return await e.question(n)}finally{e.close()}}function zs(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 Lt(n){let e=n.display_name?.trim();return e?`${e} (${n.id})`:n.id}function kn(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 Qe(n){console.log(JSON.stringify(n,null,2))}import{stdin as k,stdout as ye}from"node:process";import{createInterface as $s}from"node:readline/promises";import{mkdir as Ln,mkdtemp as Gs,rm as Hs}from"node:fs/promises";import js from"node:os";import xt from"node:path";function Un(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 i=>{await Ws(i)});let t=Ut(e.command("doctor").description("Check LucidLink runner readiness and source access"));Dt(t).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-doctor"});await V({sourceConfig:he({options:i,localTempDir:o.localTempDir}),localTempDir:o.localTempDir,tuningWarnings:Zs(i)})});let r=Ut(e.command("list").description("List planned LucidLink source files before syncing")).option("--sample-size <number>","Number of planned paths to print","20");Dt(r).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-list"});await Q({sourceConfig:he({options:i,localTempDir:o.localTempDir}),sampleSize:P(i.sampleSize,"--sample-size")})});let s=Ut(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);Dt(s).action(async i=>{let o=R({tempDir:i.tempDir,session:i.session,commandName:"lucidlink-probe"});await J({sourceConfig:he({options:i,localTempDir:o.localTempDir}),localTempDir:o.localTempDir,maxFiles:P(i.maxFiles,"--max-files"),maxBytes:Y(i.maxBytes,"--max-bytes"),keepLocal:i.keepLocal})})}async function Ws(n,e={}){let t=e.prompts??Vs(),r=await xn({value:n.filespace,optionName:"--filespace",promptMessage:"LucidLink filespace (<filespace>.<workspace>): ",promptText:t.promptText}),s=await xn({value:n.user,optionName:"--user",promptMessage:"LucidLink user: ",promptText:t.promptText}),i=n.passwordFile?Sn(n.passwordFile):await Ys(t.promptPassword),o={filespace:r,user:s,password:i},a=n.authFile??de(),l=Xs(n.instance,"--instance");console.log(`Validating LucidLink filespace ${r}...`),await qs({authFile:o,instanceId:l,createDaemon:e.createDaemon}),await yn(a,o),console.log(`Saved LucidLink auth to ${a}`)}async function qs(n){let e=await Gs(xt.join(js.tmpdir(),"aspect-sync-lucidlink-login-")),t=xt.join(e,"mnt"),r=xt.join(e,"cache"),i=(n.createDaemon??(a=>new j(a)))({filespace:n.authFile.filespace,user:n.authFile.user,password:n.authFile.password,instanceId:n.instanceId,mountPoint:t,cacheRootPath:r}),o;try{await i.checkClientInstalled(),await Ln(t,{recursive:!0}),await Ln(r,{recursive:!0}),await i.start()}catch(a){throw o=a,a}finally{try{await Ks({daemon:i,validationError:o})}finally{await Hs(e,{recursive:!0,force:!0})}}}async function Ks(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 xn(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 Ys(n){let e=await n("LucidLink password: ");if(!e)throw new Error("--password-file or password prompt cannot be empty");return e}function Vs(){return{promptText:Qs,promptPassword:Js}}async function Qs(n){let e=$s({input:k,output:ye});try{return await e.question(n)}finally{e.close()}}function Js(n){if(!k.isTTY||!ye.isTTY)throw new Error("Interactive LucidLink password prompt requires a TTY; provide --password-file");return new Promise((e,t)=>{let r=[],s=k.isRaw,i=()=>{k.off("data",o),k.setRawMode(s),k.pause()},o=a=>{let l=a.toString("utf-8");for(let c of l){if(c===""){i(),ye.write(`
|
|
25
25
|
`),t(new Error("LucidLink password prompt cancelled"));return}if(c==="\r"||c===`
|
|
26
26
|
`){i(),ye.write(`
|
|
27
|
-
`),e(r.join(""));return}if(c==="\x7F"){r.pop();continue}c>=" "&&r.push(c)}};ye.write(n),k.setRawMode(!0),k.resume(),k.on("data",o)})}function
|
|
28
|
-
${s.trim()}`:"")))}),r.on("error",i=>{t(new Error(`Failed to start rclone config validation: ${i.message}`))})})}function
|
|
27
|
+
`),e(r.join(""));return}if(c==="\x7F"){r.pop();continue}c>=" "&&r.push(c)}};ye.write(n),k.setRawMode(!0),k.resume(),k.on("data",o)})}function Xs(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 Ut(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 Dt(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 Zs(n){return n.lucidCacheSize?[]:["--lucid-cache-size is not set; LucidLink will use its current local cache configuration."]}import{spawn as ei}from"node:child_process";function _n(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 ti(s)});let t=_t(e.command("doctor").description("Check rclone runner readiness and source access"));Dn(t).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"rclone-doctor"});await V({sourceConfig:me(s),localTempDir:i.localTempDir,tuningWarnings:ni(s)})}),_t(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 Q({sourceConfig:me(s),sampleSize:P(s.sampleSize,"--sample-size")})});let r=_t(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);Dn(r).action(async s=>{let i=R({tempDir:s.tempDir,session:s.session,commandName:"rclone-probe"});await J({sourceConfig:me(s),localTempDir:i.localTempDir,maxFiles:P(s.maxFiles,"--max-files"),maxBytes:Y(s.maxBytes,"--max-bytes"),keepLocal:s.keepLocal})})}async function ti(n){await Ue(),await ri(n.remote),console.log(`rclone remote "${n.remote}" is configured and ready for aspect-sync.`)}function _t(n){return n.requiredOption("--remote <remote>","rclone remote name (e.g., dropbox)").requiredOption("--source-path <path>","path within the rclone remote").option("--rclone-transfers <number>","Number of parallel file transfers","4").option("--rclone-multi-thread-streams <number>","Streams per large file","4").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),[])}function Dn(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 ni(n){let e=[],t=Number.parseInt(n.rcloneTransfers??"4",10);return Number.isFinite(t)&&t>=32&&e.push("--rclone-transfers 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 ri(n){return new Promise((e,t)=>{let r=ei("rclone",["config","show",n],{stdio:["ignore","pipe","pipe"]}),s="";r.stderr?.on("data",i=>{s+=i.toString()}),r.on("close",i=>{if(i===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()?`
|
|
28
|
+
${s.trim()}`:"")))}),r.on("error",i=>{t(new Error(`Failed to start rclone config validation: ${i.message}`))})})}function On(n,e){let t=n.command("sync").description("Sync files from a source into Aspect");si(t,e),ii(t,e),oi(t,e),ai(t,e)}function si(n,e){Je(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-transfers <number>","Number of parallel file transfers (default: 4)","4").option("--rclone-multi-thread-streams <number>","Streams per large file (default: 4, higher = faster large files)","4").option("--rclone-multi-thread-chunk-size <size>","Chunk size for multi-threading (default: 64MiB)","64MiB").option("--rclone-multi-thread-cutoff <size>","Minimum file size for multi-threading (default: 64MiB)","64MiB").option("--rclone-buffer-size <size>","Buffer size per transfer (default: 64M, memory = transfers 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),[]).action(async r=>{await e({commandOptions:r,buildConfig:s=>An({options:r,environment:s})})})}function ii(n,e){Je(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=>Fn({options:r,environment:s})})})}function oi(n,e){Je(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=>wn({options:r,environment:s})})})}function ai(n,e){Je(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-download-concurrent <number>","Concurrent Frame.io original downloads (default: 4)","4").option("--frameio-page-size <number>","Frame.io folder listing page size (default: 100)","100").action(async r=>{await e({commandOptions:r,buildConfig:s=>En({options:r,environment:s})})})}function Je(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")}var Bn=ui(import.meta.url),di=Ot.dirname(Bn),Mn=JSON.parse(ci(Ot.join(di,"..","package.json"),"utf-8"));function pi(n={}){let e=new li;return e.name("aspect-sync").description("Sync files from external services to Aspect").version(n.packageVersion??Mn.version),Tn(e),Un(e),_n(e),On(e,n.executeSyncCommand??mi(n)),e}function mi(n){return async e=>{await hi({execution:e,environment:n.getEnvironment?.()??fi()})}}async function hi(n){let e=0;try{let t=n.execution.buildConfig(n.environment),r=gi(t),s=await yi(t,r);s&&Ht({config:t,packageVersion:Mn.version,user:s});let i=new qe(t,r);n.execution.commandOptions.check?await i.runCheckOnly():t.batchSizeBytes!==void 0?await i.runBatched():await i.run()}catch(t){console.error("Fatal error:",t),e=1}finally{await Wt()}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(n){return new x({apiUrl:n.apiUrl,apiKey:n.apiKey,edgeWorkerUrl:n.edgeWorkerUrl,sessionId:n.sessionName})}async function yi(n,e){return n.analytics.disabled||!n.analytics.posthogKey?null:await e.get("/users/me")}function Si(){let n=process.argv[1];return n!==void 0&&Ot.resolve(n)===Bn}export{pi as createProgram};
|