feat: add removable reference feature vertical slice
This commit is contained in:
@@ -15,6 +15,7 @@ export type { ApplicationApi, ApplicationOutputPorts };
|
||||
*/
|
||||
export function createApplication(
|
||||
outputPorts: ApplicationOutputPorts,
|
||||
featureInputs: Readonly<Record<string, unknown>> = {},
|
||||
): ApplicationApi {
|
||||
const session = Object.freeze({
|
||||
getSnapshot: () => outputPorts.session.getState(),
|
||||
@@ -107,6 +108,18 @@ export function createApplication(
|
||||
}
|
||||
},
|
||||
});
|
||||
const installedFeatureInputs = Object.freeze({ ...featureInputs });
|
||||
const features = Object.freeze({
|
||||
has(featureId: string) {
|
||||
return Object.hasOwn(installedFeatureInputs, featureId);
|
||||
},
|
||||
get(featureId: string) {
|
||||
if (!Object.hasOwn(installedFeatureInputs, featureId)) {
|
||||
throw new Error(`Application feature is not installed: ${featureId}`);
|
||||
}
|
||||
return installedFeatureInputs[featureId];
|
||||
},
|
||||
});
|
||||
|
||||
return Object.freeze({
|
||||
session,
|
||||
@@ -114,5 +127,6 @@ export function createApplication(
|
||||
diagnostics,
|
||||
runtime,
|
||||
recovery,
|
||||
features,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -47,4 +47,8 @@ export type ApplicationApi = Readonly<{
|
||||
| Readonly<{ action: "support"; reason: string }>
|
||||
>;
|
||||
}>;
|
||||
features: Readonly<{
|
||||
has(featureId: string): boolean;
|
||||
get(featureId: string): unknown;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
@@ -7,11 +7,5 @@ export type {
|
||||
export type { ClockPort } from "../clock-port.js";
|
||||
export type { QueryCachePort } from "../query-cache-port.js";
|
||||
export type { ReleaseInfoPort } from "../release-info-port.js";
|
||||
export type {
|
||||
RequestContext,
|
||||
ResourceCommandPort,
|
||||
ResourceQueryPort,
|
||||
Result,
|
||||
} from "../resource-ports.js";
|
||||
export type { StoragePort } from "../storage-port.js";
|
||||
export type { TelemetryPort } from "../telemetry-port.js";
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* @template Query
|
||||
* @template Model
|
||||
* @typedef {{ execute(query: Query, context?: RequestContext): Promise<Result<Model>> }} ResourceQueryPort
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template Command
|
||||
* @template Model
|
||||
* @typedef {{ execute(command: Command, context?: RequestContext): Promise<Result<Model>> }} ResourceCommandPort
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* operationId: string,
|
||||
* routeId: string,
|
||||
* signal?: AbortSignal,
|
||||
* idempotencyKey?: string
|
||||
* }} RequestContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template Value
|
||||
* @typedef {{ ok: true, value: Value, meta?: Record<string, unknown> } |
|
||||
* { ok: false, error: import("../../contracts/errors.js").ApiFailure }} Result
|
||||
*/
|
||||
|
||||
export {};
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* @param {import("../../domain/models/resource.js").Resource} resource
|
||||
* @param {(value: Date) => string} [formatDate]
|
||||
*/
|
||||
export function toResourceViewModel(
|
||||
resource,
|
||||
formatDate = (value) => new Intl.DateTimeFormat("ko-KR").format(value),
|
||||
) {
|
||||
return Object.freeze({
|
||||
resourceId: resource.id,
|
||||
title: resource.displayName,
|
||||
createdAtLabel: resource.createdAt
|
||||
? formatDate(new Date(resource.createdAt))
|
||||
: null,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user