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
15 changes: 15 additions & 0 deletions connectors/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@
"script": "sha256:665a010ce5cc1d44a5278f010a56dafa94ff00e4dcd6458fb22afe3d01a505a4",
"metadata": "sha256:b556e27341f88d841cf09cf68e0f9b9fa262f64465b2aa2cf9b64c831fe0a6eb"
}
},
{
"id": "heb-playwright",
"company": "heb",
"version": "1.0.0",
"name": "H-E-B",
"description": "Exports your H-E-B account profile, order history, and product nutrition data using Playwright browser automation.",
"files": {
"script": "heb/heb-playwright.js",
"metadata": "heb/heb-playwright.json"
},
"checksums": {
"script": "sha256:10fb9715d30d4484371c1f82b35521842e608ebf54e045c6fcc0d80444e13e2a",
"metadata": "sha256:b449085b127d03739a91880250f699dd0b1118f5469474733e647514757e4ae3"
}
}
]
}
Binary file added public/icons/heb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 39 additions & 18 deletions scripts/sync-connectors-dev.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,60 @@
#!/usr/bin/env node

/**
* Syncs project connectors to ~/.dataconnect/connectors/ for dev mode.
* Syncs connectors to ~/.dataconnect/connectors/ for dev mode.
*
* The Rust backend checks ~/.dataconnect/connectors/ first (user overrides),
* falling back to the project's connectors/ directory. In production this
* allows OTA updates, but in dev it means local edits are shadowed by stale
* copies. This script copies the project connectors into the user directory
* so dev always runs the latest source tree version.
* If CONNECTORS_PATH is set, syncs from that directory (e.g. a local
* data-connectors repo checkout). Otherwise falls back to the project's
* own connectors/ directory.
*
* Usage:
* CONNECTORS_PATH=../data-connectors npm run tauri:dev
*/

import { cpSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { cpSync, existsSync, mkdirSync, readFileSync } from 'fs';
import { join, dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
import { homedir } from 'os';

const __dirname = dirname(fileURLToPath(import.meta.url));
const PROJECT_CONNECTORS = join(__dirname, '..', 'connectors');
const SOURCE_CONNECTORS = process.env.CONNECTORS_PATH
? resolve(process.env.CONNECTORS_PATH)
: PROJECT_CONNECTORS;
const USER_CONNECTORS = join(homedir(), '.dataconnect', 'connectors');

function log(msg) {
console.log(`[sync-connectors-dev] ${msg}`);
}

// Only sync company/connector dirs (skip schemas/, types/, lib/, registry.json, etc.)
function isConnectorDir(name) {
const skipDirs = ['schemas', 'types', 'lib', 'node_modules'];
if (skipDirs.includes(name)) return false;
const fullPath = join(PROJECT_CONNECTORS, name);
return statSync(fullPath).isDirectory();
// Derive connector directories from registry.json file paths.
function getConnectorDirs() {
const registryPath = join(SOURCE_CONNECTORS, 'registry.json');
if (!existsSync(registryPath)) {
log(`No registry.json found at ${registryPath}`);
return [];
}
const registry = JSON.parse(readFileSync(registryPath, 'utf-8'));
const dirs = new Set();
for (const connector of registry.connectors ?? []) {
for (const filePath of Object.values(connector.files ?? {})) {
dirs.add(filePath.split('/')[0]);
}
}
return [...dirs];
}

function main() {
if (!existsSync(PROJECT_CONNECTORS)) {
log('No project connectors directory found, skipping');
if (!existsSync(SOURCE_CONNECTORS)) {
log(`Connectors source not found: ${SOURCE_CONNECTORS}, skipping`);
return;
}

const dirs = readdirSync(PROJECT_CONNECTORS).filter(isConnectorDir);
if (process.env.CONNECTORS_PATH) {
log(`Using CONNECTORS_PATH: ${SOURCE_CONNECTORS}`);
}

const dirs = getConnectorDirs();

if (dirs.length === 0) {
log('No connector directories found, skipping');
Expand All @@ -48,7 +65,11 @@ function main() {

let copied = 0;
for (const dir of dirs) {
const src = join(PROJECT_CONNECTORS, dir);
const src = join(SOURCE_CONNECTORS, dir);
if (!existsSync(src)) {
log(`Skipping ${dir}/ (not found in ${SOURCE_CONNECTORS})`);
continue;
}
const dest = join(USER_CONNECTORS, dir);
cpSync(src, dest, { recursive: true });
copied++;
Expand Down
13 changes: 13 additions & 0 deletions src/components/icons/platform-heb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { ComponentPropsWithoutRef } from "react"

export const PlatformHebIcon = (
props: ComponentPropsWithoutRef<"img"> & { style?: React.CSSProperties }
) => {
return (
<img
src="/icons/heb.png"
alt="H-E-B"
{...props}
/>
)
}
2 changes: 2 additions & 0 deletions src/lib/platform/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ElementType } from "react"
import { IconX } from "@/components/icons/icon-x"
import { PlatformChatGPTIcon } from "@/components/icons/platform-chatgpt"
import { PlatformGithubIcon } from "@/components/icons/platform-github"
import { PlatformHebIcon } from "@/components/icons/platform-heb"
import { PlatformInstagramGlyphIcon } from "@/components/icons/platform-instagram-glyph"
import { PlatformLinkedinIcon } from "@/components/icons/platform-linkedin"
import { PlatformShopIcon } from "@/components/icons/platform-shop"
Expand All @@ -18,6 +19,7 @@ export type PlatformIconComponent = ElementType<{ className?: string }>
const PLATFORM_ICON_COMPONENTS: Record<string, PlatformIconComponent> = {
chatgpt: PlatformChatGPTIcon,
github: PlatformGithubIcon,
heb: PlatformHebIcon,
instagram: PlatformInstagramGlyphIcon,
linkedin: PlatformLinkedinIcon,
shop: PlatformShopIcon,
Expand Down
12 changes: 12 additions & 0 deletions src/lib/platform/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,16 @@ export const PLATFORM_REGISTRY: PlatformRegistryEntry[] = [
showInConnectList: true,
ingestScope: "shop.orders",
},
{
id: "heb",
displayName: "H-E-B",
iconKey: "heb",
iconEmoji: "🛒",
primaryColor: "#E31837",
platformIds: ["heb-playwright"],
aliases: ["heb"],
availability: "requiresConnector",
showInConnectList: true,
ingestScope: "heb.orders",
},
]