@empire-builder-kit/runtime 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @empire-builder-kit/runtime
2
+
3
+ Publishable runtime primitives for Empire Builder Kit workspaces and apps.
4
+
5
+ ## Purpose
6
+
7
+ - provide a stable runtime dependency for repos generated from `@empire-builder-kit/preset`
8
+ - keep auth/session, frontend client contracts, config parsing, request context, logging, and observability conventions versioned outside a single workspace
9
+ - add shared response and error-envelope helpers so generated repos can return the same public contract by default
10
+ - separate framework runtime contracts from monorepo-only `packages/shared/*` internals
11
+
12
+ ## Exports
13
+
14
+ - `@empire-builder-kit/runtime`
15
+ - `@empire-builder-kit/runtime/auth`
16
+ - `@empire-builder-kit/runtime/config`
17
+ - `@empire-builder-kit/runtime/frontend`
18
+ - `@empire-builder-kit/runtime/request-context`
19
+ - `@empire-builder-kit/runtime/logging`
20
+ - `@empire-builder-kit/runtime/observability`
21
+ - `@empire-builder-kit/runtime/response`
22
+
23
+ ## Verification
24
+
25
+ - `pnpm nx build @empire-builder-kit/runtime`
26
+ - `pnpm nx test @empire-builder-kit/runtime`
27
+ - `pnpm nx lint @empire-builder-kit/runtime`
28
+ - `pnpm nx typecheck @empire-builder-kit/runtime`
package/dist/auth.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import type { RequestActor, RequestMetadata, RequestMetadataValue } from './request-context';
2
+ export type AuthSessionStatus = 'anonymous' | 'authenticated';
3
+ export interface AuthSessionSubject {
4
+ displayName?: string;
5
+ email?: string;
6
+ id: string;
7
+ permissions?: string[];
8
+ roles?: string[];
9
+ tenantId?: string;
10
+ type: RequestActor['type'];
11
+ }
12
+ export interface AuthSession {
13
+ expiresAt?: string;
14
+ issuedAt?: string;
15
+ metadata: RequestMetadata;
16
+ sessionId?: string;
17
+ status: AuthSessionStatus;
18
+ subject?: AuthSessionSubject;
19
+ }
20
+ export interface AnonymousSessionInput {
21
+ expiresAt?: string;
22
+ issuedAt?: string;
23
+ metadata?: Record<string, RequestMetadataValue | undefined>;
24
+ sessionId?: string;
25
+ }
26
+ export interface AuthenticatedSessionInput extends AnonymousSessionInput {
27
+ subject: AuthSessionSubject;
28
+ }
29
+ export interface AuthenticatedSession extends AuthSession {
30
+ status: 'authenticated';
31
+ subject: AuthSessionSubject;
32
+ }
33
+ export declare const authContract: {
34
+ readonly exportPath: "@empire-builder-kit/runtime/auth";
35
+ readonly packageName: "@empire-builder-kit/runtime";
36
+ };
37
+ export declare function createAnonymousSession(input?: AnonymousSessionInput): AuthSession;
38
+ export declare function createAuthenticatedSession(input: AuthenticatedSessionInput): AuthenticatedSession;
39
+ export declare function isAuthenticatedSession(session: AuthSession): session is AuthenticatedSession;
40
+ export declare function toRequestActor(session: AuthSession): RequestActor | undefined;
41
+ export declare function toSessionLogMetadata(session: AuthSession): RequestMetadata;
42
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +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"}
package/dist/auth.js ADDED
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authContract = void 0;
4
+ exports.createAnonymousSession = createAnonymousSession;
5
+ exports.createAuthenticatedSession = createAuthenticatedSession;
6
+ exports.isAuthenticatedSession = isAuthenticatedSession;
7
+ exports.toRequestActor = toRequestActor;
8
+ exports.toSessionLogMetadata = toSessionLogMetadata;
9
+ exports.authContract = {
10
+ exportPath: '@empire-builder-kit/runtime/auth',
11
+ packageName: '@empire-builder-kit/runtime',
12
+ };
13
+ function normalizeMetadata(metadata) {
14
+ const entries = Object.entries(metadata ?? {}).filter(([, value]) => value !== undefined);
15
+ return Object.fromEntries(entries);
16
+ }
17
+ function normalizeList(values) {
18
+ const normalized = (values ?? [])
19
+ .map((value) => value.trim())
20
+ .filter(Boolean);
21
+ if (normalized.length === 0) {
22
+ return undefined;
23
+ }
24
+ return [...new Set(normalized)];
25
+ }
26
+ function normalizeSubject(subject) {
27
+ return {
28
+ ...subject,
29
+ displayName: subject.displayName?.trim() || undefined,
30
+ email: subject.email?.trim() || undefined,
31
+ permissions: normalizeList(subject.permissions),
32
+ roles: normalizeList(subject.roles),
33
+ tenantId: subject.tenantId?.trim() || undefined,
34
+ };
35
+ }
36
+ function createAnonymousSession(input = {}) {
37
+ return {
38
+ expiresAt: input.expiresAt,
39
+ issuedAt: input.issuedAt,
40
+ metadata: normalizeMetadata(input.metadata),
41
+ sessionId: input.sessionId,
42
+ status: 'anonymous',
43
+ };
44
+ }
45
+ function createAuthenticatedSession(input) {
46
+ return {
47
+ ...createAnonymousSession(input),
48
+ status: 'authenticated',
49
+ subject: normalizeSubject(input.subject),
50
+ };
51
+ }
52
+ function isAuthenticatedSession(session) {
53
+ return session.status === 'authenticated' && session.subject !== undefined;
54
+ }
55
+ function toRequestActor(session) {
56
+ if (!isAuthenticatedSession(session)) {
57
+ return undefined;
58
+ }
59
+ return {
60
+ id: session.subject.id,
61
+ type: session.subject.type,
62
+ };
63
+ }
64
+ function toSessionLogMetadata(session) {
65
+ return normalizeMetadata({
66
+ authExpiresAt: session.expiresAt,
67
+ authIssuedAt: session.issuedAt,
68
+ authPermissions: session.subject?.permissions?.join(','),
69
+ authRoles: session.subject?.roles?.join(','),
70
+ authSessionId: session.sessionId,
71
+ authStatus: session.status,
72
+ authSubjectEmail: session.subject?.email,
73
+ authSubjectId: session.subject?.id,
74
+ authSubjectName: session.subject?.displayName,
75
+ authSubjectType: session.subject?.type,
76
+ authTenantId: session.subject?.tenantId,
77
+ ...session.metadata,
78
+ });
79
+ }
@@ -0,0 +1,52 @@
1
+ export type ConfigSource = Record<string, string | undefined>;
2
+ export interface ConfigIssue {
3
+ key: string;
4
+ message: string;
5
+ value?: string;
6
+ }
7
+ export interface ConfigParserContext {
8
+ propertyKey: string;
9
+ source: ConfigSource;
10
+ }
11
+ export type ConfigParser<T> = (context: ConfigParserContext) => T;
12
+ export type ConfigSchema = Record<string, ConfigParser<unknown>>;
13
+ export type InferConfig<S extends ConfigSchema> = {
14
+ [Key in keyof S]: ReturnType<S[Key]>;
15
+ };
16
+ interface StringOptions {
17
+ defaultValue?: string;
18
+ env?: string;
19
+ minLength?: number;
20
+ pattern?: RegExp;
21
+ trim?: boolean;
22
+ }
23
+ interface NumberOptions {
24
+ defaultValue?: number;
25
+ env?: string;
26
+ integer?: boolean;
27
+ max?: number;
28
+ min?: number;
29
+ }
30
+ interface BooleanOptions {
31
+ defaultValue?: boolean;
32
+ env?: string;
33
+ }
34
+ interface EnumOptions<T extends string> {
35
+ defaultValue?: T;
36
+ env?: string;
37
+ }
38
+ export declare class ConfigValidationError extends Error {
39
+ readonly issues: ConfigIssue[];
40
+ constructor(issues: ConfigIssue[]);
41
+ }
42
+ export declare function formatConfigIssues(issues: ConfigIssue[]): string;
43
+ export declare function loadConfig<S extends ConfigSchema>(schema: S, source?: ConfigSource): InferConfig<S>;
44
+ export declare function string(options?: StringOptions): ConfigParser<string>;
45
+ export declare function optionalString(options?: Omit<StringOptions, 'defaultValue'> & {
46
+ defaultValue?: string;
47
+ }): ConfigParser<string | undefined>;
48
+ export declare function number(options?: NumberOptions): ConfigParser<number>;
49
+ export declare function boolean(options?: BooleanOptions): ConfigParser<boolean>;
50
+ export declare function enumValue<const T extends string>(values: readonly T[], options?: EnumOptions<T>): ConfigParser<T>;
51
+ export {};
52
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,KAAK,CAAC,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,YAAY,IAAI;KAC/C,GAAG,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;CACrC,CAAC;AAEF,UAAU,aAAa;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,WAAW,CAAC,CAAC,SAAS,MAAM;IACpC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAYD,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;gBAEnB,MAAM,EAAE,WAAW,EAAE;CAKlC;AAwCD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAUhE;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,YAAY,EAC/C,MAAM,EAAE,CAAC,EACT,MAAM,GAAE,YAA0B,GACjC,WAAW,CAAC,CAAC,CAAC,CA4BhB;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,CA6BxE;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,CA6BlC;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,CAiCxE;AAED,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,YAAY,CAAC,OAAO,CAAC,CAyB3E;AAED,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAC9C,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,OAAO,GAAE,WAAW,CAAC,CAAC,CAAM,GAC3B,YAAY,CAAC,CAAC,CAAC,CAmBjB"}
package/dist/config.js ADDED
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigValidationError = void 0;
4
+ exports.formatConfigIssues = formatConfigIssues;
5
+ exports.loadConfig = loadConfig;
6
+ exports.string = string;
7
+ exports.optionalString = optionalString;
8
+ exports.number = number;
9
+ exports.boolean = boolean;
10
+ exports.enumValue = enumValue;
11
+ class ConfigFieldError extends Error {
12
+ issue;
13
+ constructor(issue) {
14
+ super(`${issue.key}: ${issue.message}`);
15
+ this.name = 'ConfigFieldError';
16
+ this.issue = issue;
17
+ }
18
+ }
19
+ class ConfigValidationError extends Error {
20
+ issues;
21
+ constructor(issues) {
22
+ super(formatConfigIssues(issues));
23
+ this.name = 'ConfigValidationError';
24
+ this.issues = issues;
25
+ }
26
+ }
27
+ exports.ConfigValidationError = ConfigValidationError;
28
+ function normalizeEnvKey(propertyKey, env) {
29
+ if (env) {
30
+ return env;
31
+ }
32
+ return propertyKey
33
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
34
+ .replace(/[\s-]+/g, '_')
35
+ .toUpperCase();
36
+ }
37
+ function createIssue(key, message, value) {
38
+ return {
39
+ key,
40
+ message,
41
+ value,
42
+ };
43
+ }
44
+ function throwFieldError(key, message, value) {
45
+ throw new ConfigFieldError(createIssue(key, message, value));
46
+ }
47
+ function normalizeStringValue(value, trim = true) {
48
+ return trim ? value.trim() : value;
49
+ }
50
+ function resolveStringValue(rawValue, defaultValue) {
51
+ if (rawValue === undefined) {
52
+ return defaultValue;
53
+ }
54
+ return rawValue;
55
+ }
56
+ function formatConfigIssues(issues) {
57
+ const summary = issues
58
+ .map(({ key, message, value }) => value === undefined
59
+ ? `- ${key}: ${message}`
60
+ : `- ${key}: ${message} (received "${value}")`)
61
+ .join('\n');
62
+ return `Invalid configuration:\n${summary}`;
63
+ }
64
+ function loadConfig(schema, source = process.env) {
65
+ const issues = [];
66
+ const config = {};
67
+ for (const [propertyKey, parser] of Object.entries(schema)) {
68
+ try {
69
+ config[propertyKey] = parser({
70
+ propertyKey: String(propertyKey),
71
+ source,
72
+ });
73
+ }
74
+ catch (error) {
75
+ if (error instanceof ConfigFieldError) {
76
+ issues.push(error.issue);
77
+ continue;
78
+ }
79
+ throw error;
80
+ }
81
+ }
82
+ if (issues.length > 0) {
83
+ throw new ConfigValidationError(issues);
84
+ }
85
+ return config;
86
+ }
87
+ function string(options = {}) {
88
+ return ({ propertyKey, source }) => {
89
+ const envKey = normalizeEnvKey(propertyKey, options.env);
90
+ const rawValue = resolveStringValue(source[envKey], options.defaultValue);
91
+ if (rawValue === undefined) {
92
+ throwFieldError(envKey, 'is required');
93
+ }
94
+ const value = normalizeStringValue(rawValue, options.trim !== false);
95
+ if (value.length === 0) {
96
+ throwFieldError(envKey, 'must not be empty', rawValue);
97
+ }
98
+ if (options.minLength !== undefined && value.length < options.minLength) {
99
+ throwFieldError(envKey, `must be at least ${options.minLength} characters`, value);
100
+ }
101
+ if (options.pattern && !options.pattern.test(value)) {
102
+ throwFieldError(envKey, 'does not match the expected pattern', value);
103
+ }
104
+ return value;
105
+ };
106
+ }
107
+ function optionalString(options = {}) {
108
+ return ({ propertyKey, source }) => {
109
+ const envKey = normalizeEnvKey(propertyKey, options.env);
110
+ const rawValue = resolveStringValue(source[envKey], options.defaultValue);
111
+ if (rawValue === undefined) {
112
+ return undefined;
113
+ }
114
+ const value = normalizeStringValue(rawValue, options.trim !== false);
115
+ if (value.length === 0) {
116
+ return undefined;
117
+ }
118
+ if (options.minLength !== undefined && value.length < options.minLength) {
119
+ throwFieldError(envKey, `must be at least ${options.minLength} characters`, value);
120
+ }
121
+ if (options.pattern && !options.pattern.test(value)) {
122
+ throwFieldError(envKey, 'does not match the expected pattern', value);
123
+ }
124
+ return value;
125
+ };
126
+ }
127
+ function number(options = {}) {
128
+ return ({ propertyKey, source }) => {
129
+ const envKey = normalizeEnvKey(propertyKey, options.env);
130
+ const rawValue = source[envKey];
131
+ if (rawValue === undefined || rawValue.trim().length === 0) {
132
+ if (options.defaultValue !== undefined) {
133
+ return options.defaultValue;
134
+ }
135
+ throwFieldError(envKey, 'is required', rawValue);
136
+ }
137
+ const value = Number(rawValue);
138
+ if (Number.isNaN(value)) {
139
+ throwFieldError(envKey, 'must be a valid number', rawValue);
140
+ }
141
+ if (options.integer && !Number.isInteger(value)) {
142
+ throwFieldError(envKey, 'must be an integer', rawValue);
143
+ }
144
+ if (options.min !== undefined && value < options.min) {
145
+ throwFieldError(envKey, `must be at least ${options.min}`, rawValue);
146
+ }
147
+ if (options.max !== undefined && value > options.max) {
148
+ throwFieldError(envKey, `must be at most ${options.max}`, rawValue);
149
+ }
150
+ return value;
151
+ };
152
+ }
153
+ function boolean(options = {}) {
154
+ return ({ propertyKey, source }) => {
155
+ const envKey = normalizeEnvKey(propertyKey, options.env);
156
+ const rawValue = source[envKey];
157
+ if (rawValue === undefined || rawValue.trim().length === 0) {
158
+ if (options.defaultValue !== undefined) {
159
+ return options.defaultValue;
160
+ }
161
+ throwFieldError(envKey, 'is required', rawValue);
162
+ }
163
+ const normalized = rawValue.trim().toLowerCase();
164
+ if (['true', '1', 'yes', 'on'].includes(normalized)) {
165
+ return true;
166
+ }
167
+ if (['false', '0', 'no', 'off'].includes(normalized)) {
168
+ return false;
169
+ }
170
+ throwFieldError(envKey, 'must be a boolean value', rawValue);
171
+ };
172
+ }
173
+ function enumValue(values, options = {}) {
174
+ return ({ propertyKey, source }) => {
175
+ const envKey = normalizeEnvKey(propertyKey, options.env);
176
+ const rawValue = resolveStringValue(source[envKey], options.defaultValue);
177
+ if (rawValue === undefined) {
178
+ throwFieldError(envKey, 'is required');
179
+ }
180
+ if (!values.includes(rawValue)) {
181
+ throwFieldError(envKey, `must be one of ${values.map((value) => `"${value}"`).join(', ')}`, rawValue);
182
+ }
183
+ return rawValue;
184
+ };
185
+ }
@@ -0,0 +1,42 @@
1
+ import type { AuthSessionStatus } from './auth';
2
+ export type FrontendRuntime = 'web' | 'mobile';
3
+ export type FrontendDeploymentMode = 'opennext' | 'container' | 'static-export' | 'expo';
4
+ export type FrontendSessionTransport = 'cookie' | 'bearer' | 'none';
5
+ export type FrontendSessionStorage = 'server' | 'secure-store' | 'memory';
6
+ export interface FrontendAuthContract {
7
+ exportPath: '@empire-builder-kit/runtime/auth';
8
+ initialStatus: AuthSessionStatus;
9
+ storage: FrontendSessionStorage;
10
+ transport: FrontendSessionTransport;
11
+ }
12
+ export interface FrontendApiContract {
13
+ sameScopeImportPrefix: string;
14
+ sdkPackage: string;
15
+ }
16
+ export interface FrontendDeploymentContract {
17
+ mode: FrontendDeploymentMode;
18
+ publicBaseUrlEnvVar: string;
19
+ stageEnvVar: string;
20
+ }
21
+ export interface FrontendClientContract {
22
+ api: FrontendApiContract;
23
+ app: string;
24
+ auth: FrontendAuthContract;
25
+ client: string;
26
+ deployment: FrontendDeploymentContract;
27
+ runtime: FrontendRuntime;
28
+ }
29
+ export interface FrontendClientContractInput {
30
+ api?: Partial<FrontendApiContract>;
31
+ app: string;
32
+ auth?: Partial<Omit<FrontendAuthContract, 'exportPath'>>;
33
+ client: string;
34
+ deployment?: Partial<FrontendDeploymentContract>;
35
+ runtime: FrontendRuntime;
36
+ }
37
+ export declare const frontendContract: {
38
+ readonly exportPath: "@empire-builder-kit/runtime/frontend";
39
+ readonly packageName: "@empire-builder-kit/runtime";
40
+ };
41
+ export declare function createFrontendClientContract(input: FrontendClientContractInput): FrontendClientContract;
42
+ //# sourceMappingURL=frontend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../src/frontend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,sBAAsB,GAC9B,UAAU,GACV,WAAW,GACX,eAAe,GACf,MAAM,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,kCAAkC,CAAC;IAC/C,aAAa,EAAE,iBAAiB,CAAC;IACjC,OAAO,EAAE,sBAAsB,CAAC;IAChC,SAAS,EAAE,wBAAwB,CAAC;CACrC;AAED,MAAM,WAAW,mBAAmB;IAClC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,mBAAmB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,0BAA0B,CAAC;IACvC,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACjD,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAsCX,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,2BAA2B,GACjC,sBAAsB,CAkCxB"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.frontendContract = void 0;
4
+ exports.createFrontendClientContract = createFrontendClientContract;
5
+ exports.frontendContract = {
6
+ exportPath: '@empire-builder-kit/runtime/frontend',
7
+ packageName: '@empire-builder-kit/runtime',
8
+ };
9
+ function trimOrFallback(value, fallback) {
10
+ const normalized = value?.trim();
11
+ return normalized && normalized.length > 0 ? normalized : fallback;
12
+ }
13
+ function defaultsForRuntime(runtime) {
14
+ if (runtime === 'mobile') {
15
+ return {
16
+ auth: {
17
+ initialStatus: 'anonymous',
18
+ storage: 'secure-store',
19
+ transport: 'bearer',
20
+ },
21
+ deployment: {
22
+ mode: 'expo',
23
+ publicBaseUrlEnvVar: 'EXPO_PUBLIC_API_BASE_URL',
24
+ stageEnvVar: 'EXPO_PUBLIC_STAGE',
25
+ },
26
+ };
27
+ }
28
+ return {
29
+ auth: {
30
+ initialStatus: 'anonymous',
31
+ storage: 'server',
32
+ transport: 'cookie',
33
+ },
34
+ deployment: {
35
+ mode: 'opennext',
36
+ publicBaseUrlEnvVar: 'NEXT_PUBLIC_APP_URL',
37
+ stageEnvVar: 'NEXT_PUBLIC_STAGE',
38
+ },
39
+ };
40
+ }
41
+ function createFrontendClientContract(input) {
42
+ const runtimeDefaults = defaultsForRuntime(input.runtime);
43
+ const app = trimOrFallback(input.app, 'app');
44
+ return {
45
+ api: {
46
+ sameScopeImportPrefix: trimOrFallback(input.api?.sameScopeImportPrefix, `@${app}/`),
47
+ sdkPackage: trimOrFallback(input.api?.sdkPackage, `@${app}/sdk/client`),
48
+ },
49
+ app,
50
+ auth: {
51
+ exportPath: '@empire-builder-kit/runtime/auth',
52
+ initialStatus: input.auth?.initialStatus ?? runtimeDefaults.auth.initialStatus,
53
+ storage: input.auth?.storage ?? runtimeDefaults.auth.storage,
54
+ transport: input.auth?.transport ?? runtimeDefaults.auth.transport,
55
+ },
56
+ client: trimOrFallback(input.client, `${app}-${input.runtime}`),
57
+ deployment: {
58
+ mode: input.deployment?.mode ?? runtimeDefaults.deployment.mode,
59
+ publicBaseUrlEnvVar: trimOrFallback(input.deployment?.publicBaseUrlEnvVar, runtimeDefaults.deployment.publicBaseUrlEnvVar),
60
+ stageEnvVar: trimOrFallback(input.deployment?.stageEnvVar, runtimeDefaults.deployment.stageEnvVar),
61
+ },
62
+ runtime: input.runtime,
63
+ };
64
+ }
@@ -0,0 +1,12 @@
1
+ export * from './auth';
2
+ export * from './config';
3
+ export * from './frontend';
4
+ export * from './logging';
5
+ export * from './observability';
6
+ export * from './request-context';
7
+ export * from './response';
8
+ 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 name: "@empire-builder-kit/runtime";
11
+ };
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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;;;CAWjB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runtimePackage = void 0;
4
+ const tslib_1 = require("tslib");
5
+ tslib_1.__exportStar(require("./auth"), exports);
6
+ tslib_1.__exportStar(require("./config"), exports);
7
+ tslib_1.__exportStar(require("./frontend"), exports);
8
+ tslib_1.__exportStar(require("./logging"), exports);
9
+ tslib_1.__exportStar(require("./observability"), exports);
10
+ tslib_1.__exportStar(require("./request-context"), exports);
11
+ tslib_1.__exportStar(require("./response"), exports);
12
+ exports.runtimePackage = {
13
+ exports: [
14
+ '@empire-builder-kit/runtime/auth',
15
+ '@empire-builder-kit/runtime/config',
16
+ '@empire-builder-kit/runtime/frontend',
17
+ '@empire-builder-kit/runtime/request-context',
18
+ '@empire-builder-kit/runtime/logging',
19
+ '@empire-builder-kit/runtime/observability',
20
+ '@empire-builder-kit/runtime/response',
21
+ ],
22
+ name: '@empire-builder-kit/runtime',
23
+ };
@@ -0,0 +1,70 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export type LogMetadata = Record<string, unknown>;
3
+ export interface LoggerActor {
4
+ id?: string;
5
+ type?: string;
6
+ }
7
+ export interface LoggerContext {
8
+ actor?: LoggerActor;
9
+ correlationId?: string;
10
+ metadata?: Record<string, string | number | boolean | null | undefined>;
11
+ operation?: string;
12
+ requestId?: string;
13
+ source?: string;
14
+ stage?: string;
15
+ }
16
+ export interface SerializedError {
17
+ code?: number | string;
18
+ message: string;
19
+ name: string;
20
+ stack?: string;
21
+ }
22
+ export interface LogEntry {
23
+ app: string;
24
+ correlationId?: string;
25
+ error?: SerializedError;
26
+ level: LogLevel;
27
+ message: string;
28
+ metadata?: LogMetadata;
29
+ requestId?: string;
30
+ service?: string;
31
+ stage?: string;
32
+ timestamp: string;
33
+ }
34
+ export interface LogEventInput {
35
+ context?: LoggerContext;
36
+ error?: unknown;
37
+ metadata?: LogMetadata;
38
+ }
39
+ export interface ChildLoggerOptions {
40
+ context?: LoggerContext;
41
+ metadata?: LogMetadata;
42
+ service?: string;
43
+ stage?: string;
44
+ }
45
+ export interface CreateLoggerOptions {
46
+ app: string;
47
+ context?: LoggerContext;
48
+ metadata?: LogMetadata;
49
+ now?: () => Date;
50
+ service?: string;
51
+ sink?: (entry: LogEntry) => void;
52
+ stage?: string;
53
+ }
54
+ export interface Logger {
55
+ child(options?: ChildLoggerOptions): Logger;
56
+ debug(message: string, input?: LogEventInput): LogEntry;
57
+ error(message: string, input?: LogEventInput): LogEntry;
58
+ info(message: string, input?: LogEventInput): LogEntry;
59
+ log(level: LogLevel, message: string, input?: LogEventInput): LogEntry;
60
+ warn(message: string, input?: LogEventInput): LogEntry;
61
+ }
62
+ export declare const loggingContract: {
63
+ readonly defaultFormat: "json";
64
+ readonly exportPath: "@empire-builder-kit/runtime/logging";
65
+ readonly packageName: "@empire-builder-kit/runtime";
66
+ };
67
+ export declare function serializeError(error: unknown): SerializedError;
68
+ export declare function consoleSink(entry: LogEntry): void;
69
+ export declare function createLogger(options: CreateLoggerOptions): Logger;
70
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loggingContract = void 0;
4
+ exports.serializeError = serializeError;
5
+ exports.consoleSink = consoleSink;
6
+ exports.createLogger = createLogger;
7
+ exports.loggingContract = {
8
+ defaultFormat: 'json',
9
+ exportPath: '@empire-builder-kit/runtime/logging',
10
+ packageName: '@empire-builder-kit/runtime',
11
+ };
12
+ function mergeContext(base, overrides) {
13
+ if (!base && !overrides) {
14
+ return undefined;
15
+ }
16
+ return {
17
+ actor: overrides?.actor ?? base?.actor,
18
+ correlationId: overrides?.correlationId ?? base?.correlationId,
19
+ metadata: {
20
+ ...(base?.metadata ?? {}),
21
+ ...(overrides?.metadata ?? {}),
22
+ },
23
+ operation: overrides?.operation ?? base?.operation,
24
+ requestId: overrides?.requestId ?? base?.requestId,
25
+ source: overrides?.source ?? base?.source,
26
+ stage: overrides?.stage ?? base?.stage,
27
+ };
28
+ }
29
+ function contextMetadata(context) {
30
+ if (!context) {
31
+ return {};
32
+ }
33
+ return compactObject({
34
+ actorId: context.actor?.id,
35
+ actorType: context.actor?.type,
36
+ operation: context.operation,
37
+ source: context.source,
38
+ ...(context.metadata ?? {}),
39
+ });
40
+ }
41
+ function compactObject(value) {
42
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
43
+ }
44
+ function safeStringify(value) {
45
+ if (typeof value === 'string') {
46
+ return value;
47
+ }
48
+ try {
49
+ return JSON.stringify(value);
50
+ }
51
+ catch {
52
+ return String(value);
53
+ }
54
+ }
55
+ function serializeError(error) {
56
+ if (error instanceof Error) {
57
+ const value = error;
58
+ return compactObject({
59
+ code: value.code,
60
+ message: value.message,
61
+ name: value.name,
62
+ stack: value.stack,
63
+ });
64
+ }
65
+ return {
66
+ message: safeStringify(error),
67
+ name: 'UnknownError',
68
+ };
69
+ }
70
+ function consoleSink(entry) {
71
+ console.log(JSON.stringify(entry));
72
+ }
73
+ function createLogger(options) {
74
+ const sink = options.sink ?? consoleSink;
75
+ const now = options.now ?? (() => new Date());
76
+ const write = (level, message, input = {}) => {
77
+ const mergedContext = mergeContext(options.context, input.context);
78
+ const metadata = compactObject({
79
+ ...(options.metadata ?? {}),
80
+ ...contextMetadata(mergedContext),
81
+ ...(input.metadata ?? {}),
82
+ });
83
+ const entry = compactObject({
84
+ app: options.app,
85
+ correlationId: mergedContext?.correlationId,
86
+ error: input.error === undefined ? undefined : serializeError(input.error),
87
+ level,
88
+ message,
89
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
90
+ requestId: mergedContext?.requestId,
91
+ service: options.service,
92
+ stage: mergedContext?.stage ?? options.stage,
93
+ timestamp: now().toISOString(),
94
+ });
95
+ sink(entry);
96
+ return entry;
97
+ };
98
+ return {
99
+ child(childOptions = {}) {
100
+ return createLogger({
101
+ app: options.app,
102
+ context: mergeContext(options.context, childOptions.context),
103
+ metadata: {
104
+ ...(options.metadata ?? {}),
105
+ ...(childOptions.metadata ?? {}),
106
+ },
107
+ now,
108
+ service: childOptions.service ?? options.service,
109
+ sink,
110
+ stage: childOptions.stage ?? options.stage,
111
+ });
112
+ },
113
+ debug(message, input) {
114
+ return write('debug', message, input);
115
+ },
116
+ error(message, input) {
117
+ return write('error', message, input);
118
+ },
119
+ info(message, input) {
120
+ return write('info', message, input);
121
+ },
122
+ log(level, message, input) {
123
+ return write(level, message, input);
124
+ },
125
+ warn(message, input) {
126
+ return write('warn', message, input);
127
+ },
128
+ };
129
+ }
@@ -0,0 +1,71 @@
1
+ export type AlarmSeverity = 'low' | 'medium' | 'high' | 'critical';
2
+ export interface QueueAlertThresholds {
3
+ messagesInFlight: number;
4
+ messagesVisible: number;
5
+ oldestMessageAgeSeconds: number;
6
+ }
7
+ export interface AlarmDefinition {
8
+ comparisonOperator: 'GreaterThanOrEqualToThreshold';
9
+ description: string;
10
+ dimensions: Record<string, string>;
11
+ evaluationPeriods: number;
12
+ metricName: string;
13
+ name: string;
14
+ namespace: string;
15
+ periodSeconds: number;
16
+ severity: AlarmSeverity;
17
+ threshold: number;
18
+ }
19
+ export interface AlarmNameInput {
20
+ app: string;
21
+ component: string;
22
+ metric: string;
23
+ severity?: AlarmSeverity;
24
+ stage: string;
25
+ }
26
+ export interface QueueAlarmInput {
27
+ app: string;
28
+ queue: string;
29
+ severity?: AlarmSeverity;
30
+ stage: string;
31
+ thresholds?: Partial<QueueAlertThresholds>;
32
+ }
33
+ export interface DashboardPathInput {
34
+ app: string;
35
+ dashboard: string;
36
+ stage: string;
37
+ }
38
+ export interface DashboardRegistrationInput extends DashboardPathInput {
39
+ description: string;
40
+ title: string;
41
+ }
42
+ export interface MonitoringDashboardRegistration extends DashboardPathInput, Pick<DashboardRegistrationInput, 'description' | 'title'> {
43
+ path: string;
44
+ }
45
+ export interface QueueAlarmRegistrationInput extends QueueAlarmInput {
46
+ dashboard?: string;
47
+ summary: string;
48
+ }
49
+ export interface QueueAlarmRegistration extends QueueAlarmInput {
50
+ alarms: AlarmDefinition[];
51
+ dashboardPath?: string;
52
+ summary: string;
53
+ thresholds: QueueAlertThresholds;
54
+ }
55
+ export type MonitoringOwner = 'platform' | 'product';
56
+ export interface AppGroupMonitoringRegistration {
57
+ app: string;
58
+ dashboards: MonitoringDashboardRegistration[];
59
+ owner: MonitoringOwner;
60
+ queues: QueueAlarmRegistration[];
61
+ summary: string;
62
+ }
63
+ export declare function createMetricNamespace(app: string): string;
64
+ export declare function createAlarmName(input: AlarmNameInput): string;
65
+ export declare function defaultQueueAlertThresholds(overrides?: Partial<QueueAlertThresholds>): QueueAlertThresholds;
66
+ export declare function createQueueAlarmDefinitions(input: QueueAlarmInput): AlarmDefinition[];
67
+ export declare function createDashboardPath(input: DashboardPathInput): string;
68
+ export declare function createDashboardRegistration(input: DashboardRegistrationInput): MonitoringDashboardRegistration;
69
+ export declare function createQueueAlarmRegistration(input: QueueAlarmRegistrationInput): QueueAlarmRegistration;
70
+ export declare function defineAppGroupMonitoringRegistration<T extends AppGroupMonitoringRegistration>(registration: T): T;
71
+ //# sourceMappingURL=observability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMetricNamespace = createMetricNamespace;
4
+ exports.createAlarmName = createAlarmName;
5
+ exports.defaultQueueAlertThresholds = defaultQueueAlertThresholds;
6
+ exports.createQueueAlarmDefinitions = createQueueAlarmDefinitions;
7
+ exports.createDashboardPath = createDashboardPath;
8
+ exports.createDashboardRegistration = createDashboardRegistration;
9
+ exports.createQueueAlarmRegistration = createQueueAlarmRegistration;
10
+ exports.defineAppGroupMonitoringRegistration = defineAppGroupMonitoringRegistration;
11
+ function normalizeSegment(value) {
12
+ return value
13
+ .trim()
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9]+/g, '-')
16
+ .replace(/^-+|-+$/g, '');
17
+ }
18
+ function createMetricNamespace(app) {
19
+ return `EBK/${normalizeSegment(app)}`;
20
+ }
21
+ function createAlarmName(input) {
22
+ return [
23
+ normalizeSegment(input.app),
24
+ normalizeSegment(input.stage),
25
+ normalizeSegment(input.component),
26
+ normalizeSegment(input.metric),
27
+ normalizeSegment(input.severity ?? 'medium'),
28
+ ].join('-');
29
+ }
30
+ function defaultQueueAlertThresholds(overrides = {}) {
31
+ return {
32
+ messagesInFlight: 10,
33
+ messagesVisible: 25,
34
+ oldestMessageAgeSeconds: 300,
35
+ ...overrides,
36
+ };
37
+ }
38
+ function createQueueAlarmDefinitions(input) {
39
+ const thresholds = defaultQueueAlertThresholds(input.thresholds);
40
+ const namespace = 'AWS/SQS';
41
+ const severity = input.severity ?? 'high';
42
+ return [
43
+ {
44
+ comparisonOperator: 'GreaterThanOrEqualToThreshold',
45
+ description: `Visible messages in ${input.queue} exceed the shared queue threshold.`,
46
+ dimensions: {
47
+ QueueName: input.queue,
48
+ },
49
+ evaluationPeriods: 2,
50
+ metricName: 'ApproximateNumberOfMessagesVisible',
51
+ name: createAlarmName({
52
+ app: input.app,
53
+ component: input.queue,
54
+ metric: 'messages-visible',
55
+ severity,
56
+ stage: input.stage,
57
+ }),
58
+ namespace,
59
+ periodSeconds: 60,
60
+ severity,
61
+ threshold: thresholds.messagesVisible,
62
+ },
63
+ {
64
+ comparisonOperator: 'GreaterThanOrEqualToThreshold',
65
+ description: `In-flight messages in ${input.queue} exceed the shared queue threshold.`,
66
+ dimensions: {
67
+ QueueName: input.queue,
68
+ },
69
+ evaluationPeriods: 2,
70
+ metricName: 'ApproximateNumberOfMessagesNotVisible',
71
+ name: createAlarmName({
72
+ app: input.app,
73
+ component: input.queue,
74
+ metric: 'messages-in-flight',
75
+ severity,
76
+ stage: input.stage,
77
+ }),
78
+ namespace,
79
+ periodSeconds: 60,
80
+ severity,
81
+ threshold: thresholds.messagesInFlight,
82
+ },
83
+ {
84
+ comparisonOperator: 'GreaterThanOrEqualToThreshold',
85
+ description: `Oldest message age in ${input.queue} exceeds the shared queue threshold.`,
86
+ dimensions: {
87
+ QueueName: input.queue,
88
+ },
89
+ evaluationPeriods: 2,
90
+ metricName: 'ApproximateAgeOfOldestMessage',
91
+ name: createAlarmName({
92
+ app: input.app,
93
+ component: input.queue,
94
+ metric: 'oldest-message-age',
95
+ severity,
96
+ stage: input.stage,
97
+ }),
98
+ namespace,
99
+ periodSeconds: 60,
100
+ severity,
101
+ threshold: thresholds.oldestMessageAgeSeconds,
102
+ },
103
+ ];
104
+ }
105
+ function createDashboardPath(input) {
106
+ return `/${normalizeSegment(input.stage)}/${normalizeSegment(input.app)}/${normalizeSegment(input.dashboard)}`;
107
+ }
108
+ function createDashboardRegistration(input) {
109
+ return {
110
+ ...input,
111
+ path: createDashboardPath(input),
112
+ };
113
+ }
114
+ function createQueueAlarmRegistration(input) {
115
+ const thresholds = defaultQueueAlertThresholds(input.thresholds);
116
+ return {
117
+ ...input,
118
+ alarms: createQueueAlarmDefinitions({
119
+ ...input,
120
+ thresholds,
121
+ }),
122
+ dashboardPath: input.dashboard
123
+ ? createDashboardPath({
124
+ app: input.app,
125
+ dashboard: input.dashboard,
126
+ stage: input.stage,
127
+ })
128
+ : undefined,
129
+ thresholds,
130
+ };
131
+ }
132
+ function defineAppGroupMonitoringRegistration(registration) {
133
+ return registration;
134
+ }
@@ -0,0 +1,31 @@
1
+ export type RequestMetadataValue = string | number | boolean | null;
2
+ export type RequestMetadata = Record<string, RequestMetadataValue>;
3
+ export interface RequestActor {
4
+ id?: string;
5
+ type: 'service' | 'system' | 'user';
6
+ }
7
+ export interface RequestContext {
8
+ app: string;
9
+ actor?: RequestActor;
10
+ correlationId: string;
11
+ metadata: RequestMetadata;
12
+ operation: string;
13
+ requestId: string;
14
+ source?: string;
15
+ stage?: string;
16
+ }
17
+ export interface RequestContextInput {
18
+ app: string;
19
+ actor?: RequestActor;
20
+ correlationId?: string;
21
+ metadata?: Record<string, RequestMetadataValue | undefined>;
22
+ operation: string;
23
+ requestId?: string;
24
+ source?: string;
25
+ stage?: string;
26
+ }
27
+ export declare function createRequestContext(input: RequestContextInput): RequestContext;
28
+ export declare function extendRequestContext(context: RequestContext, overrides?: Partial<RequestContextInput>): RequestContext;
29
+ export declare function toRequestHeaders(context: Pick<RequestContext, 'correlationId' | 'requestId'>): Record<string, string>;
30
+ export declare function toRequestLogMetadata(context: Partial<RequestContext>): RequestMetadata;
31
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,GACzB,cAAc,CAahB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,EACvB,SAAS,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAC3C,cAAc,CAchB;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,GAAG,WAAW,CAAC,GAC3D,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKxB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,eAAe,CAYjB"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRequestContext = createRequestContext;
4
+ exports.extendRequestContext = extendRequestContext;
5
+ exports.toRequestHeaders = toRequestHeaders;
6
+ exports.toRequestLogMetadata = toRequestLogMetadata;
7
+ const node_crypto_1 = require("node:crypto");
8
+ function normalizeMetadata(metadata) {
9
+ const entries = Object.entries(metadata ?? {}).filter(([, value]) => value !== undefined);
10
+ return Object.fromEntries(entries);
11
+ }
12
+ function createRequestContext(input) {
13
+ const requestId = input.requestId ?? (0, node_crypto_1.randomUUID)();
14
+ return {
15
+ app: input.app,
16
+ actor: input.actor,
17
+ correlationId: input.correlationId ?? requestId,
18
+ metadata: normalizeMetadata(input.metadata),
19
+ operation: input.operation,
20
+ requestId,
21
+ source: input.source,
22
+ stage: input.stage,
23
+ };
24
+ }
25
+ function extendRequestContext(context, overrides = {}) {
26
+ return {
27
+ app: overrides.app ?? context.app,
28
+ actor: overrides.actor ?? context.actor,
29
+ correlationId: overrides.correlationId ?? context.correlationId,
30
+ metadata: {
31
+ ...context.metadata,
32
+ ...normalizeMetadata(overrides.metadata),
33
+ },
34
+ operation: overrides.operation ?? context.operation,
35
+ requestId: overrides.requestId ?? context.requestId,
36
+ source: overrides.source ?? context.source,
37
+ stage: overrides.stage ?? context.stage,
38
+ };
39
+ }
40
+ function toRequestHeaders(context) {
41
+ return {
42
+ 'x-correlation-id': context.correlationId,
43
+ 'x-request-id': context.requestId,
44
+ };
45
+ }
46
+ function toRequestLogMetadata(context) {
47
+ return normalizeMetadata({
48
+ actorId: context.actor?.id,
49
+ actorType: context.actor?.type,
50
+ app: context.app,
51
+ correlationId: context.correlationId,
52
+ operation: context.operation,
53
+ requestId: context.requestId,
54
+ source: context.source,
55
+ stage: context.stage,
56
+ ...context.metadata,
57
+ });
58
+ }
@@ -0,0 +1,61 @@
1
+ export interface ResponseMetadata {
2
+ correlationId?: string;
3
+ requestId?: string;
4
+ [key: string]: unknown;
5
+ }
6
+ export interface SuccessResponse<T, M extends ResponseMetadata = ResponseMetadata> {
7
+ data: T;
8
+ meta?: M;
9
+ ok: true;
10
+ status: number;
11
+ }
12
+ export interface RuntimeErrorDetails {
13
+ [key: string]: unknown;
14
+ }
15
+ export interface RuntimeErrorShape {
16
+ code: string;
17
+ details?: RuntimeErrorDetails;
18
+ message: string;
19
+ retryable: boolean;
20
+ }
21
+ export interface ErrorResponse<M extends ResponseMetadata = ResponseMetadata> {
22
+ error: RuntimeErrorShape;
23
+ meta?: M;
24
+ ok: false;
25
+ status: number;
26
+ }
27
+ export type AppResponse<T, M extends ResponseMetadata = ResponseMetadata> = ErrorResponse<M> | SuccessResponse<T, M>;
28
+ export interface RuntimeErrorOptions {
29
+ code: string;
30
+ details?: RuntimeErrorDetails;
31
+ expose?: boolean;
32
+ message: string;
33
+ retryable?: boolean;
34
+ status?: number;
35
+ }
36
+ export interface CreateErrorResponseOptions<M extends ResponseMetadata = ResponseMetadata> {
37
+ fallbackCode?: string;
38
+ fallbackMessage?: string;
39
+ includeDetails?: boolean;
40
+ meta?: M;
41
+ }
42
+ export interface CreateSuccessResponseOptions<M extends ResponseMetadata = ResponseMetadata> {
43
+ meta?: M;
44
+ status?: number;
45
+ }
46
+ export declare const responseContract: {
47
+ readonly exportPath: "@empire-builder-kit/runtime/response";
48
+ readonly packageName: "@empire-builder-kit/runtime";
49
+ };
50
+ export declare class RuntimeError extends Error {
51
+ readonly code: string;
52
+ readonly details?: RuntimeErrorDetails;
53
+ readonly expose: boolean;
54
+ readonly retryable: boolean;
55
+ readonly status: number;
56
+ constructor(options: RuntimeErrorOptions);
57
+ }
58
+ export declare function isRuntimeError(error: unknown): error is RuntimeError;
59
+ export declare function createSuccessResponse<T, M extends ResponseMetadata = ResponseMetadata>(data: T, options?: CreateSuccessResponseOptions<M>): SuccessResponse<T, M>;
60
+ export declare function createErrorResponse<M extends ResponseMetadata = ResponseMetadata>(error: unknown, options?: CreateErrorResponseOptions<M>): ErrorResponse<M>;
61
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,EACD,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAE7C,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAC1E,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IACpE,aAAa,CAAC,CAAC,CAAC,GAChB,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE1B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B,CACzC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAE7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,CAAC,CAAC;CACV;AAED,MAAM,WAAW,4BAA4B,CAC3C,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IAE7C,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE,mBAAmB;CASzC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,wBAAgB,qBAAqB,CACnC,CAAC,EACD,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAE7C,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,4BAA4B,CAAC,CAAC,CAAM,GAC5C,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAOvB;AAED,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAE7C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,0BAA0B,CAAC,CAAC,CAAM,GAC1C,aAAa,CAAC,CAAC,CAAC,CAelB"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuntimeError = exports.responseContract = void 0;
4
+ exports.isRuntimeError = isRuntimeError;
5
+ exports.createSuccessResponse = createSuccessResponse;
6
+ exports.createErrorResponse = createErrorResponse;
7
+ exports.responseContract = {
8
+ exportPath: '@empire-builder-kit/runtime/response',
9
+ packageName: '@empire-builder-kit/runtime',
10
+ };
11
+ class RuntimeError extends Error {
12
+ code;
13
+ details;
14
+ expose;
15
+ retryable;
16
+ status;
17
+ constructor(options) {
18
+ super(options.message);
19
+ this.name = 'RuntimeError';
20
+ this.code = options.code;
21
+ this.details = options.details;
22
+ this.status = options.status ?? 500;
23
+ this.retryable = options.retryable ?? false;
24
+ this.expose = options.expose ?? this.status < 500;
25
+ }
26
+ }
27
+ exports.RuntimeError = RuntimeError;
28
+ function isRuntimeError(error) {
29
+ return error instanceof RuntimeError;
30
+ }
31
+ function createSuccessResponse(data, options = {}) {
32
+ return compactObject({
33
+ data,
34
+ meta: options.meta,
35
+ ok: true,
36
+ status: options.status ?? 200,
37
+ });
38
+ }
39
+ function createErrorResponse(error, options = {}) {
40
+ const normalized = normalizeError(error, options);
41
+ return compactObject({
42
+ error: compactObject({
43
+ code: normalized.code,
44
+ details: options.includeDetails === false ? undefined : normalized.details,
45
+ message: normalized.message,
46
+ retryable: normalized.retryable,
47
+ }),
48
+ meta: options.meta,
49
+ ok: false,
50
+ status: normalized.status,
51
+ });
52
+ }
53
+ function normalizeError(error, options) {
54
+ if (isRuntimeError(error)) {
55
+ return error;
56
+ }
57
+ return new RuntimeError({
58
+ code: options.fallbackCode ?? 'internal_error',
59
+ expose: false,
60
+ message: options.fallbackMessage ?? 'Internal server error',
61
+ status: 500,
62
+ });
63
+ }
64
+ function compactObject(value) {
65
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
66
+ }
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@empire-builder-kit/runtime",
3
+ "version": "0.0.1-alpha.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "@org/source": "./src/index.ts",
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./auth": {
19
+ "@org/source": "./src/auth.ts",
20
+ "types": "./dist/auth.d.ts",
21
+ "import": "./dist/auth.js",
22
+ "default": "./dist/auth.js"
23
+ },
24
+ "./config": {
25
+ "@org/source": "./src/config.ts",
26
+ "types": "./dist/config.d.ts",
27
+ "import": "./dist/config.js",
28
+ "default": "./dist/config.js"
29
+ },
30
+ "./frontend": {
31
+ "@org/source": "./src/frontend.ts",
32
+ "types": "./dist/frontend.d.ts",
33
+ "import": "./dist/frontend.js",
34
+ "default": "./dist/frontend.js"
35
+ },
36
+ "./request-context": {
37
+ "@org/source": "./src/request-context.ts",
38
+ "types": "./dist/request-context.d.ts",
39
+ "import": "./dist/request-context.js",
40
+ "default": "./dist/request-context.js"
41
+ },
42
+ "./logging": {
43
+ "@org/source": "./src/logging.ts",
44
+ "types": "./dist/logging.d.ts",
45
+ "import": "./dist/logging.js",
46
+ "default": "./dist/logging.js"
47
+ },
48
+ "./observability": {
49
+ "@org/source": "./src/observability.ts",
50
+ "types": "./dist/observability.d.ts",
51
+ "import": "./dist/observability.js",
52
+ "default": "./dist/observability.js"
53
+ },
54
+ "./response": {
55
+ "@org/source": "./src/response.ts",
56
+ "types": "./dist/response.d.ts",
57
+ "import": "./dist/response.js",
58
+ "default": "./dist/response.js"
59
+ }
60
+ },
61
+ "files": [
62
+ "dist",
63
+ "!**/*.tsbuildinfo"
64
+ ],
65
+ "nx": {
66
+ "tags": [
67
+ "scope:workspace",
68
+ "layer:runtime",
69
+ "type:runtime",
70
+ "visibility:public"
71
+ ],
72
+ "targets": {
73
+ "typecheck": {
74
+ "dependsOn": [
75
+ "build",
76
+ "^build"
77
+ ]
78
+ },
79
+ "build": {
80
+ "executor": "@nx/js:tsc",
81
+ "outputs": [
82
+ "{options.outputPath}"
83
+ ],
84
+ "options": {
85
+ "outputPath": "packages/runtime/dist",
86
+ "main": "packages/runtime/src/index.ts",
87
+ "tsConfig": "packages/runtime/tsconfig.lib.json",
88
+ "rootDir": "packages/runtime/src",
89
+ "generatePackageJson": false,
90
+ "assets": [
91
+ {
92
+ "input": "./packages/runtime/src",
93
+ "glob": "**/!(*.ts)",
94
+ "output": "."
95
+ },
96
+ {
97
+ "input": "./packages/runtime/src",
98
+ "glob": "**/*.d.ts",
99
+ "output": "."
100
+ }
101
+ ]
102
+ }
103
+ }
104
+ }
105
+ },
106
+ "dependencies": {
107
+ "tslib": "^2.3.0"
108
+ }
109
+ }