@serve.zone/platformclient 1.2.0 → 2.0.1

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/platformclient',
6
- version: '1.2.0',
6
+ version: '2.0.1',
7
7
  description: 'a module that makes it really easy to use the serve.zone platform inside your app'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSw0QkFBNEI7SUFDbEMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG1GQUFtRjtDQUNqRyxDQUFBIn0=
@@ -35,6 +35,7 @@ export declare class SzPlatformClient {
35
35
  private getConfiguredAuthorizationString;
36
36
  private getAuthorizationStringFromBindings;
37
37
  private setAuthorizationTag;
38
+ stop(): Promise<void>;
38
39
  private discoverPlatformBindings;
39
40
  private parsePlatformBindingsEnv;
40
41
  private mergePlatformBindings;
@@ -128,6 +128,12 @@ export class SzPlatformClient {
128
128
  }
129
129
  }
130
130
  }
131
+ async stop() {
132
+ await this.emailConnector.stop();
133
+ if (this.typedsocket) {
134
+ await this.typedsocket.stop();
135
+ }
136
+ }
131
137
  async discoverPlatformBindings() {
132
138
  const bindings = [];
133
139
  const envBindings = await this.getConfiguredEnvVar('SERVEZONE_PLATFORM_BINDINGS');
@@ -175,4 +181,4 @@ export class SzPlatformClient {
175
181
  return processEnv?.[envNameArg];
176
182
  }
177
183
  }
178
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wbGF0Zm9ybWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMucGxhdGZvcm1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzNGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBWXhDLE1BQU0sT0FBTyxnQkFBZ0I7SUFjM0IsWUFBWSxzQkFBMEQ7UUFiL0QsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUdsQixxQkFBZ0IsR0FBNEQsRUFBRSxDQUFDO1FBQy9FLGdCQUFXLEdBQXFDLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUV0RixpQkFBWSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV4QyxtQkFBYyxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsaUJBQVksR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4Qyw4QkFBeUIsR0FBRyxJQUFJLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xFLG9CQUFlLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUduRCxJQUFJLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQUMsc0JBQTBEO1FBQzFFLElBQUksQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFB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
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wbGF0Zm9ybWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMucGxhdGZvcm1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzNGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBWXhDLE1BQU0sT0FBTyxnQkFBZ0I7SUFjM0IsWUFBWSxzQkFBMEQ7UUFiL0QsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUdsQixxQkFBZ0IsR0FBNEQsRUFBRSxDQUFDO1FBQy9FLGdCQUFXLEdBQXFDLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUV0RixpQkFBWSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV4QyxtQkFBYyxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsaUJBQVksR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4Qyw4QkFBeUIsR0FBRyxJQUFJLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xFLG9CQUFlLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUduRCxJQUFJLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQUMsc0JBQTBEO1FBQzFFLElBQUksQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7UUFDM0UsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FDaEQsSUFBSSxDQUFDLGdCQUFnQixFQUNyQixNQUFNLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUN0QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQztRQUN2RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUI7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDbEYsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDekIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUNuRSxJQUFJLENBQUMsV0FBa0IsRUFDdkIsTUFBTSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FDbEMsQ0FBQztRQUNGLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVNLGtCQUFrQixDQUN2QixhQUF3RTtRQUV4RSxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUMvQyxPQUFPLENBQ0wsVUFBVSxDQUFDLFlBQVksS0FBSyxVQUFVO2dCQUN0QyxVQUFVLENBQUMsTUFBTSxLQUFLLFFBQVE7Z0JBQzlCLENBQUMsQ0FBQyxhQUFhLElBQUksVUFBVSxDQUFDLFVBQVUsS0FBSyxhQUFhLENBQUMsQ0FDNUQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLFlBQVksQ0FBQyxVQUE4QztRQUNqRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxVQUFVLENBQUM7WUFDdEMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsbUJBQW1CO1lBQ3RCLFVBQVUsQ0FBQyxtQkFBbUI7Z0JBQzlCLFVBQVUsQ0FBQyxhQUFhO2dCQUN4QixVQUFVLENBQUMsS0FBSztnQkFDaEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQzNCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxVQUFVLENBQUMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDO1FBQzVGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQ2hELElBQUksQ0FBQyxnQkFBZ0IsRUFDckIsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUN6RCxPQUFPLENBQ21ELENBQzdELENBQUM7SUFDSixDQUFDO0lBRU8sS0FBSyxDQUFDLG9CQUFvQjtRQUNoQyxNQUFNLGlCQUFpQixHQUNyQixJQUFJLENBQUMsaUJBQWlCO1lBQ3RCLENBQUMsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsd0JBQXdCLENBQUMsQ0FBQztZQUMxRCxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsaUJBQWlCO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsQ0FBQyxDQUFDO1FBQzNHLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLGdDQUFnQztRQUN0QyxLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzVDLElBQUksT0FBTyxDQUFDLFlBQVksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDdkUsU0FBUztZQUNYLENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUM3RCxTQUFTO1lBQ1gsQ0FBQztZQUNELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUU7Z0JBQ3ZELE9BQU8sV0FBVyxDQUFDLFFBQVEsS0FBSyxjQUFjLElBQUksV0FBVyxDQUFDLFFBQVEsS0FBSyxNQUFNLENBQUM7WUFDcEYsQ0FBQyxDQUFDLENBQUM7WUFDSCxNQUFNLFdBQVcsR0FBRyxRQUFRLEVBQUUsV0FBVyxJQUFJLFFBQVEsRUFBRSxXQUFXLENBQUM7WUFDbkUsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsT0FBTyxXQUFXLENBQUM7WUFDckIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sOEJBQThCLENBQ3BDLGFBQXVFO1FBRXZFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNoRixDQUFDO0lBRU8sS0FBSyxDQUFDLGdDQUFnQztRQUM1QyxPQUFPLENBQ0wsQ0FBQyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ3BFLENBQUMsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUM3RCxDQUFDO0lBQ0osQ0FBQztJQUVPLGtDQUFrQztRQUN4QyxNQUFNLFlBQVksR0FBRztZQUNuQixrQ0FBa0M7WUFDbEMsMEJBQTBCO1lBQzFCLHFCQUFxQjtZQUNyQixlQUFlO1lBQ2YsT0FBTztTQUNSLENBQUM7UUFDRixLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzVDLEtBQUssTUFBTSxVQUFVLElBQUksT0FBTyxDQUFDLFdBQVcsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDbkQsS0FBSyxNQUFNLE9BQU8sSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDbkMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUN4QyxJQUFJLEtBQUssRUFBRSxDQUFDO3dCQUNWLE9BQU8sS0FBSyxDQUFDO29CQUNmLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxtQkFBbUI7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxlQUFzQixFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2xGLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQ0FBZ0MsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JFLE9BQU8sQ0FBQyxJQUFJLENBQUMsMkNBQTJDLEVBQUcsS0FBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RGLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyx3QkFBd0I7UUFDcEMsTUFBTSxRQUFRLEdBQTRELEVBQUUsQ0FBQztRQUM3RSxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFFaEYsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLDZCQUE2QixFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDOUYsQ0FBQztRQUNELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLDRCQUE0QixFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDNUYsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFTyx3QkFBd0IsQ0FBQyxVQUFrQixFQUFFLFdBQW1CO1FBQ3RFLElBQUksV0FBb0IsQ0FBQztRQUN6QixJQUFJLENBQUM7WUFDSCxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxVQUFVLDBCQUEwQixDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQy9CLE9BQU8sV0FBc0UsQ0FBQztRQUNoRixDQUFDO1FBQ0QsSUFBSSxXQUFXLElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkQsT0FBTyxDQUFDLFdBQW9FLENBQUMsQ0FBQztRQUNoRixDQUFDO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLFVBQVUsa0RBQWtELENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRU8scUJBQXFCLENBQzNCLG1CQUE0RSxFQUM1RSxjQUF1RTtRQUV2RSxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBaUUsQ0FBQztRQUM1RixLQUFLLE1BQU0sT0FBTyxJQUFJLENBQUMsR0FBRyxtQkFBbUIsRUFBRSxHQUFHLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDbEUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVNLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxVQUFrQjtRQUNqRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkQsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixPQUFPLFlBQVksQ0FBQztRQUN0QixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxVQUFrQjtRQUN6QyxNQUFNLFVBQVUsR0FBSSxVQUVsQixDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUM7UUFDaEIsT0FBTyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsQyxDQUFDO0NBQ0YifQ==
@@ -10,14 +10,25 @@ export interface IServiceMailSmtpCredentials {
10
10
  password: string;
11
11
  addressToken?: string;
12
12
  }
13
+ export interface IServiceMailTypedCredentials {
14
+ from: string;
15
+ typedUrl: string;
16
+ credentialId: string;
17
+ credentialSecret: string;
18
+ addressToken?: string;
19
+ }
13
20
  export interface IServiceMailStatus {
14
21
  ready: boolean;
15
22
  from?: string;
16
23
  host?: string;
17
24
  port?: number;
18
25
  tlsMode?: TServiceMailTlsMode;
26
+ typedUrl?: string;
27
+ transport?: 'typedsocket' | 'smtp' | 'none';
19
28
  usernameConfigured: boolean;
20
29
  passwordConfigured: boolean;
30
+ typedCredentialConfigured?: boolean;
31
+ smtpReady?: boolean;
21
32
  missing: string[];
22
33
  }
23
34
  export interface IServiceMailAttachment {
@@ -56,6 +67,16 @@ export type IServiceMailInboundHandleResult = plugins.servezoneInterfaces.reques
56
67
  export type TServiceMailInboundHandler = (messageArg: IServiceMailInboundMessage) => Promise<IServiceMailInboundHandlerResult | void> | IServiceMailInboundHandlerResult | void;
57
68
  export declare class SzEmailConnector {
58
69
  platformClientRef: SzPlatformClient;
70
+ private mailTypedSocket?;
71
+ private mailTypedSocketUrl?;
72
+ private mailTypedSocketPromise?;
73
+ private mailTypedSocketAbortController?;
74
+ private mailTypedSocketStatusSubscription?;
75
+ private inboundHandler?;
76
+ private inboundTypedHandlerRegistered;
77
+ private inboundEndpointRegistrations;
78
+ private inboundEndpointReplayPromise?;
79
+ private readonly inboundEndpointReplayRetryDelaysMs;
59
80
  constructor(platformClientRefArg: SzPlatformClient);
60
81
  /**
61
82
  * Legacy platform-service email path. New service-mail code should use sendMail().
@@ -70,6 +91,8 @@ export declare class SzEmailConnector {
70
91
  html: string;
71
92
  }): Promise<IServiceMailSendResult>;
72
93
  sendMail(optionsArg: IServiceMailSendOptions): Promise<IServiceMailSendResult>;
94
+ registerInboundHandler(handlerArg: TServiceMailInboundHandler, addressArg?: string): Promise<plugins.servezoneInterfaces.requests.mail.IReq_RegisterServiceMailEndpoint['response']>;
95
+ stop(): Promise<void>;
73
96
  normalizeInboundMessage(payloadArg: unknown): IServiceMailInboundMessage;
74
97
  handleInboundPayload(payloadArg: unknown, handlerArg: TServiceMailInboundHandler): Promise<IServiceMailInboundHandleResult>;
75
98
  createInboundHandler(handlerArg: TServiceMailInboundHandler): (payloadArg: unknown) => Promise<{
@@ -77,6 +100,7 @@ export declare class SzEmailConnector {
77
100
  workAppMessageId?: string;
78
101
  message?: string;
79
102
  }>;
103
+ private ensureInboundTypedHandler;
80
104
  sendNotification(optionsArg: {
81
105
  toArg: string;
82
106
  subject: string;
@@ -91,6 +115,17 @@ export declare class SzEmailConnector {
91
115
  private readMailEnvVar;
92
116
  private getCredentialEnvVarFromBindings;
93
117
  private hasAnyMailEnvValue;
118
+ private getServiceMailTypedCredentials;
119
+ private getMailTypedSocket;
120
+ private stopMailTypedSocket;
121
+ private watchMailTypedSocketStatus;
122
+ private handleMailTypedSocketStatus;
123
+ private replayInboundEndpointRegistrationsWithRetry;
124
+ private replayInboundEndpointRegistrationsWithRetryInner;
125
+ private replayInboundEndpointRegistrationsOnce;
126
+ private waitForInboundEndpointReplayRetry;
127
+ private registerServiceMailEndpoint;
128
+ private normalizeTypedSocketUrl;
94
129
  private normalizeTlsMode;
95
130
  private getMailEnvToken;
96
131
  private listToArray;
@@ -2,6 +2,9 @@ import * as plugins from '../plugins.js';
2
2
  import { logger } from '../logger.js';
3
3
  export class SzEmailConnector {
4
4
  constructor(platformClientRefArg) {
5
+ this.inboundTypedHandlerRegistered = false;
6
+ this.inboundEndpointRegistrations = new Set();
7
+ this.inboundEndpointReplayRetryDelaysMs = [500, 1000, 2000, 5000];
5
8
  this.platformClientRef = platformClientRefArg;
6
9
  }
7
10
  /**
@@ -34,27 +37,39 @@ export class SzEmailConnector {
34
37
  const missingPrefix = useDefaultEnv || !token ? undefined : token;
35
38
  const port = env.smtpPort ? Number(env.smtpPort) : undefined;
36
39
  const tlsMode = this.normalizeTlsMode(env.smtpTlsMode || 'starttls');
37
- const missing = [];
38
- if (!env.from)
39
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_FROM` : 'MAIL_FROM');
40
+ const typedMissing = [];
41
+ const smtpMissing = [];
42
+ if (!env.typedUrl)
43
+ typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_TYPED_URL` : 'MAIL_TYPED_URL');
44
+ if (!env.apiCredentialId)
45
+ typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_API_CREDENTIAL_ID` : 'MAIL_API_CREDENTIAL_ID');
46
+ if (!env.apiCredentialSecret)
47
+ typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_API_CREDENTIAL_SECRET` : 'MAIL_API_CREDENTIAL_SECRET');
40
48
  if (!env.smtpHost)
41
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_HOST` : 'SMTP_HOST');
49
+ smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_HOST` : 'SMTP_HOST');
42
50
  if (!env.smtpPort || !Number.isInteger(port) || port < 1 || port > 65535) {
43
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PORT` : 'SMTP_PORT');
51
+ smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PORT` : 'SMTP_PORT');
44
52
  }
45
53
  if (!env.smtpUsername)
46
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_USERNAME` : 'SMTP_USERNAME');
54
+ smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_USERNAME` : 'SMTP_USERNAME');
47
55
  if (!env.smtpPassword)
48
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PASSWORD` : 'SMTP_PASSWORD');
56
+ smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PASSWORD` : 'SMTP_PASSWORD');
57
+ const fromMissing = env.from ? [] : [missingPrefix ? `MAIL_${missingPrefix}_FROM` : 'MAIL_FROM'];
58
+ const typedReady = fromMissing.length === 0 && typedMissing.length === 0;
59
+ const smtpReady = fromMissing.length === 0 && smtpMissing.length === 0;
49
60
  return {
50
- ready: missing.length === 0,
61
+ ready: typedReady,
51
62
  from: env.from,
52
63
  host: env.smtpHost,
53
64
  port,
54
65
  tlsMode,
66
+ typedUrl: env.typedUrl,
67
+ transport: typedReady ? 'typedsocket' : smtpReady ? 'smtp' : 'none',
55
68
  usernameConfigured: Boolean(env.smtpUsername),
56
69
  passwordConfigured: Boolean(env.smtpPassword),
57
- missing,
70
+ typedCredentialConfigured: Boolean(env.apiCredentialId && env.apiCredentialSecret),
71
+ smtpReady,
72
+ missing: typedReady ? [] : [...fromMissing, ...typedMissing],
58
73
  };
59
74
  }
60
75
  async getServiceMailCredentials(addressArg) {
@@ -103,37 +118,56 @@ export class SzEmailConnector {
103
118
  logger.log('info', `service mail debug send: ${optionsArg.subject} to ${this.listToArray(optionsArg.to).join(', ')}`);
104
119
  return { messageId: 'debug' };
105
120
  }
106
- const credentials = await this.getServiceMailCredentials(optionsArg.from);
107
- const smartsmtp = await plugins.getSmartsmtp();
108
- const smtp = await smartsmtp.Smartsmtp.createSmartsmtpWithRelay({
109
- smtpServer: credentials.host,
110
- smtpPort: credentials.port,
111
- smtpTlsMode: credentials.tlsMode,
112
- smtpUser: credentials.username,
113
- smtpPassword: credentials.password,
121
+ const credentials = await this.getServiceMailTypedCredentials(optionsArg.from);
122
+ const typedSocket = await this.getMailTypedSocket(credentials.typedUrl);
123
+ const request = typedSocket.createTypedRequest('enqueueMail');
124
+ const result = await request.fire({
125
+ auth: {
126
+ credentialId: credentials.credentialId,
127
+ credentialSecret: credentials.credentialSecret,
128
+ },
129
+ outboundIdentityId: credentials.credentialId,
130
+ message: {
131
+ from: credentials.from,
132
+ to: this.listToArray(optionsArg.to),
133
+ cc: optionsArg.cc ? this.listToArray(optionsArg.cc) : undefined,
134
+ bcc: optionsArg.bcc ? this.listToArray(optionsArg.bcc) : undefined,
135
+ subject: optionsArg.subject,
136
+ text: optionsArg.text,
137
+ html: optionsArg.html,
138
+ headers: optionsArg.headers,
139
+ attachments: optionsArg.attachments?.map((attachmentArg) => ({
140
+ filename: attachmentArg.filename,
141
+ contentType: attachmentArg.contentType,
142
+ binaryAttachmentString: this.normalizeAttachmentContent(attachmentArg.content),
143
+ })),
144
+ },
114
145
  });
115
- const result = (await smtp.nodemailerTransport.sendMail({
116
- from: credentials.from,
117
- to: this.listToArray(optionsArg.to),
118
- cc: optionsArg.cc ? this.listToArray(optionsArg.cc) : undefined,
119
- bcc: optionsArg.bcc ? this.listToArray(optionsArg.bcc) : undefined,
120
- subject: optionsArg.subject,
121
- text: optionsArg.text,
122
- html: optionsArg.html,
123
- headers: optionsArg.headers,
124
- attachments: optionsArg.attachments?.map((attachmentArg) => ({
125
- filename: attachmentArg.filename,
126
- contentType: attachmentArg.contentType,
127
- content: this.normalizeAttachmentContent(attachmentArg.content),
128
- })),
129
- }));
146
+ if (!result.accepted) {
147
+ throw new Error(result.message || 'service mail was not accepted by dcrouter');
148
+ }
130
149
  return {
131
- messageId: result.messageId,
132
- accepted: Array.isArray(result.accepted) ? result.accepted.map(String) : undefined,
133
- rejected: Array.isArray(result.rejected) ? result.rejected.map(String) : undefined,
134
- response: result.response,
150
+ messageId: result.spoolItemId,
151
+ accepted: this.listToArray(optionsArg.to),
152
+ rejected: [],
153
+ response: result.message,
135
154
  };
136
155
  }
156
+ async registerInboundHandler(handlerArg, addressArg) {
157
+ this.inboundHandler = handlerArg;
158
+ this.ensureInboundTypedHandler();
159
+ const credentials = await this.getServiceMailTypedCredentials(addressArg);
160
+ const typedSocket = await this.getMailTypedSocket(credentials.typedUrl);
161
+ const result = await this.registerServiceMailEndpoint(typedSocket, credentials);
162
+ const registeredAddresses = result.addresses?.length ? result.addresses : [credentials.from];
163
+ for (const address of registeredAddresses) {
164
+ this.inboundEndpointRegistrations.add(address.trim().toLowerCase());
165
+ }
166
+ return result;
167
+ }
168
+ async stop() {
169
+ await this.stopMailTypedSocket();
170
+ }
137
171
  normalizeInboundMessage(payloadArg) {
138
172
  const payload = this.asRecord(payloadArg);
139
173
  const deliveryCandidate = this.asRecord(payload.delivery || payload.message || payload);
@@ -172,6 +206,17 @@ export class SzEmailConnector {
172
206
  createInboundHandler(handlerArg) {
173
207
  return async (payloadArg) => await this.handleInboundPayload(payloadArg, handlerArg);
174
208
  }
209
+ ensureInboundTypedHandler() {
210
+ if (this.inboundTypedHandlerRegistered)
211
+ return;
212
+ this.inboundTypedHandlerRegistered = true;
213
+ this.platformClientRef.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('deliverInboundMail', async (dataArg) => {
214
+ if (!this.inboundHandler) {
215
+ return { accepted: false, message: 'No service mail inbound handler registered' };
216
+ }
217
+ return await this.handleInboundPayload(dataArg.delivery, this.inboundHandler);
218
+ }));
219
+ }
175
220
  async sendNotification(optionsArg) { }
176
221
  async sendActionLink(optionsArg) { }
177
222
  async readMailEnv(tokenArg) {
@@ -183,6 +228,9 @@ export class SzEmailConnector {
183
228
  smtpTlsMode: await this.readMailEnvVar(`${prefix}SMTP_TLS_MODE`),
184
229
  smtpUsername: await this.readMailEnvVar(`${prefix}SMTP_USERNAME`),
185
230
  smtpPassword: await this.readMailEnvVar(`${prefix}SMTP_PASSWORD`),
231
+ typedUrl: await this.readMailEnvVar(tokenArg ? `${prefix}TYPED_URL` : 'MAIL_TYPED_URL'),
232
+ apiCredentialId: await this.readMailEnvVar(tokenArg ? `${prefix}API_CREDENTIAL_ID` : 'MAIL_API_CREDENTIAL_ID'),
233
+ apiCredentialSecret: await this.readMailEnvVar(tokenArg ? `${prefix}API_CREDENTIAL_SECRET` : 'MAIL_API_CREDENTIAL_SECRET'),
186
234
  };
187
235
  }
188
236
  async readMailEnvVar(envNameArg) {
@@ -205,6 +253,202 @@ export class SzEmailConnector {
205
253
  hasAnyMailEnvValue(envArg) {
206
254
  return Boolean(envArg && Object.values(envArg).some(Boolean));
207
255
  }
256
+ async getServiceMailTypedCredentials(addressArg) {
257
+ const requestedAddress = addressArg?.trim().toLowerCase();
258
+ const requestedToken = requestedAddress ? this.getMailEnvToken(requestedAddress) : undefined;
259
+ const scopedEnv = requestedToken ? await this.readMailEnv(requestedToken) : undefined;
260
+ const hasScopedConfig = scopedEnv && Object.values(scopedEnv).some(Boolean);
261
+ const env = hasScopedConfig ? scopedEnv : await this.readMailEnv();
262
+ const from = env.from?.trim().toLowerCase();
263
+ if (!from)
264
+ throw new Error('MAIL_FROM is required for typed service mail');
265
+ if (requestedAddress && from !== requestedAddress) {
266
+ throw new Error(`No typed service mail credentials are configured for ${requestedAddress}`);
267
+ }
268
+ if (!env.typedUrl)
269
+ throw new Error('MAIL_TYPED_URL is required for typed service mail');
270
+ if (!env.apiCredentialId)
271
+ throw new Error('MAIL_API_CREDENTIAL_ID is required for typed service mail');
272
+ if (!env.apiCredentialSecret)
273
+ throw new Error('MAIL_API_CREDENTIAL_SECRET is required for typed service mail');
274
+ return {
275
+ from,
276
+ typedUrl: this.normalizeTypedSocketUrl(env.typedUrl),
277
+ credentialId: env.apiCredentialId,
278
+ credentialSecret: env.apiCredentialSecret,
279
+ addressToken: hasScopedConfig ? requestedToken : undefined,
280
+ };
281
+ }
282
+ async getMailTypedSocket(urlArg) {
283
+ const normalizedUrl = this.normalizeTypedSocketUrl(urlArg);
284
+ if (this.mailTypedSocket && this.mailTypedSocketUrl === normalizedUrl) {
285
+ return this.mailTypedSocket;
286
+ }
287
+ if (this.mailTypedSocketPromise && this.mailTypedSocketUrl === normalizedUrl) {
288
+ return await this.mailTypedSocketPromise;
289
+ }
290
+ if (this.mailTypedSocket || this.mailTypedSocketPromise) {
291
+ await this.stopMailTypedSocket();
292
+ }
293
+ this.mailTypedSocketUrl = normalizedUrl;
294
+ const abortController = new AbortController();
295
+ this.mailTypedSocketAbortController = abortController;
296
+ const socketPromise = plugins.typedsocket.TypedSocket.createClient(this.platformClientRef.typedrouter, normalizedUrl, { autoReconnect: true, abortSignal: abortController.signal });
297
+ this.mailTypedSocketPromise = socketPromise;
298
+ try {
299
+ const socket = await socketPromise;
300
+ if (this.mailTypedSocketPromise === socketPromise && this.mailTypedSocketUrl === normalizedUrl) {
301
+ this.mailTypedSocket = socket;
302
+ this.watchMailTypedSocketStatus(socket);
303
+ }
304
+ else {
305
+ await socket.stop();
306
+ }
307
+ return socket;
308
+ }
309
+ catch (error) {
310
+ if (this.mailTypedSocketPromise === socketPromise) {
311
+ this.mailTypedSocketPromise = undefined;
312
+ this.mailTypedSocketUrl = undefined;
313
+ this.mailTypedSocketAbortController = undefined;
314
+ }
315
+ throw error;
316
+ }
317
+ }
318
+ async stopMailTypedSocket() {
319
+ const socket = this.mailTypedSocket;
320
+ const socketPromise = this.mailTypedSocketPromise;
321
+ const abortController = this.mailTypedSocketAbortController;
322
+ const statusSubscription = this.mailTypedSocketStatusSubscription;
323
+ this.mailTypedSocket = undefined;
324
+ this.mailTypedSocketPromise = undefined;
325
+ this.mailTypedSocketUrl = undefined;
326
+ this.mailTypedSocketAbortController = undefined;
327
+ this.mailTypedSocketStatusSubscription = undefined;
328
+ statusSubscription?.unsubscribe();
329
+ abortController?.abort();
330
+ if (socket) {
331
+ await socket.stop();
332
+ return;
333
+ }
334
+ if (socketPromise) {
335
+ try {
336
+ const pendingSocket = await socketPromise;
337
+ await pendingSocket.stop();
338
+ }
339
+ catch {
340
+ // The pending connection already failed; there is no socket to stop.
341
+ }
342
+ }
343
+ }
344
+ watchMailTypedSocketStatus(socketArg) {
345
+ this.mailTypedSocketStatusSubscription?.unsubscribe();
346
+ this.mailTypedSocketStatusSubscription = socketArg.statusSubject.subscribe((statusArg) => {
347
+ void this.handleMailTypedSocketStatus(socketArg, statusArg);
348
+ });
349
+ }
350
+ async handleMailTypedSocketStatus(socketArg, statusArg) {
351
+ if (statusArg !== 'connected' || this.mailTypedSocket !== socketArg) {
352
+ return;
353
+ }
354
+ try {
355
+ await this.replayInboundEndpointRegistrationsWithRetry(socketArg);
356
+ }
357
+ catch (error) {
358
+ console.warn('Could not re-register service mail endpoint after reconnect:', error.message);
359
+ }
360
+ }
361
+ async replayInboundEndpointRegistrationsWithRetry(socketArg) {
362
+ if (!this.inboundEndpointRegistrations.size) {
363
+ return;
364
+ }
365
+ if (this.inboundEndpointReplayPromise) {
366
+ return await this.inboundEndpointReplayPromise;
367
+ }
368
+ const replayPromise = this.replayInboundEndpointRegistrationsWithRetryInner(socketArg);
369
+ this.inboundEndpointReplayPromise = replayPromise;
370
+ try {
371
+ await replayPromise;
372
+ }
373
+ finally {
374
+ if (this.inboundEndpointReplayPromise === replayPromise) {
375
+ this.inboundEndpointReplayPromise = undefined;
376
+ }
377
+ }
378
+ }
379
+ async replayInboundEndpointRegistrationsWithRetryInner(socketArg) {
380
+ let lastError;
381
+ const delays = [0, ...this.inboundEndpointReplayRetryDelaysMs];
382
+ for (let attemptIndex = 0; attemptIndex < delays.length; attemptIndex++) {
383
+ if (this.mailTypedSocket !== socketArg) {
384
+ return;
385
+ }
386
+ if (attemptIndex > 0) {
387
+ const shouldContinue = await this.waitForInboundEndpointReplayRetry(socketArg, delays[attemptIndex]);
388
+ if (!shouldContinue) {
389
+ return;
390
+ }
391
+ }
392
+ try {
393
+ await this.replayInboundEndpointRegistrationsOnce(socketArg);
394
+ return;
395
+ }
396
+ catch (error) {
397
+ lastError = error;
398
+ }
399
+ }
400
+ throw lastError instanceof Error
401
+ ? lastError
402
+ : new Error('Could not re-register service mail endpoint after reconnect');
403
+ }
404
+ async replayInboundEndpointRegistrationsOnce(socketArg) {
405
+ for (const address of this.inboundEndpointRegistrations.values()) {
406
+ if (this.mailTypedSocket !== socketArg) {
407
+ return;
408
+ }
409
+ const credentials = await this.getServiceMailTypedCredentials(address);
410
+ if (this.normalizeTypedSocketUrl(credentials.typedUrl) !== this.mailTypedSocketUrl) {
411
+ continue;
412
+ }
413
+ await this.registerServiceMailEndpoint(socketArg, credentials);
414
+ }
415
+ }
416
+ async waitForInboundEndpointReplayRetry(socketArg, delayMsArg) {
417
+ if (this.mailTypedSocket !== socketArg) {
418
+ return false;
419
+ }
420
+ const abortSignal = this.mailTypedSocketAbortController?.signal;
421
+ if (abortSignal?.aborted) {
422
+ return false;
423
+ }
424
+ return await new Promise((resolve) => {
425
+ const resolveOnce = (resultArg) => {
426
+ clearTimeout(timeout);
427
+ abortSignal?.removeEventListener('abort', abortHandler);
428
+ resolve(resultArg && this.mailTypedSocket === socketArg);
429
+ };
430
+ const abortHandler = () => resolveOnce(false);
431
+ const timeout = setTimeout(() => resolveOnce(true), delayMsArg);
432
+ abortSignal?.addEventListener('abort', abortHandler, { once: true });
433
+ });
434
+ }
435
+ async registerServiceMailEndpoint(typedSocketArg, credentialsArg) {
436
+ const request = typedSocketArg.createTypedRequest('registerServiceMailEndpoint');
437
+ const result = await request.fire({
438
+ auth: {
439
+ credentialId: credentialsArg.credentialId,
440
+ credentialSecret: credentialsArg.credentialSecret,
441
+ },
442
+ addresses: [credentialsArg.from],
443
+ });
444
+ if (!result.success) {
445
+ throw new Error(result.message || 'Could not register service mail endpoint');
446
+ }
447
+ return result;
448
+ }
449
+ normalizeTypedSocketUrl(urlArg) {
450
+ return urlArg.trim().replace(/\/typedrequest\/?$/, '').replace(/\/+$/, '');
451
+ }
208
452
  normalizeTlsMode(valueArg) {
209
453
  if (valueArg === 'plain' || valueArg === 'starttls' || valueArg === 'implicitTls')
210
454
  return valueArg;
@@ -218,7 +462,7 @@ export class SzEmailConnector {
218
462
  return Array.isArray(valueArg) ? valueArg : [valueArg];
219
463
  }
220
464
  normalizeAttachmentContent(contentArg) {
221
- return typeof contentArg === 'string' ? contentArg : Buffer.from(contentArg);
465
+ return Buffer.from(contentArg).toString('base64');
222
466
  }
223
467
  asRecord(valueArg) {
224
468
  return valueArg && typeof valueArg === 'object' ? valueArg : {};
@@ -248,4 +492,4 @@ export class SzEmailConnector {
248
492
  }
249
493
  }
250
494
  }
251
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lbWFpbGNvbm5lY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2VtYWlsL2NsYXNzZXMuZW1haWxjb25uZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQTRFdEMsTUFBTSxPQUFPLGdCQUFnQjtJQUczQixZQUFZLG9CQUFzQztRQUNoRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsb0JBQW9CLENBQUM7SUFDaEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFNBQVMsQ0FDcEIsVUFBZ0Y7UUFFaEYsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsMkJBQTJCLFVBQVUsQ0FBQyxLQUFLLE9BQU8sVUFBVSxDQUFDLEVBQUU7O1VBRTlFLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDOztTQUVyRSxDQUFDLENBQUM7UUFDUCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFlBQVksR0FDaEIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FDbkQsV0FBVyxDQUNaLENBQUM7UUFDSixNQUFNLFFBQVEsR0FBRyxNQUFNLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckQsT0FBTyxRQUFRLENBQUMsVUFBVSxDQUFDO0lBQzdCLENBQUM7SUFFTSxLQUFLLENBQUMs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
495
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lbWFpbGNvbm5lY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2VtYWlsL2NsYXNzZXMuZW1haWxjb25uZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQWlGdEMsTUFBTSxPQUFPLGdCQUFnQjtJQWEzQixZQUFZLG9CQUFzQztRQUwxQyxrQ0FBNkIsR0FBRyxLQUFLLENBQUM7UUFDdEMsaUNBQTRCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUV4Qyx1Q0FBa0MsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRzVFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsU0FBUyxDQUNwQixVQUFnRjtRQUVoRixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSwyQkFBMkIsVUFBVSxDQUFDLEtBQUssT0FBTyxVQUFVLENBQUMsRUFBRTs7VUFFOUUsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7O1NBRXJFLENBQUMsQ0FBQztRQUNQLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUNu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
@@ -3,7 +3,6 @@ export { servezoneInterfaces, };
3
3
  import * as qenv from '@push.rocks/qenv';
4
4
  import * as smartlog from '@push.rocks/smartlog';
5
5
  export { qenv, smartlog, };
6
- export declare const getSmartsmtp: () => Promise<typeof import("@push.rocks/smartsmtp")>;
7
6
  import * as typedrequest from '@api.global/typedrequest';
8
7
  import * as typedserver from '@api.global/typedserver';
9
8
  import * as typedsocket from '@api.global/typedsocket';
@@ -5,10 +5,9 @@ export { servezoneInterfaces, };
5
5
  import * as qenv from '@push.rocks/qenv';
6
6
  import * as smartlog from '@push.rocks/smartlog';
7
7
  export { qenv, smartlog, };
8
- export const getSmartsmtp = async () => await import('@push.rocks/smartsmtp');
9
8
  // @api.global scope
10
9
  import * as typedrequest from '@api.global/typedrequest';
11
10
  import * as typedserver from '@api.global/typedserver';
12
11
  import * as typedsocket from '@api.global/typedsocket';
13
12
  export { typedrequest, typedserver, typedsocket, };
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxtQkFBbUIsTUFBTSx3QkFBd0IsQ0FBQztBQUU5RCxPQUFPLEVBQ0wsbUJBQW1CLEdBQ3BCLENBQUE7QUFFRCxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFDTCxJQUFJLEVBQ0osUUFBUSxHQUNULENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0FBRzlFLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUV2RCxPQUFPLEVBQ0wsWUFBWSxFQUNaLFdBQVcsRUFDWCxXQUFXLEdBQ1osQ0FBQSJ9
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxtQkFBbUIsTUFBTSx3QkFBd0IsQ0FBQztBQUU5RCxPQUFPLEVBQ0wsbUJBQW1CLEdBQ3BCLENBQUE7QUFFRCxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE9BQU8sRUFDTCxJQUFJLEVBQ0osUUFBUSxHQUNULENBQUE7QUFHRCxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUNMLFlBQVksRUFDWixXQUFXLEVBQ1gsV0FBVyxHQUNaLENBQUEifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/platformclient",
3
- "version": "1.2.0",
3
+ "version": "2.0.1",
4
4
  "private": false,
5
5
  "description": "a module that makes it really easy to use the serve.zone platform inside your app",
6
6
  "main": "dist_ts/index.js",
@@ -13,7 +13,7 @@
13
13
  "@git.zone/tsbundle": "^2.11.0",
14
14
  "@git.zone/tsrun": "^2.0.4",
15
15
  "@git.zone/tstest": "^3.6.6",
16
- "@types/node": "^25.9.1"
16
+ "@types/node": "^25.9.3"
17
17
  },
18
18
  "dependencies": {
19
19
  "@api.global/typedrequest": "^3.3.0",
@@ -22,8 +22,7 @@
22
22
  "@push.rocks/qenv": "^6.1.4",
23
23
  "@push.rocks/smartlog": "^3.2.2",
24
24
  "@push.rocks/smartntml": "^2.0.9",
25
- "@push.rocks/smartsmtp": "^3.1.0",
26
- "@serve.zone/interfaces": "^7.27.0"
25
+ "@serve.zone/interfaces": "^7.28.0"
27
26
  },
28
27
  "repository": {
29
28
  "type": "git",
package/readme.md CHANGED
@@ -38,7 +38,7 @@ await platformClient.emailConnector.sendEmail({
38
38
 
39
39
  | Connector | Main methods | Platform capability |
40
40
  | --- | --- | --- |
41
- | `emailConnector` | `getServiceMailStatus()`, `getServiceMailCredentials()`, `sendMail()`, `sendText()`, `sendHtml()`, `normalizeInboundMessage()`, `handleInboundPayload()`, `createInboundHandler()`, `sendEmail()` | `email` |
41
+ | `emailConnector` | `getServiceMailStatus()`, `getServiceMailCredentials()`, `sendMail()`, `sendText()`, `sendHtml()`, `registerInboundHandler()`, `normalizeInboundMessage()`, `handleInboundPayload()`, `createInboundHandler()`, `sendEmail()` | `email` |
42
42
  | `smsConnector` | `sendSms()`, `sendSmsVerifcation()` | `sms` |
43
43
  | `pushNotificationConnector` | `sendPushNotification()` | `pushnotification` |
44
44
  | `letterConnector` | `sendLetter()` | `letter` |
@@ -57,7 +57,9 @@ The client needs an authorization string and a platform endpoint. You can provid
57
57
 
58
58
  Binding environment variables must contain JSON encoded `IPlatformBinding` objects from `@serve.zone/interfaces`.
59
59
 
60
- Service mail credentials can be provided directly as environment variables or through `email` platform binding credentials. The default sender uses `MAIL_FROM`, `SMTP_HOST`, `SMTP_PORT`, `SMTP_TLS_MODE`, `SMTP_USERNAME`, and `SMTP_PASSWORD`. Additional configured sender addresses use scoped variables such as `MAIL_TEST_SERVICE_GATED_ONE_FROM` and `MAIL_TEST_SERVICE_GATED_ONE_SMTP_USERNAME`.
60
+ Service mail credentials can be provided directly as environment variables or through `email` platform binding credentials. Standard platformclient mail uses dcrouter TypedSocket/TypedRequest service credentials. The default sender uses `MAIL_FROM`, `MAIL_TYPED_URL`, `MAIL_API_CREDENTIAL_ID`, and `MAIL_API_CREDENTIAL_SECRET`. Additional configured sender addresses use scoped variables such as `MAIL_TEST_SERVICE_GATED_ONE_FROM`, `MAIL_TEST_SERVICE_GATED_ONE_TYPED_URL`, `MAIL_TEST_SERVICE_GATED_ONE_API_CREDENTIAL_ID`, and `MAIL_TEST_SERVICE_GATED_ONE_API_CREDENTIAL_SECRET`.
61
+
62
+ SMTP compatibility credentials are still discoverable with `getServiceMailCredentials()` for applications that explicitly implement SMTP themselves. Those compatibility variables are `SMTP_HOST`, `SMTP_PORT`, `SMTP_TLS_MODE`, `SMTP_USERNAME`, and `SMTP_PASSWORD`, plus scoped `MAIL_<TOKEN>_SMTP_*` variants. They are not used by `sendMail()`, `sendText()`, `sendHtml()`, or `registerInboundHandler()`.
61
63
 
62
64
  ```typescript
63
65
  import { SzPlatformClient } from '@serve.zone/platformclient';
@@ -102,9 +104,32 @@ console.log(verificationCode); // 123456
102
104
 
103
105
  The current SMS verification method is spelled `sendSmsVerifcation()` in code. Use that exact method name until the public API changes.
104
106
 
107
+ ## Lifecycle
108
+
109
+ `SzPlatformClient` keeps TypedSocket connections open for platform requests and typed service-mail delivery. Call `stop()` when a short-lived process, worker, or test is done with the client.
110
+
111
+ ```typescript
112
+ const client = new SzPlatformClient({
113
+ token: process.env.SERVEZONE_PLATFORM_TOKEN,
114
+ platformUrl: process.env.SERVEZONE_PLATFORM_URL,
115
+ });
116
+
117
+ await client.init();
118
+
119
+ try {
120
+ await client.emailConnector.sendText({
121
+ to: 'user@example.com',
122
+ subject: 'Done',
123
+ text: 'The job has finished.',
124
+ });
125
+ } finally {
126
+ await client.stop();
127
+ }
128
+ ```
129
+
105
130
  ## Connector Examples
106
131
 
107
- Service mail over managed SMTP credentials:
132
+ Service mail over managed TypedSocket credentials:
108
133
 
109
134
  ```typescript
110
135
  const status = await client.emailConnector.getServiceMailStatus();
@@ -118,6 +143,8 @@ if (status.ready) {
118
143
  }
119
144
  ```
120
145
 
146
+ `getServiceMailStatus().ready` means the typed service-mail path is configured. The status also exposes `transport`, `typedUrl`, `typedCredentialConfigured`, and `smtpReady` so applications can distinguish standard TypedSocket mail from explicit SMTP compatibility configuration.
147
+
121
148
  Specific sender address:
122
149
 
123
150
  ```typescript
@@ -129,7 +156,18 @@ await client.emailConnector.sendHtml({
129
156
  });
130
157
  ```
131
158
 
132
- Inbound message normalization for webhook or TypedRequest-style delivery:
159
+ Typed inbound mail registration:
160
+
161
+ ```typescript
162
+ await client.emailConnector.registerInboundHandler(async (message) => {
163
+ console.log(message.from, message.to, message.subject);
164
+ return { accepted: true, workAppMessageId: message.messageId };
165
+ });
166
+ ```
167
+
168
+ `registerInboundHandler()` registers this client connection as the typed endpoint for the configured service mail address. dcrouter then delivers inbound messages through the shared `deliverInboundMail` TypedRequest contract.
169
+
170
+ Inbound message normalization for webhook or direct TypedRequest-style delivery:
133
171
 
134
172
  ```typescript
135
173
  const inboundHandler = client.emailConnector.createInboundHandler(async (message) => {
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/platformclient',
6
- version: '1.2.0',
6
+ version: '2.0.1',
7
7
  description: 'a module that makes it really easy to use the serve.zone platform inside your app'
8
8
  }
@@ -174,6 +174,13 @@ export class SzPlatformClient {
174
174
  }
175
175
  }
176
176
 
177
+ public async stop(): Promise<void> {
178
+ await this.emailConnector.stop();
179
+ if (this.typedsocket) {
180
+ await this.typedsocket.stop();
181
+ }
182
+ }
183
+
177
184
  private async discoverPlatformBindings() {
178
185
  const bindings: plugins.servezoneInterfaces.platform.IPlatformBinding[] = [];
179
186
  const envBindings = await this.getConfiguredEnvVar('SERVEZONE_PLATFORM_BINDINGS');
@@ -15,14 +15,26 @@ export interface IServiceMailSmtpCredentials {
15
15
  addressToken?: string;
16
16
  }
17
17
 
18
+ export interface IServiceMailTypedCredentials {
19
+ from: string;
20
+ typedUrl: string;
21
+ credentialId: string;
22
+ credentialSecret: string;
23
+ addressToken?: string;
24
+ }
25
+
18
26
  export interface IServiceMailStatus {
19
27
  ready: boolean;
20
28
  from?: string;
21
29
  host?: string;
22
30
  port?: number;
23
31
  tlsMode?: TServiceMailTlsMode;
32
+ typedUrl?: string;
33
+ transport?: 'typedsocket' | 'smtp' | 'none';
24
34
  usernameConfigured: boolean;
25
35
  passwordConfigured: boolean;
36
+ typedCredentialConfigured?: boolean;
37
+ smtpReady?: boolean;
26
38
  missing: string[];
27
39
  }
28
40
 
@@ -66,19 +78,22 @@ export interface IServiceMailInboundHandlerResult {
66
78
  export type IServiceMailInboundHandleResult =
67
79
  plugins.servezoneInterfaces.requests.mail.IReq_DeliverInboundMail['response'];
68
80
 
69
- interface INodemailerSendResult {
70
- messageId?: string;
71
- accepted?: unknown[];
72
- rejected?: unknown[];
73
- response?: string;
74
- }
75
-
76
81
  export type TServiceMailInboundHandler = (
77
82
  messageArg: IServiceMailInboundMessage,
78
83
  ) => Promise<IServiceMailInboundHandlerResult | void> | IServiceMailInboundHandlerResult | void;
79
84
 
80
85
  export class SzEmailConnector {
81
86
  public platformClientRef: SzPlatformClient;
87
+ private mailTypedSocket?: plugins.typedsocket.TypedSocket;
88
+ private mailTypedSocketUrl?: string;
89
+ private mailTypedSocketPromise?: Promise<plugins.typedsocket.TypedSocket>;
90
+ private mailTypedSocketAbortController?: AbortController;
91
+ private mailTypedSocketStatusSubscription?: { unsubscribe: () => void };
92
+ private inboundHandler?: TServiceMailInboundHandler;
93
+ private inboundTypedHandlerRegistered = false;
94
+ private inboundEndpointRegistrations = new Set<string>();
95
+ private inboundEndpointReplayPromise?: Promise<void>;
96
+ private readonly inboundEndpointReplayRetryDelaysMs = [500, 1000, 2000, 5000];
82
97
 
83
98
  constructor(platformClientRefArg: SzPlatformClient) {
84
99
  this.platformClientRef = platformClientRefArg;
@@ -122,23 +137,33 @@ export class SzEmailConnector {
122
137
  const missingPrefix = useDefaultEnv || !token ? undefined : token;
123
138
  const port = env.smtpPort ? Number(env.smtpPort) : undefined;
124
139
  const tlsMode = this.normalizeTlsMode(env.smtpTlsMode || 'starttls');
125
- const missing: string[] = [];
126
- if (!env.from) missing.push(missingPrefix ? `MAIL_${missingPrefix}_FROM` : 'MAIL_FROM');
127
- if (!env.smtpHost) missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_HOST` : 'SMTP_HOST');
140
+ const typedMissing: string[] = [];
141
+ const smtpMissing: string[] = [];
142
+ if (!env.typedUrl) typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_TYPED_URL` : 'MAIL_TYPED_URL');
143
+ if (!env.apiCredentialId) typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_API_CREDENTIAL_ID` : 'MAIL_API_CREDENTIAL_ID');
144
+ if (!env.apiCredentialSecret) typedMissing.push(missingPrefix ? `MAIL_${missingPrefix}_API_CREDENTIAL_SECRET` : 'MAIL_API_CREDENTIAL_SECRET');
145
+ if (!env.smtpHost) smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_HOST` : 'SMTP_HOST');
128
146
  if (!env.smtpPort || !Number.isInteger(port) || port! < 1 || port! > 65535) {
129
- missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PORT` : 'SMTP_PORT');
147
+ smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PORT` : 'SMTP_PORT');
130
148
  }
131
- if (!env.smtpUsername) missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_USERNAME` : 'SMTP_USERNAME');
132
- if (!env.smtpPassword) missing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PASSWORD` : 'SMTP_PASSWORD');
149
+ if (!env.smtpUsername) smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_USERNAME` : 'SMTP_USERNAME');
150
+ if (!env.smtpPassword) smtpMissing.push(missingPrefix ? `MAIL_${missingPrefix}_SMTP_PASSWORD` : 'SMTP_PASSWORD');
151
+ const fromMissing = env.from ? [] : [missingPrefix ? `MAIL_${missingPrefix}_FROM` : 'MAIL_FROM'];
152
+ const typedReady = fromMissing.length === 0 && typedMissing.length === 0;
153
+ const smtpReady = fromMissing.length === 0 && smtpMissing.length === 0;
133
154
  return {
134
- ready: missing.length === 0,
155
+ ready: typedReady,
135
156
  from: env.from,
136
157
  host: env.smtpHost,
137
158
  port,
138
159
  tlsMode,
160
+ typedUrl: env.typedUrl,
161
+ transport: typedReady ? 'typedsocket' : smtpReady ? 'smtp' : 'none',
139
162
  usernameConfigured: Boolean(env.smtpUsername),
140
163
  passwordConfigured: Boolean(env.smtpPassword),
141
- missing,
164
+ typedCredentialConfigured: Boolean(env.apiCredentialId && env.apiCredentialSecret),
165
+ smtpReady,
166
+ missing: typedReady ? [] : [...fromMissing, ...typedMissing],
142
167
  };
143
168
  }
144
169
 
@@ -188,38 +213,62 @@ export class SzEmailConnector {
188
213
  return { messageId: 'debug' };
189
214
  }
190
215
 
191
- const credentials = await this.getServiceMailCredentials(optionsArg.from);
192
- const smartsmtp = await plugins.getSmartsmtp();
193
- const smtp = await smartsmtp.Smartsmtp.createSmartsmtpWithRelay({
194
- smtpServer: credentials.host,
195
- smtpPort: credentials.port,
196
- smtpTlsMode: credentials.tlsMode,
197
- smtpUser: credentials.username,
198
- smtpPassword: credentials.password,
216
+ const credentials = await this.getServiceMailTypedCredentials(optionsArg.from);
217
+ const typedSocket = await this.getMailTypedSocket(credentials.typedUrl);
218
+ const request = typedSocket.createTypedRequest<plugins.servezoneInterfaces.requests.mail.IReq_EnqueueMail>('enqueueMail');
219
+ const result = await request.fire({
220
+ auth: {
221
+ credentialId: credentials.credentialId,
222
+ credentialSecret: credentials.credentialSecret,
223
+ },
224
+ outboundIdentityId: credentials.credentialId,
225
+ message: {
226
+ from: credentials.from,
227
+ to: this.listToArray(optionsArg.to),
228
+ cc: optionsArg.cc ? this.listToArray(optionsArg.cc) : undefined,
229
+ bcc: optionsArg.bcc ? this.listToArray(optionsArg.bcc) : undefined,
230
+ subject: optionsArg.subject,
231
+ text: optionsArg.text,
232
+ html: optionsArg.html,
233
+ headers: optionsArg.headers,
234
+ attachments: optionsArg.attachments?.map((attachmentArg) => ({
235
+ filename: attachmentArg.filename,
236
+ contentType: attachmentArg.contentType,
237
+ binaryAttachmentString: this.normalizeAttachmentContent(attachmentArg.content),
238
+ })),
239
+ },
199
240
  });
200
- const result = (await smtp.nodemailerTransport.sendMail({
201
- from: credentials.from,
202
- to: this.listToArray(optionsArg.to),
203
- cc: optionsArg.cc ? this.listToArray(optionsArg.cc) : undefined,
204
- bcc: optionsArg.bcc ? this.listToArray(optionsArg.bcc) : undefined,
205
- subject: optionsArg.subject,
206
- text: optionsArg.text,
207
- html: optionsArg.html,
208
- headers: optionsArg.headers,
209
- attachments: optionsArg.attachments?.map((attachmentArg) => ({
210
- filename: attachmentArg.filename,
211
- contentType: attachmentArg.contentType,
212
- content: this.normalizeAttachmentContent(attachmentArg.content),
213
- })),
214
- })) as INodemailerSendResult;
241
+ if (!result.accepted) {
242
+ throw new Error(result.message || 'service mail was not accepted by dcrouter');
243
+ }
215
244
  return {
216
- messageId: result.messageId,
217
- accepted: Array.isArray(result.accepted) ? result.accepted.map(String) : undefined,
218
- rejected: Array.isArray(result.rejected) ? result.rejected.map(String) : undefined,
219
- response: result.response,
245
+ messageId: result.spoolItemId,
246
+ accepted: this.listToArray(optionsArg.to),
247
+ rejected: [],
248
+ response: result.message,
220
249
  };
221
250
  }
222
251
 
252
+ public async registerInboundHandler(
253
+ handlerArg: TServiceMailInboundHandler,
254
+ addressArg?: string,
255
+ ): Promise<plugins.servezoneInterfaces.requests.mail.IReq_RegisterServiceMailEndpoint['response']> {
256
+ this.inboundHandler = handlerArg;
257
+ this.ensureInboundTypedHandler();
258
+ const credentials = await this.getServiceMailTypedCredentials(addressArg);
259
+ const typedSocket = await this.getMailTypedSocket(credentials.typedUrl);
260
+ const result = await this.registerServiceMailEndpoint(typedSocket, credentials);
261
+ const registeredAddresses = result.addresses?.length ? result.addresses : [credentials.from];
262
+ for (const address of registeredAddresses) {
263
+ this.inboundEndpointRegistrations.add(address.trim().toLowerCase());
264
+ }
265
+ return result;
266
+ }
267
+
268
+ public async stop(): Promise<void> {
269
+ await this.stopMailTypedSocket();
270
+ }
271
+
223
272
  public normalizeInboundMessage(payloadArg: unknown): IServiceMailInboundMessage {
224
273
  const payload = this.asRecord(payloadArg);
225
274
  const deliveryCandidate = this.asRecord(payload.delivery || payload.message || payload);
@@ -264,6 +313,22 @@ export class SzEmailConnector {
264
313
  return async (payloadArg: unknown) => await this.handleInboundPayload(payloadArg, handlerArg);
265
314
  }
266
315
 
316
+ private ensureInboundTypedHandler(): void {
317
+ if (this.inboundTypedHandlerRegistered) return;
318
+ this.inboundTypedHandlerRegistered = true;
319
+ this.platformClientRef.typedrouter.addTypedHandler(
320
+ new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.mail.IReq_DeliverInboundMail>(
321
+ 'deliverInboundMail',
322
+ async (dataArg) => {
323
+ if (!this.inboundHandler) {
324
+ return { accepted: false, message: 'No service mail inbound handler registered' };
325
+ }
326
+ return await this.handleInboundPayload(dataArg.delivery, this.inboundHandler);
327
+ },
328
+ ),
329
+ );
330
+ }
331
+
267
332
  public async sendNotification(optionsArg: { toArg: string; subject: string; text: string }) {}
268
333
 
269
334
  public async sendActionLink(optionsArg: { toArg: string; subject: string; text: string }) {}
@@ -275,6 +340,9 @@ export class SzEmailConnector {
275
340
  smtpTlsMode?: string;
276
341
  smtpUsername?: string;
277
342
  smtpPassword?: string;
343
+ typedUrl?: string;
344
+ apiCredentialId?: string;
345
+ apiCredentialSecret?: string;
278
346
  }> {
279
347
  const prefix = tokenArg ? `MAIL_${tokenArg}_` : '';
280
348
  return {
@@ -284,6 +352,9 @@ export class SzEmailConnector {
284
352
  smtpTlsMode: await this.readMailEnvVar(`${prefix}SMTP_TLS_MODE`),
285
353
  smtpUsername: await this.readMailEnvVar(`${prefix}SMTP_USERNAME`),
286
354
  smtpPassword: await this.readMailEnvVar(`${prefix}SMTP_PASSWORD`),
355
+ typedUrl: await this.readMailEnvVar(tokenArg ? `${prefix}TYPED_URL` : 'MAIL_TYPED_URL'),
356
+ apiCredentialId: await this.readMailEnvVar(tokenArg ? `${prefix}API_CREDENTIAL_ID` : 'MAIL_API_CREDENTIAL_ID'),
357
+ apiCredentialSecret: await this.readMailEnvVar(tokenArg ? `${prefix}API_CREDENTIAL_SECRET` : 'MAIL_API_CREDENTIAL_SECRET'),
287
358
  };
288
359
  }
289
360
 
@@ -310,10 +381,230 @@ export class SzEmailConnector {
310
381
  smtpTlsMode?: string;
311
382
  smtpUsername?: string;
312
383
  smtpPassword?: string;
384
+ typedUrl?: string;
385
+ apiCredentialId?: string;
386
+ apiCredentialSecret?: string;
313
387
  }): boolean {
314
388
  return Boolean(envArg && Object.values(envArg).some(Boolean));
315
389
  }
316
390
 
391
+ private async getServiceMailTypedCredentials(addressArg?: string): Promise<IServiceMailTypedCredentials> {
392
+ const requestedAddress = addressArg?.trim().toLowerCase();
393
+ const requestedToken = requestedAddress ? this.getMailEnvToken(requestedAddress) : undefined;
394
+ const scopedEnv = requestedToken ? await this.readMailEnv(requestedToken) : undefined;
395
+ const hasScopedConfig = scopedEnv && Object.values(scopedEnv).some(Boolean);
396
+ const env = hasScopedConfig ? scopedEnv! : await this.readMailEnv();
397
+ const from = env.from?.trim().toLowerCase();
398
+ if (!from) throw new Error('MAIL_FROM is required for typed service mail');
399
+ if (requestedAddress && from !== requestedAddress) {
400
+ throw new Error(`No typed service mail credentials are configured for ${requestedAddress}`);
401
+ }
402
+ if (!env.typedUrl) throw new Error('MAIL_TYPED_URL is required for typed service mail');
403
+ if (!env.apiCredentialId) throw new Error('MAIL_API_CREDENTIAL_ID is required for typed service mail');
404
+ if (!env.apiCredentialSecret) throw new Error('MAIL_API_CREDENTIAL_SECRET is required for typed service mail');
405
+ return {
406
+ from,
407
+ typedUrl: this.normalizeTypedSocketUrl(env.typedUrl),
408
+ credentialId: env.apiCredentialId,
409
+ credentialSecret: env.apiCredentialSecret,
410
+ addressToken: hasScopedConfig ? requestedToken : undefined,
411
+ };
412
+ }
413
+
414
+ private async getMailTypedSocket(urlArg: string): Promise<plugins.typedsocket.TypedSocket> {
415
+ const normalizedUrl = this.normalizeTypedSocketUrl(urlArg);
416
+ if (this.mailTypedSocket && this.mailTypedSocketUrl === normalizedUrl) {
417
+ return this.mailTypedSocket;
418
+ }
419
+ if (this.mailTypedSocketPromise && this.mailTypedSocketUrl === normalizedUrl) {
420
+ return await this.mailTypedSocketPromise;
421
+ }
422
+ if (this.mailTypedSocket || this.mailTypedSocketPromise) {
423
+ await this.stopMailTypedSocket();
424
+ }
425
+ this.mailTypedSocketUrl = normalizedUrl;
426
+ const abortController = new AbortController();
427
+ this.mailTypedSocketAbortController = abortController;
428
+ const socketPromise = plugins.typedsocket.TypedSocket.createClient(
429
+ this.platformClientRef.typedrouter,
430
+ normalizedUrl,
431
+ { autoReconnect: true, abortSignal: abortController.signal },
432
+ );
433
+ this.mailTypedSocketPromise = socketPromise;
434
+ try {
435
+ const socket = await socketPromise;
436
+ if (this.mailTypedSocketPromise === socketPromise && this.mailTypedSocketUrl === normalizedUrl) {
437
+ this.mailTypedSocket = socket;
438
+ this.watchMailTypedSocketStatus(socket);
439
+ } else {
440
+ await socket.stop();
441
+ }
442
+ return socket;
443
+ } catch (error) {
444
+ if (this.mailTypedSocketPromise === socketPromise) {
445
+ this.mailTypedSocketPromise = undefined;
446
+ this.mailTypedSocketUrl = undefined;
447
+ this.mailTypedSocketAbortController = undefined;
448
+ }
449
+ throw error;
450
+ }
451
+ }
452
+
453
+ private async stopMailTypedSocket(): Promise<void> {
454
+ const socket = this.mailTypedSocket;
455
+ const socketPromise = this.mailTypedSocketPromise;
456
+ const abortController = this.mailTypedSocketAbortController;
457
+ const statusSubscription = this.mailTypedSocketStatusSubscription;
458
+ this.mailTypedSocket = undefined;
459
+ this.mailTypedSocketPromise = undefined;
460
+ this.mailTypedSocketUrl = undefined;
461
+ this.mailTypedSocketAbortController = undefined;
462
+ this.mailTypedSocketStatusSubscription = undefined;
463
+ statusSubscription?.unsubscribe();
464
+ abortController?.abort();
465
+ if (socket) {
466
+ await socket.stop();
467
+ return;
468
+ }
469
+ if (socketPromise) {
470
+ try {
471
+ const pendingSocket = await socketPromise;
472
+ await pendingSocket.stop();
473
+ } catch {
474
+ // The pending connection already failed; there is no socket to stop.
475
+ }
476
+ }
477
+ }
478
+
479
+ private watchMailTypedSocketStatus(socketArg: plugins.typedsocket.TypedSocket): void {
480
+ this.mailTypedSocketStatusSubscription?.unsubscribe();
481
+ this.mailTypedSocketStatusSubscription = socketArg.statusSubject.subscribe((statusArg) => {
482
+ void this.handleMailTypedSocketStatus(socketArg, statusArg);
483
+ });
484
+ }
485
+
486
+ private async handleMailTypedSocketStatus(
487
+ socketArg: plugins.typedsocket.TypedSocket,
488
+ statusArg: plugins.typedsocket.TConnectionStatus,
489
+ ): Promise<void> {
490
+ if (statusArg !== 'connected' || this.mailTypedSocket !== socketArg) {
491
+ return;
492
+ }
493
+ try {
494
+ await this.replayInboundEndpointRegistrationsWithRetry(socketArg);
495
+ } catch (error) {
496
+ console.warn('Could not re-register service mail endpoint after reconnect:', (error as Error).message);
497
+ }
498
+ }
499
+
500
+ private async replayInboundEndpointRegistrationsWithRetry(
501
+ socketArg: plugins.typedsocket.TypedSocket,
502
+ ): Promise<void> {
503
+ if (!this.inboundEndpointRegistrations.size) {
504
+ return;
505
+ }
506
+ if (this.inboundEndpointReplayPromise) {
507
+ return await this.inboundEndpointReplayPromise;
508
+ }
509
+
510
+ const replayPromise = this.replayInboundEndpointRegistrationsWithRetryInner(socketArg);
511
+ this.inboundEndpointReplayPromise = replayPromise;
512
+ try {
513
+ await replayPromise;
514
+ } finally {
515
+ if (this.inboundEndpointReplayPromise === replayPromise) {
516
+ this.inboundEndpointReplayPromise = undefined;
517
+ }
518
+ }
519
+ }
520
+
521
+ private async replayInboundEndpointRegistrationsWithRetryInner(
522
+ socketArg: plugins.typedsocket.TypedSocket,
523
+ ): Promise<void> {
524
+ let lastError: unknown;
525
+ const delays = [0, ...this.inboundEndpointReplayRetryDelaysMs];
526
+ for (let attemptIndex = 0; attemptIndex < delays.length; attemptIndex++) {
527
+ if (this.mailTypedSocket !== socketArg) {
528
+ return;
529
+ }
530
+ if (attemptIndex > 0) {
531
+ const shouldContinue = await this.waitForInboundEndpointReplayRetry(socketArg, delays[attemptIndex]);
532
+ if (!shouldContinue) {
533
+ return;
534
+ }
535
+ }
536
+ try {
537
+ await this.replayInboundEndpointRegistrationsOnce(socketArg);
538
+ return;
539
+ } catch (error) {
540
+ lastError = error;
541
+ }
542
+ }
543
+ throw lastError instanceof Error
544
+ ? lastError
545
+ : new Error('Could not re-register service mail endpoint after reconnect');
546
+ }
547
+
548
+ private async replayInboundEndpointRegistrationsOnce(
549
+ socketArg: plugins.typedsocket.TypedSocket,
550
+ ): Promise<void> {
551
+ for (const address of this.inboundEndpointRegistrations.values()) {
552
+ if (this.mailTypedSocket !== socketArg) {
553
+ return;
554
+ }
555
+ const credentials = await this.getServiceMailTypedCredentials(address);
556
+ if (this.normalizeTypedSocketUrl(credentials.typedUrl) !== this.mailTypedSocketUrl) {
557
+ continue;
558
+ }
559
+ await this.registerServiceMailEndpoint(socketArg, credentials);
560
+ }
561
+ }
562
+
563
+ private async waitForInboundEndpointReplayRetry(
564
+ socketArg: plugins.typedsocket.TypedSocket,
565
+ delayMsArg: number,
566
+ ): Promise<boolean> {
567
+ if (this.mailTypedSocket !== socketArg) {
568
+ return false;
569
+ }
570
+ const abortSignal = this.mailTypedSocketAbortController?.signal;
571
+ if (abortSignal?.aborted) {
572
+ return false;
573
+ }
574
+ return await new Promise<boolean>((resolve) => {
575
+ const resolveOnce = (resultArg: boolean) => {
576
+ clearTimeout(timeout);
577
+ abortSignal?.removeEventListener('abort', abortHandler);
578
+ resolve(resultArg && this.mailTypedSocket === socketArg);
579
+ };
580
+ const abortHandler = () => resolveOnce(false);
581
+ const timeout = setTimeout(() => resolveOnce(true), delayMsArg);
582
+ abortSignal?.addEventListener('abort', abortHandler, { once: true });
583
+ });
584
+ }
585
+
586
+ private async registerServiceMailEndpoint(
587
+ typedSocketArg: plugins.typedsocket.TypedSocket,
588
+ credentialsArg: IServiceMailTypedCredentials,
589
+ ): Promise<plugins.servezoneInterfaces.requests.mail.IReq_RegisterServiceMailEndpoint['response']> {
590
+ const request = typedSocketArg.createTypedRequest<plugins.servezoneInterfaces.requests.mail.IReq_RegisterServiceMailEndpoint>('registerServiceMailEndpoint');
591
+ const result = await request.fire({
592
+ auth: {
593
+ credentialId: credentialsArg.credentialId,
594
+ credentialSecret: credentialsArg.credentialSecret,
595
+ },
596
+ addresses: [credentialsArg.from],
597
+ });
598
+ if (!result.success) {
599
+ throw new Error(result.message || 'Could not register service mail endpoint');
600
+ }
601
+ return result;
602
+ }
603
+
604
+ private normalizeTypedSocketUrl(urlArg: string): string {
605
+ return urlArg.trim().replace(/\/typedrequest\/?$/, '').replace(/\/+$/, '');
606
+ }
607
+
317
608
  private normalizeTlsMode(valueArg: string): TServiceMailTlsMode {
318
609
  if (valueArg === 'plain' || valueArg === 'starttls' || valueArg === 'implicitTls') return valueArg;
319
610
  throw new Error(`Invalid SMTP_TLS_MODE: ${valueArg}`);
@@ -328,8 +619,8 @@ export class SzEmailConnector {
328
619
  return Array.isArray(valueArg) ? valueArg : [valueArg];
329
620
  }
330
621
 
331
- private normalizeAttachmentContent(contentArg: string | Uint8Array): string | Buffer {
332
- return typeof contentArg === 'string' ? contentArg : Buffer.from(contentArg);
622
+ private normalizeAttachmentContent(contentArg: string | Uint8Array): string {
623
+ return Buffer.from(contentArg).toString('base64');
333
624
  }
334
625
 
335
626
  private asRecord(valueArg: unknown): Record<string, unknown> {
package/ts/plugins.ts CHANGED
@@ -14,8 +14,6 @@ export {
14
14
  smartlog,
15
15
  }
16
16
 
17
- export const getSmartsmtp = async () => await import('@push.rocks/smartsmtp');
18
-
19
17
 
20
18
  // @api.global scope
21
19
  import * as typedrequest from '@api.global/typedrequest';