@happyvertical/smrt-core 0.36.8 → 0.37.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/dist/child-accessors.d.ts +1 -1
- package/dist/child-accessors.d.ts.map +1 -1
- package/dist/child-accessors.js +1 -1
- package/dist/child-accessors.js.map +1 -1
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +3 -1
- package/dist/class.js.map +1 -1
- package/dist/collection-cache.d.ts.map +1 -1
- package/dist/collection-cache.js +5 -3
- package/dist/collection-cache.js.map +1 -1
- package/dist/collection.d.ts +39 -16
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +40 -19
- package/dist/collection.js.map +1 -1
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/decorators/compatibility.d.ts +1 -1
- package/dist/decorators/compatibility.d.ts.map +1 -1
- package/dist/decorators/compatibility.js.map +1 -1
- package/dist/decorators/index.d.ts +4 -4
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js.map +1 -1
- package/dist/hierarchical.d.ts.map +1 -1
- package/dist/hierarchical.js.map +1 -1
- package/dist/junction.d.ts.map +1 -1
- package/dist/junction.js.map +1 -1
- package/dist/manifest/discover-smrt-packages.d.ts +10 -0
- package/dist/manifest/discover-smrt-packages.d.ts.map +1 -1
- package/dist/manifest/discover-smrt-packages.js.map +1 -1
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +34 -37
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/index.js +2 -2
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/manifest-loader.d.ts +10 -0
- package/dist/manifest/manifest-loader.d.ts.map +1 -1
- package/dist/manifest/manifest-loader.js.map +1 -1
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +39 -20
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +2 -2
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest/test-manifest-stub.d.ts.map +1 -1
- package/dist/manifest/test-manifest-stub.js +2301 -629
- package/dist/manifest/test-manifest-stub.js.map +1 -1
- package/dist/manifest.json +39 -20
- package/dist/migrations/differ.d.ts +104 -13
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +199 -26
- package/dist/migrations/differ.js.map +1 -1
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/ast.js +1 -7
- package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/ast.js.map +1 -0
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/escape.js.map +1 -1
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/index.js +17 -14
- package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/index.js.map +1 -0
- package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/unescape.js +10 -0
- package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
- package/dist/object.d.ts +64 -17
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +76 -30
- package/dist/object.js.map +1 -1
- package/dist/registry/class-registration.d.ts +3 -3
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +39 -42
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/inheritance-resolver.d.ts +17 -3
- package/dist/registry/inheritance-resolver.d.ts.map +1 -1
- package/dist/registry/inheritance-resolver.js +1 -1
- package/dist/registry/inheritance-resolver.js.map +1 -1
- package/dist/registry/manifest-field-merge.d.ts +17 -3
- package/dist/registry/manifest-field-merge.d.ts.map +1 -1
- package/dist/registry/manifest-field-merge.js +8 -6
- package/dist/registry/manifest-field-merge.js.map +1 -1
- package/dist/registry/schema-builder.d.ts +1 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/shared-state.d.ts +3 -3
- package/dist/registry/shared-state.d.ts.map +1 -1
- package/dist/registry/shared-state.js.map +1 -1
- package/dist/registry/types.d.ts +78 -19
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/validator.d.ts +2 -1
- package/dist/registry/validator.d.ts.map +1 -1
- package/dist/registry/validator.js +38 -39
- package/dist/registry/validator.js.map +1 -1
- package/dist/registry.d.ts +84 -57
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +31 -25
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +22 -20
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/smrt-knowledge.json +8 -7
- package/dist/system-fields.d.ts +1 -1
- package/dist/system-fields.d.ts.map +1 -1
- package/dist/system-fields.js.map +1 -1
- package/dist/vite-plugin/index.js +1 -1
- package/package.json +7 -7
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js.map +0 -1
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js.map +0 -1
- package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js +0 -10
- /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/assert-valid-pattern.js +0 -0
- /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/brace-expressions.js +0 -0
- /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/escape.js +0 -0
package/dist/object.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AITool } from '@happyvertical/ai';
|
|
1
|
+
import { AITextCompletionOptions, AITool } from '@happyvertical/ai';
|
|
2
2
|
import { SmrtClassOptions, SmrtClass } from './class';
|
|
3
3
|
import { GenerateEmbeddingsOptions } from './embeddings/types';
|
|
4
4
|
import { ToolCall, ToolCallResult } from './tools/tool-executor';
|
|
@@ -42,7 +42,14 @@ export interface SmrtObjectOptions extends SmrtClassOptions {
|
|
|
42
42
|
*/
|
|
43
43
|
_skipAutoEmbeddings?: boolean;
|
|
44
44
|
/**
|
|
45
|
-
* Allow arbitrary field values to be passed
|
|
45
|
+
* Allow arbitrary field values to be passed.
|
|
46
|
+
*
|
|
47
|
+
* This index signature is intentionally `any` (not `unknown`): subclass
|
|
48
|
+
* option interfaces across every package (e.g. `FeatureDefinitionOptions`)
|
|
49
|
+
* are plain interfaces with no index signature, and TS does not consider
|
|
50
|
+
* such an interface assignable to `[key: string]: unknown` — only to
|
|
51
|
+
* `[key: string]: any`. Narrowing it would break `super(options)` in every
|
|
52
|
+
* downstream model. Documented irreducible leaf (S4 #1579).
|
|
46
53
|
*/
|
|
47
54
|
[key: string]: any;
|
|
48
55
|
}
|
|
@@ -63,6 +70,26 @@ export interface LoadRelatedOptions {
|
|
|
63
70
|
*/
|
|
64
71
|
allowCrossTenant?: boolean;
|
|
65
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Options accepted by the AI operations {@link SmrtObject.is},
|
|
75
|
+
* {@link SmrtObject.do}, and {@link SmrtObject.describe}.
|
|
76
|
+
*
|
|
77
|
+
* Extends the underlying AI client's {@link AITextCompletionOptions} (model,
|
|
78
|
+
* temperature, maxTokens, …) with two non-standard control keys that are
|
|
79
|
+
* consumed by these methods and NOT forwarded to `ai.message()`.
|
|
80
|
+
*/
|
|
81
|
+
export interface AiOperationOptions extends AITextCompletionOptions {
|
|
82
|
+
/**
|
|
83
|
+
* Set to `false` to omit the injected object "content body" — for callers
|
|
84
|
+
* that already curate the relevant fields into the instruction/criteria
|
|
85
|
+
* string. Any other value (including `undefined`) injects it.
|
|
86
|
+
*/
|
|
87
|
+
includeData?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Override the injected object-data truncation budget, in characters.
|
|
90
|
+
*/
|
|
91
|
+
maxDataLength?: number;
|
|
92
|
+
}
|
|
66
93
|
/**
|
|
67
94
|
* Base class for all persistent SMRT domain objects.
|
|
68
95
|
*
|
|
@@ -282,7 +309,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
282
309
|
* @param data - Database row data (with snake_case column names)
|
|
283
310
|
* @throws Error if STI validation fails
|
|
284
311
|
*/
|
|
285
|
-
loadDataFromDb(data:
|
|
312
|
+
loadDataFromDb(data: Record<string, unknown>): Promise<void>;
|
|
286
313
|
/**
|
|
287
314
|
* Gets the database table name for this object
|
|
288
315
|
*/
|
|
@@ -292,7 +319,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
292
319
|
*
|
|
293
320
|
* @returns Object containing field definitions with current values
|
|
294
321
|
*/
|
|
295
|
-
getFields(): Promise<
|
|
322
|
+
getFields(): Promise<any>;
|
|
296
323
|
/**
|
|
297
324
|
* Override hook for customizing JSON serialization output.
|
|
298
325
|
*
|
|
@@ -315,7 +342,9 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
315
342
|
* class Article extends SmrtObject {
|
|
316
343
|
* body: string = '';
|
|
317
344
|
*
|
|
318
|
-
* protected transformJSON(
|
|
345
|
+
* protected transformJSON(
|
|
346
|
+
* data: Record<string, unknown>,
|
|
347
|
+
* ): Record<string, unknown> {
|
|
319
348
|
* return {
|
|
320
349
|
* ...data,
|
|
321
350
|
* wordCount: this.body.split(/\s+/).length,
|
|
@@ -327,7 +356,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
327
356
|
*
|
|
328
357
|
* @see {@link toJSON} for the framework implementation (do not override)
|
|
329
358
|
*/
|
|
330
|
-
protected transformJSON(data:
|
|
359
|
+
protected transformJSON(data: Record<string, unknown>): Record<string, unknown>;
|
|
331
360
|
/**
|
|
332
361
|
* Custom JSON serialization
|
|
333
362
|
* Returns a plain object with all field values for proper JSON.stringify() behavior
|
|
@@ -345,7 +374,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
345
374
|
* **Customization:** Override `transformJSON()` instead of this method.
|
|
346
375
|
* See transformJSON() documentation for safe customization patterns.
|
|
347
376
|
*/
|
|
348
|
-
toJSON():
|
|
377
|
+
toJSON(): Record<string, unknown>;
|
|
349
378
|
/**
|
|
350
379
|
* Converts this object to a plain JavaScript object (POJO)
|
|
351
380
|
*
|
|
@@ -555,14 +584,14 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
555
584
|
/**
|
|
556
585
|
* Gets the value of a field on this object
|
|
557
586
|
*/
|
|
558
|
-
protected getFieldValue(fieldName: string):
|
|
587
|
+
protected getFieldValue(fieldName: string): unknown;
|
|
559
588
|
/**
|
|
560
589
|
* Gets the value of a property.
|
|
561
590
|
*
|
|
562
591
|
* @param key - Property name to get value from
|
|
563
592
|
* @returns The property value
|
|
564
593
|
*/
|
|
565
|
-
protected getPropertyValue(key: string):
|
|
594
|
+
protected getPropertyValue(key: string): unknown;
|
|
566
595
|
/**
|
|
567
596
|
* Classifies a raw database driver error message as a unique-constraint or
|
|
568
597
|
* not-null-constraint violation, across SQLite, PostgreSQL and DuckDB.
|
|
@@ -694,7 +723,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
694
723
|
*
|
|
695
724
|
* @see {@link do} for open-ended instructions instead of boolean checks
|
|
696
725
|
*/
|
|
697
|
-
is(criteria: string, options?:
|
|
726
|
+
is(criteria: string, options?: AiOperationOptions): Promise<any>;
|
|
698
727
|
/**
|
|
699
728
|
* Performs a freeform operation on this object using AI instructions.
|
|
700
729
|
*
|
|
@@ -727,7 +756,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
727
756
|
*
|
|
728
757
|
* @see {@link is} for boolean criteria checks
|
|
729
758
|
*/
|
|
730
|
-
do(instructions: string, options?:
|
|
759
|
+
do(instructions: string, options?: AiOperationOptions): Promise<string>;
|
|
731
760
|
/**
|
|
732
761
|
* Generates a description of this object using AI (Issue #52)
|
|
733
762
|
*
|
|
@@ -756,7 +785,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
756
785
|
* // "Premium widget, steel construction"
|
|
757
786
|
* ```
|
|
758
787
|
*/
|
|
759
|
-
describe(options?:
|
|
788
|
+
describe(options?: AiOperationOptions): Promise<string>;
|
|
760
789
|
/**
|
|
761
790
|
* Runs a lifecycle hook if it's defined in the object's configuration
|
|
762
791
|
*
|
|
@@ -823,6 +852,24 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
823
852
|
* ```
|
|
824
853
|
*/
|
|
825
854
|
isRelatedLoaded(fieldName: string): boolean;
|
|
855
|
+
/**
|
|
856
|
+
* Internal: seed the lazy-load relationship cache from an external batch
|
|
857
|
+
* loader.
|
|
858
|
+
*
|
|
859
|
+
* `SmrtCollection`'s eager `include:` and `getOrUpsert` paths resolve
|
|
860
|
+
* relationships in bulk and need to prime each instance's cache so a later
|
|
861
|
+
* {@link loadRelated}/{@link loadRelatedMany} call returns the already-fetched
|
|
862
|
+
* value instead of re-querying. This method is the sanctioned write path into
|
|
863
|
+
* the otherwise-private `_loadedRelationships` map, so collaborators never have
|
|
864
|
+
* to structurally cast into the private field (which the no-private-reach-ins
|
|
865
|
+
* convention forbids). The leading underscore keeps it out of the generated
|
|
866
|
+
* REST/CLI/MCP surface, like other framework-internal members.
|
|
867
|
+
*
|
|
868
|
+
* @param fieldName - Relationship field whose value is being cached
|
|
869
|
+
* @param value - The loaded relationship (a `SmrtObject`, an array of them, or
|
|
870
|
+
* `null`), stored verbatim
|
|
871
|
+
*/
|
|
872
|
+
_setLoadedRelationship(fieldName: string, value: unknown): void;
|
|
826
873
|
/**
|
|
827
874
|
* Lazy-loads a `foreignKey` or `crossPackageRef` relationship and caches the
|
|
828
875
|
* result.
|
|
@@ -917,7 +964,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
917
964
|
protected resolveManyToManyJoin(fieldName: string, relationship: {
|
|
918
965
|
sourceClass: string;
|
|
919
966
|
targetClass: string;
|
|
920
|
-
options?:
|
|
967
|
+
options?: Record<string, unknown>;
|
|
921
968
|
}): Promise<{
|
|
922
969
|
through: string;
|
|
923
970
|
sourceColumn: string;
|
|
@@ -1024,8 +1071,8 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
1024
1071
|
id?: string;
|
|
1025
1072
|
scope: string;
|
|
1026
1073
|
key: string;
|
|
1027
|
-
value:
|
|
1028
|
-
metadata?:
|
|
1074
|
+
value: unknown;
|
|
1075
|
+
metadata?: unknown;
|
|
1029
1076
|
confidence?: number;
|
|
1030
1077
|
version?: number;
|
|
1031
1078
|
expiresAt?: Date;
|
|
@@ -1066,7 +1113,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
1066
1113
|
key: string;
|
|
1067
1114
|
includeAncestors?: boolean;
|
|
1068
1115
|
minConfidence?: number;
|
|
1069
|
-
}): Promise<
|
|
1116
|
+
}): Promise<unknown>;
|
|
1070
1117
|
/**
|
|
1071
1118
|
* Retrieves all remembered context entries for this object in a scope.
|
|
1072
1119
|
*
|
|
@@ -1098,7 +1145,7 @@ export declare class SmrtObject extends SmrtClass {
|
|
|
1098
1145
|
scope?: string;
|
|
1099
1146
|
includeDescendants?: boolean;
|
|
1100
1147
|
minConfidence?: number;
|
|
1101
|
-
}): Promise<Map<string,
|
|
1148
|
+
}): Promise<Map<string, unknown>>;
|
|
1102
1149
|
/**
|
|
1103
1150
|
* Deletes a specific remembered context entry for this object.
|
|
1104
1151
|
*
|
package/dist/object.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"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"}
|
package/dist/object.js
CHANGED
|
@@ -289,12 +289,13 @@ class SmrtObject extends SmrtClass {
|
|
|
289
289
|
const options = this.options;
|
|
290
290
|
if (options.created_at !== void 0) this.created_at = options.created_at;
|
|
291
291
|
if (options.updated_at !== void 0) this.updated_at = options.updated_at;
|
|
292
|
-
if (options._meta_type
|
|
292
|
+
if (typeof options._meta_type === "string") {
|
|
293
293
|
this.setMetaType(options._meta_type);
|
|
294
294
|
}
|
|
295
295
|
const fields = await fieldsFromClass(
|
|
296
296
|
this.constructor
|
|
297
297
|
);
|
|
298
|
+
const writable = this;
|
|
298
299
|
for (const [key, field] of Object.entries(fields)) {
|
|
299
300
|
if (options[key] !== void 0) {
|
|
300
301
|
const clonedValue = this.cloneValue(options[key]);
|
|
@@ -307,7 +308,7 @@ class SmrtObject extends SmrtClass {
|
|
|
307
308
|
}
|
|
308
309
|
}
|
|
309
310
|
if (!descriptor || descriptor.set || descriptor.writable === true) {
|
|
310
|
-
|
|
311
|
+
writable[key] = clonedValue;
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
}
|
|
@@ -463,17 +464,18 @@ class SmrtObject extends SmrtClass {
|
|
|
463
464
|
});
|
|
464
465
|
}
|
|
465
466
|
if (isSTI) {
|
|
466
|
-
|
|
467
|
+
const metaType = formattedData._meta_type;
|
|
468
|
+
if (!metaType) {
|
|
467
469
|
throw new Error(
|
|
468
470
|
`STI validation failed: Missing _meta_type discriminator in database row for ${className}. Ensure the row was saved with STI support enabled.`
|
|
469
471
|
);
|
|
470
472
|
}
|
|
471
|
-
if (!isValidMetaType(
|
|
473
|
+
if (!isValidMetaType(metaType, className)) {
|
|
472
474
|
throw new Error(
|
|
473
|
-
`STI validation failed: Type mismatch when loading ${className}. Database row has _meta_type='${
|
|
475
|
+
`STI validation failed: Type mismatch when loading ${className}. Database row has _meta_type='${metaType}' but expected '${getExpectedMetaType(className)}'. This usually means you're trying to load a row with the wrong class.`
|
|
474
476
|
);
|
|
475
477
|
}
|
|
476
|
-
this.setMetaType(
|
|
478
|
+
this.setMetaType(metaType);
|
|
477
479
|
}
|
|
478
480
|
if (process.env.DEBUG_STI) {
|
|
479
481
|
logger.debug("[loadDataFromDb] Starting field hydration", {
|
|
@@ -483,6 +485,7 @@ class SmrtObject extends SmrtClass {
|
|
|
483
485
|
}
|
|
484
486
|
let hydratedCount = 0;
|
|
485
487
|
let skippedCount = 0;
|
|
488
|
+
const writable = this;
|
|
486
489
|
for (const field in fields) {
|
|
487
490
|
if (Object.hasOwn(fields, field)) {
|
|
488
491
|
let descriptor = Object.getOwnPropertyDescriptor(this, field);
|
|
@@ -501,7 +504,7 @@ class SmrtObject extends SmrtClass {
|
|
|
501
504
|
valueType: typeof value
|
|
502
505
|
});
|
|
503
506
|
}
|
|
504
|
-
|
|
507
|
+
writable[field] = value;
|
|
505
508
|
hydratedCount++;
|
|
506
509
|
} else {
|
|
507
510
|
skippedCount++;
|
|
@@ -555,6 +558,11 @@ class SmrtObject extends SmrtClass {
|
|
|
555
558
|
*
|
|
556
559
|
* @returns Object containing field definitions with current values
|
|
557
560
|
*/
|
|
561
|
+
// Explicit `any` return (documented S4 #1579 leaf): subclasses legitimately
|
|
562
|
+
// OVERRIDE getFields() with domain-specific shapes (e.g. projects'
|
|
563
|
+
// `Project.getFields(): Promise<ProjectField[]>`), which a precise field-map
|
|
564
|
+
// return type would reject. The body below stays internally typed.
|
|
565
|
+
// biome-ignore lint/suspicious/noExplicitAny: subclasses OVERRIDE getFields() with domain shapes (e.g. `Project.getFields(): Promise<ProjectField[]>`); a precise base return type would reject those overrides. S4 #1579.
|
|
558
566
|
async getFields() {
|
|
559
567
|
const className = this.getResolvedClassName();
|
|
560
568
|
const cachedFields = await ObjectRegistry.getAllFields(className);
|
|
@@ -595,7 +603,9 @@ class SmrtObject extends SmrtClass {
|
|
|
595
603
|
* class Article extends SmrtObject {
|
|
596
604
|
* body: string = '';
|
|
597
605
|
*
|
|
598
|
-
* protected transformJSON(
|
|
606
|
+
* protected transformJSON(
|
|
607
|
+
* data: Record<string, unknown>,
|
|
608
|
+
* ): Record<string, unknown> {
|
|
599
609
|
* return {
|
|
600
610
|
* ...data,
|
|
601
611
|
* wordCount: this.body.split(/\s+/).length,
|
|
@@ -636,13 +646,15 @@ class SmrtObject extends SmrtClass {
|
|
|
636
646
|
created_at: this.created_at,
|
|
637
647
|
updated_at: this.updated_at
|
|
638
648
|
};
|
|
649
|
+
const self = this;
|
|
639
650
|
const tableStrategy = ObjectRegistry.getTableStrategy(
|
|
640
651
|
this.getResolvedQualifiedName()
|
|
641
652
|
);
|
|
642
653
|
const isSTI = tableStrategy === "sti";
|
|
654
|
+
const metaData = {};
|
|
643
655
|
if (isSTI) {
|
|
644
656
|
data._meta_type = this.getResolvedQualifiedName();
|
|
645
|
-
data._meta_data =
|
|
657
|
+
data._meta_data = metaData;
|
|
646
658
|
}
|
|
647
659
|
const registered = ObjectRegistry.getClass(className);
|
|
648
660
|
let registeredFields = registered?.inheritedFields || ObjectRegistry.getFields(className);
|
|
@@ -665,7 +677,7 @@ class SmrtObject extends SmrtClass {
|
|
|
665
677
|
}
|
|
666
678
|
for (const key of registeredFields.keys()) {
|
|
667
679
|
if (key.startsWith("_") || key === "id" || key === "slug" || key === "context" || key === "created_at" || key === "updated_at" || key === "options" || // Skip options object (not a database column)
|
|
668
|
-
typeof
|
|
680
|
+
typeof self[key] === "function") {
|
|
669
681
|
continue;
|
|
670
682
|
}
|
|
671
683
|
const fieldDef = registeredFields.get(key);
|
|
@@ -675,21 +687,22 @@ class SmrtObject extends SmrtClass {
|
|
|
675
687
|
if (fieldDef && (fieldDef.type === "oneToMany" || fieldDef.type === "manyToMany")) {
|
|
676
688
|
continue;
|
|
677
689
|
}
|
|
678
|
-
const prop =
|
|
690
|
+
const prop = self[key];
|
|
679
691
|
const value = this.getPropertyValue(key);
|
|
680
692
|
if (value === void 0) {
|
|
681
693
|
const fieldType = prop && typeof prop === "object" && "type" in prop && prop.type || fieldDef?.type;
|
|
682
694
|
if (fieldType === "text") {
|
|
683
|
-
const
|
|
695
|
+
const propTenancy = prop && typeof prop === "object" && "__tenancy" in prop ? prop.__tenancy : void 0;
|
|
696
|
+
const hasTenancyMarker = propTenancy?.isTenantIdField || fieldDef?.__tenancy?.isTenantIdField || fieldDef?._meta?.__tenancy?.isTenantIdField;
|
|
684
697
|
if (hasTenancyMarker) {
|
|
685
698
|
if (isSTI && fieldDef?.type === "meta") {
|
|
686
|
-
|
|
699
|
+
metaData[key] = null;
|
|
687
700
|
} else {
|
|
688
701
|
data[key] = null;
|
|
689
702
|
}
|
|
690
703
|
} else {
|
|
691
704
|
if (isSTI && fieldDef?.type === "meta") {
|
|
692
|
-
|
|
705
|
+
metaData[key] = "";
|
|
693
706
|
} else {
|
|
694
707
|
data[key] = "";
|
|
695
708
|
}
|
|
@@ -697,7 +710,7 @@ class SmrtObject extends SmrtClass {
|
|
|
697
710
|
} else if (fieldType === "json") {
|
|
698
711
|
const defaultValue = fieldDef?.default ?? null;
|
|
699
712
|
if (isSTI && fieldDef?.type === "meta") {
|
|
700
|
-
|
|
713
|
+
metaData[key] = defaultValue;
|
|
701
714
|
} else {
|
|
702
715
|
data[key] = defaultValue;
|
|
703
716
|
}
|
|
@@ -705,7 +718,7 @@ class SmrtObject extends SmrtClass {
|
|
|
705
718
|
continue;
|
|
706
719
|
}
|
|
707
720
|
if (isSTI && fieldDef && fieldDef.type === "meta") {
|
|
708
|
-
|
|
721
|
+
metaData[key] = value;
|
|
709
722
|
} else {
|
|
710
723
|
data[key] = value;
|
|
711
724
|
}
|
|
@@ -899,13 +912,14 @@ class SmrtObject extends SmrtClass {
|
|
|
899
912
|
*/
|
|
900
913
|
async getSlug() {
|
|
901
914
|
if (!this.slug) {
|
|
915
|
+
const self = this;
|
|
902
916
|
let sourceField = null;
|
|
903
|
-
if (
|
|
904
|
-
sourceField = String(
|
|
905
|
-
} else if (
|
|
906
|
-
sourceField = String(
|
|
907
|
-
} else if (
|
|
908
|
-
sourceField = String(
|
|
917
|
+
if (self.name) {
|
|
918
|
+
sourceField = String(self.name);
|
|
919
|
+
} else if (self.title) {
|
|
920
|
+
sourceField = String(self.title);
|
|
921
|
+
} else if (self.label) {
|
|
922
|
+
sourceField = String(self.label);
|
|
909
923
|
} else if (this.id) {
|
|
910
924
|
sourceField = String(this.id);
|
|
911
925
|
}
|
|
@@ -1263,9 +1277,12 @@ See issue #377: https://github.com/happyvertical/smrt/issues/377`
|
|
|
1263
1277
|
}
|
|
1264
1278
|
return;
|
|
1265
1279
|
}
|
|
1266
|
-
const fields = await fieldsFromClass(
|
|
1280
|
+
const fields = await fieldsFromClass(
|
|
1281
|
+
this.constructor
|
|
1282
|
+
);
|
|
1267
1283
|
for (const [fieldName, field] of Object.entries(fields)) {
|
|
1268
|
-
|
|
1284
|
+
const options = field?.options;
|
|
1285
|
+
if (options?.required) {
|
|
1269
1286
|
const value = this.getFieldValue(fieldName);
|
|
1270
1287
|
if (value === null || value === void 0 || value === "") {
|
|
1271
1288
|
throw ValidationError.requiredField(fieldName, className);
|
|
@@ -1822,6 +1839,26 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
1822
1839
|
isRelatedLoaded(fieldName) {
|
|
1823
1840
|
return this._loadedRelationships.has(fieldName);
|
|
1824
1841
|
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Internal: seed the lazy-load relationship cache from an external batch
|
|
1844
|
+
* loader.
|
|
1845
|
+
*
|
|
1846
|
+
* `SmrtCollection`'s eager `include:` and `getOrUpsert` paths resolve
|
|
1847
|
+
* relationships in bulk and need to prime each instance's cache so a later
|
|
1848
|
+
* {@link loadRelated}/{@link loadRelatedMany} call returns the already-fetched
|
|
1849
|
+
* value instead of re-querying. This method is the sanctioned write path into
|
|
1850
|
+
* the otherwise-private `_loadedRelationships` map, so collaborators never have
|
|
1851
|
+
* to structurally cast into the private field (which the no-private-reach-ins
|
|
1852
|
+
* convention forbids). The leading underscore keeps it out of the generated
|
|
1853
|
+
* REST/CLI/MCP surface, like other framework-internal members.
|
|
1854
|
+
*
|
|
1855
|
+
* @param fieldName - Relationship field whose value is being cached
|
|
1856
|
+
* @param value - The loaded relationship (a `SmrtObject`, an array of them, or
|
|
1857
|
+
* `null`), stored verbatim
|
|
1858
|
+
*/
|
|
1859
|
+
_setLoadedRelationship(fieldName, value) {
|
|
1860
|
+
this._loadedRelationships.set(fieldName, value);
|
|
1861
|
+
}
|
|
1825
1862
|
/**
|
|
1826
1863
|
* Lazy-loads a `foreignKey` or `crossPackageRef` relationship and caches the
|
|
1827
1864
|
* result.
|
|
@@ -1859,6 +1896,10 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
1859
1896
|
*
|
|
1860
1897
|
* @see {@link getRelated} for a convenience wrapper that auto-detects relationship type
|
|
1861
1898
|
*/
|
|
1899
|
+
// Returns a polymorphic related object whose concrete subclass type only the
|
|
1900
|
+
// CALLER knows (e.g. `metafield.validateValue(...)`). Typed `any` so callers
|
|
1901
|
+
// can use the concrete API without a cast at every site; a generic with a
|
|
1902
|
+
// `SmrtObject` default wouldn't help untyped callers. Documented S4 #1579 leaf.
|
|
1862
1903
|
async loadRelated(fieldName, opts) {
|
|
1863
1904
|
if (this._loadedRelationships.has(fieldName)) {
|
|
1864
1905
|
const cached = this._loadedRelationships.get(fieldName);
|
|
@@ -1995,6 +2036,8 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
1995
2036
|
* console.log(`${orders.length} orders found`);
|
|
1996
2037
|
* ```
|
|
1997
2038
|
*/
|
|
2039
|
+
// Polymorphic related objects; concrete type is caller-known (see loadRelated).
|
|
2040
|
+
// Documented S4 #1579 leaf.
|
|
1998
2041
|
async loadRelatedMany(fieldName, opts) {
|
|
1999
2042
|
if (this._loadedRelationships.has(fieldName)) {
|
|
2000
2043
|
const cached = this._loadedRelationships.get(fieldName);
|
|
@@ -2104,7 +2147,8 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
2104
2147
|
fieldName
|
|
2105
2148
|
);
|
|
2106
2149
|
const opts = relationship.options || {};
|
|
2107
|
-
const
|
|
2150
|
+
const optsMeta = opts._meta && typeof opts._meta === "object" ? opts._meta : void 0;
|
|
2151
|
+
const through = decorator?.through ?? opts.through ?? optsMeta?.through;
|
|
2108
2152
|
if (!through) {
|
|
2109
2153
|
throw RuntimeError.invalidState(
|
|
2110
2154
|
`manyToMany field ${fieldName} on ${relationship.sourceClass} is missing the 'through' join table name`,
|
|
@@ -2113,12 +2157,12 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
2113
2157
|
}
|
|
2114
2158
|
const targetSimpleName = relationship.targetClass.includes(":") ? relationship.targetClass.split(":").pop() : relationship.targetClass;
|
|
2115
2159
|
const sourceSimpleName = relationship.sourceClass.includes(":") ? relationship.sourceClass.split(":").pop() : relationship.sourceClass;
|
|
2116
|
-
const sourceColumn = decorator?.sourceKey ?? opts.sourceKey ??
|
|
2117
|
-
const targetColumn = decorator?.targetKey ?? opts.targetKey ??
|
|
2160
|
+
const sourceColumn = decorator?.sourceKey ?? opts.sourceKey ?? optsMeta?.sourceKey ?? `${toSnakeCase(sourceSimpleName)}_id`;
|
|
2161
|
+
const targetColumn = decorator?.targetKey ?? opts.targetKey ?? optsMeta?.targetKey ?? `${toSnakeCase(targetSimpleName)}_id`;
|
|
2118
2162
|
return {
|
|
2119
2163
|
through: String(through),
|
|
2120
|
-
sourceColumn,
|
|
2121
|
-
targetColumn,
|
|
2164
|
+
sourceColumn: String(sourceColumn),
|
|
2165
|
+
targetColumn: String(targetColumn),
|
|
2122
2166
|
targetClassName: relationship.targetClass
|
|
2123
2167
|
};
|
|
2124
2168
|
}
|
|
@@ -2145,6 +2189,8 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
2145
2189
|
* const orders = await customer.getRelated('orders');
|
|
2146
2190
|
* ```
|
|
2147
2191
|
*/
|
|
2192
|
+
// Polymorphic related object(s); concrete type is caller-known (see
|
|
2193
|
+
// loadRelated). Documented S4 #1579 leaf.
|
|
2148
2194
|
async getRelated(fieldName, opts) {
|
|
2149
2195
|
if (this._loadedRelationships.has(fieldName)) {
|
|
2150
2196
|
const cached = this._loadedRelationships.get(fieldName);
|
|
@@ -2337,7 +2383,7 @@ Based on the content body, please follow the instructions and provide a response
|
|
|
2337
2383
|
}
|
|
2338
2384
|
if (result) {
|
|
2339
2385
|
try {
|
|
2340
|
-
return JSON.parse(result.value);
|
|
2386
|
+
return JSON.parse(String(result.value));
|
|
2341
2387
|
} catch (error) {
|
|
2342
2388
|
logger.warn("Skipping corrupted _smrt_contexts value in recall()", {
|
|
2343
2389
|
ownerClass: this._className,
|