@static-suite/static-suite-data-server 0.0.21 → 0.0.23

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 CHANGED
@@ -8,6 +8,55 @@ A flexible, fast and developer friendly Data Server for [Static Suite](https://w
8
8
 
9
9
  Data Server supports static JSON includes (`entityInclude`, `configInclude`, `localeInclude` and `customInclude`) and the dynamic `queryInclude`, keeping track of the relationships between includes and data: when a file changes, it knows which other files should also change, thus enabling _incremental builds_ for any kind of SSG (Gatsby, Next.js, etc).
10
10
 
11
+ - [Static Suite Data Server](#static-suite-data-server)
12
+ - [Options](#options)
13
+ - [Options from file.](#options-from-file)
14
+ - [Usage](#usage)
15
+ - [SSG develop/build phase](#ssg-developbuild-phase)
16
+ - [Previewing a content from Drupal](#previewing-a-content-from-drupal)
17
+ - [Developing/debugging queries on a local environment](#developingdebugging-queries-on-a-local-environment)
18
+ - [Data structure](#data-structure)
19
+ - [Store internal structure](#store-internal-structure)
20
+ - [Getting a file](#getting-a-file)
21
+ - [Getting a subset of files](#getting-a-subset-of-files)
22
+ - [Subset options](#subset-options)
23
+ - [Return value](#return-value)
24
+ - [Getting a subset of files via HTTP](#getting-a-subset-of-files-via-http)
25
+ - [Return value](#return-value-1)
26
+ - [Indexes](#indexes)
27
+ - [Custom indexes](#custom-indexes)
28
+ - [Queries](#queries)
29
+ - [Hooks](#hooks)
30
+ - [Available hooks](#available-hooks)
31
+ - [`onModuleLoad({config, store, logger }): void`](#onmoduleloadconfig-store-logger--void)
32
+ - [`onStoreLoadStart({ store, logger, dependencyTagger }): void`](#onstoreloadstart-store-logger-dependencytagger--void)
33
+ - [`onProcessFile({ store, logger, dependencyTagger, relativeFilepath, fileContent }): fileContent`](#onprocessfile-store-logger-dependencytagger-relativefilepath-filecontent--filecontent)
34
+ - [`onStoreItemAdd({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitemadd-store-logger-dependencytagger-relativefilepath-storeitem--void)
35
+ - [`onStoreLoadDone({ store, logger, dependencyTagger }): void`](#onstoreloaddone-store-logger-dependencytagger--void)
36
+ - [`onStoreChangeStart({ store, logger, dependencyTagger, changedFiles }): void`](#onstorechangestart-store-logger-dependencytagger-changedfiles--void)
37
+ - [`onStoreItemBeforeUpdate({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitembeforeupdate-store-logger-dependencytagger-relativefilepath-storeitem--void)
38
+ - [`onStoreItemAfterUpdate({ store, logger, dependencyTagger, relativeFilepath, storeItem, previousStoreItem }): void`](#onstoreitemafterupdate-store-logger-dependencytagger-relativefilepath-storeitem-previousstoreitem--void)
39
+ - [`onStoreItemDelete({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitemdelete-store-logger-dependencytagger-relativefilepath-storeitem--void)
40
+ - [`onStoreChangeDone({ store, logger, dependencyTagger, changedFiles }): void`](#onstorechangedone-store-logger-dependencytagger-changedfiles--void)
41
+ - [`onDumpCreate(options: OnDumpHookOptions): Dump`](#ondumpcreateoptions-ondumphookoptions-dump)
42
+ - [Hook example](#hook-example)
43
+ - [`File taxonomy.hook.js`](#file-taxonomyhookjs)
44
+ - [`File listContentsByTermId.query.js`](#file-listcontentsbytermidqueryjs)
45
+ - [Tasks](#tasks)
46
+ - [Dumps](#dumps)
47
+ - [Dependency tags](#dependency-tags)
48
+ - [Dependency tagger](#dependency-tagger)
49
+ - [`setDependency(tag: string, dependsOnTags: string[]): void`](#setdependencytag-string-dependsontags-string-void)
50
+ - [`addDependency(tag: string, dependsOnTags: string[]): void`](#adddependencytag-string-dependsontags-string-void)
51
+ - [`deleteDependency(tag: string, dependsOnTags?: string[]): void`](#deletedependencytag-string-dependsontags-string-void)
52
+ - [`invalidateTags(tags: string[]): void`](#invalidatetagstags-string-void)
53
+ - [Dependency tags example](#dependency-tags-example)
54
+ - [`File taxonomy.hook.js`](#file-taxonomyhookjs-1)
55
+ - [`File listContentsByTermId.query.js`](#file-listcontentsbytermidqueryjs-1)
56
+ - [Run modes](#run-modes)
57
+ - [Dev run mode](#dev-run-mode)
58
+ - [Prod run mode](#prod-run-mode)
59
+
11
60
  ## Options
12
61
 
13
62
  - `dataDir` / `--data-dir`: path to the directory where data from Static Suite is stored. Required.
@@ -15,6 +64,7 @@ Data Server supports static JSON includes (`entityInclude`, `configInclude`, `lo
15
64
  - `dumpDir` / `--dump-dir`: path to the directory where data from Static Suite is dumped after being processed by Data Server. Optional.
16
65
  - `queryDir` / `--query-dir`: path to the directory where queries are stored. Optional.
17
66
  - `hookDir` / `--hook-dir`: path to the directory where hooks are stored. Optional.
67
+ - `taskDir` / `--task-dir`: path to the directory where tasks are stored. Optional.
18
68
  - `logLevel` / `--log-level`: log level verbosity: `error`, `warn`, `info` or `debug`. Optional. Defaults to `info`.
19
69
  - `logFile` / `--log-file`: path to the log file. Data server logs its errors to the stdOut, but they can also be saved into a log file. Optional.
20
70
  - `logFileLevel` / `--log-file-level`: log level verbosity for the log file: `error`, `warn`, `info` or `debug`. Optional. Defaults to the value of `logLevel` / `--log-level`
@@ -344,7 +394,7 @@ Received parameters:
344
394
 
345
395
  - `config`: object with configuration options defined at Data Server start: `dataDir`, `workDir`, `queryDir`, etc
346
396
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
347
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
397
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
348
398
 
349
399
  #### `onStoreLoadStart({ store, logger, dependencyTagger }): void`
350
400
 
@@ -353,7 +403,7 @@ Called before the store starts loading for the first time.
353
403
  Received parameters:
354
404
 
355
405
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
356
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
406
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
357
407
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
358
408
 
359
409
  #### `onProcessFile({ store, logger, dependencyTagger, relativeFilepath, fileContent }): fileContent`
@@ -363,7 +413,7 @@ Called after a file is read from disk, before adding it to the store. It is aime
363
413
  Received parameters:
364
414
 
365
415
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
366
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
416
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
367
417
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
368
418
  - `relativeFilepath`: relative file path inside the data dir.
369
419
  - `fileContent`: file contents, an object with "raw" and "json" members.
@@ -379,7 +429,7 @@ Called after a file is added into the store for the first time.
379
429
  Received parameters:
380
430
 
381
431
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
382
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
432
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
383
433
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
384
434
  - `relativeFilepath`: relative file path inside the data dir.
385
435
  - `storeItem`: contents of the store item.
@@ -391,7 +441,7 @@ Called after the store finishes loading for the first time.
391
441
  Received parameters:
392
442
 
393
443
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
394
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
444
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
395
445
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
396
446
 
397
447
  #### `onStoreChangeStart({ store, logger, dependencyTagger, changedFiles }): void`
@@ -401,7 +451,7 @@ Called before the store starts updating.
401
451
  Received parameters:
402
452
 
403
453
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
404
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
454
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
405
455
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
406
456
  - `changedFiles`: a group of changed files in Static Suite's data dir, an object with the following keys:
407
457
  - `fromUniqueId`: a unique id representing the date from which those changes are obtained.
@@ -417,7 +467,7 @@ Called before a file is updated in the store.
417
467
  Received parameters:
418
468
 
419
469
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
420
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
470
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
421
471
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
422
472
  - `relativeFilepath`: relative file path inside the data dir.
423
473
  - `storeItem`: contents of the store item.
@@ -429,7 +479,7 @@ Called after a file is updated in the store.
429
479
  Received parameters:
430
480
 
431
481
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
432
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
482
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
433
483
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
434
484
  - `relativeFilepath`: relative file path inside the data dir.
435
485
  - `storeItem`: contents of the store item.
@@ -442,7 +492,7 @@ Called after a file is deleted from the store.
442
492
  Received parameters:
443
493
 
444
494
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
445
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
495
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
446
496
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
447
497
  - `relativeFilepath`: relative file path inside the data dir.
448
498
  - `storeItem`: contents of the store item.
@@ -454,7 +504,7 @@ Called after the store ends updating.
454
504
  Received parameters:
455
505
 
456
506
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
457
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
507
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
458
508
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
459
509
  - `changedFiles`: a group of changed files in Static Suite's data dir, an object with the following keys:
460
510
  - `fromUniqueId`: a unique id representing the date from which those changes are obtained.
@@ -591,6 +641,67 @@ const listContentsByTermId = ({ store, args }) => {
591
641
  module.exports.default = listContentsByTermId;
592
642
  ```
593
643
 
644
+ ## Tasks
645
+
646
+ Data Server allows the execution of custom tasks. Just like [queries](#queries) and [hooks](#hooks), tasks are stored in a file inside a directory defined by the `taskDir` / `--task-dir` option.
647
+
648
+ Each task is a file named `${queryId}.task.js`, and it must export a default function that receives an object as an argument, containing two keys (`store` and `args`):
649
+
650
+ - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
651
+
652
+ - `args`: object with arguments used by that task.
653
+
654
+ > PLEASE NOTE: since `store` is a shared object, you MUST NOT alter it from your tasks.
655
+
656
+ Tasks must return an object with the following keys:
657
+
658
+ - `result`: the list of returned results. It must be an structure representable as JSON (an object, array, string, etc)
659
+ - `contentType`: optional content-type for the `result` field. Defaults to `application/json`.
660
+ - `httpStatus`: optional HTTP status for the data available in "result". Defaults to 200.
661
+
662
+ Example: get customized content data
663
+
664
+ ```javascript
665
+ const getComponentChunkName = page => {
666
+ const bundle = page.data.content.bundle.replace(/_/g, '-');
667
+ return `component---src-views-${bundle}-${bundle}-jsx`;
668
+ };
669
+
670
+ const getPageDataObject = page => ({
671
+ componentChunkName: getComponentChunkName(page),
672
+ path: page.data.content.url.path,
673
+ result: {
674
+ pageContext: {
675
+ node: page,
676
+ },
677
+ },
678
+ staticQueryHashes: [],
679
+ });
680
+
681
+ const getPageData = ({ store, args }) => {
682
+ let pageData;
683
+ const pathFromArgs = args.path?.trim();
684
+ if (pathFromArgs) {
685
+ const path = pathFromArgs.trim().replace(/^\/+|\/+$/g, '');
686
+ const storeKey = path === 'index' ? '/' : `/${path}`;
687
+ const storeFile = store.index.url.get(storeKey);
688
+ if (storeFile !== undefined) {
689
+ pageData = getPageDataObject(storeFile);
690
+ }
691
+ }
692
+
693
+ const res = {
694
+ httpStatus: pageData ? 200 : 404,
695
+ result: pageData || 'not found',
696
+ contentType: pageData ? 'application/json' : 'text/plain',
697
+ };
698
+
699
+ return res;
700
+ };
701
+
702
+ module.exports.default = getPageData;
703
+ ```
704
+
594
705
  ## Dumps
595
706
 
596
707
  Data Server is able to detect when a file is being used (included) by other file. When a file changes, Data Server provides a list of all files affected by that change. This list can therefore be used to generate incremental builds of your site, building only the HTML pages for those changed files.
@@ -801,6 +912,7 @@ It watches for changes in the post processor and query files:
801
912
 
802
913
  - When a file inside the `queryDir` / `--query-dir` changes, all files inside that directory are reloaded to ensure any module or sub module is properly refreshed
803
914
  - When a file inside the `hookDir` / `--hook-dir` changes, all files inside that directory are reloaded, and the store is reloaded and passed again through all hooks, so any changes in them are applied to all data files.
915
+ - When a file inside the `taskDir` / `--task-dir` changes, all files inside that directory are reloaded.
804
916
 
805
917
  This is the intended mode when developing queries (executing it by directly requesting the HTTP endpoint to execute a query). This mode is not required for the develop phase of a SSG, since the SSG will get the data from the Data Server only once.
806
918
 
package/dist/bin/serve.js CHANGED
@@ -77,11 +77,6 @@ const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
77
77
  describe: 'Show help',
78
78
  type: 'boolean',
79
79
  },
80
- })
81
- .completion('completion', (_current, _argv, done) => {
82
- setTimeout(() => {
83
- done(['query-dir', 'data-dir']);
84
- }, 500);
85
80
  })
86
81
  .config(config)
87
82
  .parseSync();
@@ -8,6 +8,55 @@ A flexible, fast and developer friendly Data Server for [Static Suite](https://w
8
8
 
9
9
  Data Server supports static JSON includes (`entityInclude`, `configInclude`, `localeInclude` and `customInclude`) and the dynamic `queryInclude`, keeping track of the relationships between includes and data: when a file changes, it knows which other files should also change, thus enabling _incremental builds_ for any kind of SSG (Gatsby, Next.js, etc).
10
10
 
11
+ - [Static Suite Data Server](#static-suite-data-server)
12
+ - [Options](#options)
13
+ - [Options from file.](#options-from-file)
14
+ - [Usage](#usage)
15
+ - [SSG develop/build phase](#ssg-developbuild-phase)
16
+ - [Previewing a content from Drupal](#previewing-a-content-from-drupal)
17
+ - [Developing/debugging queries on a local environment](#developingdebugging-queries-on-a-local-environment)
18
+ - [Data structure](#data-structure)
19
+ - [Store internal structure](#store-internal-structure)
20
+ - [Getting a file](#getting-a-file)
21
+ - [Getting a subset of files](#getting-a-subset-of-files)
22
+ - [Subset options](#subset-options)
23
+ - [Return value](#return-value)
24
+ - [Getting a subset of files via HTTP](#getting-a-subset-of-files-via-http)
25
+ - [Return value](#return-value-1)
26
+ - [Indexes](#indexes)
27
+ - [Custom indexes](#custom-indexes)
28
+ - [Queries](#queries)
29
+ - [Hooks](#hooks)
30
+ - [Available hooks](#available-hooks)
31
+ - [`onModuleLoad({config, store, logger }): void`](#onmoduleloadconfig-store-logger--void)
32
+ - [`onStoreLoadStart({ store, logger, dependencyTagger }): void`](#onstoreloadstart-store-logger-dependencytagger--void)
33
+ - [`onProcessFile({ store, logger, dependencyTagger, relativeFilepath, fileContent }): fileContent`](#onprocessfile-store-logger-dependencytagger-relativefilepath-filecontent--filecontent)
34
+ - [`onStoreItemAdd({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitemadd-store-logger-dependencytagger-relativefilepath-storeitem--void)
35
+ - [`onStoreLoadDone({ store, logger, dependencyTagger }): void`](#onstoreloaddone-store-logger-dependencytagger--void)
36
+ - [`onStoreChangeStart({ store, logger, dependencyTagger, changedFiles }): void`](#onstorechangestart-store-logger-dependencytagger-changedfiles--void)
37
+ - [`onStoreItemBeforeUpdate({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitembeforeupdate-store-logger-dependencytagger-relativefilepath-storeitem--void)
38
+ - [`onStoreItemAfterUpdate({ store, logger, dependencyTagger, relativeFilepath, storeItem, previousStoreItem }): void`](#onstoreitemafterupdate-store-logger-dependencytagger-relativefilepath-storeitem-previousstoreitem--void)
39
+ - [`onStoreItemDelete({ store, logger, dependencyTagger, relativeFilepath, storeItem }): void`](#onstoreitemdelete-store-logger-dependencytagger-relativefilepath-storeitem--void)
40
+ - [`onStoreChangeDone({ store, logger, dependencyTagger, changedFiles }): void`](#onstorechangedone-store-logger-dependencytagger-changedfiles--void)
41
+ - [`onDumpCreate(options: OnDumpHookOptions): Dump`](#ondumpcreateoptions-ondumphookoptions-dump)
42
+ - [Hook example](#hook-example)
43
+ - [`File taxonomy.hook.js`](#file-taxonomyhookjs)
44
+ - [`File listContentsByTermId.query.js`](#file-listcontentsbytermidqueryjs)
45
+ - [Tasks](#tasks)
46
+ - [Dumps](#dumps)
47
+ - [Dependency tags](#dependency-tags)
48
+ - [Dependency tagger](#dependency-tagger)
49
+ - [`setDependency(tag: string, dependsOnTags: string[]): void`](#setdependencytag-string-dependsontags-string-void)
50
+ - [`addDependency(tag: string, dependsOnTags: string[]): void`](#adddependencytag-string-dependsontags-string-void)
51
+ - [`deleteDependency(tag: string, dependsOnTags?: string[]): void`](#deletedependencytag-string-dependsontags-string-void)
52
+ - [`invalidateTags(tags: string[]): void`](#invalidatetagstags-string-void)
53
+ - [Dependency tags example](#dependency-tags-example)
54
+ - [`File taxonomy.hook.js`](#file-taxonomyhookjs-1)
55
+ - [`File listContentsByTermId.query.js`](#file-listcontentsbytermidqueryjs-1)
56
+ - [Run modes](#run-modes)
57
+ - [Dev run mode](#dev-run-mode)
58
+ - [Prod run mode](#prod-run-mode)
59
+
11
60
  ## Options
12
61
 
13
62
  - `dataDir` / `--data-dir`: path to the directory where data from Static Suite is stored. Required.
@@ -15,6 +64,7 @@ Data Server supports static JSON includes (`entityInclude`, `configInclude`, `lo
15
64
  - `dumpDir` / `--dump-dir`: path to the directory where data from Static Suite is dumped after being processed by Data Server. Optional.
16
65
  - `queryDir` / `--query-dir`: path to the directory where queries are stored. Optional.
17
66
  - `hookDir` / `--hook-dir`: path to the directory where hooks are stored. Optional.
67
+ - `taskDir` / `--task-dir`: path to the directory where tasks are stored. Optional.
18
68
  - `logLevel` / `--log-level`: log level verbosity: `error`, `warn`, `info` or `debug`. Optional. Defaults to `info`.
19
69
  - `logFile` / `--log-file`: path to the log file. Data server logs its errors to the stdOut, but they can also be saved into a log file. Optional.
20
70
  - `logFileLevel` / `--log-file-level`: log level verbosity for the log file: `error`, `warn`, `info` or `debug`. Optional. Defaults to the value of `logLevel` / `--log-level`
@@ -344,7 +394,7 @@ Received parameters:
344
394
 
345
395
  - `config`: object with configuration options defined at Data Server start: `dataDir`, `workDir`, `queryDir`, etc
346
396
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
347
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
397
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
348
398
 
349
399
  #### `onStoreLoadStart({ store, logger, dependencyTagger }): void`
350
400
 
@@ -353,7 +403,7 @@ Called before the store starts loading for the first time.
353
403
  Received parameters:
354
404
 
355
405
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
356
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
406
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
357
407
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
358
408
 
359
409
  #### `onProcessFile({ store, logger, dependencyTagger, relativeFilepath, fileContent }): fileContent`
@@ -363,7 +413,7 @@ Called after a file is read from disk, before adding it to the store. It is aime
363
413
  Received parameters:
364
414
 
365
415
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
366
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
416
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
367
417
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
368
418
  - `relativeFilepath`: relative file path inside the data dir.
369
419
  - `fileContent`: file contents, an object with "raw" and "json" members.
@@ -379,7 +429,7 @@ Called after a file is added into the store for the first time.
379
429
  Received parameters:
380
430
 
381
431
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
382
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
432
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
383
433
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
384
434
  - `relativeFilepath`: relative file path inside the data dir.
385
435
  - `storeItem`: contents of the store item.
@@ -391,7 +441,7 @@ Called after the store finishes loading for the first time.
391
441
  Received parameters:
392
442
 
393
443
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
394
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
444
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
395
445
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
396
446
 
397
447
  #### `onStoreChangeStart({ store, logger, dependencyTagger, changedFiles }): void`
@@ -401,7 +451,7 @@ Called before the store starts updating.
401
451
  Received parameters:
402
452
 
403
453
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
404
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
454
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
405
455
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
406
456
  - `changedFiles`: a group of changed files in Static Suite's data dir, an object with the following keys:
407
457
  - `fromUniqueId`: a unique id representing the date from which those changes are obtained.
@@ -417,7 +467,7 @@ Called before a file is updated in the store.
417
467
  Received parameters:
418
468
 
419
469
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
420
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
470
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
421
471
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
422
472
  - `relativeFilepath`: relative file path inside the data dir.
423
473
  - `storeItem`: contents of the store item.
@@ -429,7 +479,7 @@ Called after a file is updated in the store.
429
479
  Received parameters:
430
480
 
431
481
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
432
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
482
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
433
483
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
434
484
  - `relativeFilepath`: relative file path inside the data dir.
435
485
  - `storeItem`: contents of the store item.
@@ -442,7 +492,7 @@ Called after a file is deleted from the store.
442
492
  Received parameters:
443
493
 
444
494
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
445
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
495
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
446
496
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
447
497
  - `relativeFilepath`: relative file path inside the data dir.
448
498
  - `storeItem`: contents of the store item.
@@ -454,7 +504,7 @@ Called after the store ends updating.
454
504
  Received parameters:
455
505
 
456
506
  - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
457
- - `logger`: the logger service width several functions to log messages: `error()`, `warn()`, `info()`, `error()`
507
+ - `logger`: the logger service with several functions to log messages: `error()`, `warn()`, `info()`, `error()`
458
508
  - `dependencyTagger`: the dependency tagger service. See [Dependency Tags](#dependency-tags) section.
459
509
  - `changedFiles`: a group of changed files in Static Suite's data dir, an object with the following keys:
460
510
  - `fromUniqueId`: a unique id representing the date from which those changes are obtained.
@@ -591,6 +641,67 @@ const listContentsByTermId = ({ store, args }) => {
591
641
  module.exports.default = listContentsByTermId;
592
642
  ```
593
643
 
644
+ ## Tasks
645
+
646
+ Data Server allows the execution of custom tasks. Just like [queries](#queries) and [hooks](#hooks), tasks are stored in a file inside a directory defined by the `taskDir` / `--task-dir` option.
647
+
648
+ Each task is a file named `${queryId}.task.js`, and it must export a default function that receives an object as an argument, containing two keys (`store` and `args`):
649
+
650
+ - `store`: the object that holds all data. See [store internal structure](#store-internal-structure).
651
+
652
+ - `args`: object with arguments used by that task.
653
+
654
+ > PLEASE NOTE: since `store` is a shared object, you MUST NOT alter it from your tasks.
655
+
656
+ Tasks must return an object with the following keys:
657
+
658
+ - `result`: the list of returned results. It must be an structure representable as JSON (an object, array, string, etc)
659
+ - `contentType`: optional content-type for the `result` field. Defaults to `application/json`.
660
+ - `httpStatus`: optional HTTP status for the data available in "result". Defaults to 200.
661
+
662
+ Example: get customized content data
663
+
664
+ ```javascript
665
+ const getComponentChunkName = page => {
666
+ const bundle = page.data.content.bundle.replace(/_/g, '-');
667
+ return `component---src-views-${bundle}-${bundle}-jsx`;
668
+ };
669
+
670
+ const getPageDataObject = page => ({
671
+ componentChunkName: getComponentChunkName(page),
672
+ path: page.data.content.url.path,
673
+ result: {
674
+ pageContext: {
675
+ node: page,
676
+ },
677
+ },
678
+ staticQueryHashes: [],
679
+ });
680
+
681
+ const getPageData = ({ store, args }) => {
682
+ let pageData;
683
+ const pathFromArgs = args.path?.trim();
684
+ if (pathFromArgs) {
685
+ const path = pathFromArgs.trim().replace(/^\/+|\/+$/g, '');
686
+ const storeKey = path === 'index' ? '/' : `/${path}`;
687
+ const storeFile = store.index.url.get(storeKey);
688
+ if (storeFile !== undefined) {
689
+ pageData = getPageDataObject(storeFile);
690
+ }
691
+ }
692
+
693
+ const res = {
694
+ httpStatus: pageData ? 200 : 404,
695
+ result: pageData || 'not found',
696
+ contentType: pageData ? 'application/json' : 'text/plain',
697
+ };
698
+
699
+ return res;
700
+ };
701
+
702
+ module.exports.default = getPageData;
703
+ ```
704
+
594
705
  ## Dumps
595
706
 
596
707
  Data Server is able to detect when a file is being used (included) by other file. When a file changes, Data Server provides a list of all files affected by that change. This list can therefore be used to generate incremental builds of your site, building only the HTML pages for those changed files.
@@ -801,6 +912,7 @@ It watches for changes in the post processor and query files:
801
912
 
802
913
  - When a file inside the `queryDir` / `--query-dir` changes, all files inside that directory are reloaded to ensure any module or sub module is properly refreshed
803
914
  - When a file inside the `hookDir` / `--hook-dir` changes, all files inside that directory are reloaded, and the store is reloaded and passed again through all hooks, so any changes in them are applied to all data files.
915
+ - When a file inside the `taskDir` / `--task-dir` changes, all files inside that directory are reloaded.
804
916
 
805
917
  This is the intended mode when developing queries (executing it by directly requesting the HTTP endpoint to execute a query). This mode is not required for the develop phase of a SSG, since the SSG will get the data from the Data Server only once.
806
918
 
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/http/routes/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQ5C,QAAA,MAAM,UAAU,QAAS,OAAO,OAAO,QAAQ,KAAG,IAMjD,CAAC;AAEF,QAAA,MAAM,QAAQ,QAAS,OAAO,OAAO,QAAQ,KAAG,IAQ/C,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/http/routes/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQ5C,QAAA,MAAM,UAAU,QAAS,OAAO,OAAO,QAAQ,KAAG,IAMjD,CAAC;AAEF,QAAA,MAAM,QAAQ,QAAS,OAAO,OAAO,QAAQ,KAAG,IAa/C,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC"}
@@ -15,7 +15,11 @@ const runQuery = (req, res) => {
15
15
  const queryDefinition = req.originalUrl.replace(/^\/query\//, '');
16
16
  const response = query_1.queryRunner.run(queryDefinition);
17
17
  res.status(200);
18
- res.set('application/json');
18
+ res.set({
19
+ 'Content-Type': 'metadata' in response
20
+ ? response.metadata.contentType
21
+ : 'application/json',
22
+ });
19
23
  res.send(response);
20
24
  };
21
25
  exports.runQuery = runQuery;
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../src/http/routes/task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQ5C,QAAA,MAAM,SAAS,QAAS,OAAO,OAAO,QAAQ,KAAG,IAKhD,CAAC;AAEF,QAAA,MAAM,OAAO,QAAS,OAAO,OAAO,QAAQ,KAAG,IAW9C,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../src/http/routes/task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQ5C,QAAA,MAAM,SAAS,QAAS,OAAO,OAAO,QAAQ,KAAG,IAKhD,CAAC;AAEF,QAAA,MAAM,OAAO,QAAS,OAAO,OAAO,QAAQ,KAAG,IAoB9C,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC"}
@@ -15,8 +15,14 @@ const runTask = (req, res) => {
15
15
  const args = req.query;
16
16
  const taskId = req.params[0];
17
17
  const response = task_1.taskRunner.run(taskId, args);
18
- res.status(200);
19
- res.set('application/json');
20
- res.send(response);
18
+ res.status('metadata' in response && response.metadata.httpStatus
19
+ ? response.metadata.httpStatus
20
+ : 200);
21
+ res.set({
22
+ 'Content-Type': 'metadata' in response
23
+ ? response.metadata.contentType
24
+ : 'application/json',
25
+ });
26
+ res.send('data' in response ? response.data : response);
21
27
  };
22
28
  exports.runTask = runTask;
@@ -63,6 +63,12 @@ export type TaskModuleResult = {
63
63
  * @defaultValue 'application/json'
64
64
  */
65
65
  contentType?: string;
66
+ /**
67
+ * Optional HTTP status type for the data available in "result"
68
+ *
69
+ * @defaultValue 200
70
+ */
71
+ httpStatus?: number;
66
72
  };
67
73
  /**
68
74
  * A successful response returned after executing a task.
@@ -95,6 +101,12 @@ export type TaskSuccessfulResponse = {
95
101
  * Execution time taken by the task, in milliseconds.
96
102
  */
97
103
  execTimeMs: number;
104
+ /**
105
+ * Optional HTTP status type for the data available in "data"
106
+ *
107
+ * @defaultValue 200
108
+ */
109
+ httpStatus?: number;
98
110
  };
99
111
  };
100
112
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"task.types.d.ts","sourceRoot":"","sources":["../../../src/lib/task/task.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,GAAG,CACD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,GACb,sBAAsB,GAAG,iBAAiB,CAAC;CAC/C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC;IAEZ;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,IAAI,EAAE,GAAG,CAAC;IAEV;;OAEG;IACH,QAAQ,EAAE;QACR;;;;;;;WAOG;QACH,WAAW,EAAE,MAAM,CAAC;QAEpB;;WAEG;QACH,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,gBAAgB,CAAC;CACtE,CAAC;AACF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,iBAChB,sBAAsB,GAAG,iBAAiB,sCAED,CAAC"}
1
+ {"version":3,"file":"task.types.d.ts","sourceRoot":"","sources":["../../../src/lib/task/task.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,GAAG,CACD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,GACb,sBAAsB,GAAG,iBAAiB,CAAC;CAC/C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC;IAEZ;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,IAAI,EAAE,GAAG,CAAC;IAEV;;OAEG;IACH,QAAQ,EAAE;QACR;;;;;;;WAOG;QACH,WAAW,EAAE,MAAM,CAAC;QAEpB;;WAEG;QACH,UAAU,EAAE,MAAM,CAAC;QAEnB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,GAAG,gBAAgB,CAAC;CACtE,CAAC;AACF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,iBAChB,sBAAsB,GAAG,iBAAiB,sCAED,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"taskRunner.d.ts","sourceRoot":"","sources":["../../../src/lib/task/taskRunner.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,UAAU,EAIX,MAAM,cAAc,CAAC;AAkBtB,eAAO,MAAM,UAAU,EAAE,UAkDxB,CAAC"}
1
+ {"version":3,"file":"taskRunner.d.ts","sourceRoot":"","sources":["../../../src/lib/task/taskRunner.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,UAAU,EAIX,MAAM,cAAc,CAAC;AAkBtB,eAAO,MAAM,UAAU,EAAE,UAoDxB,CAAC"}
@@ -42,6 +42,7 @@ exports.taskRunner = {
42
42
  const taskResult = {
43
43
  result: undefined,
44
44
  contentType: undefined,
45
+ httpStatus: undefined,
45
46
  };
46
47
  try {
47
48
  const taskModule = taskModuleInfo.getModule();
@@ -51,6 +52,7 @@ exports.taskRunner = {
51
52
  });
52
53
  taskResult.result = taskResponse?.result;
53
54
  taskResult.contentType = taskResponse?.contentType || 'application/json';
55
+ taskResult.httpStatus = taskResponse?.httpStatus || 200;
54
56
  }
55
57
  catch (e) {
56
58
  // Log error and rethrow.
@@ -63,6 +65,7 @@ exports.taskRunner = {
63
65
  metadata: {
64
66
  contentType: taskResult.contentType || 'application/json',
65
67
  execTimeMs,
68
+ httpStatus: taskResult.httpStatus || 200,
66
69
  },
67
70
  };
68
71
  logger_1.logger.debug(`#${count} Task "${taskId}" took ${execTimeMs} ms.`);
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.47.9"
8
+ "packageVersion": "7.52.11"
9
9
  }
10
10
  ]
11
11
  }
@@ -540,6 +540,12 @@ declare type TaskSuccessfulResponse = {
540
540
  * Execution time taken by the task, in milliseconds.
541
541
  */
542
542
  execTimeMs: number;
543
+ /**
544
+ * Optional HTTP status type for the data available in "data"
545
+ *
546
+ * @defaultValue 200
547
+ */
548
+ httpStatus?: number;
543
549
  };
544
550
  };
545
551
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@static-suite/static-suite-data-server",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "A flexible, fast and developer friendly Data Server for Static Suite",
5
5
  "main": "./dist/lib/index.js",
6
6
  "typings": "./dist/lib/index.d.ts",
@@ -85,4 +85,4 @@
85
85
  "src/__tests__/mocks/*"
86
86
  ]
87
87
  }
88
- }
88
+ }
package/src/bin/serve.ts CHANGED
@@ -79,11 +79,6 @@ const argv = yargs(hideBin(process.argv))
79
79
  type: 'boolean',
80
80
  },
81
81
  })
82
- .completion('completion', (_current, _argv, done) => {
83
- setTimeout(() => {
84
- done(['query-dir', 'data-dir']);
85
- }, 500);
86
- })
87
82
  .config(config)
88
83
  .parseSync();
89
84
 
@@ -20,7 +20,12 @@ const runQuery = (req: Request, res: Response): void => {
20
20
  const response: QuerySuccessfulResponse | QueryErrorResponse =
21
21
  queryRunner.run(queryDefinition);
22
22
  res.status(200);
23
- res.set('application/json');
23
+ res.set({
24
+ 'Content-Type':
25
+ 'metadata' in response
26
+ ? response.metadata.contentType
27
+ : 'application/json',
28
+ });
24
29
  res.send(response);
25
30
  };
26
31
 
@@ -21,9 +21,18 @@ const runTask = (req: Request, res: Response): void => {
21
21
  taskId,
22
22
  args,
23
23
  );
24
- res.status(200);
25
- res.set('application/json');
26
- res.send(response);
24
+ res.status(
25
+ 'metadata' in response && response.metadata.httpStatus
26
+ ? response.metadata.httpStatus
27
+ : 200,
28
+ );
29
+ res.set({
30
+ 'Content-Type':
31
+ 'metadata' in response
32
+ ? response.metadata.contentType
33
+ : 'application/json',
34
+ });
35
+ res.send('data' in response ? response.data : response);
27
36
  };
28
37
 
29
38
  export { taskIndex, runTask };
@@ -70,6 +70,13 @@ export type TaskModuleResult = {
70
70
  * @defaultValue 'application/json'
71
71
  */
72
72
  contentType?: string;
73
+
74
+ /**
75
+ * Optional HTTP status type for the data available in "result"
76
+ *
77
+ * @defaultValue 200
78
+ */
79
+ httpStatus?: number;
73
80
  };
74
81
 
75
82
  /**
@@ -105,6 +112,13 @@ export type TaskSuccessfulResponse = {
105
112
  * Execution time taken by the task, in milliseconds.
106
113
  */
107
114
  execTimeMs: number;
115
+
116
+ /**
117
+ * Optional HTTP status type for the data available in "data"
118
+ *
119
+ * @defaultValue 200
120
+ */
121
+ httpStatus?: number;
108
122
  };
109
123
  };
110
124
 
@@ -46,6 +46,7 @@ export const taskRunner: TaskRunner = {
46
46
  const taskResult: TaskModuleResult = {
47
47
  result: undefined,
48
48
  contentType: undefined,
49
+ httpStatus: undefined,
49
50
  };
50
51
  try {
51
52
  const taskModule = taskModuleInfo.getModule();
@@ -54,8 +55,8 @@ export const taskRunner: TaskRunner = {
54
55
  args,
55
56
  });
56
57
  taskResult.result = taskResponse?.result;
57
-
58
58
  taskResult.contentType = taskResponse?.contentType || 'application/json';
59
+ taskResult.httpStatus = taskResponse?.httpStatus || 200;
59
60
  } catch (e) {
60
61
  // Log error and rethrow.
61
62
  logger.error(
@@ -69,6 +70,7 @@ export const taskRunner: TaskRunner = {
69
70
  metadata: {
70
71
  contentType: taskResult.contentType || 'application/json',
71
72
  execTimeMs,
73
+ httpStatus: taskResult.httpStatus || 200,
72
74
  },
73
75
  };
74
76