dbm-graph-api 1.1.13 → 1.1.15
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 +2 -2
- package/src/dbm-graph-api/action/admin/index.js +3 -1
- package/src/dbm-graph-api/action/admin/setup/SetupOrganization.js +48 -0
- package/src/dbm-graph-api/action/admin/setup/SetupWebsite.js +29 -0
- package/src/dbm-graph-api/action/admin/setup/index.js +2 -0
- package/src/dbm-graph-api/data/Question.js +94 -0
- package/src/dbm-graph-api/data/index.js +1 -0
- package/src/dbm-graph-api/index.js +49 -6
- package/src/dbm-graph-api/range/encode/HelpSection.js +21 -0
- package/src/dbm-graph-api/range/encode/UrlRequest.js +2 -0
- package/src/dbm-graph-api/range/encode/admin/Fields.js +22 -0
- package/src/dbm-graph-api/range/encode/admin/index.js +1 -0
- package/src/dbm-graph-api/range/encode/index.js +4 -1
- package/src/dbm-graph-api/range/select/GlobalObjectRelationQuery.js +41 -0
- package/src/dbm-graph-api/range/select/index.js +2 -1
- package/src/dbm-graph-api/schema/JsonLdGenerator.js +191 -0
- package/src/dbm-graph-api/schema/index.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbm-graph-api",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@aws-sdk/client-s3": "^3.741.0",
|
|
15
15
|
"@aws-sdk/s3-request-presigner": "^3.741.0",
|
|
16
|
-
"dbm": "^1.1.
|
|
16
|
+
"dbm": "^1.1.11",
|
|
17
17
|
"mime": "^4.0.6",
|
|
18
18
|
"sharp": "^0.33.5",
|
|
19
19
|
"ws": "^8.18.0"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
|
|
3
|
+
export default class SetupOrganization extends Dbm.core.BaseObject {
|
|
4
|
+
_construct() {
|
|
5
|
+
super._construct();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async performAction(aData, aEncodeSession) {
|
|
9
|
+
let returnObject = {};
|
|
10
|
+
|
|
11
|
+
let user = await aEncodeSession.outputController.getUser();
|
|
12
|
+
|
|
13
|
+
if(user) {
|
|
14
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
let website = await database.getGlobalObject("website");
|
|
18
|
+
|
|
19
|
+
if(website) {
|
|
20
|
+
let organization = await website.singleObjectRelationQuery("out:by:organization");
|
|
21
|
+
if(!organization) {
|
|
22
|
+
organization = await database.createObject("private", ["organization"]);
|
|
23
|
+
await website.addOutgoingRelation(organization, "by");
|
|
24
|
+
|
|
25
|
+
let localBusiness = await database.createObject("private", ["localBusiness"]);
|
|
26
|
+
await organization.addIncomingRelation(localBusiness, "in");
|
|
27
|
+
|
|
28
|
+
let location = await database.createObject("private", ["location"]);
|
|
29
|
+
await location.updateField("name", "Local business location");
|
|
30
|
+
localBusiness.addOutgoingRelation(location, "at");
|
|
31
|
+
|
|
32
|
+
let schemaSubtype = "LocalBusiness";
|
|
33
|
+
if(aData["localBusinessType"]) {
|
|
34
|
+
schemaSubtype = aData["localBusinessType"]
|
|
35
|
+
}
|
|
36
|
+
let schemaType = await database.getTypeObject("schema/type", schemaSubtype);
|
|
37
|
+
localBusiness.addIncomingRelation(schemaType, "for");
|
|
38
|
+
|
|
39
|
+
returnObject["localBusinessId"] = localBusiness.id;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
returnObject["websiteId"] = website.id;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return returnObject;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
|
|
3
|
+
export default class SetupWebsite extends Dbm.core.BaseObject {
|
|
4
|
+
_construct() {
|
|
5
|
+
super._construct();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async performAction(aData, aEncodeSession) {
|
|
9
|
+
let returnObject = {};
|
|
10
|
+
|
|
11
|
+
let user = await aEncodeSession.outputController.getUser();
|
|
12
|
+
|
|
13
|
+
if(user) {
|
|
14
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
15
|
+
|
|
16
|
+
let globalObject = await database.getIdentifiableObject("globalObject", "website");
|
|
17
|
+
|
|
18
|
+
let website = await globalObject.singleObjectRelationQuery("out:pointingTo:*");
|
|
19
|
+
if(!website) {
|
|
20
|
+
website = await database.createObject("private", ["website"]);
|
|
21
|
+
await globalObject.addOutgoingRelation(website, "pointingTo");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
returnObject["id"] = website.id;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return returnObject;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
import DbmGraphApi from "../../../index.js";
|
|
3
|
+
|
|
4
|
+
export default class Question extends Dbm.core.BaseObject {
|
|
5
|
+
_construct() {
|
|
6
|
+
super._construct();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getData(aData, aEncodeSession) {
|
|
10
|
+
let returnObject = {};
|
|
11
|
+
|
|
12
|
+
let question = aData["value"];
|
|
13
|
+
returnObject["question"] = question;
|
|
14
|
+
|
|
15
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
16
|
+
let questionItem = await database.createObject("private", ["customerQuestion"]);
|
|
17
|
+
await questionItem.updateField("question", question);
|
|
18
|
+
returnObject["id"] = questionItem.id;
|
|
19
|
+
|
|
20
|
+
let selectQuery = new DbmGraphApi.range.Query();
|
|
21
|
+
await selectQuery.setObjectType("helpSection");
|
|
22
|
+
selectQuery.includePrivate();
|
|
23
|
+
let items = await selectQuery.getObjects();
|
|
24
|
+
|
|
25
|
+
let currentArray = items;
|
|
26
|
+
let currentArrayLength = currentArray.length;
|
|
27
|
+
let helpPages = new Array(currentArrayLength);
|
|
28
|
+
|
|
29
|
+
for(let i = 0; i < currentArrayLength; i++) {
|
|
30
|
+
let currentItem = currentArray[i];
|
|
31
|
+
let fields = await currentItem.getFields();
|
|
32
|
+
|
|
33
|
+
let codedObject = {id: currentItem.id, content: fields.title};
|
|
34
|
+
helpPages[i] = codedObject;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let helpPagesString = JSON.stringify(helpPages);
|
|
38
|
+
|
|
39
|
+
console.log(helpPages);
|
|
40
|
+
|
|
41
|
+
let instructions = "Find out which the best help pages for the question and return the id from this json: {data}. {additionalInstructions} Respond with only a json object {hasMatch: boolean, pages: array with ids of the pages (in order of relevance)}, no markdown.";
|
|
42
|
+
instructions = instructions.split("{data}").join(helpPagesString);
|
|
43
|
+
|
|
44
|
+
let additionalInstructions = "Units are stored in square feet, so convert square meters to feet.";
|
|
45
|
+
instructions = instructions.split("{additionalInstructions}").join(additionalInstructions);
|
|
46
|
+
|
|
47
|
+
let body = {
|
|
48
|
+
"model": "gpt-4o-mini",
|
|
49
|
+
"response_format": { "type": "json_object" },
|
|
50
|
+
"messages": [
|
|
51
|
+
{"role":"system","content": instructions},
|
|
52
|
+
{"role": "user", "content": question}
|
|
53
|
+
],
|
|
54
|
+
"temperature": 0.7
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let headers = {
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
'Authorization': 'Bearer ' + Dbm.getInstance().repository.getItem("openAi").token
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let response = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: headers,
|
|
65
|
+
body: JSON.stringify(body),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
let data = await response.json();
|
|
69
|
+
await questionItem.updateField("response", data);
|
|
70
|
+
|
|
71
|
+
let message = data.choices[0].message;
|
|
72
|
+
let content = JSON.parse(message.content);
|
|
73
|
+
console.log(content);
|
|
74
|
+
|
|
75
|
+
let pages = [];
|
|
76
|
+
{
|
|
77
|
+
let currentArray = content.pages;
|
|
78
|
+
let currentArrayLength = currentArray.length;
|
|
79
|
+
for(let i = 0; i < currentArrayLength; i++) {
|
|
80
|
+
let currentId = 1*currentArray[i];
|
|
81
|
+
|
|
82
|
+
if(!isNaN(currentId)) {
|
|
83
|
+
pages.push(currentId);
|
|
84
|
+
await aEncodeSession.encodeSingle(currentId, "helpSection");
|
|
85
|
+
await questionItem.addIncomingRelation(currentId, "suggestedFor");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
returnObject["answers"] = pages;
|
|
91
|
+
|
|
92
|
+
return returnObject;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -4,6 +4,7 @@ export {default as FreeUrl} from "./FreeUrl.js";
|
|
|
4
4
|
export {default as SeoSummary} from "./SeoSummary.js";
|
|
5
5
|
export {default as AltText} from "./AltText.js";
|
|
6
6
|
export {default as Breadcrumb} from "./Breadcrumb.js";
|
|
7
|
+
export {default as Question} from "./Question.js";
|
|
7
8
|
|
|
8
9
|
export * as server from "./server/index.js";
|
|
9
10
|
|
|
@@ -18,6 +18,7 @@ export * as data from "./data/index.js";
|
|
|
18
18
|
export * as action from "./action/index.js";
|
|
19
19
|
export * as processAction from "./processAction/index.js";
|
|
20
20
|
export * as taskrunner from "./taskrunner/index.js";
|
|
21
|
+
export * as schema from "./schema/index.js";
|
|
21
22
|
|
|
22
23
|
let fullSelectSetup = function() {
|
|
23
24
|
let selectPrefix = "graphApi/range/select/";
|
|
@@ -50,6 +51,12 @@ let fullSelectSetup = function() {
|
|
|
50
51
|
let currentSelect = new DbmGraphApi.range.select.ObjectRelationQuery();
|
|
51
52
|
currentSelect.item.register(selectPrefix + name);
|
|
52
53
|
}
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
let name = "globalObjectRelationQuery";
|
|
57
|
+
let currentSelect = new DbmGraphApi.range.select.GlobalObjectRelationQuery();
|
|
58
|
+
currentSelect.item.register(selectPrefix + name);
|
|
59
|
+
}
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
export {fullSelectSetup};
|
|
@@ -167,6 +174,20 @@ let fullEncodeSetup = function() {
|
|
|
167
174
|
currentEncode.item.register(encodePrefix + name);
|
|
168
175
|
currentEncode.item.setValue("encodingType", name);
|
|
169
176
|
}
|
|
177
|
+
|
|
178
|
+
{
|
|
179
|
+
let name = "admin_fields";
|
|
180
|
+
let currentEncode = new DbmGraphApi.range.encode.admin.Fields();
|
|
181
|
+
currentEncode.item.register(encodePrefix + name);
|
|
182
|
+
currentEncode.item.setValue("encodingType", name);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
{
|
|
186
|
+
let name = "helpSection";
|
|
187
|
+
let currentEncode = new DbmGraphApi.range.encode.HelpSection();
|
|
188
|
+
currentEncode.item.register(encodePrefix + name);
|
|
189
|
+
currentEncode.item.setValue("encodingType", name);
|
|
190
|
+
}
|
|
170
191
|
}
|
|
171
192
|
|
|
172
193
|
export {fullEncodeSetup};
|
|
@@ -183,6 +204,7 @@ let fullDataSetup = function() {
|
|
|
183
204
|
registerDataFunction("example", new DbmGraphApi.data.Example());
|
|
184
205
|
|
|
185
206
|
registerDataFunction("breadcrumb", new DbmGraphApi.data.Breadcrumb());
|
|
207
|
+
registerDataFunction("question", new DbmGraphApi.data.Question());
|
|
186
208
|
|
|
187
209
|
registerDataFunction("admin/freeUrl", new DbmGraphApi.data.FreeUrl());
|
|
188
210
|
registerDataFunction("admin/seoSummary", new DbmGraphApi.data.SeoSummary());
|
|
@@ -207,6 +229,9 @@ let fullActionSetup = function() {
|
|
|
207
229
|
registerActionFunction("cron/processActions", new DbmGraphApi.action.cron.ProcessActions());
|
|
208
230
|
registerActionFunction("admin/addAndProcessAction", new DbmGraphApi.action.admin.AddAndProcessAction());
|
|
209
231
|
|
|
232
|
+
registerActionFunction("admin/setup/setupWebsite", new DbmGraphApi.action.admin.setup.SetupWebsite());
|
|
233
|
+
registerActionFunction("admin/setup/setupOrganization", new DbmGraphApi.action.admin.setup.SetupOrganization());
|
|
234
|
+
|
|
210
235
|
registerActionFunction("development/restartServer", new DbmGraphApi.action.development.RestartServer());
|
|
211
236
|
registerActionFunction("development/restartDatabaseConnection", new DbmGraphApi.action.development.RestartDatabaseConnection());
|
|
212
237
|
}
|
|
@@ -541,6 +566,10 @@ export const setupSite = function(aServer) {
|
|
|
541
566
|
let url = await databaseObject.getUrl();
|
|
542
567
|
if(url) {
|
|
543
568
|
let fields = await databaseObject.getFields();
|
|
569
|
+
|
|
570
|
+
if(fields["seo/noIndex"]) {
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
544
573
|
|
|
545
574
|
response += ' <url>\n';
|
|
546
575
|
response += ' <loc>' + fullUrl + url + '</loc>\n';
|
|
@@ -673,13 +702,31 @@ export const setupSite = function(aServer) {
|
|
|
673
702
|
if(fields["seo/noIndex"]) {
|
|
674
703
|
robotsSettings[0] = "noindex";
|
|
675
704
|
}
|
|
676
|
-
if(fields["seo/
|
|
705
|
+
if(fields["seo/noFollow"]) {
|
|
677
706
|
robotsSettings[1] = "nofollow";
|
|
678
707
|
}
|
|
679
708
|
|
|
680
709
|
let content = robotsSettings.join(", ");
|
|
681
710
|
returnString += `<meta name="robots" content="${content}" />`;
|
|
682
711
|
}
|
|
712
|
+
|
|
713
|
+
let baseUrl = request.protocol + "://" + request.hostname;
|
|
714
|
+
if(request.port && request.port !== 80 && request.port !== 443) {
|
|
715
|
+
baseUrl += ":" + request.port;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
let schemaGenrator = new DbmGraphApi.schema.JsonLdGenerator();
|
|
719
|
+
schemaGenrator.baseUrl = baseUrl;
|
|
720
|
+
let schemaMarkup = await schemaGenrator.getWebsiteEntites();
|
|
721
|
+
schemaMarkup = schemaMarkup.concat(await schemaGenrator.getPageEntites(urlObject))
|
|
722
|
+
let encodedMarkup = JSON.stringify(schemaMarkup, null, 2);
|
|
723
|
+
|
|
724
|
+
returnString += `<script type="application/ld+json">
|
|
725
|
+
{
|
|
726
|
+
"@context": "https://schema.org",
|
|
727
|
+
"@graph": ${encodedMarkup}
|
|
728
|
+
}
|
|
729
|
+
</script>`;
|
|
683
730
|
|
|
684
731
|
returnString += `<title>${fields.title} - ${siteName}</title>
|
|
685
732
|
|
|
@@ -707,11 +754,7 @@ export const setupSite = function(aServer) {
|
|
|
707
754
|
`;
|
|
708
755
|
}
|
|
709
756
|
|
|
710
|
-
let fullUrl =
|
|
711
|
-
if(request.port && request.port !== 80 && request.port !== 443) {
|
|
712
|
-
fullUrl += ":" + request.port;
|
|
713
|
-
}
|
|
714
|
-
fullUrl += url;
|
|
757
|
+
let fullUrl = baseUrl + url;
|
|
715
758
|
|
|
716
759
|
returnString += `
|
|
717
760
|
<link rel="canonical" href="${fullUrl}" />
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
import EncodeBaseObject from "./EncodeBaseObject.js";
|
|
3
|
+
|
|
4
|
+
export default class HelpSection extends EncodeBaseObject {
|
|
5
|
+
_construct() {
|
|
6
|
+
super._construct();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getEncodedData(aId, aEncodingSession) {
|
|
10
|
+
|
|
11
|
+
let returnObject = {};
|
|
12
|
+
|
|
13
|
+
let object = Dbm.getInstance().repository.getItem("graphDatabase").controller.getObject(aId);
|
|
14
|
+
|
|
15
|
+
let fields = await object.getFields();
|
|
16
|
+
returnObject["title"] = fields["title"] !== null ? fields["title"] : null;
|
|
17
|
+
returnObject["link"] = fields["link"] !== null ? fields["link"] : null;
|
|
18
|
+
|
|
19
|
+
return returnObject;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -21,6 +21,8 @@ export default class UrlRequest extends EncodeBaseObject {
|
|
|
21
21
|
|
|
22
22
|
let fields = await object.getFields();
|
|
23
23
|
returnObject["meta/description"] = fields["meta/description"] ? fields["meta/description"] : null;
|
|
24
|
+
returnObject["seo/noIndex"] = fields["seo/noIndex"] ? fields["seo/noIndex"] : false;
|
|
25
|
+
returnObject["seo/noFollow"] = fields["seo/noFollow"] ? fields["seo/noFollow"] : false;
|
|
24
26
|
|
|
25
27
|
return returnObject;
|
|
26
28
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
import EncodeBaseObject from "../EncodeBaseObject.js";
|
|
3
|
+
|
|
4
|
+
export default class Fields extends EncodeBaseObject {
|
|
5
|
+
_construct() {
|
|
6
|
+
super._construct();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getEncodedData(aId, aEncodingSession) {
|
|
10
|
+
|
|
11
|
+
let returnObject = {};
|
|
12
|
+
|
|
13
|
+
await aEncodingSession.outputController.requireRole("admin");
|
|
14
|
+
|
|
15
|
+
let object = Dbm.getInstance().repository.getItem("graphDatabase").controller.getObject(aId);
|
|
16
|
+
|
|
17
|
+
let fields = await object.getFields();
|
|
18
|
+
returnObject["fields"] = fields;
|
|
19
|
+
|
|
20
|
+
return returnObject;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default as Fields} from "./Fields.js";
|
|
@@ -15,4 +15,7 @@ export {default as Visibility} from "./Visibility.js";
|
|
|
15
15
|
export {default as Relations} from "./Relations.js";
|
|
16
16
|
export {default as ObjectTypes} from "./ObjectTypes.js";
|
|
17
17
|
export {default as RepresentingPage} from "./RepresentingPage.js";
|
|
18
|
-
export {default as PageRepresentation} from "./PageRepresentation.js";
|
|
18
|
+
export {default as PageRepresentation} from "./PageRepresentation.js";
|
|
19
|
+
export {default as HelpSection} from "./HelpSection.js";
|
|
20
|
+
|
|
21
|
+
export * as admin from "./admin/index.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
|
|
3
|
+
import SelectBaseObject from "./SelectBaseObject.js";
|
|
4
|
+
|
|
5
|
+
export default class GlobalObjectRelationQuery extends SelectBaseObject {
|
|
6
|
+
_construct() {
|
|
7
|
+
super._construct();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async select(aQuery, aData, aRequest) {
|
|
11
|
+
//console.log("ObjectRelationQuery::select");
|
|
12
|
+
|
|
13
|
+
if(!aData["path"]) {
|
|
14
|
+
throw("Parameter path not set");
|
|
15
|
+
}
|
|
16
|
+
if(!aData["identifer"]) {
|
|
17
|
+
throw("Parameter identifer not set");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
21
|
+
|
|
22
|
+
let globalObject = await database.getGlobalObject(aData["identifer"]);
|
|
23
|
+
|
|
24
|
+
let fromIds = globalObject ? [globalObject.id] : [];
|
|
25
|
+
|
|
26
|
+
let ids;
|
|
27
|
+
if(aData["path"] === "(root)") {
|
|
28
|
+
ids = fromIds;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
ids = await database.objectRelationQuery(fromIds, aData["path"]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(ids);
|
|
35
|
+
await aQuery.includeOnly(ids);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async filter(aIds, aData, aRequest) {
|
|
39
|
+
return aIds;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -3,4 +3,5 @@ export {default as IdSelection} from "./IdSelection.js";
|
|
|
3
3
|
export {default as ByObjectType} from "./ByObjectType.js";
|
|
4
4
|
export {default as IncludePrivate} from "./IncludePrivate.js";
|
|
5
5
|
export {default as IncludeDraft} from "./IncludeDraft.js";
|
|
6
|
-
export {default as ObjectRelationQuery} from "./ObjectRelationQuery.js";
|
|
6
|
+
export {default as ObjectRelationQuery} from "./ObjectRelationQuery.js";
|
|
7
|
+
export {default as GlobalObjectRelationQuery} from "./GlobalObjectRelationQuery.js";
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import Dbm from "dbm";
|
|
2
|
+
|
|
3
|
+
export default class JsonLdGenerator extends Dbm.core.BaseObject{
|
|
4
|
+
|
|
5
|
+
_construct() {
|
|
6
|
+
super._construct();
|
|
7
|
+
|
|
8
|
+
this.baseUrl = null;
|
|
9
|
+
this.name = null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async encodeWebsiteEntity(aDatabaseObject) {
|
|
13
|
+
console.log("encodeWebsiteEntity");
|
|
14
|
+
|
|
15
|
+
let site = Dbm.getInstance().repository.getItem("site");
|
|
16
|
+
let fields = await aDatabaseObject.getFields();
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
"@type": "WebSite",
|
|
20
|
+
"@id": this.baseUrl + "/" + "#website",
|
|
21
|
+
"url": this.baseUrl + "/",
|
|
22
|
+
"name": fields["name"] ? fields["name"] : site.name,
|
|
23
|
+
"publisher": {
|
|
24
|
+
"@id": this.baseUrl + "/" + "#organization"
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async encodeOrganizationEntity(aDatabaseObject) {
|
|
30
|
+
console.log("encodeOrganizationEntity");
|
|
31
|
+
|
|
32
|
+
let site = Dbm.getInstance().repository.getItem("site");
|
|
33
|
+
let fields = await aDatabaseObject.getFields();
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
"@type": "Organization",
|
|
37
|
+
"@id": this.baseUrl + "/" + "#organization",
|
|
38
|
+
"url": this.baseUrl + "/",
|
|
39
|
+
"name": fields["name"] ? fields["name"] : site.name,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//Logo
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async encodeLocalBusiness(aDatabaseObject) {
|
|
46
|
+
|
|
47
|
+
let site = Dbm.getInstance().repository.getItem("site");
|
|
48
|
+
|
|
49
|
+
let type = await aDatabaseObject.singleObjectRelationQuery("in:for:schema/type");
|
|
50
|
+
let typeName = await type.getIdentifier();
|
|
51
|
+
let fields = await aDatabaseObject.getFields();
|
|
52
|
+
|
|
53
|
+
let returnObject = {
|
|
54
|
+
"@type": typeName,
|
|
55
|
+
"@id": this.baseUrl + "/" + "#local-business",
|
|
56
|
+
"url": this.baseUrl + "/",
|
|
57
|
+
"name": fields["name"] ? fields["name"] : site.name,
|
|
58
|
+
"telephone": fields["phoneNumber"],
|
|
59
|
+
"email": fields["email"],
|
|
60
|
+
"priceRange": fields["priceRangeDescription"],
|
|
61
|
+
"parentOrganization": {
|
|
62
|
+
"@id": this.baseUrl + "/" + "#organization"
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if(fields["rating/value"]) {
|
|
67
|
+
returnObject["aggregateRating"] = {
|
|
68
|
+
"@type": "AggregateRating",
|
|
69
|
+
"ratingValue": fields["rating/value"],
|
|
70
|
+
"reviewCount": fields["rating/count"],
|
|
71
|
+
"bestRating": fields["rating/max"] ? fields["rating/max"] : "5",
|
|
72
|
+
"worstRating": fields["rating/min"] ? fields["rating/min"] : "1",
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let location = await aDatabaseObject.singleObjectRelationQuery("out:at:location");
|
|
77
|
+
|
|
78
|
+
if(location) {
|
|
79
|
+
let fields = await location.getFields();
|
|
80
|
+
|
|
81
|
+
returnObject["address"] = {
|
|
82
|
+
"@type": "PostalAddress",
|
|
83
|
+
"streetAddress": fields["street"],
|
|
84
|
+
"addressLocality": fields["city"],
|
|
85
|
+
"postalCode": fields["postCode"],
|
|
86
|
+
"addressCountry": fields["country"]
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
returnObject["geo"] = {
|
|
90
|
+
"@type": "GeoCoordinates",
|
|
91
|
+
"latitude": fields["latitude"],
|
|
92
|
+
"longitude": fields["longitude"]
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return returnObject;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getWebsiteEntites() {
|
|
100
|
+
console.log("getWebsiteEntites");
|
|
101
|
+
|
|
102
|
+
let returnArray = [];
|
|
103
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
104
|
+
|
|
105
|
+
let website = await database.getGlobalObject("website");
|
|
106
|
+
if(website) {
|
|
107
|
+
returnArray.push(await this.encodeWebsiteEntity(website));
|
|
108
|
+
|
|
109
|
+
let organization = await website.singleObjectRelationQuery("out:by:organization");
|
|
110
|
+
returnArray.push(await this.encodeOrganizationEntity(organization));
|
|
111
|
+
|
|
112
|
+
let currentArray = await website.objectRelationQuery("out:by:organization,in:in:localBusiness");
|
|
113
|
+
let currentArrayLength = currentArray.length;
|
|
114
|
+
for(let i = 0; i < currentArrayLength; i++) {
|
|
115
|
+
let currentLocalBusiness = currentArray[i];
|
|
116
|
+
returnArray.push(await this.encodeLocalBusiness(currentLocalBusiness));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return returnArray;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async getPageEntites(aPage) {
|
|
124
|
+
|
|
125
|
+
let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
|
|
126
|
+
|
|
127
|
+
let fields = await aPage.getFields();
|
|
128
|
+
let url = await aPage.getUrl();
|
|
129
|
+
let returnArray = [];
|
|
130
|
+
|
|
131
|
+
let fullUrl = this.baseUrl + url;
|
|
132
|
+
|
|
133
|
+
let pageObject = {
|
|
134
|
+
"@type": "WebPage",
|
|
135
|
+
"@id": fullUrl + "#webpage",
|
|
136
|
+
"url": fullUrl,
|
|
137
|
+
"name": fields["title"],
|
|
138
|
+
"description": fields["meta/description"],
|
|
139
|
+
"breadcrumb": {
|
|
140
|
+
"@id": fullUrl +"#breadcrumb"
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
returnArray.push(pageObject);
|
|
145
|
+
|
|
146
|
+
let urlParts = url.split("/");
|
|
147
|
+
urlParts.pop();
|
|
148
|
+
|
|
149
|
+
let breadcrumbItems = [];
|
|
150
|
+
|
|
151
|
+
let currentUrl = "";
|
|
152
|
+
let currentArray = urlParts;
|
|
153
|
+
let currentArrayLength = currentArray.length;
|
|
154
|
+
for(let i = 0; i < currentArrayLength; i++) {
|
|
155
|
+
let currentPart = currentArray[i];
|
|
156
|
+
currentUrl += currentPart + "/";
|
|
157
|
+
let urlObject = await database.getObjectByUrl(currentUrl);
|
|
158
|
+
if(urlObject) {
|
|
159
|
+
let urlObjectFields = await urlObject.getFields();
|
|
160
|
+
let encodedStep = {
|
|
161
|
+
"@type": "ListItem",
|
|
162
|
+
"position": (i+1),
|
|
163
|
+
"name": urlObjectFields["navigationName"] ? urlObjectFields["navigationName"] : urlObjectFields["title"],
|
|
164
|
+
"item": this.baseUrl + currentUrl
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
breadcrumbItems.push(encodedStep);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let breadcrumbList = {
|
|
172
|
+
"@type": "BreadcrumbList",
|
|
173
|
+
"@id": fullUrl + "#breadcrumb",
|
|
174
|
+
"itemListElement": breadcrumbItems
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
returnArray.push(breadcrumbList);
|
|
178
|
+
|
|
179
|
+
return returnArray;
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
/*
|
|
185
|
+
"primaryImageOfPage": {
|
|
186
|
+
"@id": "https://example.com/product/acme-coffee-maker#primaryimage"
|
|
187
|
+
}
|
|
188
|
+
*/
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default as JsonLdGenerator} from "./JsonLdGenerator.js";
|