feat: add module contracts and discovery
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const localIdentifierPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
||||
const namespacedIdentifierPattern =
|
||||
/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*(?:\.[a-z][a-z0-9]*(?:-[a-z0-9]+)*)+$/u;
|
||||
|
||||
export const moduleIdSchema = z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(64)
|
||||
.regex(localIdentifierPattern, "Must be a lowercase kebab-case module identifier.");
|
||||
|
||||
export const capabilityIdSchema = z
|
||||
.string()
|
||||
.min(3)
|
||||
.max(160)
|
||||
.regex(namespacedIdentifierPattern, "Must be a lowercase dot-namespaced capability identifier.");
|
||||
|
||||
export const permissionIdSchema = z
|
||||
.string()
|
||||
.min(3)
|
||||
.max(160)
|
||||
.regex(namespacedIdentifierPattern, "Must be a lowercase dot-namespaced permission identifier.");
|
||||
|
||||
export const logicalBucketIdSchema = z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(48)
|
||||
.regex(localIdentifierPattern, "Must be a lowercase kebab-case logical bucket identifier.");
|
||||
|
||||
export const packageRelativePathSchema = z.string().superRefine((value, context) => {
|
||||
if (!value.startsWith("./")) {
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
message: "Must begin with ./ and remain inside the module package.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.includes("\\") || value.includes("\0") || value.includes("?") || value.includes("#")) {
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
message: "Must be a portable package-relative path without URLs, queries, or fragments.",
|
||||
});
|
||||
}
|
||||
|
||||
const segments = value.slice(2).split("/");
|
||||
if (segments.some((segment) => segment === "" || segment === "." || segment === "..")) {
|
||||
context.addIssue({
|
||||
code: "custom",
|
||||
message: "Must not contain empty, current-directory, or parent-directory segments.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export type ModuleId = z.infer<typeof moduleIdSchema>;
|
||||
export type CapabilityId = z.infer<typeof capabilityIdSchema>;
|
||||
export type PermissionId = z.infer<typeof permissionIdSchema>;
|
||||
export type LogicalBucketId = z.infer<typeof logicalBucketIdSchema>;
|
||||
export type PackageRelativePath = z.infer<typeof packageRelativePathSchema>;
|
||||
Reference in New Issue
Block a user