@graph-knowledge/api 0.1.2 → 0.1.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 +12 -1
- package/package.json +3 -3
- package/src/index.js +19 -6
- package/src/lib/clients/firebase-auth-client.js +16 -12
- package/src/lib/clients/firebase-firestore-client.js +23 -19
- package/src/lib/config/api-config.js +2 -0
- package/src/lib/constants/element-defaults.js +5 -2
- package/src/lib/errors/api-errors.js +13 -5
- package/src/lib/graph-knowledge-api.js +29 -25
- package/src/lib/interfaces/auth-client.interface.js +2 -0
- package/src/lib/interfaces/batch-operations.interface.d.ts +1 -1
- package/src/lib/interfaces/batch-operations.interface.js +2 -0
- package/src/lib/interfaces/document-operations.interface.js +2 -0
- package/src/lib/interfaces/element-operations.interface.d.ts +1 -1
- package/src/lib/interfaces/element-operations.interface.js +2 -0
- package/src/lib/interfaces/element-validator.interface.js +2 -0
- package/src/lib/interfaces/firestore-client.interface.js +2 -0
- package/src/lib/interfaces/node-operations.interface.d.ts +1 -1
- package/src/lib/interfaces/node-operations.interface.js +2 -0
- package/src/lib/models/document.model.js +4 -1
- package/src/lib/models/index.js +5 -1
- package/src/lib/operations/batch-operations.d.ts +1 -1
- package/src/lib/operations/batch-operations.js +15 -11
- package/src/lib/operations/document-operations.js +14 -10
- package/src/lib/operations/element-operations.d.ts +1 -1
- package/src/lib/operations/element-operations.js +18 -14
- package/src/lib/operations/node-operations.d.ts +1 -1
- package/src/lib/operations/node-operations.js +10 -6
- package/src/lib/testing/index.js +7 -2
- package/src/lib/testing/mock-auth-client.js +8 -4
- package/src/lib/testing/mock-firestore-client.js +5 -1
- package/src/lib/types/api-types.d.ts +1 -1
- package/src/lib/types/api-types.js +2 -0
- package/src/lib/types/element-input-types.js +2 -0
- package/src/lib/utils/link-level-manager.d.ts +1 -1
- package/src/lib/utils/link-level-manager.js +5 -1
- package/src/lib/utils/uuid.js +4 -1
- package/src/lib/validators/document-validator.js +18 -14
- package/src/lib/validators/element-type-validators/base-element-validator.js +20 -16
- package/src/lib/validators/element-type-validators/connector-validator.js +13 -9
- package/src/lib/validators/element-type-validators/custom-shape-validator.js +11 -6
- package/src/lib/validators/element-type-validators/rectangle-validator.js +10 -6
- package/src/lib/validators/element-type-validators/text-validator.js +17 -13
- package/src/lib/validators/element-type-validators/uml-validators.js +29 -20
- package/src/lib/validators/element-validator-registry.js +22 -18
- package/src/lib/validators/node-validator.js +22 -18
package/README.md
CHANGED
|
@@ -194,6 +194,17 @@ await api.elements.create(documentId, nodeId, {
|
|
|
194
194
|
textAlign: "center"
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
+
// Create multi-line text (use \n for line breaks)
|
|
198
|
+
await api.elements.create(documentId, nodeId, {
|
|
199
|
+
type: "text",
|
|
200
|
+
x: 100,
|
|
201
|
+
y: 200,
|
|
202
|
+
text: "Line 1\nLine 2\nLine 3",
|
|
203
|
+
fontSize: 18,
|
|
204
|
+
lineHeight: 1.4 // Optional: adjust line spacing (default: 1.2)
|
|
205
|
+
});
|
|
206
|
+
// Note: height is auto-calculated based on the number of lines and lineHeight
|
|
207
|
+
|
|
197
208
|
// Create a connector
|
|
198
209
|
await api.elements.create(documentId, nodeId, {
|
|
199
210
|
type: "connector",
|
|
@@ -263,7 +274,7 @@ await api.batch.deleteElements(documentId, nodeId, [
|
|
|
263
274
|
| Type | Description |
|
|
264
275
|
|------|-------------|
|
|
265
276
|
| `rectangle` | Rectangle shape with fill, stroke, corner radius |
|
|
266
|
-
| `text` | Text element with font customization |
|
|
277
|
+
| `text` | Text element with font customization (supports multi-line with `\n`) |
|
|
267
278
|
| `connector` | Line connecting two elements |
|
|
268
279
|
| `uml-class` | UML class diagram element |
|
|
269
280
|
| `uml-interface` | UML interface element |
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graph-knowledge/api",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "0.1.4",
|
|
5
4
|
"description": "Headless Document API for Graph Knowledge - programmatic access to documents, nodes, and elements",
|
|
6
5
|
"license": "MIT",
|
|
7
6
|
"author": "Graph Knowledge Team",
|
|
@@ -23,6 +22,7 @@
|
|
|
23
22
|
"exports": {
|
|
24
23
|
".": {
|
|
25
24
|
"types": "./src/index.d.ts",
|
|
25
|
+
"require": "./src/index.js",
|
|
26
26
|
"default": "./src/index.js"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"firebase": ">=10.0.0 <13.0.0"
|
|
39
39
|
},
|
|
40
40
|
"sideEffects": false,
|
|
41
|
-
"
|
|
41
|
+
"type": "commonjs"
|
|
42
42
|
}
|
package/src/index.js
CHANGED
|
@@ -1,19 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// =============================================================================
|
|
2
3
|
// Graph Knowledge Headless Document API
|
|
3
4
|
// =============================================================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MockFirestoreClient = exports.MockAuthClient = exports.LinkLevelManager = exports.CURRENT_DOCUMENT_SCHEMA_VERSION = exports.PermissionError = exports.ValidationError = exports.NotFoundError = exports.AuthenticationError = exports.GraphKnowledgeAPIError = exports.GraphKnowledgeAPI = void 0;
|
|
4
7
|
// Main API Class
|
|
5
|
-
|
|
8
|
+
var graph_knowledge_api_1 = require("./lib/graph-knowledge-api");
|
|
9
|
+
Object.defineProperty(exports, "GraphKnowledgeAPI", { enumerable: true, get: function () { return graph_knowledge_api_1.GraphKnowledgeAPI; } });
|
|
6
10
|
// =============================================================================
|
|
7
11
|
// Errors
|
|
8
12
|
// =============================================================================
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
var api_errors_1 = require("./lib/errors/api-errors");
|
|
14
|
+
Object.defineProperty(exports, "GraphKnowledgeAPIError", { enumerable: true, get: function () { return api_errors_1.GraphKnowledgeAPIError; } });
|
|
15
|
+
Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return api_errors_1.AuthenticationError; } });
|
|
16
|
+
Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return api_errors_1.NotFoundError; } });
|
|
17
|
+
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return api_errors_1.ValidationError; } });
|
|
18
|
+
Object.defineProperty(exports, "PermissionError", { enumerable: true, get: function () { return api_errors_1.PermissionError; } });
|
|
19
|
+
var models_1 = require("./lib/models");
|
|
20
|
+
Object.defineProperty(exports, "CURRENT_DOCUMENT_SCHEMA_VERSION", { enumerable: true, get: function () { return models_1.CURRENT_DOCUMENT_SCHEMA_VERSION; } });
|
|
11
21
|
// =============================================================================
|
|
12
22
|
// Utilities
|
|
13
23
|
// =============================================================================
|
|
14
|
-
|
|
24
|
+
var link_level_manager_1 = require("./lib/utils/link-level-manager");
|
|
25
|
+
Object.defineProperty(exports, "LinkLevelManager", { enumerable: true, get: function () { return link_level_manager_1.LinkLevelManager; } });
|
|
15
26
|
// =============================================================================
|
|
16
27
|
// Testing Utilities
|
|
17
28
|
// =============================================================================
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
var mock_auth_client_1 = require("./lib/testing/mock-auth-client");
|
|
30
|
+
Object.defineProperty(exports, "MockAuthClient", { enumerable: true, get: function () { return mock_auth_client_1.MockAuthClient; } });
|
|
31
|
+
var mock_firestore_client_1 = require("./lib/testing/mock-firestore-client");
|
|
32
|
+
Object.defineProperty(exports, "MockFirestoreClient", { enumerable: true, get: function () { return mock_firestore_client_1.MockFirestoreClient; } });
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FirebaseAuthClient = void 0;
|
|
4
|
+
const auth_1 = require("firebase/auth");
|
|
5
|
+
const firestore_1 = require("firebase/firestore");
|
|
6
|
+
const api_errors_1 = require("../errors/api-errors");
|
|
4
7
|
/**
|
|
5
8
|
* Firebase Auth implementation of IAuthClient.
|
|
6
9
|
*/
|
|
7
|
-
|
|
10
|
+
class FirebaseAuthClient {
|
|
8
11
|
auth;
|
|
9
12
|
firestore;
|
|
10
13
|
_currentUser = null;
|
|
@@ -14,7 +17,7 @@ export class FirebaseAuthClient {
|
|
|
14
17
|
this.auth = auth;
|
|
15
18
|
this.firestore = firestore;
|
|
16
19
|
this._initPromise = new Promise((resolve) => {
|
|
17
|
-
const unsubscribe = onAuthStateChanged(this.auth, (user) => {
|
|
20
|
+
const unsubscribe = (0, auth_1.onAuthStateChanged)(this.auth, (user) => {
|
|
18
21
|
this._currentUser = user;
|
|
19
22
|
if (!this._initialized) {
|
|
20
23
|
this._initialized = true;
|
|
@@ -32,16 +35,16 @@ export class FirebaseAuthClient {
|
|
|
32
35
|
}
|
|
33
36
|
async signIn(email, password) {
|
|
34
37
|
try {
|
|
35
|
-
const credential = await signInWithEmailAndPassword(this.auth, email, password);
|
|
38
|
+
const credential = await (0, auth_1.signInWithEmailAndPassword)(this.auth, email, password);
|
|
36
39
|
this._currentUser = credential.user;
|
|
37
40
|
}
|
|
38
41
|
catch (error) {
|
|
39
42
|
const message = error instanceof Error ? error.message : "Sign in failed";
|
|
40
|
-
throw new AuthenticationError(message);
|
|
43
|
+
throw new api_errors_1.AuthenticationError(message);
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
async signOut() {
|
|
44
|
-
await
|
|
47
|
+
await (0, auth_1.signOut)(this.auth);
|
|
45
48
|
this._currentUser = null;
|
|
46
49
|
}
|
|
47
50
|
get currentUserId() {
|
|
@@ -49,7 +52,7 @@ export class FirebaseAuthClient {
|
|
|
49
52
|
}
|
|
50
53
|
requireAuth() {
|
|
51
54
|
if (!this._currentUser) {
|
|
52
|
-
throw new AuthenticationError("Not authenticated");
|
|
55
|
+
throw new api_errors_1.AuthenticationError("Not authenticated");
|
|
53
56
|
}
|
|
54
57
|
return this._currentUser.uid;
|
|
55
58
|
}
|
|
@@ -58,8 +61,8 @@ export class FirebaseAuthClient {
|
|
|
58
61
|
return false;
|
|
59
62
|
}
|
|
60
63
|
// Read premium status from user profile in Firestore
|
|
61
|
-
const userDoc = doc(this.firestore, `users/${this._currentUser.uid}`);
|
|
62
|
-
const snapshot = await getDoc(userDoc);
|
|
64
|
+
const userDoc = (0, firestore_1.doc)(this.firestore, `users/${this._currentUser.uid}`);
|
|
65
|
+
const snapshot = await (0, firestore_1.getDoc)(userDoc);
|
|
63
66
|
if (!snapshot.exists()) {
|
|
64
67
|
return false;
|
|
65
68
|
}
|
|
@@ -70,7 +73,8 @@ export class FirebaseAuthClient {
|
|
|
70
73
|
this.requireAuth();
|
|
71
74
|
const premium = await this.isPremium();
|
|
72
75
|
if (!premium) {
|
|
73
|
-
throw new PermissionError("Premium subscription required");
|
|
76
|
+
throw new api_errors_1.PermissionError("Premium subscription required");
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
}
|
|
80
|
+
exports.FirebaseAuthClient = FirebaseAuthClient;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FirebaseFirestoreClient = void 0;
|
|
4
|
+
const firestore_1 = require("firebase/firestore");
|
|
2
5
|
/**
|
|
3
6
|
* Firebase Firestore batch writer implementation.
|
|
4
7
|
*/
|
|
@@ -10,15 +13,15 @@ class FirestoreBatchWriter {
|
|
|
10
13
|
this.batch = batch;
|
|
11
14
|
}
|
|
12
15
|
set(path, data) {
|
|
13
|
-
const docRef = doc(this.db, path);
|
|
16
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
14
17
|
this.batch.set(docRef, data);
|
|
15
18
|
}
|
|
16
19
|
update(path, data) {
|
|
17
|
-
const docRef = doc(this.db, path);
|
|
20
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
18
21
|
this.batch.update(docRef, data);
|
|
19
22
|
}
|
|
20
23
|
delete(path) {
|
|
21
|
-
const docRef = doc(this.db, path);
|
|
24
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
22
25
|
this.batch.delete(docRef);
|
|
23
26
|
}
|
|
24
27
|
async commit() {
|
|
@@ -28,14 +31,14 @@ class FirestoreBatchWriter {
|
|
|
28
31
|
/**
|
|
29
32
|
* Firebase Firestore implementation of IFirestoreClient.
|
|
30
33
|
*/
|
|
31
|
-
|
|
34
|
+
class FirebaseFirestoreClient {
|
|
32
35
|
db;
|
|
33
36
|
constructor(db) {
|
|
34
37
|
this.db = db;
|
|
35
38
|
}
|
|
36
39
|
async getDocument(path) {
|
|
37
|
-
const docRef = doc(this.db, path);
|
|
38
|
-
const snapshot = await getDoc(docRef);
|
|
40
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
41
|
+
const snapshot = await (0, firestore_1.getDoc)(docRef);
|
|
39
42
|
if (!snapshot.exists()) {
|
|
40
43
|
return null;
|
|
41
44
|
}
|
|
@@ -45,35 +48,36 @@ export class FirebaseFirestoreClient {
|
|
|
45
48
|
};
|
|
46
49
|
}
|
|
47
50
|
async setDocument(path, data) {
|
|
48
|
-
const docRef = doc(this.db, path);
|
|
49
|
-
await setDoc(docRef, data);
|
|
51
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
52
|
+
await (0, firestore_1.setDoc)(docRef, data);
|
|
50
53
|
}
|
|
51
54
|
async updateDocument(path, data) {
|
|
52
|
-
const docRef = doc(this.db, path);
|
|
53
|
-
await updateDoc(docRef, data);
|
|
55
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
56
|
+
await (0, firestore_1.updateDoc)(docRef, data);
|
|
54
57
|
}
|
|
55
58
|
async deleteDocument(path) {
|
|
56
|
-
const docRef = doc(this.db, path);
|
|
57
|
-
await deleteDoc(docRef);
|
|
59
|
+
const docRef = (0, firestore_1.doc)(this.db, path);
|
|
60
|
+
await (0, firestore_1.deleteDoc)(docRef);
|
|
58
61
|
}
|
|
59
62
|
async getCollection(path) {
|
|
60
|
-
const collectionRef = collection(this.db, path);
|
|
61
|
-
const snapshot = await getDocs(collectionRef);
|
|
63
|
+
const collectionRef = (0, firestore_1.collection)(this.db, path);
|
|
64
|
+
const snapshot = await (0, firestore_1.getDocs)(collectionRef);
|
|
62
65
|
return snapshot.docs.map((doc) => ({
|
|
63
66
|
id: doc.id,
|
|
64
67
|
...doc.data()
|
|
65
68
|
}));
|
|
66
69
|
}
|
|
67
70
|
async queryCollection(path, field, value) {
|
|
68
|
-
const collectionRef = collection(this.db, path);
|
|
69
|
-
const q = query(collectionRef, where(field, "==", value));
|
|
70
|
-
const snapshot = await getDocs(q);
|
|
71
|
+
const collectionRef = (0, firestore_1.collection)(this.db, path);
|
|
72
|
+
const q = (0, firestore_1.query)(collectionRef, (0, firestore_1.where)(field, "==", value));
|
|
73
|
+
const snapshot = await (0, firestore_1.getDocs)(q);
|
|
71
74
|
return snapshot.docs.map((doc) => ({
|
|
72
75
|
id: doc.id,
|
|
73
76
|
...doc.data()
|
|
74
77
|
}));
|
|
75
78
|
}
|
|
76
79
|
batch() {
|
|
77
|
-
return new FirestoreBatchWriter(this.db, writeBatch(this.db));
|
|
80
|
+
return new FirestoreBatchWriter(this.db, (0, firestore_1.writeBatch)(this.db));
|
|
78
81
|
}
|
|
79
82
|
}
|
|
83
|
+
exports.FirebaseFirestoreClient = FirebaseFirestoreClient;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CUSTOM_SHAPE_DIMENSIONS = exports.DEFAULT_ELEMENT_DIMENSIONS = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* Default dimensions per element type.
|
|
3
6
|
* Shared between ElementOperations and BatchOperations.
|
|
4
7
|
*/
|
|
5
|
-
|
|
8
|
+
exports.DEFAULT_ELEMENT_DIMENSIONS = {
|
|
6
9
|
rectangle: { width: 150, height: 120 },
|
|
7
10
|
text: { width: 100, height: 30 },
|
|
8
11
|
connector: { width: 0, height: 0 },
|
|
@@ -16,4 +19,4 @@ export const DEFAULT_ELEMENT_DIMENSIONS = {
|
|
|
16
19
|
/**
|
|
17
20
|
* Default dimensions for custom shapes.
|
|
18
21
|
*/
|
|
19
|
-
|
|
22
|
+
exports.DEFAULT_CUSTOM_SHAPE_DIMENSIONS = { width: 100, height: 100 };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PermissionError = exports.ValidationError = exports.NotFoundError = exports.AuthenticationError = exports.GraphKnowledgeAPIError = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* Base error class for all API errors.
|
|
3
6
|
*/
|
|
4
|
-
|
|
7
|
+
class GraphKnowledgeAPIError extends Error {
|
|
5
8
|
code;
|
|
6
9
|
constructor(message, code) {
|
|
7
10
|
super(message);
|
|
@@ -9,28 +12,31 @@ export class GraphKnowledgeAPIError extends Error {
|
|
|
9
12
|
this.name = "GraphKnowledgeAPIError";
|
|
10
13
|
}
|
|
11
14
|
}
|
|
15
|
+
exports.GraphKnowledgeAPIError = GraphKnowledgeAPIError;
|
|
12
16
|
/**
|
|
13
17
|
* Thrown when authentication fails or user is not authenticated.
|
|
14
18
|
*/
|
|
15
|
-
|
|
19
|
+
class AuthenticationError extends GraphKnowledgeAPIError {
|
|
16
20
|
constructor(message) {
|
|
17
21
|
super(message, "AUTH_ERROR");
|
|
18
22
|
this.name = "AuthenticationError";
|
|
19
23
|
}
|
|
20
24
|
}
|
|
25
|
+
exports.AuthenticationError = AuthenticationError;
|
|
21
26
|
/**
|
|
22
27
|
* Thrown when a requested resource is not found.
|
|
23
28
|
*/
|
|
24
|
-
|
|
29
|
+
class NotFoundError extends GraphKnowledgeAPIError {
|
|
25
30
|
constructor(message) {
|
|
26
31
|
super(message, "NOT_FOUND");
|
|
27
32
|
this.name = "NotFoundError";
|
|
28
33
|
}
|
|
29
34
|
}
|
|
35
|
+
exports.NotFoundError = NotFoundError;
|
|
30
36
|
/**
|
|
31
37
|
* Thrown when input validation fails.
|
|
32
38
|
*/
|
|
33
|
-
|
|
39
|
+
class ValidationError extends GraphKnowledgeAPIError {
|
|
34
40
|
field;
|
|
35
41
|
details;
|
|
36
42
|
constructor(message, field, details) {
|
|
@@ -40,12 +46,14 @@ export class ValidationError extends GraphKnowledgeAPIError {
|
|
|
40
46
|
this.name = "ValidationError";
|
|
41
47
|
}
|
|
42
48
|
}
|
|
49
|
+
exports.ValidationError = ValidationError;
|
|
43
50
|
/**
|
|
44
51
|
* Thrown when the user lacks permission to perform an operation.
|
|
45
52
|
*/
|
|
46
|
-
|
|
53
|
+
class PermissionError extends GraphKnowledgeAPIError {
|
|
47
54
|
constructor(message) {
|
|
48
55
|
super(message, "PERMISSION_DENIED");
|
|
49
56
|
this.name = "PermissionError";
|
|
50
57
|
}
|
|
51
58
|
}
|
|
59
|
+
exports.PermissionError = PermissionError;
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphKnowledgeAPI = void 0;
|
|
4
|
+
const app_1 = require("firebase/app");
|
|
5
|
+
const auth_1 = require("firebase/auth");
|
|
6
|
+
const firestore_1 = require("firebase/firestore");
|
|
7
|
+
const firebase_auth_client_1 = require("./clients/firebase-auth-client");
|
|
8
|
+
const firebase_firestore_client_1 = require("./clients/firebase-firestore-client");
|
|
9
|
+
const document_operations_1 = require("./operations/document-operations");
|
|
10
|
+
const node_operations_1 = require("./operations/node-operations");
|
|
11
|
+
const element_operations_1 = require("./operations/element-operations");
|
|
12
|
+
const batch_operations_1 = require("./operations/batch-operations");
|
|
13
|
+
const document_validator_1 = require("./validators/document-validator");
|
|
14
|
+
const node_validator_1 = require("./validators/node-validator");
|
|
15
|
+
const element_validator_registry_1 = require("./validators/element-validator-registry");
|
|
13
16
|
/**
|
|
14
17
|
* Main entry point for the Graph Knowledge Headless API.
|
|
15
18
|
*
|
|
@@ -45,7 +48,7 @@ import { ElementValidatorRegistry } from "./validators/element-validator-registr
|
|
|
45
48
|
* });
|
|
46
49
|
* ```
|
|
47
50
|
*/
|
|
48
|
-
|
|
51
|
+
class GraphKnowledgeAPI {
|
|
49
52
|
app;
|
|
50
53
|
auth;
|
|
51
54
|
db;
|
|
@@ -60,21 +63,21 @@ export class GraphKnowledgeAPI {
|
|
|
60
63
|
*/
|
|
61
64
|
constructor(config) {
|
|
62
65
|
// Initialize Firebase
|
|
63
|
-
this.app = initializeApp(config.firebaseConfig, config.appName ?? `graph-knowledge-api-${Date.now()}`);
|
|
64
|
-
this.auth = getAuth(this.app);
|
|
65
|
-
this.db = getFirestore(this.app);
|
|
66
|
+
this.app = (0, app_1.initializeApp)(config.firebaseConfig, config.appName ?? `graph-knowledge-api-${Date.now()}`);
|
|
67
|
+
this.auth = (0, auth_1.getAuth)(this.app);
|
|
68
|
+
this.db = (0, firestore_1.getFirestore)(this.app);
|
|
66
69
|
// Create clients
|
|
67
|
-
const firestoreClient = new FirebaseFirestoreClient(this.db);
|
|
68
|
-
this._authClient = new FirebaseAuthClient(this.auth, this.db);
|
|
70
|
+
const firestoreClient = new firebase_firestore_client_1.FirebaseFirestoreClient(this.db);
|
|
71
|
+
this._authClient = new firebase_auth_client_1.FirebaseAuthClient(this.auth, this.db);
|
|
69
72
|
// Create validators
|
|
70
|
-
const documentValidator = new DocumentValidator();
|
|
71
|
-
const nodeValidator = new NodeValidator();
|
|
72
|
-
const elementValidatorRegistry = new ElementValidatorRegistry();
|
|
73
|
+
const documentValidator = new document_validator_1.DocumentValidator();
|
|
74
|
+
const nodeValidator = new node_validator_1.NodeValidator();
|
|
75
|
+
const elementValidatorRegistry = new element_validator_registry_1.ElementValidatorRegistry();
|
|
73
76
|
// Create operations (dependency injection)
|
|
74
|
-
this._documents = new DocumentOperations(firestoreClient, this._authClient, documentValidator);
|
|
75
|
-
this._nodes = new NodeOperations(firestoreClient, this._authClient, nodeValidator);
|
|
76
|
-
this._elements = new ElementOperations(firestoreClient, this._authClient, elementValidatorRegistry);
|
|
77
|
-
this._batch = new BatchOperations(firestoreClient, this._authClient, elementValidatorRegistry);
|
|
77
|
+
this._documents = new document_operations_1.DocumentOperations(firestoreClient, this._authClient, documentValidator);
|
|
78
|
+
this._nodes = new node_operations_1.NodeOperations(firestoreClient, this._authClient, nodeValidator);
|
|
79
|
+
this._elements = new element_operations_1.ElementOperations(firestoreClient, this._authClient, elementValidatorRegistry);
|
|
80
|
+
this._batch = new batch_operations_1.BatchOperations(firestoreClient, this._authClient, elementValidatorRegistry);
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
80
83
|
* Authentication client for sign-in/sign-out operations.
|
|
@@ -152,3 +155,4 @@ export class GraphKnowledgeAPI {
|
|
|
152
155
|
return this._authClient.requirePremium();
|
|
153
156
|
}
|
|
154
157
|
}
|
|
158
|
+
exports.GraphKnowledgeAPI = GraphKnowledgeAPI;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Domain models bundled for npm package self-containment.
|
|
3
4
|
* These are copies of the types from @graph-knowledge/domain.
|
|
4
5
|
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.CURRENT_DOCUMENT_SCHEMA_VERSION = void 0;
|
|
5
8
|
/**
|
|
6
9
|
* Current document schema version.
|
|
7
10
|
* Increment this when making breaking changes to Document, GraphNode, or GraphElement structure.
|
|
@@ -10,4 +13,4 @@
|
|
|
10
13
|
* - 0: Legacy documents (no schemaVersion field)
|
|
11
14
|
* - 1: Initial versioned schema (added schemaVersion tracking)
|
|
12
15
|
*/
|
|
13
|
-
|
|
16
|
+
exports.CURRENT_DOCUMENT_SCHEMA_VERSION = 1;
|
package/src/lib/models/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CURRENT_DOCUMENT_SCHEMA_VERSION = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* Domain models bundled for npm package.
|
|
3
6
|
* Re-exports types needed by the API.
|
|
4
7
|
*/
|
|
5
|
-
|
|
8
|
+
var document_model_1 = require("./document.model");
|
|
9
|
+
Object.defineProperty(exports, "CURRENT_DOCUMENT_SCHEMA_VERSION", { enumerable: true, get: function () { return document_model_1.CURRENT_DOCUMENT_SCHEMA_VERSION; } });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphElement } from "
|
|
1
|
+
import { GraphElement } from "../models";
|
|
2
2
|
import { IBatchOperations, BatchUpdateElementInput } from "../interfaces/batch-operations.interface";
|
|
3
3
|
import { IFirestoreClient } from "../interfaces/firestore-client.interface";
|
|
4
4
|
import { IAuthClient } from "../interfaces/auth-client.interface";
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BatchOperations = void 0;
|
|
4
|
+
const uuid_1 = require("../utils/uuid");
|
|
5
|
+
const api_errors_1 = require("../errors/api-errors");
|
|
6
|
+
const element_defaults_1 = require("../constants/element-defaults");
|
|
4
7
|
/**
|
|
5
8
|
* Implementation of batch element operations.
|
|
6
9
|
*/
|
|
7
|
-
|
|
10
|
+
class BatchOperations {
|
|
8
11
|
firestore;
|
|
9
12
|
auth;
|
|
10
13
|
validatorRegistry;
|
|
@@ -29,7 +32,7 @@ export class BatchOperations {
|
|
|
29
32
|
const nodePath = `documents/${documentId}/nodes/${nodeId}`;
|
|
30
33
|
const node = await this.firestore.getDocument(nodePath);
|
|
31
34
|
if (!node) {
|
|
32
|
-
throw new NotFoundError(`Node ${nodeId} not found`);
|
|
35
|
+
throw new api_errors_1.NotFoundError(`Node ${nodeId} not found`);
|
|
33
36
|
}
|
|
34
37
|
// Build all elements
|
|
35
38
|
const newElements = inputs.map((input) => {
|
|
@@ -37,7 +40,7 @@ export class BatchOperations {
|
|
|
37
40
|
const x = input.x ?? 0;
|
|
38
41
|
const y = input.y ?? 0;
|
|
39
42
|
const element = {
|
|
40
|
-
id: generateUuid(),
|
|
43
|
+
id: (0, uuid_1.generateUuid)(),
|
|
41
44
|
elementType: input.type,
|
|
42
45
|
x,
|
|
43
46
|
y,
|
|
@@ -69,7 +72,7 @@ export class BatchOperations {
|
|
|
69
72
|
const nodePath = `documents/${documentId}/nodes/${nodeId}`;
|
|
70
73
|
const node = await this.firestore.getDocument(nodePath);
|
|
71
74
|
if (!node) {
|
|
72
|
-
throw new NotFoundError(`Node ${nodeId} not found`);
|
|
75
|
+
throw new api_errors_1.NotFoundError(`Node ${nodeId} not found`);
|
|
73
76
|
}
|
|
74
77
|
// Create a map for quick lookup
|
|
75
78
|
const updateMap = new Map(updates.map((u) => [u.elementId, u]));
|
|
@@ -77,7 +80,7 @@ export class BatchOperations {
|
|
|
77
80
|
for (const update of updates) {
|
|
78
81
|
const exists = node.elements.some((e) => e.id === update.elementId);
|
|
79
82
|
if (!exists) {
|
|
80
|
-
throw new NotFoundError(`Element ${update.elementId} not found`);
|
|
83
|
+
throw new api_errors_1.NotFoundError(`Element ${update.elementId} not found`);
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
86
|
// Apply all updates
|
|
@@ -127,7 +130,7 @@ export class BatchOperations {
|
|
|
127
130
|
const nodePath = `documents/${documentId}/nodes/${nodeId}`;
|
|
128
131
|
const node = await this.firestore.getDocument(nodePath);
|
|
129
132
|
if (!node) {
|
|
130
|
-
throw new NotFoundError(`Node ${nodeId} not found`);
|
|
133
|
+
throw new api_errors_1.NotFoundError(`Node ${nodeId} not found`);
|
|
131
134
|
}
|
|
132
135
|
const idsToDelete = new Set(elementIds);
|
|
133
136
|
const updatedElements = node.elements.filter((e) => !idsToDelete.has(e.id));
|
|
@@ -140,9 +143,9 @@ export class BatchOperations {
|
|
|
140
143
|
*/
|
|
141
144
|
getDefaultDimensions(type) {
|
|
142
145
|
if (type.startsWith("custom:")) {
|
|
143
|
-
return DEFAULT_CUSTOM_SHAPE_DIMENSIONS;
|
|
146
|
+
return element_defaults_1.DEFAULT_CUSTOM_SHAPE_DIMENSIONS;
|
|
144
147
|
}
|
|
145
|
-
return (DEFAULT_ELEMENT_DIMENSIONS[type] ?? DEFAULT_CUSTOM_SHAPE_DIMENSIONS);
|
|
148
|
+
return (element_defaults_1.DEFAULT_ELEMENT_DIMENSIONS[type] ?? element_defaults_1.DEFAULT_CUSTOM_SHAPE_DIMENSIONS);
|
|
146
149
|
}
|
|
147
150
|
/**
|
|
148
151
|
* Normalizes rotation to integer in range [0, 360).
|
|
@@ -179,3 +182,4 @@ export class BatchOperations {
|
|
|
179
182
|
return props;
|
|
180
183
|
}
|
|
181
184
|
}
|
|
185
|
+
exports.BatchOperations = BatchOperations;
|