feat: add module schema discovery and validation
This commit is contained in:
@@ -397,12 +397,17 @@ describe("module discovery", () => {
|
||||
await createModule(modulesDirectory, "missing-server", {
|
||||
manifest: {
|
||||
...manifestFor("missing-server"),
|
||||
entrypoints: { server: "./dist/server/missing.js" },
|
||||
entrypoints: {
|
||||
server: "./dist/server/missing.js",
|
||||
schema: "./dist/schema/missing.js",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let error = await discoveryError(modulesDirectory);
|
||||
expect(issueCodes(error)).toContain("MODULE_ENTRYPOINT_MISSING");
|
||||
expect(error.issues.filter((issue) => issue.code === "MODULE_ENTRYPOINT_MISSING")).toHaveLength(
|
||||
2,
|
||||
);
|
||||
|
||||
error = await discoveryError(modulesDirectory, { platformVersion: "invalid" });
|
||||
expect(issueCodes(error)).toContain("DISCOVERY_CONFIGURATION_INVALID");
|
||||
@@ -427,21 +432,100 @@ describe("module discovery", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
"./src/schema/index.ts",
|
||||
"./dist/schema/index.cjs",
|
||||
])("rejects non-ESM schema entrypoint %s", async (schemaEntrypoint) => {
|
||||
const modulesDirectory = await createModulesDirectory();
|
||||
await createModule(modulesDirectory, "schema-source", {
|
||||
manifest: {
|
||||
...manifestFor("schema-source"),
|
||||
entrypoints: {
|
||||
server: "./dist/server/index.js",
|
||||
schema: schemaEntrypoint,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const error = await discoveryError(modulesDirectory);
|
||||
expect(error.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
code: "MODULE_ENTRYPOINT_INVALID",
|
||||
message: "schema must reference compiled ESM JavaScript with a .js or .mjs extension.",
|
||||
path: "entrypoints.schema",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts an optional compiled ESM schema entrypoint", async () => {
|
||||
const modulesDirectory = await createModulesDirectory();
|
||||
await createModule(modulesDirectory, "compiled-schema", {
|
||||
manifest: {
|
||||
...manifestFor("compiled-schema"),
|
||||
entrypoints: {
|
||||
server: "./dist/server/index.js",
|
||||
schema: "./dist/schema/index.mjs",
|
||||
},
|
||||
},
|
||||
});
|
||||
const schemaDirectory = path.join(modulesDirectory, "compiled-schema", "dist/schema");
|
||||
await mkdir(schemaDirectory, { recursive: true });
|
||||
await writeFile(path.join(schemaDirectory, "index.mjs"), "export default {};\n");
|
||||
|
||||
const modules = await discoverModules({
|
||||
moduleSdkVersion: "0.1.0",
|
||||
modulesDirectory,
|
||||
platformVersion: "0.1.0",
|
||||
});
|
||||
expect(modules[0]?.entrypoints.schema).toBe(path.join(schemaDirectory, "index.mjs"));
|
||||
});
|
||||
|
||||
it("requires executable entrypoints to be files and migrations to be a directory", async () => {
|
||||
const modulesDirectory = await createModulesDirectory();
|
||||
await createModule(modulesDirectory, "wrong-entrypoint-kind", {
|
||||
manifest: {
|
||||
...manifestFor("wrong-entrypoint-kind"),
|
||||
entrypoints: {
|
||||
server: "./dist/server",
|
||||
server: "./dist/server.js",
|
||||
schema: "./dist/schema.js",
|
||||
migrations: "./dist/server/index.js",
|
||||
},
|
||||
},
|
||||
});
|
||||
await Promise.all([
|
||||
mkdir(path.join(modulesDirectory, "wrong-entrypoint-kind", "dist/server.js")),
|
||||
mkdir(path.join(modulesDirectory, "wrong-entrypoint-kind", "dist/schema.js")),
|
||||
]);
|
||||
|
||||
const error = await discoveryError(modulesDirectory);
|
||||
expect(error.issues.filter((issue) => issue.code === "MODULE_ENTRYPOINT_INVALID")).toHaveLength(
|
||||
2,
|
||||
3,
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects schema entrypoint links that escape the module directory", async () => {
|
||||
const modulesDirectory = await createModulesDirectory();
|
||||
await createModule(modulesDirectory, "linked-schema", {
|
||||
manifest: {
|
||||
...manifestFor("linked-schema"),
|
||||
entrypoints: {
|
||||
server: "./dist/server/index.js",
|
||||
schema: "./dist/schema/index.js",
|
||||
},
|
||||
},
|
||||
});
|
||||
const schemaDirectory = path.join(modulesDirectory, "linked-schema", "dist/schema");
|
||||
const externalSchema = path.join(modulesDirectory, "external-schema.js");
|
||||
await mkdir(schemaDirectory, { recursive: true });
|
||||
await writeFile(externalSchema, "export default {};\n");
|
||||
await symlink("../../../external-schema.js", path.join(schemaDirectory, "index.js"));
|
||||
|
||||
const error = await discoveryError(modulesDirectory);
|
||||
expect(error.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
code: "MODULE_ENTRYPOINT_INVALID",
|
||||
path: "entrypoints.schema",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user