dbm-graph-api 1.1.6 → 1.1.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbm-graph-api",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -14,6 +14,8 @@
14
14
  "@aws-sdk/client-s3": "^3.741.0",
15
15
  "@aws-sdk/s3-request-presigner": "^3.741.0",
16
16
  "dbm": "^1.1.4",
17
+ "mime": "^4.0.6",
18
+ "sharp": "^0.33.5",
17
19
  "ws": "^8.18.0"
18
20
  },
19
21
  "optionalDependencies": {
@@ -6,6 +6,10 @@ import DbmGraphApi from "../../index.js";
6
6
  import Api from "./Api.js";
7
7
  import UrlRequest from "./UrlRequest.js";
8
8
 
9
+ import fs from "node:fs";
10
+ import sharp from 'sharp';
11
+ import mime from 'mime';
12
+
9
13
  export {Api};
10
14
 
11
15
  export * as range from "./range/index.js";
@@ -13,6 +17,7 @@ export * as admin from "./admin/index.js";
13
17
  export * as data from "./data/index.js";
14
18
  export * as action from "./action/index.js";
15
19
  export * as processAction from "./processAction/index.js";
20
+ export * as taskrunner from "./taskrunner/index.js";
16
21
 
17
22
  let fullSelectSetup = function() {
18
23
  let selectPrefix = "graphApi/range/select/";
@@ -179,20 +184,36 @@ let fullProcessActionSetup = function() {
179
184
 
180
185
  export {fullProcessActionSetup};
181
186
 
187
+ let setupInternalTaskRunner = function() {
188
+ Dbm.getInstance().repository.getItem("taskRunner").requireProperty("runners", []);
189
+
190
+ let runner = new DbmGraphApi.taskrunner.InternalTaskRunner();
191
+ runner.startAtStartup();
192
+
193
+ let runners = [].concat(Dbm.getInstance().repository.getItem("taskRunner").runners);
194
+ runners.push(runner);
195
+ Dbm.getInstance().repository.getItem("taskRunner").runners = runners;
196
+
197
+ }
198
+
199
+ export {setupInternalTaskRunner};
200
+
201
+
182
202
  let fullSetup = function() {
183
203
 
184
204
  fullSelectSetup();
185
205
  fullEncodeSetup();
186
206
  fullDataSetup();
187
207
  fullActionSetup();
188
- fullProcessActionSetup()
208
+ fullProcessActionSetup();
209
+ setupInternalTaskRunner();
189
210
 
190
211
  DbmGraphApi.admin.edit.fullSetup();
191
212
  }
192
213
 
193
214
  export {fullSetup};
194
215
 
195
- let setupEndpoints = function(aServer) {
216
+ export const setupEndpoints = function(aServer) {
196
217
  aServer.post('/api/user/login', async function handler (aRequest, aReply) {
197
218
 
198
219
  let username = aRequest.body['username'];
@@ -399,4 +420,265 @@ let setupEndpoints = function(aServer) {
399
420
  });
400
421
  }
401
422
 
402
- export {setupEndpoints};
423
+ export const setupSite = function(aServer) {
424
+
425
+ aServer.get('/cdn-cgi/image/:options/*', async function(request, reply) {
426
+ console.log("/cdn-cgi/image/");
427
+
428
+ let publicDir = Dbm.getInstance().repository.getItem("site").publicDir;
429
+
430
+ let nextPosition = request.url.indexOf('/', "/cdn-cgi/image/".length);
431
+ let imageUrl = request.url.substring(nextPosition+1);
432
+
433
+ let realPath;
434
+ try {
435
+ realPath = fs.realpathSync(publicDir + "/" + imageUrl);
436
+ console.log(realPath);
437
+ console.log(realPath);
438
+ if(realPath.indexOf(publicDir + "/") !== 0) {
439
+ throw("Not in folder");
440
+ }
441
+
442
+ if(!fs.lstatSync(realPath).isFile()) {
443
+ throw("Not a file");
444
+ }
445
+ }
446
+ catch(theError) {
447
+ reply.code(404);
448
+ return;
449
+ }
450
+
451
+ let imageResize = sharp(realPath);
452
+
453
+ let options = {
454
+ background: {r: 0, g: 0, b: 0, alpha: 0}
455
+ };
456
+ let currentArray = request.params.options.split(",");
457
+ let currentArrayLength = currentArray.length;
458
+ for(let i = 0; i < currentArrayLength; i++) {
459
+ let tempArray = currentArray[i].split("=");
460
+ let name = tempArray[0];
461
+ switch(name) {
462
+ case "width":
463
+ case "height":
464
+ options[name] = 1*tempArray[1];
465
+ break;
466
+ default:
467
+ options[name] = tempArray[1];
468
+ }
469
+
470
+ }
471
+
472
+ imageResize.resize(options);
473
+
474
+ let image = await imageResize.toBuffer();
475
+ reply.header('Content-Type', mime.getType(realPath));
476
+ reply.send(image);
477
+ });
478
+
479
+ aServer.get('/sitemap.xml', async function(request, reply) {
480
+
481
+ let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
482
+
483
+ reply.header("Content-Type", "application/xml; charset=utf-8");
484
+
485
+ let response = '<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n';
486
+
487
+ let pages = await database.getObjectsOfType("page");
488
+
489
+ let fullUrl = request.protocol + "://" + request.hostname;
490
+ if(request.port && request.port !== 80 && request.port !== 443) {
491
+ fullUrl += ":" + request.port;
492
+ }
493
+
494
+ let currentArray = pages;
495
+ let currentArrayLength = currentArray.length;
496
+ for(let i = 0; i < currentArrayLength; i++) {
497
+ let databaseObject = currentArray[i];
498
+ let url = await databaseObject.getUrl();
499
+ if(url) {
500
+ let fields = await databaseObject.getFields();
501
+
502
+ response += ' <url>\n';
503
+ response += ' <loc>' + fullUrl + url + '</loc>\n';
504
+ if(fields["lastModified"]) {
505
+ response += ' <lastmod>' + fields["lastModified"] + '</lastmod>\n';
506
+ }
507
+ response += ' </url>\n';
508
+ }
509
+ }
510
+
511
+ response += '</urlset>';
512
+
513
+ return response;
514
+ });
515
+
516
+ aServer.get('/robots.txt', async function(request, reply) {
517
+ reply.header("Content-Type", "text/plain; charset=utf-8");
518
+ return "User-agent: *\nDisallow:"
519
+ });
520
+
521
+ aServer.get('/*', async function(request, reply) {
522
+ let site = Dbm.getInstance().repository.getItem("site");
523
+ let database = Dbm.getInstance().repository.getItem("graphDatabase").controller;
524
+
525
+ let version = site.version;
526
+ let assetsUri = site.assetsUri;
527
+ let language = site.language;
528
+ let siteName = site.name;
529
+ let loader = "loader.js?version=" + site.version;
530
+ if((process.env.NODE_ENV === "production" && request.query.forceLoad !== "unminified") || request.query.forceLoad === "minified") {
531
+ loader = "loader.min.js?version=" + site.version;
532
+ }
533
+
534
+ let url = request.url;
535
+ let index = url.indexOf("?");
536
+ if(index >= 0) {
537
+ url = url.substring(0, index);
538
+ }
539
+ if(url[url.length-1] !== "/") {
540
+ url += "/";
541
+ }
542
+
543
+ let urlObject = await database.getObjectByUrl(url);
544
+ let moduleName = site.moduleName;
545
+ if(request.query.forceModule) {
546
+ moduleName = request.query.forceModule;
547
+ }
548
+
549
+ if(!urlObject) {
550
+ reply.code(404);
551
+ reply.type('text/html');
552
+
553
+ let returnString = `
554
+ <!doctype html>
555
+ <html lang="${language}">
556
+ <head>
557
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
558
+ <title>Page not found - ${siteName}</title>`;
559
+
560
+ {
561
+ let currentArray = site.preconnectUrls;
562
+ let currentArrayLength =currentArray.length;
563
+ for(let i = 0; i < currentArrayLength; i++) {
564
+ returnString += `<link rel="preconnect" href="${currentArray[i]}" crossorigin>`;
565
+ }
566
+ }
567
+
568
+ returnString += `<link rel="preconnect" href="${process.env.S3_BUCKET_PUBLIC_PATH}" crossorigin>
569
+ <!-- Google Tag Manager -->
570
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
571
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
572
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
573
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
574
+ })(window,document,'script','dataLayer','GTM-K8BL9Q5S');</script>
575
+ <!-- End Google Tag Manager -->
576
+ <link rel="stylesheet" type="text/css" href="${assetsUri}css/main.css?version=${version}" />
577
+ <meta name="viewport" content="initial-scale=1,user-scalable=yes" />
578
+ <meta name="HandheldFriendly" content="true" />
579
+ <link rel="icon" type="image/png" href="${assetsUri}img/favicon.png">
580
+ </head>
581
+ <body>
582
+ <div id="site"></div>
583
+ <script>
584
+ (function(d,b,m,j,s){
585
+ d[m] = d[m] || {}; d[m][j] = d[m][j] || {_: [], create: function(element, moduleName, data) {return this._.push({element, moduleName, data});}, remove: function(id) {this._[id-1] = null;}};
586
+ let e = b.createElement("script"); e.async = true; e.src = s; b.head.appendChild(e);
587
+ })(window, document, "dbmstartup", "modules", "${assetsUri}js/${loader}");
588
+
589
+ dbmstartup.modules.create(document.getElementById("site"), "${moduleName}", {});
590
+ </script>
591
+ </body>
592
+ </html>
593
+ `;
594
+
595
+ return returnString;
596
+ }
597
+
598
+ reply.code(200);
599
+ reply.type('text/html');
600
+
601
+ let fields = await urlObject.getFields();
602
+
603
+ let returnString = `
604
+ <!doctype html>
605
+ <html lang="${language}">
606
+ <head>
607
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
608
+ <meta name="viewport" content="initial-scale=1,user-scalable=yes" />
609
+ <meta name="HandheldFriendly" content="true" />
610
+
611
+ `;
612
+ {
613
+ let currentArray = site.preconnectUrls;
614
+ let currentArrayLength =currentArray.length;
615
+ for(let i = 0; i < currentArrayLength; i++) {
616
+ returnString += `<link rel="preconnect" href="${currentArray[i]}" crossorigin>`;
617
+ }
618
+ }
619
+
620
+ returnString += `<title>${fields.title} - ${siteName}</title>
621
+
622
+ <meta property="og:type" content="website" />
623
+ <meta property="og:locale" content="${language}" />
624
+ <meta property="og:site_name" content="${siteName}" />
625
+ <meta property="og:title" content="${fields.title}" />
626
+
627
+ <!-- Google Tag Manager -->
628
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
629
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
630
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
631
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
632
+ })(window,document,'script','dataLayer','GTM-K8BL9Q5S');</script>
633
+ <!-- End Google Tag Manager -->
634
+
635
+ <link rel="stylesheet" type="text/css" href="${assetsUri}css/main.css?version=${version}" />
636
+
637
+ <link rel="icon" type="image/png" href="${assetsUri}img/favicon.png">`;
638
+
639
+ if(fields['meta/description']) {
640
+ returnString += `
641
+ <meta name="description" content="${fields['meta/description']}" />
642
+ <meta property="og:description" content="${fields['meta/description']}" />
643
+ `;
644
+ }
645
+
646
+ let fullUrl = request.protocol + "://" + request.hostname;
647
+ if(request.port && request.port !== 80 && request.port !== 443) {
648
+ fullUrl += ":" + request.port;
649
+ }
650
+ fullUrl += url;
651
+
652
+ returnString += `
653
+ <link rel="canonical" href="${fullUrl}" />
654
+ <meta property="og:url" content="${fullUrl}" />
655
+ `;
656
+
657
+ /*
658
+ <meta property="article:publisher" content="https://sv-se.facebook.com/..." />
659
+ <meta property="article:modified_time" content="2024-09-03T13:19:26+00:00" />
660
+
661
+ <meta property="og:image" content="https://..." />
662
+ <meta property="og:image:width" content="1024" />
663
+ <meta property="og:image:height" content="683" />
664
+ <meta property="og:image:type" content="image/jpeg" />
665
+ <meta name="twitter:card" content="summary_large_image" />
666
+ */
667
+
668
+ returnString += `</head>
669
+ <body>
670
+ <div id="site"></div>
671
+ <script>
672
+ (function(d,b,m,j,s){
673
+ d[m] = d[m] || {}; d[m][j] = d[m][j] || {_: [], create: function(element, moduleName, data) {return this._.push({element, moduleName, data});}, remove: function(id) {this._[id-1] = null;}};
674
+ let e = b.createElement("script"); e.async = true; e.src = s; b.head.appendChild(e);
675
+ })(window, document, "dbmstartup", "modules", "${assetsUri}js/${loader}");
676
+
677
+ dbmstartup.modules.create(document.getElementById("site"), "${moduleName}", {});
678
+ </script>
679
+ </body>
680
+ </html>`;
681
+
682
+ return returnString;
683
+ });
684
+ }
@@ -0,0 +1,69 @@
1
+ import Dbm from "dbm";
2
+ import DbmGraphApi from "../../../index.js";
3
+
4
+ export default class ExternalTaskRunner extends Dbm.core.BaseObject {
5
+
6
+ _construct() {
7
+ super._construct();
8
+
9
+ this._isRunning = false;
10
+ this._intervalId = -1;
11
+ this._timeBetween = 5;
12
+
13
+ this.item.requireProperty("url", null);
14
+ this.item.requireProperty("method", "GET");
15
+ this.item.requireProperty("headers", {});
16
+ this.item.requireProperty("body", null);
17
+ this.item.requireProperty("continueCheck", "remaining");
18
+ this.item.requireProperty("continueField", "data.remaining");
19
+
20
+ this._runNextTaskBound = this._runNextTask.bind(this);
21
+ }
22
+
23
+ start() {
24
+ if(!this._isRunning) {
25
+ this._isRunning = true;
26
+ this._runNextTask();
27
+ }
28
+ }
29
+
30
+ async _runNextTask() {
31
+ console.log("_runNextTask");
32
+
33
+ let runDirect = false;
34
+
35
+ try {
36
+ let requestData = {
37
+ method: this.item.method,
38
+ headers: this.item.headers
39
+ };
40
+
41
+ if(this.item.body) {
42
+ requestData["body"] = this.item.body;
43
+ }
44
+
45
+ let response = await fetch(this.item.url, requestData);
46
+
47
+ let data = await response.json();
48
+
49
+ let continueData = Dbm.objectPath(data, this.item.continueField);
50
+ console.log(continueData);
51
+
52
+ if(continueData > 0) {
53
+ runDirect = true;
54
+ }
55
+ }
56
+ catch(theError) {
57
+ console.log(theError);
58
+ }
59
+
60
+ if(this._isRunning) {
61
+ if(runDirect) {
62
+ this._intervalId = setTimeout(this._runNextTaskBound, 1);
63
+ }
64
+ else {
65
+ this._intervalId = setTimeout(this._runNextTaskBound, this._timeBetween*1000);
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,60 @@
1
+ import Dbm from "dbm";
2
+ import DbmGraphApi from "../../../index.js";
3
+
4
+ export default class InternalTaskRunner extends Dbm.core.BaseObject {
5
+
6
+ _construct() {
7
+ super._construct();
8
+
9
+ this._isRunning = false;
10
+ this._intervalId = -1;
11
+ this._timeBetween = 5;
12
+
13
+ this._runNextTaskBound = this._runNextTask.bind(this);
14
+ }
15
+
16
+ start() {
17
+ if(!this._isRunning) {
18
+ this._isRunning = true;
19
+ this._runNextTask();
20
+ }
21
+ }
22
+
23
+ startAtStartup() {
24
+ //console.log("startAtStartup");
25
+ if(!this._isRunning) {
26
+ this._isRunning = true;
27
+ setTimeout(this._runNextTaskBound, this._timeBetween*1000);
28
+ }
29
+ }
30
+
31
+ async _runNextTask() {
32
+ //console.log("_runNextTask");
33
+
34
+ let runDirect = false;
35
+
36
+ try {
37
+ let encodeSession = new DbmGraphApi.range.EncodeSession();
38
+ encodeSession.outputController = this;
39
+
40
+ let dataFunctionItem = Dbm.getInstance().repository.getItemIfExists("graphApi/action/cron/processActions");
41
+ let returnData = await dataFunctionItem.controller.performAction({}, encodeSession);
42
+
43
+ if(returnData.remaining > 0) {
44
+ runDirect = true
45
+ }
46
+ }
47
+ catch(theError) {
48
+ console.log(theError);
49
+ }
50
+
51
+ if(this._isRunning) {
52
+ if(runDirect) {
53
+ this._intervalId = setTimeout(this._runNextTaskBound, 1);
54
+ }
55
+ else {
56
+ this._intervalId = setTimeout(this._runNextTaskBound, this._timeBetween*1000);
57
+ }
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,2 @@
1
+ export {default as InternalTaskRunner} from "./InternalTaskRunner.js";
2
+ export {default as ExternalTaskRunner} from "./ExternalTaskRunner.js";