aiex-cli 0.0.2-beta.2 → 0.0.2-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +287 -215
- package/dist/{doctor-collector-BhNgLdrJ.mjs → doctor-collector-CGUF999y.mjs} +1 -1
- package/dist/index.mjs +1 -1
- package/dist/web/assets/AISettings-BgwAdAIK.js +346 -0
- package/dist/web/assets/ExtractRunner-BxI-y6zS.js +1 -0
- package/dist/web/assets/{ExtractionViewer-D7tghmR-.js → ExtractionViewer-Dxgbk3y5.js} +1 -1
- package/dist/web/assets/{JsonSchemaEditor-DXhYW-Un.js → JsonSchemaEditor-ul3bZNBq.js} +3 -3
- package/dist/web/assets/{api-client-CIC2X8_4.js → api-client-BwMoRXRu.js} +1 -1
- package/dist/web/assets/{cssMode-CCz1uj8b.js → cssMode-BJcNHjlk.js} +1 -1
- package/dist/web/assets/{editor.main-DOue-nGf.js → editor.main-DQNDtAJT.js} +2 -2
- package/dist/web/assets/{freemarker2-C87H7V8i.js → freemarker2-S3U7WteK.js} +1 -1
- package/dist/web/assets/{handlebars-TLnoktZW.js → handlebars-BrE9AAwL.js} +1 -1
- package/dist/web/assets/{html-Rewbtgcp.js → html-C6Vb0qjf.js} +1 -1
- package/dist/web/assets/{htmlMode-Cr9y3YUi.js → htmlMode-D6ZrqWr1.js} +1 -1
- package/dist/web/assets/{index-FPVIOydC.js → index-e8dWRIEv.js} +7 -7
- package/dist/web/assets/{javascript-BO8DPECx.js → javascript-DB-UTK4i.js} +1 -1
- package/dist/web/assets/{jsonMode-B78m_Y1l.js → jsonMode-w2VFiNNs.js} +1 -1
- package/dist/web/assets/{liquid-CDp_8YUE.js → liquid-1XTLVrg3.js} +1 -1
- package/dist/web/assets/{mdx-CeR1GULE.js → mdx-C4k_4MX5.js} +1 -1
- package/dist/web/assets/{monaco.contribution-tCitzj1_.js → monaco.contribution-DrrjJ0Xr.js} +2 -2
- package/dist/web/assets/{python-DWmB1hQ6.js → python-DU-NBP37.js} +1 -1
- package/dist/web/assets/{razor-BVk762Lq.js → razor-CDS0MJZV.js} +1 -1
- package/dist/web/assets/select-Dj2p-fw_.js +439 -0
- package/dist/web/assets/{tsMode-Gjs5D1gt.js → tsMode-ClDl0-oy.js} +1 -1
- package/dist/web/assets/{typescript-Cw6YtwrM.js → typescript-DVPndl3f.js} +1 -1
- package/dist/web/assets/{xml-guZq0YZJ.js → xml-ZTAdiNZS.js} +1 -1
- package/dist/web/assets/{yaml-B9TbU-LX.js → yaml-4WO-VI9I.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/AISettings-DU-jBPOf.js +0 -205
- package/dist/web/assets/ExtractRunner-CzfLlCCf.js +0 -1
- package/dist/web/assets/baseinput-B7PU5-38.js +0 -2
- package/dist/web/assets/checkbox-CCQwMfLd.js +0 -142
- package/dist/web/assets/select-DKPPF403.js +0 -438
- /package/dist/web/assets/{DataBrowser-DQwOvooY.js → DataBrowser-CLOlYw5B.js} +0 -0
- /package/dist/web/assets/{abap-C3UM4cME.js → abap-CFuyUYKP.js} +0 -0
- /package/dist/web/assets/{apex-BQBZvQmN.js → apex-Ctq_xcrv.js} +0 -0
- /package/dist/web/assets/{azcli-Dn9Awrok.js → azcli-BBQSVn-C.js} +0 -0
- /package/dist/web/assets/{bat-JgEezSDo.js → bat-DbnqAfvr.js} +0 -0
- /package/dist/web/assets/{bicep-vcQeC7wE.js → bicep-BtDlIXop.js} +0 -0
- /package/dist/web/assets/{cameligo-C0cr0T3L.js → cameligo-BLeJgKTj.js} +0 -0
- /package/dist/web/assets/{clojure-Brc1-rbW.js → clojure-aZUQIUKP.js} +0 -0
- /package/dist/web/assets/{coffee-BiZYU83a.js → coffee-Secadq9U.js} +0 -0
- /package/dist/web/assets/{cpp-ikWHCInz.js → cpp-JicRPTRv.js} +0 -0
- /package/dist/web/assets/{csharp-BRWs_LfH.js → csharp-C7NSOZyj.js} +0 -0
- /package/dist/web/assets/{csp-CcAumoJw.js → csp-CIje7830.js} +0 -0
- /package/dist/web/assets/{css-BZm6paiA.js → css-G0bm1q_M.js} +0 -0
- /package/dist/web/assets/{cypher-CDQMONdb.js → cypher-CldD5D0u.js} +0 -0
- /package/dist/web/assets/{dart-Ci4SZdF1.js → dart-DIK3l8YT.js} +0 -0
- /package/dist/web/assets/{dockerfile-BV0tAr-M.js → dockerfile-czxaGh2L.js} +0 -0
- /package/dist/web/assets/{ecl-CP7nM2KN.js → ecl-BqdYhwmw.js} +0 -0
- /package/dist/web/assets/{editor.api-BU_q4v8i.js → editor.api-DrogPInQ.js} +0 -0
- /package/dist/web/assets/{elixir-GcA6wFiI.js → elixir-m52LePTW.js} +0 -0
- /package/dist/web/assets/{flow9-CIb9youF.js → flow9-B5QJ9GvZ.js} +0 -0
- /package/dist/web/assets/{fsharp-BVaBE4co.js → fsharp-Bsj2_cCa.js} +0 -0
- /package/dist/web/assets/{go-Bbqf306x.js → go-BqOR3oKA.js} +0 -0
- /package/dist/web/assets/{graphql-DJPrC4l-.js → graphql-B8qEHPdi.js} +0 -0
- /package/dist/web/assets/{hcl-QyfWVWpM.js → hcl-DWuCE4v-.js} +0 -0
- /package/dist/web/assets/{ini-CgstZeS8.js → ini-Qq7k0Z4_.js} +0 -0
- /package/dist/web/assets/{java-D4AG88ZY.js → java-BYPjirKp.js} +0 -0
- /package/dist/web/assets/{julia-CN8U9648.js → julia-BDPeJze-.js} +0 -0
- /package/dist/web/assets/{kotlin-gNNgpJhY.js → kotlin-Cn6ib1e9.js} +0 -0
- /package/dist/web/assets/{less-C3SY2L8t.js → less-CJaXZ051.js} +0 -0
- /package/dist/web/assets/{lexon-CznnqzUX.js → lexon-8Vqfm7H_.js} +0 -0
- /package/dist/web/assets/{lua-f3xyJgy5.js → lua-CvR2zKQJ.js} +0 -0
- /package/dist/web/assets/{m3-Cl7J89p-.js → m3-B_srJ0-W.js} +0 -0
- /package/dist/web/assets/{markdown-Bv2fnzzT.js → markdown-BLHPl-_K.js} +0 -0
- /package/dist/web/assets/{mips-D6rXUTWa.js → mips-DVyJ6qEt.js} +0 -0
- /package/dist/web/assets/{msdax-Bb1N2x5J.js → msdax-CSgWECQy.js} +0 -0
- /package/dist/web/assets/{mysql-DXSr6oD7.js → mysql-DgAobqZA.js} +0 -0
- /package/dist/web/assets/{objective-c-CEJiVkDa.js → objective-c-YsnCzZhx.js} +0 -0
- /package/dist/web/assets/{pascal-BtkMEIba.js → pascal-DBRbVM1J.js} +0 -0
- /package/dist/web/assets/{pascaligo-C7FAwqk7.js → pascaligo-DGMAqea9.js} +0 -0
- /package/dist/web/assets/{perl-D9kqkBbN.js → perl-BbO9hyuY.js} +0 -0
- /package/dist/web/assets/{pgsql-BjGTBL1W.js → pgsql-C-hxeXjm.js} +0 -0
- /package/dist/web/assets/{php-BN0c0noA.js → php-CNUtuIOY.js} +0 -0
- /package/dist/web/assets/{pla-B94QTqOt.js → pla-kg11R4PY.js} +0 -0
- /package/dist/web/assets/{postiats-DH91dqBs.js → postiats-B1z9yYod.js} +0 -0
- /package/dist/web/assets/{powerquery-D7P0oUen.js → powerquery-B7uH8tJZ.js} +0 -0
- /package/dist/web/assets/{powershell-CCVHmJax.js → powershell-C4XFI11Z.js} +0 -0
- /package/dist/web/assets/{protobuf-BIP7pixC.js → protobuf-BcOV_0Q2.js} +0 -0
- /package/dist/web/assets/{pug-DcbLK7HH.js → pug-68xbfbza.js} +0 -0
- /package/dist/web/assets/{qsharp-B-VY_WOG.js → qsharp-BrGH6SSV.js} +0 -0
- /package/dist/web/assets/{r-DwRtsJsj.js → r--OWX2YhF.js} +0 -0
- /package/dist/web/assets/{redis-CaW0tkwu.js → redis-BOXumJdj.js} +0 -0
- /package/dist/web/assets/{redshift-3tS8G0ME.js → redshift-8U3qVUZv.js} +0 -0
- /package/dist/web/assets/{restructuredtext-_TNyGyK0.js → restructuredtext-D6puF6Gd.js} +0 -0
- /package/dist/web/assets/{ruby-A-MwVfO4.js → ruby-g_KUrR8T.js} +0 -0
- /package/dist/web/assets/{rust-oemlUIvG.js → rust-Dm8AnzU3.js} +0 -0
- /package/dist/web/assets/{sb-BDZuaI3W.js → sb-D_ts6T0n.js} +0 -0
- /package/dist/web/assets/{scala-Bfo2loK4.js → scala-C6NOuwmJ.js} +0 -0
- /package/dist/web/assets/{scheme-N2eo7rjB.js → scheme-CPooyhAN.js} +0 -0
- /package/dist/web/assets/{scss-vjjSCTgN.js → scss-DUEUJROR.js} +0 -0
- /package/dist/web/assets/{shell-Bfb9Yq6w.js → shell-kdqtsGKx.js} +0 -0
- /package/dist/web/assets/{solidity-C9RbukzG.js → solidity-CnMA-U-d.js} +0 -0
- /package/dist/web/assets/{sophia-DWV_MWOg.js → sophia-BKvc9daj.js} +0 -0
- /package/dist/web/assets/{sparql-iMXILWhh.js → sparql-Bh3XvRxY.js} +0 -0
- /package/dist/web/assets/{sql-CJDj31JM.js → sql-CRPVrMOO.js} +0 -0
- /package/dist/web/assets/{st-BG9AQ1OO.js → st-DBvoSKfh.js} +0 -0
- /package/dist/web/assets/{swift-B579DvHm.js → swift-B8QEexRZ.js} +0 -0
- /package/dist/web/assets/{systemverilog-BNgaF3ZX.js → systemverilog-CBeOTblq.js} +0 -0
- /package/dist/web/assets/{tcl-grdtJiUA.js → tcl-DR5kknHN.js} +0 -0
- /package/dist/web/assets/{twig-JAsFXBZw.js → twig-5OXXSkT1.js} +0 -0
- /package/dist/web/assets/{typespec-D3hIQXEU.js → typespec-cVMWW5z1.js} +0 -0
- /package/dist/web/assets/{vb-H38jRcEz.js → vb-DRjqfs-G.js} +0 -0
- /package/dist/web/assets/{wgsl-BC5Grc5r.js → wgsl-B5lRvHwm.js} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as version, T as formatDoctorDiagnosticsJson, _ as createConfig, a as parseJsonSchema, b as name, c as getDefaultAIConfig, d as DEFAULT_MARKITDOWN_CONFIG, f as DEFAULT_MINERU_CONFIG, g as AIConfigSchema, h as PLACEHOLDER_TEXT, i as JsonSchemaDefinitionSchema, l as readAIConfig, m as PLACEHOLDER_SCHEMA, n as createMigrationConfig, o as toSnakeCase, p as DEFAULT_PROMPT_CONFIG, s as generateDrizzleSchema, t as collectDoctorDiagnostics, u as writeAIConfig, v as seedConfig, w as doctorDiagnosticsTableRows, x as package_default, y as description } from "./doctor-collector-
|
|
1
|
+
import { S as version, T as formatDoctorDiagnosticsJson, _ as createConfig, a as parseJsonSchema, b as name, c as getDefaultAIConfig, d as DEFAULT_MARKITDOWN_CONFIG, f as DEFAULT_MINERU_CONFIG, g as AIConfigSchema, h as PLACEHOLDER_TEXT, i as JsonSchemaDefinitionSchema, l as readAIConfig, m as PLACEHOLDER_SCHEMA, n as createMigrationConfig, o as toSnakeCase, p as DEFAULT_PROMPT_CONFIG, s as generateDrizzleSchema, t as collectDoctorDiagnostics, u as writeAIConfig, v as seedConfig, w as doctorDiagnosticsTableRows, x as package_default, y as description } from "./doctor-collector-CGUF999y.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
@@ -23,6 +23,7 @@ import { jsonrepair } from "jsonrepair";
|
|
|
23
23
|
import fs$1 from "node:fs";
|
|
24
24
|
import Database from "better-sqlite3";
|
|
25
25
|
import { glob, globSync } from "tinyglobby";
|
|
26
|
+
import { Client, extractNotionId } from "@notionhq/client";
|
|
26
27
|
import { execa } from "execa";
|
|
27
28
|
import { extractText, getDocumentProxy, getMeta } from "unpdf";
|
|
28
29
|
import { Buffer } from "node:buffer";
|
|
@@ -33,7 +34,6 @@ import open from "open";
|
|
|
33
34
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
34
35
|
import { Hono } from "hono";
|
|
35
36
|
import { cors } from "hono/cors";
|
|
36
|
-
import { Client, extractNotionId } from "@notionhq/client";
|
|
37
37
|
import { zValidator } from "@hono/zod-validator";
|
|
38
38
|
import { Kysely, SqliteDialect, sql } from "kysely";
|
|
39
39
|
|
|
@@ -13487,6 +13487,213 @@ async function deleteExtractionAuditRecord(aiexDir, id) {
|
|
|
13487
13487
|
return true;
|
|
13488
13488
|
}
|
|
13489
13489
|
|
|
13490
|
+
//#endregion
|
|
13491
|
+
//#region src/core/notion-sink.ts
|
|
13492
|
+
const RICH_TEXT_LIMIT = 2e3;
|
|
13493
|
+
const UUID_RE = /^[0-9a-f]{32}$/i;
|
|
13494
|
+
const HYPHENATED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
13495
|
+
function truncateText(value) {
|
|
13496
|
+
return value.length > RICH_TEXT_LIMIT ? value.slice(0, RICH_TEXT_LIMIT) : value;
|
|
13497
|
+
}
|
|
13498
|
+
function stringifyValue(value) {
|
|
13499
|
+
if (value === null || value === void 0) return "";
|
|
13500
|
+
if (typeof value === "string") return value;
|
|
13501
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
13502
|
+
return JSON.stringify(value);
|
|
13503
|
+
}
|
|
13504
|
+
function asNumber(value) {
|
|
13505
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
13506
|
+
if (typeof value === "string" && value.trim()) {
|
|
13507
|
+
const parsed = Number(value);
|
|
13508
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
13509
|
+
}
|
|
13510
|
+
return null;
|
|
13511
|
+
}
|
|
13512
|
+
function asBoolean(value) {
|
|
13513
|
+
if (typeof value === "boolean") return value;
|
|
13514
|
+
if (typeof value === "number") return value !== 0;
|
|
13515
|
+
if (typeof value === "string") {
|
|
13516
|
+
const normalized = value.trim().toLowerCase();
|
|
13517
|
+
return [
|
|
13518
|
+
"true",
|
|
13519
|
+
"yes",
|
|
13520
|
+
"1",
|
|
13521
|
+
"y"
|
|
13522
|
+
].includes(normalized);
|
|
13523
|
+
}
|
|
13524
|
+
return !!value;
|
|
13525
|
+
}
|
|
13526
|
+
function asDateStart(value) {
|
|
13527
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) return value.toISOString();
|
|
13528
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
13529
|
+
const date = new Date(value);
|
|
13530
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
13531
|
+
}
|
|
13532
|
+
if (typeof value === "string" && value.trim()) {
|
|
13533
|
+
const ms = Date.parse(value);
|
|
13534
|
+
if (Number.isNaN(ms)) return null;
|
|
13535
|
+
return new Date(ms).toISOString();
|
|
13536
|
+
}
|
|
13537
|
+
return null;
|
|
13538
|
+
}
|
|
13539
|
+
function asStringArray(value) {
|
|
13540
|
+
if (Array.isArray(value)) return value.map((item) => stringifyValue(item).trim()).filter(Boolean);
|
|
13541
|
+
const text$1 = stringifyValue(value).trim();
|
|
13542
|
+
return text$1 ? [text$1] : [];
|
|
13543
|
+
}
|
|
13544
|
+
function buildPropertyValue(type, value) {
|
|
13545
|
+
const text$1 = truncateText(stringifyValue(value));
|
|
13546
|
+
switch (type) {
|
|
13547
|
+
case "title": return { title: text$1 ? [{ text: { content: text$1 } }] : [] };
|
|
13548
|
+
case "rich_text": return { rich_text: text$1 ? [{ text: { content: text$1 } }] : [] };
|
|
13549
|
+
case "number": return { number: asNumber(value) };
|
|
13550
|
+
case "checkbox": return { checkbox: asBoolean(value) };
|
|
13551
|
+
case "date": {
|
|
13552
|
+
const start = asDateStart(value);
|
|
13553
|
+
return { date: start ? { start } : null };
|
|
13554
|
+
}
|
|
13555
|
+
case "select": {
|
|
13556
|
+
const name$1 = stringifyValue(value).trim();
|
|
13557
|
+
return { select: name$1 ? { name: name$1 } : null };
|
|
13558
|
+
}
|
|
13559
|
+
case "multi_select": return { multi_select: asStringArray(value).map((name$1) => ({ name: name$1 })) };
|
|
13560
|
+
case "url": return { url: text$1 || null };
|
|
13561
|
+
case "email": return { email: text$1 || null };
|
|
13562
|
+
case "phone_number": return { phone_number: text$1 || null };
|
|
13563
|
+
default: return null;
|
|
13564
|
+
}
|
|
13565
|
+
}
|
|
13566
|
+
function findTitleProperty(properties, preferred) {
|
|
13567
|
+
if (preferred && properties[preferred]?.type === "title") return preferred;
|
|
13568
|
+
return Object.entries(properties).find(([, property]) => property?.type === "title")?.[0] ?? null;
|
|
13569
|
+
}
|
|
13570
|
+
function hyphenateDatabaseId(value) {
|
|
13571
|
+
const id = value.replace(/-/g, "");
|
|
13572
|
+
if (!UUID_RE.test(id)) return value;
|
|
13573
|
+
return `${id.slice(0, 8)}-${id.slice(8, 12)}-${id.slice(12, 16)}-${id.slice(16, 20)}-${id.slice(20)}`;
|
|
13574
|
+
}
|
|
13575
|
+
function parseNotionDatabaseId(value) {
|
|
13576
|
+
const input = value.trim();
|
|
13577
|
+
if (!input) return "";
|
|
13578
|
+
const extracted = extractNotionId(input);
|
|
13579
|
+
if (extracted) return extracted;
|
|
13580
|
+
if (HYPHENATED_UUID_RE.test(input)) return input;
|
|
13581
|
+
if (UUID_RE.test(input)) return hyphenateDatabaseId(input);
|
|
13582
|
+
return input;
|
|
13583
|
+
}
|
|
13584
|
+
function normalizeFieldName(value) {
|
|
13585
|
+
return value.normalize("NFKC").toLowerCase().replace(/[^\p{Letter}\p{Number}]+/gu, "");
|
|
13586
|
+
}
|
|
13587
|
+
function buildMatchKeys(field) {
|
|
13588
|
+
return [
|
|
13589
|
+
field.name,
|
|
13590
|
+
field.title,
|
|
13591
|
+
field.description
|
|
13592
|
+
].filter((value) => !!value?.trim()).map(normalizeFieldName).filter(Boolean);
|
|
13593
|
+
}
|
|
13594
|
+
function suggestFieldMap(schemaFields, databaseProperties) {
|
|
13595
|
+
const propertyByKey = /* @__PURE__ */ new Map();
|
|
13596
|
+
for (const propertyName of Object.keys(databaseProperties)) propertyByKey.set(normalizeFieldName(propertyName), propertyName);
|
|
13597
|
+
const fieldMap = {};
|
|
13598
|
+
for (const field of schemaFields) for (const key of buildMatchKeys(field)) {
|
|
13599
|
+
const propertyName = propertyByKey.get(key);
|
|
13600
|
+
if (propertyName) {
|
|
13601
|
+
fieldMap[field.name] = propertyName;
|
|
13602
|
+
break;
|
|
13603
|
+
}
|
|
13604
|
+
}
|
|
13605
|
+
return fieldMap;
|
|
13606
|
+
}
|
|
13607
|
+
function hasProperties(value) {
|
|
13608
|
+
return !!value && typeof value === "object" && !!value.properties && typeof value.properties === "object";
|
|
13609
|
+
}
|
|
13610
|
+
function firstDataSourceId(database) {
|
|
13611
|
+
return (Array.isArray(database?.data_sources) ? database.data_sources : []).find((source) => typeof source?.id === "string" && source.id.trim())?.id;
|
|
13612
|
+
}
|
|
13613
|
+
async function resolveNotionDataSource(notion, inputId) {
|
|
13614
|
+
const id = parseNotionDatabaseId(inputId);
|
|
13615
|
+
if (!id) throw new Error("Notion database or data source URL/ID is required.");
|
|
13616
|
+
try {
|
|
13617
|
+
const dataSource$1 = await notion.dataSources.retrieve({ data_source_id: id });
|
|
13618
|
+
if (hasProperties(dataSource$1)) return {
|
|
13619
|
+
databaseId: typeof dataSource$1.parent?.database_id === "string" ? dataSource$1.parent.database_id : id,
|
|
13620
|
+
dataSourceId: dataSource$1.id ?? id,
|
|
13621
|
+
properties: dataSource$1.properties,
|
|
13622
|
+
parent: { data_source_id: dataSource$1.id ?? id }
|
|
13623
|
+
};
|
|
13624
|
+
} catch {}
|
|
13625
|
+
const database = await notion.databases.retrieve({ database_id: id });
|
|
13626
|
+
if (hasProperties(database)) return {
|
|
13627
|
+
databaseId: database.id ?? id,
|
|
13628
|
+
properties: database.properties,
|
|
13629
|
+
parent: { database_id: database.id ?? id }
|
|
13630
|
+
};
|
|
13631
|
+
const dataSourceId = firstDataSourceId(database);
|
|
13632
|
+
if (!dataSourceId) throw new Error("No data source found for this Notion database. Copy the data source link from Notion, or share the source database with the integration.");
|
|
13633
|
+
const dataSource = await notion.dataSources.retrieve({ data_source_id: dataSourceId });
|
|
13634
|
+
if (!hasProperties(dataSource)) throw new Error("Notion data source did not return properties. Make sure it is shared with the integration and is not a linked data source.");
|
|
13635
|
+
return {
|
|
13636
|
+
databaseId: database.id ?? id,
|
|
13637
|
+
dataSourceId: dataSource.id ?? dataSourceId,
|
|
13638
|
+
properties: dataSource.properties,
|
|
13639
|
+
parent: { data_source_id: dataSource.id ?? dataSourceId }
|
|
13640
|
+
};
|
|
13641
|
+
}
|
|
13642
|
+
async function inspectNotionDatabase(input) {
|
|
13643
|
+
if (!input.token.trim()) throw new Error("Notion integration token is required.");
|
|
13644
|
+
const id = parseNotionDatabaseId(input.databaseId);
|
|
13645
|
+
if (!id) throw new Error("Notion database or data source URL/ID is required.");
|
|
13646
|
+
const resolved = await resolveNotionDataSource(new Client({ auth: input.token }), id);
|
|
13647
|
+
const databaseProperties = resolved.properties;
|
|
13648
|
+
const titleProperty = findTitleProperty(databaseProperties) ?? void 0;
|
|
13649
|
+
return {
|
|
13650
|
+
databaseId: resolved.databaseId,
|
|
13651
|
+
dataSourceId: resolved.dataSourceId,
|
|
13652
|
+
titleProperty,
|
|
13653
|
+
properties: Object.entries(databaseProperties).map(([name$1, property]) => ({
|
|
13654
|
+
name: name$1,
|
|
13655
|
+
type: property?.type ?? "unknown"
|
|
13656
|
+
})).sort((a, b) => a.name.localeCompare(b.name)),
|
|
13657
|
+
suggestedFieldMap: suggestFieldMap(input.schemaFields, databaseProperties)
|
|
13658
|
+
};
|
|
13659
|
+
}
|
|
13660
|
+
function validateNotionConfig(config) {
|
|
13661
|
+
if (!config?.enabled) return "Notion export is not enabled. Configure Notion settings first.";
|
|
13662
|
+
if (!config.token.trim()) return "Notion integration token is required.";
|
|
13663
|
+
return null;
|
|
13664
|
+
}
|
|
13665
|
+
async function writeNotionPage(config, schemaName, data) {
|
|
13666
|
+
const configError = validateNotionConfig(config);
|
|
13667
|
+
if (configError) throw new Error(configError);
|
|
13668
|
+
const notionConfig = config;
|
|
13669
|
+
const schemaConfig = notionConfig.schemas[schemaName];
|
|
13670
|
+
if (!schemaConfig) throw new Error(`Notion database is not configured for schema "${schemaName}".`);
|
|
13671
|
+
if (!schemaConfig.databaseId.trim()) throw new Error(`Notion database ID is required for schema "${schemaName}".`);
|
|
13672
|
+
const notion = new Client({ auth: notionConfig.token });
|
|
13673
|
+
const resolved = await resolveNotionDataSource(notion, schemaConfig.databaseId);
|
|
13674
|
+
const databaseProperties = resolved.properties;
|
|
13675
|
+
const fieldMap = schemaConfig.fieldMap ?? {};
|
|
13676
|
+
const properties = {};
|
|
13677
|
+
for (const [sourceField, sourceValue] of Object.entries(data)) {
|
|
13678
|
+
const notionPropertyName = fieldMap[sourceField] ?? sourceField;
|
|
13679
|
+
const notionProperty = databaseProperties[notionPropertyName];
|
|
13680
|
+
if (!notionProperty) continue;
|
|
13681
|
+
const propertyValue = buildPropertyValue(notionProperty.type, sourceValue);
|
|
13682
|
+
if (propertyValue) properties[notionPropertyName] = propertyValue;
|
|
13683
|
+
}
|
|
13684
|
+
const titleProperty = findTitleProperty(databaseProperties, schemaConfig.titleProperty);
|
|
13685
|
+
if (titleProperty && !properties[titleProperty]) properties[titleProperty] = buildPropertyValue("title", Object.entries(data).find(([, value]) => typeof value === "string" && value.trim())?.[1] ?? schemaName);
|
|
13686
|
+
if (Object.keys(properties).length === 0) throw new Error("No extracted fields matched Notion database properties.");
|
|
13687
|
+
return {
|
|
13688
|
+
pageId: (await notion.pages.create({
|
|
13689
|
+
parent: resolved.parent,
|
|
13690
|
+
properties
|
|
13691
|
+
})).id,
|
|
13692
|
+
databaseId: resolved.databaseId,
|
|
13693
|
+
dataSourceId: resolved.dataSourceId
|
|
13694
|
+
};
|
|
13695
|
+
}
|
|
13696
|
+
|
|
13490
13697
|
//#endregion
|
|
13491
13698
|
//#region src/core/pdf-converter/external.ts
|
|
13492
13699
|
function applyTemplate(value, context) {
|
|
@@ -13681,6 +13888,17 @@ const SUPPORTED_EXTENSIONS = new Set([
|
|
|
13681
13888
|
const PDF_EXT_RE = /\.pdf$/i;
|
|
13682
13889
|
const JSON_EXT_RE$1 = /\.json$/;
|
|
13683
13890
|
const SUPPORTED_FILE_PATTERN = `*.{${[...SUPPORTED_EXTENSIONS].join(",")}}`;
|
|
13891
|
+
async function syncResultToNotion(aiConfig, schemaName, data) {
|
|
13892
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error("Extraction result is not an object and cannot be written to Notion.");
|
|
13893
|
+
const page = await writeNotionPage(aiConfig.notion, schemaName, data);
|
|
13894
|
+
return [{
|
|
13895
|
+
databaseId: page.databaseId,
|
|
13896
|
+
pageId: page.pageId
|
|
13897
|
+
}];
|
|
13898
|
+
}
|
|
13899
|
+
function shouldSyncNotion(aiConfig, schemaName) {
|
|
13900
|
+
return !!aiConfig.notion?.enabled && !!aiConfig.notion.schemas?.[schemaName]?.databaseId?.trim();
|
|
13901
|
+
}
|
|
13684
13902
|
async function ensureDatabaseReady(dbPath, schema) {
|
|
13685
13903
|
try {
|
|
13686
13904
|
await fs.access(dbPath);
|
|
@@ -13872,11 +14090,28 @@ async function processOneFile(aiexDir, config, aiConfig, schemaName, filePath, m
|
|
|
13872
14090
|
insert: options?.insert
|
|
13873
14091
|
});
|
|
13874
14092
|
if (r.success) {
|
|
14093
|
+
let notionPages;
|
|
14094
|
+
if (shouldSyncNotion(aiConfig, schemaName)) try {
|
|
14095
|
+
notionPages = await syncResultToNotion(aiConfig, schemaName, r.data);
|
|
14096
|
+
consola.success(`Synced to Notion: ${notionPages.length} page(s)`);
|
|
14097
|
+
} catch (error) {
|
|
14098
|
+
await updateExtractionAuditRecord(aiexDir, audit.id, {
|
|
14099
|
+
status: "failed",
|
|
14100
|
+
outputPath: r.outputPath,
|
|
14101
|
+
outputName: r.outputPath ? path.basename(r.outputPath) : void 0,
|
|
14102
|
+
tablesInserted: r.tablesInserted,
|
|
14103
|
+
tokensUsed: r.tokensUsed,
|
|
14104
|
+
error: error instanceof Error ? error.message : String(error)
|
|
14105
|
+
});
|
|
14106
|
+
consola.error(`Notion sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
14107
|
+
return false;
|
|
14108
|
+
}
|
|
13875
14109
|
await updateExtractionAuditRecord(aiexDir, audit.id, {
|
|
13876
14110
|
status: "succeeded",
|
|
13877
14111
|
outputPath: r.outputPath,
|
|
13878
14112
|
outputName: r.outputPath ? path.basename(r.outputPath) : void 0,
|
|
13879
14113
|
tablesInserted: r.tablesInserted,
|
|
14114
|
+
notionPages,
|
|
13880
14115
|
tokensUsed: r.tokensUsed
|
|
13881
14116
|
});
|
|
13882
14117
|
consola.success(`Processed: ${path.basename(filePath)}`);
|
|
@@ -13984,11 +14219,33 @@ async function runAuditedSingleExtraction(input) {
|
|
|
13984
14219
|
});
|
|
13985
14220
|
return false;
|
|
13986
14221
|
}
|
|
14222
|
+
let notionPages;
|
|
14223
|
+
if (input.aiConfig.notion?.enabled && input.aiConfig.notion.schemas?.[input.schemaName]?.databaseId?.trim()) try {
|
|
14224
|
+
if (!result.data || typeof result.data !== "object" || Array.isArray(result.data)) throw new Error("Extraction result is not an object and cannot be written to Notion.");
|
|
14225
|
+
const page = await writeNotionPage(input.aiConfig.notion, input.schemaName, result.data);
|
|
14226
|
+
notionPages = [{
|
|
14227
|
+
databaseId: page.databaseId,
|
|
14228
|
+
pageId: page.pageId
|
|
14229
|
+
}];
|
|
14230
|
+
consola.success(`Synced to Notion: ${notionPages.length} page(s)`);
|
|
14231
|
+
} catch (error) {
|
|
14232
|
+
await updateExtractionAuditRecord(input.aiexDir, audit.id, {
|
|
14233
|
+
status: "failed",
|
|
14234
|
+
outputPath: result.outputPath,
|
|
14235
|
+
outputName: result.outputPath ? path.basename(result.outputPath) : void 0,
|
|
14236
|
+
tablesInserted: result.tablesInserted,
|
|
14237
|
+
tokensUsed: result.tokensUsed,
|
|
14238
|
+
error: error instanceof Error ? error.message : String(error)
|
|
14239
|
+
});
|
|
14240
|
+
consola.error(`Notion sync failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
14241
|
+
return false;
|
|
14242
|
+
}
|
|
13987
14243
|
await updateExtractionAuditRecord(input.aiexDir, audit.id, {
|
|
13988
14244
|
status: "succeeded",
|
|
13989
14245
|
outputPath: result.outputPath,
|
|
13990
14246
|
outputName: result.outputPath ? path.basename(result.outputPath) : void 0,
|
|
13991
14247
|
tablesInserted: result.tablesInserted,
|
|
14248
|
+
notionPages,
|
|
13992
14249
|
tokensUsed: result.tokensUsed
|
|
13993
14250
|
});
|
|
13994
14251
|
return true;
|
|
@@ -14300,7 +14557,18 @@ async function runInteractive(aiexDir, config, aiConfig, modelOverride) {
|
|
|
14300
14557
|
cancel("Cancelled");
|
|
14301
14558
|
return false;
|
|
14302
14559
|
}
|
|
14303
|
-
return (
|
|
14560
|
+
return runAuditedSingleExtraction({
|
|
14561
|
+
aiexDir,
|
|
14562
|
+
config,
|
|
14563
|
+
aiConfig,
|
|
14564
|
+
schemaName,
|
|
14565
|
+
text: textContent,
|
|
14566
|
+
source: {
|
|
14567
|
+
type: "text",
|
|
14568
|
+
text: textContent
|
|
14569
|
+
},
|
|
14570
|
+
modelOverride
|
|
14571
|
+
});
|
|
14304
14572
|
} else if (inputSource === "file") {
|
|
14305
14573
|
const filePathStr = await text({
|
|
14306
14574
|
message: "Enter file path:",
|
|
@@ -14315,7 +14583,20 @@ async function runInteractive(aiexDir, config, aiConfig, modelOverride) {
|
|
|
14315
14583
|
const fp = filePathStr;
|
|
14316
14584
|
try {
|
|
14317
14585
|
const input = await readExtractFileInput(fp, aiConfig);
|
|
14318
|
-
return (
|
|
14586
|
+
return runAuditedSingleExtraction({
|
|
14587
|
+
aiexDir,
|
|
14588
|
+
config,
|
|
14589
|
+
aiConfig,
|
|
14590
|
+
schemaName,
|
|
14591
|
+
text: input.text,
|
|
14592
|
+
filePath: input.filePath,
|
|
14593
|
+
source: {
|
|
14594
|
+
type: "file",
|
|
14595
|
+
filePath: fp,
|
|
14596
|
+
fileName: path.basename(fp)
|
|
14597
|
+
},
|
|
14598
|
+
modelOverride
|
|
14599
|
+
});
|
|
14319
14600
|
} catch (e) {
|
|
14320
14601
|
consola.error(`Cannot read file: ${fp} — ${e instanceof Error ? e.message : String(e)}`);
|
|
14321
14602
|
return false;
|
|
@@ -14521,213 +14802,6 @@ const schemaCommand = defineCommand({
|
|
|
14521
14802
|
}
|
|
14522
14803
|
});
|
|
14523
14804
|
|
|
14524
|
-
//#endregion
|
|
14525
|
-
//#region src/core/notion-sink.ts
|
|
14526
|
-
const RICH_TEXT_LIMIT = 2e3;
|
|
14527
|
-
const UUID_RE = /^[0-9a-f]{32}$/i;
|
|
14528
|
-
const HYPHENATED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
14529
|
-
function truncateText(value) {
|
|
14530
|
-
return value.length > RICH_TEXT_LIMIT ? value.slice(0, RICH_TEXT_LIMIT) : value;
|
|
14531
|
-
}
|
|
14532
|
-
function stringifyValue(value) {
|
|
14533
|
-
if (value === null || value === void 0) return "";
|
|
14534
|
-
if (typeof value === "string") return value;
|
|
14535
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
14536
|
-
return JSON.stringify(value);
|
|
14537
|
-
}
|
|
14538
|
-
function asNumber(value) {
|
|
14539
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
14540
|
-
if (typeof value === "string" && value.trim()) {
|
|
14541
|
-
const parsed = Number(value);
|
|
14542
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
14543
|
-
}
|
|
14544
|
-
return null;
|
|
14545
|
-
}
|
|
14546
|
-
function asBoolean(value) {
|
|
14547
|
-
if (typeof value === "boolean") return value;
|
|
14548
|
-
if (typeof value === "number") return value !== 0;
|
|
14549
|
-
if (typeof value === "string") {
|
|
14550
|
-
const normalized = value.trim().toLowerCase();
|
|
14551
|
-
return [
|
|
14552
|
-
"true",
|
|
14553
|
-
"yes",
|
|
14554
|
-
"1",
|
|
14555
|
-
"y"
|
|
14556
|
-
].includes(normalized);
|
|
14557
|
-
}
|
|
14558
|
-
return !!value;
|
|
14559
|
-
}
|
|
14560
|
-
function asDateStart(value) {
|
|
14561
|
-
if (value instanceof Date && !Number.isNaN(value.getTime())) return value.toISOString();
|
|
14562
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
14563
|
-
const date = new Date(value);
|
|
14564
|
-
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
14565
|
-
}
|
|
14566
|
-
if (typeof value === "string" && value.trim()) {
|
|
14567
|
-
const ms = Date.parse(value);
|
|
14568
|
-
if (Number.isNaN(ms)) return null;
|
|
14569
|
-
return new Date(ms).toISOString();
|
|
14570
|
-
}
|
|
14571
|
-
return null;
|
|
14572
|
-
}
|
|
14573
|
-
function asStringArray(value) {
|
|
14574
|
-
if (Array.isArray(value)) return value.map((item) => stringifyValue(item).trim()).filter(Boolean);
|
|
14575
|
-
const text$1 = stringifyValue(value).trim();
|
|
14576
|
-
return text$1 ? [text$1] : [];
|
|
14577
|
-
}
|
|
14578
|
-
function buildPropertyValue(type, value) {
|
|
14579
|
-
const text$1 = truncateText(stringifyValue(value));
|
|
14580
|
-
switch (type) {
|
|
14581
|
-
case "title": return { title: text$1 ? [{ text: { content: text$1 } }] : [] };
|
|
14582
|
-
case "rich_text": return { rich_text: text$1 ? [{ text: { content: text$1 } }] : [] };
|
|
14583
|
-
case "number": return { number: asNumber(value) };
|
|
14584
|
-
case "checkbox": return { checkbox: asBoolean(value) };
|
|
14585
|
-
case "date": {
|
|
14586
|
-
const start = asDateStart(value);
|
|
14587
|
-
return { date: start ? { start } : null };
|
|
14588
|
-
}
|
|
14589
|
-
case "select": {
|
|
14590
|
-
const name$1 = stringifyValue(value).trim();
|
|
14591
|
-
return { select: name$1 ? { name: name$1 } : null };
|
|
14592
|
-
}
|
|
14593
|
-
case "multi_select": return { multi_select: asStringArray(value).map((name$1) => ({ name: name$1 })) };
|
|
14594
|
-
case "url": return { url: text$1 || null };
|
|
14595
|
-
case "email": return { email: text$1 || null };
|
|
14596
|
-
case "phone_number": return { phone_number: text$1 || null };
|
|
14597
|
-
default: return null;
|
|
14598
|
-
}
|
|
14599
|
-
}
|
|
14600
|
-
function findTitleProperty(properties, preferred) {
|
|
14601
|
-
if (preferred && properties[preferred]?.type === "title") return preferred;
|
|
14602
|
-
return Object.entries(properties).find(([, property]) => property?.type === "title")?.[0] ?? null;
|
|
14603
|
-
}
|
|
14604
|
-
function hyphenateDatabaseId(value) {
|
|
14605
|
-
const id = value.replace(/-/g, "");
|
|
14606
|
-
if (!UUID_RE.test(id)) return value;
|
|
14607
|
-
return `${id.slice(0, 8)}-${id.slice(8, 12)}-${id.slice(12, 16)}-${id.slice(16, 20)}-${id.slice(20)}`;
|
|
14608
|
-
}
|
|
14609
|
-
function parseNotionDatabaseId(value) {
|
|
14610
|
-
const input = value.trim();
|
|
14611
|
-
if (!input) return "";
|
|
14612
|
-
const extracted = extractNotionId(input);
|
|
14613
|
-
if (extracted) return extracted;
|
|
14614
|
-
if (HYPHENATED_UUID_RE.test(input)) return input;
|
|
14615
|
-
if (UUID_RE.test(input)) return hyphenateDatabaseId(input);
|
|
14616
|
-
return input;
|
|
14617
|
-
}
|
|
14618
|
-
function normalizeFieldName(value) {
|
|
14619
|
-
return value.normalize("NFKC").toLowerCase().replace(/[^\p{Letter}\p{Number}]+/gu, "");
|
|
14620
|
-
}
|
|
14621
|
-
function buildMatchKeys(field) {
|
|
14622
|
-
return [
|
|
14623
|
-
field.name,
|
|
14624
|
-
field.title,
|
|
14625
|
-
field.description
|
|
14626
|
-
].filter((value) => !!value?.trim()).map(normalizeFieldName).filter(Boolean);
|
|
14627
|
-
}
|
|
14628
|
-
function suggestFieldMap(schemaFields, databaseProperties) {
|
|
14629
|
-
const propertyByKey = /* @__PURE__ */ new Map();
|
|
14630
|
-
for (const propertyName of Object.keys(databaseProperties)) propertyByKey.set(normalizeFieldName(propertyName), propertyName);
|
|
14631
|
-
const fieldMap = {};
|
|
14632
|
-
for (const field of schemaFields) for (const key of buildMatchKeys(field)) {
|
|
14633
|
-
const propertyName = propertyByKey.get(key);
|
|
14634
|
-
if (propertyName) {
|
|
14635
|
-
fieldMap[field.name] = propertyName;
|
|
14636
|
-
break;
|
|
14637
|
-
}
|
|
14638
|
-
}
|
|
14639
|
-
return fieldMap;
|
|
14640
|
-
}
|
|
14641
|
-
function hasProperties(value) {
|
|
14642
|
-
return !!value && typeof value === "object" && !!value.properties && typeof value.properties === "object";
|
|
14643
|
-
}
|
|
14644
|
-
function firstDataSourceId(database) {
|
|
14645
|
-
return (Array.isArray(database?.data_sources) ? database.data_sources : []).find((source) => typeof source?.id === "string" && source.id.trim())?.id;
|
|
14646
|
-
}
|
|
14647
|
-
async function resolveNotionDataSource(notion, inputId) {
|
|
14648
|
-
const id = parseNotionDatabaseId(inputId);
|
|
14649
|
-
if (!id) throw new Error("Notion database or data source URL/ID is required.");
|
|
14650
|
-
try {
|
|
14651
|
-
const dataSource$1 = await notion.dataSources.retrieve({ data_source_id: id });
|
|
14652
|
-
if (hasProperties(dataSource$1)) return {
|
|
14653
|
-
databaseId: typeof dataSource$1.parent?.database_id === "string" ? dataSource$1.parent.database_id : id,
|
|
14654
|
-
dataSourceId: dataSource$1.id ?? id,
|
|
14655
|
-
properties: dataSource$1.properties,
|
|
14656
|
-
parent: { data_source_id: dataSource$1.id ?? id }
|
|
14657
|
-
};
|
|
14658
|
-
} catch {}
|
|
14659
|
-
const database = await notion.databases.retrieve({ database_id: id });
|
|
14660
|
-
if (hasProperties(database)) return {
|
|
14661
|
-
databaseId: database.id ?? id,
|
|
14662
|
-
properties: database.properties,
|
|
14663
|
-
parent: { database_id: database.id ?? id }
|
|
14664
|
-
};
|
|
14665
|
-
const dataSourceId = firstDataSourceId(database);
|
|
14666
|
-
if (!dataSourceId) throw new Error("No data source found for this Notion database. Copy the data source link from Notion, or share the source database with the integration.");
|
|
14667
|
-
const dataSource = await notion.dataSources.retrieve({ data_source_id: dataSourceId });
|
|
14668
|
-
if (!hasProperties(dataSource)) throw new Error("Notion data source did not return properties. Make sure it is shared with the integration and is not a linked data source.");
|
|
14669
|
-
return {
|
|
14670
|
-
databaseId: database.id ?? id,
|
|
14671
|
-
dataSourceId: dataSource.id ?? dataSourceId,
|
|
14672
|
-
properties: dataSource.properties,
|
|
14673
|
-
parent: { data_source_id: dataSource.id ?? dataSourceId }
|
|
14674
|
-
};
|
|
14675
|
-
}
|
|
14676
|
-
async function inspectNotionDatabase(input) {
|
|
14677
|
-
if (!input.token.trim()) throw new Error("Notion integration token is required.");
|
|
14678
|
-
const id = parseNotionDatabaseId(input.databaseId);
|
|
14679
|
-
if (!id) throw new Error("Notion database or data source URL/ID is required.");
|
|
14680
|
-
const resolved = await resolveNotionDataSource(new Client({ auth: input.token }), id);
|
|
14681
|
-
const databaseProperties = resolved.properties;
|
|
14682
|
-
const titleProperty = findTitleProperty(databaseProperties) ?? void 0;
|
|
14683
|
-
return {
|
|
14684
|
-
databaseId: resolved.databaseId,
|
|
14685
|
-
dataSourceId: resolved.dataSourceId,
|
|
14686
|
-
titleProperty,
|
|
14687
|
-
properties: Object.entries(databaseProperties).map(([name$1, property]) => ({
|
|
14688
|
-
name: name$1,
|
|
14689
|
-
type: property?.type ?? "unknown"
|
|
14690
|
-
})).sort((a, b) => a.name.localeCompare(b.name)),
|
|
14691
|
-
suggestedFieldMap: suggestFieldMap(input.schemaFields, databaseProperties)
|
|
14692
|
-
};
|
|
14693
|
-
}
|
|
14694
|
-
function validateNotionConfig(config) {
|
|
14695
|
-
if (!config?.enabled) return "Notion export is not enabled. Configure Notion settings first.";
|
|
14696
|
-
if (!config.token.trim()) return "Notion integration token is required.";
|
|
14697
|
-
return null;
|
|
14698
|
-
}
|
|
14699
|
-
async function writeNotionPage(config, schemaName, data) {
|
|
14700
|
-
const configError = validateNotionConfig(config);
|
|
14701
|
-
if (configError) throw new Error(configError);
|
|
14702
|
-
const notionConfig = config;
|
|
14703
|
-
const schemaConfig = notionConfig.schemas[schemaName];
|
|
14704
|
-
if (!schemaConfig) throw new Error(`Notion database is not configured for schema "${schemaName}".`);
|
|
14705
|
-
if (!schemaConfig.databaseId.trim()) throw new Error(`Notion database ID is required for schema "${schemaName}".`);
|
|
14706
|
-
const notion = new Client({ auth: notionConfig.token });
|
|
14707
|
-
const resolved = await resolveNotionDataSource(notion, schemaConfig.databaseId);
|
|
14708
|
-
const databaseProperties = resolved.properties;
|
|
14709
|
-
const fieldMap = schemaConfig.fieldMap ?? {};
|
|
14710
|
-
const properties = {};
|
|
14711
|
-
for (const [sourceField, sourceValue] of Object.entries(data)) {
|
|
14712
|
-
const notionPropertyName = fieldMap[sourceField] ?? sourceField;
|
|
14713
|
-
const notionProperty = databaseProperties[notionPropertyName];
|
|
14714
|
-
if (!notionProperty) continue;
|
|
14715
|
-
const propertyValue = buildPropertyValue(notionProperty.type, sourceValue);
|
|
14716
|
-
if (propertyValue) properties[notionPropertyName] = propertyValue;
|
|
14717
|
-
}
|
|
14718
|
-
const titleProperty = findTitleProperty(databaseProperties, schemaConfig.titleProperty);
|
|
14719
|
-
if (titleProperty && !properties[titleProperty]) properties[titleProperty] = buildPropertyValue("title", Object.entries(data).find(([, value]) => typeof value === "string" && value.trim())?.[1] ?? schemaName);
|
|
14720
|
-
if (Object.keys(properties).length === 0) throw new Error("No extracted fields matched Notion database properties.");
|
|
14721
|
-
return {
|
|
14722
|
-
pageId: (await notion.pages.create({
|
|
14723
|
-
parent: resolved.parent,
|
|
14724
|
-
properties
|
|
14725
|
-
})).id,
|
|
14726
|
-
databaseId: resolved.databaseId,
|
|
14727
|
-
dataSourceId: resolved.dataSourceId
|
|
14728
|
-
};
|
|
14729
|
-
}
|
|
14730
|
-
|
|
14731
14805
|
//#endregion
|
|
14732
14806
|
//#region src/server/routes/ai.ts
|
|
14733
14807
|
const JSON_EXT_RE = /\.json$/i;
|
|
@@ -15113,7 +15187,7 @@ async function executeAuditedExtraction(input) {
|
|
|
15113
15187
|
});
|
|
15114
15188
|
}
|
|
15115
15189
|
const notionPages = [];
|
|
15116
|
-
if (input.
|
|
15190
|
+
if (aiConfig.notion?.enabled && aiConfig.notion.schemas?.[input.schemaName]?.databaseId?.trim()) try {
|
|
15117
15191
|
if (!result.data || typeof result.data !== "object" || Array.isArray(result.data)) throw new Error("Extraction result is not an object and cannot be written to Notion.");
|
|
15118
15192
|
notionPages.push(await writeNotionPage(aiConfig.notion, input.schemaName, result.data));
|
|
15119
15193
|
} catch (error) {
|
|
@@ -15168,7 +15242,6 @@ function extractRoutes(config) {
|
|
|
15168
15242
|
const schemaName = getFormString(body.schema);
|
|
15169
15243
|
const text$1 = getFormString(body.text);
|
|
15170
15244
|
const modelName = getFormString(body.model);
|
|
15171
|
-
const syncNotion = getFormString(body.notion) === "true";
|
|
15172
15245
|
const file = getFormFile(body.file);
|
|
15173
15246
|
if (!schemaName) return c.json({
|
|
15174
15247
|
success: false,
|
|
@@ -15209,8 +15282,7 @@ function extractRoutes(config) {
|
|
|
15209
15282
|
schemaName,
|
|
15210
15283
|
text: text$1,
|
|
15211
15284
|
filePath,
|
|
15212
|
-
modelName
|
|
15213
|
-
syncNotion
|
|
15285
|
+
modelName
|
|
15214
15286
|
});
|
|
15215
15287
|
} catch (error) {
|
|
15216
15288
|
return c.json({
|
|
@@ -65,7 +65,7 @@ function doctorDiagnosticsTableRows(d) {
|
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region package.json
|
|
67
67
|
var name = "aiex-cli";
|
|
68
|
-
var version = "0.0.2-beta.
|
|
68
|
+
var version = "0.0.2-beta.3";
|
|
69
69
|
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
70
70
|
var package_default = {
|
|
71
71
|
name,
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as buildDoctorDiagnostics, T as formatDoctorDiagnosticsJson, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, w as doctorDiagnosticsTableRows } from "./doctor-collector-
|
|
1
|
+
import { C as buildDoctorDiagnostics, T as formatDoctorDiagnosticsJson, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, w as doctorDiagnosticsTableRows } from "./doctor-collector-CGUF999y.mjs";
|
|
2
2
|
|
|
3
3
|
export { JsonSchemaDefinitionSchema, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };
|