Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ARCHITECTURE-BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Three overlapping config loading strategies: `parseApsorc()` (used), `loadConfig

`createDirectoryContents` and `writeFile` are holdovers from an older template system. No command calls them. `init` uses git clone, `generate` uses Eta templates.

**Fix:** Delete both functions. Keep `createFile` and `withGeneratedMeta`.
**Fix:** Delete both functions. Keep `createFile`.

**Gains:** Removes dead code that suggests an alternative template mechanism exists.

Expand Down
4 changes: 2 additions & 2 deletions src/lib/generators/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
Entity,
AuthConfig,
} from "../types";
import { createFile, withGeneratedMeta } from "../utils/file-system";
import { createFile } from "../utils/file-system";

/**
* Abstract base class for language-specific generators.
Expand Down Expand Up @@ -154,7 +154,7 @@ export abstract class BaseGenerator implements LanguageGenerator {
): Promise<string> {
const content = await this.templateEngine.renderFileAsync(
templatePath,
withGeneratedMeta(data)
data
);
return content as string;
}
Expand Down
4 changes: 1 addition & 3 deletions src/lib/generators/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
AuthConfig,
Field,
} from "../types";
// Utilities available for future use: createFile, withGeneratedMeta from "../utils/file-system"
// Utilities available for future use: createFile from "../utils/file-system"
import { getFieldForTemplate, typeExistsInEntity, fieldToEnumType } from "../utils/field";
import {
getRelationshipForTemplate,
Expand Down Expand Up @@ -475,8 +475,6 @@ export class TypeScriptGenerator extends BaseGenerator {
const templateData = {
scopedEntities,
authConfig: normalizedAuth,
generatedAt: new Date().toISOString(),
generatedBy: "Apso CLI",
};

// Generate auth.guard.ts if auth is configured
Expand Down
1 change: 0 additions & 1 deletion src/lib/templates/guards/auth.guard.eta
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* AuthGuard - Authentication guard for <%= it.authConfig.provider %> provider
*
* Auto-generated by Apso CLI from .apsorc auth configuration
* Generated at: <%= it.generatedAt %>
*
* This guard:
* - Validates session tokens from cookies/headers
Expand Down
1 change: 0 additions & 1 deletion src/lib/templates/guards/guards.module.eta
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { <%= it.authConfig.accountUserEntity %> } from '../<%= it.authConfig.acc
* GuardsModule provides authentication and scope-based data isolation guards.
*
* Auto-generated from .apsorc configuration.
* Generated at: <%= it.generatedAt %>
*
* Usage:
* 1. Import GuardsModule in your AppModule
Expand Down
10 changes: 0 additions & 10 deletions src/lib/utils/file-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,3 @@ const writeFile = (
fs.chmodSync(fileWritePath, mode);
}
};

export function withGeneratedMeta<T extends object>(
data: T
): T & { generatedAt: string; generatedBy: string } {
return {
...data,
generatedAt: new Date().toISOString(),
generatedBy: process.env.USER || process.env.USERNAME || "unknown",
};
}
23 changes: 23 additions & 0 deletions test/lib/generators/typescript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,26 @@ describe("http controller suppression (issue #93)", () => {
});
});
});

describe("guard regeneration (cli#129)", () => {
test("renders the same guard files when nothing changed", async () => {
const generator = new TypeScriptGenerator(createConfig([]));
const entities: Entity[] = [
{
name: "Project",
fields: [{ name: "name", type: "text" }],
scopeBy: "workspaceId",
},
];
const auth = { provider: "better-auth" as const };

const first = await generator.generateGuards(entities, auth);
await new Promise((resolve) => {
setTimeout(resolve, 5);
});
const second = await generator.generateGuards(entities, auth);

expect(first.map((f) => f.path)).toContain("guards/auth.guard.ts");
expect(second).toEqual(first);
});
});