apns-send
Version:
The apns-send npm package enables seamless integration of push notifications using the Apple Push Notification service (APNs) with the HTTP/2 protocol.
2 lines (1 loc) • 7.44 kB
JavaScript
;var I=Object.create;var u=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var H=(n,t)=>{for(var e in t)u(n,e,{get:t[e],enumerable:!0})},v=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of N(t))!w.call(n,r)&&r!==e&&u(n,r,{get:()=>t[r],enumerable:!(o=R(t,r))||o.enumerable});return n};var b=(n,t,e)=>(e=n!=null?I(A(n)):{},v(t||!n||!n.__esModule?u(e,"default",{value:n,enumerable:!0}):e,n)),O=n=>v(u({},"__esModule",{value:!0}),n);var U={};H(U,{ApnsClient:()=>y,Errors:()=>g,Host:()=>x,Notification:()=>p,Priority:()=>m,PushType:()=>h,SilentNotification:()=>T});module.exports=O(U);var P=require("jsonwebtoken"),S=require("events");var g=(i=>(i.badCertificate="BadCertificate",i.badCertificateEnvironment="BadCertificateEnvironment",i.badCollapseId="BadCollapseId",i.badDeviceToken="BadDeviceToken",i.badExpirationDate="BadExpirationDate",i.badMessageId="BadMessageId",i.badPath="BadPath",i.badPriority="BadPriority",i.badTopic="BadTopic",i.deviceTokenNotForTopic="DeviceTokenNotForTopic",i.duplicateHeaders="DuplicateHeaders",i.error="Error",i.expiredProviderToken="ExpiredProviderToken",i.forbidden="Forbidden",i.idleTimeout="IdleTimeout",i.internalServerError="InternalServerError",i.invalidProviderToken="InvalidProviderToken",i.invalidPushType="InvalidPushType",i.invalidSigningKey="InvalidSigningKey",i.methodNotAllowed="MethodNotAllowed",i.missingDeviceToken="MissingDeviceToken",i.missingProviderToken="MissingProviderToken",i.missingTopic="MissingTopic",i.payloadEmpty="PayloadEmpty",i.payloadTooLarge="PayloadTooLarge",i.serviceUnavailable="ServiceUnavailable",i.shutdown="Shutdown",i.tooManyProviderTokenUpdates="TooManyProviderTokenUpdates",i.tooManyRequests="TooManyRequests",i.topicDisallowed="TopicDisallowed",i.unknownError="UnknownError",i.unregistered="Unregistered",i))(g||{});var _=b(require("path"));var d=b(require("http2"));function k(n){return{100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",208:"Already Reported",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",307:"Temporary Redirect",308:"Permanent Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",421:"Misdirected Request",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required"}[n]||"Unknown"}var c=class{constructor(t){this._http2Client=d.default.connect(t.url)}async request(t,e){let o=this._http2Client.request({...(e==null?void 0:e.headers)??{},[d.default.constants.HTTP2_HEADER_METHOD]:e.method,[d.default.constants.HTTP2_HEADER_PATH]:t},{endStream:!(e!=null&&e.body)});e!=null&&e.body&&o.write(e.body),o.end();let{headers:r,status:a}=await this._responseHeaders(o,e.timeout),l=await this._responseJson(o),s=k(a);return{status:a,statusText:s,headers:r,body:l}}_responseHeaders(t,e){return new Promise((o,r)=>{e&&t.setTimeout(e??5e3,r),t.on("error",r),t.on("response",a=>o({headers:a,status:Number(a[d.default.constants.HTTP2_HEADER_STATUS])}))})}_responseJson(t){return new Promise((e,o)=>{let r=[];t.on("error",o),t.on("data",a=>r.push(a)),t.on("end",()=>{t.destroy(),t.removeAllListeners(),e(this._convertBufferToJson(Buffer.concat(r)))})})}_convertBufferToJson(t){if(t){let e=t.toString("utf8");return e?JSON.parse(e):void 0}}};var M=3,f="ES256",D=55*60*1e3,x=(e=>(e.production="api.push.apple.com",e.development="api.sandbox.push.apple.com",e))(x||{});function C(n){return`https://${n??"api.push.apple.com"}`}var y=class extends c{constructor(e){super({url:C(e.host)});this._emitter=new S.EventEmitter,this.team=e.team,this.keyId=e.keyId,this.signingKey=e.signingKey,this.defaultTopic=e.defaultTopic,this.host=e.host??"api.push.apple.com",this._token=null,this._handleEvents()}send(e){return this._push(e)}sendMany(e){let o=e.map(r=>this._push(r).catch(a=>({error:a})));return Promise.all(o)}async _push(e){return this.request(this._getPath(e.deviceToken),{headers:this._buildHeaders(e),body:JSON.stringify(e.buildApnsOptions()),method:"POST"})}_buildHeaders(e){var r,a,l,s;let o={authorization:`bearer ${this._getSigningToken()}`,"apns-push-type":e.pushType,"apns-priority":((r=e==null?void 0:e.priority)==null?void 0:r.toString())??"0","apns-topic":((a=e==null?void 0:e.options)==null?void 0:a.topic)??this.defaultTopic,":method":"POST",":scheme":"https",":path":this._getPath(e==null?void 0:e.deviceToken)};return(l=e==null?void 0:e.options)!=null&&l.expiration&&(o["apns-expiration"]=typeof e.options.expiration=="number"?e.options.expiration.toFixed(0):(e.options.expiration.getTime()/1e3).toFixed(0)),(s=e==null?void 0:e.options)!=null&&s.collapseId&&(o["apns-collapse-id"]=e.options.collapseId),o}_getPath(e){if(!e)throw new Error("Device token is required");return _.default.join(`/${M}`,"device",`${e}`)}_getSigningToken(){if(this._token&&Date.now()-this._token.timestamp<D)return this._token.value;let e={iss:this.team,iat:Math.floor(Date.now()/1e3)},o=(0,P.sign)(e,this.signingKey,{algorithm:f,header:{alg:f,kid:this.keyId}});return this._token={value:o,timestamp:Date.now()},o}_handleEvents(){this._emitter.on("ExpiredProviderToken",()=>this._resetSigningToken())}_resetSigningToken(){this._token=null}};var h=(s=>(s.alert="alert",s.background="background",s.voip="voip",s.complication="complication",s.fileprovider="fileprovider",s.mdm="mdm",s.liveactivity="liveactivity",s))(h||{});var m=(e=>(e[e.immediate=10]="immediate",e[e.throttled=5]="throttled",e))(m||{});var p=class{constructor(t,e){this.deviceToken=t,this.options=e??{}}get pushType(){return this.options.type??"alert"}get priority(){return this.options.priority??10}buildApnsOptions(){let t={aps:this.options.aps??{}};this.options.alert&&(t.aps.alert=this.options.alert),typeof this.options.contentAvailable=="boolean"&&(t.aps["content-available"]=1),(typeof this.options.sound=="string"||typeof this.options.sound=="object")&&(t.aps.sound=this.options.sound),typeof this.options.category=="string"&&(t.aps.category=this.options.category),typeof this.options.badge=="number"&&(t.aps.badge=this.options.badge),typeof this.options.threadId=="string"&&(t.aps["thread-id"]=this.options.threadId);for(let e in this.options.data)t[e]=this.options.data[e];return t}};var T=class extends p{constructor(t,e={}){super(t,{contentAvailable:!0,type:"background",priority:5,...e})}};0&&(module.exports={ApnsClient,Errors,Host,Notification,Priority,PushType,SilentNotification});