@loom-framework/core 0.1.0-alpha.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/adapter-filesystem.d.ts +32 -0
- package/dist/adapter-filesystem.d.ts.map +1 -0
- package/dist/adapter-filesystem.js +141 -0
- package/dist/adapter-filesystem.js.map +1 -0
- package/dist/adapter-sqlite.d.ts +51 -0
- package/dist/adapter-sqlite.d.ts.map +1 -0
- package/dist/adapter-sqlite.js +225 -0
- package/dist/adapter-sqlite.js.map +1 -0
- package/dist/capability-generator.d.ts +20 -0
- package/dist/capability-generator.d.ts.map +1 -0
- package/dist/capability-generator.js +288 -0
- package/dist/capability-generator.js.map +1 -0
- package/dist/commands.d.ts +32 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +40 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +483 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +179 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +198 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileSystem DataAdapter
|
|
3
|
+
*
|
|
4
|
+
* Stores data as JSON files, organized by model.
|
|
5
|
+
* Default adapter for development and small deployments.
|
|
6
|
+
*/
|
|
7
|
+
import type { DataAdapter, ModelSchema, ReadOptions, LoomConfig } from './types.js';
|
|
8
|
+
export interface FileSystemAdapterOptions {
|
|
9
|
+
dataDir: string;
|
|
10
|
+
config: LoomConfig;
|
|
11
|
+
}
|
|
12
|
+
export declare class FileSystemAdapter implements DataAdapter {
|
|
13
|
+
readonly name = "filesystem";
|
|
14
|
+
private dataDir;
|
|
15
|
+
private config;
|
|
16
|
+
private schemas;
|
|
17
|
+
constructor(options: FileSystemAdapterOptions);
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
healthCheck(): Promise<boolean>;
|
|
20
|
+
read(model: string, options?: ReadOptions): Promise<unknown>;
|
|
21
|
+
write(model: string, data: Record<string, unknown>): Promise<unknown>;
|
|
22
|
+
update(model: string, id: string, data: Record<string, unknown>): Promise<unknown>;
|
|
23
|
+
delete(model: string, id: string): Promise<void>;
|
|
24
|
+
getSchema(model: string): Promise<ModelSchema | undefined>;
|
|
25
|
+
listModels(): Promise<string[]>;
|
|
26
|
+
private requireModel;
|
|
27
|
+
private getModelDir;
|
|
28
|
+
private getRecordPath;
|
|
29
|
+
private matchesFilter;
|
|
30
|
+
private generateId;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=adapter-filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-filesystem.d.ts","sourceRoot":"","sources":["../src/adapter-filesystem.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAuC;gBAE1C,OAAO,EAAE,wBAAwB;IAUvC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAmC5D,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBrE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI1D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAMrC,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;CAMnB"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileSystem DataAdapter
|
|
3
|
+
*
|
|
4
|
+
* Stores data as JSON files, organized by model.
|
|
5
|
+
* Default adapter for development and small deployments.
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
export class FileSystemAdapter {
|
|
10
|
+
name = 'filesystem';
|
|
11
|
+
dataDir;
|
|
12
|
+
config;
|
|
13
|
+
schemas = new Map();
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.dataDir = options.dataDir;
|
|
16
|
+
this.config = options.config;
|
|
17
|
+
// Index model schemas
|
|
18
|
+
for (const model of options.config.data.models) {
|
|
19
|
+
this.schemas.set(model.name, model);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async initialize() {
|
|
23
|
+
await fs.mkdir(this.dataDir, { recursive: true });
|
|
24
|
+
// Create model directories
|
|
25
|
+
for (const model of this.config.data.models) {
|
|
26
|
+
const modelDir = this.getModelDir(model.name);
|
|
27
|
+
await fs.mkdir(modelDir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async healthCheck() {
|
|
31
|
+
try {
|
|
32
|
+
await fs.access(this.dataDir);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async read(model, options) {
|
|
40
|
+
this.requireModel(model);
|
|
41
|
+
// Read by ID
|
|
42
|
+
if (options?.id) {
|
|
43
|
+
const filePath = this.getRecordPath(model, options.id);
|
|
44
|
+
try {
|
|
45
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
46
|
+
return JSON.parse(content);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Read all records for model
|
|
53
|
+
const modelDir = this.getModelDir(model);
|
|
54
|
+
const files = await fs.readdir(modelDir);
|
|
55
|
+
const records = [];
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
if (!file.endsWith('.json'))
|
|
58
|
+
continue;
|
|
59
|
+
const content = await fs.readFile(path.join(modelDir, file), 'utf-8');
|
|
60
|
+
const record = JSON.parse(content);
|
|
61
|
+
// Apply filter if provided
|
|
62
|
+
if (options?.filter && !this.matchesFilter(record, options.filter)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
records.push(record);
|
|
66
|
+
}
|
|
67
|
+
return records;
|
|
68
|
+
}
|
|
69
|
+
async write(model, data) {
|
|
70
|
+
this.requireModel(model);
|
|
71
|
+
const schema = this.schemas.get(model);
|
|
72
|
+
const id = data.id || this.generateId();
|
|
73
|
+
// Validate required fields
|
|
74
|
+
for (const field of schema.fields) {
|
|
75
|
+
if (field.required && data[field.name] === undefined) {
|
|
76
|
+
throw new Error(`Missing required field: ${field.name}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const record = { id, ...data };
|
|
80
|
+
const filePath = this.getRecordPath(model, id);
|
|
81
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
82
|
+
await fs.writeFile(filePath, JSON.stringify(record, null, 2), 'utf-8');
|
|
83
|
+
return record;
|
|
84
|
+
}
|
|
85
|
+
async update(model, id, data) {
|
|
86
|
+
this.requireModel(model);
|
|
87
|
+
const filePath = this.getRecordPath(model, id);
|
|
88
|
+
let existing;
|
|
89
|
+
try {
|
|
90
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
91
|
+
existing = JSON.parse(content);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
throw new Error(`Record not found: ${model}/${id}`);
|
|
95
|
+
}
|
|
96
|
+
const updated = { ...existing, ...data, id }; // Preserve ID
|
|
97
|
+
await fs.writeFile(filePath, JSON.stringify(updated, null, 2), 'utf-8');
|
|
98
|
+
return updated;
|
|
99
|
+
}
|
|
100
|
+
async delete(model, id) {
|
|
101
|
+
this.requireModel(model);
|
|
102
|
+
const filePath = this.getRecordPath(model, id);
|
|
103
|
+
try {
|
|
104
|
+
await fs.unlink(filePath);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
throw new Error(`Record not found: ${model}/${id}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async getSchema(model) {
|
|
111
|
+
return this.schemas.get(model);
|
|
112
|
+
}
|
|
113
|
+
async listModels() {
|
|
114
|
+
return Array.from(this.schemas.keys());
|
|
115
|
+
}
|
|
116
|
+
// ── Private Helpers ──
|
|
117
|
+
requireModel(model) {
|
|
118
|
+
if (!this.schemas.has(model)) {
|
|
119
|
+
throw new Error(`Unknown model: ${model}. Available: ${Array.from(this.schemas.keys()).join(', ')}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
getModelDir(model) {
|
|
123
|
+
const schema = this.schemas.get(model);
|
|
124
|
+
const adapterConfig = schema.adapters?.filesystem;
|
|
125
|
+
const subDir = adapterConfig?.dir || model;
|
|
126
|
+
return path.join(this.dataDir, subDir);
|
|
127
|
+
}
|
|
128
|
+
getRecordPath(model, id) {
|
|
129
|
+
return path.join(this.getModelDir(model), `${id}.json`);
|
|
130
|
+
}
|
|
131
|
+
matchesFilter(record, filter) {
|
|
132
|
+
return Object.entries(filter).every(([key, value]) => record[key] === value);
|
|
133
|
+
}
|
|
134
|
+
generateId() {
|
|
135
|
+
// Simple ID generation without dynamic import
|
|
136
|
+
const timestamp = Date.now().toString(36);
|
|
137
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
138
|
+
return `rec_${timestamp}_${random}`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=adapter-filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-filesystem.js","sourceRoot":"","sources":["../src/adapter-filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite DataAdapter
|
|
3
|
+
*
|
|
4
|
+
* Stores data in a SQLite database using better-sqlite3.
|
|
5
|
+
* Suitable for medium-scale and embedded deployments.
|
|
6
|
+
*/
|
|
7
|
+
import type { DataAdapter, ModelSchema, ReadOptions, LoomConfig } from './types.js';
|
|
8
|
+
export interface SQLiteAdapterOptions {
|
|
9
|
+
/** Path to the SQLite database file */
|
|
10
|
+
dbPath: string;
|
|
11
|
+
config: LoomConfig;
|
|
12
|
+
}
|
|
13
|
+
export declare class SQLiteAdapter implements DataAdapter {
|
|
14
|
+
readonly name = "sqlite";
|
|
15
|
+
private dbPath;
|
|
16
|
+
private config;
|
|
17
|
+
private db;
|
|
18
|
+
private schemas;
|
|
19
|
+
constructor(options: SQLiteAdapterOptions);
|
|
20
|
+
initialize(): Promise<void>;
|
|
21
|
+
healthCheck(): Promise<boolean>;
|
|
22
|
+
read(model: string, options?: ReadOptions): Promise<unknown>;
|
|
23
|
+
write(model: string, data: Record<string, unknown>): Promise<unknown>;
|
|
24
|
+
update(model: string, id: string, data: Record<string, unknown>): Promise<unknown>;
|
|
25
|
+
delete(model: string, id: string): Promise<void>;
|
|
26
|
+
getSchema(model: string): Promise<ModelSchema | undefined>;
|
|
27
|
+
listModels(): Promise<string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Close the database connection
|
|
30
|
+
*/
|
|
31
|
+
close(): void;
|
|
32
|
+
private requireModel;
|
|
33
|
+
/**
|
|
34
|
+
* Create a table for a model based on its schema
|
|
35
|
+
*/
|
|
36
|
+
private createTable;
|
|
37
|
+
/**
|
|
38
|
+
* Map Loom field types to SQLite types
|
|
39
|
+
*/
|
|
40
|
+
private mapFieldType;
|
|
41
|
+
/**
|
|
42
|
+
* Serialize a value for SQLite storage
|
|
43
|
+
*/
|
|
44
|
+
private serializeValue;
|
|
45
|
+
/**
|
|
46
|
+
* Deserialize a row from SQLite storage
|
|
47
|
+
*/
|
|
48
|
+
private deserializeRow;
|
|
49
|
+
private generateId;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=adapter-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-sqlite.d.ts","sourceRoot":"","sources":["../src/adapter-sqlite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,MAAM,WAAW,oBAAoB;IACnC,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,qBAAa,aAAc,YAAW,WAAW;IAC/C,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,OAAO,CAAuC;gBAE1C,OAAO,EAAE,oBAAoB;IASnC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IA+B5D,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BrE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBlF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI1D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIrC;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,UAAU;CAKnB"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite DataAdapter
|
|
3
|
+
*
|
|
4
|
+
* Stores data in a SQLite database using better-sqlite3.
|
|
5
|
+
* Suitable for medium-scale and embedded deployments.
|
|
6
|
+
*/
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
export class SQLiteAdapter {
|
|
11
|
+
name = 'sqlite';
|
|
12
|
+
dbPath;
|
|
13
|
+
config;
|
|
14
|
+
db;
|
|
15
|
+
schemas = new Map();
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.dbPath = options.dbPath;
|
|
18
|
+
this.config = options.config;
|
|
19
|
+
for (const model of options.config.data.models) {
|
|
20
|
+
this.schemas.set(model.name, model);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async initialize() {
|
|
24
|
+
// Ensure directory exists
|
|
25
|
+
const dir = path.dirname(this.dbPath);
|
|
26
|
+
if (!fs.existsSync(dir)) {
|
|
27
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
this.db = new Database(this.dbPath);
|
|
30
|
+
this.db.pragma('journal_mode = WAL');
|
|
31
|
+
this.db.pragma('foreign_keys = ON');
|
|
32
|
+
// Auto-create tables from config
|
|
33
|
+
for (const model of this.config.data.models) {
|
|
34
|
+
this.createTable(model);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async healthCheck() {
|
|
38
|
+
try {
|
|
39
|
+
this.db.prepare('SELECT 1').get();
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async read(model, options) {
|
|
47
|
+
this.requireModel(model);
|
|
48
|
+
// Read by ID
|
|
49
|
+
if (options?.id) {
|
|
50
|
+
const row = this.db.prepare(`SELECT * FROM "${model}" WHERE id = ?`).get(options.id);
|
|
51
|
+
return row ? this.deserializeRow(row, model) : null;
|
|
52
|
+
}
|
|
53
|
+
// Read all with optional filter
|
|
54
|
+
let sql = `SELECT * FROM "${model}"`;
|
|
55
|
+
const params = [];
|
|
56
|
+
if (options?.filter && Object.keys(options.filter).length > 0) {
|
|
57
|
+
const filter = options.filter;
|
|
58
|
+
const conditions = Object.entries(filter).map(([key, value]) => {
|
|
59
|
+
params.push(value);
|
|
60
|
+
return `"${key}" = ?`;
|
|
61
|
+
});
|
|
62
|
+
sql += ` WHERE ${conditions.join(' AND ')}`;
|
|
63
|
+
}
|
|
64
|
+
if (options?.limit) {
|
|
65
|
+
sql += ` LIMIT ?`;
|
|
66
|
+
params.push(options.limit);
|
|
67
|
+
}
|
|
68
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
69
|
+
return rows.map((row) => this.deserializeRow(row, model));
|
|
70
|
+
}
|
|
71
|
+
async write(model, data) {
|
|
72
|
+
this.requireModel(model);
|
|
73
|
+
const schema = this.schemas.get(model);
|
|
74
|
+
const id = data.id || this.generateId();
|
|
75
|
+
// Validate required fields (skip id — auto-generated if not provided)
|
|
76
|
+
for (const field of schema.fields) {
|
|
77
|
+
if (field.name === 'id')
|
|
78
|
+
continue;
|
|
79
|
+
if (field.required && data[field.name] === undefined) {
|
|
80
|
+
throw new Error(`Missing required field: ${field.name}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const record = { id, ...data };
|
|
84
|
+
// Insert into table
|
|
85
|
+
const columns = Object.keys(record);
|
|
86
|
+
const values = columns.map((col) => this.serializeValue(record[col], model, col));
|
|
87
|
+
const placeholders = columns.map(() => '?').join(', ');
|
|
88
|
+
const colNames = columns.map((c) => `"${c}"`).join(', ');
|
|
89
|
+
this.db.prepare(`INSERT INTO "${model}" (${colNames}) VALUES (${placeholders})`).run(...values);
|
|
90
|
+
return record;
|
|
91
|
+
}
|
|
92
|
+
async update(model, id, data) {
|
|
93
|
+
this.requireModel(model);
|
|
94
|
+
// Check record exists
|
|
95
|
+
const existing = this.db.prepare(`SELECT * FROM "${model}" WHERE id = ?`).get(id);
|
|
96
|
+
if (!existing) {
|
|
97
|
+
throw new Error(`Record not found: ${model}/${id}`);
|
|
98
|
+
}
|
|
99
|
+
const updated = { ...existing, ...data, id };
|
|
100
|
+
const columns = Object.keys(data);
|
|
101
|
+
const values = columns.map((col) => this.serializeValue(updated[col], model, col));
|
|
102
|
+
const setClause = columns.map((c) => `"${c}" = ?`).join(', ');
|
|
103
|
+
this.db.prepare(`UPDATE "${model}" SET ${setClause} WHERE id = ?`).run(...values, id);
|
|
104
|
+
return this.deserializeRow(updated, model);
|
|
105
|
+
}
|
|
106
|
+
async delete(model, id) {
|
|
107
|
+
this.requireModel(model);
|
|
108
|
+
const result = this.db.prepare(`DELETE FROM "${model}" WHERE id = ?`).run(id);
|
|
109
|
+
if (result.changes === 0) {
|
|
110
|
+
throw new Error(`Record not found: ${model}/${id}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async getSchema(model) {
|
|
114
|
+
return this.schemas.get(model);
|
|
115
|
+
}
|
|
116
|
+
async listModels() {
|
|
117
|
+
return Array.from(this.schemas.keys());
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Close the database connection
|
|
121
|
+
*/
|
|
122
|
+
close() {
|
|
123
|
+
this.db?.close();
|
|
124
|
+
}
|
|
125
|
+
// ── Private Helpers ──
|
|
126
|
+
requireModel(model) {
|
|
127
|
+
if (!this.schemas.has(model)) {
|
|
128
|
+
throw new Error(`Unknown model: ${model}. Available: ${Array.from(this.schemas.keys()).join(', ')}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Create a table for a model based on its schema
|
|
133
|
+
*/
|
|
134
|
+
createTable(model) {
|
|
135
|
+
const columns = ['id TEXT PRIMARY KEY'];
|
|
136
|
+
for (const field of model.fields) {
|
|
137
|
+
if (field.name === 'id')
|
|
138
|
+
continue; // Already added
|
|
139
|
+
const colType = this.mapFieldType(field.type);
|
|
140
|
+
const notNull = field.required ? ' NOT NULL' : '';
|
|
141
|
+
const defaultVal = field.default !== undefined ? ` DEFAULT ${JSON.stringify(field.default)}` : '';
|
|
142
|
+
columns.push(`"${field.name}" ${colType}${notNull}${defaultVal}`);
|
|
143
|
+
}
|
|
144
|
+
const sql = `CREATE TABLE IF NOT EXISTS "${model.name}" (${columns.join(', ')})`;
|
|
145
|
+
this.db.exec(sql);
|
|
146
|
+
// Create indexes
|
|
147
|
+
if (model.indexes) {
|
|
148
|
+
for (const index of model.indexes) {
|
|
149
|
+
const indexName = `idx_${model.name}_${index.fields.join('_')}`;
|
|
150
|
+
const unique = index.unique ? 'UNIQUE ' : '';
|
|
151
|
+
const cols = index.fields.map((f) => `"${f}"`).join(', ');
|
|
152
|
+
this.db.exec(`CREATE ${unique}INDEX IF NOT EXISTS "${indexName}" ON "${model.name}" (${cols})`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Map Loom field types to SQLite types
|
|
158
|
+
*/
|
|
159
|
+
mapFieldType(type) {
|
|
160
|
+
switch (type) {
|
|
161
|
+
case 'string':
|
|
162
|
+
case 'date':
|
|
163
|
+
return 'TEXT';
|
|
164
|
+
case 'number':
|
|
165
|
+
return 'REAL';
|
|
166
|
+
case 'boolean':
|
|
167
|
+
return 'INTEGER';
|
|
168
|
+
case 'string[]':
|
|
169
|
+
case 'number[]':
|
|
170
|
+
case 'json':
|
|
171
|
+
return 'TEXT'; // Stored as JSON string
|
|
172
|
+
default:
|
|
173
|
+
return 'TEXT';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Serialize a value for SQLite storage
|
|
178
|
+
*/
|
|
179
|
+
serializeValue(value, model, field) {
|
|
180
|
+
if (value === null || value === undefined)
|
|
181
|
+
return null;
|
|
182
|
+
const schema = this.schemas.get(model);
|
|
183
|
+
const fieldDef = schema?.fields.find((f) => f.name === field);
|
|
184
|
+
if (fieldDef && (fieldDef.type === 'string[]' || fieldDef.type === 'number[]' || fieldDef.type === 'json')) {
|
|
185
|
+
return JSON.stringify(value);
|
|
186
|
+
}
|
|
187
|
+
if (typeof value === 'boolean')
|
|
188
|
+
return value ? 1 : 0;
|
|
189
|
+
return value;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Deserialize a row from SQLite storage
|
|
193
|
+
*/
|
|
194
|
+
deserializeRow(row, model) {
|
|
195
|
+
const schema = this.schemas.get(model);
|
|
196
|
+
if (!schema)
|
|
197
|
+
return row;
|
|
198
|
+
const result = { ...row };
|
|
199
|
+
for (const field of schema.fields) {
|
|
200
|
+
const value = result[field.name];
|
|
201
|
+
if (value === null || value === undefined)
|
|
202
|
+
continue;
|
|
203
|
+
if (field.type === 'string[]' || field.type === 'number[]' || field.type === 'json') {
|
|
204
|
+
if (typeof value === 'string') {
|
|
205
|
+
try {
|
|
206
|
+
result[field.name] = JSON.parse(value);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Keep as-is if not valid JSON
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (field.type === 'boolean') {
|
|
214
|
+
result[field.name] = Boolean(value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
generateId() {
|
|
220
|
+
const timestamp = Date.now().toString(36);
|
|
221
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
222
|
+
return `rec_${timestamp}_${random}`;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=adapter-sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-sqlite.js","sourceRoot":"","sources":["../src/adapter-sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Generator
|
|
3
|
+
*
|
|
4
|
+
* Core innovation: One schema definition → MCP Server + CLI commands
|
|
5
|
+
*
|
|
6
|
+
* From loom.config.ts model definitions, generates:
|
|
7
|
+
* 1. MCP Server (.loom/mcp-server/) - structured data CRUD tools
|
|
8
|
+
* 2. CLI data commands (cli/commands/data/) - dev/debug data access
|
|
9
|
+
* 3. MCP config (.loom/mcp.json) - Claude Code MCP registration
|
|
10
|
+
*/
|
|
11
|
+
import type { LoomConfig } from './types.js';
|
|
12
|
+
export interface GenerateResult {
|
|
13
|
+
mcpServerDir: string;
|
|
14
|
+
filesWritten: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate all capabilities from config
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateCapabilities(projectRoot: string, config: LoomConfig): Promise<GenerateResult>;
|
|
20
|
+
//# sourceMappingURL=capability-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-generator.d.ts","sourceRoot":"","sources":["../src/capability-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAe,UAAU,EAAmB,MAAM,YAAY,CAAC;AA6N3E,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,cAAc,CAAC,CA+EzB"}
|