@arinoto/cdk-arch 0.2.1 → 0.4.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.
@@ -1,21 +1,48 @@
1
1
  import { Construct } from 'constructs';
2
2
  import { Function } from './function';
3
- export interface ApiRoutes {
4
- [name: string]: RouteEntry;
5
- }
6
- export interface RouteEntry {
3
+ /**
4
+ * A route entry that captures the handler's argument and return types.
5
+ */
6
+ export interface RouteEntry<TArgs extends any[] = any[], TReturn = any> {
7
7
  path: string;
8
- handler: Function;
8
+ handler: Function<TArgs, TReturn>;
9
9
  }
10
10
  /**
11
- * Represents an API container that routes requests to functions
11
+ * Base type for route definitions - maps route names to route entries.
12
+ */
13
+ export type ApiRoutes = {
14
+ [name: string]: RouteEntry;
15
+ };
16
+ /**
17
+ * Extract the handler signature from a Function type.
18
+ */
19
+ export type HandlerOf<T> = T extends Function<infer Args, infer Return> ? (...args: Args) => Promise<Return> : never;
20
+ /**
21
+ * Extract handler signatures from all routes in an ApiRoutes type.
22
+ */
23
+ export type RouteHandlers<TRoutes extends ApiRoutes> = {
24
+ [K in keyof TRoutes]: HandlerOf<TRoutes[K]['handler']>;
25
+ };
26
+ /**
27
+ * Represents an API container that routes requests to functions.
28
+ *
29
+ * @typeParam TRoutes - The type of the routes object, preserving route names and handler signatures.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const api = new ApiContainer(arch, 'api', {
34
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
35
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
36
+ * });
37
+ * // api has type ApiContainer<{ hello: RouteEntry<[string], string>, hellos: RouteEntry<[], Greeting[]> }>
38
+ * ```
12
39
  */
13
- export declare class ApiContainer extends Construct {
14
- readonly routes: ApiRoutes;
15
- constructor(scope: Construct, id: string, routes?: ApiRoutes);
16
- addRoute(name: string, path: string, handler: Function): void;
17
- getRoute(name: string): RouteEntry;
18
- listRoutes(): string[];
40
+ export declare class ApiContainer<TRoutes extends ApiRoutes = ApiRoutes> extends Construct {
41
+ readonly routes: TRoutes;
42
+ constructor(scope: Construct, id: string, routes?: TRoutes);
43
+ addRoute<TArgs extends any[], TReturn>(name: string, path: string, handler: Function<TArgs, TReturn>): void;
44
+ getRoute<K extends keyof TRoutes & string>(name: K): TRoutes[K];
45
+ listRoutes(): (keyof TRoutes & string)[];
19
46
  /**
20
47
  * Returns a list of TBDFunctions that have not been overloaded.
21
48
  * Use this to validate that all required implementations are provided.
@@ -1 +1 @@
1
- {"version":3,"file":"api-container.d.ts","sourceRoot":"","sources":["../src/api-container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,SAAS;IACxB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,GAAE,SAAc;IAKhE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,IAAI;IAI7D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAQlC,UAAU,IAAK,MAAM,EAAE;IAIvB;;;OAGG;IACH,iBAAiB,IAAI,QAAQ,EAAE;CAKhC"}
1
+ {"version":3,"file":"api-container.d.ts","sourceRoot":"","sources":["../src/api-container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;CAC5B,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,IAAI,EAAE,MAAM,MAAM,CAAC,GACnE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,GAClC,KAAK,CAAC;AAEV;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,OAAO,SAAS,SAAS,IAAI;KACpD,CAAC,IAAI,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAY,CAAC,OAAO,SAAS,SAAS,GAAG,SAAS,CAAE,SAAQ,SAAS;IAChF,SAAgB,MAAM,EAAE,OAAO,CAAC;gBAEpB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,GAAE,OAAuB;IAKzE,QAAQ,CAAC,KAAK,SAAS,GAAG,EAAE,EAAE,OAAO,EACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,GAChC,IAAI;IAIP,QAAQ,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ/D,UAAU,IAAI,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE;IAIxC;;;OAGG;IACH,iBAAiB,IAAI,QAAQ,EAAE;CAKhC"}
@@ -4,7 +4,18 @@ exports.ApiContainer = void 0;
4
4
  const constructs_1 = require("constructs");
5
5
  const function_1 = require("./function");
6
6
  /**
7
- * Represents an API container that routes requests to functions
7
+ * Represents an API container that routes requests to functions.
8
+ *
9
+ * @typeParam TRoutes - The type of the routes object, preserving route names and handler signatures.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const api = new ApiContainer(arch, 'api', {
14
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
15
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
16
+ * });
17
+ * // api has type ApiContainer<{ hello: RouteEntry<[string], string>, hellos: RouteEntry<[], Greeting[]> }>
18
+ * ```
8
19
  */
9
20
  class ApiContainer extends constructs_1.Construct {
10
21
  constructor(scope, id, routes = {}) {
@@ -35,4 +46,4 @@ class ApiContainer extends constructs_1.Construct {
35
46
  }
36
47
  }
37
48
  exports.ApiContainer = ApiContainer;
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWNvbnRhaW5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hcGktY29udGFpbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF1QztBQUN2Qyx5Q0FBbUQ7QUFXbkQ7O0dBRUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxzQkFBUztJQUd6QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLFNBQW9CLEVBQUU7UUFDOUQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQsUUFBUSxDQUFDLElBQVksRUFBRSxJQUFZLEVBQUUsT0FBaUI7UUFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0lBRUQsUUFBUSxDQUFDLElBQVk7UUFDbkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSw2QkFBNkIsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsaUJBQWlCO1FBQ2YsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7YUFDOUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQzthQUMzQixNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksc0JBQVcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQWpDRCxvQ0FpQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEZ1bmN0aW9uLCBUQkRGdW5jdGlvbiB9IGZyb20gJy4vZnVuY3Rpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFwaVJvdXRlcyB7XG4gIFtuYW1lOiBzdHJpbmddOiBSb3V0ZUVudHJ5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlRW50cnkge1xuICBwYXRoOiBzdHJpbmc7XG4gIGhhbmRsZXI6IEZ1bmN0aW9uO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gQVBJIGNvbnRhaW5lciB0aGF0IHJvdXRlcyByZXF1ZXN0cyB0byBmdW5jdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIEFwaUNvbnRhaW5lciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSByb3V0ZXM6IEFwaVJvdXRlcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCByb3V0ZXM6IEFwaVJvdXRlcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnJvdXRlcyA9IHJvdXRlcztcbiAgfVxuXG4gIGFkZFJvdXRlKG5hbWU6IHN0cmluZywgcGF0aDogc3RyaW5nLCBoYW5kbGVyOiBGdW5jdGlvbik6IHZvaWQge1xuICAgIHRoaXMucm91dGVzW25hbWVdID0geyBwYXRoLCBoYW5kbGVyIH07XG4gIH1cblxuICBnZXRSb3V0ZShuYW1lOiBzdHJpbmcpOiBSb3V0ZUVudHJ5IHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMucm91dGVzW25hbWVdO1xuICAgIGlmICghZW50cnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUm91dGUgJyR7bmFtZX0nIG5vdCBmb3VuZCBpbiBjb250YWluZXIgJyR7dGhpcy5ub2RlLmlkfSdgKTtcbiAgICB9XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgbGlzdFJvdXRlcygpIDogc3RyaW5nW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnJvdXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgVEJERnVuY3Rpb25zIHRoYXQgaGF2ZSBub3QgYmVlbiBvdmVybG9hZGVkLlxuICAgKiBVc2UgdGhpcyB0byB2YWxpZGF0ZSB0aGF0IGFsbCByZXF1aXJlZCBpbXBsZW1lbnRhdGlvbnMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgdmFsaWRhdGVPdmVybG9hZHMoKTogRnVuY3Rpb25bXSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5yb3V0ZXMpXG4gICAgICAubWFwKGVudHJ5ID0+IGVudHJ5LmhhbmRsZXIpXG4gICAgICAuZmlsdGVyKGZuID0+IGZuIGluc3RhbmNlb2YgVEJERnVuY3Rpb24gJiYgIWZuLmhhc092ZXJsb2FkKCkpO1xuICB9XG59XG4iXX0=
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWNvbnRhaW5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hcGktY29udGFpbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF1QztBQUN2Qyx5Q0FBbUQ7QUErQm5EOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFhLFlBQW9ELFNBQVEsc0JBQVM7SUFHaEYsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxTQUFrQixFQUFhO1FBQ3ZFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELFFBQVEsQ0FDTixJQUFZLEVBQ1osSUFBWSxFQUNaLE9BQWlDO1FBRWhDLElBQUksQ0FBQyxNQUFvQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3ZELENBQUM7SUFFRCxRQUFRLENBQW1DLElBQU87UUFDaEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSw2QkFBNkIsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQStCLENBQUM7SUFDaEUsQ0FBQztJQUVEOzs7T0FHRztJQUNILGlCQUFpQjtRQUNmLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO2FBQzlCLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7YUFDM0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLHNCQUFXLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNsRSxDQUFDO0NBQ0Y7QUFyQ0Qsb0NBcUNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBGdW5jdGlvbiwgVEJERnVuY3Rpb24gfSBmcm9tICcuL2Z1bmN0aW9uJztcblxuLyoqXG4gKiBBIHJvdXRlIGVudHJ5IHRoYXQgY2FwdHVyZXMgdGhlIGhhbmRsZXIncyBhcmd1bWVudCBhbmQgcmV0dXJuIHR5cGVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlRW50cnk8VEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLCBUUmV0dXJuID0gYW55PiB7XG4gIHBhdGg6IHN0cmluZztcbiAgaGFuZGxlcjogRnVuY3Rpb248VEFyZ3MsIFRSZXR1cm4+O1xufVxuXG4vKipcbiAqIEJhc2UgdHlwZSBmb3Igcm91dGUgZGVmaW5pdGlvbnMgLSBtYXBzIHJvdXRlIG5hbWVzIHRvIHJvdXRlIGVudHJpZXMuXG4gKi9cbmV4cG9ydCB0eXBlIEFwaVJvdXRlcyA9IHtcbiAgW25hbWU6IHN0cmluZ106IFJvdXRlRW50cnk7XG59XG5cbi8qKlxuICogRXh0cmFjdCB0aGUgaGFuZGxlciBzaWduYXR1cmUgZnJvbSBhIEZ1bmN0aW9uIHR5cGUuXG4gKi9cbmV4cG9ydCB0eXBlIEhhbmRsZXJPZjxUPiA9IFQgZXh0ZW5kcyBGdW5jdGlvbjxpbmZlciBBcmdzLCBpbmZlciBSZXR1cm4+XG4gID8gKC4uLmFyZ3M6IEFyZ3MpID0+IFByb21pc2U8UmV0dXJuPlxuICA6IG5ldmVyO1xuXG4vKipcbiAqIEV4dHJhY3QgaGFuZGxlciBzaWduYXR1cmVzIGZyb20gYWxsIHJvdXRlcyBpbiBhbiBBcGlSb3V0ZXMgdHlwZS5cbiAqL1xuZXhwb3J0IHR5cGUgUm91dGVIYW5kbGVyczxUUm91dGVzIGV4dGVuZHMgQXBpUm91dGVzPiA9IHtcbiAgW0sgaW4ga2V5b2YgVFJvdXRlc106IEhhbmRsZXJPZjxUUm91dGVzW0tdWydoYW5kbGVyJ10+O1xufTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIEFQSSBjb250YWluZXIgdGhhdCByb3V0ZXMgcmVxdWVzdHMgdG8gZnVuY3Rpb25zLlxuICpcbiAqIEB0eXBlUGFyYW0gVFJvdXRlcyAtIFRoZSB0eXBlIG9mIHRoZSByb3V0ZXMgb2JqZWN0LCBwcmVzZXJ2aW5nIHJvdXRlIG5hbWVzIGFuZCBoYW5kbGVyIHNpZ25hdHVyZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGFwaSA9IG5ldyBBcGlDb250YWluZXIoYXJjaCwgJ2FwaScsIHtcbiAqICAgaGVsbG86IHsgcGF0aDogJ0dFVCAvdjEvYXBpL2hlbGxvL3tuYW1lfScsIGhhbmRsZXI6IGhlbGxvRnVuY3Rpb24gfSxcbiAqICAgaGVsbG9zOiB7IHBhdGg6ICdHRVQgL3YxL2FwaS9oZWxsb3MnLCBoYW5kbGVyOiBoZWxsb3NGdW5jdGlvbiB9XG4gKiB9KTtcbiAqIC8vIGFwaSBoYXMgdHlwZSBBcGlDb250YWluZXI8eyBoZWxsbzogUm91dGVFbnRyeTxbc3RyaW5nXSwgc3RyaW5nPiwgaGVsbG9zOiBSb3V0ZUVudHJ5PFtdLCBHcmVldGluZ1tdPiB9PlxuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBBcGlDb250YWluZXI8VFJvdXRlcyBleHRlbmRzIEFwaVJvdXRlcyA9IEFwaVJvdXRlcz4gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgcm91dGVzOiBUUm91dGVzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJvdXRlczogVFJvdXRlcyA9IHt9IGFzIFRSb3V0ZXMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucm91dGVzID0gcm91dGVzO1xuICB9XG5cbiAgYWRkUm91dGU8VEFyZ3MgZXh0ZW5kcyBhbnlbXSwgVFJldHVybj4oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBoYW5kbGVyOiBGdW5jdGlvbjxUQXJncywgVFJldHVybj5cbiAgKTogdm9pZCB7XG4gICAgKHRoaXMucm91dGVzIGFzIEFwaVJvdXRlcylbbmFtZV0gPSB7IHBhdGgsIGhhbmRsZXIgfTtcbiAgfVxuXG4gIGdldFJvdXRlPEsgZXh0ZW5kcyBrZXlvZiBUUm91dGVzICYgc3RyaW5nPihuYW1lOiBLKTogVFJvdXRlc1tLXSB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLnJvdXRlc1tuYW1lXTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJvdXRlICcke25hbWV9JyBub3QgZm91bmQgaW4gY29udGFpbmVyICcke3RoaXMubm9kZS5pZH0nYCk7XG4gICAgfVxuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIGxpc3RSb3V0ZXMoKTogKGtleW9mIFRSb3V0ZXMgJiBzdHJpbmcpW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnJvdXRlcykgYXMgKGtleW9mIFRSb3V0ZXMgJiBzdHJpbmcpW107XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgVEJERnVuY3Rpb25zIHRoYXQgaGF2ZSBub3QgYmVlbiBvdmVybG9hZGVkLlxuICAgKiBVc2UgdGhpcyB0byB2YWxpZGF0ZSB0aGF0IGFsbCByZXF1aXJlZCBpbXBsZW1lbnRhdGlvbnMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgdmFsaWRhdGVPdmVybG9hZHMoKTogRnVuY3Rpb25bXSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5yb3V0ZXMpXG4gICAgICAubWFwKGVudHJ5ID0+IGVudHJ5LmhhbmRsZXIpXG4gICAgICAuZmlsdGVyKGZuID0+IGZuIGluc3RhbmNlb2YgVEJERnVuY3Rpb24gJiYgIWZuLmhhc092ZXJsb2FkKCkpO1xuICB9XG59XG4iXX0=
package/dist/binding.d.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import { Construct } from 'constructs';
2
- import { ApiContainer } from './api-container';
2
+ import { ApiContainer, ApiRoutes } from './api-container';
3
3
  import { FunctionHandler } from './function';
4
4
  /**
5
5
  * Service discovery configuration for runtime
6
6
  */
7
7
  export interface ServiceEndpoint {
8
- host: string;
9
- port: number;
8
+ baseUrl: string;
10
9
  }
11
10
  /**
12
11
  * Binding options for an ApiContainer
@@ -30,12 +29,7 @@ export declare class ArchitectureBinding {
30
29
  * Optionally override function implementations with the overloads option.
31
30
  * Overload keys must be route names registered via addRoute.
32
31
  */
33
- bind(component: ApiContainer, options: BindOptions): void;
34
- /**
35
- * Bind a component from environment variables.
36
- * Looks for {PREFIX}_HOST and {PREFIX}_PORT environment variables.
37
- */
38
- bindFromEnv(component: ApiContainer, envPrefix: string, overloads?: Record<string, FunctionHandler>): void;
32
+ bind<TRoutes extends ApiRoutes>(component: ApiContainer<TRoutes>, options: BindOptions): void;
39
33
  getEndpoint(component: Construct): ServiceEndpoint | undefined;
40
34
  getAllBindings(): Map<Construct, ServiceEndpoint>;
41
35
  setLocal(component: Construct): void;
@@ -1 +1 @@
1
- {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAY,eAAe,EAAE,MAAM,YAAY,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,eAAe,CAA6B;IAEpD;;;;OAIG;IACH,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAezD;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI;IAQ1G,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,eAAe,GAAG,SAAS;IAI9D,cAAc,IAAI,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC;IAIjD,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAIpC,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;CAGvC;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAY,eAAe,EAAE,MAAM,YAAY,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,eAAe,CAA6B;IAEpD;;;;OAIG;IACH,IAAI,CAAC,OAAO,SAAS,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAe7F,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,eAAe,GAAG,SAAS;IAI9D,cAAc,IAAI,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC;IAIjD,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAIpC,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;CAGvC;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
package/dist/binding.js CHANGED
@@ -17,7 +17,7 @@ class ArchitectureBinding {
17
17
  * Overload keys must be route names registered via addRoute.
18
18
  */
19
19
  bind(component, options) {
20
- this.bindings.set(component, { host: options.host, port: options.port });
20
+ this.bindings.set(component, { baseUrl: options.baseUrl });
21
21
  Object.entries(options.overloads ?? {}).forEach(([name, handler]) => {
22
22
  const route = component.getRoute(name);
23
23
  if (!route) {
@@ -29,17 +29,6 @@ class ArchitectureBinding {
29
29
  route.handler.overload(handler);
30
30
  });
31
31
  }
32
- /**
33
- * Bind a component from environment variables.
34
- * Looks for {PREFIX}_HOST and {PREFIX}_PORT environment variables.
35
- */
36
- bindFromEnv(component, envPrefix, overloads) {
37
- const host = process.env[`${envPrefix}_HOST`];
38
- const port = process.env[`${envPrefix}_PORT`];
39
- if (host && port) {
40
- this.bind(component, { host, port: parseInt(port), overloads });
41
- }
42
- }
43
32
  getEndpoint(component) {
44
33
  return this.bindings.get(component);
45
34
  }
@@ -58,4 +47,4 @@ exports.ArchitectureBinding = ArchitectureBinding;
58
47
  * Global binding registry
59
48
  */
60
49
  exports.architectureBinding = new ArchitectureBinding();
61
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluZGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9iaW5kaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHlDQUF1RDtBQXFCdkQ7OztHQUdHO0FBQ0gsTUFBYSxtQkFBbUI7SUFBaEM7UUFDVSxhQUFRLEdBQW9DLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdEQsb0JBQWUsR0FBbUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQWlEdEQsQ0FBQztJQS9DQzs7OztPQUlHO0lBQ0gsSUFBSSxDQUFDLFNBQXVCLEVBQUUsT0FBb0I7UUFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXpFLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFO1lBQ2xFLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLDZCQUE2QixTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkYsQ0FBQztZQUNELElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLFlBQVksbUJBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLDZCQUE2QixDQUFDLENBQUM7WUFDL0QsQ0FBQztZQUNELEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILFdBQVcsQ0FBQyxTQUF1QixFQUFFLFNBQWlCLEVBQUUsU0FBMkM7UUFDakcsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsT0FBTyxDQUFDLENBQUM7UUFDOUMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsT0FBTyxDQUFDLENBQUM7UUFDOUMsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVyxDQUFDLFNBQW9CO1FBQzlCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELFFBQVEsQ0FBQyxTQUFvQjtRQUMzQixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsT0FBTyxDQUFDLFNBQW9CO1FBQzFCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsQ0FBQztDQUNGO0FBbkRELGtEQW1EQztBQUVEOztHQUVHO0FBQ1UsUUFBQSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEFwaUNvbnRhaW5lciB9IGZyb20gJy4vYXBpLWNvbnRhaW5lcic7XG5pbXBvcnQgeyBGdW5jdGlvbiwgRnVuY3Rpb25IYW5kbGVyIH0gZnJvbSAnLi9mdW5jdGlvbic7XG5cbi8qKlxuICogU2VydmljZSBkaXNjb3ZlcnkgY29uZmlndXJhdGlvbiBmb3IgcnVudGltZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZpY2VFbmRwb2ludCB7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIEJpbmRpbmcgb3B0aW9ucyBmb3IgYW4gQXBpQ29udGFpbmVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmluZE9wdGlvbnMgZXh0ZW5kcyBTZXJ2aWNlRW5kcG9pbnQge1xuICAvKipcbiAgICogT3ZlcnJpZGUgZnVuY3Rpb24gaW1wbGVtZW50YXRpb25zLlxuICAgKiBLZXlzIGFyZSBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBvbiB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgb3ZlcmxvYWRzPzogUmVjb3JkPHN0cmluZywgRnVuY3Rpb25IYW5kbGVyPjtcbn1cblxuLyoqXG4gKiBCaW5kaW5nIGJldHdlZW4gYXJjaGl0ZWN0dXJhbCBjb21wb25lbnRzIGFuZCB0aGVpciBydW50aW1lIGVuZHBvaW50cy5cbiAqIFN1cHBvcnRzIGZ1bmN0aW9uIG92ZXJsb2FkaW5nIGZvciByZXBsYWNpbmcgaW1wbGVtZW50YXRpb25zIGF0IHJ1bnRpbWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBBcmNoaXRlY3R1cmVCaW5kaW5nIHtcbiAgcHJpdmF0ZSBiaW5kaW5nczogTWFwPENvbnN0cnVjdCwgU2VydmljZUVuZHBvaW50PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBsb2NhbENvbXBvbmVudHM6IFNldDxDb25zdHJ1Y3Q+ID0gbmV3IFNldCgpO1xuXG4gIC8qKlxuICAgKiBCaW5kIGFuIGFyY2hpdGVjdHVyYWwgY29tcG9uZW50IHRvIGEgc2VydmljZSBlbmRwb2ludC5cbiAgICogT3B0aW9uYWxseSBvdmVycmlkZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgd2l0aCB0aGUgb3ZlcmxvYWRzIG9wdGlvbi5cbiAgICogT3ZlcmxvYWQga2V5cyBtdXN0IGJlIHJvdXRlIG5hbWVzIHJlZ2lzdGVyZWQgdmlhIGFkZFJvdXRlLlxuICAgKi9cbiAgYmluZChjb21wb25lbnQ6IEFwaUNvbnRhaW5lciwgb3B0aW9uczogQmluZE9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLmJpbmRpbmdzLnNldChjb21wb25lbnQsIHsgaG9zdDogb3B0aW9ucy5ob3N0LCBwb3J0OiBvcHRpb25zLnBvcnQgfSk7XG5cbiAgICBPYmplY3QuZW50cmllcyhvcHRpb25zLm92ZXJsb2FkcyA/PyB7fSkuZm9yRWFjaCgoW25hbWUsIGhhbmRsZXJdKSA9PiB7XG4gICAgICBjb25zdCByb3V0ZSA9IGNvbXBvbmVudC5nZXRSb3V0ZShuYW1lKTtcbiAgICAgIGlmICghcm91dGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSb3V0ZSAnJHtuYW1lfScgbm90IGZvdW5kIGluIGNvbXBvbmVudCAnJHtjb21wb25lbnQubm9kZS5pZH0nYCk7XG4gICAgICB9XG4gICAgICBpZiAoIShyb3V0ZS5oYW5kbGVyIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUm91dGUgJyR7bmFtZX0nIGhhbmRsZXIgaXMgbm90IGEgRnVuY3Rpb25gKTtcbiAgICAgIH1cbiAgICAgIHJvdXRlLmhhbmRsZXIub3ZlcmxvYWQoaGFuZGxlcik7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQmluZCBhIGNvbXBvbmVudCBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAgICogTG9va3MgZm9yIHtQUkVGSVh9X0hPU1QgYW5kIHtQUkVGSVh9X1BPUlQgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgYmluZEZyb21FbnYoY29tcG9uZW50OiBBcGlDb250YWluZXIsIGVudlByZWZpeDogc3RyaW5nLCBvdmVybG9hZHM/OiBSZWNvcmQ8c3RyaW5nLCBGdW5jdGlvbkhhbmRsZXI+KTogdm9pZCB7XG4gICAgY29uc3QgaG9zdCA9IHByb2Nlc3MuZW52W2Ake2VudlByZWZpeH1fSE9TVGBdO1xuICAgIGNvbnN0IHBvcnQgPSBwcm9jZXNzLmVudltgJHtlbnZQcmVmaXh9X1BPUlRgXTtcbiAgICBpZiAoaG9zdCAmJiBwb3J0KSB7XG4gICAgICB0aGlzLmJpbmQoY29tcG9uZW50LCB7IGhvc3QsIHBvcnQ6IHBhcnNlSW50KHBvcnQpLCBvdmVybG9hZHMgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0RW5kcG9pbnQoY29tcG9uZW50OiBDb25zdHJ1Y3QpOiBTZXJ2aWNlRW5kcG9pbnQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmJpbmRpbmdzLmdldChjb21wb25lbnQpO1xuICB9XG5cbiAgZ2V0QWxsQmluZGluZ3MoKTogTWFwPENvbnN0cnVjdCwgU2VydmljZUVuZHBvaW50PiB7XG4gICAgcmV0dXJuIHRoaXMuYmluZGluZ3M7XG4gIH1cblxuICBzZXRMb2NhbChjb21wb25lbnQ6IENvbnN0cnVjdCk6IHZvaWQge1xuICAgIHRoaXMubG9jYWxDb21wb25lbnRzLmFkZChjb21wb25lbnQpO1xuICB9XG5cbiAgaXNMb2NhbChjb21wb25lbnQ6IENvbnN0cnVjdCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxvY2FsQ29tcG9uZW50cy5oYXMoY29tcG9uZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIEdsb2JhbCBiaW5kaW5nIHJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBjb25zdCBhcmNoaXRlY3R1cmVCaW5kaW5nID0gbmV3IEFyY2hpdGVjdHVyZUJpbmRpbmcoKTtcbiJdfQ==
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluZGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9iaW5kaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHlDQUF1RDtBQW9CdkQ7OztHQUdHO0FBQ0gsTUFBYSxtQkFBbUI7SUFBaEM7UUFDVSxhQUFRLEdBQW9DLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdEQsb0JBQWUsR0FBbUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQXFDdEQsQ0FBQztJQW5DQzs7OztPQUlHO0lBQ0gsSUFBSSxDQUE0QixTQUFnQyxFQUFFLE9BQW9CO1FBQ3BGLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUUzRCxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUNsRSxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSw2QkFBNkIsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ25GLENBQUM7WUFDRCxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxZQUFZLG1CQUFRLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSw2QkFBNkIsQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFDRCxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXLENBQUMsU0FBb0I7UUFDOUIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQsUUFBUSxDQUFDLFNBQW9CO1FBQzNCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxPQUFPLENBQUMsU0FBb0I7UUFDMUIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUF2Q0Qsa0RBdUNDO0FBRUQ7O0dBRUc7QUFDVSxRQUFBLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXBpQ29udGFpbmVyLCBBcGlSb3V0ZXMgfSBmcm9tICcuL2FwaS1jb250YWluZXInO1xuaW1wb3J0IHsgRnVuY3Rpb24sIEZ1bmN0aW9uSGFuZGxlciB9IGZyb20gJy4vZnVuY3Rpb24nO1xuXG4vKipcbiAqIFNlcnZpY2UgZGlzY292ZXJ5IGNvbmZpZ3VyYXRpb24gZm9yIHJ1bnRpbWVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlRW5kcG9pbnQge1xuICBiYXNlVXJsOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQmluZGluZyBvcHRpb25zIGZvciBhbiBBcGlDb250YWluZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCaW5kT3B0aW9ucyBleHRlbmRzIFNlcnZpY2VFbmRwb2ludCB7XG4gIC8qKlxuICAgKiBPdmVycmlkZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMuXG4gICAqIEtleXMgYXJlIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIG9uIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBvdmVybG9hZHM/OiBSZWNvcmQ8c3RyaW5nLCBGdW5jdGlvbkhhbmRsZXI+O1xufVxuXG4vKipcbiAqIEJpbmRpbmcgYmV0d2VlbiBhcmNoaXRlY3R1cmFsIGNvbXBvbmVudHMgYW5kIHRoZWlyIHJ1bnRpbWUgZW5kcG9pbnRzLlxuICogU3VwcG9ydHMgZnVuY3Rpb24gb3ZlcmxvYWRpbmcgZm9yIHJlcGxhY2luZyBpbXBsZW1lbnRhdGlvbnMgYXQgcnVudGltZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFyY2hpdGVjdHVyZUJpbmRpbmcge1xuICBwcml2YXRlIGJpbmRpbmdzOiBNYXA8Q29uc3RydWN0LCBTZXJ2aWNlRW5kcG9pbnQ+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGxvY2FsQ29tcG9uZW50czogU2V0PENvbnN0cnVjdD4gPSBuZXcgU2V0KCk7XG5cbiAgLyoqXG4gICAqIEJpbmQgYW4gYXJjaGl0ZWN0dXJhbCBjb21wb25lbnQgdG8gYSBzZXJ2aWNlIGVuZHBvaW50LlxuICAgKiBPcHRpb25hbGx5IG92ZXJyaWRlIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9ucyB3aXRoIHRoZSBvdmVybG9hZHMgb3B0aW9uLlxuICAgKiBPdmVybG9hZCBrZXlzIG11c3QgYmUgcm91dGUgbmFtZXMgcmVnaXN0ZXJlZCB2aWEgYWRkUm91dGUuXG4gICAqL1xuICBiaW5kPFRSb3V0ZXMgZXh0ZW5kcyBBcGlSb3V0ZXM+KGNvbXBvbmVudDogQXBpQ29udGFpbmVyPFRSb3V0ZXM+LCBvcHRpb25zOiBCaW5kT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuYmluZGluZ3Muc2V0KGNvbXBvbmVudCwgeyBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwgfSk7XG5cbiAgICBPYmplY3QuZW50cmllcyhvcHRpb25zLm92ZXJsb2FkcyA/PyB7fSkuZm9yRWFjaCgoW25hbWUsIGhhbmRsZXJdKSA9PiB7XG4gICAgICBjb25zdCByb3V0ZSA9IGNvbXBvbmVudC5nZXRSb3V0ZShuYW1lKTtcbiAgICAgIGlmICghcm91dGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSb3V0ZSAnJHtuYW1lfScgbm90IGZvdW5kIGluIGNvbXBvbmVudCAnJHtjb21wb25lbnQubm9kZS5pZH0nYCk7XG4gICAgICB9XG4gICAgICBpZiAoIShyb3V0ZS5oYW5kbGVyIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUm91dGUgJyR7bmFtZX0nIGhhbmRsZXIgaXMgbm90IGEgRnVuY3Rpb25gKTtcbiAgICAgIH1cbiAgICAgIHJvdXRlLmhhbmRsZXIub3ZlcmxvYWQoaGFuZGxlcik7XG4gICAgfSk7XG4gIH1cblxuICBnZXRFbmRwb2ludChjb21wb25lbnQ6IENvbnN0cnVjdCk6IFNlcnZpY2VFbmRwb2ludCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuYmluZGluZ3MuZ2V0KGNvbXBvbmVudCk7XG4gIH1cblxuICBnZXRBbGxCaW5kaW5ncygpOiBNYXA8Q29uc3RydWN0LCBTZXJ2aWNlRW5kcG9pbnQ+IHtcbiAgICByZXR1cm4gdGhpcy5iaW5kaW5ncztcbiAgfVxuXG4gIHNldExvY2FsKGNvbXBvbmVudDogQ29uc3RydWN0KTogdm9pZCB7XG4gICAgdGhpcy5sb2NhbENvbXBvbmVudHMuYWRkKGNvbXBvbmVudCk7XG4gIH1cblxuICBpc0xvY2FsKGNvbXBvbmVudDogQ29uc3RydWN0KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubG9jYWxDb21wb25lbnRzLmhhcyhjb21wb25lbnQpO1xuICB9XG59XG5cbi8qKlxuICogR2xvYmFsIGJpbmRpbmcgcmVnaXN0cnlcbiAqL1xuZXhwb3J0IGNvbnN0IGFyY2hpdGVjdHVyZUJpbmRpbmcgPSBuZXcgQXJjaGl0ZWN0dXJlQmluZGluZygpO1xuIl19
@@ -1 +1 @@
1
- {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,eAAe,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE/G;;;GAGG;AACH,qBAAa,QAAQ,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,CAAE,SAAQ,SAAS;IACjF,SAAgB,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,CAAC,SAAS,CAAC,CAAkC;gBAExC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC;IAKlF;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxD,WAAW,IAAI,OAAO;IAIf,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;CAIhD;AAED;;;GAGG;AACH,qBAAa,WAAW,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,CAAE,SAAQ,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACvF,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM;CAKzC"}
1
+ {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,eAAe,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE/G;;;GAGG;AACH,qBAAa,QAAQ,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,CAAE,SAAQ,SAAS;IACjF,SAAgB,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,CAAC,SAAS,CAAC,CAAkC;gBAExC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC;IAKlF;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxD,WAAW,IAAI,OAAO;IAIf,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;CAIhD;AAED;;;GAGG;AACH,qBAAa,WAAW,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,CAAE,SAAQ,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACvF,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM;CAGzC"}
package/dist/function.js CHANGED
@@ -33,10 +33,8 @@ exports.Function = Function;
33
33
  */
34
34
  class TBDFunction extends Function {
35
35
  constructor(scope, id) {
36
- super(scope, id, (() => {
37
- return Promise.reject(new Error(`Function '${id}' is not implemented. Provide an overload before invoking.`));
38
- }));
36
+ super(scope, id, (() => Promise.reject(new Error(`Function '${id}' is not implemented. Provide an overload before invoking.`))));
39
37
  }
40
38
  }
41
39
  exports.TBDFunction = TBDFunction;
42
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBSXZDOzs7R0FHRztBQUNILE1BQWEsUUFBcUQsU0FBUSxzQkFBUztJQUlqRixZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLE9BQXdDO1FBQ2hGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7T0FHRztJQUNILFFBQVEsQ0FBQyxPQUF3QztRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztJQUMzQixDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7SUFDdEMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxHQUFHLElBQVc7UUFDMUIsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzFDLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7Q0FDRjtBQXpCRCw0QkF5QkM7QUFFRDs7O0dBR0c7QUFDSCxNQUFhLFdBQXdELFNBQVEsUUFBd0I7SUFDbkcsWUFBWSxLQUFnQixFQUFFLEVBQVU7UUFDdEMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUU7WUFDckIsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGFBQWEsRUFBRSw0REFBNEQsQ0FBQyxDQUFDLENBQUM7UUFDaEgsQ0FBQyxDQUFvQyxDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGO0FBTkQsa0NBTUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuZXhwb3J0IHR5cGUgRnVuY3Rpb25IYW5kbGVyPFRBcmdzIGV4dGVuZHMgYW55W10gPSBhbnlbXSwgVFJldHVybiA9IGFueT4gPSAoLi4uYXJnczogVEFyZ3MpID0+IFByb21pc2U8VFJldHVybj47XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHNlcnZlcmxlc3MgZnVuY3Rpb24gb3IgaGFuZGxlciBpbiB0aGUgYXJjaGl0ZWN0dXJlLlxuICogR2VuZXJpYyBvdmVyIGFyZ3VtZW50IHR5cGVzIChUQXJncykgYW5kIHJldHVybiB0eXBlIChUUmV0dXJuKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uPFRBcmdzIGV4dGVuZHMgYW55W10gPSBhbnlbXSwgVFJldHVybiA9IGFueT4gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgaGFuZGxlcjogRnVuY3Rpb25IYW5kbGVyPFRBcmdzLCBUUmV0dXJuPjtcbiAgcHJpdmF0ZSBfb3ZlcmxvYWQ/OiBGdW5jdGlvbkhhbmRsZXI8VEFyZ3MsIFRSZXR1cm4+O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGhhbmRsZXI6IEZ1bmN0aW9uSGFuZGxlcjxUQXJncywgVFJldHVybj4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIGZ1bmN0aW9uJ3MgaW1wbGVtZW50YXRpb24gYXQgcnVudGltZS5cbiAgICogVXNlZCBmb3IgcmVwbGFjaW5nIGluLW1lbW9yeSBpbXBsZW1lbnRhdGlvbnMgd2l0aCBzdG9yYWdlIGFkYXB0ZXJzIG9yIEhUVFAgY2FsbHMuXG4gICAqL1xuICBvdmVybG9hZChoYW5kbGVyOiBGdW5jdGlvbkhhbmRsZXI8VEFyZ3MsIFRSZXR1cm4+KTogdm9pZCB7XG4gICAgdGhpcy5fb3ZlcmxvYWQgPSBoYW5kbGVyO1xuICB9XG5cbiAgaGFzT3ZlcmxvYWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX292ZXJsb2FkICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgaW52b2tlKC4uLmFyZ3M6IFRBcmdzKTogUHJvbWlzZTxUUmV0dXJuPiB7XG4gICAgY29uc3QgZm4gPSB0aGlzLl9vdmVybG9hZCA/PyB0aGlzLmhhbmRsZXI7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmbiguLi5hcmdzKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIHBsYWNlaG9sZGVyIGZ1bmN0aW9uIHRoYXQgbXVzdCBiZSBvdmVybG9hZGVkIGJlZm9yZSB1c2UuXG4gKiBVc2UgdGhpcyB3aGVuIGRlZmluaW5nIGFuIEFQSSBjb250cmFjdCB3aXRob3V0IHByb3ZpZGluZyBhbiBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFRCREZ1bmN0aW9uPFRBcmdzIGV4dGVuZHMgYW55W10gPSBhbnlbXSwgVFJldHVybiA9IGFueT4gZXh0ZW5kcyBGdW5jdGlvbjxUQXJncywgVFJldHVybj4ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCAoKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgRnVuY3Rpb24gJyR7aWR9JyBpcyBub3QgaW1wbGVtZW50ZWQuIFByb3ZpZGUgYW4gb3ZlcmxvYWQgYmVmb3JlIGludm9raW5nLmApKTtcbiAgICB9KSBhcyBGdW5jdGlvbkhhbmRsZXI8VEFyZ3MsIFRSZXR1cm4+KTtcbiAgfVxufVxuIl19
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBSXZDOzs7R0FHRztBQUNILE1BQWEsUUFBcUQsU0FBUSxzQkFBUztJQUlqRixZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLE9BQXdDO1FBQ2hGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7T0FHRztJQUNILFFBQVEsQ0FBQyxPQUF3QztRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztJQUMzQixDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7SUFDdEMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxHQUFHLElBQVc7UUFDMUIsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzFDLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7Q0FDRjtBQXpCRCw0QkF5QkM7QUFFRDs7O0dBR0c7QUFDSCxNQUFhLFdBQXdELFNBQVEsUUFBd0I7SUFDbkcsWUFBWSxLQUFnQixFQUFFLEVBQVU7UUFDdEMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGFBQWEsRUFBRSw0REFBNEQsQ0FBQyxDQUFDLENBQW9DLENBQUMsQ0FBQztJQUN0SyxDQUFDO0NBQ0Y7QUFKRCxrQ0FJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5leHBvcnQgdHlwZSBGdW5jdGlvbkhhbmRsZXI8VEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLCBUUmV0dXJuID0gYW55PiA9ICguLi5hcmdzOiBUQXJncykgPT4gUHJvbWlzZTxUUmV0dXJuPjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2VydmVybGVzcyBmdW5jdGlvbiBvciBoYW5kbGVyIGluIHRoZSBhcmNoaXRlY3R1cmUuXG4gKiBHZW5lcmljIG92ZXIgYXJndW1lbnQgdHlwZXMgKFRBcmdzKSBhbmQgcmV0dXJuIHR5cGUgKFRSZXR1cm4pLlxuICovXG5leHBvcnQgY2xhc3MgRnVuY3Rpb248VEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLCBUUmV0dXJuID0gYW55PiBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyOiBGdW5jdGlvbkhhbmRsZXI8VEFyZ3MsIFRSZXR1cm4+O1xuICBwcml2YXRlIF9vdmVybG9hZD86IEZ1bmN0aW9uSGFuZGxlcjxUQXJncywgVFJldHVybj47XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgaGFuZGxlcjogRnVuY3Rpb25IYW5kbGVyPFRBcmdzLCBUUmV0dXJuPikge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZSB0aGUgZnVuY3Rpb24ncyBpbXBsZW1lbnRhdGlvbiBhdCBydW50aW1lLlxuICAgKiBVc2VkIGZvciByZXBsYWNpbmcgaW4tbWVtb3J5IGltcGxlbWVudGF0aW9ucyB3aXRoIHN0b3JhZ2UgYWRhcHRlcnMgb3IgSFRUUCBjYWxscy5cbiAgICovXG4gIG92ZXJsb2FkKGhhbmRsZXI6IEZ1bmN0aW9uSGFuZGxlcjxUQXJncywgVFJldHVybj4pOiB2b2lkIHtcbiAgICB0aGlzLl9vdmVybG9hZCA9IGhhbmRsZXI7XG4gIH1cblxuICBoYXNPdmVybG9hZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3ZlcmxvYWQgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBpbnZva2UoLi4uYXJnczogVEFyZ3MpOiBQcm9taXNlPFRSZXR1cm4+IHtcbiAgICBjb25zdCBmbiA9IHRoaXMuX292ZXJsb2FkID8/IHRoaXMuaGFuZGxlcjtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZuKC4uLmFyZ3MpKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgcGxhY2Vob2xkZXIgZnVuY3Rpb24gdGhhdCBtdXN0IGJlIG92ZXJsb2FkZWQgYmVmb3JlIHVzZS5cbiAqIFVzZSB0aGlzIHdoZW4gZGVmaW5pbmcgYW4gQVBJIGNvbnRyYWN0IHdpdGhvdXQgcHJvdmlkaW5nIGFuIGltcGxlbWVudGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgVEJERnVuY3Rpb248VEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLCBUUmV0dXJuID0gYW55PiBleHRlbmRzIEZ1bmN0aW9uPFRBcmdzLCBUUmV0dXJuPiB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsICgoKSA9PiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYEZ1bmN0aW9uICcke2lkfScgaXMgbm90IGltcGxlbWVudGVkLiBQcm92aWRlIGFuIG92ZXJsb2FkIGJlZm9yZSBpbnZva2luZy5gKSkpIGFzIEZ1bmN0aW9uSGFuZGxlcjxUQXJncywgVFJldHVybj4pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,32 @@
1
+ import { ApiContainer, ApiRoutes, RouteHandlers } from './api-container';
2
+ import { ServiceEndpoint } from './binding';
3
+ export type Fetcher = () => {
4
+ fetch: typeof fetch;
5
+ };
6
+ /**
7
+ * Create an HTTP handler for a route by name.
8
+ * Looks up the route path from the container's registry.
9
+ */
10
+ export declare const httpHandler: <TRoutes extends ApiRoutes, K extends keyof TRoutes & string>(endpoint: ServiceEndpoint, container: ApiContainer<TRoutes>, routeName: K, fetcher?: Fetcher) => RouteHandlers<TRoutes>[K];
11
+ /**
12
+ * Create HTTP bindings for multiple routes as a callable client.
13
+ * Returns a strongly-typed object where each route name maps to an async function
14
+ * with the same signature as the original handler.
15
+ *
16
+ * @typeParam TRoutes - The routes type from the ApiContainer
17
+ * @typeParam K - The subset of route names to include in the client
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const api = new ApiContainer(arch, 'api', {
22
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
23
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
24
+ * });
25
+ *
26
+ * const client = createHttpBindings(endpoint, api, ['hello', 'hellos']);
27
+ * await client.hello('John'); // (name: string) => Promise<string>
28
+ * await client.hellos(); // () => Promise<Greeting[]>
29
+ * ```
30
+ */
31
+ export declare const createHttpBindings: <TRoutes extends ApiRoutes, K extends keyof TRoutes & string>(endpoint: ServiceEndpoint, container: ApiContainer<TRoutes>, routeNames: readonly K[], fetcher?: Fetcher) => Pick<RouteHandlers<TRoutes>, K>;
32
+ //# sourceMappingURL=http-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-handler.d.ts","sourceRoot":"","sources":["../src/http-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,MAAM,OAAO,GAAG,MAAM;IAAE,KAAK,EAAE,OAAO,KAAK,CAAA;CAAE,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,SAAS,SAAS,EACzB,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAEhC,UAAU,eAAe,EACzB,WAAW,YAAY,CAAC,OAAO,CAAC,EAChC,WAAW,CAAC,EACZ,UAAS,OAAyB,KACjC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CA+B1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,SAAS,SAAS,EACzB,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAEhC,UAAU,eAAe,EACzB,WAAW,YAAY,CAAC,OAAO,CAAC,EAChC,YAAY,SAAS,CAAC,EAAE,EACxB,UAAS,OAAyB,KACjC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAQhC,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHttpBindings = exports.httpHandler = void 0;
4
+ /**
5
+ * Create an HTTP handler for a route by name.
6
+ * Looks up the route path from the container's registry.
7
+ */
8
+ const httpHandler = (endpoint, container, routeName, fetcher = () => ({ fetch })) => {
9
+ const route = container.getRoute(routeName);
10
+ const [method, path] = route.path.split(' ');
11
+ const pathParams = path.match(/\{(\w+)\}/g) || [];
12
+ const handler = async (...args) => {
13
+ const url = pathParams.reduce((u, param, i) => args[i] !== undefined ? u.replace(param, encodeURIComponent(String(args[i]))) : u, `${endpoint.baseUrl}${path}`);
14
+ const options = {
15
+ method: method || 'GET',
16
+ headers: { 'Content-Type': 'application/json' },
17
+ ...((method === 'POST' || method === 'PUT') && args.length > pathParams.length
18
+ ? { body: JSON.stringify(args[pathParams.length]) }
19
+ : {})
20
+ };
21
+ console.log('HTTP handler. Will fetch', { url, options });
22
+ const response = await fetcher().fetch(url, options);
23
+ if (!response.ok) {
24
+ throw new Error(`Remote call to ${url} with ${JSON.stringify(options)} failed: ${JSON.stringify(response)}`);
25
+ }
26
+ return response.json();
27
+ };
28
+ return handler;
29
+ };
30
+ exports.httpHandler = httpHandler;
31
+ /**
32
+ * Create HTTP bindings for multiple routes as a callable client.
33
+ * Returns a strongly-typed object where each route name maps to an async function
34
+ * with the same signature as the original handler.
35
+ *
36
+ * @typeParam TRoutes - The routes type from the ApiContainer
37
+ * @typeParam K - The subset of route names to include in the client
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const api = new ApiContainer(arch, 'api', {
42
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
43
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
44
+ * });
45
+ *
46
+ * const client = createHttpBindings(endpoint, api, ['hello', 'hellos']);
47
+ * await client.hello('John'); // (name: string) => Promise<string>
48
+ * await client.hellos(); // () => Promise<Greeting[]>
49
+ * ```
50
+ */
51
+ const createHttpBindings = (endpoint, container, routeNames, fetcher = () => ({ fetch })) => {
52
+ return routeNames.reduce((acc, name) => {
53
+ acc[name] = (0, exports.httpHandler)(endpoint, container, name, fetcher);
54
+ return acc;
55
+ }, {});
56
+ };
57
+ exports.createHttpBindings = createHttpBindings;
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2h0dHAtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQTs7O0dBR0c7QUFDSSxNQUFNLFdBQVcsR0FBRyxDQUl6QixRQUF5QixFQUN6QixTQUFnQyxFQUNoQyxTQUFZLEVBQ1osVUFBbUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBQyxDQUFDLEVBQ1AsRUFBRTtJQUM3QixNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRTVDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFbEQsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLEdBQUcsSUFBVyxFQUFFLEVBQUU7UUFDdkMsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FDM0IsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEdBQUcsSUFBSSxFQUFFLENBQzdCLENBQUM7UUFFRixNQUFNLE9BQU8sR0FBZ0I7WUFDM0IsTUFBTSxFQUFFLE1BQU0sSUFBSSxLQUFLO1lBQ3ZCLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRTtZQUMvQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxJQUFJLE1BQU0sS0FBSyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNO2dCQUM1RSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7Z0JBQ25ELENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDUixDQUFDO1FBRUYsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxFQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9HLENBQUM7UUFFRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDLENBQUM7SUFFRixPQUFPLE9BQW9DLENBQUM7QUFDOUMsQ0FBQyxDQUFDO0FBdkNXLFFBQUEsV0FBVyxlQXVDdEI7QUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNJLE1BQU0sa0JBQWtCLEdBQUcsQ0FJaEMsUUFBeUIsRUFDekIsU0FBZ0MsRUFDaEMsVUFBd0IsRUFDeEIsVUFBbUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFDLEtBQUssRUFBQyxDQUFDLEVBQ0QsRUFBRTtJQUNuQyxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQ3RCLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ1osR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUEsbUJBQVcsRUFBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1RCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFDRCxFQUFxQyxDQUN0QyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBaEJXLFFBQUEsa0JBQWtCLHNCQWdCN0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcGlDb250YWluZXIsIEFwaVJvdXRlcywgUm91dGVIYW5kbGVycyB9IGZyb20gJy4vYXBpLWNvbnRhaW5lcic7XG5pbXBvcnQgeyBGdW5jdGlvbkhhbmRsZXIgfSBmcm9tICcuL2Z1bmN0aW9uJztcbmltcG9ydCB7IFNlcnZpY2VFbmRwb2ludCB9IGZyb20gJy4vYmluZGluZyc7XG5cbmV4cG9ydCB0eXBlIEZldGNoZXIgPSAoKSA9PiB7IGZldGNoOiB0eXBlb2YgZmV0Y2ggfTtcblxuLyoqXG4gKiBDcmVhdGUgYW4gSFRUUCBoYW5kbGVyIGZvciBhIHJvdXRlIGJ5IG5hbWUuXG4gKiBMb29rcyB1cCB0aGUgcm91dGUgcGF0aCBmcm9tIHRoZSBjb250YWluZXIncyByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGNvbnN0IGh0dHBIYW5kbGVyID0gPFxuICBUUm91dGVzIGV4dGVuZHMgQXBpUm91dGVzLFxuICBLIGV4dGVuZHMga2V5b2YgVFJvdXRlcyAmIHN0cmluZ1xuPihcbiAgZW5kcG9pbnQ6IFNlcnZpY2VFbmRwb2ludCxcbiAgY29udGFpbmVyOiBBcGlDb250YWluZXI8VFJvdXRlcz4sXG4gIHJvdXRlTmFtZTogSyxcbiAgZmV0Y2hlcjogRmV0Y2hlciA9ICgpID0+ICh7ZmV0Y2h9KVxuKTogUm91dGVIYW5kbGVyczxUUm91dGVzPltLXSA9PiB7XG4gIGNvbnN0IHJvdXRlID0gY29udGFpbmVyLmdldFJvdXRlKHJvdXRlTmFtZSk7XG5cbiAgY29uc3QgW21ldGhvZCwgcGF0aF0gPSByb3V0ZS5wYXRoLnNwbGl0KCcgJyk7XG4gIGNvbnN0IHBhdGhQYXJhbXMgPSBwYXRoLm1hdGNoKC9cXHsoXFx3KylcXH0vZykgfHwgW107XG5cbiAgY29uc3QgaGFuZGxlciA9IGFzeW5jICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIGNvbnN0IHVybCA9IHBhdGhQYXJhbXMucmVkdWNlKFxuICAgICAgKHUsIHBhcmFtLCBpKSA9PiBhcmdzW2ldICE9PSB1bmRlZmluZWQgPyB1LnJlcGxhY2UocGFyYW0sIGVuY29kZVVSSUNvbXBvbmVudChTdHJpbmcoYXJnc1tpXSkpKSA6IHUsXG4gICAgICBgJHtlbmRwb2ludC5iYXNlVXJsfSR7cGF0aH1gXG4gICAgKTtcblxuICAgIGNvbnN0IG9wdGlvbnM6IFJlcXVlc3RJbml0ID0ge1xuICAgICAgbWV0aG9kOiBtZXRob2QgfHwgJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIC4uLigobWV0aG9kID09PSAnUE9TVCcgfHwgbWV0aG9kID09PSAnUFVUJykgJiYgYXJncy5sZW5ndGggPiBwYXRoUGFyYW1zLmxlbmd0aFxuICAgICAgICA/IHsgYm9keTogSlNPTi5zdHJpbmdpZnkoYXJnc1twYXRoUGFyYW1zLmxlbmd0aF0pIH1cbiAgICAgICAgOiB7fSlcbiAgICB9O1xuXG4gICAgY29uc29sZS5sb2coJ0hUVFAgaGFuZGxlci4gV2lsbCBmZXRjaCcsIHt1cmwsIG9wdGlvbnN9KTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoZXIoKS5mZXRjaCh1cmwsIG9wdGlvbnMpO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZW1vdGUgY2FsbCB0byAke3VybH0gd2l0aCAke0pTT04uc3RyaW5naWZ5KG9wdGlvbnMpfSBmYWlsZWQ6ICR7SlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpfWApO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gIH07XG5cbiAgcmV0dXJuIGhhbmRsZXIgYXMgUm91dGVIYW5kbGVyczxUUm91dGVzPltLXTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIEhUVFAgYmluZGluZ3MgZm9yIG11bHRpcGxlIHJvdXRlcyBhcyBhIGNhbGxhYmxlIGNsaWVudC5cbiAqIFJldHVybnMgYSBzdHJvbmdseS10eXBlZCBvYmplY3Qgd2hlcmUgZWFjaCByb3V0ZSBuYW1lIG1hcHMgdG8gYW4gYXN5bmMgZnVuY3Rpb25cbiAqIHdpdGggdGhlIHNhbWUgc2lnbmF0dXJlIGFzIHRoZSBvcmlnaW5hbCBoYW5kbGVyLlxuICpcbiAqIEB0eXBlUGFyYW0gVFJvdXRlcyAtIFRoZSByb3V0ZXMgdHlwZSBmcm9tIHRoZSBBcGlDb250YWluZXJcbiAqIEB0eXBlUGFyYW0gSyAtIFRoZSBzdWJzZXQgb2Ygcm91dGUgbmFtZXMgdG8gaW5jbHVkZSBpbiB0aGUgY2xpZW50XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGFwaSA9IG5ldyBBcGlDb250YWluZXIoYXJjaCwgJ2FwaScsIHtcbiAqICAgaGVsbG86IHsgcGF0aDogJ0dFVCAvdjEvYXBpL2hlbGxvL3tuYW1lfScsIGhhbmRsZXI6IGhlbGxvRnVuY3Rpb24gfSxcbiAqICAgaGVsbG9zOiB7IHBhdGg6ICdHRVQgL3YxL2FwaS9oZWxsb3MnLCBoYW5kbGVyOiBoZWxsb3NGdW5jdGlvbiB9XG4gKiB9KTtcbiAqXG4gKiBjb25zdCBjbGllbnQgPSBjcmVhdGVIdHRwQmluZGluZ3MoZW5kcG9pbnQsIGFwaSwgWydoZWxsbycsICdoZWxsb3MnXSk7XG4gKiBhd2FpdCBjbGllbnQuaGVsbG8oJ0pvaG4nKTsgIC8vIChuYW1lOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nPlxuICogYXdhaXQgY2xpZW50LmhlbGxvcygpOyAgICAgICAvLyAoKSA9PiBQcm9taXNlPEdyZWV0aW5nW10+XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUh0dHBCaW5kaW5ncyA9IDxcbiAgVFJvdXRlcyBleHRlbmRzIEFwaVJvdXRlcyxcbiAgSyBleHRlbmRzIGtleW9mIFRSb3V0ZXMgJiBzdHJpbmdcbj4oXG4gIGVuZHBvaW50OiBTZXJ2aWNlRW5kcG9pbnQsXG4gIGNvbnRhaW5lcjogQXBpQ29udGFpbmVyPFRSb3V0ZXM+LFxuICByb3V0ZU5hbWVzOiByZWFkb25seSBLW10sXG4gIGZldGNoZXI6IEZldGNoZXIgPSAoKSA9PiAoe2ZldGNofSlcbik6IFBpY2s8Um91dGVIYW5kbGVyczxUUm91dGVzPiwgSz4gPT4ge1xuICByZXR1cm4gcm91dGVOYW1lcy5yZWR1Y2UoXG4gICAgKGFjYywgbmFtZSkgPT4ge1xuICAgICAgYWNjW25hbWVdID0gaHR0cEhhbmRsZXIoZW5kcG9pbnQsIGNvbnRhaW5lciwgbmFtZSwgZmV0Y2hlcik7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAge30gYXMgUGljazxSb3V0ZUhhbmRsZXJzPFRSb3V0ZXM+LCBLPlxuICApO1xufTtcbiJdfQ==
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Construct } from 'constructs';
2
2
  export { Architecture, ArchitectureDefinition, ComponentDefinition } from './architecture';
3
3
  export { Function, TBDFunction, FunctionHandler } from './function';
4
- export { ApiContainer, ApiRoutes, RouteEntry } from './api-container';
4
+ export { ApiContainer, ApiRoutes, RouteEntry, HandlerOf, RouteHandlers } from './api-container';
5
5
  export { ArchitectureBinding, ServiceEndpoint, architectureBinding } from './binding';
6
+ export { httpHandler, createHttpBindings, Fetcher } from './http-handler';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.architectureBinding = exports.ArchitectureBinding = exports.ApiContainer = exports.TBDFunction = exports.Function = exports.Architecture = exports.Construct = void 0;
3
+ exports.createHttpBindings = exports.httpHandler = exports.architectureBinding = exports.ArchitectureBinding = exports.ApiContainer = exports.TBDFunction = exports.Function = exports.Architecture = exports.Construct = void 0;
4
4
  var constructs_1 = require("constructs");
5
5
  Object.defineProperty(exports, "Construct", { enumerable: true, get: function () { return constructs_1.Construct; } });
6
6
  var architecture_1 = require("./architecture");
@@ -13,4 +13,7 @@ Object.defineProperty(exports, "ApiContainer", { enumerable: true, get: function
13
13
  var binding_1 = require("./binding");
14
14
  Object.defineProperty(exports, "ArchitectureBinding", { enumerable: true, get: function () { return binding_1.ArchitectureBinding; } });
15
15
  Object.defineProperty(exports, "architectureBinding", { enumerable: true, get: function () { return binding_1.architectureBinding; } });
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQXVDO0FBQTlCLHVHQUFBLFNBQVMsT0FBQTtBQUNsQiwrQ0FBMkY7QUFBbEYsNEdBQUEsWUFBWSxPQUFBO0FBQ3JCLHVDQUFvRTtBQUEzRCxvR0FBQSxRQUFRLE9BQUE7QUFBRSx1R0FBQSxXQUFXLE9BQUE7QUFDOUIsaURBQXNFO0FBQTdELDZHQUFBLFlBQVksT0FBQTtBQUNyQixxQ0FBc0Y7QUFBN0UsOEdBQUEsbUJBQW1CLE9BQUE7QUFBbUIsOEdBQUEsbUJBQW1CLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmV4cG9ydCB7IEFyY2hpdGVjdHVyZSwgQXJjaGl0ZWN0dXJlRGVmaW5pdGlvbiwgQ29tcG9uZW50RGVmaW5pdGlvbiB9IGZyb20gJy4vYXJjaGl0ZWN0dXJlJztcbmV4cG9ydCB7IEZ1bmN0aW9uLCBUQkRGdW5jdGlvbiwgRnVuY3Rpb25IYW5kbGVyIH0gZnJvbSAnLi9mdW5jdGlvbic7XG5leHBvcnQgeyBBcGlDb250YWluZXIsIEFwaVJvdXRlcywgUm91dGVFbnRyeSB9IGZyb20gJy4vYXBpLWNvbnRhaW5lcic7XG5leHBvcnQgeyBBcmNoaXRlY3R1cmVCaW5kaW5nLCBTZXJ2aWNlRW5kcG9pbnQsIGFyY2hpdGVjdHVyZUJpbmRpbmcgfSBmcm9tICcuL2JpbmRpbmcnO1xuIl19
16
+ var http_handler_1 = require("./http-handler");
17
+ Object.defineProperty(exports, "httpHandler", { enumerable: true, get: function () { return http_handler_1.httpHandler; } });
18
+ Object.defineProperty(exports, "createHttpBindings", { enumerable: true, get: function () { return http_handler_1.createHttpBindings; } });
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQXVDO0FBQTlCLHVHQUFBLFNBQVMsT0FBQTtBQUNsQiwrQ0FBMkY7QUFBbEYsNEdBQUEsWUFBWSxPQUFBO0FBQ3JCLHVDQUFvRTtBQUEzRCxvR0FBQSxRQUFRLE9BQUE7QUFBRSx1R0FBQSxXQUFXLE9BQUE7QUFDOUIsaURBQWdHO0FBQXZGLDZHQUFBLFlBQVksT0FBQTtBQUNyQixxQ0FBc0Y7QUFBN0UsOEdBQUEsbUJBQW1CLE9BQUE7QUFBbUIsOEdBQUEsbUJBQW1CLE9BQUE7QUFDbEUsK0NBQTBFO0FBQWpFLDJHQUFBLFdBQVcsT0FBQTtBQUFFLGtIQUFBLGtCQUFrQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5leHBvcnQgeyBBcmNoaXRlY3R1cmUsIEFyY2hpdGVjdHVyZURlZmluaXRpb24sIENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuL2FyY2hpdGVjdHVyZSc7XG5leHBvcnQgeyBGdW5jdGlvbiwgVEJERnVuY3Rpb24sIEZ1bmN0aW9uSGFuZGxlciB9IGZyb20gJy4vZnVuY3Rpb24nO1xuZXhwb3J0IHsgQXBpQ29udGFpbmVyLCBBcGlSb3V0ZXMsIFJvdXRlRW50cnksIEhhbmRsZXJPZiwgUm91dGVIYW5kbGVycyB9IGZyb20gJy4vYXBpLWNvbnRhaW5lcic7XG5leHBvcnQgeyBBcmNoaXRlY3R1cmVCaW5kaW5nLCBTZXJ2aWNlRW5kcG9pbnQsIGFyY2hpdGVjdHVyZUJpbmRpbmcgfSBmcm9tICcuL2JpbmRpbmcnO1xuZXhwb3J0IHsgaHR0cEhhbmRsZXIsIGNyZWF0ZUh0dHBCaW5kaW5ncywgRmV0Y2hlciB9IGZyb20gJy4vaHR0cC1oYW5kbGVyJztcbiJdfQ==
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@arinoto/cdk-arch",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "CDK Architecture primitives for event-driven solution architectures",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "module": "dist/index.js",
7
8
  "private": false,
8
9
  "publishConfig": {
9
10
  "access": "public"
@@ -1,31 +1,66 @@
1
1
  import { Construct } from 'constructs';
2
2
  import { Function, TBDFunction } from './function';
3
3
 
4
- export interface ApiRoutes {
5
- [name: string]: RouteEntry;
4
+ /**
5
+ * A route entry that captures the handler's argument and return types.
6
+ */
7
+ export interface RouteEntry<TArgs extends any[] = any[], TReturn = any> {
8
+ path: string;
9
+ handler: Function<TArgs, TReturn>;
6
10
  }
7
11
 
8
- export interface RouteEntry {
9
- path: string;
10
- handler: Function;
12
+ /**
13
+ * Base type for route definitions - maps route names to route entries.
14
+ */
15
+ export type ApiRoutes = {
16
+ [name: string]: RouteEntry;
11
17
  }
12
18
 
13
19
  /**
14
- * Represents an API container that routes requests to functions
20
+ * Extract the handler signature from a Function type.
21
+ */
22
+ export type HandlerOf<T> = T extends Function<infer Args, infer Return>
23
+ ? (...args: Args) => Promise<Return>
24
+ : never;
25
+
26
+ /**
27
+ * Extract handler signatures from all routes in an ApiRoutes type.
28
+ */
29
+ export type RouteHandlers<TRoutes extends ApiRoutes> = {
30
+ [K in keyof TRoutes]: HandlerOf<TRoutes[K]['handler']>;
31
+ };
32
+
33
+ /**
34
+ * Represents an API container that routes requests to functions.
35
+ *
36
+ * @typeParam TRoutes - The type of the routes object, preserving route names and handler signatures.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const api = new ApiContainer(arch, 'api', {
41
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
42
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
43
+ * });
44
+ * // api has type ApiContainer<{ hello: RouteEntry<[string], string>, hellos: RouteEntry<[], Greeting[]> }>
45
+ * ```
15
46
  */
16
- export class ApiContainer extends Construct {
17
- public readonly routes: ApiRoutes;
47
+ export class ApiContainer<TRoutes extends ApiRoutes = ApiRoutes> extends Construct {
48
+ public readonly routes: TRoutes;
18
49
 
19
- constructor(scope: Construct, id: string, routes: ApiRoutes = {}) {
50
+ constructor(scope: Construct, id: string, routes: TRoutes = {} as TRoutes) {
20
51
  super(scope, id);
21
52
  this.routes = routes;
22
53
  }
23
54
 
24
- addRoute(name: string, path: string, handler: Function): void {
25
- this.routes[name] = { path, handler };
55
+ addRoute<TArgs extends any[], TReturn>(
56
+ name: string,
57
+ path: string,
58
+ handler: Function<TArgs, TReturn>
59
+ ): void {
60
+ (this.routes as ApiRoutes)[name] = { path, handler };
26
61
  }
27
62
 
28
- getRoute(name: string): RouteEntry {
63
+ getRoute<K extends keyof TRoutes & string>(name: K): TRoutes[K] {
29
64
  const entry = this.routes[name];
30
65
  if (!entry) {
31
66
  throw new Error(`Route '${name}' not found in container '${this.node.id}'`);
@@ -33,8 +68,8 @@ export class ApiContainer extends Construct {
33
68
  return entry;
34
69
  }
35
70
 
36
- listRoutes() : string[] {
37
- return Object.keys(this.routes);
71
+ listRoutes(): (keyof TRoutes & string)[] {
72
+ return Object.keys(this.routes) as (keyof TRoutes & string)[];
38
73
  }
39
74
 
40
75
  /**
package/src/binding.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import { Construct } from 'constructs';
2
- import { ApiContainer } from './api-container';
2
+ import { ApiContainer, ApiRoutes } from './api-container';
3
3
  import { Function, FunctionHandler } from './function';
4
4
 
5
5
  /**
6
6
  * Service discovery configuration for runtime
7
7
  */
8
8
  export interface ServiceEndpoint {
9
- host: string;
10
- port: number;
9
+ baseUrl: string;
11
10
  }
12
11
 
13
12
  /**
@@ -34,8 +33,8 @@ export class ArchitectureBinding {
34
33
  * Optionally override function implementations with the overloads option.
35
34
  * Overload keys must be route names registered via addRoute.
36
35
  */
37
- bind(component: ApiContainer, options: BindOptions): void {
38
- this.bindings.set(component, { host: options.host, port: options.port });
36
+ bind<TRoutes extends ApiRoutes>(component: ApiContainer<TRoutes>, options: BindOptions): void {
37
+ this.bindings.set(component, { baseUrl: options.baseUrl });
39
38
 
40
39
  Object.entries(options.overloads ?? {}).forEach(([name, handler]) => {
41
40
  const route = component.getRoute(name);
@@ -49,18 +48,6 @@ export class ArchitectureBinding {
49
48
  });
50
49
  }
51
50
 
52
- /**
53
- * Bind a component from environment variables.
54
- * Looks for {PREFIX}_HOST and {PREFIX}_PORT environment variables.
55
- */
56
- bindFromEnv(component: ApiContainer, envPrefix: string, overloads?: Record<string, FunctionHandler>): void {
57
- const host = process.env[`${envPrefix}_HOST`];
58
- const port = process.env[`${envPrefix}_PORT`];
59
- if (host && port) {
60
- this.bind(component, { host, port: parseInt(port), overloads });
61
- }
62
- }
63
-
64
51
  getEndpoint(component: Construct): ServiceEndpoint | undefined {
65
52
  return this.bindings.get(component);
66
53
  }
package/src/function.ts CHANGED
@@ -39,8 +39,6 @@ export class Function<TArgs extends any[] = any[], TReturn = any> extends Constr
39
39
  */
40
40
  export class TBDFunction<TArgs extends any[] = any[], TReturn = any> extends Function<TArgs, TReturn> {
41
41
  constructor(scope: Construct, id: string) {
42
- super(scope, id, (() => {
43
- return Promise.reject(new Error(`Function '${id}' is not implemented. Provide an overload before invoking.`));
44
- }) as FunctionHandler<TArgs, TReturn>);
42
+ super(scope, id, (() => Promise.reject(new Error(`Function '${id}' is not implemented. Provide an overload before invoking.`))) as FunctionHandler<TArgs, TReturn>);
45
43
  }
46
44
  }
@@ -0,0 +1,88 @@
1
+ import { ApiContainer, ApiRoutes, RouteHandlers } from './api-container';
2
+ import { FunctionHandler } from './function';
3
+ import { ServiceEndpoint } from './binding';
4
+
5
+ export type Fetcher = () => { fetch: typeof fetch };
6
+
7
+ /**
8
+ * Create an HTTP handler for a route by name.
9
+ * Looks up the route path from the container's registry.
10
+ */
11
+ export const httpHandler = <
12
+ TRoutes extends ApiRoutes,
13
+ K extends keyof TRoutes & string
14
+ >(
15
+ endpoint: ServiceEndpoint,
16
+ container: ApiContainer<TRoutes>,
17
+ routeName: K,
18
+ fetcher: Fetcher = () => ({fetch})
19
+ ): RouteHandlers<TRoutes>[K] => {
20
+ const route = container.getRoute(routeName);
21
+
22
+ const [method, path] = route.path.split(' ');
23
+ const pathParams = path.match(/\{(\w+)\}/g) || [];
24
+
25
+ const handler = async (...args: any[]) => {
26
+ const url = pathParams.reduce(
27
+ (u, param, i) => args[i] !== undefined ? u.replace(param, encodeURIComponent(String(args[i]))) : u,
28
+ `${endpoint.baseUrl}${path}`
29
+ );
30
+
31
+ const options: RequestInit = {
32
+ method: method || 'GET',
33
+ headers: { 'Content-Type': 'application/json' },
34
+ ...((method === 'POST' || method === 'PUT') && args.length > pathParams.length
35
+ ? { body: JSON.stringify(args[pathParams.length]) }
36
+ : {})
37
+ };
38
+
39
+ console.log('HTTP handler. Will fetch', {url, options});
40
+ const response = await fetcher().fetch(url, options);
41
+
42
+ if (!response.ok) {
43
+ throw new Error(`Remote call to ${url} with ${JSON.stringify(options)} failed: ${JSON.stringify(response)}`);
44
+ }
45
+
46
+ return response.json();
47
+ };
48
+
49
+ return handler as RouteHandlers<TRoutes>[K];
50
+ };
51
+
52
+ /**
53
+ * Create HTTP bindings for multiple routes as a callable client.
54
+ * Returns a strongly-typed object where each route name maps to an async function
55
+ * with the same signature as the original handler.
56
+ *
57
+ * @typeParam TRoutes - The routes type from the ApiContainer
58
+ * @typeParam K - The subset of route names to include in the client
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const api = new ApiContainer(arch, 'api', {
63
+ * hello: { path: 'GET /v1/api/hello/{name}', handler: helloFunction },
64
+ * hellos: { path: 'GET /v1/api/hellos', handler: hellosFunction }
65
+ * });
66
+ *
67
+ * const client = createHttpBindings(endpoint, api, ['hello', 'hellos']);
68
+ * await client.hello('John'); // (name: string) => Promise<string>
69
+ * await client.hellos(); // () => Promise<Greeting[]>
70
+ * ```
71
+ */
72
+ export const createHttpBindings = <
73
+ TRoutes extends ApiRoutes,
74
+ K extends keyof TRoutes & string
75
+ >(
76
+ endpoint: ServiceEndpoint,
77
+ container: ApiContainer<TRoutes>,
78
+ routeNames: readonly K[],
79
+ fetcher: Fetcher = () => ({fetch})
80
+ ): Pick<RouteHandlers<TRoutes>, K> => {
81
+ return routeNames.reduce(
82
+ (acc, name) => {
83
+ acc[name] = httpHandler(endpoint, container, name, fetcher);
84
+ return acc;
85
+ },
86
+ {} as Pick<RouteHandlers<TRoutes>, K>
87
+ );
88
+ };
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { Construct } from 'constructs';
2
2
  export { Architecture, ArchitectureDefinition, ComponentDefinition } from './architecture';
3
3
  export { Function, TBDFunction, FunctionHandler } from './function';
4
- export { ApiContainer, ApiRoutes, RouteEntry } from './api-container';
4
+ export { ApiContainer, ApiRoutes, RouteEntry, HandlerOf, RouteHandlers } from './api-container';
5
5
  export { ArchitectureBinding, ServiceEndpoint, architectureBinding } from './binding';
6
+ export { httpHandler, createHttpBindings, Fetcher } from './http-handler';