@smplcty/dev-backend 0.1.2 → 0.2.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.
package/dist/config.d.ts CHANGED
@@ -5,6 +5,10 @@ export interface RouteConfig {
5
5
  * Overrides values from the base envFile. Useful when handlers
6
6
  * need different DATABASE_URL values. */
7
7
  envFile?: string;
8
+ /** Optional authorizer module path. If set, the authorizer is
9
+ * called before the handler on every request. If it returns
10
+ * `{ isAuthorized: false }`, the request is rejected with 403. */
11
+ authorizer?: string;
8
12
  }
9
13
  export interface Config {
10
14
  /** HTTP port. Default 4000. */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB;;8CAE0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AAUD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAiCrD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB;;8CAE0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;uEAEmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AAUD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAkCrD"}
package/dist/config.js CHANGED
@@ -27,6 +27,7 @@ export function loadConfig(configPath) {
27
27
  routes[path] = {
28
28
  handler: resolve(dir, entry.handler),
29
29
  envFile: entry.envFile ? resolve(dir, entry.envFile) : undefined,
30
+ authorizer: entry.authorizer ? resolve(dir, entry.authorizer) : undefined,
30
31
  };
31
32
  }
32
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4B7C;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,GAAc,CAAC;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAc,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,KAAK,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,MAAM,GAAgC,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,GAAG;gBACb,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;gBACpC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;aACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,IAAI,cAAc,CAAC;QACpD,MAAM;KACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgC7C;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,GAAc,CAAC;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAc,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,KAAK,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,MAAM,GAAgC,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,GAAG;gBACb,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;gBACpC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;gBAChE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;aAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,IAAI,cAAc,CAAC;QACpD,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -1,13 +1,20 @@
1
1
  import type { RouteConfig } from './config.js';
2
2
  export type Handler = (event: Record<string, unknown>) => Promise<{
3
3
  statusCode: number;
4
- body?: string;
4
+ body?: string | Record<string, unknown>;
5
5
  headers?: Record<string, string>;
6
6
  }>;
7
+ export type Authorizer = (event: Record<string, unknown>) => Promise<{
8
+ isAuthorized: boolean;
9
+ }>;
10
+ export interface LoadedRoute {
11
+ handler: Handler;
12
+ authorizer?: Authorizer;
13
+ }
7
14
  /**
8
- * Import all handler modules. For routes with a per-route envFile,
9
- * temporarily override process.env before importing so the handler's
10
- * module-level init (e.g. Pool creation) picks up the right values.
15
+ * Import all handler modules (and optional authorizers). For routes
16
+ * with a per-route envFile, temporarily override process.env before
17
+ * importing so the handler's module-level init picks up the right values.
11
18
  */
12
- export declare function loadHandlers(routes: Record<string, RouteConfig>): Promise<Record<string, Handler>>;
19
+ export declare function loadHandlers(routes: Record<string, RouteConfig>): Promise<Record<string, LoadedRoute>>;
13
20
  //# sourceMappingURL=handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA6ClC"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IACnE,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CA4DtC"}
package/dist/handlers.js CHANGED
@@ -2,14 +2,13 @@ import { readFileSync, existsSync } from 'node:fs';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { loadEnvFile } from './env.js';
4
4
  /**
5
- * Import all handler modules. For routes with a per-route envFile,
6
- * temporarily override process.env before importing so the handler's
7
- * module-level init (e.g. Pool creation) picks up the right values.
5
+ * Import all handler modules (and optional authorizers). For routes
6
+ * with a per-route envFile, temporarily override process.env before
7
+ * importing so the handler's module-level init picks up the right values.
8
8
  */
9
9
  export async function loadHandlers(routes) {
10
- const handlers = {};
10
+ const loaded = {};
11
11
  for (const [path, route] of Object.entries(routes)) {
12
- // Snapshot env vars that the route's envFile might override
13
12
  const overrides = new Map();
14
13
  if (route.envFile) {
15
14
  const keys = readEnvKeys(route.envFile);
@@ -26,8 +25,18 @@ export async function loadHandlers(routes) {
26
25
  console.error(` ${path}: ${route.handler} does not export a handler function — skipping`);
27
26
  continue;
28
27
  }
29
- handlers[path] = handler;
30
- console.log(` ${path} → ${route.handler}`);
28
+ let authorizer;
29
+ if (route.authorizer) {
30
+ const authMod = (await import(pathToFileURL(route.authorizer).href));
31
+ authorizer = authMod.handler;
32
+ if (typeof authorizer !== 'function') {
33
+ console.error(` ${path}: ${route.authorizer} does not export a handler function — skipping authorizer`);
34
+ authorizer = undefined;
35
+ }
36
+ }
37
+ loaded[path] = { handler, authorizer };
38
+ const suffix = authorizer ? ' (with authorizer)' : '';
39
+ console.log(` ${path} → ${route.handler}${suffix}`);
31
40
  }
32
41
  catch (err) {
33
42
  console.error(` ${path}: failed to import ${route.handler}:`, err);
@@ -44,7 +53,7 @@ export async function loadHandlers(routes) {
44
53
  }
45
54
  }
46
55
  }
47
- return handlers;
56
+ return loaded;
48
57
  }
49
58
  /**
50
59
  * Parse an env file to extract just the key names.
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { loadConfig, type Config, type RouteConfig } from './config.js';
2
2
  export { loadEnvFile } from './env.js';
3
- export { loadHandlers, type Handler } from './handlers.js';
3
+ export { loadHandlers, type Handler, type Authorizer, type LoadedRoute } from './handlers.js';
4
4
  export { startServer } from './server.js';
5
5
  export { buildEvent, decompressResponse } from './event.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiC,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAgB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiC,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAmD,MAAM,eAAe,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { Handler } from './handlers.js';
1
+ import type { LoadedRoute } from './handlers.js';
2
2
  /**
3
3
  * Start the HTTP server that routes requests to Lambda handlers.
4
4
  */
5
- export declare function startServer(handlers: Record<string, Handler>, port: number): void;
5
+ export declare function startServer(routes: Record<string, LoadedRoute>, port: number): void;
6
6
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C;;GAEG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,EAAE,MAAM,GACX,IAAI,CAkDN"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACnC,IAAI,EAAE,MAAM,GACX,IAAI,CAsEN"}
package/dist/server.js CHANGED
@@ -3,7 +3,7 @@ import { buildEvent, decompressResponse } from './event.js';
3
3
  /**
4
4
  * Start the HTTP server that routes requests to Lambda handlers.
5
5
  */
6
- export function startServer(handlers, port) {
6
+ export function startServer(routes, port) {
7
7
  const server = createServer(async (req, res) => {
8
8
  const url = req.url ?? '/';
9
9
  const [rawPath, query] = url.replace('//', '/').split('?');
@@ -15,8 +15,8 @@ export function startServer(handlers, port) {
15
15
  res.end();
16
16
  return;
17
17
  }
18
- const handler = handlers[rawPath];
19
- if (!handler) {
18
+ const route = routes[rawPath];
19
+ if (!route) {
20
20
  setCorsHeaders(res);
21
21
  res.statusCode = 404;
22
22
  res.setHeader('Content-Type', 'application/json');
@@ -25,11 +25,27 @@ export function startServer(handlers, port) {
25
25
  }
26
26
  try {
27
27
  const event = await buildEvent(req, rawPath, query);
28
- const response = await handler(event);
28
+ // Run authorizer if configured
29
+ if (route.authorizer) {
30
+ const { isAuthorized } = await route.authorizer(event);
31
+ if (!isAuthorized) {
32
+ setCorsHeaders(res);
33
+ res.statusCode = 403;
34
+ res.setHeader('Content-Type', 'application/json');
35
+ res.end(JSON.stringify({ message: 'Forbidden' }));
36
+ return;
37
+ }
38
+ }
39
+ const response = await route.handler(event);
29
40
  setCorsHeaders(res);
30
41
  res.statusCode = response.statusCode;
31
42
  res.setHeader('Content-Type', 'application/json');
32
43
  let body = response.body ?? '';
44
+ // Auto-stringify object bodies — some handlers return body as
45
+ // an object expecting API Gateway to serialize it.
46
+ if (typeof body !== 'string') {
47
+ body = JSON.stringify(body);
48
+ }
33
49
  if (response.headers?.['Content-Encoding'] === 'gzip') {
34
50
  body = decompressResponse(body);
35
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smplcty/dev-backend",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Local Lambda dev server — reads a routes config, loads .env, serves Lambda handlers over HTTP with API Gateway v2 event translation.",
5
5
  "license": "MIT",
6
6
  "type": "module",