@an5/orm 1.2.0 → 1.3.1

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.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/dist/generator/src/api.d.ts +3 -0
  3. package/dist/generator/src/api.js +7 -1
  4. package/dist/generator/src/code-generator.js +12 -1
  5. package/dist/generator/src/code-request.d.ts +2 -2
  6. package/dist/generator/src/code-request.js +24 -3
  7. package/dist/generator/src/config.d.ts +18 -0
  8. package/dist/generator/src/config.js +24 -0
  9. package/dist/generator/src/dialect.js +4 -2
  10. package/dist/generator/src/dotnet-generator.js +97 -1
  11. package/dist/generator/src/field-types.js +3 -0
  12. package/dist/generator/src/golang-generator.d.ts +8 -0
  13. package/dist/generator/src/golang-generator.js +183 -9
  14. package/dist/generator/src/index.js +18 -0
  15. package/dist/generator/src/java-generator.d.ts +56 -0
  16. package/dist/generator/src/java-generator.js +1408 -0
  17. package/dist/generator/src/kotlin-generator.d.ts +34 -0
  18. package/dist/generator/src/kotlin-generator.js +753 -0
  19. package/dist/generator/src/python-generator.js +4 -2
  20. package/dist/generator/src/rust-generator.js +36 -1
  21. package/dist/generator/src/swift-generator.d.ts +42 -0
  22. package/dist/generator/src/swift-generator.js +768 -0
  23. package/generator/src/api.ts +3 -0
  24. package/generator/src/code-generator.ts +13 -1
  25. package/generator/src/code-request.ts +17 -3
  26. package/generator/src/config.ts +48 -0
  27. package/generator/src/dialect.ts +5 -3
  28. package/generator/src/dotnet-generator.ts +97 -1
  29. package/generator/src/field-types.ts +3 -0
  30. package/generator/src/golang-generator.ts +184 -9
  31. package/generator/src/index.ts +21 -0
  32. package/generator/src/java-generator.ts +1459 -0
  33. package/generator/src/kotlin-generator.ts +798 -0
  34. package/generator/src/python-generator.ts +4 -2
  35. package/generator/src/rust-generator.ts +37 -1
  36. package/generator/src/swift-generator.ts +830 -0
  37. package/package.json +2 -2
@@ -56,7 +56,7 @@ class PythonGenerator {
56
56
  }
57
57
  generateOrmTypes(models, outputDir) {
58
58
  let content = '# This file is auto-generated. Do not edit directly.\n';
59
- content += '"""\nAN5 ORM typed filter/args dataclasses for type-safe queries.\n\nUsage example::\n\n db.user.find_many(where=UserWhereInput(name=StringFilter(contains="John")),\n order_by=UserOrderByInput(created_at="desc"),\n take=10)\n"""\n';
59
+ content += '"""\nAN5 ORM typed filter/args dataclasses.\n\nThese describe the filter shapes the Python client accepts. The adapter reads plain\ndicts, not these dataclasses, and it quotes every key verbatim, so use the schema\nfield names (`createdAt`, not `created_at`):\n\n db.user.find_many(where={"name": {"contains": "John"}},\n order_by={"createdAt": "desc"},\n take=10)\n"""\n';
60
60
  content += 'from __future__ import annotations\n';
61
61
  content += 'from dataclasses import dataclass, field\n';
62
62
  content += 'from typing import List, Optional, Any\n';
@@ -318,9 +318,11 @@ class PythonGenerator {
318
318
  }
319
319
  content += 'class An5Client:\n';
320
320
  content += ' """AN5 Python ORM Client - type-safe database access.\n\n';
321
+ content += ' Query keys are schema field names, used verbatim: the SQL builder quotes a key\n';
322
+ content += ' as-is, so `createdAt` reaches the database and `created_at` does not.\n\n';
321
323
  content += ' Usage:\n';
322
324
  content += ' db = An5Client()\n';
323
- content += ' users = db.user.find_many(where={"name": {"contains": "John"}}, order_by={"created_at": "asc"}, take=10)\n';
325
+ content += ' users = db.user.find_many(where={"name": {"contains": "John"}}, order_by={"createdAt": "asc"}, take=10)\n';
324
326
  content += ' user = db.user.find_first(where={"id": "abc"})\n';
325
327
  content += ' new = db.user.create(data={"name": "Alice", "email": "alice@example.com"})\n';
326
328
  content += ' """\n';
@@ -490,6 +490,20 @@ pub struct DateTimeFilter {
490
490
  s.push(` #[serde(default, skip_serializing_if = "Option::is_none")]`);
491
491
  s.push(` pub where_: Option<${name}WhereInput>,`);
492
492
  s.push(`}\n`);
493
+ // VectorSearchArgs mirrors the runtime's, so a caller can narrow the search.
494
+ s.push(`/// ORM-style args for ${name}.vector_search().`);
495
+ s.push(`#[derive(Debug, Clone, Default, Serialize, Deserialize)]`);
496
+ s.push(`pub struct ${name}VectorSearchArgs {`);
497
+ s.push(` pub vector: Vec<f32>,`);
498
+ s.push(` #[serde(default, skip_serializing_if = "Option::is_none")]`);
499
+ s.push(` pub take: Option<i64>,`);
500
+ s.push(` #[serde(default, skip_serializing_if = "Option::is_none")]`);
501
+ s.push(` pub where_: Option<${name}WhereInput>,`);
502
+ s.push(` #[serde(default)]`);
503
+ s.push(` pub vector_field: String,`);
504
+ s.push(` #[serde(default)]`);
505
+ s.push(` pub distance_metric: String,`);
506
+ s.push(`}\n`);
493
507
  // UpdateArgs carries the typed input alongside the where clause.
494
508
  s.push(`/// ORM-style args for ${name}.update().`);
495
509
  s.push(`#[derive(Debug, Clone, Default, Serialize, Deserialize)]`);
@@ -587,7 +601,7 @@ pub struct DateTimeFilter {
587
601
 
588
602
  use an5_adapters::{
589
603
  AdapterMetadata, An5Adapter, CountArgs, DeleteManyArgs, FindManyArgs, RowMap, TableClient,
590
- UpdateArgs,
604
+ UpdateArgs, VectorSearchArgs,
591
605
  };
592
606
  use serde::de::DeserializeOwned;
593
607
 
@@ -808,6 +822,27 @@ impl SqlBuilder {
808
822
  lines.push(` deserialize_rows(rows)`);
809
823
  lines.push(` }`);
810
824
  lines.push(``);
825
+ lines.push(` /// The rows nearest \`vector\`, each carrying a \`distance\`.`);
826
+ lines.push(` pub async fn vector_search(&self, args: &${name}VectorSearchArgs) -> Result<Vec<(${name}, f64)>> {`);
827
+ lines.push(` let rows = self`);
828
+ lines.push(` .db`);
829
+ lines.push(` .table("${model.name}")`);
830
+ lines.push(` .vector_search(&VectorSearchArgs {`);
831
+ lines.push(` vector: args.vector.iter().map(|v| *v as f64).collect(),`);
832
+ lines.push(` take: args.take.unwrap_or(0),`);
833
+ lines.push(` r#where: to_value(&args.where_)?,`);
834
+ lines.push(` vector_field: args.vector_field.clone(),`);
835
+ lines.push(` distance_metric: args.distance_metric.clone(),`);
836
+ lines.push(` ..Default::default()`);
837
+ lines.push(` })`);
838
+ lines.push(` .await?;`);
839
+ lines.push(` rows.into_iter().map(|row| {`);
840
+ lines.push(` let distance = row.get("distance").and_then(serde_json::Value::as_f64)`);
841
+ lines.push(` .ok_or("vector search returned no distance")?;`);
842
+ lines.push(` Ok((deserialize_row(row)?, distance))`);
843
+ lines.push(` }).collect()`);
844
+ lines.push(` }`);
845
+ lines.push(``);
811
846
  lines.push(` pub async fn find_first(&self, args: &${name}FindFirstArgs) -> Result<Option<${name}>> {`);
812
847
  lines.push(` let row = self`);
813
848
  lines.push(` .db`);
@@ -0,0 +1,42 @@
1
+ import { Model } from './types';
2
+ export declare class SwiftGenerator {
3
+ private outputDir;
4
+ /** The database being generated for; decides types like `TIMESTAMP`. */
5
+ private provider;
6
+ constructor(outputDir: string);
7
+ generate(models: Model[]): void;
8
+ /**
9
+ * The SwiftPM manifest for the generated client.
10
+ *
11
+ * <p>SwiftPM has no "point a build at this folder" story the way a csproj or a go.mod
12
+ * does: a target's sources have to live under `Sources/<Target>/`. Emitting the manifest
13
+ * and that layout together is what makes the output a package an app can depend on,
14
+ * rather than a directory a consumer has to restructure by hand.
15
+ */
16
+ private generatePackageManifest;
17
+ /** Where SwiftPM expects a target's sources. */
18
+ private get sourceDir();
19
+ private capitalize;
20
+ /**
21
+ * The property name for a column.
22
+ *
23
+ * Backticked rather than renamed where possible: `default` and `class` are valid column
24
+ * names, and renaming them in the model but not in the SQL is a mismatch nobody notices.
25
+ */
26
+ private property;
27
+ private static toCamelCase;
28
+ private static toLowerCamelCase;
29
+ /** The Swift type for a column. */
30
+ private mapType;
31
+ private mapOptionalType;
32
+ /** How a column is read out of a row, as a Swift expression. */
33
+ private readExpression;
34
+ private filterType;
35
+ private generateModels;
36
+ private modelSource;
37
+ private generateOrmTypes;
38
+ private generateMetadata;
39
+ private generateConfig;
40
+ private generateClient;
41
+ private tableName;
42
+ }