Skip to content
Open
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
4 changes: 2 additions & 2 deletions .agents/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ EOF

Don't put `Generated with [Claude Code](https://claude.ai/code)`, or
`Co-authored-by` trailers at the end of the commit message. Instead,
use the `Assiged-by` trailer to indicate that the commit was generated by
an AI assistant, if necessary. The format of the `Assiged-by` trailer should
use the `Assisted-by` trailer to indicate that the commit was generated by
an AI assistant, if necessary. The format of the `Assisted-by` trailer should
be:

~~~~
Expand Down
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ Version 2.1.6

To be released.

### @fedify/astro

- Restored the npm entrypoint contract for `@fedify/astro` by making the
build emit _dist/\*.js_ and _dist/\*.d.ts_ files that match the published
Comment thread
dahlia marked this conversation as resolved.
package metadata again. This fixes package resolution failures caused by
_package.json_ exporting files that did not exist in the npm tarball.
Comment thread
dahlia marked this conversation as resolved.
[[#699], [#701]]

[#699]: https://github.com/fedify-dev/fedify/issues/699
[#701]: https://github.com/fedify-dev/fedify/pull/701

### @fedify/cli

- Fixed `fedify lookup` failing to look up URLs on private or localhost
Expand Down
1 change: 1 addition & 0 deletions packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"build": "pnpm --filter @fedify/astro... run build:self",
"prepack": "pnpm build",
"prepublish": "pnpm build",
"pretest": "pnpm build",
"test": "node --experimental-transform-types --test"
}
}
179 changes: 179 additions & 0 deletions packages/astro/src/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { deepStrictEqual, strictEqual } from "node:assert/strict";
import { access, readFile } from "node:fs/promises";
import { createRequire } from "node:module";
import { dirname, resolve } from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
import type {
Federation,
FederationFetchOptions,
} from "@fedify/fedify/federation";
import type { APIContext } from "astro";

const require = createRequire(import.meta.url);
const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");

type MockFederation<TContextData> = Pick<Federation<TContextData>, "fetch">;

function toFederation<TContextData>(
federation: MockFederation<TContextData>,
): Federation<TContextData> {
return federation as Federation<TContextData>;
}

function toApiContext(context: Pick<APIContext, "request">): APIContext {
return context as APIContext;
}

function expectResponse(response: void | Response): Response {
if (!(response instanceof Response)) {
throw new TypeError("Expected middleware to return a Response");
}
return response;
}

function expectTarget(actual: unknown, expected: string, key: string): string {
strictEqual(actual, expected, `Expected ${key} to be ${expected}`);
return actual;
}

async function assertTargetExists(path: string): Promise<void> {
await access(resolve(packageDir, path));
}

test("self-reference ESM import exposes working Astro integration API", async () => {
const mod = await import("@fedify/astro");

strictEqual(typeof mod.fedifyIntegration, "function");
strictEqual(typeof mod.fedifyMiddleware, "function");

Comment thread
dahlia marked this conversation as resolved.
const integration = mod.fedifyIntegration();
strictEqual(integration.name, "@fedify/astro");

let capturedConfig: unknown;
(
integration.hooks as Record<
"astro:config:setup",
(args: { updateConfig(config: unknown): void }) => void
>
)["astro:config:setup"]({
updateConfig(config) {
capturedConfig = config;
},
});
deepStrictEqual(capturedConfig, {
vite: {
ssr: {
noExternal: ["@fedify/fedify", "@fedify/vocab"],
},
},
});

let capturedRequest: Request | undefined;
let capturedContextData: unknown;
const middleware = mod.fedifyMiddleware(
toFederation<string>({
async fetch(
request: Request,
options: FederationFetchOptions<string>,
) {
capturedRequest = request;
capturedContextData = options.contextData;
if (options.onNotAcceptable == null) {
throw new TypeError("Expected onNotAcceptable to be defined");
}
return await options.onNotAcceptable(request);
},
}),
() => "test-context",
);

const request = new Request("https://example.com/");
const response = expectResponse(
await middleware(
toApiContext({ request }),
() => Promise.resolve(new Response("Not found", { status: 404 })),
),
);
strictEqual(capturedRequest, request);
strictEqual(capturedContextData, "test-context");
strictEqual(response.status, 406);
strictEqual(response.headers.get("Vary"), "Accept");
});

test(
"self-reference CommonJS require exposes working Astro middleware API",
{ skip: "Deno" in globalThis },
async () => {
const packageJson = JSON.parse(
await readFile(resolve(packageDir, "package.json"), "utf8"),
);
const exportMap = packageJson.exports["."];
const targets = [
expectTarget(packageJson.main, "./dist/mod.cjs", "package.json main"),
expectTarget(packageJson.module, "./dist/mod.js", "package.json module"),
expectTarget(packageJson.types, "./dist/mod.d.ts", "package.json types"),
expectTarget(
exportMap.require.types,
"./dist/mod.d.cts",
'package.json exports["."].require.types',
),
expectTarget(
exportMap.require.default,
"./dist/mod.cjs",
'package.json exports["."].require.default',
),
expectTarget(
exportMap.import.types,
"./dist/mod.d.ts",
'package.json exports["."].import.types',
),
expectTarget(
exportMap.import.default,
"./dist/mod.js",
'package.json exports["."].import.default',
),
];

for (const target of new Set(targets)) {
await assertTargetExists(target);
}

const mod = require("@fedify/astro") as typeof import("@fedify/astro");

strictEqual(typeof mod.fedifyIntegration, "function");
strictEqual(typeof mod.fedifyMiddleware, "function");

let nextCalled = false;
const middleware = mod.fedifyMiddleware(
toFederation<void>({
async fetch(
_request: Request,
options: FederationFetchOptions<void>,
) {
if (options.onNotFound == null) {
throw new TypeError("Expected onNotFound to be defined");
}
return await options.onNotFound(
new Request("https://example.com/actor"),
);
},
}),
() => undefined,
);

const response = expectResponse(
await middleware(
toApiContext({ request: new Request("https://example.com/inbox") }),
() => {
nextCalled = true;
return Promise.resolve(new Response("Handled by Astro"));
},
),
);

strictEqual(nextCalled, true);
strictEqual(response.status, 200);
strictEqual(await response.text(), "Handled by Astro");
},
);
6 changes: 6 additions & 0 deletions packages/astro/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ export default defineConfig({
dts: true,
format: ["esm", "cjs"],
platform: "node",
outExtensions({ format }) {
return {
js: format === "cjs" ? ".cjs" : ".js",
dts: format === "cjs" ? ".d.cts" : ".d.ts",
};
},
});
Loading