aiex-cli 0.1.0 → 0.1.1-beta.2
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/README.md +8 -29
- package/dist/cli.mjs +434 -483
- package/dist/{generate-drizzle-schema-BqSy0OMm.mjs → generate-drizzle-schema-sZ01QiYJ.mjs} +139 -75
- package/dist/index.d.mts +18 -2
- package/dist/index.mjs +1 -1
- package/dist/table-schema.json +37 -9
- package/dist/web/assets/{AISettings-CxoghpZX.js → AISettings-CRumcTjo.js} +10 -10
- package/dist/web/assets/{DataBrowser-BqmnFDWC.js → DataBrowser-BqRaZJrX.js} +2 -2
- package/dist/web/assets/{ExtractionViewer-Bs8c6xa2.js → ExtractionViewer-lbdQGv2F.js} +1 -1
- package/dist/web/assets/{JsonSchemaEditor-ITVm2zG1.js → JsonSchemaEditor-BywWmkGm.js} +9 -9
- package/dist/web/assets/api-client-CpqFbcyH.js +1 -0
- package/dist/web/assets/{index-DhL7jaO_.js → index-7jWPnI_e.js} +8 -8
- package/dist/web/assets/index-BiNFY3ky.css +2 -0
- package/dist/web/assets/object-utils-OmJ-hFrY.js +1 -0
- package/dist/web/index.html +4 -4
- package/dist/{zh-CN-B2yrInX9.mjs → zh-CN-BAGJklRp.mjs} +15 -56
- package/package.json +1 -1
- package/dist/web/assets/api-client-EJKabzZK.js +0 -1
- package/dist/web/assets/index-D0So2rJE.css +0 -2
- package/dist/web/assets/object-utils-CqCiBqJ4.js +0 -1
|
@@ -11,7 +11,7 @@ import { z } from "zod";
|
|
|
11
11
|
|
|
12
12
|
//#region package.json
|
|
13
13
|
var name = "aiex-cli";
|
|
14
|
-
var version = "0.1.
|
|
14
|
+
var version = "0.1.1-beta.2";
|
|
15
15
|
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
16
16
|
var package_default = {
|
|
17
17
|
name,
|
|
@@ -405,9 +405,60 @@ function getColumnChecks(prop, colName) {
|
|
|
405
405
|
value: prop.maximum
|
|
406
406
|
});
|
|
407
407
|
}
|
|
408
|
+
if (prop.enum?.length) checks.push({
|
|
409
|
+
name: `${colName}_enum`,
|
|
410
|
+
column: colName,
|
|
411
|
+
kind: "enum_value",
|
|
412
|
+
value: prop.enum
|
|
413
|
+
});
|
|
408
414
|
return checks;
|
|
409
415
|
}
|
|
410
|
-
function
|
|
416
|
+
function warnNonDrizzleBackedProperty(warnings, schemaPath, property) {
|
|
417
|
+
if (property.pattern) warnings.push(`${schemaPath}.pattern is kept for extraction guidance but is not emitted as a SQLite constraint because SQLite has no portable REGEXP support.`);
|
|
418
|
+
if (property.drizzle?.customType) warnings.push(`${schemaPath}.drizzle.customType is declared but not emitted. AIEX currently supports stable built-in Drizzle SQLite column types only.`);
|
|
419
|
+
}
|
|
420
|
+
function describeColumnType(columnType) {
|
|
421
|
+
switch (columnType.class) {
|
|
422
|
+
case "text": return {
|
|
423
|
+
drizzleType: columnType.mode === "json" ? `text({ mode: 'json' })` : "text()",
|
|
424
|
+
sqliteType: "text"
|
|
425
|
+
};
|
|
426
|
+
case "integer": return {
|
|
427
|
+
drizzleType: columnType.mode ? `integer({ mode: '${columnType.mode}' })` : "integer()",
|
|
428
|
+
sqliteType: "integer"
|
|
429
|
+
};
|
|
430
|
+
case "real": return {
|
|
431
|
+
drizzleType: "real()",
|
|
432
|
+
sqliteType: "real"
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function columnNotes(property, column) {
|
|
437
|
+
const notes = [];
|
|
438
|
+
if (property.type === "object" || property.type === "array") notes.push("stored_as_json");
|
|
439
|
+
if (property.format === "date-time") notes.push("date_time_as_timestamp");
|
|
440
|
+
if (property.drizzle?.mode) notes.push(`drizzle_mode:${property.drizzle.mode}`);
|
|
441
|
+
if (property.foreignKey) notes.push(`foreign_key:${property.foreignKey.table}.${property.foreignKey.column}`);
|
|
442
|
+
if (column.default !== void 0) notes.push("default");
|
|
443
|
+
return notes;
|
|
444
|
+
}
|
|
445
|
+
function mapColumnToReport(schemaPath, table, property, column, relation) {
|
|
446
|
+
const columnType = describeColumnType(column.columnType);
|
|
447
|
+
return {
|
|
448
|
+
schemaPath,
|
|
449
|
+
table,
|
|
450
|
+
column: column.name,
|
|
451
|
+
drizzleType: columnType.drizzleType,
|
|
452
|
+
sqliteType: columnType.sqliteType,
|
|
453
|
+
nullable: column.isNullable,
|
|
454
|
+
primary: column.isPrimary,
|
|
455
|
+
unique: column.isUnique,
|
|
456
|
+
relation,
|
|
457
|
+
constraints: property.enum?.length ? { enumValues: property.enum } : void 0,
|
|
458
|
+
notes: columnNotes(property, column)
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
function parseObjectToTable(schema, warnings, mapping) {
|
|
411
462
|
const tableName = schema.table.name;
|
|
412
463
|
const columns = [];
|
|
413
464
|
const checks = [];
|
|
@@ -426,6 +477,8 @@ function parseObjectToTable(schema, _warnings) {
|
|
|
426
477
|
const column = mapPropertyToColumn(propName, prop, requiredFields.has(propName));
|
|
427
478
|
columns.push(column);
|
|
428
479
|
checks.push(...getColumnChecks(prop, column.name));
|
|
480
|
+
warnNonDrizzleBackedProperty(warnings, `$.properties.${propName}`, prop);
|
|
481
|
+
mapping.push(mapColumnToReport(`$.properties.${propName}`, tableName, prop, column, "root"));
|
|
429
482
|
}
|
|
430
483
|
if (schema.table.timestamps) {
|
|
431
484
|
const tsCol = {
|
|
@@ -444,18 +497,36 @@ function parseObjectToTable(schema, _warnings) {
|
|
|
444
497
|
...tsCol,
|
|
445
498
|
name: "updated_at"
|
|
446
499
|
});
|
|
500
|
+
mapping.push(mapColumnToReport("$.table.timestamps.createdAt", tableName, {
|
|
501
|
+
type: "integer",
|
|
502
|
+
drizzle: { mode: "timestamp" }
|
|
503
|
+
}, tsCol, "root"));
|
|
504
|
+
mapping.push(mapColumnToReport("$.table.timestamps.updatedAt", tableName, {
|
|
505
|
+
type: "integer",
|
|
506
|
+
drizzle: { mode: "timestamp" }
|
|
507
|
+
}, {
|
|
508
|
+
...tsCol,
|
|
509
|
+
name: "updated_at"
|
|
510
|
+
}, "root"));
|
|
511
|
+
}
|
|
512
|
+
if (schema.table.softDelete) {
|
|
513
|
+
const deletedAt = {
|
|
514
|
+
name: "deleted_at",
|
|
515
|
+
columnType: {
|
|
516
|
+
class: "integer",
|
|
517
|
+
mode: "timestamp"
|
|
518
|
+
},
|
|
519
|
+
isPrimary: false,
|
|
520
|
+
isAutoIncrement: false,
|
|
521
|
+
isNullable: true,
|
|
522
|
+
isUnique: false
|
|
523
|
+
};
|
|
524
|
+
columns.push(deletedAt);
|
|
525
|
+
mapping.push(mapColumnToReport("$.table.softDelete.deletedAt", tableName, {
|
|
526
|
+
type: "integer",
|
|
527
|
+
drizzle: { mode: "timestamp" }
|
|
528
|
+
}, deletedAt, "root"));
|
|
447
529
|
}
|
|
448
|
-
if (schema.table.softDelete) columns.push({
|
|
449
|
-
name: "deleted_at",
|
|
450
|
-
columnType: {
|
|
451
|
-
class: "integer",
|
|
452
|
-
mode: "timestamp"
|
|
453
|
-
},
|
|
454
|
-
isPrimary: false,
|
|
455
|
-
isAutoIncrement: false,
|
|
456
|
-
isNullable: true,
|
|
457
|
-
isUnique: false
|
|
458
|
-
});
|
|
459
530
|
return checks.length > 0 ? {
|
|
460
531
|
name: tableName,
|
|
461
532
|
columns,
|
|
@@ -465,7 +536,7 @@ function parseObjectToTable(schema, _warnings) {
|
|
|
465
536
|
columns
|
|
466
537
|
};
|
|
467
538
|
}
|
|
468
|
-
function parseNestedObject(propName, property, parentTableName, warnings) {
|
|
539
|
+
function parseNestedObject(propName, property, parentTableName, warnings, mapping) {
|
|
469
540
|
const nestedTableName = `${parentTableName}_${toSnakeCase(propName)}`;
|
|
470
541
|
const columns = [];
|
|
471
542
|
const checks = [];
|
|
@@ -478,6 +549,18 @@ function parseNestedObject(propName, property, parentTableName, warnings) {
|
|
|
478
549
|
isNullable: false,
|
|
479
550
|
isUnique: false
|
|
480
551
|
});
|
|
552
|
+
mapping.push({
|
|
553
|
+
schemaPath: `$.properties.${propName}.id`,
|
|
554
|
+
table: nestedTableName,
|
|
555
|
+
column: "id",
|
|
556
|
+
drizzleType: "integer().primaryKey({ autoIncrement: true })",
|
|
557
|
+
sqliteType: "integer",
|
|
558
|
+
nullable: false,
|
|
559
|
+
primary: true,
|
|
560
|
+
unique: false,
|
|
561
|
+
relation: relationType,
|
|
562
|
+
notes: ["generated_nested_primary_key"]
|
|
563
|
+
});
|
|
481
564
|
columns.push({
|
|
482
565
|
name: `${parentTableName}_id`,
|
|
483
566
|
columnType: { class: "integer" },
|
|
@@ -491,6 +574,18 @@ function parseNestedObject(propName, property, parentTableName, warnings) {
|
|
|
491
574
|
column: "id"
|
|
492
575
|
}
|
|
493
576
|
});
|
|
577
|
+
mapping.push({
|
|
578
|
+
schemaPath: `$.properties.${propName}.${parentTableName}Id`,
|
|
579
|
+
table: nestedTableName,
|
|
580
|
+
column: `${parentTableName}_id`,
|
|
581
|
+
drizzleType: "integer().references(...)",
|
|
582
|
+
sqliteType: "integer",
|
|
583
|
+
nullable: false,
|
|
584
|
+
primary: false,
|
|
585
|
+
unique: false,
|
|
586
|
+
relation: relationType,
|
|
587
|
+
notes: [`generated_parent_foreign_key:${parentTableName}.id`]
|
|
588
|
+
});
|
|
494
589
|
if (property.type === "object" && property.properties) for (const [childName, childProp] of Object.entries(property.properties)) {
|
|
495
590
|
if (childProp.nested?.enabled) {
|
|
496
591
|
warnings.push(`Nested property "${childName}" inside "${nestedTableName}" is skipped — only one level of nesting is supported. Remove nested.enabled or use drizzle.mode: 'json' instead.`);
|
|
@@ -499,6 +594,8 @@ function parseNestedObject(propName, property, parentTableName, warnings) {
|
|
|
499
594
|
const column = mapPropertyToColumn(childName, childProp, false);
|
|
500
595
|
columns.push(column);
|
|
501
596
|
checks.push(...getColumnChecks(childProp, column.name));
|
|
597
|
+
warnNonDrizzleBackedProperty(warnings, `$.properties.${propName}.properties.${childName}`, childProp);
|
|
598
|
+
mapping.push(mapColumnToReport(`$.properties.${propName}.properties.${childName}`, nestedTableName, childProp, column, relationType));
|
|
502
599
|
}
|
|
503
600
|
const relation = {
|
|
504
601
|
fromTable: nestedTableName,
|
|
@@ -531,15 +628,16 @@ function parseJsonSchema(schema) {
|
|
|
531
628
|
const relations = [];
|
|
532
629
|
const reverseRelations = [];
|
|
533
630
|
const warnings = [];
|
|
534
|
-
const
|
|
631
|
+
const mapping = [];
|
|
632
|
+
const mainTable = parseObjectToTable(schema, warnings, mapping);
|
|
535
633
|
tables.push(mainTable);
|
|
536
634
|
for (const [propName, prop] of Object.entries(schema.properties)) if (prop.type === "object" && prop.nested?.enabled) {
|
|
537
|
-
const nested = parseNestedObject(propName, prop, mainTable.name, warnings);
|
|
635
|
+
const nested = parseNestedObject(propName, prop, mainTable.name, warnings, mapping);
|
|
538
636
|
tables.push(nested.table);
|
|
539
637
|
relations.push(nested.relation);
|
|
540
638
|
reverseRelations.push(nested.reverseRelation);
|
|
541
639
|
} else if (prop.type === "array" && prop.items?.nested?.enabled && prop.items?.type === "object" && prop.items.properties) {
|
|
542
|
-
const nested = parseNestedObject(propName, prop.items, mainTable.name, warnings);
|
|
640
|
+
const nested = parseNestedObject(propName, prop.items, mainTable.name, warnings, mapping);
|
|
543
641
|
tables.push(nested.table);
|
|
544
642
|
relations.push(nested.relation);
|
|
545
643
|
reverseRelations.push(nested.reverseRelation);
|
|
@@ -548,7 +646,8 @@ function parseJsonSchema(schema) {
|
|
|
548
646
|
tables,
|
|
549
647
|
relations,
|
|
550
648
|
reverseRelations,
|
|
551
|
-
warnings
|
|
649
|
+
warnings,
|
|
650
|
+
mapping
|
|
552
651
|
};
|
|
553
652
|
}
|
|
554
653
|
|
|
@@ -810,7 +909,8 @@ const en = {
|
|
|
810
909
|
description: "Sync JSON Schema to SQLite database",
|
|
811
910
|
args: {
|
|
812
911
|
generate: "Only generate Drizzle schema, skip migrate",
|
|
813
|
-
name: "Name for the migration"
|
|
912
|
+
name: "Name for the migration",
|
|
913
|
+
force: "Allow high-risk schema migrations"
|
|
814
914
|
},
|
|
815
915
|
noSchemas: "No schema files found in {{path}}",
|
|
816
916
|
runWebHint: "Run {{cmd}} to create and configure schemas in the Web UI",
|
|
@@ -825,7 +925,9 @@ const en = {
|
|
|
825
925
|
databaseMigrated: "Database migrated",
|
|
826
926
|
migrationsApplied: "Migrations applied",
|
|
827
927
|
migrationFail: "Migration failed",
|
|
828
|
-
runWithoutGenerate: "Done! Run without --generate to apply migrations"
|
|
928
|
+
runWithoutGenerate: "Done! Run without --generate to apply migrations",
|
|
929
|
+
riskSummary: "Migration risk: {{level}} ({{count}} item(s))",
|
|
930
|
+
highRiskBlocked: "High-risk schema migration blocked. Review .aiex/drizzle/schema-map.json and rerun with {{flag}} to continue."
|
|
829
931
|
},
|
|
830
932
|
extract: {
|
|
831
933
|
description: "Extract structured data from text, images, or PDFs",
|
|
@@ -862,30 +964,6 @@ const en = {
|
|
|
862
964
|
fileRequiredSingle: "Please provide a file (-f) to extract from",
|
|
863
965
|
noSchemas: "No schema files found in {{path}}. Run {{cmd}} to create and configure schemas first."
|
|
864
966
|
},
|
|
865
|
-
history: {
|
|
866
|
-
description: "List extraction audit records",
|
|
867
|
-
empty: "No extraction history found",
|
|
868
|
-
errors: {
|
|
869
|
-
idRequired: "Audit record id is required",
|
|
870
|
-
recordNotFound: "Extraction record not found: {{id}}"
|
|
871
|
-
},
|
|
872
|
-
deleted: "Deleted extraction record: {{id}}"
|
|
873
|
-
},
|
|
874
|
-
show: {
|
|
875
|
-
description: "Show an extraction audit record",
|
|
876
|
-
args: { id: "Audit record id" }
|
|
877
|
-
},
|
|
878
|
-
retry: {
|
|
879
|
-
description: "Retry an extraction audit record",
|
|
880
|
-
args: {
|
|
881
|
-
id: "Audit record id",
|
|
882
|
-
noInsert: "Extract and save JSON without inserting into SQLite"
|
|
883
|
-
}
|
|
884
|
-
},
|
|
885
|
-
rm: {
|
|
886
|
-
description: "Delete an extraction audit record and cached upload",
|
|
887
|
-
args: { id: "Audit record id" }
|
|
888
|
-
},
|
|
889
967
|
batch: {
|
|
890
968
|
scanning: "Scanning {{dir}} for supported files...",
|
|
891
969
|
found: "Found {{count}} file(s) to process",
|
|
@@ -932,6 +1010,14 @@ const en = {
|
|
|
932
1010
|
model: "AI model to use for extraction (overrides default/auto-selected model)",
|
|
933
1011
|
noInsert: "Extract and save JSON without inserting into SQLite database"
|
|
934
1012
|
},
|
|
1013
|
+
interactive: {
|
|
1014
|
+
selectSchema: "Select a schema to watch with:",
|
|
1015
|
+
enterDirPath: "Enter directory path to watch:",
|
|
1016
|
+
dirPathRequired: "Please enter a directory path",
|
|
1017
|
+
selectModel: "Select an AI model:",
|
|
1018
|
+
autoModel: "Auto-select model",
|
|
1019
|
+
askNoInsert: "Save extracted JSON without inserting into SQLite?"
|
|
1020
|
+
},
|
|
935
1021
|
errors: {
|
|
936
1022
|
schemaRequired: "Schema name (-s) is required",
|
|
937
1023
|
dirRequired: "Watch directory path (-d) is required",
|
|
@@ -963,35 +1049,6 @@ const en = {
|
|
|
963
1049
|
failTitle: "AIEX Watch Failed: {{file}}"
|
|
964
1050
|
}
|
|
965
1051
|
},
|
|
966
|
-
dump: {
|
|
967
|
-
description: "Dump SQLite database table to Excel (.xlsx) or CSV (.csv)",
|
|
968
|
-
args: {
|
|
969
|
-
table: "SQLite table name to export",
|
|
970
|
-
schema: "Schema name (without .json extension) to export",
|
|
971
|
-
format: "Export format: csv or xlsx (default: inferred from output or csv)",
|
|
972
|
-
output: "Output file path (default: ./<tableName>.<format>)"
|
|
973
|
-
},
|
|
974
|
-
errors: {
|
|
975
|
-
tableOrSchemaRequired: "Either table name (--table / -t) or schema name (--schema / -s) is required",
|
|
976
|
-
schemaNotFound: "Schema file for \"{{name}}\" not found",
|
|
977
|
-
noTableName: "Schema \"{{name}}\" does not define a database table name.",
|
|
978
|
-
tableMismatch: "Specified table name \"{{table}}\" does not match schema table name \"{{schemaTable}}\"",
|
|
979
|
-
unsupportedFormat: "Unsupported dump format: \"{{format}}\". Supported formats: csv, xlsx",
|
|
980
|
-
dbNotFound: "Database file not found at {{path}}. Please run \"{{cmd}}\" to create the database first.",
|
|
981
|
-
tableNotFound: "Table \"{{name}}\" not found in database. Run \"{{cmd}}\" first to migrate.",
|
|
982
|
-
tableEmpty: "Table \"{{name}}\" is empty. Exporting empty file..."
|
|
983
|
-
},
|
|
984
|
-
loading: "Loading data from table \"{{name}}\"...",
|
|
985
|
-
loaded: "Loaded {{count}} row(s)",
|
|
986
|
-
emptyTable: "Empty table",
|
|
987
|
-
formatting: "Formatting data...",
|
|
988
|
-
formatted: "Data formatted",
|
|
989
|
-
writing: "Writing {{format}} file to {{path}}...",
|
|
990
|
-
dumpCompleted: "Dump completed successfully",
|
|
991
|
-
successMsg: "Successfully dumped {{count}} row(s) to {{path}}",
|
|
992
|
-
fileWriteFailed: "File write failed",
|
|
993
|
-
dbQueryFailed: "Database query failed"
|
|
994
|
-
},
|
|
995
1052
|
doctor: {
|
|
996
1053
|
description: "Print environment and configuration diagnostics",
|
|
997
1054
|
args: { json: "Print diagnostics as JSON" },
|
|
@@ -1036,7 +1093,8 @@ const en = {
|
|
|
1036
1093
|
noFiles: "No schema files found",
|
|
1037
1094
|
migrationFailed: "Migration failed",
|
|
1038
1095
|
migrationHelperInvalidOutput: "Migration helper did not return valid output",
|
|
1039
|
-
migrationHelperFailed: "Migration helper failed"
|
|
1096
|
+
migrationHelperFailed: "Migration helper failed",
|
|
1097
|
+
highRiskMigrationBlocked: "High-risk schema migration blocked"
|
|
1040
1098
|
},
|
|
1041
1099
|
db: {
|
|
1042
1100
|
notFound: "Database not found at {{path}}. Run {{cmd}} first to create the database.",
|
|
@@ -1295,7 +1353,7 @@ async function initI18n(lng) {
|
|
|
1295
1353
|
fallbackLng: "en",
|
|
1296
1354
|
resources: {
|
|
1297
1355
|
"en": { translation: en },
|
|
1298
|
-
"zh-CN": { translation: await import("./zh-CN-
|
|
1356
|
+
"zh-CN": { translation: await import("./zh-CN-BAGJklRp.mjs").then((m) => m.zhCN) }
|
|
1299
1357
|
},
|
|
1300
1358
|
interpolation: { escapeValue: false },
|
|
1301
1359
|
returnNull: false
|
|
@@ -1637,6 +1695,9 @@ function renderColumnType(ct) {
|
|
|
1637
1695
|
function renderDefaultValue(value) {
|
|
1638
1696
|
return JSON.stringify(value);
|
|
1639
1697
|
}
|
|
1698
|
+
function renderSqlLiteral(value) {
|
|
1699
|
+
return typeof value === "number" ? String(value) : `'${value.replace(/'/g, "''")}'`;
|
|
1700
|
+
}
|
|
1640
1701
|
function generateColumnDefinition(column) {
|
|
1641
1702
|
if (column.isPrimary && column.isAutoIncrement) return ` ${column.name}: integer().primaryKey({ autoIncrement: true })`;
|
|
1642
1703
|
let def = ` ${column.name}: ${renderColumnType(column.columnType)}`;
|
|
@@ -1663,6 +1724,9 @@ function renderCheckToDrizzle(check, tableVar) {
|
|
|
1663
1724
|
case "max_value":
|
|
1664
1725
|
expr = `${colRef} <= ${check.value}`;
|
|
1665
1726
|
break;
|
|
1727
|
+
case "enum_value":
|
|
1728
|
+
expr = `${colRef} IN (${(Array.isArray(check.value) ? check.value : []).map(renderSqlLiteral).join(", ")})`;
|
|
1729
|
+
break;
|
|
1666
1730
|
}
|
|
1667
1731
|
return ` ${check.name}: check('${check.name}', sql\`${expr}\`)`;
|
|
1668
1732
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -305,8 +305,8 @@ type ColumnType = {
|
|
|
305
305
|
interface CheckConstraint {
|
|
306
306
|
name: string;
|
|
307
307
|
column: string;
|
|
308
|
-
kind: 'min_length' | 'max_length' | 'min_value' | 'max_value';
|
|
309
|
-
value: number;
|
|
308
|
+
kind: 'min_length' | 'max_length' | 'min_value' | 'max_value' | 'enum_value';
|
|
309
|
+
value: number | (string | number)[];
|
|
310
310
|
}
|
|
311
311
|
interface ParsedColumn {
|
|
312
312
|
name: string;
|
|
@@ -322,6 +322,21 @@ interface ParsedColumn {
|
|
|
322
322
|
column: string;
|
|
323
323
|
};
|
|
324
324
|
}
|
|
325
|
+
interface SchemaMappingEntry {
|
|
326
|
+
schemaPath: string;
|
|
327
|
+
table: string;
|
|
328
|
+
column: string;
|
|
329
|
+
drizzleType: string;
|
|
330
|
+
sqliteType: 'text' | 'integer' | 'real';
|
|
331
|
+
nullable: boolean;
|
|
332
|
+
primary: boolean;
|
|
333
|
+
unique: boolean;
|
|
334
|
+
relation?: 'root' | 'has-one' | 'has-many';
|
|
335
|
+
constraints?: {
|
|
336
|
+
enumValues?: (string | number)[];
|
|
337
|
+
};
|
|
338
|
+
notes: string[];
|
|
339
|
+
}
|
|
325
340
|
interface ParsedTable {
|
|
326
341
|
name: string;
|
|
327
342
|
columns: ParsedColumn[];
|
|
@@ -345,6 +360,7 @@ interface ParseResult {
|
|
|
345
360
|
relations: ParsedRelation[];
|
|
346
361
|
reverseRelations: ParsedReverseRelation[];
|
|
347
362
|
warnings: string[];
|
|
363
|
+
mapping?: SchemaMappingEntry[];
|
|
348
364
|
}
|
|
349
365
|
interface MigrationConfig {
|
|
350
366
|
schemaPath: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { _ as doctorDiagnosticsSeverityRows, g as buildDoctorDiagnostics, i as generateDrizzleConfig, m as parseJsonSchema, n as collectDoctorDiagnostics, p as JsonSchemaDefinitionSchema, r as createMigrationConfig, t as generateDrizzleSchema, v as doctorDiagnosticsTableRows, y as formatDoctorDiagnosticsJson } from "./generate-drizzle-schema-
|
|
1
|
+
import { _ as doctorDiagnosticsSeverityRows, g as buildDoctorDiagnostics, i as generateDrizzleConfig, m as parseJsonSchema, n as collectDoctorDiagnostics, p as JsonSchemaDefinitionSchema, r as createMigrationConfig, t as generateDrizzleSchema, v as doctorDiagnosticsTableRows, y as formatDoctorDiagnosticsJson } from "./generate-drizzle-schema-sZ01QiYJ.mjs";
|
|
2
2
|
|
|
3
3
|
export { JsonSchemaDefinitionSchema, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsSeverityRows, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };
|
package/dist/table-schema.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/OSpoon/aiex-cli/main/app/cli/schemas/table-schema.json",
|
|
4
4
|
"title": "aiex Table Schema",
|
|
5
|
-
"description": "Defines
|
|
5
|
+
"description": "Defines an AIEX Drizzle-backed schema dialect file for schema-to-SQLite migration.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["title", "type", "table", "properties"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -40,6 +40,12 @@
|
|
|
40
40
|
"items": { "type": "string" },
|
|
41
41
|
"description": "List of property names that are NOT NULL.",
|
|
42
42
|
"default": []
|
|
43
|
+
},
|
|
44
|
+
"examples": {
|
|
45
|
+
"type": "array",
|
|
46
|
+
"description": "Few-shot examples used by AI extraction prompts.",
|
|
47
|
+
"items": { "$ref": "#/$defs/examplePair" },
|
|
48
|
+
"default": []
|
|
43
49
|
}
|
|
44
50
|
},
|
|
45
51
|
|
|
@@ -113,12 +119,17 @@
|
|
|
113
119
|
},
|
|
114
120
|
"pattern": {
|
|
115
121
|
"type": "string",
|
|
116
|
-
"description": "Regular expression
|
|
122
|
+
"description": "Regular expression guidance for extraction and validation. Not emitted as a SQLite constraint because SQLite has no portable built-in REGEXP support."
|
|
117
123
|
},
|
|
118
124
|
"enum": {
|
|
119
125
|
"type": "array",
|
|
120
|
-
"items": {
|
|
121
|
-
|
|
126
|
+
"items": {
|
|
127
|
+
"oneOf": [
|
|
128
|
+
{ "type": "string" },
|
|
129
|
+
{ "type": "number" }
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"description": "Enumeration of allowed values for this field. Emitted as a SQLite CHECK constraint."
|
|
122
133
|
},
|
|
123
134
|
"examples": {
|
|
124
135
|
"type": "array",
|
|
@@ -132,20 +143,20 @@
|
|
|
132
143
|
"minLength": {
|
|
133
144
|
"type": "integer",
|
|
134
145
|
"minimum": 0,
|
|
135
|
-
"description": "Minimum string length
|
|
146
|
+
"description": "Minimum string length. Emitted as a SQLite CHECK constraint."
|
|
136
147
|
},
|
|
137
148
|
"maxLength": {
|
|
138
149
|
"type": "integer",
|
|
139
150
|
"minimum": 1,
|
|
140
|
-
"description": "Maximum string length
|
|
151
|
+
"description": "Maximum string length. Emitted as a SQLite CHECK constraint."
|
|
141
152
|
},
|
|
142
153
|
"minimum": {
|
|
143
154
|
"type": "number",
|
|
144
|
-
"description": "Minimum numeric value
|
|
155
|
+
"description": "Minimum numeric value. Emitted as a SQLite CHECK constraint."
|
|
145
156
|
},
|
|
146
157
|
"maximum": {
|
|
147
158
|
"type": "number",
|
|
148
|
-
"description": "Maximum numeric value
|
|
159
|
+
"description": "Maximum numeric value. Emitted as a SQLite CHECK constraint."
|
|
149
160
|
},
|
|
150
161
|
"drizzle": {
|
|
151
162
|
"$ref": "#/$defs/drizzleConfig",
|
|
@@ -198,7 +209,24 @@
|
|
|
198
209
|
},
|
|
199
210
|
"customType": {
|
|
200
211
|
"type": "string",
|
|
201
|
-
"description": "Custom Drizzle type name
|
|
212
|
+
"description": "Custom Drizzle type name. Accepted by the schema shape but not emitted by AIEX; generation reports a warning."
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
"examplePair": {
|
|
218
|
+
"type": "object",
|
|
219
|
+
"required": ["text", "output"],
|
|
220
|
+
"additionalProperties": false,
|
|
221
|
+
"properties": {
|
|
222
|
+
"text": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1,
|
|
225
|
+
"description": "Source text example."
|
|
226
|
+
},
|
|
227
|
+
"output": {
|
|
228
|
+
"type": "object",
|
|
229
|
+
"description": "Expected extracted output for the source text example."
|
|
202
230
|
}
|
|
203
231
|
}
|
|
204
232
|
},
|