@trigger.dev/core 3.0.0-beta.34 → 3.0.0-beta.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/catalog-XTlJQaMn.d.mts +202 -0
  2. package/dist/catalog-dRKTgwQ7.d.ts +202 -0
  3. package/dist/{manager-WNMVbgHf.d.mts → manager-JkbddlcO.d.mts} +43 -42
  4. package/dist/{manager-WNMVbgHf.d.ts → manager-JkbddlcO.d.ts} +43 -42
  5. package/dist/{messages-vq7Bk4Ap.d.mts → messages-6_-q72KG.d.mts} +5970 -2067
  6. package/dist/{messages-vq7Bk4Ap.d.ts → messages-6_-q72KG.d.ts} +5970 -2067
  7. package/dist/{catalog-tX1P4jZQ.d.ts → schemas-r4ZP9S-F.d.mts} +22 -201
  8. package/dist/{catalog-Y8FyPWvh.d.mts → schemas-r4ZP9S-F.d.ts} +22 -201
  9. package/dist/v3/dev/index.d.mts +2 -2
  10. package/dist/v3/dev/index.d.ts +2 -2
  11. package/dist/v3/dev/index.js +4 -4
  12. package/dist/v3/dev/index.js.map +1 -1
  13. package/dist/v3/dev/index.mjs +4 -4
  14. package/dist/v3/dev/index.mjs.map +1 -1
  15. package/dist/v3/index.d.mts +584 -152
  16. package/dist/v3/index.d.ts +584 -152
  17. package/dist/v3/index.js +962 -350
  18. package/dist/v3/index.js.map +1 -1
  19. package/dist/v3/index.mjs +953 -350
  20. package/dist/v3/index.mjs.map +1 -1
  21. package/dist/v3/otel/index.js +1 -1
  22. package/dist/v3/otel/index.js.map +1 -1
  23. package/dist/v3/otel/index.mjs +1 -1
  24. package/dist/v3/otel/index.mjs.map +1 -1
  25. package/dist/v3/prod/index.d.mts +3 -3
  26. package/dist/v3/prod/index.d.ts +3 -3
  27. package/dist/v3/prod/index.js +90 -15
  28. package/dist/v3/prod/index.js.map +1 -1
  29. package/dist/v3/prod/index.mjs +90 -15
  30. package/dist/v3/prod/index.mjs.map +1 -1
  31. package/dist/v3/workers/index.d.mts +6 -5
  32. package/dist/v3/workers/index.d.ts +6 -5
  33. package/dist/v3/workers/index.js +476 -53
  34. package/dist/v3/workers/index.js.map +1 -1
  35. package/dist/v3/workers/index.mjs +477 -54
  36. package/dist/v3/workers/index.mjs.map +1 -1
  37. package/dist/v3/zodMessageHandler.d.mts +1 -1
  38. package/dist/v3/zodMessageHandler.d.ts +1 -1
  39. package/dist/v3/zodNamespace.js +16 -6
  40. package/dist/v3/zodNamespace.js.map +1 -1
  41. package/dist/v3/zodNamespace.mjs +17 -7
  42. package/dist/v3/zodNamespace.mjs.map +1 -1
  43. package/dist/v3/zodSocket.js +16 -6
  44. package/dist/v3/zodSocket.js.map +1 -1
  45. package/dist/v3/zodSocket.mjs +17 -7
  46. package/dist/v3/zodSocket.mjs.map +1 -1
  47. package/dist/v3/zodfetch.d.mts +262 -0
  48. package/dist/v3/zodfetch.d.ts +262 -0
  49. package/dist/v3/zodfetch.js +744 -0
  50. package/dist/v3/zodfetch.js.map +1 -0
  51. package/dist/v3/zodfetch.mjs +716 -0
  52. package/dist/v3/zodfetch.mjs.map +1 -0
  53. package/package.json +9 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts"],"names":["io","z","LogLevel","SimpleStructuredLogger","constructor","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","message","args","console","error","warn","loggerFunction","structuredLog","length","timestamp","Date","JSON","stringify","messageSchema","object","version","literal","default","type","string","payload","unknown","ZodSocketMessageHandler","options","schema","handlers","handleMessage","parsedMessage","parseMessage","Error","handler","String","ack","safeParse","success","data","parsedPayload","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","_schema","ZodSocketMessageSender","socket","send","emit","sendWithAck","callbackResult","emitWithAck","ZodSocketConnection","opts","uri","secure","host","port","namespace","transports","auth","token","authToken","extraHeaders","reconnectionDelay","reconnectionDelayMax","socketId","id","serverMessages","clientMessages","onError","onConnection","reason","description","onDisconnect","close","connect","bind"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAASA,UAAU;AACnB,SAASC,SAAS;;;ICSX;UAAKC,WAAQ;AAARA,EAAAA,UAAAA,UACV,KAAA,IAAA,CAAA,IAAA;AADUA,EAAAA,UAAAA,UAEV,OAAA,IAAA,CAAA,IAAA;AAFUA,EAAAA,UAAAA,UAGV,MAAA,IAAA,CAAA,IAAA;AAHUA,EAAAA,UAAAA,UAIV,MAAA,IAAA,CAAA,IAAA;AAJUA,EAAAA,UAAAA,UAKV,OAAA,IAAA,CAAA,IAAA;GALUA,aAAAA,WAAAA,CAAAA,EAAAA;;AAQL,IAAMC,0BAAN,MAAMA,wBAAAA;EACXC,YACUC,MACAC,QAAkB;IAAC;IAAK;IAAQC,SAASC,QAAQC,IAAIC,SAAS,EAAA,IAClER,SAASS,QACTT,SAASU,MACLC,QACR;AAoCF;gBAzCUR;iBACAC;kBAGAO;EACP;EAEHC,MAAMD,QAAiCP,OAAkB;AACvD,WAAO,IAAIH,wBAAuB,KAAKE,MAAMC,OAAO;MAAE,GAAG,KAAKO;MAAQ,GAAGA;IAAO,CAAA;EAClF;EAEAE,IAAIC,YAAoBC,MAAsB;AAC5C,QAAI,KAAKX,QAAQJ,SAASa;AAAK;AAE/B,0BAAK,kCAAL,WAAoBG,QAAQH,KAAKC,SAAS,OAAA,GAAUC;EACtD;EAEAE,MAAMH,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASiB;AAAO;AAEjC,0BAAK,kCAAL,WAAoBD,QAAQC,OAAOH,SAAS,SAAA,GAAYC;EAC1D;EAEAG,KAAKJ,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASkB;AAAM;AAEhC,0BAAK,kCAAL,WAAoBF,QAAQE,MAAMJ,SAAS,QAAA,GAAWC;EACxD;EAEAL,KAAKI,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASU;AAAM;AAEhC,0BAAK,kCAAL,WAAoBM,QAAQN,MAAMI,SAAS,QAAA,GAAWC;EACxD;EAEAN,MAAMK,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASS;AAAO;AAEjC,0BAAK,kCAAL,WAAoBO,QAAQP,OAAOK,SAAS,SAAA,GAAYC;EAC1D;AAmBF;AAjBE;mBAAc,gCACZI,gBACAL,SACAV,UACGW,MACH;AACA,QAAMK,gBAAgB;IACpB,GAAIL,KAAKM,WAAW,IAAIN,KAAK,CAAA,IAAKA;IAClC,GAAG,KAAKJ;IACRW,WAAW,oBAAIC,KAAAA;IACfpB,MAAM,KAAKA;IACXW;IACAV;EACF;AAEAe,iBAAeK,KAAKC,UAAUL,aAAAA,CAAAA;AAChC,GAhBc;AA3CHnB;AAAN,IAAMA,yBAAN;;;AD+DP,IAAMyB,gBAAgB3B,EAAE4B,OAAO;EAC7BC,SAAS7B,EAAE8B,QAAQ,IAAA,EAAMC,QAAQ,IAAA;EACjCC,MAAMhC,EAAEiC,OAAM;EACdC,SAASlC,EAAEmC,QAAO;AACpB,CAAA;AArFA;AAuFO,IAAMC,2BAAN,MAAMA,yBAAAA;EAIXjC,YAAYkC,SAAsD;AAHlE;AACA;AAGE,uBAAK,SAAUA,QAAQC;AACvB,uBAAK,WAAYD,QAAQE;EAC3B;EAEA,MAAaC,cAAczB,SAAkB;AAC3C,UAAM0B,gBAAgB,KAAKC,aAAa3B,OAAAA;AAExC,QAAI,CAAC,mBAAK,YAAW;AACnB,YAAM,IAAI4B,MAAM,sBAAA;IAClB;AAEA,UAAMC,UAAU,mBAAK,WAAUH,cAAcT,IAAI;AAEjD,QAAI,CAACY,SAAS;AACZ3B,cAAQC,MAAM,gCAAgC2B,OAAOJ,cAAcT,IAAI,CAAA,EAAG;AAC1E;IACF;AAEA,UAAMc,MAAM,MAAMF,QAAQH,cAAcP,OAAO;AAE/C,WAAOY;EACT;EAEOJ,aAAa3B,SAA0D;AAC5E,UAAM0B,gBAAgBd,cAAcoB,UAAUhC,OAAAA;AAE9C,QAAI,CAAC0B,cAAcO,SAAS;AAC1B,YAAM,IAAIL,MAAM,4BAA4BlB,KAAKC,UAAUe,cAAcvB,KAAK,CAAA,EAAG;IACnF;AAEA,UAAMoB,SAAS,mBAAK,SAAQG,cAAcQ,KAAKjB,IAAI,EAAE,SAAA;AAErD,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBF,cAAcQ,KAAKjB,IAAI,EAAE;IACpE;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUN,cAAcQ,KAAKf,OAAO;AAEjE,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAEA,WAAO;MACLc,MAAMS,cAAcQ,KAAKjB;MACzBE,SAASgB,cAAcD;IACzB;EACF;EAEOE,iBAAiBC,SAA2BC,QAA2B;AAC5E,UAAMvC,MAAMuC,UAAUpC;AAEtB,QAAI,CAAC,mBAAK,YAAW;AACnBH,UAAIH,KAAK,sBAAA;AACT;IACF;AAEA,eAAW2C,aAAaC,OAAOC,KAAK,mBAAK,UAAS,GAAG;AACnDJ,cAAQK,GAAGH,WAAW,OAAOvC,SAAc2C,aAAkC;AAC3E5C,YAAIH,KAAK,YAAY2C,SAAAA,IAAa;UAChCpB,SAASnB;UACT4C,aAAa,CAAC,CAACD;QACjB,CAAA;AAEA,YAAIZ;AAEJ,YAAI;AAEF,cAAI,aAAa/B,SAAS;AACxB+B,kBAAM,MAAM,KAAKN,cAAc;cAAER,MAAMsB;cAAW,GAAGvC;YAAQ,CAAA;UAC/D,OAAO;AAEL,kBAAM,EAAEc,SAAS,GAAGK,QAAAA,IAAYnB;AAChC+B,kBAAM,MAAM,KAAKN,cAAc;cAAER,MAAMsB;cAAWzB;cAASK;YAAQ,CAAA;UACrE;QACF,SAAShB,OAAO;AACdJ,cAAII,MAAM,gCAAgC;YAAEA;UAAM,CAAA;AAClD;QACF;AAEA,YAAIwC,YAAY,OAAOA,aAAa,YAAY;AAC9CA,mBAASZ,GAAAA;QACX;MACF,CAAA;IACF;EACF;AACF;AAzFE;AACA;AAFWV;AAAN,IAAMA,0BAAN;AAvFP,IAAAwB,UAAA;AAsMO,IAAMC,0BAAN,MAAMA,wBAAAA;EAIX1D,YAAYkC,SAAyD;AAHrE,uBAAAuB,UAAA;AACA;AAGE,uBAAKA,UAAUvB,QAAQC;AACvB,uBAAK,SAAUD,QAAQyB;EACzB;EAEOC,KACL/B,MACAE,SACM;AACN,UAAMI,SAAS,mBAAKsB,UAAQ5B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBX,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,uBAAK,SAAQ8C,KAAKhC,MAAM;MAAEE;MAASL,SAAS;IAAK,CAAA;AAEjD;EACF;EAEA,MAAaoC,YACXjC,MACAE,SAC+D;AAC/D,UAAMI,SAAS,mBAAKsB,UAAQ5B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBX,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,UAAMgD,iBAAiB,MAAM,mBAAK,SAAQC,YAAYnC,MAAM;MAAEE;MAASL,SAAS;IAAK,CAAA;AAErF,WAAOqC;EACT;AACF;AAnDEN,WAAA;AACA;AAFWC;AAAN,IAAMA,yBAAN;AAtMP;AAsSO,IAAMO,uBAAN,MAAMA,qBAAAA;EAUXjE,YAAYkE,MAAoE;AANhF;AAGA;AACA;AAGE,UAAMC,MAAM,GAAGD,KAAKE,SAAS,QAAQ,IAAI,MAAMF,KAAKG,IAAI,IACtDH,KAAKI,SAASJ,KAAKE,SAAS,QAAQ,KAAG,IACrCF,KAAKK,SAAS;AAElB,UAAMrB,SAAS,IAAInD,uBAAuBmE,KAAKK,WAAWzE,SAASU,IAAI;AACvE0C,WAAOvC,IAAI,kBAAkB;MAAEwD;IAAI,CAAA;AAEnC,SAAKR,SAAS/D,GAAGuE,KAAK;MACpBK,YAAY;QAAC;;MACbC,MAAM;QACJC,OAAOR,KAAKS;MACd;MACAC,cAAcV,KAAKU;MACnBC,mBAAmB;MACnBC,sBAAsB;IACxB,CAAA;AAEA,uBAAK,SAAU5B,OAAOxC,MAAM;MAC1BqE,UAAU,KAAKpB,OAAOqB;IACxB,CAAA;AAEA,uBAAK,UAAW,IAAI/C,wBAAwB;MAC1CE,QAAQ+B,KAAKe;MACb7C,UAAU8B,KAAK9B;IACjB,CAAA;AACA,uBAAK,UAASY,iBAAiB,KAAKW,QAAQ,mBAAK,QAAO;AAExD,uBAAK,SAAU,IAAID,uBAAuB;MACxCvB,QAAQ+B,KAAKgB;MACbvB,QAAQ,KAAKA;IACf,CAAA;AAEA,SAAKA,OAAOL,GAAG,iBAAiB,OAAOvC,UAAU;AAC/C,yBAAK,SAAQA,MAAM,kBAAkBA,KAAAA,EAAO;AAE5C,UAAImD,KAAKiB,SAAS;AAChB,cAAMjB,KAAKiB,QAAQ,KAAKxB,QAAQ5C,OAAO,mBAAK,QAAO;MACrD;IACF,CAAA;AAEA,SAAK4C,OAAOL,GAAG,WAAW,YAAY;AACpC,yBAAK,SAAQ9C,KAAK,SAAA;AAElB,UAAI0D,KAAKkB,cAAc;AACrB,cAAMlB,KAAKkB,aAAa,KAAKzB,QAAQ,mBAAK,WAAU,mBAAK,UAAS,mBAAK,QAAO;MAChF;IACF,CAAA;AAEA,SAAKA,OAAOL,GAAG,cAAc,OAAO+B,QAAQC,gBAAgB;AAC1D,yBAAK,SAAQ9E,KAAK,cAAc;QAAE6E;QAAQC;MAAY,CAAA;AAEtD,UAAIpB,KAAKqB,cAAc;AACrB,cAAMrB,KAAKqB,aAAa,KAAK5B,QAAQ0B,QAAQC,aAAa,mBAAK,QAAO;MACxE;IACF,CAAA;EACF;EAEAE,QAAQ;AACN,SAAK7B,OAAO6B,MAAK;EACnB;EAEAC,UAAU;AACR,SAAK9B,OAAO8B,QAAO;EACrB;EAEA,IAAI7B,OAAO;AACT,WAAO,mBAAK,SAAQA,KAAK8B,KAAK,mBAAK,QAAO;EAC5C;EAEA,IAAI5B,cAAc;AAChB,WAAO,mBAAK,SAAQA,YAAY4B,KAAK,mBAAK,QAAO;EACnD;AACF;AA/EE;AAGA;AACA;AARWzB;AAAN,IAAMA,sBAAN","sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.literal(\"v1\").default(\"v1\"),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog> {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", { error });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n>;\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n\nfunction createLogger(prefix: string) {\n return (...args: any[]) => console.log(prefix, ...args);\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts"],"names":["io","ZodError","z","LogLevel","SimpleStructuredLogger","constructor","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","message","args","console","error","warn","loggerFunction","structuredLog","length","timestamp","Date","JSON","stringify","fromZodError","messageSchema","object","version","string","type","payload","unknown","ZodSocketMessageHandler","options","schema","handlers","handleMessage","parsedMessage","parseMessage","Error","handler","String","ack","safeParse","success","data","messageWithVersion","parsedPayload","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","stack","_schema","ZodSocketMessageSender","socket","send","emit","sendWithAck","callbackResult","emitWithAck","ZodSocketConnection","opts","uri","secure","host","port","namespace","transports","auth","token","authToken","extraHeaders","reconnectionDelay","reconnectionDelayMax","socketId","id","serverMessages","clientMessages","onError","onConnection","reason","description","onDisconnect","close","connect","bind"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAASA,UAAU;AACnB,SAASC,UAAUC,SAAS;;;ICSrB;UAAKC,WAAQ;AAARA,EAAAA,UAAAA,UACV,KAAA,IAAA,CAAA,IAAA;AADUA,EAAAA,UAAAA,UAEV,OAAA,IAAA,CAAA,IAAA;AAFUA,EAAAA,UAAAA,UAGV,MAAA,IAAA,CAAA,IAAA;AAHUA,EAAAA,UAAAA,UAIV,MAAA,IAAA,CAAA,IAAA;AAJUA,EAAAA,UAAAA,UAKV,OAAA,IAAA,CAAA,IAAA;GALUA,aAAAA,WAAAA,CAAAA,EAAAA;;AAQL,IAAMC,0BAAN,MAAMA,wBAAAA;EACXC,YACUC,MACAC,QAAkB;IAAC;IAAK;IAAQC,SAASC,QAAQC,IAAIC,SAAS,EAAA,IAClER,SAASS,QACTT,SAASU,MACLC,QACR;AAoCF;gBAzCUR;iBACAC;kBAGAO;EACP;EAEHC,MAAMD,QAAiCP,OAAkB;AACvD,WAAO,IAAIH,wBAAuB,KAAKE,MAAMC,OAAO;MAAE,GAAG,KAAKO;MAAQ,GAAGA;IAAO,CAAA;EAClF;EAEAE,IAAIC,YAAoBC,MAAsB;AAC5C,QAAI,KAAKX,QAAQJ,SAASa;AAAK;AAE/B,0BAAK,kCAAL,WAAoBG,QAAQH,KAAKC,SAAS,OAAA,GAAUC;EACtD;EAEAE,MAAMH,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASiB;AAAO;AAEjC,0BAAK,kCAAL,WAAoBD,QAAQC,OAAOH,SAAS,SAAA,GAAYC;EAC1D;EAEAG,KAAKJ,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASkB;AAAM;AAEhC,0BAAK,kCAAL,WAAoBF,QAAQE,MAAMJ,SAAS,QAAA,GAAWC;EACxD;EAEAL,KAAKI,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASU;AAAM;AAEhC,0BAAK,kCAAL,WAAoBM,QAAQN,MAAMI,SAAS,QAAA,GAAWC;EACxD;EAEAN,MAAMK,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASS;AAAO;AAEjC,0BAAK,kCAAL,WAAoBO,QAAQP,OAAOK,SAAS,SAAA,GAAYC;EAC1D;AAmBF;AAjBE;mBAAc,gCACZI,gBACAL,SACAV,UACGW,MACH;AACA,QAAMK,gBAAgB;IACpB,GAAIL,KAAKM,WAAW,IAAIN,KAAK,CAAA,IAAKA;IAClC,GAAG,KAAKJ;IACRW,WAAW,oBAAIC,KAAAA;IACfpB,MAAM,KAAKA;IACXW;IACAV;EACF;AAEAe,iBAAeK,KAAKC,UAAUL,aAAAA,CAAAA;AAChC,GAhBc;AA3CHnB;AAAN,IAAMA,yBAAN;;;ADdP,SAASyB,oBAAoB;AA8E7B,IAAMC,gBAAgB5B,EAAE6B,OAAO;EAC7BC,SAAS9B,EAAE+B,OAAM;EACjBC,MAAMhC,EAAE+B,OAAM;EACdE,SAASjC,EAAEkC,QAAO;AACpB,CAAA;AAtFA;AAwFO,IAAMC,2BAAN,MAAMA,yBAAAA;EAIXhC,YAAYiC,SAAsD;AAHlE;AACA;AAGE,uBAAK,SAAUA,QAAQC;AACvB,uBAAK,WAAYD,QAAQE;EAC3B;EAEA,MAAaC,cAAcxB,SAAkB;AAC3C,UAAMyB,gBAAgB,KAAKC,aAAa1B,OAAAA;AAExC,QAAI,CAAC,mBAAK,YAAW;AACnB,YAAM,IAAI2B,MAAM,sBAAA;IAClB;AAEA,UAAMC,UAAU,mBAAK,WAAUH,cAAcR,IAAI;AAEjD,QAAI,CAACW,SAAS;AACZ1B,cAAQC,MAAM,gCAAgC0B,OAAOJ,cAAcR,IAAI,CAAA,EAAG;AAC1E;IACF;AAEA,UAAMa,MAAM,MAAMF,QAAQH,cAAcP,OAAO;AAE/C,WAAOY;EACT;EAEOJ,aAAa1B,SAA0D;AAC5E,UAAMyB,gBAAgBZ,cAAckB,UAAU/B,OAAAA;AAE9C,QAAI,CAACyB,cAAcO,SAAS;AAC1B,YAAM,IAAIL,MAAM,4BAA4BjB,KAAKC,UAAUc,cAActB,KAAK,CAAA,EAAG;IACnF;AAEA,UAAMmB,SAAS,mBAAK,SAAQG,cAAcQ,KAAKhB,IAAI,EAAE,SAAA;AAErD,QAAI,CAACK,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBF,cAAcQ,KAAKhB,IAAI,EAAE;IACpE;AAEA,UAAMiB,qBAAqB;MACzBnB,SAASU,cAAcQ,KAAKlB;MAC5B,GAAI,OAAOU,cAAcQ,KAAKf,YAAY,WAAWO,cAAcQ,KAAKf,UAAU,CAAC;IACrF;AAEA,UAAMiB,gBAAgBb,OAAOS,UAAUG,kBAAAA;AAEvC,QAAI,CAACC,cAAcH,SAAS;AAC1B9B,cAAQC,MAAM,mCAAmC;QAC/CH;QACAkB,SAASgB;MACX,CAAA;AAEA,YAAMC,cAAchC,iBAAiBnB,WACjC4B,aAAauB,cAAchC,KAAK,IAChCgC,cAAchC;IACpB;AAEA,WAAO;MACLc,MAAMQ,cAAcQ,KAAKhB;MACzBC,SAASiB,cAAcF;IACzB;EACF;EAEOG,iBAAiBC,SAA2BC,QAA2B;AAC5E,UAAMvC,MAAMuC,UAAUpC;AAEtB,QAAI,CAAC,mBAAK,YAAW;AACnBH,UAAIH,KAAK,sBAAA;AACT;IACF;AAEA,eAAW2C,aAAaC,OAAOC,KAAK,mBAAK,UAAS,GAAG;AACnDJ,cAAQK,GAAGH,WAAW,OAAOvC,SAAc2C,aAAkC;AAC3E5C,YAAIH,KAAK,YAAY2C,SAAAA,IAAa;UAChCrB,SAASlB;UACT4C,aAAa,CAAC,CAACD;QACjB,CAAA;AAEA,YAAIb;AAEJ,YAAI;AAEF,cAAI,aAAa9B,SAAS;AACxB8B,kBAAM,MAAM,KAAKN,cAAc;cAAEP,MAAMsB;cAAW,GAAGvC;YAAQ,CAAA;UAC/D,OAAO;AAEL,kBAAM,EAAEe,SAAS,GAAGG,QAAAA,IAAYlB;AAChC8B,kBAAM,MAAM,KAAKN,cAAc;cAAEP,MAAMsB;cAAWxB;cAASG;YAAQ,CAAA;UACrE;QACF,SAASf,OAAO;AACdJ,cAAII,MAAM,gCAAgC;YACxCA,OACEA,iBAAiBwB,QACb;cACE3B,SAASG,MAAMH;cACf6C,OAAO1C,MAAM0C;YACf,IACA1C;UACR,CAAA;AACA;QACF;AAEA,YAAIwC,YAAY,OAAOA,aAAa,YAAY;AAC9CA,mBAASb,GAAAA;QACX;MACF,CAAA;IACF;EACF;AACF;AA7GE;AACA;AAFWV;AAAN,IAAMA,0BAAN;AAxFP,IAAA0B,UAAA;AA2NO,IAAMC,0BAAN,MAAMA,wBAAAA;EAIX3D,YAAYiC,SAAyD;AAHrE,uBAAAyB,UAAA;AACA;AAGE,uBAAKA,UAAUzB,QAAQC;AACvB,uBAAK,SAAUD,QAAQ2B;EACzB;EAEOC,KACLhC,MACAC,SACM;AACN,UAAMI,SAAS,mBAAKwB,UAAQ7B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACK,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBV,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBb,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACiB,cAAcH,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoCjB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,uBAAK,SAAQ+C,KAAKjC,MAAM;MAAEC;MAASH,SAAS;IAAK,CAAA;AAEjD;EACF;EAEA,MAAaoC,YACXlC,MACAC,SAC+D;AAC/D,UAAMI,SAAS,mBAAKwB,UAAQ7B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACK,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBV,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBb,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACiB,cAAcH,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoCjB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,UAAMiD,iBAAiB,MAAM,mBAAK,SAAQC,YAAYpC,MAAM;MAAEC;MAASH,SAAS;IAAK,CAAA;AAErF,WAAOqC;EACT;AACF;AAnDEN,WAAA;AACA;AAFWC;AAAN,IAAMA,yBAAN;AA3NP;AA2TO,IAAMO,uBAAN,MAAMA,qBAAAA;EAUXlE,YAAYmE,MAAoE;AANhF;AAGA;AACA;AAGE,UAAMC,MAAM,GAAGD,KAAKE,SAAS,QAAQ,IAAI,MAAMF,KAAKG,IAAI,IACtDH,KAAKI,SAASJ,KAAKE,SAAS,QAAQ,KAAG,IACrCF,KAAKK,SAAS;AAElB,UAAMtB,SAAS,IAAInD,uBAAuBoE,KAAKK,WAAW1E,SAASU,IAAI;AACvE0C,WAAOvC,IAAI,kBAAkB;MAAEyD;IAAI,CAAA;AAEnC,SAAKR,SAASjE,GAAGyE,KAAK;MACpBK,YAAY;QAAC;;MACbC,MAAM;QACJC,OAAOR,KAAKS;MACd;MACAC,cAAcV,KAAKU;MACnBC,mBAAmB;MACnBC,sBAAsB;IACxB,CAAA;AAEA,uBAAK,SAAU7B,OAAOxC,MAAM;MAC1BsE,UAAU,KAAKpB,OAAOqB;IACxB,CAAA;AAEA,uBAAK,UAAW,IAAIjD,wBAAwB;MAC1CE,QAAQiC,KAAKe;MACb/C,UAAUgC,KAAKhC;IACjB,CAAA;AACA,uBAAK,UAASa,iBAAiB,KAAKY,QAAQ,mBAAK,QAAO;AAExD,uBAAK,SAAU,IAAID,uBAAuB;MACxCzB,QAAQiC,KAAKgB;MACbvB,QAAQ,KAAKA;IACf,CAAA;AAEA,SAAKA,OAAON,GAAG,iBAAiB,OAAOvC,UAAU;AAC/C,yBAAK,SAAQA,MAAM,kBAAkBA,KAAAA,EAAO;AAE5C,UAAIoD,KAAKiB,SAAS;AAChB,cAAMjB,KAAKiB,QAAQ,KAAKxB,QAAQ7C,OAAO,mBAAK,QAAO;MACrD;IACF,CAAA;AAEA,SAAK6C,OAAON,GAAG,WAAW,YAAY;AACpC,yBAAK,SAAQ9C,KAAK,SAAA;AAElB,UAAI2D,KAAKkB,cAAc;AACrB,cAAMlB,KAAKkB,aAAa,KAAKzB,QAAQ,mBAAK,WAAU,mBAAK,UAAS,mBAAK,QAAO;MAChF;IACF,CAAA;AAEA,SAAKA,OAAON,GAAG,cAAc,OAAOgC,QAAQC,gBAAgB;AAC1D,yBAAK,SAAQ/E,KAAK,cAAc;QAAE8E;QAAQC;MAAY,CAAA;AAEtD,UAAIpB,KAAKqB,cAAc;AACrB,cAAMrB,KAAKqB,aAAa,KAAK5B,QAAQ0B,QAAQC,aAAa,mBAAK,QAAO;MACxE;IACF,CAAA;EACF;EAEAE,QAAQ;AACN,SAAK7B,OAAO6B,MAAK;EACnB;EAEAC,UAAU;AACR,SAAK9B,OAAO8B,QAAO;EACrB;EAEA,IAAI7B,OAAO;AACT,WAAO,mBAAK,SAAQA,KAAK8B,KAAK,mBAAK,QAAO;EAC5C;EAEA,IAAI5B,cAAc;AAChB,WAAO,mBAAK,SAAQA,YAAY4B,KAAK,mBAAK,QAAO;EACnD;AACF;AA/EE;AAGA;AACA;AARWzB;AAAN,IAAMA,sBAAN","sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { ZodError, z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\nimport { fromZodError } from \"zod-validation-error\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.string(),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog> {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const messageWithVersion = {\n version: parsedMessage.data.version,\n ...(typeof parsedMessage.data.payload === \"object\" ? parsedMessage.data.payload : {}),\n };\n\n const parsedPayload = schema.safeParse(messageWithVersion);\n\n if (!parsedPayload.success) {\n console.error(\"Failed to parse message payload\", {\n message,\n payload: messageWithVersion,\n });\n\n throw parsedPayload.error instanceof ZodError\n ? fromZodError(parsedPayload.error)\n : parsedPayload.error;\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", {\n error:\n error instanceof Error\n ? {\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n>;\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n\nfunction createLogger(prefix: string) {\n return (...args: any[]) => console.log(prefix, ...args);\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { io } from 'socket.io-client';
2
- import { z } from 'zod';
2
+ import { z, ZodError } from 'zod';
3
+ import { fromZodError } from 'zod-validation-error';
3
4
 
4
5
  var __defProp = Object.defineProperty;
5
6
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -92,10 +93,8 @@ structuredLog_fn = /* @__PURE__ */ __name(function(loggerFunction, message, leve
92
93
  }, "#structuredLog");
93
94
  __name(_SimpleStructuredLogger, "SimpleStructuredLogger");
94
95
  var SimpleStructuredLogger = _SimpleStructuredLogger;
95
-
96
- // src/v3/zodSocket.ts
97
96
  var messageSchema = z.object({
98
- version: z.literal("v1").default("v1"),
97
+ version: z.string(),
99
98
  type: z.string(),
100
99
  payload: z.unknown()
101
100
  });
@@ -129,9 +128,17 @@ var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
129
128
  if (!schema) {
130
129
  throw new Error(`Unknown message type: ${parsedMessage.data.type}`);
131
130
  }
132
- const parsedPayload = schema.safeParse(parsedMessage.data.payload);
131
+ const messageWithVersion = {
132
+ version: parsedMessage.data.version,
133
+ ...typeof parsedMessage.data.payload === "object" ? parsedMessage.data.payload : {}
134
+ };
135
+ const parsedPayload = schema.safeParse(messageWithVersion);
133
136
  if (!parsedPayload.success) {
134
- throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);
137
+ console.error("Failed to parse message payload", {
138
+ message,
139
+ payload: messageWithVersion
140
+ });
141
+ throw parsedPayload.error instanceof ZodError ? fromZodError(parsedPayload.error) : parsedPayload.error;
135
142
  }
136
143
  return {
137
144
  type: parsedMessage.data.type,
@@ -167,7 +174,10 @@ var _ZodSocketMessageHandler = class _ZodSocketMessageHandler {
167
174
  }
168
175
  } catch (error) {
169
176
  log.error("Error while handling message", {
170
- error
177
+ error: error instanceof Error ? {
178
+ message: error.message,
179
+ stack: error.stack
180
+ } : error
171
181
  });
172
182
  return;
173
183
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts"],"names":["io","z","LogLevel","SimpleStructuredLogger","constructor","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","message","args","console","error","warn","loggerFunction","structuredLog","length","timestamp","Date","JSON","stringify","messageSchema","object","version","literal","default","type","string","payload","unknown","ZodSocketMessageHandler","options","schema","handlers","handleMessage","parsedMessage","parseMessage","Error","handler","String","ack","safeParse","success","data","parsedPayload","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","_schema","ZodSocketMessageSender","socket","send","emit","sendWithAck","callbackResult","emitWithAck","ZodSocketConnection","opts","uri","secure","host","port","namespace","transports","auth","token","authToken","extraHeaders","reconnectionDelay","reconnectionDelayMax","socketId","id","serverMessages","clientMessages","onError","onConnection","reason","description","onDisconnect","close","connect","bind"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAASA,UAAU;AACnB,SAASC,SAAS;;;ICSX;UAAKC,WAAQ;AAARA,EAAAA,UAAAA,UACV,KAAA,IAAA,CAAA,IAAA;AADUA,EAAAA,UAAAA,UAEV,OAAA,IAAA,CAAA,IAAA;AAFUA,EAAAA,UAAAA,UAGV,MAAA,IAAA,CAAA,IAAA;AAHUA,EAAAA,UAAAA,UAIV,MAAA,IAAA,CAAA,IAAA;AAJUA,EAAAA,UAAAA,UAKV,OAAA,IAAA,CAAA,IAAA;GALUA,aAAAA,WAAAA,CAAAA,EAAAA;;AAQL,IAAMC,0BAAN,MAAMA,wBAAAA;EACXC,YACUC,MACAC,QAAkB;IAAC;IAAK;IAAQC,SAASC,QAAQC,IAAIC,SAAS,EAAA,IAClER,SAASS,QACTT,SAASU,MACLC,QACR;AAoCF;gBAzCUR;iBACAC;kBAGAO;EACP;EAEHC,MAAMD,QAAiCP,OAAkB;AACvD,WAAO,IAAIH,wBAAuB,KAAKE,MAAMC,OAAO;MAAE,GAAG,KAAKO;MAAQ,GAAGA;IAAO,CAAA;EAClF;EAEAE,IAAIC,YAAoBC,MAAsB;AAC5C,QAAI,KAAKX,QAAQJ,SAASa;AAAK;AAE/B,0BAAK,kCAAL,WAAoBG,QAAQH,KAAKC,SAAS,OAAA,GAAUC;EACtD;EAEAE,MAAMH,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASiB;AAAO;AAEjC,0BAAK,kCAAL,WAAoBD,QAAQC,OAAOH,SAAS,SAAA,GAAYC;EAC1D;EAEAG,KAAKJ,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASkB;AAAM;AAEhC,0BAAK,kCAAL,WAAoBF,QAAQE,MAAMJ,SAAS,QAAA,GAAWC;EACxD;EAEAL,KAAKI,YAAoBC,MAAsB;AAC7C,QAAI,KAAKX,QAAQJ,SAASU;AAAM;AAEhC,0BAAK,kCAAL,WAAoBM,QAAQN,MAAMI,SAAS,QAAA,GAAWC;EACxD;EAEAN,MAAMK,YAAoBC,MAAsB;AAC9C,QAAI,KAAKX,QAAQJ,SAASS;AAAO;AAEjC,0BAAK,kCAAL,WAAoBO,QAAQP,OAAOK,SAAS,SAAA,GAAYC;EAC1D;AAmBF;AAjBE;mBAAc,gCACZI,gBACAL,SACAV,UACGW,MACH;AACA,QAAMK,gBAAgB;IACpB,GAAIL,KAAKM,WAAW,IAAIN,KAAK,CAAA,IAAKA;IAClC,GAAG,KAAKJ;IACRW,WAAW,oBAAIC,KAAAA;IACfpB,MAAM,KAAKA;IACXW;IACAV;EACF;AAEAe,iBAAeK,KAAKC,UAAUL,aAAAA,CAAAA;AAChC,GAhBc;AA3CHnB;AAAN,IAAMA,yBAAN;;;AD+DP,IAAMyB,gBAAgB3B,EAAE4B,OAAO;EAC7BC,SAAS7B,EAAE8B,QAAQ,IAAA,EAAMC,QAAQ,IAAA;EACjCC,MAAMhC,EAAEiC,OAAM;EACdC,SAASlC,EAAEmC,QAAO;AACpB,CAAA;AArFA;AAuFO,IAAMC,2BAAN,MAAMA,yBAAAA;EAIXjC,YAAYkC,SAAsD;AAHlE;AACA;AAGE,uBAAK,SAAUA,QAAQC;AACvB,uBAAK,WAAYD,QAAQE;EAC3B;EAEA,MAAaC,cAAczB,SAAkB;AAC3C,UAAM0B,gBAAgB,KAAKC,aAAa3B,OAAAA;AAExC,QAAI,CAAC,mBAAK,YAAW;AACnB,YAAM,IAAI4B,MAAM,sBAAA;IAClB;AAEA,UAAMC,UAAU,mBAAK,WAAUH,cAAcT,IAAI;AAEjD,QAAI,CAACY,SAAS;AACZ3B,cAAQC,MAAM,gCAAgC2B,OAAOJ,cAAcT,IAAI,CAAA,EAAG;AAC1E;IACF;AAEA,UAAMc,MAAM,MAAMF,QAAQH,cAAcP,OAAO;AAE/C,WAAOY;EACT;EAEOJ,aAAa3B,SAA0D;AAC5E,UAAM0B,gBAAgBd,cAAcoB,UAAUhC,OAAAA;AAE9C,QAAI,CAAC0B,cAAcO,SAAS;AAC1B,YAAM,IAAIL,MAAM,4BAA4BlB,KAAKC,UAAUe,cAAcvB,KAAK,CAAA,EAAG;IACnF;AAEA,UAAMoB,SAAS,mBAAK,SAAQG,cAAcQ,KAAKjB,IAAI,EAAE,SAAA;AAErD,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBF,cAAcQ,KAAKjB,IAAI,EAAE;IACpE;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUN,cAAcQ,KAAKf,OAAO;AAEjE,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAEA,WAAO;MACLc,MAAMS,cAAcQ,KAAKjB;MACzBE,SAASgB,cAAcD;IACzB;EACF;EAEOE,iBAAiBC,SAA2BC,QAA2B;AAC5E,UAAMvC,MAAMuC,UAAUpC;AAEtB,QAAI,CAAC,mBAAK,YAAW;AACnBH,UAAIH,KAAK,sBAAA;AACT;IACF;AAEA,eAAW2C,aAAaC,OAAOC,KAAK,mBAAK,UAAS,GAAG;AACnDJ,cAAQK,GAAGH,WAAW,OAAOvC,SAAc2C,aAAkC;AAC3E5C,YAAIH,KAAK,YAAY2C,SAAAA,IAAa;UAChCpB,SAASnB;UACT4C,aAAa,CAAC,CAACD;QACjB,CAAA;AAEA,YAAIZ;AAEJ,YAAI;AAEF,cAAI,aAAa/B,SAAS;AACxB+B,kBAAM,MAAM,KAAKN,cAAc;cAAER,MAAMsB;cAAW,GAAGvC;YAAQ,CAAA;UAC/D,OAAO;AAEL,kBAAM,EAAEc,SAAS,GAAGK,QAAAA,IAAYnB;AAChC+B,kBAAM,MAAM,KAAKN,cAAc;cAAER,MAAMsB;cAAWzB;cAASK;YAAQ,CAAA;UACrE;QACF,SAAShB,OAAO;AACdJ,cAAII,MAAM,gCAAgC;YAAEA;UAAM,CAAA;AAClD;QACF;AAEA,YAAIwC,YAAY,OAAOA,aAAa,YAAY;AAC9CA,mBAASZ,GAAAA;QACX;MACF,CAAA;IACF;EACF;AACF;AAzFE;AACA;AAFWV;AAAN,IAAMA,0BAAN;AAvFP,IAAAwB,UAAA;AAsMO,IAAMC,0BAAN,MAAMA,wBAAAA;EAIX1D,YAAYkC,SAAyD;AAHrE,uBAAAuB,UAAA;AACA;AAGE,uBAAKA,UAAUvB,QAAQC;AACvB,uBAAK,SAAUD,QAAQyB;EACzB;EAEOC,KACL/B,MACAE,SACM;AACN,UAAMI,SAAS,mBAAKsB,UAAQ5B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBX,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,uBAAK,SAAQ8C,KAAKhC,MAAM;MAAEE;MAASL,SAAS;IAAK,CAAA;AAEjD;EACF;EAEA,MAAaoC,YACXjC,MACAE,SAC+D;AAC/D,UAAMI,SAAS,mBAAKsB,UAAQ5B,IAAAA,EAAM,SAAA;AAElC,QAAI,CAACM,QAAQ;AACX,YAAM,IAAIK,MAAM,yBAAyBX,IAAAA,EAAgB;IAC3D;AAEA,UAAMkB,gBAAgBZ,OAAOS,UAAUb,OAAAA;AAEvC,QAAI,CAACgB,cAAcF,SAAS;AAC1B,YAAM,IAAIL,MAAM,oCAAoClB,KAAKC,UAAUwB,cAAchC,KAAK,CAAA,EAAG;IAC3F;AAGA,UAAMgD,iBAAiB,MAAM,mBAAK,SAAQC,YAAYnC,MAAM;MAAEE;MAASL,SAAS;IAAK,CAAA;AAErF,WAAOqC;EACT;AACF;AAnDEN,WAAA;AACA;AAFWC;AAAN,IAAMA,yBAAN;AAtMP;AAsSO,IAAMO,uBAAN,MAAMA,qBAAAA;EAUXjE,YAAYkE,MAAoE;AANhF;AAGA;AACA;AAGE,UAAMC,MAAM,GAAGD,KAAKE,SAAS,QAAQ,IAAI,MAAMF,KAAKG,IAAI,IACtDH,KAAKI,SAASJ,KAAKE,SAAS,QAAQ,KAAG,IACrCF,KAAKK,SAAS;AAElB,UAAMrB,SAAS,IAAInD,uBAAuBmE,KAAKK,WAAWzE,SAASU,IAAI;AACvE0C,WAAOvC,IAAI,kBAAkB;MAAEwD;IAAI,CAAA;AAEnC,SAAKR,SAAS/D,GAAGuE,KAAK;MACpBK,YAAY;QAAC;;MACbC,MAAM;QACJC,OAAOR,KAAKS;MACd;MACAC,cAAcV,KAAKU;MACnBC,mBAAmB;MACnBC,sBAAsB;IACxB,CAAA;AAEA,uBAAK,SAAU5B,OAAOxC,MAAM;MAC1BqE,UAAU,KAAKpB,OAAOqB;IACxB,CAAA;AAEA,uBAAK,UAAW,IAAI/C,wBAAwB;MAC1CE,QAAQ+B,KAAKe;MACb7C,UAAU8B,KAAK9B;IACjB,CAAA;AACA,uBAAK,UAASY,iBAAiB,KAAKW,QAAQ,mBAAK,QAAO;AAExD,uBAAK,SAAU,IAAID,uBAAuB;MACxCvB,QAAQ+B,KAAKgB;MACbvB,QAAQ,KAAKA;IACf,CAAA;AAEA,SAAKA,OAAOL,GAAG,iBAAiB,OAAOvC,UAAU;AAC/C,yBAAK,SAAQA,MAAM,kBAAkBA,KAAAA,EAAO;AAE5C,UAAImD,KAAKiB,SAAS;AAChB,cAAMjB,KAAKiB,QAAQ,KAAKxB,QAAQ5C,OAAO,mBAAK,QAAO;MACrD;IACF,CAAA;AAEA,SAAK4C,OAAOL,GAAG,WAAW,YAAY;AACpC,yBAAK,SAAQ9C,KAAK,SAAA;AAElB,UAAI0D,KAAKkB,cAAc;AACrB,cAAMlB,KAAKkB,aAAa,KAAKzB,QAAQ,mBAAK,WAAU,mBAAK,UAAS,mBAAK,QAAO;MAChF;IACF,CAAA;AAEA,SAAKA,OAAOL,GAAG,cAAc,OAAO+B,QAAQC,gBAAgB;AAC1D,yBAAK,SAAQ9E,KAAK,cAAc;QAAE6E;QAAQC;MAAY,CAAA;AAEtD,UAAIpB,KAAKqB,cAAc;AACrB,cAAMrB,KAAKqB,aAAa,KAAK5B,QAAQ0B,QAAQC,aAAa,mBAAK,QAAO;MACxE;IACF,CAAA;EACF;EAEAE,QAAQ;AACN,SAAK7B,OAAO6B,MAAK;EACnB;EAEAC,UAAU;AACR,SAAK9B,OAAO8B,QAAO;EACrB;EAEA,IAAI7B,OAAO;AACT,WAAO,mBAAK,SAAQA,KAAK8B,KAAK,mBAAK,QAAO;EAC5C;EAEA,IAAI5B,cAAc;AAChB,WAAO,mBAAK,SAAQA,YAAY4B,KAAK,mBAAK,QAAO;EACnD;AACF;AA/EE;AAGA;AACA;AARWzB;AAAN,IAAMA,sBAAN","sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.literal(\"v1\").default(\"v1\"),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog> {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const parsedPayload = schema.safeParse(parsedMessage.data.payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", { error });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n>;\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n\nfunction createLogger(prefix: string) {\n return (...args: any[]) => console.log(prefix, ...args);\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/v3/zodSocket.ts","../../src/v3/utils/structuredLogger.ts"],"names":["io","ZodError","z","LogLevel","SimpleStructuredLogger","constructor","name","level","includes","process","env","DEBUG","debug","info","fields","child","log","message","args","console","error","warn","loggerFunction","structuredLog","length","timestamp","Date","JSON","stringify","fromZodError","messageSchema","object","version","string","type","payload","unknown","ZodSocketMessageHandler","options","schema","handlers","handleMessage","parsedMessage","parseMessage","Error","handler","String","ack","safeParse","success","data","messageWithVersion","parsedPayload","registerHandlers","emitter","logger","eventName","Object","keys","on","callback","hasCallback","stack","_schema","ZodSocketMessageSender","socket","send","emit","sendWithAck","callbackResult","emitWithAck","ZodSocketConnection","opts","uri","secure","host","port","namespace","transports","auth","token","authToken","extraHeaders","reconnectionDelay","reconnectionDelayMax","socketId","id","serverMessages","clientMessages","onError","onConnection","reason","description","onDisconnect","close","connect","bind"],"mappings":"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","sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport { io } from \"socket.io-client\";\nimport { ZodError, z } from \"zod\";\nimport { EventEmitterLike, ZodMessageValueSchema } from \"./zodMessageHandler\";\nimport { LogLevel, SimpleStructuredLogger, StructuredLogger } from \"./utils/structuredLogger\";\nimport { fromZodError } from \"zod-validation-error\";\n\nexport interface ZodSocketMessageCatalogSchema {\n [key: string]:\n | {\n message: ZodMessageValueSchema<any>;\n }\n | {\n message: ZodMessageValueSchema<any>;\n callback?: ZodMessageValueSchema<any>;\n };\n}\n\nexport type ZodMessageCatalogToSocketIoEvents<TCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TCatalog]: SocketMessageHasCallback<TCatalog, K> extends true\n ? (\n message: z.infer<GetSocketMessageSchema<TCatalog, K>>,\n callback: (ack: z.infer<GetSocketCallbackSchema<TCatalog, K>>) => void\n ) => void\n : (message: z.infer<GetSocketMessageSchema<TCatalog, K>>) => void;\n};\n\nexport type GetSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType][\"message\"];\n\nexport type InferSocketMessageSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketMessageSchema<TRPCCatalog, TMessageType>>;\n\nexport type GetSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = TRPCCatalog[TMessageType] extends { callback: any }\n ? TRPCCatalog[TMessageType][\"callback\"]\n : never;\n\nexport type InferSocketCallbackSchema<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = z.infer<GetSocketCallbackSchema<TRPCCatalog, TMessageType>>;\n\nexport type SocketMessageHasCallback<\n TRPCCatalog extends ZodSocketMessageCatalogSchema,\n TMessageType extends keyof TRPCCatalog,\n> = GetSocketCallbackSchema<TRPCCatalog, TMessageType> extends never ? false : true;\n\nexport type ZodSocketMessageHandlers<TCatalogSchema extends ZodSocketMessageCatalogSchema> =\n Partial<{\n [K in keyof TCatalogSchema]: (\n payload: z.infer<GetSocketMessageSchema<TCatalogSchema, K>>\n ) => Promise<\n SocketMessageHasCallback<TCatalogSchema, K> extends true\n ? z.input<GetSocketCallbackSchema<TCatalogSchema, K>>\n : void\n >;\n }>;\n\nexport type ZodSocketMessageHandlerOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> =\n {\n schema: TMessageCatalog;\n handlers?: ZodSocketMessageHandlers<TMessageCatalog>;\n };\n\ntype MessageFromSocketSchema<\n K extends keyof TMessageCatalog,\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n type: K;\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>;\n};\n\nexport type MessagesFromSocketCatalog<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: MessageFromSocketSchema<K, TMessageCatalog>;\n}[keyof TMessageCatalog];\n\nconst messageSchema = z.object({\n version: z.string(),\n type: z.string(),\n payload: z.unknown(),\n});\n\nexport class ZodSocketMessageHandler<TRPCCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TRPCCatalog;\n #handlers: ZodSocketMessageHandlers<TRPCCatalog> | undefined;\n\n constructor(options: ZodSocketMessageHandlerOptions<TRPCCatalog>) {\n this.#schema = options.schema;\n this.#handlers = options.handlers;\n }\n\n public async handleMessage(message: unknown) {\n const parsedMessage = this.parseMessage(message);\n\n if (!this.#handlers) {\n throw new Error(\"No handlers provided\");\n }\n\n const handler = this.#handlers[parsedMessage.type];\n\n if (!handler) {\n console.error(`No handler for message type: ${String(parsedMessage.type)}`);\n return;\n }\n\n const ack = await handler(parsedMessage.payload);\n\n return ack;\n }\n\n public parseMessage(message: unknown): MessagesFromSocketCatalog<TRPCCatalog> {\n const parsedMessage = messageSchema.safeParse(message);\n\n if (!parsedMessage.success) {\n throw new Error(`Failed to parse message: ${JSON.stringify(parsedMessage.error)}`);\n }\n\n const schema = this.#schema[parsedMessage.data.type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${parsedMessage.data.type}`);\n }\n\n const messageWithVersion = {\n version: parsedMessage.data.version,\n ...(typeof parsedMessage.data.payload === \"object\" ? parsedMessage.data.payload : {}),\n };\n\n const parsedPayload = schema.safeParse(messageWithVersion);\n\n if (!parsedPayload.success) {\n console.error(\"Failed to parse message payload\", {\n message,\n payload: messageWithVersion,\n });\n\n throw parsedPayload.error instanceof ZodError\n ? fromZodError(parsedPayload.error)\n : parsedPayload.error;\n }\n\n return {\n type: parsedMessage.data.type,\n payload: parsedPayload.data,\n };\n }\n\n public registerHandlers(emitter: EventEmitterLike, logger?: StructuredLogger) {\n const log = logger ?? console;\n\n if (!this.#handlers) {\n log.info(\"No handlers provided\");\n return;\n }\n\n for (const eventName of Object.keys(this.#handlers)) {\n emitter.on(eventName, async (message: any, callback?: any): Promise<void> => {\n log.info(`handling ${eventName}`, {\n payload: message,\n hasCallback: !!callback,\n });\n\n let ack;\n\n try {\n // FIXME: this only works if the message doesn't have genuine payload prop\n if (\"payload\" in message) {\n ack = await this.handleMessage({ type: eventName, ...message });\n } else {\n // Handle messages not sent by ZodMessageSender\n const { version, ...payload } = message;\n ack = await this.handleMessage({ type: eventName, version, payload });\n }\n } catch (error) {\n log.error(\"Error while handling message\", {\n error:\n error instanceof Error\n ? {\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n return;\n }\n\n if (callback && typeof callback === \"function\") {\n callback(ack);\n }\n });\n }\n }\n}\n\nexport type ZodSocketMessageSenderOptions<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n schema: TMessageCatalog;\n socket: ZodSocket<any, TMessageCatalog>;\n};\n\nexport type GetSocketMessagesWithCallback<TMessageCatalog extends ZodSocketMessageCatalogSchema> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? K\n : never;\n}[keyof TMessageCatalog];\n\nexport type GetSocketMessagesWithoutCallback<\n TMessageCatalog extends ZodSocketMessageCatalogSchema,\n> = {\n [K in keyof TMessageCatalog]: SocketMessageHasCallback<TMessageCatalog, K> extends true\n ? never\n : K;\n}[keyof TMessageCatalog];\n\nexport class ZodSocketMessageSender<TMessageCatalog extends ZodSocketMessageCatalogSchema> {\n #schema: TMessageCatalog;\n #socket: ZodSocket<any, TMessageCatalog>;\n\n constructor(options: ZodSocketMessageSenderOptions<TMessageCatalog>) {\n this.#schema = options.schema;\n this.#socket = options.socket;\n }\n\n public send<K extends GetSocketMessagesWithoutCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): void {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n this.#socket.emit(type, { payload, version: \"v1\" });\n\n return;\n }\n\n public async sendWithAck<K extends GetSocketMessagesWithCallback<TMessageCatalog>>(\n type: K,\n payload: z.input<GetSocketMessageSchema<TMessageCatalog, K>>\n ): Promise<z.infer<GetSocketCallbackSchema<TMessageCatalog, K>>> {\n const schema = this.#schema[type][\"message\"];\n\n if (!schema) {\n throw new Error(`Unknown message type: ${type as string}`);\n }\n\n const parsedPayload = schema.safeParse(payload);\n\n if (!parsedPayload.success) {\n throw new Error(`Failed to parse message payload: ${JSON.stringify(parsedPayload.error)}`);\n }\n\n // @ts-expect-error\n const callbackResult = await this.#socket.emitWithAck(type, { payload, version: \"v1\" });\n\n return callbackResult;\n }\n}\n\nexport type ZodSocket<\n TListenEvents extends ZodSocketMessageCatalogSchema,\n TEmitEvents extends ZodSocketMessageCatalogSchema,\n> = Socket<\n ZodMessageCatalogToSocketIoEvents<TListenEvents>,\n ZodMessageCatalogToSocketIoEvents<TEmitEvents>\n>;\n\ninterface ZodSocketConnectionOptions<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n host: string;\n port?: number;\n secure?: boolean;\n namespace: string;\n clientMessages: TClientMessages;\n serverMessages: TServerMessages;\n extraHeaders?: {\n [header: string]: string;\n };\n handlers?: ZodSocketMessageHandlers<TServerMessages>;\n authToken?: string;\n onConnection?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n handler: ZodSocketMessageHandler<TServerMessages>,\n sender: ZodSocketMessageSender<TClientMessages>,\n logger: StructuredLogger\n ) => Promise<void>;\n onDisconnect?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n reason: Socket.DisconnectReason,\n description: any,\n logger: StructuredLogger\n ) => Promise<void>;\n onError?: (\n socket: ZodSocket<TServerMessages, TClientMessages>,\n err: Error,\n logger: StructuredLogger\n ) => Promise<void>;\n}\n\nexport class ZodSocketConnection<\n TClientMessages extends ZodSocketMessageCatalogSchema,\n TServerMessages extends ZodSocketMessageCatalogSchema,\n> {\n #sender: ZodSocketMessageSender<TClientMessages>;\n socket: ZodSocket<TServerMessages, TClientMessages>;\n\n #handler: ZodSocketMessageHandler<TServerMessages>;\n #logger: StructuredLogger;\n\n constructor(opts: ZodSocketConnectionOptions<TClientMessages, TServerMessages>) {\n const uri = `${opts.secure ? \"wss\" : \"ws\"}://${opts.host}:${\n opts.port ?? (opts.secure ? \"443\" : \"80\")\n }/${opts.namespace}`;\n\n const logger = new SimpleStructuredLogger(opts.namespace, LogLevel.info);\n logger.log(\"new zod socket\", { uri });\n\n this.socket = io(uri, {\n transports: [\"websocket\"],\n auth: {\n token: opts.authToken,\n },\n extraHeaders: opts.extraHeaders,\n reconnectionDelay: 500,\n reconnectionDelayMax: 1000,\n });\n\n this.#logger = logger.child({\n socketId: this.socket.id,\n });\n\n this.#handler = new ZodSocketMessageHandler({\n schema: opts.serverMessages,\n handlers: opts.handlers,\n });\n this.#handler.registerHandlers(this.socket, this.#logger);\n\n this.#sender = new ZodSocketMessageSender({\n schema: opts.clientMessages,\n socket: this.socket,\n });\n\n this.socket.on(\"connect_error\", async (error) => {\n this.#logger.error(`connect_error: ${error}`);\n\n if (opts.onError) {\n await opts.onError(this.socket, error, this.#logger);\n }\n });\n\n this.socket.on(\"connect\", async () => {\n this.#logger.info(\"connect\");\n\n if (opts.onConnection) {\n await opts.onConnection(this.socket, this.#handler, this.#sender, this.#logger);\n }\n });\n\n this.socket.on(\"disconnect\", async (reason, description) => {\n this.#logger.info(\"disconnect\", { reason, description });\n\n if (opts.onDisconnect) {\n await opts.onDisconnect(this.socket, reason, description, this.#logger);\n }\n });\n }\n\n close() {\n this.socket.close();\n }\n\n connect() {\n this.socket.connect();\n }\n\n get send() {\n return this.#sender.send.bind(this.#sender);\n }\n\n get sendWithAck() {\n return this.#sender.sendWithAck.bind(this.#sender);\n }\n}\n\nfunction createLogger(prefix: string) {\n return (...args: any[]) => console.log(prefix, ...args);\n}\n","type StructuredArgs = (Record<string, unknown> | undefined)[];\n\nexport interface StructuredLogger {\n log: (message: string, ...args: StructuredArgs) => any;\n error: (message: string, ...args: StructuredArgs) => any;\n warn: (message: string, ...args: StructuredArgs) => any;\n info: (message: string, ...args: StructuredArgs) => any;\n debug: (message: string, ...args: StructuredArgs) => any;\n child: (fields: Record<string, unknown>) => StructuredLogger;\n}\n\nexport enum LogLevel {\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n}\n\nexport class SimpleStructuredLogger implements StructuredLogger {\n constructor(\n private name: string,\n private level: LogLevel = [\"1\", \"true\"].includes(process.env.DEBUG ?? \"\")\n ? LogLevel.debug\n : LogLevel.info,\n private fields?: Record<string, unknown>\n ) {}\n\n child(fields: Record<string, unknown>, level?: LogLevel) {\n return new SimpleStructuredLogger(this.name, level, { ...this.fields, ...fields });\n }\n\n log(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.log) return;\n\n this.#structuredLog(console.log, message, \"log\", ...args);\n }\n\n error(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.error) return;\n\n this.#structuredLog(console.error, message, \"error\", ...args);\n }\n\n warn(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.warn) return;\n\n this.#structuredLog(console.warn, message, \"warn\", ...args);\n }\n\n info(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.info) return;\n\n this.#structuredLog(console.info, message, \"info\", ...args);\n }\n\n debug(message: string, ...args: StructuredArgs) {\n if (this.level < LogLevel.debug) return;\n\n this.#structuredLog(console.debug, message, \"debug\", ...args);\n }\n\n #structuredLog(\n loggerFunction: (message: string, ...args: any[]) => void,\n message: string,\n level: string,\n ...args: StructuredArgs\n ) {\n const structuredLog = {\n ...(args.length === 1 ? args[0] : args),\n ...this.fields,\n timestamp: new Date(),\n name: this.name,\n message,\n level,\n };\n\n loggerFunction(JSON.stringify(structuredLog));\n }\n}\n"]}
@@ -0,0 +1,262 @@
1
+ import { z } from 'zod';
2
+ import { R as RetryOptions } from '../schemas-r4ZP9S-F.mjs';
3
+ import { Readable } from 'node:stream';
4
+
5
+ interface CursorPageParams {
6
+ limit?: number;
7
+ after?: string;
8
+ before?: string;
9
+ }
10
+ interface OffsetLimitPageParams {
11
+ limit?: number;
12
+ page?: number;
13
+ }
14
+ interface PageResponse<Item> {
15
+ data: Array<Item>;
16
+ }
17
+ interface CursorPageResponse<Item> extends PageResponse<Item> {
18
+ pagination: {
19
+ next?: string;
20
+ previous?: string;
21
+ };
22
+ }
23
+ interface OffsetLimitPageResponse<Item> extends PageResponse<Item> {
24
+ pagination: {
25
+ currentPage: number;
26
+ totalPages: number;
27
+ count: number;
28
+ };
29
+ }
30
+ interface Page<Item> {
31
+ getPaginatedItems(): Item[];
32
+ hasNextPage(): boolean;
33
+ hasPreviousPage(): boolean;
34
+ }
35
+ declare class CursorPage<Item> implements CursorPageResponse<Item>, Page<Item>, AsyncIterable<Item> {
36
+ private pageFetcher;
37
+ data: Array<Item>;
38
+ pagination: {
39
+ next?: string;
40
+ previous?: string;
41
+ };
42
+ constructor(data: Array<Item>, pagination: {
43
+ next?: string;
44
+ previous?: string;
45
+ }, pageFetcher: (params: Omit<CursorPageParams, "limit">) => Promise<CursorPage<Item>>);
46
+ getPaginatedItems(): Item[];
47
+ hasNextPage(): boolean;
48
+ hasPreviousPage(): boolean;
49
+ getNextPage(): Promise<CursorPage<Item>>;
50
+ getPreviousPage(): Promise<CursorPage<Item>>;
51
+ iterPages(): AsyncGenerator<CursorPage<Item>, void, unknown>;
52
+ [Symbol.asyncIterator](): AsyncGenerator<Awaited<Item>, void, unknown>;
53
+ }
54
+ declare class OffsetLimitPage<Item> implements OffsetLimitPageResponse<Item>, Page<Item>, AsyncIterable<Item> {
55
+ private pageFetcher;
56
+ data: Array<Item>;
57
+ pagination: {
58
+ currentPage: number;
59
+ totalPages: number;
60
+ count: number;
61
+ };
62
+ constructor(data: Array<Item>, pagination: {
63
+ currentPage: number;
64
+ totalPages: number;
65
+ count: number;
66
+ }, pageFetcher: (params: Omit<OffsetLimitPageParams, "limit">) => Promise<OffsetLimitPage<Item>>);
67
+ getPaginatedItems(): Item[];
68
+ hasNextPage(): boolean;
69
+ hasPreviousPage(): boolean;
70
+ getNextPage(): Promise<OffsetLimitPage<Item>>;
71
+ getPreviousPage(): Promise<OffsetLimitPage<Item>>;
72
+ iterPages(): AsyncGenerator<OffsetLimitPage<Item>, void, unknown>;
73
+ [Symbol.asyncIterator](): AsyncGenerator<Awaited<Item>, void, unknown>;
74
+ }
75
+
76
+ declare const defaultRetryOptions: {
77
+ maxAttempts: number;
78
+ factor: number;
79
+ minTimeoutInMs: number;
80
+ maxTimeoutInMs: number;
81
+ randomize: false;
82
+ };
83
+ type ZodFetchOptions = {
84
+ retry?: RetryOptions;
85
+ };
86
+ interface FetchCursorPageParams extends CursorPageParams {
87
+ query?: URLSearchParams;
88
+ }
89
+ interface FetchOffsetLimitPageParams extends OffsetLimitPageParams {
90
+ query?: URLSearchParams;
91
+ }
92
+ declare function zodfetch<TResponseBodySchema extends z.ZodTypeAny>(schema: TResponseBodySchema, url: string, requestInit?: RequestInit, options?: ZodFetchOptions): ApiPromise<z.output<TResponseBodySchema>>;
93
+ declare function zodfetchCursorPage<TItemSchema extends z.ZodTypeAny>(schema: TItemSchema, url: string, params: FetchCursorPageParams, requestInit?: RequestInit, options?: ZodFetchOptions): CursorPagePromise<TItemSchema>;
94
+ declare function zodfetchOffsetLimitPage<TItemSchema extends z.ZodTypeAny>(schema: TItemSchema, url: string, params: FetchOffsetLimitPageParams, requestInit?: RequestInit, options?: ZodFetchOptions): OffsetLimitPagePromise<TItemSchema>;
95
+ declare function zodupload<TResponseBodySchema extends z.ZodTypeAny, TBody = Record<string, unknown>>(schema: TResponseBodySchema, url: string, body: TBody, requestInit?: RequestInit, options?: ZodFetchOptions): ApiPromise<z.output<TResponseBodySchema>>;
96
+ type ZodFetchResult<T> = {
97
+ data: T;
98
+ response: Response;
99
+ };
100
+ type ToFileInput = Uploadable | Exclude<BlobLikePart, string> | AsyncIterable<BlobLikePart>;
101
+ /**
102
+ * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
103
+ * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
104
+ * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
105
+ * @param {Object=} options additional properties
106
+ * @param {string=} options.type the MIME type of the content
107
+ * @param {number=} options.lastModified the last modified timestamp
108
+ * @returns a {@link File} with the given properties
109
+ */
110
+ declare function toFile(value: ToFileInput | PromiseLike<ToFileInput>, name?: string | null | undefined, options?: FilePropertyBag | undefined): Promise<FileLike>;
111
+ /**
112
+ * Intended to match web.Blob, node.Blob, node-fetch.Blob, etc.
113
+ */
114
+ interface BlobLike {
115
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */
116
+ readonly size: number;
117
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */
118
+ readonly type: string;
119
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */
120
+ text(): Promise<string>;
121
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
122
+ slice(start?: number, end?: number): BlobLike;
123
+ }
124
+ /**
125
+ * Intended to match web.File, node.File, node-fetch.File, etc.
126
+ */
127
+ interface FileLike extends BlobLike {
128
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */
129
+ readonly lastModified: number;
130
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */
131
+ readonly name: string;
132
+ }
133
+ /**
134
+ * Intended to match web.Response, node.Response, node-fetch.Response, etc.
135
+ */
136
+ interface ResponseLike {
137
+ url: string;
138
+ blob(): Promise<BlobLike>;
139
+ }
140
+ type Uploadable = FileLike | ResponseLike | Readable;
141
+ declare const isResponseLike: (value: any) => value is ResponseLike;
142
+ declare const isFileLike: (value: any) => value is FileLike;
143
+ /**
144
+ * The BlobLike type omits arrayBuffer() because @types/node-fetch@^2.6.4 lacks it; but this check
145
+ * adds the arrayBuffer() method type because it is available and used at runtime
146
+ */
147
+ declare const isBlobLike: (value: any) => value is BlobLike & {
148
+ arrayBuffer(): Promise<ArrayBuffer>;
149
+ };
150
+ declare const isFsReadStream: (value: any) => value is Readable;
151
+ declare const isUploadable: (value: any) => value is Uploadable;
152
+ type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | Uint8Array | DataView;
153
+ declare const isRecordLike: (value: any) => value is Record<string, string>;
154
+ /**
155
+ * A subclass of `Promise` providing additional helper methods
156
+ * for interacting with the SDK.
157
+ */
158
+ declare class ApiPromise<T> extends Promise<T> {
159
+ private responsePromise;
160
+ constructor(responsePromise: Promise<ZodFetchResult<T>>);
161
+ /**
162
+ * Gets the raw `Response` instance instead of parsing the response
163
+ * data.
164
+ *
165
+ * If you want to parse the response body but still get the `Response`
166
+ * instance, you can use {@link withResponse()}.
167
+ */
168
+ asResponse(): Promise<Response>;
169
+ /**
170
+ * Gets the parsed response data and the raw `Response` instance.
171
+ *
172
+ * If you just want to get the raw `Response` instance without parsing it,
173
+ * you can use {@link asResponse()}.
174
+ */
175
+ withResponse(): Promise<{
176
+ data: T;
177
+ response: Response;
178
+ }>;
179
+ private parse;
180
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
181
+ catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
182
+ finally(onfinally?: (() => void) | undefined | null): Promise<T>;
183
+ }
184
+ declare class CursorPagePromise<TItemSchema extends z.ZodTypeAny> extends ApiPromise<CursorPage<z.output<TItemSchema>>> implements AsyncIterable<z.output<TItemSchema>> {
185
+ #private;
186
+ private schema;
187
+ private url;
188
+ private params;
189
+ private requestInit?;
190
+ private options?;
191
+ constructor(result: Promise<ZodFetchResult<CursorPageResponse<z.output<TItemSchema>>>>, schema: TItemSchema, url: string, params: FetchCursorPageParams, requestInit?: RequestInit | undefined, options?: ZodFetchOptions | undefined);
192
+ /**
193
+ * Allow auto-paginating iteration on an unawaited list call, eg:
194
+ *
195
+ * for await (const item of client.items.list()) {
196
+ * console.log(item)
197
+ * }
198
+ */
199
+ [Symbol.asyncIterator](): AsyncGenerator<Awaited<z.output<TItemSchema>>, void, unknown>;
200
+ }
201
+ declare class OffsetLimitPagePromise<TItemSchema extends z.ZodTypeAny> extends ApiPromise<OffsetLimitPage<z.output<TItemSchema>>> implements AsyncIterable<z.output<TItemSchema>> {
202
+ #private;
203
+ private schema;
204
+ private url;
205
+ private params;
206
+ private requestInit?;
207
+ private options?;
208
+ constructor(result: Promise<ZodFetchResult<OffsetLimitPageResponse<z.output<TItemSchema>>>>, schema: TItemSchema, url: string, params: FetchOffsetLimitPageParams, requestInit?: RequestInit | undefined, options?: ZodFetchOptions | undefined);
209
+ /**
210
+ * Allow auto-paginating iteration on an unawaited list call, eg:
211
+ *
212
+ * for await (const item of client.items.list()) {
213
+ * console.log(item)
214
+ * }
215
+ */
216
+ [Symbol.asyncIterator](): AsyncGenerator<Awaited<z.output<TItemSchema>>, void, unknown>;
217
+ }
218
+
219
+ type APIHeaders = Record<string, string | null | undefined>;
220
+ declare class ApiError extends Error {
221
+ readonly status: number | undefined;
222
+ readonly headers: APIHeaders | undefined;
223
+ readonly error: Object | undefined;
224
+ readonly code: string | null | undefined;
225
+ readonly param: string | null | undefined;
226
+ readonly type: string | undefined;
227
+ constructor(status: number | undefined, error: Object | undefined, message: string | undefined, headers: APIHeaders | undefined);
228
+ private static makeMessage;
229
+ static generate(status: number | undefined, errorResponse: Object | undefined, message: string | undefined, headers: APIHeaders | undefined): ApiError;
230
+ }
231
+ declare class ApiConnectionError extends ApiError {
232
+ readonly status: undefined;
233
+ constructor({ message, cause }: {
234
+ message?: string;
235
+ cause?: Error | undefined;
236
+ });
237
+ }
238
+ declare class BadRequestError extends ApiError {
239
+ readonly status: 400;
240
+ }
241
+ declare class AuthenticationError extends ApiError {
242
+ readonly status: 401;
243
+ }
244
+ declare class PermissionDeniedError extends ApiError {
245
+ readonly status: 403;
246
+ }
247
+ declare class NotFoundError extends ApiError {
248
+ readonly status: 404;
249
+ }
250
+ declare class ConflictError extends ApiError {
251
+ readonly status: 409;
252
+ }
253
+ declare class UnprocessableEntityError extends ApiError {
254
+ readonly status: 422;
255
+ }
256
+ declare class RateLimitError extends ApiError {
257
+ readonly status: 429;
258
+ }
259
+ declare class InternalServerError extends ApiError {
260
+ }
261
+
262
+ export { type APIHeaders, ApiConnectionError, ApiError, ApiPromise, AuthenticationError, BadRequestError, type BlobLike, type BlobLikePart, ConflictError, CursorPage, type CursorPageParams, CursorPagePromise, type CursorPageResponse, type FileLike, InternalServerError, NotFoundError, OffsetLimitPage, type OffsetLimitPageParams, OffsetLimitPagePromise, type OffsetLimitPageResponse, type Page, type PageResponse, PermissionDeniedError, RateLimitError, type ResponseLike, type ToFileInput, UnprocessableEntityError, type Uploadable, type ZodFetchOptions, defaultRetryOptions, isBlobLike, isFileLike, isFsReadStream, isRecordLike, isResponseLike, isUploadable, toFile, zodfetch, zodfetchCursorPage, zodfetchOffsetLimitPage, zodupload };