Skip to content

Commit

Permalink
$.contest.ts -> _.context.ts, export class Context instead of default
Browse files Browse the repository at this point in the history
  • Loading branch information
pmcelhaney committed Jan 20, 2024
1 parent ff8f982 commit 07d95ba
Show file tree
Hide file tree
Showing 5 changed files with 393 additions and 524 deletions.
14 changes: 5 additions & 9 deletions src/server/context-registry.ts
@@ -1,4 +1,8 @@
export interface Context {
// eslint-disable-next-line max-classes-per-file
export class Context {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-empty-function
public constructor() {}

[key: string]: unknown;
}

Expand All @@ -14,14 +18,6 @@ export class ContextRegistry {
}

public add(path: string, context?: Context): void {
if (context === undefined) {
// If $.context.ts exists but only exports a type, then the context object will be undefined here.
// This should be handled upstream, so that add() is not called in the first place.
// But module-loader.ts needs to be refactored a bit using type guards and the is operator
// before that can be done cleanly.
return;
}

this.entries.set(path, context);
}

Expand Down
33 changes: 22 additions & 11 deletions src/server/module-loader.ts
Expand Up @@ -13,7 +13,13 @@ import type { Module, Registry } from "./registry.js";
const debug = createDebug("counterfact:typescript-generator:module-loader");

interface ContextModule {
default?: Context;
Context: Context;
}

function isContextModule(
module: ContextModule | Module,
): module is ContextModule {
return "Context" in module && typeof module.Context === "function";
}

function reportLoadError(error: unknown, fileUrl: string) {
Expand Down Expand Up @@ -81,13 +87,14 @@ export class ModuleLoader extends EventTarget {
.then((endpoint: ContextModule | Module) => {
this.dispatchEvent(new Event(eventName));

if (pathName.includes("$.context")) {
if (pathName.includes("_.context")) {
this.contextRegistry.update(
parts.dir,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
(endpoint as ContextModule).default,
);

// @ts-expect-error TS says Context has no constructable signatures but that's not true?
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions
new (endpoint as ContextModule).Context(),
);
return "context";
}

Expand Down Expand Up @@ -147,6 +154,7 @@ export class ModuleLoader extends EventTarget {
await Promise.all(imports);
}

// eslint-disable-next-line max-statements
private async loadEndpoint(
fullPath: string,
directory: string,
Expand All @@ -162,13 +170,16 @@ export class ModuleLoader extends EventTarget {
| ContextModule
| Module;

if (file.name.includes("$.context")) {
this.contextRegistry.add(
`/${directory.replaceAll("\\", "/")}`,
if (file.name.includes("_.context")) {
if (isContextModule(endpoint)) {
this.contextRegistry.add(
`/${directory.replaceAll("\\", "/")}`,

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
(endpoint as ContextModule).default,
);
// @ts-expect-error TS says Context has no constructable signatures but that's not true?
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
new endpoint.Context(),
);
}
} else {
const url = `/${nodePath.join(
directory,
Expand Down
16 changes: 8 additions & 8 deletions test/server/module-loader.test.ts
Expand Up @@ -166,8 +166,8 @@ describe("a module loader", () => {

it("finds a context and adds it to the context registry", async () => {
const files: { [key: string]: string } = {
"$.context.mjs": 'export default "main"',
"hello/$.context.mjs": 'export default "hello"',
"_.context.mjs": 'export class Context { name = "main"};',
"hello/_.context.mjs": 'export class Context { name = "hello"};',
};

await withTemporaryFiles(files, async (basePath: string) => {
Expand All @@ -183,16 +183,16 @@ describe("a module loader", () => {

await loader.load();

expect(contextRegistry.find("/hello")).toBe("hello");
expect(contextRegistry.find("/hello/world")).toBe("hello");
expect(contextRegistry.find("/some/other/path")).toBe("main");
expect(contextRegistry.find("/hello").name).toBe("hello");
expect(contextRegistry.find("/hello/world").name).toBe("hello");
expect(contextRegistry.find("/some/other/path").name).toBe("main");
});
});

it("provides the parent context if the locale $.context.ts doesn't export a default", async () => {
it("provides the parent context if the locale _.context.ts doesn't export a default", async () => {
const files: { [key: string]: string } = {
"$.context.mjs": "export default { value: 0 }",
"hello/$.context.mjs": "export default { value: 100 }",
"_.context.mjs": "export class Context { value = 0 }",
"hello/_.context.mjs": "export class Context { value = 100 }",
};

await withTemporaryFiles(files, async (basePath: string) => {
Expand Down

0 comments on commit 07d95ba

Please sign in to comment.