Skip to content

Commit c464ad9

Browse files
feat: connect pixellab (#144)
Co-authored-by: CheerChen <meetcheerego@gmail.com>
1 parent 1b9648f commit c464ad9

13 files changed

Lines changed: 4828 additions & 0 deletions

src/providers/pixellab/actions.ts

Lines changed: 1880 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { ProviderDefinition } from "../../core/types.ts";
2+
3+
import { pixellabActions } from "./actions.ts";
4+
5+
const service = "pixellab";
6+
7+
export const provider: ProviderDefinition = {
8+
service,
9+
displayName: "PixelLab",
10+
description:
11+
"Generate, edit, animate, and manage pixel-art images, UI assets, characters, and objects with PixelLab.",
12+
categories: ["AI", "Design & Media"],
13+
authTypes: ["api_key"],
14+
auth: [
15+
{
16+
type: "api_key",
17+
label: "API Token",
18+
placeholder: "PIXELLAB_API_TOKEN",
19+
description:
20+
"PixelLab API token sent as a Bearer token. Create or manage tokens in the PixelLab dashboard: https://www.pixellab.ai/",
21+
},
22+
],
23+
homepageUrl: "https://www.pixellab.ai/",
24+
actions: pixellabActions,
25+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
import { createGuardedFetch } from "../../core/guarded-fetch.ts";
3+
import { credentialValidators } from "./executors.ts";
4+
5+
describe("PixelLab credential validator egress", () => {
6+
it("skips reserved Fake-IP DNS results for the fixed PixelLab API host", async () => {
7+
const transport = vi.fn(async () => Response.json([])) as unknown as typeof fetch;
8+
const defaultFetcher = createGuardedFetch({
9+
fetch: transport,
10+
lookup: async () => [{ address: "198.18.0.130", family: 4 }],
11+
});
12+
13+
await expect(
14+
credentialValidators.apiKey!({ apiKey: "test-token", values: {} }, { fetcher: defaultFetcher }),
15+
).resolves.toMatchObject({ grantedScopes: [] });
16+
17+
expect(transport).toHaveBeenCalledOnce();
18+
});
19+
20+
it("still blocks redirects from PixelLab to reserved targets", async () => {
21+
const transport = vi.fn(
22+
async () =>
23+
new Response(null, {
24+
status: 302,
25+
headers: { location: "http://169.254.169.254/latest/meta-data/" },
26+
}),
27+
) as unknown as typeof fetch;
28+
29+
await expect(
30+
credentialValidators.apiKey!({ apiKey: "test-token", values: {} }, { fetcher: transport }),
31+
).rejects.toThrow(/redirect location/u);
32+
33+
expect(transport).toHaveBeenCalledOnce();
34+
});
35+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { CredentialValidators, ProviderExecutors } from "../../core/types.ts";
2+
3+
import { createProviderFetch, defineApiKeyProviderExecutors } from "../provider-runtime.ts";
4+
import { pixellabCharacterActionHandlers } from "./runtime-character.ts";
5+
import { pixellabImageExtraActionHandlers } from "./runtime-image-extra.ts";
6+
import { pixellabImageActionHandlers } from "./runtime-image.ts";
7+
import { pixellabObjectActionHandlers } from "./runtime-object.ts";
8+
import { pixellabUiActionHandlers } from "./runtime-ui.ts";
9+
import { pixellabActionHandlers, validatePixellabCredential } from "./runtime.ts";
10+
11+
const service = "pixellab";
12+
13+
export const executors: ProviderExecutors = defineApiKeyProviderExecutors(
14+
service,
15+
{
16+
...pixellabActionHandlers,
17+
...pixellabImageActionHandlers,
18+
...pixellabImageExtraActionHandlers,
19+
...pixellabUiActionHandlers,
20+
...pixellabCharacterActionHandlers,
21+
...pixellabObjectActionHandlers,
22+
},
23+
{ skipDnsValidation: true },
24+
);
25+
26+
export const credentialValidators: CredentialValidators = {
27+
apiKey(input, { fetcher, signal }) {
28+
const credentialFetch = createProviderFetch({ fetch: fetcher, skipDnsValidation: true });
29+
return validatePixellabCredential(input.apiKey, credentialFetch, signal);
30+
},
31+
};

0 commit comments

Comments
 (0)