@graph-knowledge/api 0.1.2 → 0.1.3
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/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/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.3",
|
|
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;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentOperations = void 0;
|
|
4
|
+
const models_1 = require("../models");
|
|
5
|
+
const uuid_1 = require("../utils/uuid");
|
|
6
|
+
const api_errors_1 = require("../errors/api-errors");
|
|
4
7
|
// Default canvas dimensions
|
|
5
8
|
const DEFAULT_CANVAS_WIDTH = 1920;
|
|
6
9
|
const DEFAULT_CANVAS_HEIGHT = 1080;
|
|
7
10
|
/**
|
|
8
11
|
* Implementation of document CRUD operations.
|
|
9
12
|
*/
|
|
10
|
-
|
|
13
|
+
class DocumentOperations {
|
|
11
14
|
firestore;
|
|
12
15
|
auth;
|
|
13
16
|
validator;
|
|
@@ -19,8 +22,8 @@ export class DocumentOperations {
|
|
|
19
22
|
async create(input) {
|
|
20
23
|
const userId = this.auth.requireAuth();
|
|
21
24
|
this.validator.validateCreate(input);
|
|
22
|
-
const docId = generateUuid();
|
|
23
|
-
const rootNodeId = generateUuid();
|
|
25
|
+
const docId = (0, uuid_1.generateUuid)();
|
|
26
|
+
const rootNodeId = (0, uuid_1.generateUuid)();
|
|
24
27
|
const rootNode = {
|
|
25
28
|
id: rootNodeId,
|
|
26
29
|
title: input.title,
|
|
@@ -32,7 +35,7 @@ export class DocumentOperations {
|
|
|
32
35
|
owner: userId
|
|
33
36
|
};
|
|
34
37
|
const document = {
|
|
35
|
-
schemaVersion: CURRENT_DOCUMENT_SCHEMA_VERSION,
|
|
38
|
+
schemaVersion: models_1.CURRENT_DOCUMENT_SCHEMA_VERSION,
|
|
36
39
|
title: input.title,
|
|
37
40
|
content: input.content ?? "",
|
|
38
41
|
owner: userId,
|
|
@@ -56,7 +59,7 @@ export class DocumentOperations {
|
|
|
56
59
|
this.auth.requireAuth();
|
|
57
60
|
const docData = await this.firestore.getDocument(`documents/${documentId}`);
|
|
58
61
|
if (!docData) {
|
|
59
|
-
throw new NotFoundError(`Document ${documentId} not found`);
|
|
62
|
+
throw new api_errors_1.NotFoundError(`Document ${documentId} not found`);
|
|
60
63
|
}
|
|
61
64
|
const nodes = await this.firestore.getCollection(`documents/${documentId}/nodes`);
|
|
62
65
|
return {
|
|
@@ -78,7 +81,7 @@ export class DocumentOperations {
|
|
|
78
81
|
this.validator.validateUpdate(input);
|
|
79
82
|
const docData = await this.firestore.getDocument(`documents/${documentId}`);
|
|
80
83
|
if (!docData) {
|
|
81
|
-
throw new NotFoundError(`Document ${documentId} not found`);
|
|
84
|
+
throw new api_errors_1.NotFoundError(`Document ${documentId} not found`);
|
|
82
85
|
}
|
|
83
86
|
const updates = {};
|
|
84
87
|
if (input.title !== undefined)
|
|
@@ -99,10 +102,11 @@ export class DocumentOperations {
|
|
|
99
102
|
this.auth.requireAuth();
|
|
100
103
|
const docData = await this.firestore.getDocument(`documents/${documentId}`);
|
|
101
104
|
if (!docData) {
|
|
102
|
-
throw new NotFoundError(`Document ${documentId} not found`);
|
|
105
|
+
throw new api_errors_1.NotFoundError(`Document ${documentId} not found`);
|
|
103
106
|
}
|
|
104
107
|
await this.firestore.updateDocument(`documents/${documentId}`, {
|
|
105
108
|
sharedWith: userIds
|
|
106
109
|
});
|
|
107
110
|
}
|
|
108
111
|
}
|
|
112
|
+
exports.DocumentOperations = DocumentOperations;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphElement } from "
|
|
1
|
+
import { GraphElement } from "../models";
|
|
2
2
|
import { IElementOperations } from "../interfaces/element-operations.interface";
|
|
3
3
|
import { IFirestoreClient } from "../interfaces/firestore-client.interface";
|
|
4
4
|
import { IAuthClient } from "../interfaces/auth-client.interface";
|