sst-http 0.1.6 → 0.2.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.
package/README.md CHANGED
@@ -97,7 +97,7 @@ Mark a route with `@FirebaseAuth()` and the manifest records it as protected. Th
97
97
 
98
98
  ## Wire API Gateway
99
99
 
100
- `sst-http/infra` ships with a manifest-driven wiring utility plus adapters for HTTP API (ApiGatewayV2) and REST API (ApiGateway). The example below uses the HTTP API adapter inside `sst.config.ts`.
100
+ `sst-http/infra` ships with a manifest-driven wiring utility plus adapters for HTTP API (ApiGatewayV2) and REST API (ApiGateway). The example below wires all routes to a single Lambda function inside `sst.config.ts`.
101
101
 
102
102
  ```ts
103
103
  // sst.config.ts
@@ -113,23 +113,18 @@ export default $config({
113
113
  } = await import("sst-http/infra");
114
114
 
115
115
  const manifest = loadRoutesManifest("routes.manifest.json");
116
- const { api, registerRoute, ensureJwtAuthorizer } = httpApiAdapter({
117
- apiName: "Api",
118
- apiArgs: {
119
- transform: {
120
- route: {
121
- handler: {
122
- runtime: "nodejs20.x",
123
- timeout: "10 seconds",
124
- memory: "512 MB",
125
- },
126
- },
127
- },
128
- },
116
+ const { api, registerRoute, ensureJwtAuthorizer } = httpApiAdapter({ apiName: "Api" });
117
+
118
+ // Single Lambda for all routes
119
+ const handler = new sst.aws.Function("Handler", {
120
+ handler: "src/server.handler",
121
+ runtime: "nodejs20.x",
122
+ timeout: "10 seconds",
123
+ memory: "512 MB",
129
124
  });
130
125
 
131
126
  wireApiFromManifest(manifest, {
132
- handlerFile: "src/server.handler",
127
+ handler,
133
128
  firebaseProjectId: process.env.FIREBASE_PROJECT_ID!,
134
129
  registerRoute,
135
130
  ensureJwtAuthorizer,
@@ -142,6 +137,9 @@ export default $config({
142
137
 
143
138
  Swap in `restApiAdapter` if you prefer API Gateway REST APIs—the wiring contract is identical.
144
139
 
140
+ > Tip
141
+ > Set `FIREBASE_PROJECT_ID` in your environment when using `@FirebaseAuth()` so the JWT authorizer is configured correctly.
142
+
145
143
  ## Publishing
146
144
 
147
145
  ```bash
package/dist/infra.cjs CHANGED
@@ -66,7 +66,7 @@ function wireApiFromManifest(manifest, opts) {
66
66
  ref: firebaseAuthorizerRef
67
67
  } : void 0;
68
68
  opts.registerRoute(route.method, path, {
69
- handler: opts.handlerFile,
69
+ handler: opts.handler,
70
70
  protected: isProtected,
71
71
  authorizer: authConfig
72
72
  });
@@ -90,25 +90,34 @@ function httpApiAdapter(args) {
90
90
  return authorizers.get(name);
91
91
  }
92
92
  const apiAny = api;
93
- let ref = name;
94
- const payload = {
95
- type: "jwt",
96
- jwt: {
97
- issuer: cfg.issuer,
98
- audience: cfg.audiences
99
- }
100
- };
101
- if (typeof apiAny.addAuthorizers === "function") {
93
+ let ref = void 0;
94
+ if (typeof apiAny["addAuthorizer"] === "function") {
95
+ const created = apiAny.addAuthorizer({
96
+ name,
97
+ jwt: { issuer: cfg.issuer, audiences: cfg.audiences }
98
+ });
99
+ ref = created.id;
100
+ } else if (typeof apiAny.addAuthorizers === "function") {
102
101
  apiAny.addAuthorizers({
103
- [name]: payload
102
+ [name]: {
103
+ type: "jwt",
104
+ jwt: {
105
+ issuer: cfg.issuer,
106
+ audience: cfg.audiences
107
+ }
108
+ }
104
109
  });
110
+ ref = name;
105
111
  } else if (typeof apiAny.authorizer === "function") {
106
- ref = apiAny.authorizer(name, payload);
112
+ ref = apiAny.authorizer(name, {
113
+ type: "jwt",
114
+ jwt: {
115
+ issuer: cfg.issuer,
116
+ audience: cfg.audiences
117
+ }
118
+ });
107
119
  } else {
108
- apiAny.authorizers = {
109
- ...apiAny.authorizers ?? {},
110
- [name]: payload
111
- };
120
+ throw new Error("ApiGatewayV2 instance does not support authorizers");
112
121
  }
113
122
  authorizers.set(name, ref);
114
123
  return ref;
@@ -116,31 +125,34 @@ function httpApiAdapter(args) {
116
125
  const registerRoute = (method, path, config) => {
117
126
  const apiAny = api;
118
127
  const routeKey = `${method} ${path}`;
119
- const routeConfig = {
120
- handler: config.handler
121
- };
128
+ const asAny = config.handler;
129
+ const handlerInput = typeof asAny === "string" ? asAny : asAny && typeof asAny.arn !== "undefined" ? asAny.arn : asAny && typeof asAny.handler === "string" ? asAny.handler : asAny === void 0 ? void 0 : (() => {
130
+ throw new Error("Unsupported handler type: provide a handler string, FunctionArgs, or a Function ARN/output");
131
+ })();
132
+ const args2 = {};
122
133
  if (config.protected && config.authorizer) {
123
- routeConfig.authorizer = config.authorizer.ref ?? config.authorizer.name;
124
- routeConfig.authorizationType = "JWT";
125
- if (config.authorizer.roles && config.authorizer.roles.length > 0) {
126
- routeConfig.authorizationScopes = config.authorizer.roles;
127
- }
128
- if (config.authorizer.optional) {
129
- routeConfig.authorizerOptional = true;
130
- }
134
+ args2.auth = {
135
+ jwt: {
136
+ authorizer: config.authorizer.ref ?? config.authorizer.name,
137
+ scopes: config.authorizer.roles
138
+ }
139
+ };
131
140
  }
132
141
  if (typeof apiAny.route === "function") {
133
- apiAny.route(routeKey, routeConfig);
142
+ apiAny.route(routeKey, handlerInput, args2);
134
143
  return;
135
144
  }
136
145
  if (typeof apiAny.addRoutes === "function") {
137
146
  apiAny.addRoutes({
138
- [routeKey]: routeConfig
147
+ [routeKey]: {
148
+ handler: handlerInput,
149
+ ...args2
150
+ }
139
151
  });
140
152
  return;
141
153
  }
142
154
  if (typeof apiAny.addRoute === "function") {
143
- apiAny.addRoute(routeKey, routeConfig);
155
+ apiAny.addRoute(routeKey, { handler: handlerInput, ...args2 });
144
156
  return;
145
157
  }
146
158
  throw new Error("Unsupported ApiGatewayV2 instance: expected route() or addRoutes() method.");
@@ -186,31 +198,34 @@ function restApiAdapter(args) {
186
198
  const registerRoute = (method, path, config) => {
187
199
  const apiAny = api;
188
200
  const routeKey = `${method} ${path}`;
189
- const routeConfig = {
190
- handler: config.handler
191
- };
201
+ const asAny = config.handler;
202
+ const handlerInput = typeof asAny === "string" ? asAny : asAny && typeof asAny.arn !== "undefined" ? asAny.arn : asAny && typeof asAny.handler === "string" ? asAny.handler : asAny === void 0 ? void 0 : (() => {
203
+ throw new Error("Unsupported handler type: provide a handler string, FunctionArgs, or a Function ARN/output");
204
+ })();
205
+ const args2 = {};
192
206
  if (config.protected && config.authorizer) {
193
- routeConfig.authorizer = config.authorizer.ref ?? config.authorizer.name;
194
- routeConfig.authorizationType = "JWT";
195
- if (config.authorizer.roles && config.authorizer.roles.length > 0) {
196
- routeConfig.authorizationScopes = config.authorizer.roles;
197
- }
198
- if (config.authorizer.optional) {
199
- routeConfig.authorizerOptional = true;
200
- }
207
+ args2.auth = {
208
+ jwt: {
209
+ authorizer: config.authorizer.ref ?? config.authorizer.name,
210
+ scopes: config.authorizer.roles
211
+ }
212
+ };
201
213
  }
202
214
  if (typeof apiAny.route === "function") {
203
- apiAny.route(routeKey, routeConfig);
215
+ apiAny.route(routeKey, handlerInput, args2);
204
216
  return;
205
217
  }
206
218
  if (typeof apiAny.addRoutes === "function") {
207
219
  apiAny.addRoutes({
208
- [routeKey]: routeConfig
220
+ [routeKey]: {
221
+ handler: handlerInput,
222
+ ...args2
223
+ }
209
224
  });
210
225
  return;
211
226
  }
212
227
  if (typeof apiAny.addRoute === "function") {
213
- apiAny.addRoute(routeKey, routeConfig);
228
+ apiAny.addRoute(routeKey, { handler: handlerInput, ...args2 });
214
229
  return;
215
230
  }
216
231
  throw new Error("Unsupported ApiGateway instance: expected route() or addRoutes() method.");
package/dist/infra.d.cts CHANGED
@@ -2,15 +2,7 @@ import { H as HttpMethod, R as RoutesManifest } from './types-D69iuoxv.cjs';
2
2
  export { b as RoutesManifestAuth, a as RoutesManifestRoute } from './types-D69iuoxv.cjs';
3
3
  import 'aws-lambda';
4
4
 
5
- type SstApiGateway = {
6
- route?: (routeKey: string, config: Record<string, unknown>) => unknown;
7
- addRoutes?: (routes: Record<string, Record<string, unknown>>) => unknown;
8
- addRoute?: (routeKey: string, config: Record<string, unknown>) => unknown;
9
- addAuthorizers?: (authorizers: Record<string, unknown>) => unknown;
10
- authorizer?: (name: string, payload: unknown) => unknown;
11
- authorizers?: Record<string, unknown>;
12
- url?: string;
13
- };
5
+ type SstApiGateway = any;
14
6
  type SstAwsNamespace = {
15
7
  ApiGatewayV2: new (name: string, args?: unknown, opts?: unknown) => SstApiGateway;
16
8
  ApiGateway: new (name: string, args?: unknown, opts?: unknown) => SstApiGateway;
@@ -21,7 +13,7 @@ type AwsSource = {
21
13
  };
22
14
  };
23
15
  type RegisterRouteConfig = {
24
- handler: string;
16
+ handler: unknown;
25
17
  protected: boolean;
26
18
  authorizer?: {
27
19
  name: string;
@@ -36,7 +28,7 @@ type EnsureJwtAuthorizer = (name: string, cfg: {
36
28
  audiences: string[];
37
29
  }) => unknown;
38
30
  declare function wireApiFromManifest(manifest: RoutesManifest, opts: {
39
- handlerFile: string;
31
+ handler: unknown;
40
32
  firebaseProjectId: string;
41
33
  registerRoute: RegisterRoute;
42
34
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
@@ -48,12 +40,12 @@ type AdapterArgs = AwsSource & {
48
40
  apiArgs?: unknown;
49
41
  };
50
42
  declare function httpApiAdapter(args?: AdapterArgs): {
51
- api: SstApiGateway;
43
+ api: any;
52
44
  registerRoute: RegisterRoute;
53
45
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
54
46
  };
55
47
  declare function restApiAdapter(args?: AdapterArgs): {
56
- api: SstApiGateway;
48
+ api: any;
57
49
  registerRoute: RegisterRoute;
58
50
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
59
51
  };
package/dist/infra.d.ts CHANGED
@@ -2,15 +2,7 @@ import { H as HttpMethod, R as RoutesManifest } from './types-D69iuoxv.js';
2
2
  export { b as RoutesManifestAuth, a as RoutesManifestRoute } from './types-D69iuoxv.js';
3
3
  import 'aws-lambda';
4
4
 
5
- type SstApiGateway = {
6
- route?: (routeKey: string, config: Record<string, unknown>) => unknown;
7
- addRoutes?: (routes: Record<string, Record<string, unknown>>) => unknown;
8
- addRoute?: (routeKey: string, config: Record<string, unknown>) => unknown;
9
- addAuthorizers?: (authorizers: Record<string, unknown>) => unknown;
10
- authorizer?: (name: string, payload: unknown) => unknown;
11
- authorizers?: Record<string, unknown>;
12
- url?: string;
13
- };
5
+ type SstApiGateway = any;
14
6
  type SstAwsNamespace = {
15
7
  ApiGatewayV2: new (name: string, args?: unknown, opts?: unknown) => SstApiGateway;
16
8
  ApiGateway: new (name: string, args?: unknown, opts?: unknown) => SstApiGateway;
@@ -21,7 +13,7 @@ type AwsSource = {
21
13
  };
22
14
  };
23
15
  type RegisterRouteConfig = {
24
- handler: string;
16
+ handler: unknown;
25
17
  protected: boolean;
26
18
  authorizer?: {
27
19
  name: string;
@@ -36,7 +28,7 @@ type EnsureJwtAuthorizer = (name: string, cfg: {
36
28
  audiences: string[];
37
29
  }) => unknown;
38
30
  declare function wireApiFromManifest(manifest: RoutesManifest, opts: {
39
- handlerFile: string;
31
+ handler: unknown;
40
32
  firebaseProjectId: string;
41
33
  registerRoute: RegisterRoute;
42
34
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
@@ -48,12 +40,12 @@ type AdapterArgs = AwsSource & {
48
40
  apiArgs?: unknown;
49
41
  };
50
42
  declare function httpApiAdapter(args?: AdapterArgs): {
51
- api: SstApiGateway;
43
+ api: any;
52
44
  registerRoute: RegisterRoute;
53
45
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
54
46
  };
55
47
  declare function restApiAdapter(args?: AdapterArgs): {
56
- api: SstApiGateway;
48
+ api: any;
57
49
  registerRoute: RegisterRoute;
58
50
  ensureJwtAuthorizer: EnsureJwtAuthorizer;
59
51
  };
package/dist/infra.js CHANGED
@@ -39,7 +39,7 @@ function wireApiFromManifest(manifest, opts) {
39
39
  ref: firebaseAuthorizerRef
40
40
  } : void 0;
41
41
  opts.registerRoute(route.method, path, {
42
- handler: opts.handlerFile,
42
+ handler: opts.handler,
43
43
  protected: isProtected,
44
44
  authorizer: authConfig
45
45
  });
@@ -63,25 +63,34 @@ function httpApiAdapter(args) {
63
63
  return authorizers.get(name);
64
64
  }
65
65
  const apiAny = api;
66
- let ref = name;
67
- const payload = {
68
- type: "jwt",
69
- jwt: {
70
- issuer: cfg.issuer,
71
- audience: cfg.audiences
72
- }
73
- };
74
- if (typeof apiAny.addAuthorizers === "function") {
66
+ let ref = void 0;
67
+ if (typeof apiAny["addAuthorizer"] === "function") {
68
+ const created = apiAny.addAuthorizer({
69
+ name,
70
+ jwt: { issuer: cfg.issuer, audiences: cfg.audiences }
71
+ });
72
+ ref = created.id;
73
+ } else if (typeof apiAny.addAuthorizers === "function") {
75
74
  apiAny.addAuthorizers({
76
- [name]: payload
75
+ [name]: {
76
+ type: "jwt",
77
+ jwt: {
78
+ issuer: cfg.issuer,
79
+ audience: cfg.audiences
80
+ }
81
+ }
77
82
  });
83
+ ref = name;
78
84
  } else if (typeof apiAny.authorizer === "function") {
79
- ref = apiAny.authorizer(name, payload);
85
+ ref = apiAny.authorizer(name, {
86
+ type: "jwt",
87
+ jwt: {
88
+ issuer: cfg.issuer,
89
+ audience: cfg.audiences
90
+ }
91
+ });
80
92
  } else {
81
- apiAny.authorizers = {
82
- ...apiAny.authorizers ?? {},
83
- [name]: payload
84
- };
93
+ throw new Error("ApiGatewayV2 instance does not support authorizers");
85
94
  }
86
95
  authorizers.set(name, ref);
87
96
  return ref;
@@ -89,31 +98,34 @@ function httpApiAdapter(args) {
89
98
  const registerRoute = (method, path, config) => {
90
99
  const apiAny = api;
91
100
  const routeKey = `${method} ${path}`;
92
- const routeConfig = {
93
- handler: config.handler
94
- };
101
+ const asAny = config.handler;
102
+ const handlerInput = typeof asAny === "string" ? asAny : asAny && typeof asAny.arn !== "undefined" ? asAny.arn : asAny && typeof asAny.handler === "string" ? asAny.handler : asAny === void 0 ? void 0 : (() => {
103
+ throw new Error("Unsupported handler type: provide a handler string, FunctionArgs, or a Function ARN/output");
104
+ })();
105
+ const args2 = {};
95
106
  if (config.protected && config.authorizer) {
96
- routeConfig.authorizer = config.authorizer.ref ?? config.authorizer.name;
97
- routeConfig.authorizationType = "JWT";
98
- if (config.authorizer.roles && config.authorizer.roles.length > 0) {
99
- routeConfig.authorizationScopes = config.authorizer.roles;
100
- }
101
- if (config.authorizer.optional) {
102
- routeConfig.authorizerOptional = true;
103
- }
107
+ args2.auth = {
108
+ jwt: {
109
+ authorizer: config.authorizer.ref ?? config.authorizer.name,
110
+ scopes: config.authorizer.roles
111
+ }
112
+ };
104
113
  }
105
114
  if (typeof apiAny.route === "function") {
106
- apiAny.route(routeKey, routeConfig);
115
+ apiAny.route(routeKey, handlerInput, args2);
107
116
  return;
108
117
  }
109
118
  if (typeof apiAny.addRoutes === "function") {
110
119
  apiAny.addRoutes({
111
- [routeKey]: routeConfig
120
+ [routeKey]: {
121
+ handler: handlerInput,
122
+ ...args2
123
+ }
112
124
  });
113
125
  return;
114
126
  }
115
127
  if (typeof apiAny.addRoute === "function") {
116
- apiAny.addRoute(routeKey, routeConfig);
128
+ apiAny.addRoute(routeKey, { handler: handlerInput, ...args2 });
117
129
  return;
118
130
  }
119
131
  throw new Error("Unsupported ApiGatewayV2 instance: expected route() or addRoutes() method.");
@@ -159,31 +171,34 @@ function restApiAdapter(args) {
159
171
  const registerRoute = (method, path, config) => {
160
172
  const apiAny = api;
161
173
  const routeKey = `${method} ${path}`;
162
- const routeConfig = {
163
- handler: config.handler
164
- };
174
+ const asAny = config.handler;
175
+ const handlerInput = typeof asAny === "string" ? asAny : asAny && typeof asAny.arn !== "undefined" ? asAny.arn : asAny && typeof asAny.handler === "string" ? asAny.handler : asAny === void 0 ? void 0 : (() => {
176
+ throw new Error("Unsupported handler type: provide a handler string, FunctionArgs, or a Function ARN/output");
177
+ })();
178
+ const args2 = {};
165
179
  if (config.protected && config.authorizer) {
166
- routeConfig.authorizer = config.authorizer.ref ?? config.authorizer.name;
167
- routeConfig.authorizationType = "JWT";
168
- if (config.authorizer.roles && config.authorizer.roles.length > 0) {
169
- routeConfig.authorizationScopes = config.authorizer.roles;
170
- }
171
- if (config.authorizer.optional) {
172
- routeConfig.authorizerOptional = true;
173
- }
180
+ args2.auth = {
181
+ jwt: {
182
+ authorizer: config.authorizer.ref ?? config.authorizer.name,
183
+ scopes: config.authorizer.roles
184
+ }
185
+ };
174
186
  }
175
187
  if (typeof apiAny.route === "function") {
176
- apiAny.route(routeKey, routeConfig);
188
+ apiAny.route(routeKey, handlerInput, args2);
177
189
  return;
178
190
  }
179
191
  if (typeof apiAny.addRoutes === "function") {
180
192
  apiAny.addRoutes({
181
- [routeKey]: routeConfig
193
+ [routeKey]: {
194
+ handler: handlerInput,
195
+ ...args2
196
+ }
182
197
  });
183
198
  return;
184
199
  }
185
200
  if (typeof apiAny.addRoute === "function") {
186
- apiAny.addRoute(routeKey, routeConfig);
201
+ apiAny.addRoute(routeKey, { handler: handlerInput, ...args2 });
187
202
  return;
188
203
  }
189
204
  throw new Error("Unsupported ApiGateway instance: expected route() or addRoutes() method.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst-http",
3
- "version": "0.1.6",
3
+ "version": "0.2.1",
4
4
  "description": "Decorator-based routing for SST v3 with a single Lambda and Firebase JWT authorizer.",
5
5
  "license": "MIT",
6
6
  "author": "",