retold 1.0.6 → 4.0.1
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/.claude/settings.local.json +58 -0
- package/CLAUDE.md +52 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +161 -0
- package/docs/_sidebar.md +65 -0
- package/docs/_topbar.md +6 -0
- package/docs/architecture.md +312 -0
- package/docs/cover.md +15 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/fable.md +198 -0
- package/docs/getting-started.md +272 -0
- package/docs/index.html +39 -0
- package/docs/js/pict.min.js +12 -0
- package/docs/js/pict.min.js.map +1 -0
- package/docs/meadow.md +211 -0
- package/docs/modules.md +96 -0
- package/docs/orator.md +164 -0
- package/docs/pict-docuserve.min.js +58 -0
- package/docs/pict-docuserve.min.js.map +1 -0
- package/docs/pict.md +213 -0
- package/docs/retold-building-documentation.md +33 -0
- package/docs/retold-catalog.json +2826 -0
- package/docs/retold-keyword-index.json +161289 -0
- package/docs/utility.md +63 -0
- package/examples/quickstart/README.md +47 -0
- package/examples/quickstart/layer1/README.md +21 -0
- package/examples/quickstart/layer1/index.js +49 -0
- package/examples/quickstart/layer1/package-lock.json +344 -0
- package/examples/quickstart/layer1/package.json +12 -0
- package/examples/quickstart/layer2/README.md +34 -0
- package/examples/quickstart/layer2/index.js +251 -0
- package/examples/quickstart/layer2/package-lock.json +4468 -0
- package/examples/quickstart/layer2/package.json +17 -0
- package/examples/quickstart/layer2/setup-database.js +61 -0
- package/examples/quickstart/layer3/README.md +39 -0
- package/examples/quickstart/layer3/index.js +91 -0
- package/examples/quickstart/layer3/package-lock.json +1936 -0
- package/examples/quickstart/layer3/package.json +14 -0
- package/examples/quickstart/layer4/README.md +47 -0
- package/examples/quickstart/layer4/generate-build-config.js +18 -0
- package/examples/quickstart/layer4/html/index.html +17 -0
- package/examples/quickstart/layer4/package-lock.json +13206 -0
- package/examples/quickstart/layer4/package.json +38 -0
- package/examples/quickstart/layer4/server.js +28 -0
- package/examples/quickstart/layer4/source/BookStore-Application-Config.json +15 -0
- package/examples/quickstart/layer4/source/BookStore-Application.js +54 -0
- package/examples/quickstart/layer4/source/providers/Router-Config.json +18 -0
- package/examples/quickstart/layer4/source/views/View-About.js +38 -0
- package/examples/quickstart/layer4/source/views/View-Home.js +50 -0
- package/examples/quickstart/layer4/source/views/View-Layout.js +60 -0
- package/examples/quickstart/layer5/README.md +26 -0
- package/examples/quickstart/layer5/index.js +121 -0
- package/examples/quickstart/layer5/package-lock.json +345 -0
- package/examples/quickstart/layer5/package.json +13 -0
- package/modules/.claude/settings.local.json +52 -0
- package/modules/CLAUDE.md +60 -0
- package/modules/Checkout.sh +42 -0
- package/modules/Include-Retold-Module-List.sh +15 -0
- package/modules/Retold-Modules.md +24 -0
- package/modules/Status.sh +59 -0
- package/modules/Update.sh +45 -0
- package/modules/fable/Fable.md +2 -0
- package/modules/meadow/Meadow.md +1 -0
- package/modules/orator/Orator.md +1 -0
- package/modules/pict/Pict.md +1 -0
- package/package.json +30 -35
- package/source/Retold.cjs +2 -0
- package/test/Retold_tests.js +23 -41
- package/.travis.yml +0 -13
- package/source/Retold-Meadow-Macros.js +0 -269
- package/source/Retold.js +0 -48
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "retold-quickstart-layer4-pict",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Retold Quickstart: Layer 4 - Pict (Browser MVC with Views and Router)",
|
|
5
|
+
"main": "source/BookStore-Application.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "node generate-build-config.js",
|
|
8
|
+
"build": "npx quack build && npx quack copy",
|
|
9
|
+
"start": "node server.js",
|
|
10
|
+
"demo": "npm run build && npm start"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"pict": "^1.0.343",
|
|
14
|
+
"pict-application": "^1.0.28",
|
|
15
|
+
"pict-router": "^1.0.4",
|
|
16
|
+
"pict-view": "^1.0.64",
|
|
17
|
+
"pict-provider": "^1.0.3",
|
|
18
|
+
"orator": "^5.0.2",
|
|
19
|
+
"orator-serviceserver-restify": "^2.0.5",
|
|
20
|
+
"fable": "^3.1.51"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"quackage": "^1.0.41"
|
|
24
|
+
},
|
|
25
|
+
"copyFilesSettings": {
|
|
26
|
+
"whenFileExists": "overwrite"
|
|
27
|
+
},
|
|
28
|
+
"copyFiles": [
|
|
29
|
+
{
|
|
30
|
+
"from": "./html/*",
|
|
31
|
+
"to": "./dist/"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"from": "./node_modules/pict/dist/*",
|
|
35
|
+
"to": "./dist/js/"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Simple static file server using Orator to serve the built Pict application
|
|
2
|
+
const libFable = require('fable');
|
|
3
|
+
const libOrator = require('orator');
|
|
4
|
+
const libOratorServiceServerRestify = require('orator-serviceserver-restify');
|
|
5
|
+
|
|
6
|
+
let _Fable = new libFable(
|
|
7
|
+
{
|
|
8
|
+
Product: 'BookStore-Server',
|
|
9
|
+
ProductVersion: '1.0.0',
|
|
10
|
+
APIServerPort: 8086
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
_Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
|
|
14
|
+
_Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
|
|
15
|
+
_Fable.serviceManager.addServiceType('Orator', libOrator);
|
|
16
|
+
let _Orator = _Fable.serviceManager.instantiateServiceProvider('Orator');
|
|
17
|
+
|
|
18
|
+
_Orator.initialize(
|
|
19
|
+
function ()
|
|
20
|
+
{
|
|
21
|
+
_Orator.addStaticRoute(`${__dirname}/dist/`, 'index.html');
|
|
22
|
+
|
|
23
|
+
_Orator.startService(
|
|
24
|
+
function ()
|
|
25
|
+
{
|
|
26
|
+
_Fable.log.info('Open http://localhost:8086 in your browser');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Name": "BookStore Pict Application",
|
|
3
|
+
"Hash": "BookStore",
|
|
4
|
+
|
|
5
|
+
"MainViewportViewIdentifier": "BookStore-Layout",
|
|
6
|
+
|
|
7
|
+
"AutoSolveAfterInitialize": true,
|
|
8
|
+
"AutoRenderMainViewportViewAfterInitialize": false,
|
|
9
|
+
"AutoRenderViewsAfterInitialize": false,
|
|
10
|
+
|
|
11
|
+
"pict_configuration":
|
|
12
|
+
{
|
|
13
|
+
"Product": "BookStore-Pict"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const libPictApplication = require('pict-application');
|
|
2
|
+
const libPictRouter = require('pict-router');
|
|
3
|
+
|
|
4
|
+
const libViewLayout = require('./views/View-Layout.js');
|
|
5
|
+
const libViewHome = require('./views/View-Home.js');
|
|
6
|
+
const libViewAbout = require('./views/View-About.js');
|
|
7
|
+
|
|
8
|
+
class BookStoreApplication extends libPictApplication
|
|
9
|
+
{
|
|
10
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
11
|
+
{
|
|
12
|
+
super(pFable, pOptions, pServiceHash);
|
|
13
|
+
|
|
14
|
+
this.pict.addProvider('PictRouter', require('./providers/Router-Config.json'), libPictRouter);
|
|
15
|
+
|
|
16
|
+
this.pict.addView('BookStore-Layout', libViewLayout.default_configuration, libViewLayout);
|
|
17
|
+
this.pict.addView('BookStore-Home', libViewHome.default_configuration, libViewHome);
|
|
18
|
+
this.pict.addView('BookStore-About', libViewAbout.default_configuration, libViewAbout);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
onAfterInitializeAsync(fCallback)
|
|
22
|
+
{
|
|
23
|
+
this.pict.AppData.BookStore =
|
|
24
|
+
{
|
|
25
|
+
Title: 'Retold BookStore',
|
|
26
|
+
Books:
|
|
27
|
+
[
|
|
28
|
+
{ Title: 'The Hobbit', Author: 'J.R.R. Tolkien', Year: 1937 },
|
|
29
|
+
{ Title: 'Dune', Author: 'Frank Herbert', Year: 1965 },
|
|
30
|
+
{ Title: 'Neuromancer', Author: 'William Gibson', Year: 1984 }
|
|
31
|
+
]
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
this.pict.views['BookStore-Layout'].render();
|
|
35
|
+
|
|
36
|
+
return super.onAfterInitializeAsync(fCallback);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
navigateTo(pRoute)
|
|
40
|
+
{
|
|
41
|
+
this.pict.providers.PictRouter.navigate(pRoute);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
showView(pViewIdentifier)
|
|
45
|
+
{
|
|
46
|
+
if (pViewIdentifier in this.pict.views)
|
|
47
|
+
{
|
|
48
|
+
this.pict.views[pViewIdentifier].render();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = BookStoreApplication;
|
|
54
|
+
module.exports.default_configuration = require('./BookStore-Application-Config.json');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ProviderIdentifier": "Pict-Router",
|
|
3
|
+
|
|
4
|
+
"AutoInitialize": true,
|
|
5
|
+
"AutoInitializeOrdinal": 0,
|
|
6
|
+
|
|
7
|
+
"Routes":
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"path": "/Home",
|
|
11
|
+
"template": "{~LV:Pict.PictApplication.showView(`BookStore-Home`)~}"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"path": "/About",
|
|
15
|
+
"template": "{~LV:Pict.PictApplication.showView(`BookStore-About`)~}"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: 'BookStore-About',
|
|
6
|
+
DefaultRenderable: 'BookStore-About-Content',
|
|
7
|
+
DefaultDestinationAddress: '#BookStore-Content',
|
|
8
|
+
AutoRender: false,
|
|
9
|
+
|
|
10
|
+
Templates:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
Hash: 'BookStore-About-Template',
|
|
14
|
+
Template: `<h1>About</h1><p>This is a quickstart example for Retold Layer 4: Pict.</p><p>Pict provides browser-side MVC with views, templates, providers, and an application lifecycle. It uses Fable for dependency injection and service management.</p><p><a style="color:#3498db;cursor:pointer" onclick="{~P~}.PictApplication.navigateTo('/Home')">Back to Home</a></p>`
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
|
|
18
|
+
Renderables:
|
|
19
|
+
[
|
|
20
|
+
{
|
|
21
|
+
RenderableHash: 'BookStore-About-Content',
|
|
22
|
+
TemplateHash: 'BookStore-About-Template',
|
|
23
|
+
DestinationAddress: '#BookStore-Content',
|
|
24
|
+
RenderMethod: 'replace'
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
class BookStoreAboutView extends libPictView
|
|
30
|
+
{
|
|
31
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
32
|
+
{
|
|
33
|
+
super(pFable, pOptions, pServiceHash);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = BookStoreAboutView;
|
|
38
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: 'BookStore-Home',
|
|
6
|
+
DefaultRenderable: 'BookStore-Home-Content',
|
|
7
|
+
DefaultDestinationAddress: '#BookStore-Content',
|
|
8
|
+
AutoRender: false,
|
|
9
|
+
|
|
10
|
+
CSS: `
|
|
11
|
+
.bs-book-list { list-style: none; padding: 0; }
|
|
12
|
+
.bs-book-item { padding: 0.75em 1em; margin: 0.5em 0; background: #f8f9fa; border-radius: 6px; border-left: 4px solid #3498db; }
|
|
13
|
+
.bs-book-title { font-weight: 600; }
|
|
14
|
+
.bs-book-author { color: #666; }
|
|
15
|
+
.bs-book-year { color: #999; font-size: 0.9em; }
|
|
16
|
+
`,
|
|
17
|
+
|
|
18
|
+
Templates:
|
|
19
|
+
[
|
|
20
|
+
{
|
|
21
|
+
Hash: 'BookStore-Home-Template',
|
|
22
|
+
Template: `<h1>{~D:AppData.BookStore.Title~}</h1><p>A simple Pict application demonstrating views, templates, and routing.</p><h2>Book Catalog</h2><ul class="bs-book-list">{~TemplateSet:BookStore-Home-BookRow:AppData.BookStore.Books~}</ul>`
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
Hash: 'BookStore-Home-BookRow',
|
|
26
|
+
Template: `<li class="bs-book-item"><span class="bs-book-title">{~D:Record.Title~}</span> <span class="bs-book-author">by {~D:Record.Author~}</span> <span class="bs-book-year">({~D:Record.Year~})</span></li>`
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
|
|
30
|
+
Renderables:
|
|
31
|
+
[
|
|
32
|
+
{
|
|
33
|
+
RenderableHash: 'BookStore-Home-Content',
|
|
34
|
+
TemplateHash: 'BookStore-Home-Template',
|
|
35
|
+
DestinationAddress: '#BookStore-Content',
|
|
36
|
+
RenderMethod: 'replace'
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
class BookStoreHomeView extends libPictView
|
|
42
|
+
{
|
|
43
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
44
|
+
{
|
|
45
|
+
super(pFable, pOptions, pServiceHash);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = BookStoreHomeView;
|
|
50
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: 'BookStore-Layout',
|
|
6
|
+
DefaultRenderable: 'BookStore-Layout-Shell',
|
|
7
|
+
DefaultDestinationAddress: '#BookStore-Container',
|
|
8
|
+
AutoRender: false,
|
|
9
|
+
|
|
10
|
+
CSS: `
|
|
11
|
+
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
|
|
12
|
+
.bs-nav { display: flex; align-items: center; justify-content: space-between; background: #2c3e50; color: #ecf0f1; padding: 0 1.5em; height: 50px; }
|
|
13
|
+
.bs-nav a { color: #bdc3c7; text-decoration: none; padding: 0.5em 0.75em; cursor: pointer; }
|
|
14
|
+
.bs-nav a:hover { color: #fff; }
|
|
15
|
+
.bs-nav-brand { font-size: 1.2em; font-weight: 600; color: #ecf0f1; cursor: pointer; text-decoration: none; }
|
|
16
|
+
#BookStore-Content { max-width: 800px; margin: 2em auto; padding: 0 1em; }
|
|
17
|
+
`,
|
|
18
|
+
|
|
19
|
+
Templates:
|
|
20
|
+
[
|
|
21
|
+
{
|
|
22
|
+
Hash: 'BookStore-Layout-Template',
|
|
23
|
+
Template: `<div class="bs-nav"><a class="bs-nav-brand" onclick="{~P~}.PictApplication.navigateTo('/Home')">Retold BookStore</a><div><a onclick="{~P~}.PictApplication.navigateTo('/Home')">Home</a><a onclick="{~P~}.PictApplication.navigateTo('/About')">About</a></div></div><div id="BookStore-Content"></div>`
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
|
|
27
|
+
Renderables:
|
|
28
|
+
[
|
|
29
|
+
{
|
|
30
|
+
RenderableHash: 'BookStore-Layout-Shell',
|
|
31
|
+
TemplateHash: 'BookStore-Layout-Template',
|
|
32
|
+
DestinationAddress: '#BookStore-Container',
|
|
33
|
+
RenderMethod: 'replace'
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
class BookStoreLayoutView extends libPictView
|
|
39
|
+
{
|
|
40
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
41
|
+
{
|
|
42
|
+
super(pFable, pOptions, pServiceHash);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
onAfterRender()
|
|
46
|
+
{
|
|
47
|
+
this.pict.views['BookStore-Home'].render();
|
|
48
|
+
this.pict.CSSMap.injectCSS();
|
|
49
|
+
|
|
50
|
+
if (this.pict.providers.PictRouter)
|
|
51
|
+
{
|
|
52
|
+
this.pict.providers.PictRouter.resolve();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return super.onAfterRender();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = BookStoreLayoutView;
|
|
60
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Utility: Manyfest - Object Navigation
|
|
2
|
+
|
|
3
|
+
> Retold Utility Layer — Supporting tools: Manyfest (manifest management),
|
|
4
|
+
> Quackage (build), Indoctrinate (documentation), Ultravisor (process
|
|
5
|
+
> supervision), CacheTrax (caching), Precedent (meta-templating), and more
|
|
6
|
+
|
|
7
|
+
Manyfest provides schema-driven JSON object description, navigation, and
|
|
8
|
+
validation. It is used throughout Retold for consistent data access across
|
|
9
|
+
layers. Fable bundles Manyfest as a built-in service.
|
|
10
|
+
|
|
11
|
+
## Run
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install
|
|
15
|
+
npm start
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## What This Demonstrates
|
|
19
|
+
|
|
20
|
+
- Defining a manifest schema with descriptors, data types, and defaults
|
|
21
|
+
- Reading and writing values by dot-notation address (`Author.Name`)
|
|
22
|
+
- Hash-based lookups for aliased field access (e.g. `AuthorName` -> `Author.Name`)
|
|
23
|
+
- Setting values on nested paths that don't exist yet
|
|
24
|
+
- Populating objects with default values from the schema
|
|
25
|
+
- Validating objects against schema type constraints
|
|
26
|
+
- Using Manyfest as a Fable service via `_Fable.newManyfest()`
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const libFable = require('fable');
|
|
2
|
+
const libManyfest = require('manyfest');
|
|
3
|
+
|
|
4
|
+
let _Fable = new libFable(
|
|
5
|
+
{
|
|
6
|
+
Product: 'ManyfestDemo',
|
|
7
|
+
ProductVersion: '1.0.0'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// 1. Define a schema with descriptors
|
|
11
|
+
let _BookManifest = new libManyfest(
|
|
12
|
+
{
|
|
13
|
+
Scope: 'Book',
|
|
14
|
+
Descriptors:
|
|
15
|
+
{
|
|
16
|
+
'IDBook':
|
|
17
|
+
{
|
|
18
|
+
Name: 'Book ID',
|
|
19
|
+
Hash: 'ID',
|
|
20
|
+
DataType: 'Integer',
|
|
21
|
+
Default: 0
|
|
22
|
+
},
|
|
23
|
+
'Title':
|
|
24
|
+
{
|
|
25
|
+
Name: 'Title',
|
|
26
|
+
Hash: 'Title',
|
|
27
|
+
DataType: 'String',
|
|
28
|
+
Default: 'Untitled'
|
|
29
|
+
},
|
|
30
|
+
'Author.Name':
|
|
31
|
+
{
|
|
32
|
+
Name: 'Author Name',
|
|
33
|
+
Hash: 'AuthorName',
|
|
34
|
+
DataType: 'String',
|
|
35
|
+
Default: 'Unknown'
|
|
36
|
+
},
|
|
37
|
+
'Author.BirthYear':
|
|
38
|
+
{
|
|
39
|
+
Name: 'Author Birth Year',
|
|
40
|
+
Hash: 'AuthorBirthYear',
|
|
41
|
+
DataType: 'Integer',
|
|
42
|
+
Default: 0
|
|
43
|
+
},
|
|
44
|
+
'Genre':
|
|
45
|
+
{
|
|
46
|
+
Name: 'Genre',
|
|
47
|
+
Hash: 'Genre',
|
|
48
|
+
DataType: 'String',
|
|
49
|
+
Default: 'Fiction'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// 2. Create a book object
|
|
55
|
+
let tmpBook =
|
|
56
|
+
{
|
|
57
|
+
IDBook: 1,
|
|
58
|
+
Title: 'The Hobbit',
|
|
59
|
+
Author:
|
|
60
|
+
{
|
|
61
|
+
Name: 'J.R.R. Tolkien',
|
|
62
|
+
BirthYear: 1892
|
|
63
|
+
},
|
|
64
|
+
Genre: 'Fantasy'
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
_Fable.log.info('--- Manyfest Object Navigation Demo ---');
|
|
68
|
+
|
|
69
|
+
// 3. Read values by address (dot notation)
|
|
70
|
+
_Fable.log.info(`Title: ${_BookManifest.getValueAtAddress(tmpBook, 'Title')}`);
|
|
71
|
+
_Fable.log.info(`Author: ${_BookManifest.getValueAtAddress(tmpBook, 'Author.Name')}`);
|
|
72
|
+
_Fable.log.info(`Birth Year: ${_BookManifest.getValueAtAddress(tmpBook, 'Author.BirthYear')}`);
|
|
73
|
+
|
|
74
|
+
// 4. Read values by hash (aliases)
|
|
75
|
+
_Fable.log.info(`By hash 'AuthorName': ${_BookManifest.getValueByHash(tmpBook, 'AuthorName')}`);
|
|
76
|
+
_Fable.log.info(`By hash 'ID': ${_BookManifest.getValueByHash(tmpBook, 'ID')}`);
|
|
77
|
+
|
|
78
|
+
// 5. Write values by address
|
|
79
|
+
_BookManifest.setValueAtAddress(tmpBook, 'Title', 'The Hobbit (Revised Edition)');
|
|
80
|
+
_Fable.log.info(`Updated title: ${_BookManifest.getValueAtAddress(tmpBook, 'Title')}`);
|
|
81
|
+
|
|
82
|
+
// 6. Write nested values that don't exist yet
|
|
83
|
+
_BookManifest.setValueAtAddress(tmpBook, 'Publisher.Name', 'Allen & Unwin');
|
|
84
|
+
_Fable.log.info(`Publisher: ${_BookManifest.getValueAtAddress(tmpBook, 'Publisher.Name')}`);
|
|
85
|
+
|
|
86
|
+
// 7. Populate defaults for missing fields
|
|
87
|
+
let tmpEmptyBook = { IDBook: 42 };
|
|
88
|
+
_Fable.log.info('\nBefore populate defaults:');
|
|
89
|
+
_Fable.log.info(` Has Title property: ${'Title' in tmpEmptyBook}`);
|
|
90
|
+
_Fable.log.info(` Has Author.Name property: ${tmpEmptyBook.Author !== undefined}`);
|
|
91
|
+
|
|
92
|
+
_BookManifest.populateDefaults(tmpEmptyBook);
|
|
93
|
+
_Fable.log.info('After populate defaults:');
|
|
94
|
+
_Fable.log.info(` Title: ${tmpEmptyBook.Title}`);
|
|
95
|
+
_Fable.log.info(` Author.Name: ${tmpEmptyBook.Author ? tmpEmptyBook.Author.Name : 'N/A'}`);
|
|
96
|
+
_Fable.log.info(` Genre: ${tmpEmptyBook.Genre}`);
|
|
97
|
+
|
|
98
|
+
// 8. Validate an object
|
|
99
|
+
let tmpValidation = _BookManifest.validate(tmpBook);
|
|
100
|
+
_Fable.log.info(`\nValidation of full book: ${tmpValidation.Error ? 'INVALID' : 'VALID'}`);
|
|
101
|
+
if (tmpValidation.Errors.length > 0)
|
|
102
|
+
{
|
|
103
|
+
_Fable.log.info(` Errors: ${tmpValidation.Errors.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 9. Manyfest is also available as a Fable service
|
|
107
|
+
let tmpManifest = _Fable.newManyfest(
|
|
108
|
+
{
|
|
109
|
+
Scope: 'Config',
|
|
110
|
+
Descriptors:
|
|
111
|
+
{
|
|
112
|
+
'Database.Host': { Name: 'DB Host', DataType: 'String', Default: 'localhost' },
|
|
113
|
+
'Database.Port': { Name: 'DB Port', DataType: 'Integer', Default: 3306 }
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
let tmpConfig = {};
|
|
117
|
+
tmpManifest.populateDefaults(tmpConfig);
|
|
118
|
+
_Fable.log.info(`\nFable Manyfest service - DB Host: ${tmpManifest.getValueAtAddress(tmpConfig, 'Database.Host')}`);
|
|
119
|
+
_Fable.log.info(`Fable Manyfest service - DB Port: ${tmpManifest.getValueAtAddress(tmpConfig, 'Database.Port')}`);
|
|
120
|
+
|
|
121
|
+
_Fable.log.info('\n--- Manyfest Demo Complete ---');
|