1854 lines · 61.2 KB · TypeScript
RawDownload
import { afterEach, beforeEach, describe, expect, it } from "@effect/vitest";import { drizzle } from "drizzle-orm/libsql";import { migrate } from "drizzle-orm/libsql/migrator";import { Buffer } from "node:buffer";import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";import {  copyFileSync,  existsSync,  mkdirSync,  mkdtempSync,  readFileSync,  readdirSync,  rmSync,  statSync,  writeFileSync,} from "node:fs";import { tmpdir } from "node:os";import { basename, dirname, join } from "node:path";import { Schema } from "effect"; import { collectTables } from "@executor-js/api/server";import { migratedItemId } from "@executor-js/sdk/migration"; import { executeSql, openLocalLibsql } from "./libsql";import { migrateLocalV1ToV2IfNeeded } from "./v1-v2-migration"; const AuthFile = Schema.Record(Schema.String, Schema.String);const decodeAuthFile = Schema.decodeUnknownSync(Schema.fromJsonString(AuthFile));const KeychainBackupForTest = Schema.Struct({  id: Schema.String,  backupId: Schema.Union([Schema.String, Schema.Null]),  existed: Schema.Boolean,});const MigrationJournalForTest = Schema.Struct({  version: Schema.Literal(1),  source: Schema.String,  normalizedSource: Schema.String,  staging: Schema.String,  backup: Schema.String,  authPath: Schema.String,  authBackup: Schema.Union([Schema.String, Schema.Null]),  authExisted: Schema.Boolean,  keychainBackups: Schema.optional(Schema.Array(KeychainBackupForTest)),  nonce: Schema.String,  phase: Schema.Literals(["building", "built", "canonical-moved", "committed"]),});const decodeMigrationJournalForTest = Schema.decodeUnknownSync(  Schema.fromJsonString(MigrationJournalForTest),);const decodeUnknownJson = Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Unknown));// Preserves every journal field (`when`, `breakpoints`, ...), drizzle's// migrator needs them, so only `entries` is typed for the truncation filter.const decodeJournal = (text: string) =>  decodeUnknownJson(text) as {    readonly entries: ReadonlyArray<{ readonly idx: number; readonly tag: string }>;  }; let workDir: string;let previousXdgDataHome: string | undefined;let previousFetch: typeof globalThis.fetch; beforeEach(() => {  workDir = mkdtempSync(join(tmpdir(), "executor-local-v1-v2-"));  previousXdgDataHome = process.env.XDG_DATA_HOME;  previousFetch = globalThis.fetch;  process.env.XDG_DATA_HOME = join(workDir, "xdg");}); afterEach(() => {  if (previousXdgDataHome === undefined) delete process.env.XDG_DATA_HOME;  else process.env.XDG_DATA_HOME = previousXdgDataHome;  globalThis.fetch = previousFetch;  rmSync(workDir, { recursive: true, force: true });}); const seedV1Db = async (  dbPath: string,  scopeId: string,  options: {    readonly includeSecretBackedOauth?: boolean;    readonly includeGraphqlTool?: boolean;    readonly includeMcpToolBinding?: boolean;    readonly includeMcpOauth?: boolean;    readonly jsonBlobs?: boolean;    readonly oauthConnectionProvider?: string;    readonly oauthProviderStateOverrides?: Record<string, unknown>;  } = {},) => {  const client = await openLocalLibsql(dbPath);  await client.execute("PRAGMA foreign_keys = OFF");  await client.execute(`    CREATE TABLE source (      id text NOT NULL,      scope_id text NOT NULL,      plugin_id text NOT NULL,      kind text NOT NULL,      name text NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE plugin_storage (      id text NOT NULL,      scope_id text NOT NULL,      plugin_id text NOT NULL,      collection text NOT NULL,      key text NOT NULL,      data text NOT NULL,      created_at integer NOT NULL,      updated_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE credential_binding (      id text NOT NULL,      scope_id text NOT NULL,      plugin_id text NOT NULL,      source_id text NOT NULL,      source_scope_id text NOT NULL,      slot_key text NOT NULL,      kind text NOT NULL,      text_value text,      secret_id text,      connection_id text,      created_at integer NOT NULL,      updated_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE secret (      id text NOT NULL,      scope_id text NOT NULL,      name text NOT NULL,      provider text NOT NULL,      owned_by_connection_id text,      created_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE connection (      id text NOT NULL,      scope_id text NOT NULL,      provider text NOT NULL,      identity_label text,      access_token_secret_id text,      refresh_token_secret_id text,      expires_at integer,      provider_state text,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE tool_policy (      id text NOT NULL,      scope_id text NOT NULL,      pattern text NOT NULL,      action text NOT NULL,      position text NOT NULL,      created_at integer NOT NULL,      updated_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE tool (      id text NOT NULL,      scope_id text NOT NULL,      source_id text NOT NULL,      plugin_id text NOT NULL,      name text NOT NULL,      description text NOT NULL,      input_schema text,      output_schema text,      created_at integer NOT NULL,      updated_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE definition (      id text NOT NULL,      scope_id text NOT NULL,      source_id text NOT NULL,      plugin_id text NOT NULL,      name text NOT NULL,      schema text NOT NULL,      created_at integer NOT NULL,      PRIMARY KEY(scope_id, id)    )  `);  await client.execute(`    CREATE TABLE blob (      namespace text NOT NULL,      key text NOT NULL,      value text NOT NULL,      row_id text NOT NULL,      id text NOT NULL,      PRIMARY KEY(id)    )  `);   const now = Date.now();  const json = (value: unknown): string | Buffer => {    const text = JSON.stringify(value);    return options.jsonBlobs ? Buffer.from(text) : text;  };   await executeSql(    client,    "INSERT INTO source (id, scope_id, plugin_id, kind, name) VALUES (?, ?, ?, ?, ?)",    ["stripe_api", scopeId, "openapi", "openapi", "Stripe"],  );  await executeSql(    client,    "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",    [      "openapi-source-stripe",      scopeId,      "openapi",      "source",      "stripe_api",      json({        config: {          spec: "{}",          headers: {            Authorization: {              kind: "binding",              slot: "header:authorization",              prefix: "Bearer ",            },          },        },      }),      now,      now,    ],  );  await executeSql(    client,    "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",    [      "provider-settings",      scopeId,      "onepassword",      "settings",      "config",      json({ vaultId: "vault-123" }),      now,      now,    ],  );  await executeSql(    client,    "INSERT INTO credential_binding (id, scope_id, plugin_id, source_id, source_scope_id, slot_key, kind, text_value, secret_id, connection_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",    [      "stripe-auth",      scopeId,      "openapi",      "stripe_api",      scopeId,      "header:authorization",      "secret",      null,      "stripe-key",      null,      now,      now,    ],  );  await executeSql(    client,    "INSERT INTO secret (id, scope_id, name, provider, owned_by_connection_id, created_at) VALUES (?, ?, ?, ?, ?, ?)",    ["stripe-key", scopeId, "Stripe key", "file", null, now],  );  await executeSql(    client,    "INSERT INTO tool_policy (id, scope_id, pattern, action, position, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)",    ["policy-1", scopeId, "stripe_api.charges.create", "approve", "a0", now, now],  );  await executeSql(    client,    "INSERT INTO tool (id, scope_id, source_id, plugin_id, name, description, input_schema, output_schema, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",    [      "stripe_api.charges.create",      scopeId,      "stripe_api",      "openapi",      "charges.create",      "Create a charge",      json({ type: "object" }),      json({ type: "object" }),      now,      now,    ],  );  await executeSql(    client,    "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",    [      "openapi-operation-stripe-charge",      scopeId,      "openapi",      "operation",      "stripe_api.charges.create",      json({        toolId: "stripe_api.charges.create",        sourceId: "stripe_api",        binding: {          method: "post",          pathTemplate: "/v1/charges",          parameters: [],        },      }),      now,      now,    ],  );  await executeSql(    client,    "INSERT INTO definition (id, scope_id, source_id, plugin_id, name, schema, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",    [      "stripe_api.Charge",      scopeId,      "stripe_api",      "openapi",      "Charge",      json({ type: "object", properties: { id: { type: "string" } } }),      now,    ],  );  await executeSql(    client,    "INSERT INTO blob (namespace, key, value, row_id, id) VALUES (?, ?, ?, ?, ?)",    [      `${scopeId}/onepassword`,      "config",      JSON.stringify({ vaultId: "vault-123" }),      "blob-row",      JSON.stringify([`${scopeId}/onepassword`, "config"]),    ],  );   if (options.includeMcpToolBinding) {    await executeSql(      client,      "INSERT INTO source (id, scope_id, plugin_id, kind, name) VALUES (?, ?, ?, ?, ?)",      ["axiom_mcp", scopeId, "mcp", "mcp", "Axiom MCP"],    );    await executeSql(      client,      "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",      [        "mcp-source-axiom",        scopeId,        "mcp",        "source",        "axiom_mcp",        json({          config: {            endpoint: "https://mcp.axiom.co/mcp",            headers: {              Authorization: {                kind: "binding",                slot: "header:authorization",                prefix: "Bearer ",              },            },            auth: { kind: "none" },          },        }),        now,        now,      ],    );    await executeSql(      client,      "INSERT INTO secret (id, scope_id, name, provider, owned_by_connection_id, created_at) VALUES (?, ?, ?, ?, ?, ?)",      ["axiom-token", scopeId, "Axiom MCP OAuth", "file", null, now],    );    await executeSql(      client,      "INSERT INTO credential_binding (id, scope_id, plugin_id, source_id, source_scope_id, slot_key, kind, text_value, secret_id, connection_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",      [        "axiom-auth",        scopeId,        "mcp",        "axiom_mcp",        scopeId,        "header:authorization",        "secret",        null,        "axiom-token",        null,        now,        now,      ],    );    await executeSql(      client,      "INSERT INTO tool (id, scope_id, source_id, plugin_id, name, description, input_schema, output_schema, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",      [        "axiom_mcp.querydataset",        scopeId,        "axiom_mcp",        "mcp",        "querydataset",        "Query Axiom datasets",        json({ type: "object" }),        json({ type: "object" }),        now,        now,      ],    );    await executeSql(      client,      "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",      [        "mcp-binding-axiom-querydataset",        scopeId,        "mcp",        "binding",        "axiom_mcp.querydataset",        json({          namespace: "axiom_mcp",          toolId: "axiom_mcp.querydataset",          binding: {            toolId: "querydataset",            toolName: "queryDataset",            description: "Query Axiom datasets",            inputSchema: { type: "object" },            annotations: { title: "Query dataset", readOnlyHint: true },          },        }),        now,        now,      ],    );    await executeSql(      client,      "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",      [        "graphql-operation-query-hello",        scopeId,        "graphql",        "operation",        "graphql_api.query.hello",        json({          toolId: "graphql_api.query.hello",          sourceId: "graphql_api",          binding: {            kind: "query",            fieldName: "hello",            operationString: "query { hello }",            variableNames: [],          },        }),        now,        now,      ],    );  }   if (options.includeGraphqlTool) {    await executeSql(      client,      "INSERT INTO source (id, scope_id, plugin_id, kind, name) VALUES (?, ?, ?, ?, ?)",      ["graphql_api", scopeId, "graphql", "graphql", "GraphQL API"],    );    await executeSql(      client,      "INSERT INTO plugin_storage (id, scope_id, plugin_id, collection, key, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",      [        "graphql-source-api",        scopeId,        "graphql",        "source",        "graphql_api",        json({          config: {            endpoint: "https://api.example.com/graphql",            headers: {              Authorization: {                kind: "binding",                slot: "header:authorization",                prefix: "Bearer ",              },            },            auth: { kind: "none" },          },        }),        now,        now,      ],    );    await executeSql(      client,      "INSERT INTO secret (id, scope_id, name, provider, owned_by_connection_id, created_at) VALUES (?, ?, ?, ?, ?, ?)",

Lines 1–500 of 1854.