Cavnas: Implement basic service discovery logic

Change-Id: I71b25076dba94d6491ad4db748b259870991c526
diff --git a/apps/canvas/back/src/lib/fs.ts b/apps/canvas/back/src/lib/fs.ts
new file mode 100644
index 0000000..75d9453
--- /dev/null
+++ b/apps/canvas/back/src/lib/fs.ts
@@ -0,0 +1,20 @@
+import fs from "fs";
+import path from "path";
+
+export interface FileSystem {
+	exists(path: string): boolean;
+	readFile(path: string, encoding?: BufferEncoding): Promise<string>;
+}
+
+export class RealFileSystem implements FileSystem {
+	constructor(private readonly root: string) {}
+
+	exists(p: string): boolean {
+		return fs.existsSync(path.join(this.root, p));
+	}
+
+	async readFile(p: string, encoding?: BufferEncoding): Promise<string> {
+		const contents = await fs.promises.readFile(path.join(this.root, p));
+		return contents.toString(encoding);
+	}
+}