@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.
- package/README.md +1 -1
- package/dist/generator/src/api.d.ts +3 -0
- package/dist/generator/src/api.js +7 -1
- package/dist/generator/src/code-generator.js +12 -1
- package/dist/generator/src/code-request.d.ts +2 -2
- package/dist/generator/src/code-request.js +24 -3
- package/dist/generator/src/config.d.ts +18 -0
- package/dist/generator/src/config.js +24 -0
- package/dist/generator/src/dialect.js +4 -2
- package/dist/generator/src/dotnet-generator.js +97 -1
- package/dist/generator/src/field-types.js +3 -0
- package/dist/generator/src/golang-generator.d.ts +8 -0
- package/dist/generator/src/golang-generator.js +183 -9
- package/dist/generator/src/index.js +18 -0
- package/dist/generator/src/java-generator.d.ts +56 -0
- package/dist/generator/src/java-generator.js +1408 -0
- package/dist/generator/src/kotlin-generator.d.ts +34 -0
- package/dist/generator/src/kotlin-generator.js +753 -0
- package/dist/generator/src/python-generator.js +4 -2
- package/dist/generator/src/rust-generator.js +36 -1
- package/dist/generator/src/swift-generator.d.ts +42 -0
- package/dist/generator/src/swift-generator.js +768 -0
- package/generator/src/api.ts +3 -0
- package/generator/src/code-generator.ts +13 -1
- package/generator/src/code-request.ts +17 -3
- package/generator/src/config.ts +48 -0
- package/generator/src/dialect.ts +5 -3
- package/generator/src/dotnet-generator.ts +97 -1
- package/generator/src/field-types.ts +3 -0
- package/generator/src/golang-generator.ts +184 -9
- package/generator/src/index.ts +21 -0
- package/generator/src/java-generator.ts +1459 -0
- package/generator/src/kotlin-generator.ts +798 -0
- package/generator/src/python-generator.ts +4 -2
- package/generator/src/rust-generator.ts +37 -1
- package/generator/src/swift-generator.ts +830 -0
- 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
|
|
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={"
|
|
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
|
+
}
|