Publishing & Streams
The three streaming methods—publish, encrypt, and ssl—each return a Node.js EventEmitter rather than taking a callback. The Surge API responds to these operations with a live stream of newline-delimited JSON, and the SDK re-emits each message as an event, so your tool can show real progress while the work happens.
These methods are only available when the client was constructed with the surge-stream module—see Client & Authentication.
Publishing a directory
sdk.publish(projectPath, domain, creds, headers, argv)
| Argument | Description |
|---|---|
projectPath |
Directory to deploy. Files are gathered recursively, filtered by Surge's default ignore rules plus a .surgeignore file if one exists, then packed into a gzipped tarball and streamed to the API. |
domain |
Target domain, e.g. "my-site.surge.sh". |
creds |
Credentials—normally { user: "token", pass: token }. |
headers |
Optional object of extra HTTP headers. This is how deploy metadata travels: version (your client's version), file-count, project-size, message, stage, and so on. |
argv |
Optional parsed-arguments object; serialized into an argv header for the server. |
A complete example, modelled on how the CLI itself deploys:
sdk.publish("./my-site", "my-site.surge.sh",
{ user: "token", pass: token },
{
"version": "1.0.0", // your tool's version
"file-count": 42,
"project-size": 123456,
"timestamp": new Date().toJSON()
}
)
.on("progress", function(p){
// p.id is the phase: "upload", "cdn", or "encrypt"
// p.written / p.total track completion; p.file names the current file
})
.on("info", function(info){
// The deploy result: info.urls, info.instances, info.metadata
})
.on("success", function(){ console.log("Published!") })
.on("fail", function(){ console.error("Deploy failed") })
Stream events
Every JSON message from the server is emitted twice: once as a generic data event with the full object, and once as an event named after the message's type field. On top of those, the client emits lifecycle events of its own.
Server-sent events
| Event | Payload | Meaning |
|---|---|---|
progress |
{ id, written, total, file } |
Progress through a phase. id is "upload" (tarball going up), "cdn" (files propagating to the edge), or "encrypt" (certificate provisioning). |
info |
{ urls, instances, metadata, config, certs } |
The deploy succeeded. urls lists where the project is reachable; metadata.preview holds the preview URL for staged deploys. |
users |
{ users: [...] } |
Collaborators on the project, when changed during publish. |
cert / ssl |
{ data: { issuer, altnames, expiresInWords } } |
Certificate details. |
subscription |
{ data: subscription } |
The project's plan, when applicable. |
collect |
{ plan, card, stripe_pk } |
The operation requires a plan or payment before it can proceed. |
msg |
{ payload: { msg, status } } |
A human-readable server message. |
Client lifecycle events
| Event | Meaning |
|---|---|
success |
The stream ended after an info message was received. The deploy is live. |
fail |
The stream ended without an info message, or the request failed outright. |
error |
A transport error occurred on the response stream. |
unauthorized |
HTTP 401—the token is invalid or expired. Payload is the server's reason string. |
forbidden |
HTTP 403—authenticated but not permitted (not a collaborator, rate limited, project too large). Payload is the reason string. |
invalid |
HTTP 422—the domain is invalid. |
Treat success/fail as the authoritative outcome; info merely carries the result payload.
Provisioning a certificate
encrypt asks the platform to provision a free SSL certificate for a custom domain. Same event model, no request body:
sdk.encrypt("example.com", { user: "token", pass: token }, { version: "1.0.0" })
.on("cert", function(c){ console.log("Issued by " + c.data.issuer) })
.on("success", function(){ console.log("Certificate active") })
.on("fail", function(){ console.error("Could not provision certificate") })
Uploading a custom certificate
ssl streams a PEM file (certificate + key bundle) to the platform, for projects on a paid plan that bring their own certificate:
sdk.ssl("./cert.pem", "example.com",
{ user: "token", pass: token },
{ version: "1.0.0" }
)
.on("msg", function(m){ console.log(m.payload.msg) }) // "the pem file has been applied"
.on("fail", function(){ console.error("PEM rejected") })
The server validates the PEM before accepting it; an invalid bundle produces a fail with an HTTP 400.