Add queryable capability contracts and checked GraphQL artifacts
This commit is contained in:
@@ -4,13 +4,20 @@ import { parseQx, validateQxImportPath, walkSyntax } from "./source.js";
|
||||
|
||||
export const readQxSource = async (root: string, name: string) => {
|
||||
validateQxImportPath(name);
|
||||
return readRepositorySource(root, name);
|
||||
};
|
||||
|
||||
/** Refuse symlinks at every component, including the final source file. */
|
||||
export const readRepositorySource = async (root: string, name: string) => {
|
||||
if (!/^(?:[A-Za-z0-9_-][A-Za-z0-9_.-]*\/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*$/.test(name))
|
||||
throw new Error(`Invalid repository-relative source path: ${name}`);
|
||||
let current = path.resolve(root);
|
||||
const segments = name.split("/");
|
||||
for (const [index, segment] of segments.entries()) {
|
||||
current = path.join(current, segment);
|
||||
const stat = await lstat(current);
|
||||
if (stat.isSymbolicLink() || (index === segments.length - 1 ? !stat.isFile() : !stat.isDirectory()))
|
||||
throw new Error(`QX imports must be ordinary files beneath ordinary directories: ${name}`);
|
||||
throw new Error(`Sources must be ordinary files beneath ordinary directories: ${name}`);
|
||||
}
|
||||
return readFile(current, "utf8");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user