@shipstatic/ship 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/browser.js +17 -25
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +25 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/completions/ship.bash +30 -0
- package/dist/completions/ship.fish +24 -0
- package/dist/completions/ship.zsh +46 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -21
- package/dist/index.d.ts +26 -21
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +13 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as _shipstatic_types from '@shipstatic/types';
|
|
1
2
|
import { Deployment, DeploymentListResponse, Alias, AliasListResponse, Account } from '@shipstatic/types';
|
|
2
3
|
export { PingResponse, ShipError, ShipErrorType } from '@shipstatic/types';
|
|
3
4
|
|
|
@@ -63,6 +64,8 @@ interface ShipClientOptions {
|
|
|
63
64
|
apiUrl?: string | undefined;
|
|
64
65
|
/** Default API key for the client instance. */
|
|
65
66
|
apiKey?: string | undefined;
|
|
67
|
+
/** Path to custom config file. */
|
|
68
|
+
configFile?: string | undefined;
|
|
66
69
|
/**
|
|
67
70
|
* Default callback for overall deploy progress for deploys made with this client.
|
|
68
71
|
* @param progress - A number between 0 and 100.
|
|
@@ -126,7 +129,7 @@ interface DeploymentResource {
|
|
|
126
129
|
get: (id: string) => Promise<Deployment>;
|
|
127
130
|
}
|
|
128
131
|
interface AliasResource {
|
|
129
|
-
set: (aliasName: string,
|
|
132
|
+
set: (aliasName: string, deployment: string) => Promise<Alias>;
|
|
130
133
|
get: (aliasName: string) => Promise<Alias>;
|
|
131
134
|
list: () => Promise<AliasListResponse>;
|
|
132
135
|
remove: (aliasName: string) => Promise<void>;
|
|
@@ -182,15 +185,9 @@ type ExecutionEnvironment = 'browser' | 'node' | 'unknown';
|
|
|
182
185
|
*/
|
|
183
186
|
declare function __setTestEnvironment(env: ExecutionEnvironment | null): void;
|
|
184
187
|
|
|
185
|
-
/**
|
|
186
|
-
* @file Main entry point for the Ship SDK.
|
|
187
|
-
* This module provides a simplified class-based SDK interface similar to Vercel's approach.
|
|
188
|
-
*/
|
|
189
|
-
|
|
190
188
|
/**
|
|
191
189
|
* Ship SDK Client - Universal class-based interface for both Node.js and browser environments.
|
|
192
190
|
*
|
|
193
|
-
* Similar to Vercel's SDK approach:
|
|
194
191
|
* ```
|
|
195
192
|
* const ship = new Ship({ apiKey: "your-api-key" });
|
|
196
193
|
* ```
|
|
@@ -199,28 +196,40 @@ declare function __setTestEnvironment(env: ExecutionEnvironment | null): void;
|
|
|
199
196
|
* In Node.js environments, loads configuration from files and environment variables.
|
|
200
197
|
* In browser environments, uses only the provided options.
|
|
201
198
|
*/
|
|
202
|
-
/**
|
|
203
|
-
* Ship SDK Client - Simplified single class supporting both Node.js and browser environments
|
|
204
|
-
*/
|
|
205
199
|
declare class Ship {
|
|
206
200
|
private http;
|
|
207
201
|
private environment;
|
|
208
|
-
private configInitialized;
|
|
209
|
-
private configLoaded;
|
|
210
202
|
private readonly clientOptions;
|
|
211
|
-
private
|
|
212
|
-
private
|
|
213
|
-
private
|
|
214
|
-
private
|
|
203
|
+
private initPromise;
|
|
204
|
+
private _deployments;
|
|
205
|
+
private _aliases;
|
|
206
|
+
private _account;
|
|
207
|
+
private _keys;
|
|
215
208
|
constructor(options?: ShipClientOptions);
|
|
216
209
|
/**
|
|
217
|
-
*
|
|
210
|
+
* Ensure full initialization is complete - called lazily by resources
|
|
211
|
+
*/
|
|
212
|
+
private ensureInitialized;
|
|
213
|
+
/**
|
|
214
|
+
* Helper method to create initialization callback for resources
|
|
215
|
+
*/
|
|
216
|
+
private getInitCallback;
|
|
217
|
+
/**
|
|
218
|
+
* Initialize config from file/env and platform config from API
|
|
218
219
|
*/
|
|
219
220
|
private initializeConfig;
|
|
220
221
|
/**
|
|
221
222
|
* Ping the API server to check connectivity
|
|
222
223
|
*/
|
|
223
224
|
ping(): Promise<boolean>;
|
|
225
|
+
/**
|
|
226
|
+
* Deploy project (convenience shortcut to ship.deployments.create())
|
|
227
|
+
*/
|
|
228
|
+
deploy(input: DeployInput, options?: DeploymentOptions): Promise<Deployment>;
|
|
229
|
+
/**
|
|
230
|
+
* Get current account information (convenience shortcut to ship.account.get())
|
|
231
|
+
*/
|
|
232
|
+
whoami(): Promise<_shipstatic_types.Account>;
|
|
224
233
|
/**
|
|
225
234
|
* Get deployments resource (environment-specific)
|
|
226
235
|
*/
|
|
@@ -237,10 +246,6 @@ declare class Ship {
|
|
|
237
246
|
* Get keys resource
|
|
238
247
|
*/
|
|
239
248
|
get keys(): KeysResource;
|
|
240
|
-
/**
|
|
241
|
-
* Deploy files (convenience shortcut to ship.deployments.create())
|
|
242
|
-
*/
|
|
243
|
-
deploy(input: DeployInput, options?: DeploymentOptions): Promise<Deployment>;
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
export { type AccountResource, type AliasResource, type ApiDeployOptions, type DeployInput, type DeploymentOptions, type DeploymentResource, type KeysResource, type ProgressStats, Ship, type ShipClientOptions, type StaticFile, __setTestEnvironment, Ship as default, processFilesForBrowser, processFilesForNode };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var re=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var le=Object.prototype.hasOwnProperty;var M=(t,e,i,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ae(e))!le.call(t,n)&&n!==i&&re(t,n,{get:()=>e[n],enumerable:!(o=se(e,n))||o.enumerable});return t},K=(t,e,i)=>(M(t,e,"default"),i&&M(i,e,"default"));var L=null;function pe(t){L=t}function ce(){return typeof process<"u"&&process.versions&&process.versions.node?"node":typeof window<"u"||typeof self<"u"?"browser":"unknown"}function u(){return L||ce()}import{z as C}from"zod";var F={};K(F,Ee);import*as Ee from"@shipstatic/types";var x="https://api.shipstatic.com";var j="ship",me=C.object({apiUrl:C.string().url().optional(),apiKey:C.string().optional()}).strict();function H(t){try{return me.parse(t)}catch(e){if(e instanceof C.ZodError){let i=e.issues[0],o=i.path.length>0?` at ${i.path.join(".")}`:"";throw F.ShipError.config(`Configuration validation failed${o}: ${i.message}`)}throw F.ShipError.config("Configuration validation failed")}}async function fe(){try{if(u()!=="node")return{};let{cosmiconfigSync:t}=await import("cosmiconfig"),i=t(j,{searchPlaces:[`.${j}rc`,"package.json"]}).search();if(i&&!i.isEmpty&&i.config)return H(i.config)}catch(t){if(t instanceof F.ShipError)throw t}return{}}async function q(){if(u()!=="node")return{};let t={apiUrl:process.env.SHIP_API_URL,apiKey:process.env.SHIP_API_KEY},e=await fe(),i={apiUrl:t.apiUrl??e.apiUrl,apiKey:t.apiKey??e.apiKey};return H(i)}function U(t={},e={}){let i={apiUrl:t.apiUrl||e.apiUrl||x,apiKey:t.apiKey!==void 0?t.apiKey:e.apiKey};return i.apiKey!==void 0?{apiUrl:i.apiUrl,apiKey:i.apiKey}:{apiUrl:i.apiUrl}}function G(t={},e){return{onProgress:e.onProgress,onProgressStats:e.onProgressStats,maxConcurrency:e.maxConcurrentDeploys,timeout:e.timeout,apiKey:e.apiKey,apiUrl:e.apiUrl,...t}}import*as I from"mime-types";import{ShipError as h}from"@shipstatic/types";var E="/deployments",ue="/ping",R="/aliases",he="/config",ye="/account";function de(t){return typeof t=="string"?I.lookup(t)||"application/octet-stream":I.lookup(t.name)||t.type||"application/octet-stream"}async function ge(t){let e=[];for await(let i of t)e.push(i);return e}var v=class{constructor(e){this.apiUrl=e.apiUrl||x,this.apiKey=e.apiKey??""}#n(e={}){let i={...e};return this.apiKey&&(i.Authorization=`Bearer ${this.apiKey}`),i}async#i(e,i={},o){let n=this.#n(i.headers),r={...i,headers:n,credentials:u()==="browser"?"include":"same-origin"};try{return await fetch(e,r)}catch(a){throw this.#t(a,o),a}}async#e(e,i={},o){try{let n=await this.#i(e,i,o);return n.ok||await this.#o(n,o),n.headers.get("Content-Length")==="0"||n.status===204?void 0:await n.json()}catch(n){throw n instanceof h||this.#t(n,o),n}}async ping(){return(await this.#e(`${this.apiUrl}${ue}`,{method:"GET"},"Ping"))?.success||!1}async getConfig(){return await this.#e(`${this.apiUrl}${he}`,{method:"GET"},"Config")}async deploy(e,i={}){this.#r(e);let{apiUrl:o=this.apiUrl,signal:n}=i;try{let{requestBody:r,requestHeaders:a}=await this.#s(e),c={method:"POST",body:r,headers:a,signal:n||null},m=await this.#i(`${o}${E}`,c,"Deploy");return m.ok||await this.#o(m,"Deploy"),await m.json()}catch(r){throw r instanceof h?r:(this.#t(r,"Deploy"),h.business("An unexpected error occurred and was not handled."))}}#r(e){if(!e.length)throw h.business("No files to deploy.");for(let i of e)if(!i.md5)throw h.file(`MD5 checksum missing for file: ${i.path}`,i.path)}async#s(e){let i,o={};if(u()==="browser")i=this.#a(e);else if(u()==="node"){let{body:n,headers:r}=await this.#l(e);i=n,o=r}else throw h.business("Unknown or unsupported execution environment");return{requestBody:i,requestHeaders:o}}#a(e){let i=new FormData,o=[];for(let n=0;n<e.length;n++){let r=e[n],a;if(r.content instanceof File||r.content instanceof Blob)a=r.content;else throw h.file(`Unsupported file.content type for browser FormData: ${r.path}`,r.path);let c=de(a instanceof File?a:r.path),m=new File([a],r.path,{type:c});i.append("files[]",m),o.push(r.md5)}return i.append("checksums",JSON.stringify(o)),i}async#l(e){let{FormData:i,File:o}=await import("formdata-node"),{FormDataEncoder:n}=await import("form-data-encoder"),r=await import("path"),a=new i,c=[];for(let g=0;g<e.length;g++){let f=e[g],S=I.lookup(f.path)||"application/octet-stream",w;if(Buffer.isBuffer(f.content))w=new o([f.content],r.basename(f.path),{type:S});else if(typeof Blob<"u"&&f.content instanceof Blob)w=new o([f.content],r.basename(f.path),{type:S});else throw h.file(`Unsupported file.content type for Node.js FormData: ${f.path}`,f.path);let ne=f.path.startsWith("/")?f.path:"/"+f.path;a.append("files[]",w,ne),c.push(f.md5)}a.append("checksums",JSON.stringify(c));let m=new n(a),l=await ge(m.encode()),s=Buffer.concat(l.map(g=>Buffer.from(g))),p={"Content-Type":m.contentType,"Content-Length":Buffer.byteLength(s).toString()};return{body:s,headers:p}}async#o(e,i){let o={};try{let n=e.headers.get("content-type");n&&n.includes("application/json")?o=await e.json():o={message:await e.text()}}catch{o={message:"Failed to parse error response"}}if(o.error||o.code||o.message){let n=o.message||o.error||`${i} failed due to API error`;throw h.api(n,e.status,o.code,o)}throw h.api(`${i} failed due to API error`,e.status,void 0,o)}#t(e,i){throw e.name==="AbortError"?h.cancelled(`${i} operation was cancelled.`):e instanceof TypeError&&e.message.includes("fetch")?h.network(`${i} failed due to network error: ${e.message}`,e):e instanceof h?e:h.business(`An unexpected error occurred during ${i}: ${e.message||"Unknown error"}`)}async listDeployments(){return await this.#e(`${this.apiUrl}${E}`,{method:"GET"},"List Deployments")}async getDeployment(e){return await this.#e(`${this.apiUrl}${E}/${e}`,{method:"GET"},"Get Deployment")}async removeDeployment(e){await this.#e(`${this.apiUrl}${E}/${e}`,{method:"DELETE"},"Remove Deployment")}async setAlias(e,i){return await this.#e(`${this.apiUrl}${R}/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({deploymentId:i})},"Set Alias")}async getAlias(e){return await this.#e(`${this.apiUrl}${R}/${encodeURIComponent(e)}`,{method:"GET"},"Get Alias")}async listAliases(){return await this.#e(`${this.apiUrl}${R}`,{method:"GET"},"List Aliases")}async removeAlias(e){await this.#e(`${this.apiUrl}${R}/${encodeURIComponent(e)}`,{method:"DELETE"},"Remove Alias")}async getAccount(){return await this.#e(`${this.apiUrl}${ye}`,{method:"GET"},"Get Account")}async createApiKey(){return await this.#e(`${this.apiUrl}/key`,{method:"POST"},"Create API Key")}};import{ShipError as Se}from"@shipstatic/types";import{ShipError as we}from"@shipstatic/types";var k=null;function J(t){k=t}function b(){if(k===null)throw we.config("Platform configuration not initialized. The SDK must fetch configuration from the API before performing operations.");return k}import{ShipError as d}from"@shipstatic/types";import{ShipError as P}from"@shipstatic/types";async function De(t){let e=(await import("spark-md5")).default;return new Promise((i,o)=>{let r=Math.ceil(t.size/2097152),a=0,c=new e.ArrayBuffer,m=new FileReader,l=()=>{let s=a*2097152,p=Math.min(s+2097152,t.size);m.readAsArrayBuffer(t.slice(s,p))};m.onload=s=>{let p=s.target?.result;if(!p){o(P.business("Failed to read file chunk"));return}c.append(p),a++,a<r?l():i({md5:c.end()})},m.onerror=()=>{o(P.business("Failed to calculate MD5: FileReader error"))},l()})}async function Fe(t){let e=await import("crypto");if(Buffer.isBuffer(t)){let o=e.createHash("md5");return o.update(t),{md5:o.digest("hex")}}let i=await import("fs");return new Promise((o,n)=>{let r=e.createHash("md5"),a=i.createReadStream(t);a.on("error",c=>n(P.business(`Failed to read file for MD5: ${c.message}`))),a.on("data",c=>r.update(c)),a.on("end",()=>o({md5:r.digest("hex")}))})}async function O(t){let e=u();if(e==="browser"){if(!(t instanceof Blob))throw P.business("Invalid input for browser MD5 calculation: Expected Blob or File.");return De(t)}if(e==="node"){if(!(Buffer.isBuffer(t)||typeof t=="string"))throw P.business("Invalid input for Node.js MD5 calculation: Expected Buffer or file path string.");return Fe(t)}throw P.business("Unknown or unsupported execution environment for MD5 calculation.")}import{isJunk as Pe}from"junk";var ve=["__MACOSX",".Trashes",".fseventsd",".Spotlight-V100"];function T(t){return!t||t.length===0?[]:t.filter(e=>{if(!e)return!1;let i=e.replace(/\\/g,"/").split("/").filter(Boolean);if(i.length===0)return!0;let o=i[i.length-1];if(Pe(o))return!1;let n=i.slice(0,-1);for(let r of n)if(ve.some(a=>r.toLowerCase()===a.toLowerCase()))return!1;return!0})}import{ShipError as A}from"@shipstatic/types";function $(t){if(!t||t.length===0)return"";let e=t.filter(r=>r&&typeof r=="string").map(r=>r.replace(/\\/g,"/"));if(e.length===0)return"";if(e.length===1)return e[0];let i=e.map(r=>r.split("/").filter(Boolean)),o=[],n=Math.min(...i.map(r=>r.length));for(let r=0;r<n;r++){let a=i[0][r];if(i.every(c=>c[r]===a))o.push(a);else break}return o.join("/")}function B(t){return t.replace(/\\/g,"/").replace(/^\/+/,"")}import*as D from"fs";import*as y from"path";function W(t){let e=[];try{let i=D.readdirSync(t);for(let o of i){let n=y.join(t,o),r=D.statSync(n);if(r.isDirectory()){let a=W(n);e.push(...a)}else r.isFile()&&e.push(n)}}catch(i){console.error(`Error reading directory ${t}:`,i)}return e}async function V(t,e={}){let i=y.resolve(t),n=(()=>{let s=D.statSync(i);return s.isFile()?[i]:s.isDirectory()?W(i):[]})().filter(s=>{let p=y.basename(s);return T([p]).length>0}),r=D.statSync(i),a;if(e.preserveDirs)a=r.isDirectory()?i:y.dirname(i);else{let s=n.map(p=>y.dirname(p));a=$(s)}let c=[],m=0;for(let s of n)try{let p=D.statSync(s);if(p.size===0){console.warn(`Skipping empty file: ${s}`);continue}let g=b();if(p.size>g.maxFileSize)throw A.business(`File ${s} is too large. Maximum allowed size is ${g.maxFileSize/(1024*1024)}MB.`);if(m+=p.size,m>g.maxTotalSize)throw A.business(`Total deploy size is too large. Maximum allowed is ${g.maxTotalSize/(1024*1024)}MB.`);let f=D.readFileSync(s),{md5:S}=await O(f),w=y.relative(a,s).replace(/\\/g,"/");(w.includes("..")||w.includes("\0"))&&(w=y.basename(s)),w||(w=y.basename(s)),c.push({path:w,content:f,size:f.length,md5:S})}catch(p){if(p instanceof A&&p.isClientError&&p.isClientError())throw p;console.error(`Could not process file ${s}:`,p)}let l=b();if(c.length>l.maxFilesCount)throw A.business(`Too many files to deploy. Maximum allowed is ${l.maxFilesCount} files.`);return c}async function N(t,e={}){if(u()!=="node")throw A.business("processFilesForNode can only be called in a Node.js environment.");if(t.length>1){let i=[];for(let o of t){let n=await V(o,e);i.push(...n)}return i}return await V(t[0],e)}import{ShipError as Y}from"@shipstatic/types";async function z(t,e={}){if(u()!=="browser")throw Y.business("processFilesForBrowser can only be called in a browser environment.");let i=Array.isArray(t)?t:Array.from(t),o="";if(!e.preserveDirs){let l=i.map(s=>s.webkitRelativePath||s.name).filter(s=>s).map(s=>s.includes("/")?s.substring(0,s.lastIndexOf("/")):"");o=$(l)}let n=[];for(let l of i){let s=l.webkitRelativePath||l.name;if(o&&!e.preserveDirs){s=B(s);let p=o.endsWith("/")?o:`${o}/`;s.startsWith(p)?s=s.substring(p.length):s===o&&(s="")}if(s=B(s),s.includes("..")||s.includes("\0"))throw Y.business(`Security error: Unsafe file path "${s}" for file: ${l.name}`);s||(s=l.name),n.push({file:l,relativePath:s})}let r=n.map(l=>l.relativePath),a=T(r),c=new Set(a),m=[];for(let l of n){if(!c.has(l.relativePath)||l.file.size===0)continue;let{md5:s}=await O(l.file);m.push({content:l.file,path:l.relativePath,size:l.file.size,md5:s})}return m}function X(t,e={}){let i=b();if(!e.skipEmptyCheck&&t.length===0)throw d.business("No files to deploy.");if(t.length>i.maxFilesCount)throw d.business(`Too many files to deploy. Maximum allowed is ${i.maxFilesCount}.`);let o=0;for(let n of t){if(n.size>i.maxFileSize)throw d.business(`File ${n.name} is too large. Maximum allowed size is ${i.maxFileSize/(1024*1024)}MB.`);o+=n.size}if(o>i.maxTotalSize)throw d.business(`Total deploy size is too large. Maximum allowed is ${i.maxTotalSize/(1024*1024)}MB.`)}function Z(t){return X(t,{skipEmptyCheck:!0}),t.forEach(e=>{e.path&&(e.path=e.path.replace(/\\/g,"/"))}),t}async function be(t,e={}){if(!Array.isArray(t)||!t.every(o=>typeof o=="string"))throw d.business("Invalid input type for Node.js environment. Expected string[] file paths.");if(t.length===0)throw d.business("No files to deploy.");let i=await N(t,e);return Z(i)}async function Ae(t,e={}){let i;if(t instanceof HTMLInputElement){if(!t.files)throw d.business("No files selected in HTMLInputElement");i=Array.from(t.files)}else if(typeof t=="object"&&t!==null&&typeof t.length=="number"&&typeof t.item=="function")i=Array.from(t);else if(Array.isArray(t)){if(t.length>0&&typeof t[0]=="string")throw d.business("Invalid input type for browser environment. Expected File[], FileList, or HTMLInputElement.");i=t}else throw d.business("Invalid input type for browser environment. Expected File[], FileList, or HTMLInputElement.");i=i.filter(n=>n.size===0?(console.warn(`Skipping empty file: ${n.name}`),!1):!0),X(i);let o=await z(i,e);return Z(o)}async function Q(t,e={}){let i=u();if(i==="node"){if(!Array.isArray(t)||!t.every(o=>typeof o=="string"))throw d.business("Invalid input type for Node.js environment. Expected string[] file paths.");return be(t,e)}else if(i==="browser"){if(!(t instanceof HTMLInputElement||Array.isArray(t)||typeof FileList<"u"&&t instanceof FileList))throw d.business("In browser, input must be FileList, File[], or HTMLInputElement.");return Ae(t,e)}else throw d.business("Unsupported execution environment.")}function ee(t,e,i){return{create:async(o,n={})=>{e&&await e();let r=i?G(n,i):n,a=await Q(o,r);return await t.deploy(a,r)},list:async()=>t.listDeployments(),remove:async o=>{await t.removeDeployment(o)},get:async o=>t.getDeployment(o)}}function te(t){return{set:async(e,i)=>t.setAlias(e,i),get:async e=>t.getAlias(e),list:async()=>t.listAliases(),remove:async e=>{await t.removeAlias(e)}}}function ie(t){return{get:async()=>t.getAccount()}}function oe(t){return{create:async()=>t.createApiKey()}}import{ShipError as xt,ShipErrorType as Ct}from"@shipstatic/types";var _=class{constructor(e={}){this.configInitialized=!1;this.configLoaded=!1;if(this.clientOptions=e,this.environment=u(),this.environment!=="node"&&this.environment!=="browser")throw Se.business("Unsupported execution environment.");let i=U(e,{});this.http=new v({...e,...i})}async initializeConfig(){if(this.configInitialized)return;if(!this.configLoaded){let i=await q(),o=U(this.clientOptions,i);this.http=new v({...this.clientOptions,...o}),this.configLoaded=!0}let e=await this.http.getConfig();J(e),this.configInitialized=!0}async ping(){return await this.initializeConfig(),this.http.ping()}get deployments(){return this._deployments||(this._deployments=ee(this.http,()=>this.initializeConfig(),this.clientOptions)),this._deployments}get aliases(){return this._aliases||(this._aliases=te(this.http)),this._aliases}get account(){return this._account||(this._account=ie(this.http)),this._account}get keys(){return this._keys||(this._keys=oe(this.http)),this._keys}async deploy(e,i){return this.deployments.create(e,i)}},bt=_;export{_ as Ship,xt as ShipError,Ct as ShipErrorType,pe as __setTestEnvironment,bt as default,z as processFilesForBrowser,N as processFilesForNode};
|
|
1
|
+
var ae=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var _=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pe(e))!ce.call(i,n)&&n!==t&&ae(i,n,{get:()=>e[n],enumerable:!(o=le(e,n))||o.enumerable});return i},j=(i,e,t)=>(_(i,e,"default"),t&&_(t,e,"default"));var U=null;function me(i){U=i}function fe(){return typeof process<"u"&&process.versions&&process.versions.node?"node":typeof window<"u"||typeof self<"u"?"browser":"unknown"}function f(){return U||fe()}import{z as x}from"zod";var D={};j(D,Ee);import*as Ee from"@shipstatic/types";var C="https://api.shipstatic.com";var k="ship",ue=x.object({apiUrl:x.string().url().optional(),apiKey:x.string().optional()}).strict();function H(i){try{return ue.parse(i)}catch(e){if(e instanceof x.ZodError){let t=e.issues[0],o=t.path.length>0?` at ${t.path.join(".")}`:"";throw D.ShipError.config(`Configuration validation failed${o}: ${t.message}`)}throw D.ShipError.config("Configuration validation failed")}}async function he(i){try{if(f()!=="node")return{};let{cosmiconfigSync:e}=await import("cosmiconfig"),t=await import("os"),o=e(k,{searchPlaces:[`.${k}rc`,"package.json",`${t.homedir()}/.${k}rc`],stopDir:t.homedir()}),n;if(i?n=o.load(i):n=o.search(),n&&n.config)return H(n.config)}catch(e){if(e instanceof D.ShipError)throw e}return{}}async function G(i){if(f()!=="node")return{};let e={apiUrl:process.env.SHIP_API_URL,apiKey:process.env.SHIP_API_KEY},t=await he(i),o={apiUrl:e.apiUrl??t.apiUrl,apiKey:e.apiKey??t.apiKey};return H(o)}function B(i={},e={}){let t={apiUrl:i.apiUrl||e.apiUrl||C,apiKey:i.apiKey||e.apiKey};return t.apiKey!==void 0?{apiUrl:t.apiUrl,apiKey:t.apiKey}:{apiUrl:t.apiUrl}}function q(i={},e){return{onProgress:e.onProgress,onProgressStats:e.onProgressStats,maxConcurrency:e.maxConcurrentDeploys,timeout:e.timeout,apiKey:e.apiKey,apiUrl:e.apiUrl,...i}}import*as O from"mime-types";import{ShipError as h}from"@shipstatic/types";var R="/deployments",J="/ping",E="/aliases",ye="/config",de="/account";function ge(i){return typeof i=="string"?O.lookup(i)||"application/octet-stream":O.lookup(i.name)||i.type||"application/octet-stream"}async function we(i){let e=[];for await(let t of i)e.push(t);return e}var F=class{constructor(e){this.apiUrl=e.apiUrl||C,this.apiKey=e.apiKey??""}#n(e={}){let t={...e};return this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`),t}async#i(e,t={},o){let n=this.#n(t.headers),s={...t,headers:n,credentials:f()==="browser"?"include":"same-origin"};try{return await fetch(e,s)}catch(a){throw this.#t(a,o),a}}async#e(e,t={},o){try{let n=await this.#i(e,t,o);return n.ok||await this.#o(n,o),n.headers.get("Content-Length")==="0"||n.status===204?void 0:await n.json()}catch(n){throw n instanceof h||this.#t(n,o),n}}async ping(){return(await this.#e(`${this.apiUrl}${J}`,{method:"GET"},"Ping"))?.success||!1}async getPingResponse(){return await this.#e(`${this.apiUrl}${J}`,{method:"GET"},"Ping")}async getConfig(){return await this.#e(`${this.apiUrl}${ye}`,{method:"GET"},"Config")}async deploy(e,t={}){this.#r(e);let{apiUrl:o=this.apiUrl,signal:n}=t,{requestBody:s,requestHeaders:a}=await this.#s(e),c={method:"POST",body:s,headers:a,signal:n||null};return await this.#e(`${o}${R}`,c,"Deploy")}#r(e){if(!e.length)throw h.business("No files to deploy.");for(let t of e)if(!t.md5)throw h.file(`MD5 checksum missing for file: ${t.path}`,t.path)}async#s(e){let t,o={};if(f()==="browser")t=this.#a(e);else if(f()==="node"){let{body:n,headers:s}=await this.#l(e);t=n,o=s}else throw h.business("Unknown or unsupported execution environment");return{requestBody:t,requestHeaders:o}}#a(e){let t=new FormData,o=[];for(let n=0;n<e.length;n++){let s=e[n],a;if(s.content instanceof File||s.content instanceof Blob)a=s.content;else throw h.file(`Unsupported file.content type for browser FormData: ${s.path}`,s.path);let c=ge(a instanceof File?a:s.path),u=new File([a],s.path,{type:c});t.append("files[]",u),o.push(s.md5)}return t.append("checksums",JSON.stringify(o)),t}async#l(e){let{FormData:t,File:o}=await import("formdata-node"),{FormDataEncoder:n}=await import("form-data-encoder"),s=await import("path"),a=new t,c=[];for(let g=0;g<e.length;g++){let m=e[g],A=O.lookup(m.path)||"application/octet-stream",w;if(Buffer.isBuffer(m.content))w=new o([m.content],s.basename(m.path),{type:A});else if(typeof Blob<"u"&&m.content instanceof Blob)w=new o([m.content],s.basename(m.path),{type:A});else throw h.file(`Unsupported file.content type for Node.js FormData: ${m.path}`,m.path);let se=m.path.startsWith("/")?m.path:"/"+m.path;a.append("files[]",w,se),c.push(m.md5)}a.append("checksums",JSON.stringify(c));let u=new n(a),l=await we(u.encode()),r=Buffer.concat(l.map(g=>Buffer.from(g))),p={"Content-Type":u.contentType,"Content-Length":Buffer.byteLength(r).toString()};return{body:r,headers:p}}async#o(e,t){let o={};try{let n=e.headers.get("content-type");n&&n.includes("application/json")?o=await e.json():o={message:await e.text()}}catch{o={message:"Failed to parse error response"}}if(o.error||o.code||o.message){let n=o.message||o.error||`${t} failed due to API error`;throw e.status===401?h.authentication(n):h.api(n,e.status,o.code,o)}throw e.status===401?h.authentication(`Authentication failed for ${t}`):h.api(`${t} failed due to API error`,e.status,void 0,o)}#t(e,t){throw e.name==="AbortError"?h.cancelled(`${t} operation was cancelled.`):e instanceof TypeError&&e.message.includes("fetch")?h.network(`${t} failed due to network error: ${e.message}`,e):e instanceof h?e:h.business(`An unexpected error occurred during ${t}: ${e.message||"Unknown error"}`)}async listDeployments(){return await this.#e(`${this.apiUrl}${R}`,{method:"GET"},"List Deployments")}async getDeployment(e){return await this.#e(`${this.apiUrl}${R}/${e}`,{method:"GET"},"Get Deployment")}async removeDeployment(e){await this.#e(`${this.apiUrl}${R}/${e}`,{method:"DELETE"},"Remove Deployment")}async setAlias(e,t){try{let o=await this.#i(`${this.apiUrl}${E}/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({deployment:t})},"Set Alias");return o.ok||await this.#o(o,"Set Alias"),{...await o.json(),isCreate:o.status===201}}catch(o){this.#t(o,"Set Alias")}}async getAlias(e){return await this.#e(`${this.apiUrl}${E}/${encodeURIComponent(e)}`,{method:"GET"},"Get Alias")}async listAliases(){return await this.#e(`${this.apiUrl}${E}`,{method:"GET"},"List Aliases")}async removeAlias(e){await this.#e(`${this.apiUrl}${E}/${encodeURIComponent(e)}`,{method:"DELETE"},"Remove Alias")}async getAccount(){return await this.#e(`${this.apiUrl}${de}`,{method:"GET"},"Get Account")}async createApiKey(){return await this.#e(`${this.apiUrl}/key`,{method:"POST"},"Create API Key")}};import{ShipError as Ce}from"@shipstatic/types";import{ShipError as Pe}from"@shipstatic/types";var N=null;function V(i){N=i}function b(){if(N===null)throw Pe.config("Platform configuration not initialized. The SDK must fetch configuration from the API before performing operations.");return N}import{ShipError as d}from"@shipstatic/types";import{ShipError as v}from"@shipstatic/types";async function De(i){let e=(await import("spark-md5")).default;return new Promise((t,o)=>{let s=Math.ceil(i.size/2097152),a=0,c=new e.ArrayBuffer,u=new FileReader,l=()=>{let r=a*2097152,p=Math.min(r+2097152,i.size);u.readAsArrayBuffer(i.slice(r,p))};u.onload=r=>{let p=r.target?.result;if(!p){o(v.business("Failed to read file chunk"));return}c.append(p),a++,a<s?l():t({md5:c.end()})},u.onerror=()=>{o(v.business("Failed to calculate MD5: FileReader error"))},l()})}async function ve(i){let e=await import("crypto");if(Buffer.isBuffer(i)){let o=e.createHash("md5");return o.update(i),{md5:o.digest("hex")}}let t=await import("fs");return new Promise((o,n)=>{let s=e.createHash("md5"),a=t.createReadStream(i);a.on("error",c=>n(v.business(`Failed to read file for MD5: ${c.message}`))),a.on("data",c=>s.update(c)),a.on("end",()=>o({md5:s.digest("hex")}))})}async function $(i){let e=f();if(e==="browser"){if(!(i instanceof Blob))throw v.business("Invalid input for browser MD5 calculation: Expected Blob or File.");return De(i)}if(e==="node"){if(!(Buffer.isBuffer(i)||typeof i=="string"))throw v.business("Invalid input for Node.js MD5 calculation: Expected Buffer or file path string.");return ve(i)}throw v.business("Unknown or unsupported execution environment for MD5 calculation.")}import{isJunk as Fe}from"junk";var be=["__MACOSX",".Trashes",".fseventsd",".Spotlight-V100"];function T(i){return!i||i.length===0?[]:i.filter(e=>{if(!e)return!1;let t=e.replace(/\\/g,"/").split("/").filter(Boolean);if(t.length===0)return!0;let o=t[t.length-1];if(Fe(o))return!1;let n=t.slice(0,-1);for(let s of n)if(be.some(a=>s.toLowerCase()===a.toLowerCase()))return!1;return!0})}import{ShipError as S}from"@shipstatic/types";function I(i){if(!i||i.length===0)return"";let e=i.filter(s=>s&&typeof s=="string").map(s=>s.replace(/\\/g,"/"));if(e.length===0)return"";if(e.length===1)return e[0];let t=e.map(s=>s.split("/").filter(Boolean)),o=[],n=Math.min(...t.map(s=>s.length));for(let s=0;s<n;s++){let a=t[0][s];if(t.every(c=>c[s]===a))o.push(a);else break}return o.join("/")}function L(i){return i.replace(/\\/g,"/").replace(/^\/+/,"")}import*as P from"fs";import*as y from"path";function Y(i){let e=[];try{let t=P.readdirSync(i);for(let o of t){let n=y.join(i,o),s=P.statSync(n);if(s.isDirectory()){let a=Y(n);e.push(...a)}else s.isFile()&&e.push(n)}}catch(t){console.error(`Error reading directory ${i}:`,t)}return e}async function W(i,e={}){let t=y.resolve(i),n=(()=>{let r=P.statSync(t);return r.isFile()?[t]:r.isDirectory()?Y(t):[]})().filter(r=>{let p=y.basename(r);return T([p]).length>0}),s=P.statSync(t),a;if(e.preserveDirs)a=s.isDirectory()?t:y.dirname(t);else{let r=n.map(p=>y.dirname(p));a=I(r)}let c=[],u=0;for(let r of n)try{let p=P.statSync(r);if(p.size===0){console.warn(`Skipping empty file: ${r}`);continue}let g=b();if(p.size>g.maxFileSize)throw S.business(`File ${r} is too large. Maximum allowed size is ${g.maxFileSize/(1024*1024)}MB.`);if(u+=p.size,u>g.maxTotalSize)throw S.business(`Total deploy size is too large. Maximum allowed is ${g.maxTotalSize/(1024*1024)}MB.`);let m=P.readFileSync(r),{md5:A}=await $(m),w=y.relative(a,r).replace(/\\/g,"/");(w.includes("..")||w.includes("\0"))&&(w=y.basename(r)),w||(w=y.basename(r)),c.push({path:w,content:m,size:m.length,md5:A})}catch(p){if(p instanceof S&&p.isClientError&&p.isClientError())throw p;console.error(`Could not process file ${r}:`,p)}let l=b();if(c.length>l.maxFilesCount)throw S.business(`Too many files to deploy. Maximum allowed is ${l.maxFilesCount} files.`);return c}async function z(i,e={}){if(f()!=="node")throw S.business("processFilesForNode can only be called in a Node.js environment.");if(i.length>1){let t=[];for(let o of i){let n=await W(o,e);t.push(...n)}return t}return await W(i[0],e)}import{ShipError as X}from"@shipstatic/types";async function M(i,e={}){if(f()!=="browser")throw X.business("processFilesForBrowser can only be called in a browser environment.");let t=Array.isArray(i)?i:Array.from(i),o="";if(!e.preserveDirs){let l=t.map(r=>r.webkitRelativePath||r.name).filter(r=>r).map(r=>r.includes("/")?r.substring(0,r.lastIndexOf("/")):"");o=I(l)}let n=[];for(let l of t){let r=l.webkitRelativePath||l.name;if(o&&!e.preserveDirs){r=L(r);let p=o.endsWith("/")?o:`${o}/`;r.startsWith(p)?r=r.substring(p.length):r===o&&(r="")}if(r=L(r),r.includes("..")||r.includes("\0"))throw X.business(`Security error: Unsafe file path "${r}" for file: ${l.name}`);r||(r=l.name),n.push({file:l,relativePath:r})}let s=n.map(l=>l.relativePath),a=T(s),c=new Set(a),u=[];for(let l of n){if(!c.has(l.relativePath)||l.file.size===0)continue;let{md5:r}=await $(l.file);u.push({content:l.file,path:l.relativePath,size:l.file.size,md5:r})}return u}function Z(i,e={}){let t=b();if(!e.skipEmptyCheck&&i.length===0)throw d.business("No files to deploy.");if(i.length>t.maxFilesCount)throw d.business(`Too many files to deploy. Maximum allowed is ${t.maxFilesCount}.`);let o=0;for(let n of i){if(n.size>t.maxFileSize)throw d.business(`File ${n.name} is too large. Maximum allowed size is ${t.maxFileSize/(1024*1024)}MB.`);if(o+=n.size,o>t.maxTotalSize)throw d.business(`Total deploy size is too large. Maximum allowed is ${t.maxTotalSize/(1024*1024)}MB.`)}}function Q(i,e){if(e==="node"){if(!Array.isArray(i))throw d.business("Invalid input type for Node.js environment. Expected string[] file paths.");if(i.length===0)throw d.business("No files to deploy.");if(!i.every(t=>typeof t=="string"))throw d.business("Invalid input type for Node.js environment. Expected string[] file paths.")}else if(e==="browser"&&i instanceof HTMLInputElement&&!i.files)throw d.business("No files selected in HTMLInputElement")}function ee(i){return Z(i,{skipEmptyCheck:!0}),i.forEach(e=>{e.path&&(e.path=e.path.replace(/\\/g,"/"))}),i}async function Se(i,e={}){Q(i,"node");let t=await z(i,e);return ee(t)}async function Ae(i,e={}){Q(i,"browser");let t;if(i instanceof HTMLInputElement)t=Array.from(i.files);else if(typeof i=="object"&&i!==null&&typeof i.length=="number"&&typeof i.item=="function")t=Array.from(i);else if(Array.isArray(i)){if(i.length>0&&typeof i[0]=="string")throw d.business("Invalid input type for browser environment. Expected File[], FileList, or HTMLInputElement.");t=i}else throw d.business("Invalid input type for browser environment. Expected File[], FileList, or HTMLInputElement.");t=t.filter(n=>n.size===0?(console.warn(`Skipping empty file: ${n.name}`),!1):!0),Z(t);let o=await M(t,e);return ee(o)}async function te(i,e={}){let t=f();if(t!=="node"&&t!=="browser")throw d.business("Unsupported execution environment.");return t==="node"?Se(i,e):Ae(i,e)}function ie(i,e,t){return{create:async(o,n={})=>{t&&await t();let s=e?q(n,e):n,a=await te(o,s);return await i().deploy(a,s)},list:async()=>(t&&await t(),i().listDeployments()),remove:async o=>{t&&await t(),await i().removeDeployment(o)},get:async o=>(t&&await t(),i().getDeployment(o))}}function oe(i,e){return{set:async(t,o)=>(e&&await e(),i().setAlias(t,o)),get:async t=>(e&&await e(),i().getAlias(t)),list:async()=>(e&&await e(),i().listAliases()),remove:async t=>{e&&await e(),await i().removeAlias(t)}}}function ne(i,e){return{get:async()=>(e&&await e(),i().getAccount())}}function re(i,e){return{create:async()=>(e&&await e(),i().createApiKey())}}import{ShipError as xt,ShipErrorType as Rt}from"@shipstatic/types";var K=class{constructor(e={}){this.initPromise=null;if(this.clientOptions=e,this.environment=f(),this.environment!=="node"&&this.environment!=="browser")throw Ce.business("Unsupported execution environment.");let t=B(e,{});this.http=new F({...e,...t});let o=this.getInitCallback(),n=()=>this.http;this._deployments=ie(n,this.clientOptions,o),this._aliases=oe(n,o),this._account=ne(n,o),this._keys=re(n,o)}async ensureInitialized(){return this.initPromise||(this.initPromise=this.initializeConfig()),this.initPromise}getInitCallback(){return()=>this.ensureInitialized()}async initializeConfig(){try{let e=await G(this.clientOptions.configFile),t=B(this.clientOptions,e);this.http=new F({...this.clientOptions,...t});let o=await this.http.getConfig();V(o)}catch(e){throw this.initPromise=null,e}}async ping(){return await this.ensureInitialized(),this.http.ping()}async deploy(e,t){return this.deployments.create(e,t)}async whoami(){return this.account.get()}get deployments(){return this._deployments}get aliases(){return this._aliases}get account(){return this._account}get keys(){return this._keys}},St=K;export{K as Ship,xt as ShipError,Rt as ShipErrorType,me as __setTestEnvironment,St as default,M as processFilesForBrowser,z as processFilesForNode};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|