Skip to content

Commit

Permalink
fix: Fix transformed properties assigned to incorrect entities.
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenh committed Apr 30, 2024
1 parent e8d9241 commit f601e5c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 29 deletions.
5 changes: 5 additions & 0 deletions packages/orm/src/BaseEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import {

export let currentlyInstantiatingEntity: Entity | undefined;

/** Should only be used by our `joist-transform-properties` to lazy init properties. */
export function setCurrentlyInstantiatingEntity(entity: Entity): void {
currentlyInstantiatingEntity = entity;
}

/**
* Returns the internal `__data` tracking field for `entity`.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/orm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const testing = { isAllSqlPaths };
export { newPgConnectionConfig } from "joist-utils";
export { AliasAssigner } from "./AliasAssigner";
export * from "./Aliases";
export { BaseEntity, getInstanceData } from "./BaseEntity";
export { BaseEntity, getInstanceData, setCurrentlyInstantiatingEntity } from "./BaseEntity";
export { Entity, IdType, isEntity } from "./Entity";
export * from "./EntityFields";
export * from "./EntityFilter";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ describe("properties-transformer", () => {
const result = compile(source);
expect(result).toMatchInlineSnapshot(`
"class Author {
get numberOfBooks() { return this.__data.relations.numberOfBooks ??= hasAsyncProperty(() => {
get numberOfBooks() { return this.__data.relations.numberOfBooks ??= (joist_orm_1.setCurrentlyInstantiatingEntity(this), hasAsyncProperty(() => {
return 1;
}); }
})); }
}
"
`);
Expand Down
79 changes: 53 additions & 26 deletions packages/transform-properties/src/properties-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,67 @@ import { SourceFile } from "typescript";
export const transformer: ts.TransformerFactory<ts.SourceFile> = (ctx) => {
const { factory: f } = ctx;

const visit: ts.Visitor = (node) => {
if (ts.isPropertyDeclaration(node) && node.initializer && shouldRewrite(node.type?.getText())) {
const getterName = node.name;
const getter = f.createGetAccessorDeclaration(
undefined,
getterName,
[],
node.type,
f.createBlock([
f.createReturnStatement(
f.createBinaryExpression(
f.createPropertyAccessExpression(
return (sourceFile) => {
// Create the import declaration for `setCurrentlyInstantiatingEntity` so
// that our lazy initialized property is hooked up to the right entity.
// const [importFn, importDecl] = createImportDeclaration(f, "joist-orm", "setCurrentlyInstantiatingEntity");
// sourceFile = f.updateSourceFile(sourceFile, [importDecl, ...sourceFile.statements]);

const visit: ts.Visitor = (node) => {
if (ts.isPropertyDeclaration(node) && node.initializer && shouldRewrite(node.type?.getText())) {
const getterName = node.name;
const getter = f.createGetAccessorDeclaration(
undefined,
getterName,
[],
node.type,
f.createBlock([
f.createReturnStatement(
f.createBinaryExpression(
f.createPropertyAccessExpression(
f.createPropertyAccessExpression(f.createThis(), f.createIdentifier("__data")),
f.createIdentifier("relations"),
f.createPropertyAccessExpression(
f.createPropertyAccessExpression(f.createThis(), f.createIdentifier("__data")),
f.createIdentifier("relations"),
),
getterName.getText(),
),
f.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
f.createParenthesizedExpression(
f.createBinaryExpression(
f.createCallExpression(
f.createPropertyAccessExpression(
f.createIdentifier("joist_orm_1"),
f.createIdentifier("setCurrentlyInstantiatingEntity"),
),
undefined,
[f.createThis()],
),
ts.SyntaxKind.CommaToken,
node.initializer,
),
),
getterName.getText(),
),
f.createToken(ts.SyntaxKind.QuestionQuestionEqualsToken),
node.initializer,
),
),
]),
);
return [getter];
}
return ts.visitEachChild(node, visit, ctx);
};
]),
);
return [getter];
}
return ts.visitEachChild(node, visit, ctx);
};

return (sourceFile) => {
return ts.visitNode(sourceFile, visit) as SourceFile;
sourceFile = ts.visitNode(sourceFile, visit) as SourceFile;
return sourceFile;
};
};

function createImportDeclaration(f: ts.NodeFactory, moduleName: string, name: string) {
const id = f.createIdentifier(name);
const importSpecifiers = f.createImportSpecifier(false, undefined, id);
const importClause = f.createImportClause(false, undefined, f.createNamedImports([importSpecifiers]));
const decl = f.createImportDeclaration(undefined, importClause, f.createStringLiteral(moduleName));
return [id, decl] as const;
}

function shouldRewrite(typeName: string | undefined): boolean {
return (
!!typeName &&
Expand Down

0 comments on commit f601e5c

Please sign in to comment.