@akanjs/cli 3.0.0-alpha.1 → 3.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
5ce0c5971a50c46a41ba69a3a1125bb984dfbb8bc836bb7a817970eca45b7c59
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.2",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@langchain/openai": "^1.4.6",
|
|
35
35
|
"@tailwindcss/node": "^4.3.0",
|
|
36
36
|
"@trapezedev/project": "^7.1.4",
|
|
37
|
-
"akanjs": "3.0.0-alpha.
|
|
37
|
+
"akanjs": "3.0.0-alpha.2",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"dayjs": "^1.11.20",
|
package/templates/lib/db.ts
CHANGED
|
@@ -16,7 +16,9 @@ ${databaseModules.map((module) => `import * as ${module}Db from "./${module}/${m
|
|
|
16
16
|
${libs.map((lib) => `export { db as ${lib} } from "@libs/${lib}/server";`).join("\n")}
|
|
17
17
|
|
|
18
18
|
${databaseModules.map((module) => `class ${capitalize(module)}Input extends by(cnst.${capitalize(module)}Input) {}`).join("\n")}
|
|
19
|
+
${databaseModules.map((module) => `class ${capitalize(module)}Insight extends by(cnst.${capitalize(module)}Insight) {}`).join("\n")}
|
|
19
20
|
${databaseModules.length ? `export type { ${databaseModules.map((module) => `${capitalize(module)}Input`).join(", ")} };` : ""}
|
|
21
|
+
${databaseModules.length ? `export type { ${databaseModules.map((module) => `${capitalize(module)}Insight`).join(", ")} };` : ""}
|
|
20
22
|
|
|
21
23
|
${scalarModules.map((module) => `export type * from "./__scalar/${module}/${module}.document";`).join("\n")}
|
|
22
24
|
${databaseModules.map((module) => `export type * from "./${module}/${module}.document";`).join("\n")}
|
|
@@ -24,7 +26,7 @@ ${databaseModules.map((module) => `export type * from "./${module}/${module}.doc
|
|
|
24
26
|
${databaseModules
|
|
25
27
|
.map((module) => {
|
|
26
28
|
const names = { Module: module.charAt(0).toUpperCase() + module.slice(1) };
|
|
27
|
-
return `export const ${module} = DatabaseRegistry.buildModel("${module}" as const, ${names.Module}Input, ${module}Db.${names.Module}, ${module}Db.${names.Module}Model, cnst.${names.Module},
|
|
29
|
+
return `export const ${module} = DatabaseRegistry.buildModel("${module}" as const, ${names.Module}Input, ${module}Db.${names.Module}, ${module}Db.${names.Module}Model, cnst.${names.Module}, ${names.Module}Insight, ${module}Db.${names.Module}Filter);`;
|
|
28
30
|
})
|
|
29
31
|
.join("\n")}
|
|
30
32
|
${scalarModules.map((module) => `export const ${module} = DatabaseRegistry.buildScalar("${module}" as const, ${capitalize(module)});`).join("\n")}
|
|
@@ -650,7 +650,7 @@ export class TaskService extends serve(db.task, ({ plug }) => ({
|
|
|
650
650
|
For a custom adapter class (not a predefined role), pass the class itself, e.g. `ipfsApi: plug(IpfsApi)`
|
|
651
651
|
(see `libs/shared/lib/file/file.service.ts`). Injecting a file/image field is usually simpler than calling
|
|
652
652
|
storage directly: declare `image: field(File).optional()` (or `images: field([File])`) on the model and let the
|
|
653
|
-
store's generated `upload<Field>On<Model>(fileList)` action handle the upload. Add `{ cascade: "
|
|
653
|
+
store's generated `upload<Field>On<Model>(fileList)` action handle the upload. Add `{ cascade: "removeRef" }` to that
|
|
654
654
|
field when the file belongs to the model alone, and removing the model removes the file and its stored object.
|
|
655
655
|
|
|
656
656
|
---
|
|
@@ -868,12 +868,19 @@ A short list of things the type system does not always catch:
|
|
|
868
868
|
`secret` / `hidden` / `resolve()` fields with `text` throw at class-build time — the mirror is plaintext. Search
|
|
869
869
|
runs on sqlite/libsql only; `q.search()` against Postgres throws. `thumb` is mirrored for rendering and is not
|
|
870
870
|
indexed.
|
|
871
|
-
- **`cascade
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
871
|
+
- **`cascade` names a direction, and the wrong one is a data loss.** Both actions can sit on the same field shape,
|
|
872
|
+
so the value has to say which end goes away. `cascade: "removeRef"` on the relation an owner holds
|
|
873
|
+
(`image: field(File, { cascade: "removeRef" })`, arrays included) removes the target when the owner is removed;
|
|
874
|
+
only a relation accepts it. `cascade: "removeWith"` on a child's own reference to its owner
|
|
875
|
+
(`field(ID, { ref: "agentSession", cascade: "removeWith" })`, or a relation, or `refPath` for a polymorphic
|
|
876
|
+
owner whose type field must be an `enumOf`) removes the child when the owner is — the owner never learns its
|
|
877
|
+
children exist. The removal runs through the **target's service** so its `_postRemove` runs too, unless the
|
|
878
|
+
target provably has no removal side effect, in which case the boot-time plan collapses it into one query. A
|
|
879
|
+
`removeWith` field gets its index automatically. Nothing checks for other references to the same target, so
|
|
880
|
+
`removeRef` asserts exclusive ownership. Removal is soft but a storage delete is not, and a query-level removal
|
|
881
|
+
fires no hooks and therefore no cascade.
|
|
882
|
+
- **Removal is always soft, and `delete` is reserved.** `remove(id)`, the facade's `removeMany(query)`, and the
|
|
883
|
+
store's `removeManyByQuery` all stamp `removedAt`; the framework has no hard delete for a model table.
|
|
877
884
|
- **`q.search()` is a filter node, not a slice requirement.** Prefer
|
|
878
885
|
`bySearch: filter().arg("text", String).query((text, q) => q.search(text, { prefix: true }))` — the generated
|
|
879
886
|
`listBySearch` / `countBySearch` / `queryBySearch` / `insightBySearch` come for free. Only add a search slice when
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface Dict {
|
|
2
|
-
libName: string;
|
|
3
|
-
}
|
|
4
|
-
export default function getContent(scanInfo: null, dict: Dict) {
|
|
5
|
-
return `
|
|
6
|
-
// 현 디렉토리에서는 프로젝트 내 전체적으로 사용되는 로직을 구현하며, 따라서 백/프론트 비의존적인 pure js 코드만 구현 가능합니다.
|
|
7
|
-
// common폴더와 다른점은, base 코드는 시스템 전체에서 import되어 사용되므로, 가장 핵심적인 로직과 추상화된 기능만 구현해야합니다.
|
|
8
|
-
// @${dict.libName}/base에서는 서버/클라이언트 관련 라이브러리(@*/server, @*/server, @*/client, @*/client)를 모두 import할 수 없으며, @*/base 라이브러리만 import 가능합니다.
|
|
9
|
-
|
|
10
|
-
export const someBaseLogic = () => {
|
|
11
|
-
//
|
|
12
|
-
};
|
|
13
|
-
`;
|
|
14
|
-
}
|