svix 2.3.0 → 2.5.0

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 (50) hide show
  1. package/dist/index.d.mts +1248 -798
  2. package/dist/index.d.mts.map +1 -1
  3. package/dist/index.mjs +4500 -3712
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/src/api/autoconfigSubscription.ts +53 -0
  7. package/src/api/destination.ts +133 -0
  8. package/src/api/destinationTransformation.ts +55 -0
  9. package/src/api_internal/autoconfigSubscription.ts +40 -0
  10. package/src/api_internal/autoconfigSubscriptionDestination.ts +27 -0
  11. package/src/api_internal/autoconfigSubscriptionEndpoint.ts +27 -0
  12. package/src/api_internal/endpoint.ts +3 -3
  13. package/src/api_internal/{endpointAutoConfig.ts → endpointAutoConfigDeprecated.ts} +1 -1
  14. package/src/autoconfig.test.ts +162 -3
  15. package/src/autoconfig.ts +88 -26
  16. package/src/autoconfigConsumer.ts +90 -16
  17. package/src/index.ts +10 -0
  18. package/src/models/autoConfigOut.ts +26 -0
  19. package/src/models/autoConfigSubscriptionOut.ts +38 -0
  20. package/src/models/destinationIn.ts +303 -0
  21. package/src/models/destinationOut.ts +295 -0
  22. package/src/models/destinationPatch.ts +302 -0
  23. package/src/models/destinationStatus.ts +18 -0
  24. package/src/models/destinationStatusIn.ts +16 -0
  25. package/src/models/destinationTransformIn.ts +19 -0
  26. package/src/models/destinationTransformationOut.ts +22 -0
  27. package/src/models/eventBridgeConfigIn.ts +14 -2
  28. package/src/models/eventBridgeConfigOut.ts +7 -1
  29. package/src/models/eventBridgeConfigPatch.ts +6 -0
  30. package/src/models/fifoEndpointConfigIn.ts +25 -0
  31. package/src/models/index.ts +13 -0
  32. package/src/models/ingestSourceIn.ts +12 -0
  33. package/src/models/ingestSourceOut.ts +12 -0
  34. package/src/models/listResponseDestinationOut.ts +31 -0
  35. package/src/models/mergeConfig.ts +19 -0
  36. package/src/models/mergeConfigOut.ts +15 -0
  37. package/src/models/redshiftConfigIn.ts +14 -2
  38. package/src/models/redshiftConfigOut.ts +7 -1
  39. package/src/models/redshiftConfigPatch.ts +6 -0
  40. package/src/models/rotateSubscriptionIn2.ts +29 -0
  41. package/src/models/s3ConfigIn.ts +1 -1
  42. package/src/models/snsConfigIn.ts +14 -2
  43. package/src/models/snsConfigOut.ts +7 -1
  44. package/src/models/snsConfigPatch.ts +6 -0
  45. package/src/models/sqsConfigIn.ts +14 -2
  46. package/src/models/sqsConfigOut.ts +7 -1
  47. package/src/models/sqsConfigPatch.ts +6 -0
  48. package/src/models/status.ts +16 -0
  49. package/src/models/streamSinkOut.ts +15 -0
  50. package/src/request.ts +1 -1
package/src/autoconfig.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { SvixInternal } from "./api_internal";
2
+ import { AutoconfigSubscription } from "./api_internal/autoconfigSubscription";
2
3
  import { Endpoint as InternalEndpoint } from "./api_internal/endpoint";
3
4
  import type { EndpointIn } from "./models/endpointIn";
4
5
  import type { EndpointOut } from "./models/endpointOut";
@@ -10,14 +11,34 @@ import {
10
11
  } from "./webhook";
11
12
 
12
13
  const AUTOCONFIG_TOKEN_PREFIX_V1 = "auto_v1_";
14
+ const AUTOCONFIG_TOKEN_PREFIX_V2 = "auto_v2_";
15
+
13
16
  const UNSUPPORTED_TOKEN_VERSION =
14
17
  "Unsupported token version. You might need to update the Svix SDK to use this token";
15
18
 
16
19
  export interface AutoConfigTokenContentV1 {
20
+ // Application ID
17
21
  aid: string;
22
+ // Endpoint ID
18
23
  eid: string;
24
+ // Server URL
25
+ surl: string;
26
+ // Endpoint secret
27
+ esec: string;
28
+ // Token
29
+ tok: string;
30
+ }
31
+
32
+ export interface AutoConfigTokenContentV2 {
33
+ // Application ID
34
+ aid: string;
35
+ // Autoconfig ID
36
+ sid: string;
37
+ // Server URL
19
38
  surl: string;
39
+ // Endpoint secret
20
40
  esec: string;
41
+ // Token
21
42
  tok: string;
22
43
  }
23
44
 
@@ -45,66 +66,107 @@ export function isAutoConfigTokenContentV1(
45
66
  );
46
67
  }
47
68
 
48
- export function decodeAutoconfigTokenV1(token: string): AutoConfigTokenContentV1 {
49
- if (!token.startsWith(AUTOCONFIG_TOKEN_PREFIX_V1)) {
50
- throw new AutoConfigError(UNSUPPORTED_TOKEN_VERSION);
69
+ function isAutoConfigTokenContentV2(value: unknown): value is AutoConfigTokenContentV2 {
70
+ if (typeof value !== "object" || value === null) {
71
+ return false;
51
72
  }
52
- const b64 = token.slice(AUTOCONFIG_TOKEN_PREFIX_V1.length);
53
- let json: string;
73
+ const { aid, sid, surl, esec, tok } = value as AutoConfigTokenContentV2;
74
+ return (
75
+ typeof aid === "string" &&
76
+ typeof sid === "string" &&
77
+ typeof surl === "string" &&
78
+ typeof esec === "string" &&
79
+ typeof tok === "string"
80
+ );
81
+ }
54
82
 
55
- try {
56
- json = Buffer.from(b64, "base64").toString("utf8");
57
- } catch {
58
- throw new AutoConfigError();
83
+ function parseTokenPayload(token: string, prefix: string): unknown {
84
+ if (!token.startsWith(prefix)) {
85
+ throw new AutoConfigError(UNSUPPORTED_TOKEN_VERSION);
59
86
  }
60
-
61
- let parsed: unknown;
62
87
  try {
63
- parsed = JSON.parse(json);
88
+ return JSON.parse(Buffer.from(token.slice(prefix.length), "base64").toString("utf8"));
64
89
  } catch {
65
90
  throw new AutoConfigError();
66
91
  }
92
+ }
67
93
 
94
+ export function decodeAutoconfigTokenV1(token: string): AutoConfigTokenContentV1 {
95
+ const parsed = parseTokenPayload(token, AUTOCONFIG_TOKEN_PREFIX_V1);
68
96
  if (!isAutoConfigTokenContentV1(parsed)) {
69
97
  throw new AutoConfigError();
70
98
  }
99
+ return parsed;
100
+ }
71
101
 
102
+ export function decodeAutoconfigTokenV2(token: string): AutoConfigTokenContentV2 {
103
+ const parsed = parseTokenPayload(token, AUTOCONFIG_TOKEN_PREFIX_V2);
104
+ if (!isAutoConfigTokenContentV2(parsed)) {
105
+ throw new AutoConfigError();
106
+ }
72
107
  return parsed;
73
108
  }
74
109
 
110
+ export function decodeAutoconfigToken(
111
+ token: string
112
+ ):
113
+ | { version: "v1"; content: AutoConfigTokenContentV1 }
114
+ | { version: "v2"; content: AutoConfigTokenContentV2 } {
115
+ if (token.startsWith(AUTOCONFIG_TOKEN_PREFIX_V1)) {
116
+ return { version: "v1", content: decodeAutoconfigTokenV1(token) };
117
+ }
118
+ if (token.startsWith(AUTOCONFIG_TOKEN_PREFIX_V2)) {
119
+ return { version: "v2", content: decodeAutoconfigTokenV2(token) };
120
+ }
121
+ throw new AutoConfigError(UNSUPPORTED_TOKEN_VERSION);
122
+ }
123
+
75
124
  export class AutoConfig {
76
125
  private readonly appId: string;
77
- private readonly endpointId: string;
78
- private readonly endpointIn: EndpointIn;
79
126
  private readonly webhook: Webhook;
80
127
  private readonly requestCtx: SvixRequestContext;
128
+ private readonly endpointIn: EndpointIn;
129
+ private readonly endpointId?: string;
130
+ private readonly autoconfigId?: string;
81
131
 
82
132
  public constructor(token: string, endpoint: EndpointIn) {
83
- const content = decodeAutoconfigTokenV1(token);
133
+ const decoded = decodeAutoconfigToken(token);
134
+
84
135
  let webhook: Webhook;
85
136
  try {
86
- webhook = new Webhook(content.esec);
137
+ webhook = new Webhook(decoded.content.esec);
87
138
  } catch {
88
139
  throw new AutoConfigError();
89
140
  }
90
141
 
91
- this.appId = content.aid;
92
- this.endpointId = content.eid;
142
+ this.appId = decoded.content.aid;
93
143
  this.endpointIn = endpoint;
94
144
  this.webhook = webhook;
95
145
 
96
- const svix = new SvixInternal(content.tok, { serverUrl: content.surl });
146
+ if (decoded.version === "v1") {
147
+ this.endpointId = decoded.content.eid;
148
+ } else {
149
+ this.autoconfigId = decoded.content.sid;
150
+ }
151
+
152
+ const svix = new SvixInternal(decoded.content.tok, {
153
+ serverUrl: decoded.content.surl,
154
+ });
97
155
  this.requestCtx = svix.getRequestCtx();
98
156
  }
99
157
 
100
158
  public subscribe(): Promise<EndpointOut> {
101
- return new InternalEndpoint(this.requestCtx).autoConfig.update(
102
- this.appId,
103
- this.endpointId,
104
- {
105
- endpoint: this.endpointIn,
106
- }
107
- );
159
+ const endpoint = new InternalEndpoint(this.requestCtx);
160
+ if (this.autoconfigId != null) {
161
+ return new AutoconfigSubscription(this.requestCtx).endpoint.subscribe(
162
+ this.appId,
163
+ this.autoconfigId,
164
+ this.endpointIn
165
+ );
166
+ }
167
+ return endpoint.autoConfigDeprecated.update(this.appId, this.endpointId as string, {
168
+ endpoint: this.endpointIn,
169
+ });
108
170
  }
109
171
 
110
172
  public verify(
@@ -1,66 +1,112 @@
1
1
  import { SvixInternal } from "./api_internal";
2
+ import { AutoconfigSubscription } from "./api_internal/autoconfigSubscription";
2
3
  import { Endpoint as InternalEndpoint } from "./api_internal/endpoint";
3
4
  import {
4
5
  MessagePollerv2 as InternalMessagePollerv2,
5
6
  type MessagePollerv2ConsumerCommitOptions,
6
7
  type MessagePollerv2ConsumerPollOptions,
7
8
  } from "./api_internal/messagePollerv2";
8
- import { decodeAutoconfigTokenV1 } from "./autoconfig";
9
+ import { decodeAutoconfigToken } from "./autoconfig";
10
+ import type { DestinationIn } from "./models/destinationIn";
11
+ import type { DestinationOut } from "./models/destinationOut";
9
12
  import type { EndpointOut } from "./models/endpointOut";
10
13
  import type { PollerV2PollOut } from "./models/pollerV2PollOut";
11
14
  import type { SinkInCommon } from "./models/sinkInCommon";
15
+ import { DestinationStatus } from "./models/destinationStatus";
12
16
  import type { SvixRequestContext } from "./request";
13
17
 
14
18
  export class AutoConfigConsumer {
15
19
  private readonly appId: string;
16
- private readonly sinkId: string;
17
20
  private readonly sinkIn: SinkInCommon;
18
21
  private readonly requestCtx: SvixRequestContext;
22
+ private sinkId?: string;
23
+ private readonly autoconfigId?: string;
19
24
 
20
25
  public constructor(token: string, sinkIn: SinkInCommon) {
21
- const content = decodeAutoconfigTokenV1(token);
26
+ const decoded = decodeAutoconfigToken(token);
22
27
 
23
- this.appId = content.aid;
24
- this.sinkId = content.eid;
28
+ this.appId = decoded.content.aid;
25
29
  this.sinkIn = sinkIn;
26
30
 
27
- const svix = new SvixInternal(content.tok, { serverUrl: content.surl });
31
+ if (decoded.version === "v1") {
32
+ this.sinkId = decoded.content.eid;
33
+ } else {
34
+ this.autoconfigId = decoded.content.sid;
35
+ }
36
+
37
+ const svix = new SvixInternal(decoded.content.tok, {
38
+ serverUrl: decoded.content.surl,
39
+ });
28
40
  this.requestCtx = svix.getRequestCtx();
29
41
  }
30
42
 
31
- public subscribe(): Promise<EndpointOut> {
32
- return new InternalEndpoint(this.requestCtx).autoConfig.update(
33
- this.appId,
34
- this.sinkId,
35
- {
43
+ public async subscribe(): Promise<DestinationOut> {
44
+ const endpoint = new InternalEndpoint(this.requestCtx);
45
+ if (this.autoconfigId != null) {
46
+ // v2
47
+ const destination = await new AutoconfigSubscription(
48
+ this.requestCtx
49
+ ).destination.subscribe(
50
+ this.appId,
51
+ this.autoconfigId,
52
+ sinkInCommonToPollingDestination(this.sinkIn)
53
+ );
54
+ this.sinkId = destination.id;
55
+ return destination;
56
+ }
57
+
58
+ // v1
59
+ return destinationOutFromV1Endpoint(
60
+ await endpoint.autoConfigDeprecated.update(this.appId, this.sinkId as string, {
36
61
  sink: {
37
62
  type: "poller",
38
63
  config: this.sinkIn,
39
64
  },
40
- }
65
+ })
41
66
  );
42
67
  }
43
68
 
44
- public receive(
69
+ private async getSinkId(): Promise<string> {
70
+ if (this.sinkId != null) {
71
+ // Already have the sink id from subscribe() or the v1 token
72
+ return this.sinkId;
73
+ }
74
+
75
+ // Get the sink id from the autoconfig id (v2)
76
+ const destId = (
77
+ await new AutoconfigSubscription(this.requestCtx).get(
78
+ this.appId,
79
+ this.autoconfigId as string
80
+ )
81
+ ).destId;
82
+ if (destId == null) {
83
+ throw new Error("autoconfig subscription is pending. Have you called subscribe()?");
84
+ }
85
+ return destId;
86
+ }
87
+
88
+ public async receive(
45
89
  consumerId: string,
46
90
  options?: MessagePollerv2ConsumerPollOptions
47
91
  ): Promise<PollerV2PollOut> {
92
+ const sinkId = await this.getSinkId();
48
93
  return new InternalMessagePollerv2(this.requestCtx).consumerPoll(
49
94
  this.appId,
50
- this.sinkId,
95
+ sinkId,
51
96
  consumerId,
52
97
  options
53
98
  );
54
99
  }
55
100
 
56
- public commit(
101
+ public async commit(
57
102
  consumerId: string,
58
103
  offset: number,
59
104
  options?: MessagePollerv2ConsumerCommitOptions
60
105
  ): Promise<void> {
106
+ const sinkId = await this.getSinkId();
61
107
  return new InternalMessagePollerv2(this.requestCtx).consumerCommit(
62
108
  this.appId,
63
- this.sinkId,
109
+ sinkId,
64
110
  consumerId,
65
111
  {
66
112
  offset,
@@ -69,3 +115,31 @@ export class AutoConfigConsumer {
69
115
  );
70
116
  }
71
117
  }
118
+
119
+ function sinkInCommonToPollingDestination(sink: SinkInCommon): DestinationIn {
120
+ return {
121
+ type: "pollingEndpoint",
122
+ eventTypes: sink.eventTypes ?? undefined,
123
+ channels: sink.channels ?? undefined,
124
+ metadata: sink.metadata,
125
+ uid: sink.uid,
126
+ };
127
+ }
128
+
129
+ function destinationOutFromV1Endpoint(endpoint: EndpointOut): DestinationOut {
130
+ return {
131
+ id: endpoint.id,
132
+ uid: endpoint.uid,
133
+ status: endpoint.disabled ? DestinationStatus.Disabled : DestinationStatus.Enabled,
134
+ currentIterator: "",
135
+ createdAt: endpoint.createdAt,
136
+ updatedAt: endpoint.updatedAt,
137
+ batchSize: 0,
138
+ maxWaitSecs: 0,
139
+ eventTypes: endpoint.eventTypes ?? undefined,
140
+ channels: endpoint.channels ?? undefined,
141
+ metadata: endpoint.metadata,
142
+ type: "pollingEndpoint",
143
+ config: {},
144
+ };
145
+ }
package/src/index.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  // this file is @generated
2
2
  import { Application } from "./api/application";
3
3
  import { Authentication } from "./api/authentication";
4
+ import { AutoconfigSubscription } from "./api/autoconfigSubscription";
4
5
  import { BackgroundTask } from "./api/backgroundTask";
5
6
  import { Connector } from "./api/connector";
7
+ import { Destination } from "./api/destination";
6
8
  import { Endpoint } from "./api/endpoint";
7
9
  import { Environment } from "./api/environment";
8
10
  import { EventType } from "./api/eventType";
@@ -69,6 +71,10 @@ export class Svix {
69
71
  return new Authentication(this.requestCtx);
70
72
  }
71
73
 
74
+ public get autoconfigSubscription() {
75
+ return new AutoconfigSubscription(this.requestCtx);
76
+ }
77
+
72
78
  public get backgroundTask() {
73
79
  return new BackgroundTask(this.requestCtx);
74
80
  }
@@ -77,6 +83,10 @@ export class Svix {
77
83
  return new Connector(this.requestCtx);
78
84
  }
79
85
 
86
+ public get destination() {
87
+ return new Destination(this.requestCtx);
88
+ }
89
+
80
90
  public get endpoint() {
81
91
  return new Endpoint(this.requestCtx);
82
92
  }
@@ -0,0 +1,26 @@
1
+ // this file is @generated
2
+
3
+ export interface AutoConfigOut {
4
+ createdAt: Date;
5
+ token: string;
6
+ /** The AutoConfigSubscription's ID. */
7
+ id: string;
8
+ }
9
+
10
+ export const AutoConfigOutSerializer = {
11
+ _fromJsonObject(object: any): AutoConfigOut {
12
+ return {
13
+ createdAt: new Date(object["createdAt"]),
14
+ token: object["token"],
15
+ id: object["id"],
16
+ };
17
+ },
18
+
19
+ _toJsonObject(self: AutoConfigOut): any {
20
+ return {
21
+ createdAt: self.createdAt,
22
+ token: self.token,
23
+ id: self.id,
24
+ };
25
+ },
26
+ };
@@ -0,0 +1,38 @@
1
+ // this file is @generated
2
+ import { type Status, StatusSerializer } from "./status";
3
+
4
+ export interface AutoConfigSubscriptionOut {
5
+ createdAt: Date;
6
+ tokenCensored: string;
7
+ /** The AutoConfigSubscription's ID. */
8
+ id: string;
9
+ /** The Endpoint's ID. */
10
+ endpId?: string | null;
11
+ /** The StreamSink's ID. */
12
+ destId?: string | null;
13
+ status: Status;
14
+ }
15
+
16
+ export const AutoConfigSubscriptionOutSerializer = {
17
+ _fromJsonObject(object: any): AutoConfigSubscriptionOut {
18
+ return {
19
+ createdAt: new Date(object["createdAt"]),
20
+ tokenCensored: object["tokenCensored"],
21
+ id: object["id"],
22
+ endpId: object["endpId"],
23
+ destId: object["destId"],
24
+ status: StatusSerializer._fromJsonObject(object["status"]),
25
+ };
26
+ },
27
+
28
+ _toJsonObject(self: AutoConfigSubscriptionOut): any {
29
+ return {
30
+ createdAt: self.createdAt,
31
+ tokenCensored: self.tokenCensored,
32
+ id: self.id,
33
+ endpId: self.endpId,
34
+ destId: self.destId,
35
+ status: StatusSerializer._toJsonObject(self.status),
36
+ };
37
+ },
38
+ };