diff --git a/deno.json b/deno.json index 4b10bab..ca58114 100644 --- a/deno.json +++ b/deno.json @@ -1,10 +1,10 @@ { "name": "@kure/schema", - "version": "0.1.0", + "version": "0.1.1", "exports": { ".": "./mod.ts" }, "imports": { - "@kure/spec": "jsr:@kure/spec@^0.1.0" + "@kure/spec": "jsr:@kure/spec@^0.1.2" } -} \ No newline at end of file +} diff --git a/impl.ts b/impl.ts index ced1aca..7e6a5f8 100644 --- a/impl.ts +++ b/impl.ts @@ -29,3 +29,60 @@ export function factory( return build; } + +/** + * Create a [type predicate][] for the given {@link ResourceType resource type}. + * + * [type predicate]: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates + * + * @example + * ```ts + * import { Pod, Service } from "jsr:@kure/api/core"; + * import { isResource } from "jsr:@kure/schema"; + * + * export const isPod = isResource(Pod); + * export const isService = isResource(Service); + * ``` + */ +export function isResource( + type: ResourceType +): (target: unknown) => target is R; +/** + * [Check][type predicate] if a value is an instance of a + * {@link ResourceType resource type}. + * + * [type predicate]: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates + * + * @example + * ```ts + * import { Deployment } from "jsr:@kure/api/apps"; + * import { isResource, type Resource } from "jsr:@kure/schema"; + * + * function updateScale(replicas: number, resources: Resource[]) { + * for (const resource of resources) { + * if (isResource(Deployment, resource)) { + * // TypeScript now knows `resource` is a Deployment + * resource.spec.replicas = replicas; + * } + * } + * } + * ``` + */ +export function isResource( + type: ResourceType, + target: unknown +): target is R; +export function isResource( + type: ResourceType, + target?: unknown +) { + if (arguments.length < 2) + return (target: unknown) => isResource(type, target); + + return ( + target != null && + typeof target === "object" && + (target as Resource).apiVersion === type.apiVersion && + (target as Resource).kind === type.kind + ); +} diff --git a/mod.ts b/mod.ts index d2bdd15..bd45969 100644 --- a/mod.ts +++ b/mod.ts @@ -1,6 +1,6 @@ export type { Received, ReceivedObjectMeta } from "./disposition.ts"; export * from "./identity.ts"; -export { factory } from "./impl.ts"; +export { factory, isResource } from "./impl.ts"; export * from "./meta.ts"; export * from "./resource.ts";