@happyvertical/smrt-core 0.49.3 → 0.49.4
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 +4 -0
- package/agents/change-feed.md +19 -0
- package/agents/collection-reads.md +21 -0
- package/agents/generators.md +5 -0
- package/agents/memory.md +23 -3
- package/agents/null-equal-indexes.md +88 -0
- package/agents/object-runtime.md +85 -0
- package/agents/schema-paths.md +7 -7
- package/dist/browser.js +2 -2
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +13 -10
- package/dist/cascade.js.map +1 -1
- package/dist/change-feed.d.ts +22 -0
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +147 -6
- package/dist/change-feed.js.map +1 -1
- package/dist/class.js +1 -1
- package/dist/collection-cache.d.ts +10 -1
- package/dist/collection-cache.d.ts.map +1 -1
- package/dist/collection-cache.js +65 -10
- package/dist/collection-cache.js.map +1 -1
- package/dist/collection.d.ts +69 -2
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +142 -9
- package/dist/collection.js.map +1 -1
- package/dist/consumer-plugin/artifact-publication.d.ts +27 -0
- package/dist/consumer-plugin/artifact-publication.d.ts.map +1 -0
- package/dist/consumer-plugin/artifact-publication.js +80 -0
- package/dist/consumer-plugin/artifact-publication.js.map +1 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +37 -4
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/db-errors.js +1 -1
- package/dist/db-errors.js.map +1 -1
- package/dist/embedded-write-queue.d.ts +1 -1
- package/dist/embedded-write-queue.d.ts.map +1 -1
- package/dist/embedded-write-queue.js +16 -6
- package/dist/embedded-write-queue.js.map +1 -1
- package/dist/embeddings/storage.d.ts +16 -0
- package/dist/embeddings/storage.d.ts.map +1 -1
- package/dist/embeddings/storage.js +40 -0
- package/dist/embeddings/storage.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/interceptors.d.ts +22 -0
- package/dist/interceptors.d.ts.map +1 -1
- package/dist/interceptors.js +12 -0
- package/dist/interceptors.js.map +1 -1
- package/dist/junction.d.ts +12 -3
- package/dist/junction.d.ts.map +1 -1
- package/dist/junction.js +34 -4
- package/dist/junction.js.map +1 -1
- package/dist/knowledge-config.d.ts +6 -0
- package/dist/knowledge-config.d.ts.map +1 -0
- package/dist/knowledge-config.js +48 -0
- package/dist/knowledge-config.js.map +1 -0
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +91 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest.json +104 -1
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +2 -0
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/generator.d.ts.map +1 -1
- package/dist/migrations/generator.js +2 -0
- package/dist/migrations/generator.js.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +2 -1
- package/dist/migrations/null-equal-indexes.d.ts +37 -0
- package/dist/migrations/null-equal-indexes.d.ts.map +1 -0
- package/dist/migrations/null-equal-indexes.js +133 -0
- package/dist/migrations/null-equal-indexes.js.map +1 -0
- package/dist/migrations/tracker.d.ts.map +1 -1
- package/dist/migrations/tracker.js +6 -0
- package/dist/migrations/tracker.js.map +1 -1
- package/dist/migrations.js +2 -1
- package/dist/object.d.ts +33 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +316 -46
- package/dist/object.js.map +1 -1
- package/dist/plain-json.d.ts +6 -0
- package/dist/plain-json.d.ts.map +1 -0
- package/dist/plain-json.js +41 -0
- package/dist/plain-json.js.map +1 -0
- package/dist/postgres-permissions.d.ts.map +1 -1
- package/dist/postgres-permissions.js +6 -2
- package/dist/postgres-permissions.js.map +1 -1
- package/dist/prebuild/index.d.ts.map +1 -1
- package/dist/prebuild/index.js +3 -3
- package/dist/prebuild/index.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +4 -1
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +4 -3
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/validator.d.ts +1 -0
- package/dist/registry/validator.d.ts.map +1 -1
- package/dist/registry/validator.js +8 -1
- package/dist/registry/validator.js.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +21 -0
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/scanner/types.d.ts +2 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/schema/conflict-target.d.ts +8 -2
- package/dist/schema/conflict-target.d.ts.map +1 -1
- package/dist/schema/conflict-target.js +11 -3
- package/dist/schema/conflict-target.js.map +1 -1
- package/dist/schema/ddl/null-equal-index.d.ts +5 -0
- package/dist/schema/ddl/null-equal-index.d.ts.map +1 -0
- package/dist/schema/ddl/null-equal-index.js +17 -0
- package/dist/schema/ddl/null-equal-index.js.map +1 -0
- package/dist/schema/ddl/postgres-strategy.d.ts +2 -1
- package/dist/schema/ddl/postgres-strategy.d.ts.map +1 -1
- package/dist/schema/ddl/postgres-strategy.js +7 -0
- package/dist/schema/ddl/postgres-strategy.js.map +1 -1
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +8 -3
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/manifest-schema.d.ts +2 -1
- package/dist/schema/manifest-schema.d.ts.map +1 -1
- package/dist/schema/manifest-schema.js +12 -4
- package/dist/schema/manifest-schema.js.map +1 -1
- package/dist/schema/schema-manager.d.ts.map +1 -1
- package/dist/schema/schema-manager.js +1 -1
- package/dist/schema/schema-manager.js.map +1 -1
- package/dist/schema/types.d.ts +2 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/scripts/browser-plain-json-regression.mjs +85 -0
- package/dist/smrt-knowledge.json +73 -15
- package/dist/system/schema.d.ts +14 -3
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +120 -2
- package/dist/system/schema.js.map +1 -1
- package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
- package/dist/vite-plugin/api-client-entries.js +9 -7
- package/dist/vite-plugin/api-client-entries.js.map +1 -1
- package/dist/vite-plugin/index.d.ts +24 -0
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +47 -64
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +2 -2
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/web-collections.d.ts +10 -0
- package/dist/vite-plugin/web-collections.d.ts.map +1 -1
- package/dist/vite-plugin/web-collections.js +14 -2
- package/dist/vite-plugin/web-collections.js.map +1 -1
- package/package.json +5 -4
package/dist/junction.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"junction.d.ts","sourceRoot":"","sources":["../src/junction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,cAAc,EAAwB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"junction.d.ts","sourceRoot":"","sources":["../src/junction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,cAAc,EAAwB,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,8BAAsB,YAAY,CAChC,KAAK,SAAS,UAAU,CACxB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC7B;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAG,IAAI,CAAU;IAEhD,iFAAiF;IACjF,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAErC,gFAAgF;IAChF,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAEtC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAe;IAEjD;;;;;;;;;OASG;IACH,SAAS,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAe;IAErD;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,KAAK,EAAE,CAAC;IAenB;;;OAGG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,KAAK,EAAE,CAAC;IAYnB;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,KAAK,CAAC;IAWjB;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,IAAI,CAAC;IAkBhB;;;;;;;;;;;;;OAaG;IACG,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,IAAI,CAAC;CAuDjB"}
|
package/dist/junction.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GlobalInterceptors } from "./interceptors.js";
|
|
2
|
+
import { SmrtObject } from "./object.js";
|
|
1
3
|
import { SmrtCollection } from "./collection.js";
|
|
2
4
|
//#region src/junction.ts
|
|
3
5
|
/**
|
|
@@ -27,7 +29,7 @@ import { SmrtCollection } from "./collection.js";
|
|
|
27
29
|
function camelToSnake(name) {
|
|
28
30
|
return name.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
|
|
29
31
|
}
|
|
30
|
-
var SmrtJunction = class extends SmrtCollection {
|
|
32
|
+
var SmrtJunction = class SmrtJunction extends SmrtCollection {
|
|
31
33
|
/**
|
|
32
34
|
* Internal marker used by `SmrtCollection.create` to detect that this
|
|
33
35
|
* subclass is a junction and apply a registration-presence guard. Static
|
|
@@ -63,11 +65,14 @@ var SmrtJunction = class extends SmrtCollection {
|
|
|
63
65
|
* optional additional WHERE filters. Ordered ASC by `sortField` if set.
|
|
64
66
|
*/
|
|
65
67
|
async byLeft(leftId, opts = {}) {
|
|
68
|
+
const { limit, offset, ...where } = opts;
|
|
66
69
|
return await this.list({
|
|
67
70
|
where: {
|
|
68
|
-
...
|
|
71
|
+
...where,
|
|
69
72
|
[this.leftField]: leftId
|
|
70
73
|
},
|
|
74
|
+
limit,
|
|
75
|
+
offset,
|
|
71
76
|
...this.sortField ? { orderBy: `${camelToSnake(this.sortField)} ASC` } : {}
|
|
72
77
|
});
|
|
73
78
|
}
|
|
@@ -76,11 +81,14 @@ var SmrtJunction = class extends SmrtCollection {
|
|
|
76
81
|
* optional additional WHERE filters. Ordered ASC by `sortField` if set.
|
|
77
82
|
*/
|
|
78
83
|
async byRight(rightId, opts = {}) {
|
|
84
|
+
const { limit, offset, ...where } = opts;
|
|
79
85
|
return await this.list({
|
|
80
86
|
where: {
|
|
81
|
-
...
|
|
87
|
+
...where,
|
|
82
88
|
[this.rightField]: rightId
|
|
83
89
|
},
|
|
90
|
+
limit,
|
|
91
|
+
offset,
|
|
84
92
|
...this.sortField ? { orderBy: `${camelToSnake(this.sortField)} ASC` } : {}
|
|
85
93
|
});
|
|
86
94
|
}
|
|
@@ -114,11 +122,15 @@ var SmrtJunction = class extends SmrtCollection {
|
|
|
114
122
|
* @param opts - Additional WHERE filters (e.g. `{ relationship: 'thumbnail' }`)
|
|
115
123
|
*/
|
|
116
124
|
async detach(leftId, rightId, opts = {}) {
|
|
125
|
+
const filters = { ...opts };
|
|
126
|
+
delete filters.limit;
|
|
127
|
+
delete filters.offset;
|
|
117
128
|
const links = await this.list({ where: {
|
|
118
|
-
...
|
|
129
|
+
...filters,
|
|
119
130
|
[this.leftField]: leftId,
|
|
120
131
|
[this.rightField]: rightId
|
|
121
132
|
} });
|
|
133
|
+
if (await SmrtObject.tryJunctionBatch(links, [])) return;
|
|
122
134
|
for (const link of links) await link.delete();
|
|
123
135
|
}
|
|
124
136
|
/**
|
|
@@ -129,6 +141,9 @@ var SmrtJunction = class extends SmrtCollection {
|
|
|
129
141
|
* 2. Creates a new row for each `rightId`, spreading `opts` into the row data.
|
|
130
142
|
* 3. If `positionField` is set and `opts` doesn't specify it, assigns the array index.
|
|
131
143
|
*
|
|
144
|
+
* Compatible models use grouped persistence while preserving delete/create
|
|
145
|
+
* identity and feed semantics. Unsupported hooks, overrides, shapes, or batch
|
|
146
|
+
* bounds retain the sequential path; see agents/object-runtime.md.
|
|
132
147
|
* Not transactional — partial failure leaves the table in a mixed state.
|
|
133
148
|
* For atomic replaces, wrap the call in your own DB transaction.
|
|
134
149
|
*/
|
|
@@ -139,6 +154,21 @@ var SmrtJunction = class extends SmrtCollection {
|
|
|
139
154
|
...snapshotOpts,
|
|
140
155
|
[this.leftField]: leftId
|
|
141
156
|
} });
|
|
157
|
+
if (SmrtObject.hasBaseJunctionLifecycle(this._itemClass.prototype) && GlobalInterceptors.supportsBulkMutation(this.getResolvedItemClassName()) && new Set(rightIds).size === rightIds.length && this.attach === SmrtJunction.prototype.attach && SmrtCollection.hasBaseCreateLifecycle(this) && rightIds.length + existing.length <= 100 && !Object.keys(opts).some((key) => key.startsWith("_") || [
|
|
158
|
+
"db",
|
|
159
|
+
"ai",
|
|
160
|
+
"id",
|
|
161
|
+
"slug"
|
|
162
|
+
].includes(key))) {
|
|
163
|
+
const added = [];
|
|
164
|
+
for (let i = 0; i < rightIds.length; i++) added.push(await this.createUnsaved({
|
|
165
|
+
...opts,
|
|
166
|
+
...this.positionField && opts[this.positionField] === void 0 ? { [this.positionField]: i } : {},
|
|
167
|
+
[this.leftField]: leftId,
|
|
168
|
+
[this.rightField]: rightIds[i]
|
|
169
|
+
}));
|
|
170
|
+
if (await SmrtObject.tryJunctionBatch(existing, added)) return;
|
|
171
|
+
}
|
|
142
172
|
for (const link of existing) await link.delete();
|
|
143
173
|
const positionKey = this.positionField;
|
|
144
174
|
for (let i = 0; i < rightIds.length; i++) {
|
package/dist/junction.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"junction.js","names":[],"sources":["../src/junction.ts"],"sourcesContent":["/**\n * SmrtJunction — base class for two-sided junction (many-to-many) collections.\n *\n * A junction collection manages rows that link a \"left\" entity to a \"right\" entity,\n * typically with discriminator fields (relationship/role) and an optional sortOrder.\n * Examples in the monorepo:\n *\n * | Subclass | Left field | Right field | Discriminator |\n * |--------------------------------|---------------|-------------|-----------------|\n * | ContentAssetCollection | contentId | assetId | relationship |\n * | PerformerOwnedAssetCollection | performerId | assetId | role |\n * | PlaceAssetCollection | placeId | assetId | relationship |\n * | EventParticipantCollection | eventId | profileId | role |\n * | FactContentCollection | factId | contentId | relationship |\n *\n * Each subclass declares `leftField` / `rightField` (camelCase) and optionally\n * overrides `sortField` (defaults to `'sortOrder'`; set `null` to disable ORDER BY).\n *\n * Polymorphic subclasses (where \"left\" or \"right\" is a composite key like\n * `metaType + metaId`) may override `byLeft` / `byRight` / `attach` / `detach`\n * with diverging signatures — see `AssetAssociationCollection` for a reference.\n *\n * @typeParam TItem - The junction row class (extends `SmrtObject`)\n */\n\nimport { SmrtCollection, type SmrtCreateInput } from './collection';\nimport type { SmrtObject } from './object';\n\n/**\n * Options passed to `attach` / `setLinks` — written into the created junction row.\n *\n * Common keys: `relationship`, `role`, `sortOrder`, `tenantId`.\n * Subclass-specific keys (e.g. `placement`, `groupId` on EventParticipant) pass through.\n * Keys must match actual camelCase column names on the junction model; unknown\n * keys are rejected by `SmrtCollection.create`'s WHERE/field validation.\n */\nexport type JunctionAttachOptions = Record<string, unknown>;\n\n/**\n * Options passed to `byLeft` / `byRight` / `detach` — additional WHERE filters\n * narrowing the operation. Keys must match camelCase column names.\n */\nexport type JunctionFilterOptions = Record<string, unknown>;\n\nfunction camelToSnake(name: string): string {\n return name.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);\n}\n\nexport abstract class SmrtJunction<\n TItem extends SmrtObject,\n> extends SmrtCollection<TItem> {\n /**\n * Internal marker used by `SmrtCollection.create` to detect that this\n * subclass is a junction and apply a registration-presence guard. Static\n * property is inherited by all subclasses via the constructor chain.\n * Don't rename or remove without also updating the guard.\n */\n static readonly _isJunctionBase = true as const;\n\n /** Field name (camelCase) holding the \"left\" foreign key, e.g. `'contentId'`. */\n protected abstract leftField: string;\n\n /** Field name (camelCase) holding the \"right\" foreign key, e.g. `'assetId'`. */\n protected abstract rightField: string;\n\n /**\n * Field name (camelCase) used to ORDER BY when calling `byLeft` / `byRight`.\n * Defaults to `'sortOrder'`. Set to `null` to omit ORDER BY entirely.\n *\n * Independent from `positionField` — `sortField` is a *query* concern\n * (how rows are ordered when read), while `positionField` is a *write*\n * concern (what column `setLinks` auto-assigns to). Tables that order\n * by a non-position field (e.g. `'createdAt'`) should set `sortField`\n * accordingly and leave `positionField` set to `null` or its dedicated\n * position column name.\n */\n protected sortField: string | null = 'sortOrder';\n\n /**\n * Field name (camelCase) that `setLinks` auto-assigns the array index\n * to when the caller doesn't supply a value. Defaults to `'sortOrder'`.\n * Set to `null` for tables without a dedicated position column (e.g.\n * pure-key junctions, or tables ordered by timestamps).\n *\n * Writing the array index into a non-position field — like `createdAt`\n * or `placement` — would corrupt data. Subclasses without a numeric\n * position column MUST set this to `null`.\n */\n protected positionField: string | null = 'sortOrder';\n\n /**\n * Return junction rows where the left FK matches `leftId`, narrowed by\n * optional additional WHERE filters. Ordered ASC by `sortField` if set.\n */\n async byLeft(\n leftId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<TItem[]> {\n return (await this.list({\n // Spread opts FIRST so the fixed key always wins — prevents a\n // caller-supplied `{ [leftField]: otherId }` from retargeting the\n // query when opts is forwarded from untrusted input.\n where: { ...opts, [this.leftField]: leftId },\n ...(this.sortField\n ? { orderBy: `${camelToSnake(this.sortField)} ASC` }\n : {}),\n })) as TItem[];\n }\n\n /**\n * Return junction rows where the right FK matches `rightId`, narrowed by\n * optional additional WHERE filters. Ordered ASC by `sortField` if set.\n */\n async byRight(\n rightId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<TItem[]> {\n return (await this.list({\n where: { ...opts, [this.rightField]: rightId },\n ...(this.sortField\n ? { orderBy: `${camelToSnake(this.sortField)} ASC` }\n : {}),\n })) as TItem[];\n }\n\n /**\n * Create a new junction row linking `leftId` ↔ `rightId`.\n *\n * Goes through `SmrtCollection.create` which performs an upsert keyed on\n * the model's `@smrt({ conflictColumns })`. Duplicates on the conflict key\n * resolve to an UPDATE that rewrites every column — including the row's\n * `id` and any timestamp columns — to the new instance's values. For most\n * junctions that's fine: callers identify rows by (left, right, discriminator),\n * not by junction-row-id, so id rewrites are invisible.\n *\n * If your junction table is externally addressable by id (e.g. its rows\n * are exposed under `/api/v1/<table>/[id]`), override this method with a\n * find-or-create check to preserve id stability across duplicate calls.\n * See `ContentReferences.attach` for an example.\n *\n * @param opts - Extra fields to write into the row (e.g. `{ relationship, sortOrder, tenantId }`)\n */\n async attach(\n leftId: string,\n rightId: string,\n opts: JunctionAttachOptions = {},\n ): Promise<TItem> {\n return (await this.create({\n // Spread opts FIRST so the fixed key fields always win — prevents\n // a caller-supplied `{ [leftField]: otherId }` from retargeting\n // the write when opts is forwarded from untrusted input.\n ...opts,\n [this.leftField]: leftId,\n [this.rightField]: rightId,\n } as SmrtCreateInput<TItem>)) as TItem;\n }\n\n /**\n * Delete all junction rows matching `leftId` + `rightId` (+ optional filter `opts`).\n *\n * @param opts - Additional WHERE filters (e.g. `{ relationship: 'thumbnail' }`)\n */\n async detach(\n leftId: string,\n rightId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<void> {\n const links = (await this.list({\n where: {\n ...opts,\n [this.leftField]: leftId,\n [this.rightField]: rightId,\n },\n })) as TItem[];\n for (const link of links) {\n await (link as unknown as { delete(): Promise<void> }).delete();\n }\n }\n\n /**\n * Replace the full set of right-side rows for a `leftId`, scoped by `opts`.\n *\n * Behavior:\n * 1. Snapshots and deletes existing rows matching `{ leftField: leftId, ...opts }`.\n * 2. Creates a new row for each `rightId`, spreading `opts` into the row data.\n * 3. If `positionField` is set and `opts` doesn't specify it, assigns the array index.\n *\n * Not transactional — partial failure leaves the table in a mixed state.\n * For atomic replaces, wrap the call in your own DB transaction.\n */\n async setLinks(\n leftId: string,\n rightIds: string[],\n opts: JunctionAttachOptions = {},\n ): Promise<void> {\n // Strip the right-side key from snapshot opts — leaving it in would\n // narrow the delete to one specific right id, but `setLinks` is\n // contractually \"replace the full set of right rows for leftId\n // within the opts scope\". A rightField filter contradicts that.\n const snapshotOpts: JunctionAttachOptions = { ...opts };\n delete snapshotOpts[this.rightField];\n\n const existing = (await this.list({\n where: { ...snapshotOpts, [this.leftField]: leftId },\n })) as TItem[];\n for (const link of existing) {\n await (link as unknown as { delete(): Promise<void> }).delete();\n }\n\n const positionKey = this.positionField;\n for (let i = 0; i < rightIds.length; i++) {\n const rowOpts: JunctionAttachOptions = { ...opts };\n if (positionKey && rowOpts[positionKey] === undefined) {\n rowOpts[positionKey] = i;\n }\n await this.attach(leftId, rightIds[i], rowOpts);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAS,aAAa,MAAsB;CAC1C,OAAO,KAAK,QAAQ,WAAW,MAAM,IAAI,EAAE,YAAY,GAAG;AAC5D;AAEA,IAAsB,eAAtB,cAEU,eAAsB;;;;;;;CAO9B,OAAgB,kBAAkB;;;;;;;;;;;;CAmBlC,YAAqC;;;;;;;;;;;CAYrC,gBAAyC;;;;;CAMzC,MAAM,OACJ,QACA,OAA8B,CAAC,GACb;EAClB,OAAQ,MAAM,KAAK,KAAK;GAItB,OAAO;IAAE,GAAG;KAAO,KAAK,YAAY;GAAO;GAC3C,GAAI,KAAK,YACL,EAAE,SAAS,GAAG,aAAa,KAAK,SAAS,EAAE,MAAM,IACjD,CAAC;EACP,CAAC;CACH;;;;;CAMA,MAAM,QACJ,SACA,OAA8B,CAAC,GACb;EAClB,OAAQ,MAAM,KAAK,KAAK;GACtB,OAAO;IAAE,GAAG;KAAO,KAAK,aAAa;GAAQ;GAC7C,GAAI,KAAK,YACL,EAAE,SAAS,GAAG,aAAa,KAAK,SAAS,EAAE,MAAM,IACjD,CAAC;EACP,CAAC;CACH;;;;;;;;;;;;;;;;;;CAmBA,MAAM,OACJ,QACA,SACA,OAA8B,CAAC,GACf;EAChB,OAAQ,MAAM,KAAK,OAAO;GAIxB,GAAG;IACF,KAAK,YAAY;IACjB,KAAK,aAAa;EACrB,CAA2B;CAC7B;;;;;;CAOA,MAAM,OACJ,QACA,SACA,OAA8B,CAAC,GAChB;EACf,MAAM,QAAS,MAAM,KAAK,KAAK,EAC7B,OAAO;GACL,GAAG;IACF,KAAK,YAAY;IACjB,KAAK,aAAa;EACrB,EACF,CAAC;EACD,KAAK,MAAM,QAAQ,OACjB,MAAO,KAAgD,OAAO;CAElE;;;;;;;;;;;;CAaA,MAAM,SACJ,QACA,UACA,OAA8B,CAAC,GAChB;EAKf,MAAM,eAAsC,EAAE,GAAG,KAAK;EACtD,OAAO,aAAa,KAAK;EAEzB,MAAM,WAAY,MAAM,KAAK,KAAK,EAChC,OAAO;GAAE,GAAG;IAAe,KAAK,YAAY;EAAO,EACrD,CAAC;EACD,KAAK,MAAM,QAAQ,UACjB,MAAO,KAAgD,OAAO;EAGhE,MAAM,cAAc,KAAK;EACzB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,MAAM,UAAiC,EAAE,GAAG,KAAK;GACjD,IAAI,eAAe,QAAQ,iBAAiB,KAAA,GAC1C,QAAQ,eAAe;GAEzB,MAAM,KAAK,OAAO,QAAQ,SAAS,IAAI,OAAO;EAChD;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"junction.js","names":[],"sources":["../src/junction.ts"],"sourcesContent":["/**\n * SmrtJunction — base class for two-sided junction (many-to-many) collections.\n *\n * A junction collection manages rows that link a \"left\" entity to a \"right\" entity,\n * typically with discriminator fields (relationship/role) and an optional sortOrder.\n * Examples in the monorepo:\n *\n * | Subclass | Left field | Right field | Discriminator |\n * |--------------------------------|---------------|-------------|-----------------|\n * | ContentAssetCollection | contentId | assetId | relationship |\n * | PerformerOwnedAssetCollection | performerId | assetId | role |\n * | PlaceAssetCollection | placeId | assetId | relationship |\n * | EventParticipantCollection | eventId | profileId | role |\n * | FactContentCollection | factId | contentId | relationship |\n *\n * Each subclass declares `leftField` / `rightField` (camelCase) and optionally\n * overrides `sortField` (defaults to `'sortOrder'`; set `null` to disable ORDER BY).\n *\n * Polymorphic subclasses (where \"left\" or \"right\" is a composite key like\n * `metaType + metaId`) may override `byLeft` / `byRight` / `attach` / `detach`\n * with diverging signatures — see `AssetAssociationCollection` for a reference.\n *\n * @typeParam TItem - The junction row class (extends `SmrtObject`)\n */\n\nimport { SmrtCollection, type SmrtCreateInput } from './collection';\nimport { GlobalInterceptors } from './interceptors';\nimport { SmrtObject } from './object';\n\n/**\n * Options passed to `attach` / `setLinks` — written into the created junction row.\n *\n * Common keys: `relationship`, `role`, `sortOrder`, `tenantId`.\n * Subclass-specific keys (e.g. `placement`, `groupId` on EventParticipant) pass through.\n * Keys must match actual camelCase column names on the junction model; unknown\n * keys are rejected by `SmrtCollection.create`'s WHERE/field validation.\n */\nexport type JunctionAttachOptions = Record<string, unknown>;\n\n/**\n * Options passed to `byLeft` / `byRight` / `detach`.\n *\n * `limit` and `offset` bound reads made through `byLeft` / `byRight`; all\n * remaining keys are additional WHERE filters narrowing the operation. Keys\n * must match camelCase column names.\n */\nexport type JunctionFilterOptions = Record<string, unknown> & {\n limit?: number;\n offset?: number;\n};\n\nfunction camelToSnake(name: string): string {\n return name.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);\n}\n\nexport abstract class SmrtJunction<\n TItem extends SmrtObject,\n> extends SmrtCollection<TItem> {\n /**\n * Internal marker used by `SmrtCollection.create` to detect that this\n * subclass is a junction and apply a registration-presence guard. Static\n * property is inherited by all subclasses via the constructor chain.\n * Don't rename or remove without also updating the guard.\n */\n static readonly _isJunctionBase = true as const;\n\n /** Field name (camelCase) holding the \"left\" foreign key, e.g. `'contentId'`. */\n protected abstract leftField: string;\n\n /** Field name (camelCase) holding the \"right\" foreign key, e.g. `'assetId'`. */\n protected abstract rightField: string;\n\n /**\n * Field name (camelCase) used to ORDER BY when calling `byLeft` / `byRight`.\n * Defaults to `'sortOrder'`. Set to `null` to omit ORDER BY entirely.\n *\n * Independent from `positionField` — `sortField` is a *query* concern\n * (how rows are ordered when read), while `positionField` is a *write*\n * concern (what column `setLinks` auto-assigns to). Tables that order\n * by a non-position field (e.g. `'createdAt'`) should set `sortField`\n * accordingly and leave `positionField` set to `null` or its dedicated\n * position column name.\n */\n protected sortField: string | null = 'sortOrder';\n\n /**\n * Field name (camelCase) that `setLinks` auto-assigns the array index\n * to when the caller doesn't supply a value. Defaults to `'sortOrder'`.\n * Set to `null` for tables without a dedicated position column (e.g.\n * pure-key junctions, or tables ordered by timestamps).\n *\n * Writing the array index into a non-position field — like `createdAt`\n * or `placement` — would corrupt data. Subclasses without a numeric\n * position column MUST set this to `null`.\n */\n protected positionField: string | null = 'sortOrder';\n\n /**\n * Return junction rows where the left FK matches `leftId`, narrowed by\n * optional additional WHERE filters. Ordered ASC by `sortField` if set.\n */\n async byLeft(\n leftId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<TItem[]> {\n const { limit, offset, ...where } = opts;\n return (await this.list({\n // Spread opts FIRST so the fixed key always wins — prevents a\n // caller-supplied `{ [leftField]: otherId }` from retargeting the\n // query when opts is forwarded from untrusted input.\n where: { ...where, [this.leftField]: leftId },\n limit,\n offset,\n ...(this.sortField\n ? { orderBy: `${camelToSnake(this.sortField)} ASC` }\n : {}),\n })) as TItem[];\n }\n\n /**\n * Return junction rows where the right FK matches `rightId`, narrowed by\n * optional additional WHERE filters. Ordered ASC by `sortField` if set.\n */\n async byRight(\n rightId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<TItem[]> {\n const { limit, offset, ...where } = opts;\n return (await this.list({\n where: { ...where, [this.rightField]: rightId },\n limit,\n offset,\n ...(this.sortField\n ? { orderBy: `${camelToSnake(this.sortField)} ASC` }\n : {}),\n })) as TItem[];\n }\n\n /**\n * Create a new junction row linking `leftId` ↔ `rightId`.\n *\n * Goes through `SmrtCollection.create` which performs an upsert keyed on\n * the model's `@smrt({ conflictColumns })`. Duplicates on the conflict key\n * resolve to an UPDATE that rewrites every column — including the row's\n * `id` and any timestamp columns — to the new instance's values. For most\n * junctions that's fine: callers identify rows by (left, right, discriminator),\n * not by junction-row-id, so id rewrites are invisible.\n *\n * If your junction table is externally addressable by id (e.g. its rows\n * are exposed under `/api/v1/<table>/[id]`), override this method with a\n * find-or-create check to preserve id stability across duplicate calls.\n * See `ContentReferences.attach` for an example.\n *\n * @param opts - Extra fields to write into the row (e.g. `{ relationship, sortOrder, tenantId }`)\n */\n async attach(\n leftId: string,\n rightId: string,\n opts: JunctionAttachOptions = {},\n ): Promise<TItem> {\n return (await this.create({\n // Spread opts FIRST so the fixed key fields always win — prevents\n // a caller-supplied `{ [leftField]: otherId }` from retargeting\n // the write when opts is forwarded from untrusted input.\n ...opts,\n [this.leftField]: leftId,\n [this.rightField]: rightId,\n } as SmrtCreateInput<TItem>)) as TItem;\n }\n\n /**\n * Delete all junction rows matching `leftId` + `rightId` (+ optional filter `opts`).\n *\n * @param opts - Additional WHERE filters (e.g. `{ relationship: 'thumbnail' }`)\n */\n async detach(\n leftId: string,\n rightId: string,\n opts: JunctionFilterOptions = {},\n ): Promise<void> {\n // Read bounds never narrow the mutation snapshot.\n const filters = { ...opts };\n delete filters.limit;\n delete filters.offset;\n const links = (await this.list({\n where: {\n ...filters,\n [this.leftField]: leftId,\n [this.rightField]: rightId,\n },\n })) as TItem[];\n if (await SmrtObject.tryJunctionBatch(links, [])) return;\n for (const link of links) {\n await (link as unknown as { delete(): Promise<void> }).delete();\n }\n }\n\n /**\n * Replace the full set of right-side rows for a `leftId`, scoped by `opts`.\n *\n * Behavior:\n * 1. Snapshots and deletes existing rows matching `{ leftField: leftId, ...opts }`.\n * 2. Creates a new row for each `rightId`, spreading `opts` into the row data.\n * 3. If `positionField` is set and `opts` doesn't specify it, assigns the array index.\n *\n * Compatible models use grouped persistence while preserving delete/create\n * identity and feed semantics. Unsupported hooks, overrides, shapes, or batch\n * bounds retain the sequential path; see agents/object-runtime.md.\n * Not transactional — partial failure leaves the table in a mixed state.\n * For atomic replaces, wrap the call in your own DB transaction.\n */\n async setLinks(\n leftId: string,\n rightIds: string[],\n opts: JunctionAttachOptions = {},\n ): Promise<void> {\n // Strip the right-side key from snapshot opts — leaving it in would\n // narrow the delete to one specific right id, but `setLinks` is\n // contractually \"replace the full set of right rows for leftId\n // within the opts scope\". A rightField filter contradicts that.\n const snapshotOpts: JunctionAttachOptions = { ...opts };\n delete snapshotOpts[this.rightField];\n\n const existing = (await this.list({\n where: { ...snapshotOpts, [this.leftField]: leftId },\n })) as TItem[];\n // Custom create/attach implementations remain authoritative. No opt-in is\n // inferred from a method name, class name, or interceptor registration name.\n if (\n SmrtObject.hasBaseJunctionLifecycle(this._itemClass.prototype) &&\n GlobalInterceptors.supportsBulkMutation(\n this.getResolvedItemClassName(),\n ) &&\n new Set(rightIds).size === rightIds.length &&\n this.attach === SmrtJunction.prototype.attach &&\n SmrtCollection.hasBaseCreateLifecycle(this) &&\n rightIds.length + existing.length <= 100 &&\n !Object.keys(opts).some(\n (key) =>\n key.startsWith('_') || ['db', 'ai', 'id', 'slug'].includes(key),\n )\n ) {\n const added: TItem[] = [];\n for (let i = 0; i < rightIds.length; i++) {\n added.push(\n (await this.createUnsaved({\n ...opts,\n ...(this.positionField && opts[this.positionField] === undefined\n ? { [this.positionField]: i }\n : {}),\n [this.leftField]: leftId,\n [this.rightField]: rightIds[i],\n } as SmrtCreateInput<TItem>)) as TItem,\n );\n }\n if (await SmrtObject.tryJunctionBatch(existing, added)) return;\n }\n for (const link of existing) {\n await (link as unknown as { delete(): Promise<void> }).delete();\n }\n\n const positionKey = this.positionField;\n for (let i = 0; i < rightIds.length; i++) {\n const rowOpts: JunctionAttachOptions = { ...opts };\n if (positionKey && rowOpts[positionKey] === undefined) {\n rowOpts[positionKey] = i;\n }\n await this.attach(leftId, rightIds[i], rowOpts);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,SAAS,aAAa,MAAsB;CAC1C,OAAO,KAAK,QAAQ,WAAW,MAAM,IAAI,EAAE,YAAY,GAAG;AAC5D;AAEA,IAAsB,eAAtB,MAAsB,qBAEZ,eAAsB;;;;;;;CAO9B,OAAgB,kBAAkB;;;;;;;;;;;;CAmBlC,YAAqC;;;;;;;;;;;CAYrC,gBAAyC;;;;;CAMzC,MAAM,OACJ,QACA,OAA8B,CAAC,GACb;EAClB,MAAM,EAAE,OAAO,QAAQ,GAAG,UAAU;EACpC,OAAQ,MAAM,KAAK,KAAK;GAItB,OAAO;IAAE,GAAG;KAAQ,KAAK,YAAY;GAAO;GAC5C;GACA;GACA,GAAI,KAAK,YACL,EAAE,SAAS,GAAG,aAAa,KAAK,SAAS,EAAE,MAAM,IACjD,CAAC;EACP,CAAC;CACH;;;;;CAMA,MAAM,QACJ,SACA,OAA8B,CAAC,GACb;EAClB,MAAM,EAAE,OAAO,QAAQ,GAAG,UAAU;EACpC,OAAQ,MAAM,KAAK,KAAK;GACtB,OAAO;IAAE,GAAG;KAAQ,KAAK,aAAa;GAAQ;GAC9C;GACA;GACA,GAAI,KAAK,YACL,EAAE,SAAS,GAAG,aAAa,KAAK,SAAS,EAAE,MAAM,IACjD,CAAC;EACP,CAAC;CACH;;;;;;;;;;;;;;;;;;CAmBA,MAAM,OACJ,QACA,SACA,OAA8B,CAAC,GACf;EAChB,OAAQ,MAAM,KAAK,OAAO;GAIxB,GAAG;IACF,KAAK,YAAY;IACjB,KAAK,aAAa;EACrB,CAA2B;CAC7B;;;;;;CAOA,MAAM,OACJ,QACA,SACA,OAA8B,CAAC,GAChB;EAEf,MAAM,UAAU,EAAE,GAAG,KAAK;EAC1B,OAAO,QAAQ;EACf,OAAO,QAAQ;EACf,MAAM,QAAS,MAAM,KAAK,KAAK,EAC7B,OAAO;GACL,GAAG;IACF,KAAK,YAAY;IACjB,KAAK,aAAa;EACrB,EACF,CAAC;EACD,IAAI,MAAM,WAAW,iBAAiB,OAAO,CAAC,CAAC,GAAG;EAClD,KAAK,MAAM,QAAQ,OACjB,MAAO,KAAgD,OAAO;CAElE;;;;;;;;;;;;;;;CAgBA,MAAM,SACJ,QACA,UACA,OAA8B,CAAC,GAChB;EAKf,MAAM,eAAsC,EAAE,GAAG,KAAK;EACtD,OAAO,aAAa,KAAK;EAEzB,MAAM,WAAY,MAAM,KAAK,KAAK,EAChC,OAAO;GAAE,GAAG;IAAe,KAAK,YAAY;EAAO,EACrD,CAAC;EAGD,IACE,WAAW,yBAAyB,KAAK,WAAW,SAAS,KAC7D,mBAAmB,qBACjB,KAAK,yBAAyB,CAChC,KACA,IAAI,IAAI,QAAQ,CAAC,CAAC,SAAS,SAAS,UACpC,KAAK,WAAW,aAAa,UAAU,UACvC,eAAe,uBAAuB,IAAI,KAC1C,SAAS,SAAS,SAAS,UAAU,OACrC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,MAChB,QACC,IAAI,WAAW,GAAG,KAAK;GAAC;GAAM;GAAM;GAAM;EAAM,CAAC,CAAC,SAAS,GAAG,CAClE,GACA;GACA,MAAM,QAAiB,CAAC;GACxB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KACnC,MAAM,KACH,MAAM,KAAK,cAAc;IACxB,GAAG;IACH,GAAI,KAAK,iBAAiB,KAAK,KAAK,mBAAmB,KAAA,IACnD,GAAG,KAAK,gBAAgB,EAAE,IAC1B,CAAC;KACJ,KAAK,YAAY;KACjB,KAAK,aAAa,SAAS;GAC9B,CAA2B,CAC7B;GAEF,IAAI,MAAM,WAAW,iBAAiB,UAAU,KAAK,GAAG;EAC1D;EACA,KAAK,MAAM,QAAQ,UACjB,MAAO,KAAgD,OAAO;EAGhE,MAAM,cAAc,KAAK;EACzB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,MAAM,UAAiC,EAAE,GAAG,KAAK;GACjD,IAAI,eAAe,QAAQ,iBAAiB,KAAA,GAC1C,QAAQ,eAAe;GAEzB,MAAM,KAAK,OAAO,QAAQ,SAAS,IAAI,OAAO;EAChD;CACF;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DomainKnowledgeConfig } from '@happyvertical/smrt-types';
|
|
2
|
+
export declare const DEFAULT_KNOWLEDGE_CONFIG: DomainKnowledgeConfig;
|
|
3
|
+
/** Resolve the file and package portions of the documented knowledge precedence. */
|
|
4
|
+
export declare function resolveFileKnowledgeConfig(rootDir: string, packageName: string | undefined): Promise<DomainKnowledgeConfig>;
|
|
5
|
+
export declare function mergeKnowledgeConfig(...configs: Array<DomainKnowledgeConfig | undefined | null | false>): DomainKnowledgeConfig;
|
|
6
|
+
//# sourceMappingURL=knowledge-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-config.d.ts","sourceRoot":"","sources":["../src/knowledge-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,wBAAwB,EAAE,qBAWtC,CAAC;AAEF,oFAAoF;AACpF,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAoBhC;AAED,wBAAgB,oBAAoB,CAClC,GAAG,OAAO,EAAE,KAAK,CAAC,qBAAqB,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,GAClE,qBAAqB,CAYvB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region src/knowledge-config.ts
|
|
2
|
+
var DEFAULT_KNOWLEDGE_CONFIG = {
|
|
3
|
+
enabled: true,
|
|
4
|
+
api: {
|
|
5
|
+
enabled: false,
|
|
6
|
+
basePath: "/__smrt/knowledge",
|
|
7
|
+
requireAdmin: true,
|
|
8
|
+
includeDocs: false,
|
|
9
|
+
includePrompts: false
|
|
10
|
+
},
|
|
11
|
+
includeDocs: true,
|
|
12
|
+
includePrompts: true
|
|
13
|
+
};
|
|
14
|
+
/** Resolve the file and package portions of the documented knowledge precedence. */
|
|
15
|
+
async function resolveFileKnowledgeConfig(rootDir, packageName) {
|
|
16
|
+
let fileKnowledge = {};
|
|
17
|
+
let packageKnowledge = {};
|
|
18
|
+
try {
|
|
19
|
+
const { loadConfig } = await import("@happyvertical/smrt-config");
|
|
20
|
+
const config = await loadConfig({
|
|
21
|
+
cache: false,
|
|
22
|
+
searchFrom: rootDir
|
|
23
|
+
});
|
|
24
|
+
fileKnowledge = config.knowledge ?? {};
|
|
25
|
+
packageKnowledge = packageName ? config.packages?.[packageName]?.knowledge ?? {} : {};
|
|
26
|
+
} catch {
|
|
27
|
+
fileKnowledge = {};
|
|
28
|
+
packageKnowledge = {};
|
|
29
|
+
}
|
|
30
|
+
return mergeKnowledgeConfig(DEFAULT_KNOWLEDGE_CONFIG, fileKnowledge, packageKnowledge);
|
|
31
|
+
}
|
|
32
|
+
function mergeKnowledgeConfig(...configs) {
|
|
33
|
+
const merged = {};
|
|
34
|
+
for (const next of configs) {
|
|
35
|
+
if (!next) continue;
|
|
36
|
+
const api = Boolean(merged.api || next.api) ? {
|
|
37
|
+
...merged.api ?? {},
|
|
38
|
+
...next.api ?? {}
|
|
39
|
+
} : void 0;
|
|
40
|
+
Object.assign(merged, next);
|
|
41
|
+
if (api) merged.api = api;
|
|
42
|
+
}
|
|
43
|
+
return merged;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { DEFAULT_KNOWLEDGE_CONFIG, mergeKnowledgeConfig, resolveFileKnowledgeConfig };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=knowledge-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-config.js","names":[],"sources":["../src/knowledge-config.ts"],"sourcesContent":["import type { DomainKnowledgeConfig } from '@happyvertical/smrt-types';\n\nexport const DEFAULT_KNOWLEDGE_CONFIG: DomainKnowledgeConfig = {\n enabled: true,\n api: {\n enabled: false,\n basePath: '/__smrt/knowledge',\n requireAdmin: true,\n includeDocs: false,\n includePrompts: false,\n },\n includeDocs: true,\n includePrompts: true,\n};\n\n/** Resolve the file and package portions of the documented knowledge precedence. */\nexport async function resolveFileKnowledgeConfig(\n rootDir: string,\n packageName: string | undefined,\n): Promise<DomainKnowledgeConfig> {\n let fileKnowledge: DomainKnowledgeConfig = {};\n let packageKnowledge: DomainKnowledgeConfig = {};\n try {\n const { loadConfig } = await import('@happyvertical/smrt-config');\n const config = await loadConfig({ cache: false, searchFrom: rootDir });\n fileKnowledge = (config.knowledge ?? {}) as DomainKnowledgeConfig;\n packageKnowledge = (\n packageName ? (config.packages?.[packageName]?.knowledge ?? {}) : {}\n ) as DomainKnowledgeConfig;\n } catch {\n fileKnowledge = {};\n packageKnowledge = {};\n }\n\n return mergeKnowledgeConfig(\n DEFAULT_KNOWLEDGE_CONFIG,\n fileKnowledge,\n packageKnowledge,\n );\n}\n\nexport function mergeKnowledgeConfig(\n ...configs: Array<DomainKnowledgeConfig | undefined | null | false>\n): DomainKnowledgeConfig {\n const merged: DomainKnowledgeConfig = {};\n for (const next of configs) {\n if (!next) continue;\n const hasApi = Boolean(merged.api || next.api);\n const api = hasApi\n ? { ...(merged.api ?? {}), ...(next.api ?? {}) }\n : undefined;\n Object.assign(merged, next);\n if (api) merged.api = api;\n }\n return merged;\n}\n"],"mappings":";AAEA,IAAa,2BAAkD;CAC7D,SAAS;CACT,KAAK;EACH,SAAS;EACT,UAAU;EACV,cAAc;EACd,aAAa;EACb,gBAAgB;CAClB;CACA,aAAa;CACb,gBAAgB;AAClB;;AAGA,eAAsB,2BACpB,SACA,aACgC;CAChC,IAAI,gBAAuC,CAAC;CAC5C,IAAI,mBAA0C,CAAC;CAC/C,IAAI;EACF,MAAM,EAAE,eAAe,MAAM,OAAO;EACpC,MAAM,SAAS,MAAM,WAAW;GAAE,OAAO;GAAO,YAAY;EAAQ,CAAC;EACrE,gBAAiB,OAAO,aAAa,CAAC;EACtC,mBACE,cAAe,OAAO,WAAW,YAAY,EAAE,aAAa,CAAC,IAAK,CAAC;CAEvE,QAAQ;EACN,gBAAgB,CAAC;EACjB,mBAAmB,CAAC;CACtB;CAEA,OAAO,qBACL,0BACA,eACA,gBACF;AACF;AAEA,SAAgB,qBACd,GAAG,SACoB;CACvB,MAAM,SAAgC,CAAC;CACvC,KAAK,MAAM,QAAQ,SAAS;EAC1B,IAAI,CAAC,MAAM;EAEX,MAAM,MADS,QAAQ,OAAO,OAAO,KAAK,GAC9B,IACR;GAAE,GAAI,OAAO,OAAO,CAAC;GAAI,GAAI,KAAK,OAAO,CAAC;EAAG,IAC7C,KAAA;EACJ,OAAO,OAAO,QAAQ,IAAI;EAC1B,IAAI,KAAK,OAAO,MAAM;CACxB;CACA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-manifest.d.ts","sourceRoot":"","sources":["../../src/manifest/static-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"static-manifest.d.ts","sourceRoot":"","sources":["../../src/manifest/static-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,cAAc,EAAE,mBAsqDnB,CAAC;AAEX,eAAe,cAAc,CAAC"}
|
|
@@ -3,7 +3,7 @@ var staticManifest = {
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"timestamp": 0,
|
|
5
5
|
"packageName": "@happyvertical/smrt-core",
|
|
6
|
-
"packageVersion": "0.49.
|
|
6
|
+
"packageVersion": "0.49.4",
|
|
7
7
|
"objects": {
|
|
8
8
|
"@happyvertical/smrt-core:SmrtClass": {
|
|
9
9
|
"name": "smrtclass",
|
|
@@ -273,6 +273,18 @@ var staticManifest = {
|
|
|
273
273
|
"isStatic": false,
|
|
274
274
|
"isPublic": true
|
|
275
275
|
},
|
|
276
|
+
"hasBaseCreateLifecycle": {
|
|
277
|
+
"name": "hasBaseCreateLifecycle",
|
|
278
|
+
"async": false,
|
|
279
|
+
"parameters": [{
|
|
280
|
+
"name": "collection",
|
|
281
|
+
"type": "SmrtCollection<T>",
|
|
282
|
+
"optional": false
|
|
283
|
+
}],
|
|
284
|
+
"returnType": "boolean",
|
|
285
|
+
"isStatic": true,
|
|
286
|
+
"isPublic": true
|
|
287
|
+
},
|
|
276
288
|
"getOrUpsert": {
|
|
277
289
|
"name": "getOrUpsert",
|
|
278
290
|
"async": true,
|
|
@@ -520,6 +532,48 @@ var staticManifest = {
|
|
|
520
532
|
"isStatic": false,
|
|
521
533
|
"isPublic": true
|
|
522
534
|
},
|
|
535
|
+
"semanticSearchIds": {
|
|
536
|
+
"name": "semanticSearchIds",
|
|
537
|
+
"async": true,
|
|
538
|
+
"parameters": [{
|
|
539
|
+
"name": "query",
|
|
540
|
+
"type": "string",
|
|
541
|
+
"optional": false
|
|
542
|
+
}, {
|
|
543
|
+
"name": "options",
|
|
544
|
+
"type": "object",
|
|
545
|
+
"optional": true,
|
|
546
|
+
"memberTypes": [
|
|
547
|
+
"string",
|
|
548
|
+
"number",
|
|
549
|
+
"SmrtListWhereClause<ModelType>"
|
|
550
|
+
]
|
|
551
|
+
}],
|
|
552
|
+
"returnType": "Promise<Array<object>>",
|
|
553
|
+
"isStatic": false,
|
|
554
|
+
"isPublic": true
|
|
555
|
+
},
|
|
556
|
+
"findSimilarIdsToEmbedding": {
|
|
557
|
+
"name": "findSimilarIdsToEmbedding",
|
|
558
|
+
"async": true,
|
|
559
|
+
"parameters": [{
|
|
560
|
+
"name": "embedding",
|
|
561
|
+
"type": "number[]",
|
|
562
|
+
"optional": false
|
|
563
|
+
}, {
|
|
564
|
+
"name": "options",
|
|
565
|
+
"type": "object",
|
|
566
|
+
"optional": true,
|
|
567
|
+
"memberTypes": [
|
|
568
|
+
"string",
|
|
569
|
+
"number",
|
|
570
|
+
"SmrtListWhereClause<ModelType>"
|
|
571
|
+
]
|
|
572
|
+
}],
|
|
573
|
+
"returnType": "Promise<Array<object>>",
|
|
574
|
+
"isStatic": false,
|
|
575
|
+
"isPublic": true
|
|
576
|
+
},
|
|
523
577
|
"findSimilar": {
|
|
524
578
|
"name": "findSimilar",
|
|
525
579
|
"async": true,
|
|
@@ -951,6 +1005,42 @@ var staticManifest = {
|
|
|
951
1005
|
"isStatic": false,
|
|
952
1006
|
"isPublic": true
|
|
953
1007
|
},
|
|
1008
|
+
"supportsJunctionBatch": {
|
|
1009
|
+
"name": "supportsJunctionBatch",
|
|
1010
|
+
"async": false,
|
|
1011
|
+
"parameters": [],
|
|
1012
|
+
"returnType": "boolean",
|
|
1013
|
+
"isStatic": false,
|
|
1014
|
+
"isPublic": true
|
|
1015
|
+
},
|
|
1016
|
+
"hasBaseJunctionLifecycle": {
|
|
1017
|
+
"name": "hasBaseJunctionLifecycle",
|
|
1018
|
+
"async": false,
|
|
1019
|
+
"parameters": [{
|
|
1020
|
+
"name": "candidate",
|
|
1021
|
+
"type": "object",
|
|
1022
|
+
"optional": false
|
|
1023
|
+
}],
|
|
1024
|
+
"returnType": "boolean",
|
|
1025
|
+
"isStatic": true,
|
|
1026
|
+
"isPublic": true
|
|
1027
|
+
},
|
|
1028
|
+
"tryJunctionBatch": {
|
|
1029
|
+
"name": "tryJunctionBatch",
|
|
1030
|
+
"async": true,
|
|
1031
|
+
"parameters": [{
|
|
1032
|
+
"name": "removed",
|
|
1033
|
+
"type": "SmrtObject[]",
|
|
1034
|
+
"optional": false
|
|
1035
|
+
}, {
|
|
1036
|
+
"name": "added",
|
|
1037
|
+
"type": "SmrtObject[]",
|
|
1038
|
+
"optional": false
|
|
1039
|
+
}],
|
|
1040
|
+
"returnType": "Promise<boolean>",
|
|
1041
|
+
"isStatic": true,
|
|
1042
|
+
"isPublic": true
|
|
1043
|
+
},
|
|
954
1044
|
"save": {
|
|
955
1045
|
"name": "save",
|
|
956
1046
|
"async": true,
|