Skip to content
Merged
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
8 changes: 8 additions & 0 deletions apps/dashboard/src/components/provider-icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { IconSvgProps, SimpleIconData } from "@onequery/ui/icons/svg-icon";
import {
IconDatabase,
IconHelpCircle,
IconKey,
IconNotebook,
IconTerminal2,
} from "@tabler/icons-react";
Expand Down Expand Up @@ -216,6 +217,12 @@ function E2BIcon(props: ProviderIconProps) {
);
}

function OnePasswordIcon(props: ProviderIconProps) {
return (
<TablerProviderIcon {...props} defaultLabel="1Password" Icon={IconKey} />
);
}

function MicrosoftClarityIcon({ size = 24, ...props }: ProviderIconProps) {
return (
<SvgIcon
Expand Down Expand Up @@ -326,6 +333,7 @@ export const ProviderIcons = {
motherduck: MotherDuckIcon,
mongodb: createSimpleProviderIcon(siMongodb),
mysql: createSimpleProviderIcon(siMysql),
onepassword: OnePasswordIcon,
postgres: createSimpleProviderIcon(siPostgresql),
supabase: createSimpleProviderIcon(siSupabase),
posthog: createSimpleProviderIcon(siPosthog),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Developer Tools
description: Connect GitHub, Linear, Jira, Confluence, Vercel, and Discord to OneQuery.
description: Connect GitHub, Linear, Jira, Confluence, Vercel, Discord, and 1Password to OneQuery.
sidebar:
order: 5
---
Expand All @@ -9,14 +9,15 @@ Developer tool integrations are usually Source API integrations. They let agents

## Common Sources

| Provider | Provider ID | Use it for |
| ---------- | ------------ | ----------------------------------------------------------------------------- |
| GitHub | `github` | Pull requests, commits, issues, repository metadata, and code review context. |
| Linear | `linear` | Issue and workflow context. |
| Jira | `jira` | Project and ticket context. |
| Confluence | `confluence` | Internal documentation context. |
| Vercel | `vercel` | Deployments, projects, teams, and runtime observability endpoints. |
| Discord | `discord` | Workspace and channel context through bot or OAuth access. |
| Provider | Provider ID | Use it for |
| ---------- | ------------- | ----------------------------------------------------------------------------- |
| GitHub | `github` | Pull requests, commits, issues, repository metadata, and code review context. |
| Linear | `linear` | Issue and workflow context. |
| Jira | `jira` | Project and ticket context. |
| Confluence | `confluence` | Internal documentation context. |
| Vercel | `vercel` | Deployments, projects, teams, and runtime observability endpoints. |
| Discord | `discord` | Workspace and channel context through bot or OAuth access. |
| 1Password | `onepassword` | Vault and item context through a 1Password Connect Server token. |

## GitHub Example

Expand Down
2 changes: 1 addition & 1 deletion apps/landing/src/content/docs/docs/integrations/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ OneQuery integrations become named sources. Each source has a provider, a local
<LinkCard
title="Developer tools"
href="/docs/integrations/developer-tools/"
description="GitHub, Linear, Jira, Confluence, Vercel, and Discord access patterns."
description="GitHub, Linear, Jira, Confluence, Vercel, Discord, and 1Password access patterns."
/>
<LinkCard
title="Product analytics"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use the provider ID with `onequery source connect --source <provider-id>`. The s
| Databases | `postgres`, `supabase`, `mysql`, `mongodb` |
| Warehouses | `snowflake`, `bigquery`, `aws_athena_connector`, `motherduck`, `cloudflare_d1` |
| Observability | `sentry`, `laminar`, `cloudflare_workers_observability` |
| Developer workflow | `github`, `linear`, `jira`, `confluence`, `vercel`, `discord` |
| Developer workflow | `github`, `linear`, `jira`, `confluence`, `vercel`, `discord`, `onepassword` |
| Product analytics | `ga`, `amplitude`, `mixpanel`, `posthog`, `microsoft_clarity`, `cloudflare_web_analytics` |
| Marketing | `google_search_console`, `amazon_ads`, `linkedin_ads`, `tiktok_marketing`, `sendgrid` |
| Productivity | `airtable`, `cal`, `granola` |
Expand Down
28 changes: 28 additions & 0 deletions apps/landing/src/shared/icons/brands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,33 @@ function E2BIcon({ size, ...props }: IconSvgProps) {
);
}

function OnePasswordIcon({ size, ...props }: IconSvgProps) {
return (
<SvgIcon
{...props}
defaultLabel="1Password"
fill="none"
size={size}
viewBox="0 0 24 24"
>
<path
d="M7.5 14.5a4.5 4.5 0 1 1 3.77-2.05L22 12.45v3h-3v3h-3v-3h-4.73A4.48 4.48 0 0 1 7.5 14.5Z"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
/>
<path
d="M7.5 10.5h.01"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="3"
/>
</SvgIcon>
);
}

function MicrosoftClarityIcon({ size, ...props }: IconSvgProps) {
return (
<SvgIcon
Expand Down Expand Up @@ -276,6 +303,7 @@ const BRAND_ICONS = {
mysql: createSimpleBrandIcon(siMysql),
notion: createSimpleBrandIcon(siNotion),
npm: createSimpleBrandIcon(siNpm),
onepassword: OnePasswordIcon,
postgresql: createSimpleBrandIcon(siPostgresql),
postgres: createSimpleBrandIcon(siPostgresql),
posthog: createSimpleBrandIcon(siPosthog),
Expand Down
1 change: 1 addition & 0 deletions packages/db/src/__snapshots__/credentials.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports[`credentials schemas > credentialSchemaMap > matches supported provider
"mongodb",
"motherduck",
"mysql",
"onepassword",
"postgres",
"posthog",
"sendgrid",
Expand Down
19 changes: 19 additions & 0 deletions packages/db/src/connection-guide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,25 @@ export const SOURCE_CONNECT_PROVIDER_GUIDES: SourceConnectProviderGuide[] = [
},
},
},
{
provider: "onepassword",
summary:
"Connect 1Password through a self-hosted Connect Server API endpoint.",
steps: [
"Deploy or choose the 1Password Connect Server that can read the target vaults.",
"Create a Connect access token scoped to the vaults and items OneQuery should inspect.",
"Set `credentials.apiBaseUrl` to the Connect Server origin, for example `https://connect.example.com`.",
"Source API calls are read-only; use selectors such as `/v1/vaults` and `/v1/vaults/{vaultUUID}/items`.",
],
exampleInput: {
sourceKey: "onepassword_main",
credentials: {
type: "onepassword",
apiBaseUrl: "https://connect.example.com",
accessToken: "onepassword_connect_token",
},
},
},
{
provider: "microsoft_clarity",
summary: "Connect Microsoft Clarity with a project Data Export API token.",
Expand Down
51 changes: 51 additions & 0 deletions packages/db/src/credentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
MotherDuckCredentialsSchema,
MongoDBCredentialsSchema,
MySQLCredentialsSchema,
OnePasswordCredentialsSchema,
normalizeEnvVarName,
PostgresCredentialsSchema,
PostHogCredentialsSchema,
Expand Down Expand Up @@ -73,6 +74,7 @@ import type {
MotherDuckCredentials,
MongoDBCredentials,
MySQLCredentials,
OnePasswordCredentials,
PostgresCredentials,
PostHogCredentials,
SendGridCredentials,
Expand Down Expand Up @@ -1737,6 +1739,38 @@ describe("credentials schemas", () => {
});
});

describe("OnePasswordCredentialsSchema", () => {
it("validates 1Password credentials", () => {
const credentials: OnePasswordCredentials = {
accessToken: "onepassword_connect_token",
apiBaseUrl: "https://connect.example.com",
type: "onepassword",
};

const result = OnePasswordCredentialsSchema.safeParse(credentials);
expect(result.success).toBe(true);
});

it("rejects missing access token", () => {
const result = OnePasswordCredentialsSchema.safeParse({
apiBaseUrl: "https://connect.example.com",
type: "onepassword",
});

expect(result.success).toBe(false);
});

it("rejects invalid API base URL", () => {
const result = OnePasswordCredentialsSchema.safeParse({
accessToken: "onepassword_connect_token",
apiBaseUrl: "not-a-url",
type: "onepassword",
});

expect(result.success).toBe(false);
});
});

describe("MicrosoftClarityCredentialsSchema", () => {
it("validates Microsoft Clarity credentials", () => {
const credentials: MicrosoftClarityCredentials = {
Expand Down Expand Up @@ -1938,6 +1972,12 @@ describe("credentials schemas", () => {
expect(credentialSchemaMap.e2b).toBe(E2BCredentialsSchema);
});

it("should map onepassword to OnePasswordCredentialsSchema", () => {
expect(credentialSchemaMap.onepassword).toBe(
OnePasswordCredentialsSchema
);
});

it("should map slack to SlackCredentialsSchema", () => {
expect(credentialSchemaMap.slack).toBe(SlackCredentialsSchema);
});
Expand Down Expand Up @@ -2217,6 +2257,17 @@ describe("credentials schemas", () => {
expect(result.type).toBe("microsoft_clarity");
});

it("should validate 1Password credentials", () => {
const credentials = {
accessToken: "onepassword_connect_token",
apiBaseUrl: "https://connect.example.com",
type: "onepassword",
};

const result = validateCredentials(credentials);
expect(result.type).toBe("onepassword");
});

it("should validate Cloudflare Web Analytics credentials", () => {
const credentials = {
accountId: "023e105f4ecef8ad9ca31a8372d0c353",
Expand Down
15 changes: 15 additions & 0 deletions packages/db/src/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,19 @@ export type MicrosoftClarityCredentials = z.infer<
typeof MicrosoftClarityCredentialsSchema
>;

export const OnePasswordCredentialsSchema = z.object({
accessToken: requiredOpaqueString("Access token is required"),
apiBaseUrl: trimmedUrl(
"API base URL is required",
"API base URL must be a valid URL"
).transform((value) => value.replace(/\/+$/, "")),
type: z.literal("onepassword"),
});

export type OnePasswordCredentials = z.infer<
typeof OnePasswordCredentialsSchema
>;

export const CloudflareD1CredentialsSchema = z.object({
accountId: trimmedString("Account ID is required"),
apiBaseUrl: optionalTrimmedUrl("API base URL must be a valid URL"),
Expand Down Expand Up @@ -537,6 +550,7 @@ export const CredentialsSchema = z.union([
VercelCredentialsSchema,
E2BCredentialsSchema,
MicrosoftClarityCredentialsSchema,
OnePasswordCredentialsSchema,
CloudflareD1CredentialsSchema,
CloudflareWorkersObservabilityCredentialsSchema,
CloudflareWebAnalyticsCredentialsSchema,
Expand Down Expand Up @@ -604,6 +618,7 @@ export const credentialSchemaMap = {
motherduck: MotherDuckCredentialsSchema,
mongodb: MongoDBCredentialsSchema,
mysql: MySQLCredentialsSchema,
onepassword: OnePasswordCredentialsSchema,
postgres: PostgresCredentialsSchema,
posthog: PostHogCredentialsSchema,
sendgrid: SendGridCredentialsSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ exports[`data-sources schema > matches provider type snapshots 1`] = `
"jira",
"vercel",
"e2b",
"onepassword",
"microsoft_clarity",
"linear",
"cloudflare_workers_observability",
Expand Down Expand Up @@ -69,6 +70,7 @@ exports[`data-sources schema > matches provider type snapshots 1`] = `
"jira",
"vercel",
"e2b",
"onepassword",
"microsoft_clarity",
"linear",
"cloudflare_workers_observability",
Expand Down
32 changes: 32 additions & 0 deletions packages/db/src/source-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
MotherDuckCredentialsSchema,
MongoDBCredentialsSchema,
MySQLCredentialsSchema,
OnePasswordCredentialsSchema,
PostgresCredentialsSchema,
PostHogCredentialsSchema,
SendGridCredentialsSchema,
Expand Down Expand Up @@ -981,6 +982,37 @@ export const SOURCE_PROVIDER_REGISTRY = {
},
},
},
onepassword: {
label: "1Password",
credentialSchema: OnePasswordCredentialsSchema,
credentialType: "onepassword",
connectable: true,
analysisSource: true,
queryInterface: false,
sourceApiInterface: true,
testable: false,
dashboardConnectable: true,
dashboardCredentialForm: "json",
publicCategory: "Developer workflow",
guide: {
summary:
"Connect 1Password through a self-hosted Connect Server API endpoint.",
steps: [
"Deploy or choose the 1Password Connect Server that can read the target vaults.",
"Create a Connect access token scoped to the vaults and items OneQuery should inspect.",
"Set `credentials.apiBaseUrl` to the Connect Server origin, for example `https://connect.example.com`.",
"Source API calls are read-only; use selectors such as `/v1/vaults` and `/v1/vaults/{vaultUUID}/items`.",
],
exampleInput: {
sourceKey: "onepassword_main",
credentials: {
type: "onepassword",
apiBaseUrl: "https://connect.example.com",
accessToken: "onepassword_connect_token",
},
},
},
},
microsoft_clarity: {
label: "Microsoft Clarity",
credentialSchema: MicrosoftClarityCredentialsSchema,
Expand Down
43 changes: 43 additions & 0 deletions packages/server/src/source-api/adapters/onepassword.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { OnePasswordCredentials } from "@onequery/db/server";

import { createSimpleRestSourceApiAdapter } from "./simple-rest";

const ONEPASSWORD_DESCRIPTOR_VERSION = "onepassword.v1";

export const onePasswordSourceApiAdapter =
createSimpleRestSourceApiAdapter<OnePasswordCredentials>({
allowedMethods: ["GET"],
apiBaseUrl: (credentials) => credentials.apiBaseUrl,
auth: (credentials) => ({
token: credentials.accessToken,
type: "bearer",
}),
buildExamples: (sourceKey) => [
{
command: `onequery api --source ${sourceKey} /v1/vaults`,
description: "List vaults visible to the connected Connect token.",
label: "List vaults",
},
{
command: `onequery api --source ${sourceKey} /v1/vaults/<vault-uuid>/items`,
description: "List items in one vault.",
label: "List vault items",
},
{
command: `onequery api --source ${sourceKey} /v1/vaults/<vault-uuid>/items/<item-uuid>`,
description: "Fetch one item from a vault.",
label: "Get item",
},
],
descriptorVersion: ONEPASSWORD_DESCRIPTOR_VERSION,
notes: [
"1Password requests are sent to the configured Connect Server API base URL with Authorization bearer auth.",
"Only GET requests are supported. Item and vault mutations are intentionally excluded.",
"Use `params` in the field patch for Connect API query parameters such as `filter`.",
],
operationNotes: [
"Selectors should be Connect API paths such as `/v1/vaults` or `/v1/vaults/{vaultUUID}/items`.",
],
provider: "onepassword",
providerLabel: "1Password",
});
Loading
Loading