@empire-builder-kit/runtime 0.0.1-alpha.1 → 0.0.1-alpha.10
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/auth-backend.d.ts +18 -0
- package/dist/auth-backend.d.ts.map +1 -0
- package/dist/auth-backend.js +57 -0
- package/dist/auth-web.d.ts +18 -0
- package/dist/auth-web.d.ts.map +1 -0
- package/dist/auth-web.js +32 -0
- package/dist/auth.d.ts +26 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +28 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lambda.d.ts +46 -0
- package/dist/lambda.d.ts.map +1 -0
- package/dist/lambda.js +127 -0
- package/dist/observability.d.ts +18 -0
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js +116 -0
- package/package.json +34 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Empire Builder Kit Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Publishable runtime primitives for Empire Builder Kit workspaces and apps.
|
|
|
17
17
|
- `@empire-builder-kit/runtime/frontend`
|
|
18
18
|
- `@empire-builder-kit/runtime/request-context`
|
|
19
19
|
- `@empire-builder-kit/runtime/logging`
|
|
20
|
+
- `@empire-builder-kit/runtime/lambda`
|
|
20
21
|
- `@empire-builder-kit/runtime/observability`
|
|
21
22
|
- `@empire-builder-kit/runtime/response`
|
|
22
23
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BetterAuthConfig, AuthenticatedSession } from './auth';
|
|
2
|
+
import { type JWTVerifyGetKey } from 'jose';
|
|
3
|
+
/**
|
|
4
|
+
* Verifies a Cognito JWT token and returns a typed session.
|
|
5
|
+
* Uses the Cognito JWKS endpoint for validation.
|
|
6
|
+
*/
|
|
7
|
+
export interface CognitoJwtVerifier {
|
|
8
|
+
verify(token: string): Promise<AuthenticatedSession>;
|
|
9
|
+
}
|
|
10
|
+
export interface CognitoJwtVerifierOptions {
|
|
11
|
+
jwks?: JWTVerifyGetKey;
|
|
12
|
+
}
|
|
13
|
+
export declare function createCognitoJwtVerifier(config: BetterAuthConfig, options?: CognitoJwtVerifierOptions): CognitoJwtVerifier;
|
|
14
|
+
/**
|
|
15
|
+
* Extracts a Bearer token from an Authorization header.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractBearerToken(authHeader: string | undefined): string | null;
|
|
18
|
+
//# sourceMappingURL=auth-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-backend.d.ts","sourceRoot":"","sources":["../src/auth-backend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,oBAAoB,EACrB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,MAAM,CAAC;AAEd;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AA+BD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,yBAA8B,GACtC,kBAAkB,CAmCpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,GAAG,IAAI,CAKf"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCognitoJwtVerifier = createCognitoJwtVerifier;
|
|
4
|
+
exports.extractBearerToken = extractBearerToken;
|
|
5
|
+
const auth_1 = require("./auth");
|
|
6
|
+
const jose_1 = require("jose");
|
|
7
|
+
function hasExpectedAudience(payload, clientId) {
|
|
8
|
+
return (payload.aud === clientId ||
|
|
9
|
+
(Array.isArray(payload.aud) && payload.aud.includes(clientId)) ||
|
|
10
|
+
payload.client_id === clientId);
|
|
11
|
+
}
|
|
12
|
+
function normalizeGroups(groups) {
|
|
13
|
+
if (!Array.isArray(groups)) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const normalized = groups.filter((group) => typeof group === 'string');
|
|
17
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
18
|
+
}
|
|
19
|
+
function createCognitoJwtVerifier(config, options = {}) {
|
|
20
|
+
const jwks = options.jwks ??
|
|
21
|
+
(0, jose_1.createRemoteJWKSet)(new URL(`${config.issuerUrl}/.well-known/jwks.json`));
|
|
22
|
+
return {
|
|
23
|
+
async verify(token) {
|
|
24
|
+
const parts = token.split('.');
|
|
25
|
+
if (parts.length !== 3) {
|
|
26
|
+
throw new Error('Invalid JWT format');
|
|
27
|
+
}
|
|
28
|
+
const { payload } = await (0, jose_1.jwtVerify)(token, jwks, {
|
|
29
|
+
algorithms: ['RS256'],
|
|
30
|
+
issuer: config.issuerUrl,
|
|
31
|
+
});
|
|
32
|
+
if (!hasExpectedAudience(payload, config.clientId)) {
|
|
33
|
+
throw new Error('Invalid audience');
|
|
34
|
+
}
|
|
35
|
+
if (!payload.sub) {
|
|
36
|
+
throw new Error('Invalid subject');
|
|
37
|
+
}
|
|
38
|
+
return (0, auth_1.sessionFromCognitoToken)({
|
|
39
|
+
sub: payload.sub,
|
|
40
|
+
email: payload.email,
|
|
41
|
+
'cognito:username': payload['cognito:username'],
|
|
42
|
+
'cognito:groups': normalizeGroups(payload['cognito:groups']),
|
|
43
|
+
exp: payload.exp,
|
|
44
|
+
iat: payload.iat,
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Extracts a Bearer token from an Authorization header.
|
|
51
|
+
*/
|
|
52
|
+
function extractBearerToken(authHeader) {
|
|
53
|
+
if (!authHeader?.startsWith('Bearer ')) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return authHeader.slice(7).trim() || null;
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BetterAuthConfig } from './auth';
|
|
2
|
+
/**
|
|
3
|
+
* Creates Next.js middleware configuration for auth.
|
|
4
|
+
* Validates JWT from cookies or Authorization header.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createAuthMiddlewareConfig(config: BetterAuthConfig): {
|
|
7
|
+
verifier: import("./auth-backend").CognitoJwtVerifier;
|
|
8
|
+
/**
|
|
9
|
+
* Extract and verify session from a Next.js request.
|
|
10
|
+
* Checks Authorization header first, then auth cookie.
|
|
11
|
+
*/
|
|
12
|
+
getSession(request: {
|
|
13
|
+
headers: {
|
|
14
|
+
get(name: string): string | null;
|
|
15
|
+
};
|
|
16
|
+
}): Promise<import("./auth").AuthenticatedSession | null>;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=auth-web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-web.d.ts","sourceRoot":"","sources":["../src/auth-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAG1C;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,gBAAgB;;IAK/D;;;OAGG;wBACuB;QACxB,OAAO,EAAE;YAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;SAAE,CAAC;KAC/C;EAiBJ"}
|
package/dist/auth-web.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthMiddlewareConfig = createAuthMiddlewareConfig;
|
|
4
|
+
const auth_backend_1 = require("./auth-backend");
|
|
5
|
+
/**
|
|
6
|
+
* Creates Next.js middleware configuration for auth.
|
|
7
|
+
* Validates JWT from cookies or Authorization header.
|
|
8
|
+
*/
|
|
9
|
+
function createAuthMiddlewareConfig(config) {
|
|
10
|
+
const verifier = (0, auth_backend_1.createCognitoJwtVerifier)(config);
|
|
11
|
+
return {
|
|
12
|
+
verifier,
|
|
13
|
+
/**
|
|
14
|
+
* Extract and verify session from a Next.js request.
|
|
15
|
+
* Checks Authorization header first, then auth cookie.
|
|
16
|
+
*/
|
|
17
|
+
async getSession(request) {
|
|
18
|
+
const authHeader = request.headers.get('authorization');
|
|
19
|
+
const token = (0, auth_backend_1.extractBearerToken)(authHeader ?? undefined) ??
|
|
20
|
+
request.headers.get('x-auth-token');
|
|
21
|
+
if (!token) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
return await verifier.verify(token);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -39,4 +39,30 @@ export declare function createAuthenticatedSession(input: AuthenticatedSessionIn
|
|
|
39
39
|
export declare function isAuthenticatedSession(session: AuthSession): session is AuthenticatedSession;
|
|
40
40
|
export declare function toRequestActor(session: AuthSession): RequestActor | undefined;
|
|
41
41
|
export declare function toSessionLogMetadata(session: AuthSession): RequestMetadata;
|
|
42
|
+
/**
|
|
43
|
+
* BetterAuth configuration contract.
|
|
44
|
+
*
|
|
45
|
+
* App groups consume auth from the core SDK. The core app group owns
|
|
46
|
+
* the Cognito user pool and exposes these connection details so
|
|
47
|
+
* BetterAuth can be configured against the shared pool.
|
|
48
|
+
*/
|
|
49
|
+
export interface BetterAuthConfig {
|
|
50
|
+
provider: 'cognito';
|
|
51
|
+
userPoolId: string;
|
|
52
|
+
clientId: string;
|
|
53
|
+
issuerUrl: string;
|
|
54
|
+
}
|
|
55
|
+
export declare function createBetterAuthConfig(options: {
|
|
56
|
+
userPoolId: string;
|
|
57
|
+
clientId: string;
|
|
58
|
+
region?: string;
|
|
59
|
+
}): BetterAuthConfig;
|
|
60
|
+
export declare function sessionFromCognitoToken(decoded: {
|
|
61
|
+
sub: string;
|
|
62
|
+
email?: string;
|
|
63
|
+
'cognito:username'?: string;
|
|
64
|
+
'cognito:groups'?: string[];
|
|
65
|
+
exp?: number;
|
|
66
|
+
iat?: number;
|
|
67
|
+
}): AuthenticatedSession;
|
|
42
68
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAmCX,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,qBAA0B,GAChC,WAAW,CAQb;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,yBAAyB,GAC/B,oBAAoB,CAMtB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,GACnB,OAAO,IAAI,oBAAoB,CAEjC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAS7E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAe1E"}
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAmCX,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,qBAA0B,GAChC,WAAW,CAQb;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,yBAAyB,GAC/B,oBAAoB,CAMtB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,GACnB,OAAO,IAAI,oBAAoB,CAEjC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAS7E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAe1E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,gBAAgB,CAQnB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,oBAAoB,CAgBvB"}
|
package/dist/auth.js
CHANGED
|
@@ -6,6 +6,8 @@ exports.createAuthenticatedSession = createAuthenticatedSession;
|
|
|
6
6
|
exports.isAuthenticatedSession = isAuthenticatedSession;
|
|
7
7
|
exports.toRequestActor = toRequestActor;
|
|
8
8
|
exports.toSessionLogMetadata = toSessionLogMetadata;
|
|
9
|
+
exports.createBetterAuthConfig = createBetterAuthConfig;
|
|
10
|
+
exports.sessionFromCognitoToken = sessionFromCognitoToken;
|
|
9
11
|
exports.authContract = {
|
|
10
12
|
exportPath: '@empire-builder-kit/runtime/auth',
|
|
11
13
|
packageName: '@empire-builder-kit/runtime',
|
|
@@ -77,3 +79,29 @@ function toSessionLogMetadata(session) {
|
|
|
77
79
|
...session.metadata,
|
|
78
80
|
});
|
|
79
81
|
}
|
|
82
|
+
function createBetterAuthConfig(options) {
|
|
83
|
+
const region = options.region ?? 'us-east-1';
|
|
84
|
+
return {
|
|
85
|
+
provider: 'cognito',
|
|
86
|
+
userPoolId: options.userPoolId,
|
|
87
|
+
clientId: options.clientId,
|
|
88
|
+
issuerUrl: `https://cognito-idp.${region}.amazonaws.com/${options.userPoolId}`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function sessionFromCognitoToken(decoded) {
|
|
92
|
+
return createAuthenticatedSession({
|
|
93
|
+
subject: {
|
|
94
|
+
id: decoded.sub,
|
|
95
|
+
email: decoded.email,
|
|
96
|
+
displayName: decoded['cognito:username'],
|
|
97
|
+
roles: decoded['cognito:groups'],
|
|
98
|
+
type: 'user',
|
|
99
|
+
},
|
|
100
|
+
expiresAt: decoded.exp
|
|
101
|
+
? new Date(decoded.exp * 1000).toISOString()
|
|
102
|
+
: undefined,
|
|
103
|
+
issuedAt: decoded.iat
|
|
104
|
+
? new Date(decoded.iat * 1000).toISOString()
|
|
105
|
+
: undefined,
|
|
106
|
+
});
|
|
107
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,12 @@ export * from './auth';
|
|
|
2
2
|
export * from './config';
|
|
3
3
|
export * from './frontend';
|
|
4
4
|
export * from './logging';
|
|
5
|
+
export * from './lambda';
|
|
5
6
|
export * from './observability';
|
|
6
7
|
export * from './request-context';
|
|
7
8
|
export * from './response';
|
|
8
9
|
export declare const runtimePackage: {
|
|
9
|
-
readonly exports: readonly ["@empire-builder-kit/runtime/auth", "@empire-builder-kit/runtime/config", "@empire-builder-kit/runtime/frontend", "@empire-builder-kit/runtime/request-context", "@empire-builder-kit/runtime/logging", "@empire-builder-kit/runtime/observability", "@empire-builder-kit/runtime/response"];
|
|
10
|
+
readonly exports: readonly ["@empire-builder-kit/runtime/auth", "@empire-builder-kit/runtime/config", "@empire-builder-kit/runtime/frontend", "@empire-builder-kit/runtime/request-context", "@empire-builder-kit/runtime/logging", "@empire-builder-kit/runtime/lambda", "@empire-builder-kit/runtime/observability", "@empire-builder-kit/runtime/response"];
|
|
10
11
|
readonly name: "@empire-builder-kit/runtime";
|
|
11
12
|
};
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAE3B,eAAO,MAAM,cAAc;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAE3B,eAAO,MAAM,cAAc;;;CAYjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ tslib_1.__exportStar(require("./auth"), exports);
|
|
|
6
6
|
tslib_1.__exportStar(require("./config"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./frontend"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./logging"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./lambda"), exports);
|
|
9
10
|
tslib_1.__exportStar(require("./observability"), exports);
|
|
10
11
|
tslib_1.__exportStar(require("./request-context"), exports);
|
|
11
12
|
tslib_1.__exportStar(require("./response"), exports);
|
|
@@ -16,6 +17,7 @@ exports.runtimePackage = {
|
|
|
16
17
|
'@empire-builder-kit/runtime/frontend',
|
|
17
18
|
'@empire-builder-kit/runtime/request-context',
|
|
18
19
|
'@empire-builder-kit/runtime/logging',
|
|
20
|
+
'@empire-builder-kit/runtime/lambda',
|
|
19
21
|
'@empire-builder-kit/runtime/observability',
|
|
20
22
|
'@empire-builder-kit/runtime/response',
|
|
21
23
|
],
|
package/dist/lambda.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Logger } from './logging';
|
|
2
|
+
import { type RequestContext } from './request-context';
|
|
3
|
+
import { type AppResponse } from './response';
|
|
4
|
+
export interface RuntimeHttpEvent {
|
|
5
|
+
body?: string | null;
|
|
6
|
+
headers?: Record<string, string | undefined> | null;
|
|
7
|
+
rawPath?: string;
|
|
8
|
+
requestContext?: {
|
|
9
|
+
http?: {
|
|
10
|
+
method?: string;
|
|
11
|
+
path?: string;
|
|
12
|
+
sourceIp?: string;
|
|
13
|
+
userAgent?: string;
|
|
14
|
+
};
|
|
15
|
+
requestId?: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface RuntimeHttpJsonResponse {
|
|
19
|
+
body: string;
|
|
20
|
+
headers: Record<string, string>;
|
|
21
|
+
statusCode: number;
|
|
22
|
+
}
|
|
23
|
+
export interface RuntimeHttpHandlerInput<E extends RuntimeHttpEvent = RuntimeHttpEvent> {
|
|
24
|
+
context: RequestContext;
|
|
25
|
+
event: E;
|
|
26
|
+
logger: Logger;
|
|
27
|
+
}
|
|
28
|
+
export interface CreateHttpJsonHandlerOptions<T, E extends RuntimeHttpEvent = RuntimeHttpEvent> {
|
|
29
|
+
app: string;
|
|
30
|
+
handle(input: RuntimeHttpHandlerInput<E>): Promise<T> | T;
|
|
31
|
+
includeErrorDetails?: boolean;
|
|
32
|
+
logger?: Logger;
|
|
33
|
+
operation: string;
|
|
34
|
+
service?: string;
|
|
35
|
+
stage?: string;
|
|
36
|
+
successStatus?: number;
|
|
37
|
+
}
|
|
38
|
+
export type RuntimeHttpJsonHandler<E extends RuntimeHttpEvent = RuntimeHttpEvent> = (event: E) => Promise<RuntimeHttpJsonResponse>;
|
|
39
|
+
export declare const lambdaContract: {
|
|
40
|
+
readonly defaultResponseFormat: "json";
|
|
41
|
+
readonly exportPath: "@empire-builder-kit/runtime/lambda";
|
|
42
|
+
readonly packageName: "@empire-builder-kit/runtime";
|
|
43
|
+
};
|
|
44
|
+
export declare function toHttpJsonResponse<T>(response: AppResponse<T>): RuntimeHttpJsonResponse;
|
|
45
|
+
export declare function createHttpJsonHandler<T, E extends RuntimeHttpEvent = RuntimeHttpEvent>(options: CreateHttpJsonHandlerOptions<T, E>): RuntimeHttpJsonHandler<E>;
|
|
46
|
+
//# sourceMappingURL=lambda.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambda.d.ts","sourceRoot":"","sources":["../src/lambda.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE;QACf,IAAI,CAAC,EAAE;YACL,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB,CACtC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAE7C,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,CAAC,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,4BAA4B,CAC3C,CAAC,EACD,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAE7C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,sBAAsB,CAChC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAC3C,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEnD,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AA8BX,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GACvB,uBAAuB,CAczB;AAED,wBAAgB,qBAAqB,CACnC,CAAC,EACD,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAC7C,OAAO,EAAE,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAgGxE"}
|
package/dist/lambda.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lambdaContract = void 0;
|
|
4
|
+
exports.toHttpJsonResponse = toHttpJsonResponse;
|
|
5
|
+
exports.createHttpJsonHandler = createHttpJsonHandler;
|
|
6
|
+
const logging_1 = require("./logging");
|
|
7
|
+
const request_context_1 = require("./request-context");
|
|
8
|
+
const response_1 = require("./response");
|
|
9
|
+
exports.lambdaContract = {
|
|
10
|
+
defaultResponseFormat: 'json',
|
|
11
|
+
exportPath: '@empire-builder-kit/runtime/lambda',
|
|
12
|
+
packageName: '@empire-builder-kit/runtime',
|
|
13
|
+
};
|
|
14
|
+
function getHeader(headers, name) {
|
|
15
|
+
if (!headers) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const lowerName = name.toLowerCase();
|
|
19
|
+
const entry = Object.entries(headers).find(([key]) => key.toLowerCase() === lowerName);
|
|
20
|
+
return entry?.[1];
|
|
21
|
+
}
|
|
22
|
+
function resolveStage(stage) {
|
|
23
|
+
return stage ?? process.env.SST_STAGE ?? process.env.STAGE ?? 'development';
|
|
24
|
+
}
|
|
25
|
+
function createResponseMeta(context) {
|
|
26
|
+
return {
|
|
27
|
+
correlationId: context.correlationId,
|
|
28
|
+
requestId: context.requestId,
|
|
29
|
+
stage: context.stage,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function toHttpJsonResponse(response) {
|
|
33
|
+
return {
|
|
34
|
+
body: JSON.stringify(response),
|
|
35
|
+
headers: {
|
|
36
|
+
'content-type': 'application/json',
|
|
37
|
+
...(response.meta?.correlationId
|
|
38
|
+
? { 'x-correlation-id': String(response.meta.correlationId) }
|
|
39
|
+
: {}),
|
|
40
|
+
...(response.meta?.requestId
|
|
41
|
+
? { 'x-request-id': String(response.meta.requestId) }
|
|
42
|
+
: {}),
|
|
43
|
+
},
|
|
44
|
+
statusCode: response.status,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function createHttpJsonHandler(options) {
|
|
48
|
+
const stage = resolveStage(options.stage);
|
|
49
|
+
const baseLogger = options.logger ??
|
|
50
|
+
(0, logging_1.createLogger)({
|
|
51
|
+
app: options.app,
|
|
52
|
+
service: options.service ?? options.operation,
|
|
53
|
+
stage,
|
|
54
|
+
});
|
|
55
|
+
return async (event) => {
|
|
56
|
+
const requestId = getHeader(event.headers, 'x-request-id') ??
|
|
57
|
+
event.requestContext?.requestId;
|
|
58
|
+
const context = (0, request_context_1.createRequestContext)({
|
|
59
|
+
app: options.app,
|
|
60
|
+
correlationId: getHeader(event.headers, 'x-correlation-id') ?? requestId,
|
|
61
|
+
metadata: {
|
|
62
|
+
method: event.requestContext?.http?.method,
|
|
63
|
+
path: event.rawPath ?? event.requestContext?.http?.path,
|
|
64
|
+
sourceIp: event.requestContext?.http?.sourceIp,
|
|
65
|
+
userAgent: event.requestContext?.http?.userAgent,
|
|
66
|
+
},
|
|
67
|
+
operation: options.operation,
|
|
68
|
+
requestId,
|
|
69
|
+
stage,
|
|
70
|
+
});
|
|
71
|
+
const requestLogger = baseLogger.child({
|
|
72
|
+
context,
|
|
73
|
+
service: options.service ?? options.operation,
|
|
74
|
+
stage,
|
|
75
|
+
});
|
|
76
|
+
requestLogger.info(`${options.app}.${options.operation} request received`, {
|
|
77
|
+
metadata: {
|
|
78
|
+
method: event.requestContext?.http?.method,
|
|
79
|
+
path: event.rawPath ?? event.requestContext?.http?.path,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
try {
|
|
83
|
+
const data = await options.handle({
|
|
84
|
+
context,
|
|
85
|
+
event,
|
|
86
|
+
logger: requestLogger,
|
|
87
|
+
});
|
|
88
|
+
const response = (0, response_1.createSuccessResponse)(data, {
|
|
89
|
+
meta: createResponseMeta(context),
|
|
90
|
+
status: options.successStatus,
|
|
91
|
+
});
|
|
92
|
+
requestLogger.info(`${options.app}.${options.operation} request completed`, {
|
|
93
|
+
metadata: {
|
|
94
|
+
status: response.status,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
const httpResponse = toHttpJsonResponse(response);
|
|
98
|
+
return {
|
|
99
|
+
...httpResponse,
|
|
100
|
+
headers: {
|
|
101
|
+
...httpResponse.headers,
|
|
102
|
+
...(0, request_context_1.toRequestHeaders)(context),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
const response = (0, response_1.createErrorResponse)(error, {
|
|
108
|
+
includeDetails: options.includeErrorDetails,
|
|
109
|
+
meta: createResponseMeta(context),
|
|
110
|
+
});
|
|
111
|
+
requestLogger.error(`${options.app}.${options.operation} request failed`, {
|
|
112
|
+
error,
|
|
113
|
+
metadata: {
|
|
114
|
+
status: response.status,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
const httpResponse = toHttpJsonResponse(response);
|
|
118
|
+
return {
|
|
119
|
+
...httpResponse,
|
|
120
|
+
headers: {
|
|
121
|
+
...httpResponse.headers,
|
|
122
|
+
...(0, request_context_1.toRequestHeaders)(context),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
package/dist/observability.d.ts
CHANGED
|
@@ -53,6 +53,22 @@ export interface QueueAlarmRegistration extends QueueAlarmInput {
|
|
|
53
53
|
thresholds: QueueAlertThresholds;
|
|
54
54
|
}
|
|
55
55
|
export type MonitoringOwner = 'platform' | 'product';
|
|
56
|
+
export type AppGroupAlarmKind = 'app-runtime-errors' | 'web-5xx-errors' | 'function-errors' | 'runtime-smoke-failures';
|
|
57
|
+
export interface AppGroupObservabilityInput {
|
|
58
|
+
app: string;
|
|
59
|
+
functions?: readonly string[];
|
|
60
|
+
owner?: MonitoringOwner;
|
|
61
|
+
stage: string;
|
|
62
|
+
summary?: string;
|
|
63
|
+
webApps?: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
export interface AppGroupObservabilityRegistration extends AppGroupObservabilityInput {
|
|
66
|
+
alarms: AlarmDefinition[];
|
|
67
|
+
dashboards: MonitoringDashboardRegistration[];
|
|
68
|
+
owner: MonitoringOwner;
|
|
69
|
+
queues: QueueAlarmRegistration[];
|
|
70
|
+
summary: string;
|
|
71
|
+
}
|
|
56
72
|
export interface AppGroupMonitoringRegistration {
|
|
57
73
|
app: string;
|
|
58
74
|
dashboards: MonitoringDashboardRegistration[];
|
|
@@ -67,5 +83,7 @@ export declare function createQueueAlarmDefinitions(input: QueueAlarmInput): Ala
|
|
|
67
83
|
export declare function createDashboardPath(input: DashboardPathInput): string;
|
|
68
84
|
export declare function createDashboardRegistration(input: DashboardRegistrationInput): MonitoringDashboardRegistration;
|
|
69
85
|
export declare function createQueueAlarmRegistration(input: QueueAlarmRegistrationInput): QueueAlarmRegistration;
|
|
86
|
+
export declare function createDefaultAppGroupAlarmDefinitions(input: AppGroupObservabilityInput): AlarmDefinition[];
|
|
87
|
+
export declare function createAppGroupObservabilityRegistration(input: AppGroupObservabilityInput): AppGroupObservabilityRegistration;
|
|
70
88
|
export declare function defineAppGroupMonitoringRegistration<T extends AppGroupMonitoringRegistration>(registration: T): T;
|
|
71
89
|
//# sourceMappingURL=observability.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,+BAA+B,CAAC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,+BACf,
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"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"}
|
package/dist/observability.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.createQueueAlarmDefinitions = createQueueAlarmDefinitions;
|
|
|
7
7
|
exports.createDashboardPath = createDashboardPath;
|
|
8
8
|
exports.createDashboardRegistration = createDashboardRegistration;
|
|
9
9
|
exports.createQueueAlarmRegistration = createQueueAlarmRegistration;
|
|
10
|
+
exports.createDefaultAppGroupAlarmDefinitions = createDefaultAppGroupAlarmDefinitions;
|
|
11
|
+
exports.createAppGroupObservabilityRegistration = createAppGroupObservabilityRegistration;
|
|
10
12
|
exports.defineAppGroupMonitoringRegistration = defineAppGroupMonitoringRegistration;
|
|
11
13
|
function normalizeSegment(value) {
|
|
12
14
|
return value
|
|
@@ -129,6 +131,120 @@ function createQueueAlarmRegistration(input) {
|
|
|
129
131
|
thresholds,
|
|
130
132
|
};
|
|
131
133
|
}
|
|
134
|
+
function createAppGroupMetricDimensions(input, extra = {}) {
|
|
135
|
+
return {
|
|
136
|
+
App: input.app,
|
|
137
|
+
Stage: input.stage,
|
|
138
|
+
...extra,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function createDefaultAppGroupAlarmDefinitions(input) {
|
|
142
|
+
const namespace = createMetricNamespace(input.app);
|
|
143
|
+
const alarms = [
|
|
144
|
+
{
|
|
145
|
+
comparisonOperator: 'GreaterThanOrEqualToThreshold',
|
|
146
|
+
description: `Runtime errors for ${input.app} exceed the app-group baseline threshold.`,
|
|
147
|
+
dimensions: createAppGroupMetricDimensions(input),
|
|
148
|
+
evaluationPeriods: 1,
|
|
149
|
+
metricName: 'RuntimeErrors',
|
|
150
|
+
name: createAlarmName({
|
|
151
|
+
app: input.app,
|
|
152
|
+
component: 'app',
|
|
153
|
+
metric: 'runtime-errors',
|
|
154
|
+
severity: 'high',
|
|
155
|
+
stage: input.stage,
|
|
156
|
+
}),
|
|
157
|
+
namespace,
|
|
158
|
+
periodSeconds: 60,
|
|
159
|
+
severity: 'high',
|
|
160
|
+
threshold: 1,
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
for (const webApp of input.webApps ?? []) {
|
|
164
|
+
alarms.push({
|
|
165
|
+
comparisonOperator: 'GreaterThanOrEqualToThreshold',
|
|
166
|
+
description: `5xx responses for ${input.app}/${webApp} exceed the web baseline threshold.`,
|
|
167
|
+
dimensions: createAppGroupMetricDimensions(input, {
|
|
168
|
+
WebApp: webApp,
|
|
169
|
+
}),
|
|
170
|
+
evaluationPeriods: 1,
|
|
171
|
+
metricName: 'Web5xxErrors',
|
|
172
|
+
name: createAlarmName({
|
|
173
|
+
app: input.app,
|
|
174
|
+
component: `web-${webApp}`,
|
|
175
|
+
metric: '5xx-errors',
|
|
176
|
+
severity: 'high',
|
|
177
|
+
stage: input.stage,
|
|
178
|
+
}),
|
|
179
|
+
namespace,
|
|
180
|
+
periodSeconds: 60,
|
|
181
|
+
severity: 'high',
|
|
182
|
+
threshold: 1,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
for (const functionName of input.functions ?? []) {
|
|
186
|
+
alarms.push({
|
|
187
|
+
comparisonOperator: 'GreaterThanOrEqualToThreshold',
|
|
188
|
+
description: `Lambda errors for ${input.app}/${functionName} exceed the function baseline threshold.`,
|
|
189
|
+
dimensions: createAppGroupMetricDimensions(input, {
|
|
190
|
+
Function: functionName,
|
|
191
|
+
}),
|
|
192
|
+
evaluationPeriods: 1,
|
|
193
|
+
metricName: 'FunctionErrors',
|
|
194
|
+
name: createAlarmName({
|
|
195
|
+
app: input.app,
|
|
196
|
+
component: `function-${functionName}`,
|
|
197
|
+
metric: 'errors',
|
|
198
|
+
severity: 'high',
|
|
199
|
+
stage: input.stage,
|
|
200
|
+
}),
|
|
201
|
+
namespace,
|
|
202
|
+
periodSeconds: 60,
|
|
203
|
+
severity: 'high',
|
|
204
|
+
threshold: 1,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
alarms.push({
|
|
208
|
+
comparisonOperator: 'GreaterThanOrEqualToThreshold',
|
|
209
|
+
description: `Runtime smoke failures for ${input.app} exceed the release-readiness threshold.`,
|
|
210
|
+
dimensions: createAppGroupMetricDimensions(input),
|
|
211
|
+
evaluationPeriods: 1,
|
|
212
|
+
metricName: 'RuntimeSmokeFailures',
|
|
213
|
+
name: createAlarmName({
|
|
214
|
+
app: input.app,
|
|
215
|
+
component: 'runtime-smoke',
|
|
216
|
+
metric: 'failures',
|
|
217
|
+
severity: 'critical',
|
|
218
|
+
stage: input.stage,
|
|
219
|
+
}),
|
|
220
|
+
namespace,
|
|
221
|
+
periodSeconds: 300,
|
|
222
|
+
severity: 'critical',
|
|
223
|
+
threshold: 1,
|
|
224
|
+
});
|
|
225
|
+
return alarms;
|
|
226
|
+
}
|
|
227
|
+
function createAppGroupObservabilityRegistration(input) {
|
|
228
|
+
const owner = input.owner ?? 'product';
|
|
229
|
+
const summary = input.summary ??
|
|
230
|
+
`${input.app} app-group CloudWatch baseline for runtime health, web health, function errors, and smoke validation.`;
|
|
231
|
+
return {
|
|
232
|
+
...input,
|
|
233
|
+
alarms: createDefaultAppGroupAlarmDefinitions(input),
|
|
234
|
+
dashboards: [
|
|
235
|
+
createDashboardRegistration({
|
|
236
|
+
app: input.app,
|
|
237
|
+
dashboard: 'operations',
|
|
238
|
+
description: summary,
|
|
239
|
+
stage: input.stage,
|
|
240
|
+
title: `${input.app} Operations`,
|
|
241
|
+
}),
|
|
242
|
+
],
|
|
243
|
+
owner,
|
|
244
|
+
queues: [],
|
|
245
|
+
summary,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
132
248
|
function defineAppGroupMonitoringRegistration(registration) {
|
|
133
249
|
return registration;
|
|
134
250
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empire-builder-kit/runtime",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.10",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"publishConfig": {
|
|
5
|
-
"access": "public"
|
|
6
|
+
"access": "public",
|
|
7
|
+
"provenance": false
|
|
6
8
|
},
|
|
7
9
|
"main": "./dist/index.js",
|
|
8
10
|
"module": "./dist/index.js",
|
|
@@ -21,6 +23,18 @@
|
|
|
21
23
|
"import": "./dist/auth.js",
|
|
22
24
|
"default": "./dist/auth.js"
|
|
23
25
|
},
|
|
26
|
+
"./auth-backend": {
|
|
27
|
+
"@org/source": "./src/auth-backend.ts",
|
|
28
|
+
"types": "./dist/auth-backend.d.ts",
|
|
29
|
+
"import": "./dist/auth-backend.js",
|
|
30
|
+
"default": "./dist/auth-backend.js"
|
|
31
|
+
},
|
|
32
|
+
"./auth-web": {
|
|
33
|
+
"@org/source": "./src/auth-web.ts",
|
|
34
|
+
"types": "./dist/auth-web.d.ts",
|
|
35
|
+
"import": "./dist/auth-web.js",
|
|
36
|
+
"default": "./dist/auth-web.js"
|
|
37
|
+
},
|
|
24
38
|
"./config": {
|
|
25
39
|
"@org/source": "./src/config.ts",
|
|
26
40
|
"types": "./dist/config.d.ts",
|
|
@@ -45,6 +59,12 @@
|
|
|
45
59
|
"import": "./dist/logging.js",
|
|
46
60
|
"default": "./dist/logging.js"
|
|
47
61
|
},
|
|
62
|
+
"./lambda": {
|
|
63
|
+
"@org/source": "./src/lambda.ts",
|
|
64
|
+
"types": "./dist/lambda.d.ts",
|
|
65
|
+
"import": "./dist/lambda.js",
|
|
66
|
+
"default": "./dist/lambda.js"
|
|
67
|
+
},
|
|
48
68
|
"./observability": {
|
|
49
69
|
"@org/source": "./src/observability.ts",
|
|
50
70
|
"types": "./dist/observability.d.ts",
|
|
@@ -104,6 +124,16 @@
|
|
|
104
124
|
}
|
|
105
125
|
},
|
|
106
126
|
"dependencies": {
|
|
127
|
+
"jose": "^6.2.2",
|
|
107
128
|
"tslib": "^2.3.0"
|
|
108
|
-
}
|
|
109
|
-
|
|
129
|
+
},
|
|
130
|
+
"repository": {
|
|
131
|
+
"type": "git",
|
|
132
|
+
"url": "https://github.com/LukasGuptaLeary/empire-builder-kit.git",
|
|
133
|
+
"directory": "packages/runtime"
|
|
134
|
+
},
|
|
135
|
+
"bugs": {
|
|
136
|
+
"url": "https://github.com/LukasGuptaLeary/empire-builder-kit/issues"
|
|
137
|
+
},
|
|
138
|
+
"homepage": "https://github.com/LukasGuptaLeary/empire-builder-kit#readme"
|
|
139
|
+
}
|