├── javascripts
└── main.js
├── images
├── bg_hr.png
├── blacktocat.png
├── icon_download.png
└── sprite_download.png
├── package.json
├── lib
└── jsonExtender.js
├── stylesheets
├── github-light.css
└── stylesheet.css
├── params.json
├── README.md
└── index.html
/javascripts/main.js:
--------------------------------------------------------------------------------
1 | console.log('This would be the main JS file.');
2 |
--------------------------------------------------------------------------------
/images/bg_hr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maty21/json-server-extension/HEAD/images/bg_hr.png
--------------------------------------------------------------------------------
/images/blacktocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maty21/json-server-extension/HEAD/images/blacktocat.png
--------------------------------------------------------------------------------
/images/icon_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maty21/json-server-extension/HEAD/images/icon_download.png
--------------------------------------------------------------------------------
/images/sprite_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maty21/json-server-extension/HEAD/images/sprite_download.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json-server-extension",
3 | "version": "1.1.2",
4 | "description": "nice additions for json-server in order to support large scale applications",
5 | "main": "lib/jsonExtender.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": ["json","json-server","stub","combine","stub server"],
10 | "author": "maty zisserman",
11 | "license": "MIT",
12 | "dependencies": {
13 | "colors": "^1.1.2",
14 | "fs-extra": "^1.0.0",
15 | "fs-finder": "^1.8.1",
16 | "json-concat": "0.0.1",
17 | "json-server": "^0.9.0",
18 | "require-dir": "^0.3.1"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git+https://github.com/maty21/json-server-extension.git"
23 | },
24 | "bugs": {
25 | "url": "https://github.com/maty21/json-server-extension/issues"
26 | },
27 | "homepage": "https://github.com/maty21/json-server-extension#readme"
28 | }
29 |
--------------------------------------------------------------------------------
/lib/jsonExtender.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const jsonData = './db.json'
4 | const jsonConcat = require("json-concat");
5 | const Finder = require('fs-finder');
6 | const fsExtra = require('fs-extra');
7 | const requireDir = require('require-dir');
8 | const colors = require('colors');
9 | class jsonExtender {
10 | constructor(options) {
11 | const base = __dirname;
12 | this.generatedPath = options.generatedPath || `${base}/generated`
13 | this.filePath = options.filePath;
14 | this.staticPath =options.staticPath||`${base}/static` ;
15 | this.filesToGenerate = [];
16 | this.startingPoint = null;
17 | this.outputs = [];
18 | this.promise = new Promise((resolve,reject)=>{
19 | this.resolve =resolve;
20 | });
21 | }
22 |
23 | register(params) {
24 | if(params instanceof Array ){
25 | this.filesToGenerate.push(...params);
26 | }
27 | else if ( typeof params == 'string' ){
28 | let requires = requireDir(params);
29 | let funcs = Object.keys(requires).map(key => requires[key]) ;
30 | this.filesToGenerate.push(...funcs);
31 | }
32 | }
33 |
34 | generate(isRun=true) {
35 | if(!isRun){
36 | return new Promise((resolve,reject)=>{
37 | return resolve({files:'',filePath:`${this.filePath}`});
38 | })
39 | }
40 | return new Promise((resolve,reject)=>{
41 | this.status = 'success';
42 | let prevFunc = this.extend.bind(this);
43 | this.filesToGenerate.reverse().map(func=> {
44 | this.startingPoint = prevFunc = func(prevFunc);
45 |
46 | })
47 | this.startingPoint(this.createJson.bind(this));
48 | this.promise.then(data=> resolve(data)).catch((e)=>reject(e));
49 |
50 | })
51 |
52 | }
53 |
54 | createJson(object) {
55 | let absolutePath = `${this.generatedPath}/${object.path}`;
56 | fsExtra.outputJSONSync(absolutePath, object.data, null, (err) => {
57 | console.log(err) // => null
58 |
59 | })
60 |
61 | }
62 |
63 |
64 | extend(arr) {
65 |
66 | let generatedFiles = Finder.from(`${this.generatedPath}`).findFiles('*.json');
67 | let staticFiles = Finder.from(`${this.staticPath}`).findFiles('*.json');
68 | let files = [...staticFiles,
69 | ...generatedFiles]
70 | jsonConcat({
71 | src: [
72 | jsonData,
73 | ...files
74 | ],
75 | dest: this.filePath
76 | }, (json)=> {
77 | console.log('___________________________________________________________________________________________'.green)
78 | console.log(`finished successfuly`.green)
79 | console.log(`the files created and combined:`.green)
80 | let counter = 1;
81 | files.map((file)=>{
82 | console.log(` ${counter}) ${file}`.green)
83 | counter++;
84 | })
85 | console.log(`the result saved to ${this.filePath} `.green)
86 | console.log('___________________________________________________________________________________________'.green)
87 | this.resolve({files:`${files}`,filePath:`${this.filePath}`});
88 | });
89 |
90 | }
91 |
92 | }
93 |
94 | module.exports = jsonExtender;
95 |
--------------------------------------------------------------------------------
/stylesheets/github-light.css:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2016 GitHub, Inc.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
24 | */
25 |
26 | .pl-c /* comment */ {
27 | color: #969896;
28 | }
29 |
30 | .pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */,
31 | .pl-s .pl-v /* string variable */ {
32 | color: #0086b3;
33 | }
34 |
35 | .pl-e /* entity */,
36 | .pl-en /* entity.name */ {
37 | color: #795da3;
38 | }
39 |
40 | .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
41 | .pl-s .pl-s1 /* string source */ {
42 | color: #333;
43 | }
44 |
45 | .pl-ent /* entity.name.tag */ {
46 | color: #63a35c;
47 | }
48 |
49 | .pl-k /* keyword, storage, storage.type */ {
50 | color: #a71d5d;
51 | }
52 |
53 | .pl-s /* string */,
54 | .pl-pds /* punctuation.definition.string, string.regexp.character-class */,
55 | .pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
56 | .pl-sr /* string.regexp */,
57 | .pl-sr .pl-cce /* string.regexp constant.character.escape */,
58 | .pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
59 | .pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
60 | color: #183691;
61 | }
62 |
63 | .pl-v /* variable */ {
64 | color: #ed6a43;
65 | }
66 |
67 | .pl-id /* invalid.deprecated */ {
68 | color: #b52a1d;
69 | }
70 |
71 | .pl-ii /* invalid.illegal */ {
72 | color: #f8f8f8;
73 | background-color: #b52a1d;
74 | }
75 |
76 | .pl-sr .pl-cce /* string.regexp constant.character.escape */ {
77 | font-weight: bold;
78 | color: #63a35c;
79 | }
80 |
81 | .pl-ml /* markup.list */ {
82 | color: #693a17;
83 | }
84 |
85 | .pl-mh /* markup.heading */,
86 | .pl-mh .pl-en /* markup.heading entity.name */,
87 | .pl-ms /* meta.separator */ {
88 | font-weight: bold;
89 | color: #1d3e81;
90 | }
91 |
92 | .pl-mq /* markup.quote */ {
93 | color: #008080;
94 | }
95 |
96 | .pl-mi /* markup.italic */ {
97 | font-style: italic;
98 | color: #333;
99 | }
100 |
101 | .pl-mb /* markup.bold */ {
102 | font-weight: bold;
103 | color: #333;
104 | }
105 |
106 | .pl-md /* markup.deleted, meta.diff.header.from-file */ {
107 | color: #bd2c00;
108 | background-color: #ffecec;
109 | }
110 |
111 | .pl-mi1 /* markup.inserted, meta.diff.header.to-file */ {
112 | color: #55a532;
113 | background-color: #eaffea;
114 | }
115 |
116 | .pl-mdr /* meta.diff.range */ {
117 | font-weight: bold;
118 | color: #795da3;
119 | }
120 |
121 | .pl-mo /* meta.output */ {
122 | color: #1d3e81;
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/params.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Json-server-extension",
3 | "tagline": "nice additions for json-server in order to support large scale applications",
4 | "body": "# json-server-extension\r\n\r\njson-server is great for stub server usage\r\nbut in my opinion there where some caveat that i tried to solve in this package\r\n\r\n### so what this package gives you\r\n- [x] **splitting to static files -** json-server can serve only single file but in medium/large applications it not ideal, by using this package you can split your json object to files\r\n- [x] **dynamic generation -** with json server you can generate the whole file\r\n now you can create multiple generated objects decoupled each other and even combine\r\n static and generated files\r\n\r\n## Example\r\nfull example can be found here https://github.com/maty21/json-server-extension-example\r\n### init example\r\n```js\r\nconst jsonServer = require('json-server');\r\nconst _jsonExtender = require('./jsonExtender');\r\n\r\n//options:\r\n//fullPath:fullpath for the combined object\r\n//generatedPath:the path where the generated files will be found\r\n//staticPath:the path where the static files will be found\r\nconst jsonExtender = new _jsonExtender({filePath:'./db_extends.json',\r\n generatedPath:'./generated',\r\n staticPath:'./static'})\r\n\r\n//register accept array of generators or path to the generator scripts\r\n//const funcs = Object.keys(generators).map(key => generators[key])\r\njsonExtender.register('../../../generators');\r\njsonExtender.generate().then((data)=>{\r\n console.log(`wow ${data}`);\r\n var server = jsonServer.create()\r\n var router = jsonServer.router('./db_extends.json')\r\n var middlewares = jsonServer.defaults()\r\n\r\n server.use(middlewares)\r\n server.use(router)\r\n server.listen(4000, function () {\r\n console.log('JSON Server is running')\r\n }).catch((err) => {console.log(err)})\r\n\r\n});\r\n```\r\n### generator Example\r\n\r\n```js\r\nconst amount = 100;\r\n const func =next =>create => {\r\n const path = `feed/feedList.json`;\r\n const data = (amount)=> {\r\n let temp = [];\r\n for (let i = 0; i < amount; i++) {\r\n temp.push({\r\n id: `${i}N12134`,\r\n newNotificationCount: i * 3,\r\n isRead: (i % 2 == 0),\r\n isStarMark: (i % 4 == 0),\r\n iconType: \"SocialNotifications\",\r\n description: i + \": this is a new feed \",\r\n date: new Date(Date.now()).toLocaleString()\r\n }\r\n )\r\n }\r\n return temp;\r\n }\r\n create({data: {feed: data(amount)}, path: path})\r\n next(create);\r\n\r\n}\r\nmodule.exports = func;\r\n```\r\n\r\n\r\n## api\r\n\r\n#### constructor\r\n``constructor({filePath:'string',generatedPath:'string, staticPath:'string'}) ``\r\n- ``fullPath``- fullpath for the combined object\r\n- ``generatedPath``- the path where the generated files will be found ``default\r\n: './generated'``\r\n- ``staticPath``- the path where the static files will be found ``default\r\n: './static'``\r\n\r\n#### register\r\n``register('path name') / register([...generator scripts]) ``\r\n- ``register('path name')`` - a path where the generators scripts will be found the package will insatiate the scripts automatically\r\n- ``register([...generator scripts])`` -array of your generators after requiring them manually\r\n\r\n#### generate\r\n``generate(isRun[default:true]) return promise``\r\n- ``isRun`` - there is ability to not generate the db.json each time good when you want to save the state after you close the process the promise will recive the same data so you will not have to change the code\r\n- ``promise``\r\n - ``resolve`` -{files:array of combined files, filePath:the combined file path }\r\n - ``reject``- error\r\n\r\n### generator\r\n\r\n``` const func= next =>create => {}``` - the generator should be initiated as follows first you will have to call for create this is sync function and the for next\r\n- ``create({data: {feed: generatedObject}, path: path})``\r\n - ``data`` - the generated data where the name of the property will be the routing name in this case ``feed``\r\n - ``path`` - a relative path under the generated path that you set in the constructor where you wish to put the output\r\n- ``next(create)`` - just pass the create function there so it's reference will be passed in the pipeline\r\n",
5 | "note": "Don't delete this file! It's used internally to help with page regeneration."
6 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # json-server-extension
2 |
3 | json-server is great for stub server usage
4 | but in my opinion there where some caveat that i tried to solve in this package
5 |
6 | ### so what this package gives you
7 | - [x] **splitting to static files -** json-server can serve only single file but in medium/large applications it not ideal, by using this package you can split your json object to files
8 | - [x] **dynamic generation -** with json server you can generate the whole file
9 | now you can create multiple generated objects decoupled each other and even combine
10 | static and generated files
11 |
12 | ## Example
13 | full example can be found here https://github.com/maty21/json-server-extension-example
14 | ## Install
15 | `` npm i json-server-extension ``
16 | ### init example
17 | ```js
18 | const jsonServer = require('json-server');
19 | const _jsonExtender = require('./jsonExtender');
20 |
21 | //options:
22 | //fullPath:fullpath for the combined object
23 | //generatedPath:the path where the generated files will be found
24 | //staticPath:the path where the static files will be found
25 | const jsonExtender = new _jsonExtender({filePath:'./db_extends.json',
26 | generatedPath:'./generated',
27 | staticPath:'./static'})
28 |
29 | //register accept array of generators or path to the generator scripts
30 | //const funcs = Object.keys(generators).map(key => generators[key])
31 | jsonExtender.register('../../../generators');
32 | jsonExtender.generate().then((data)=>{
33 | console.log(`wow ${data}`);
34 | var server = jsonServer.create()
35 | var router = jsonServer.router('./db_extends.json')
36 | var middlewares = jsonServer.defaults()
37 |
38 | server.use(middlewares)
39 | server.use(router)
40 | server.listen(4000, function () {
41 | console.log('JSON Server is running')
42 | }).catch((err) => {console.log(err)})
43 |
44 | });
45 | ```
46 | ### generator Example
47 |
48 | ```js
49 | const amount = 100;
50 | const func =next =>create => {
51 | const path = `feed/feedList.json`;
52 | const data = (amount)=> {
53 | let temp = [];
54 | for (let i = 0; i < amount; i++) {
55 | temp.push({
56 | id: `${i}N12134`,
57 | newNotificationCount: i * 3,
58 | isRead: (i % 2 == 0),
59 | isStarMark: (i % 4 == 0),
60 | iconType: "SocialNotifications",
61 | description: i + ": this is a new feed ",
62 | date: new Date(Date.now()).toLocaleString()
63 | }
64 | )
65 | }
66 | return temp;
67 | }
68 | create({data: {feed: data(amount)}, path: path})
69 | next(create);
70 |
71 | }
72 | module.exports = func;
73 | ```
74 |
75 |
76 | ## api
77 |
78 | #### constructor
79 | ``constructor({filePath:'string',generatedPath:'string, staticPath:'string'}) ``
80 | - ``fullPath``- fullpath for the combined object
81 | - ``generatedPath``- the path where the generated files will be found ``default
82 | : './generated'``
83 | - ``staticPath``- the path where the static files will be found ``default
84 | : './static'``
85 |
86 | #### register
87 | ``register('path name') / register([...generator scripts]) ``
88 | - ``register('path name')`` - a path where the generators scripts will be found the package will insatiate the scripts automatically
89 | - ``register([...generator scripts])`` -array of your generators after requiring them manually
90 |
91 | #### generate
92 | ``generate(isRun[default:true]) return promise``
93 | - ``isRun`` - there is ability to not generate the db.json each time good when you want to save the state after you close the process the promise will recive the same data so you will not have to change the code
94 | - ``promise``
95 | - ``resolve`` -{files:array of combined files, filePath:the combined file path }
96 | - ``reject``- error
97 |
98 | ### generator
99 |
100 | ``` const func= next =>create => {}``` - the generator should be initiated as follows first you will have to call for create this is sync function and the for next
101 | - ``create({data: {feed: generatedObject}, path: path})``
102 | - ``data`` - the generated data where the name of the property will be the routing name in this case ``feed``
103 | - ``path`` - a relative path under the generated path that you set in the constructor where you wish to put the output
104 | - ``next(create)`` - just pass the create function there so it's reference will be passed in the pipeline
105 |
--------------------------------------------------------------------------------
/stylesheets/stylesheet.css:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Slate Theme for GitHub Pages
3 | by Jason Costello, @jsncostello
4 | *******************************************************************************/
5 |
6 | @import url(github-light.css);
7 |
8 | /*******************************************************************************
9 | MeyerWeb Reset
10 | *******************************************************************************/
11 |
12 | html, body, div, span, applet, object, iframe,
13 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
14 | a, abbr, acronym, address, big, cite, code,
15 | del, dfn, em, img, ins, kbd, q, s, samp,
16 | small, strike, strong, sub, sup, tt, var,
17 | b, u, i, center,
18 | dl, dt, dd, ol, ul, li,
19 | fieldset, form, label, legend,
20 | table, caption, tbody, tfoot, thead, tr, th, td,
21 | article, aside, canvas, details, embed,
22 | figure, figcaption, footer, header, hgroup,
23 | menu, nav, output, ruby, section, summary,
24 | time, mark, audio, video {
25 | margin: 0;
26 | padding: 0;
27 | border: 0;
28 | font: inherit;
29 | vertical-align: baseline;
30 | }
31 |
32 | /* HTML5 display-role reset for older browsers */
33 | article, aside, details, figcaption, figure,
34 | footer, header, hgroup, menu, nav, section {
35 | display: block;
36 | }
37 |
38 | ol, ul {
39 | list-style: none;
40 | }
41 |
42 | table {
43 | border-collapse: collapse;
44 | border-spacing: 0;
45 | }
46 |
47 | /*******************************************************************************
48 | Theme Styles
49 | *******************************************************************************/
50 |
51 | body {
52 | box-sizing: border-box;
53 | color:#373737;
54 | background: #212121;
55 | font-size: 16px;
56 | font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
57 | line-height: 1.5;
58 | -webkit-font-smoothing: antialiased;
59 | }
60 |
61 | h1, h2, h3, h4, h5, h6 {
62 | margin: 10px 0;
63 | font-weight: 700;
64 | color:#222222;
65 | font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
66 | letter-spacing: -1px;
67 | }
68 |
69 | h1 {
70 | font-size: 36px;
71 | font-weight: 700;
72 | }
73 |
74 | h2 {
75 | padding-bottom: 10px;
76 | font-size: 32px;
77 | background: url('../images/bg_hr.png') repeat-x bottom;
78 | }
79 |
80 | h3 {
81 | font-size: 24px;
82 | }
83 |
84 | h4 {
85 | font-size: 21px;
86 | }
87 |
88 | h5 {
89 | font-size: 18px;
90 | }
91 |
92 | h6 {
93 | font-size: 16px;
94 | }
95 |
96 | p {
97 | margin: 10px 0 15px 0;
98 | }
99 |
100 | footer p {
101 | color: #f2f2f2;
102 | }
103 |
104 | a {
105 | text-decoration: none;
106 | color: #007edf;
107 | text-shadow: none;
108 |
109 | transition: color 0.5s ease;
110 | transition: text-shadow 0.5s ease;
111 | -webkit-transition: color 0.5s ease;
112 | -webkit-transition: text-shadow 0.5s ease;
113 | -moz-transition: color 0.5s ease;
114 | -moz-transition: text-shadow 0.5s ease;
115 | -o-transition: color 0.5s ease;
116 | -o-transition: text-shadow 0.5s ease;
117 | -ms-transition: color 0.5s ease;
118 | -ms-transition: text-shadow 0.5s ease;
119 | }
120 |
121 | a:hover, a:focus {text-decoration: underline;}
122 |
123 | footer a {
124 | color: #F2F2F2;
125 | text-decoration: underline;
126 | }
127 |
128 | em {
129 | font-style: italic;
130 | }
131 |
132 | strong {
133 | font-weight: bold;
134 | }
135 |
136 | img {
137 | position: relative;
138 | margin: 0 auto;
139 | max-width: 739px;
140 | padding: 5px;
141 | margin: 10px 0 10px 0;
142 | border: 1px solid #ebebeb;
143 |
144 | box-shadow: 0 0 5px #ebebeb;
145 | -webkit-box-shadow: 0 0 5px #ebebeb;
146 | -moz-box-shadow: 0 0 5px #ebebeb;
147 | -o-box-shadow: 0 0 5px #ebebeb;
148 | -ms-box-shadow: 0 0 5px #ebebeb;
149 | }
150 |
151 | p img {
152 | display: inline;
153 | margin: 0;
154 | padding: 0;
155 | vertical-align: middle;
156 | text-align: center;
157 | border: none;
158 | }
159 |
160 | pre, code {
161 | width: 100%;
162 | color: #222;
163 | background-color: #fff;
164 |
165 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
166 | font-size: 14px;
167 |
168 | border-radius: 2px;
169 | -moz-border-radius: 2px;
170 | -webkit-border-radius: 2px;
171 | }
172 |
173 | pre {
174 | width: 100%;
175 | padding: 10px;
176 | box-shadow: 0 0 10px rgba(0,0,0,.1);
177 | overflow: auto;
178 | }
179 |
180 | code {
181 | padding: 3px;
182 | margin: 0 3px;
183 | box-shadow: 0 0 10px rgba(0,0,0,.1);
184 | }
185 |
186 | pre code {
187 | display: block;
188 | box-shadow: none;
189 | }
190 |
191 | blockquote {
192 | color: #666;
193 | margin-bottom: 20px;
194 | padding: 0 0 0 20px;
195 | border-left: 3px solid #bbb;
196 | }
197 |
198 |
199 | ul, ol, dl {
200 | margin-bottom: 15px
201 | }
202 |
203 | ul {
204 | list-style-position: inside;
205 | list-style: disc;
206 | padding-left: 20px;
207 | }
208 |
209 | ol {
210 | list-style-position: inside;
211 | list-style: decimal;
212 | padding-left: 20px;
213 | }
214 |
215 | dl dt {
216 | font-weight: bold;
217 | }
218 |
219 | dl dd {
220 | padding-left: 20px;
221 | font-style: italic;
222 | }
223 |
224 | dl p {
225 | padding-left: 20px;
226 | font-style: italic;
227 | }
228 |
229 | hr {
230 | height: 1px;
231 | margin-bottom: 5px;
232 | border: none;
233 | background: url('../images/bg_hr.png') repeat-x center;
234 | }
235 |
236 | table {
237 | border: 1px solid #373737;
238 | margin-bottom: 20px;
239 | text-align: left;
240 | }
241 |
242 | th {
243 | font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
244 | padding: 10px;
245 | background: #373737;
246 | color: #fff;
247 | }
248 |
249 | td {
250 | padding: 10px;
251 | border: 1px solid #373737;
252 | }
253 |
254 | form {
255 | background: #f2f2f2;
256 | padding: 20px;
257 | }
258 |
259 | /*******************************************************************************
260 | Full-Width Styles
261 | *******************************************************************************/
262 |
263 | .outer {
264 | width: 100%;
265 | }
266 |
267 | .inner {
268 | position: relative;
269 | max-width: 640px;
270 | padding: 20px 10px;
271 | margin: 0 auto;
272 | }
273 |
274 | #forkme_banner {
275 | display: block;
276 | position: absolute;
277 | top:0;
278 | right: 10px;
279 | z-index: 10;
280 | padding: 10px 50px 10px 10px;
281 | color: #fff;
282 | background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
283 | font-weight: 700;
284 | box-shadow: 0 0 10px rgba(0,0,0,.5);
285 | border-bottom-left-radius: 2px;
286 | border-bottom-right-radius: 2px;
287 | }
288 |
289 | #header_wrap {
290 | background: #212121;
291 | background: -moz-linear-gradient(top, #373737, #212121);
292 | background: -webkit-linear-gradient(top, #373737, #212121);
293 | background: -ms-linear-gradient(top, #373737, #212121);
294 | background: -o-linear-gradient(top, #373737, #212121);
295 | background: linear-gradient(top, #373737, #212121);
296 | }
297 |
298 | #header_wrap .inner {
299 | padding: 50px 10px 30px 10px;
300 | }
301 |
302 | #project_title {
303 | margin: 0;
304 | color: #fff;
305 | font-size: 42px;
306 | font-weight: 700;
307 | text-shadow: #111 0px 0px 10px;
308 | }
309 |
310 | #project_tagline {
311 | color: #fff;
312 | font-size: 24px;
313 | font-weight: 300;
314 | background: none;
315 | text-shadow: #111 0px 0px 10px;
316 | }
317 |
318 | #downloads {
319 | position: absolute;
320 | width: 210px;
321 | z-index: 10;
322 | bottom: -40px;
323 | right: 0;
324 | height: 70px;
325 | background: url('../images/icon_download.png') no-repeat 0% 90%;
326 | }
327 |
328 | .zip_download_link {
329 | display: block;
330 | float: right;
331 | width: 90px;
332 | height:70px;
333 | text-indent: -5000px;
334 | overflow: hidden;
335 | background: url(../images/sprite_download.png) no-repeat bottom left;
336 | }
337 |
338 | .tar_download_link {
339 | display: block;
340 | float: right;
341 | width: 90px;
342 | height:70px;
343 | text-indent: -5000px;
344 | overflow: hidden;
345 | background: url(../images/sprite_download.png) no-repeat bottom right;
346 | margin-left: 10px;
347 | }
348 |
349 | .zip_download_link:hover {
350 | background: url(../images/sprite_download.png) no-repeat top left;
351 | }
352 |
353 | .tar_download_link:hover {
354 | background: url(../images/sprite_download.png) no-repeat top right;
355 | }
356 |
357 | #main_content_wrap {
358 | background: #f2f2f2;
359 | border-top: 1px solid #111;
360 | border-bottom: 1px solid #111;
361 | }
362 |
363 | #main_content {
364 | padding-top: 40px;
365 | }
366 |
367 | #footer_wrap {
368 | background: #212121;
369 | }
370 |
371 |
372 |
373 | /*******************************************************************************
374 | Small Device Styles
375 | *******************************************************************************/
376 |
377 | @media screen and (max-width: 480px) {
378 | body {
379 | font-size:14px;
380 | }
381 |
382 | #downloads {
383 | display: none;
384 | }
385 |
386 | .inner {
387 | min-width: 320px;
388 | max-width: 480px;
389 | }
390 |
391 | #project_title {
392 | font-size: 32px;
393 | }
394 |
395 | h1 {
396 | font-size: 28px;
397 | }
398 |
399 | h2 {
400 | font-size: 24px;
401 | }
402 |
403 | h3 {
404 | font-size: 21px;
405 | }
406 |
407 | h4 {
408 | font-size: 18px;
409 | }
410 |
411 | h5 {
412 | font-size: 14px;
413 | }
414 |
415 | h6 {
416 | font-size: 12px;
417 | }
418 |
419 | code, pre {
420 | min-width: 320px;
421 | max-width: 480px;
422 | font-size: 11px;
423 | }
424 |
425 | }
426 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Json-server-extension
12 |
13 |
14 |
15 |
16 |
17 |
30 |
31 |
32 |
33 |
34 |
35 | json-server-extension
36 |
37 | json-server is great for stub server usage
38 | but in my opinion there where some caveat that i tried to solve in this package
39 |
40 |
41 | so what this package gives you
42 |
43 |
44 | [x] splitting to static files - json-server can serve only single file but in medium/large applications it not ideal, by using this package you can split your json object to files
45 | [x] dynamic generation - with json server you can generate the whole file
46 | now you can create multiple generated objects decoupled each other and even combine
47 | static and generated files
48 |
49 |
50 |
51 | Example
52 |
53 | full example can be found here https://github.com/maty21/json-server-extension-example
54 |
55 |
56 | init example
57 |
58 | const jsonServer = require (' json-server' );
59 | const _jsonExtender = require (' ./jsonExtender' );
60 |
61 | //options:
62 | //fullPath:fullpath for the combined object
63 | //generatedPath:the path where the generated files will be found
64 | //staticPath:the path where the static files will be found
65 | const jsonExtender = new _jsonExtender ({filePath: ' ./db_extends.json' ,
66 | generatedPath: ' ./generated' ,
67 | staticPath: ' ./static' })
68 |
69 | //register accept array of generators or path to the generator scripts
70 | //const funcs = Object.keys(generators).map(key => generators[key])
71 | jsonExtender .register (' ../../../generators' );
72 | jsonExtender .generate ().then ((data )=> {
73 | console .log (` wow ${ data} ` );
74 | var server = jsonServer .create ()
75 | var router = jsonServer .router (' ./db_extends.json' )
76 | var middlewares = jsonServer .defaults ()
77 |
78 | server .use (middlewares)
79 | server .use (router)
80 | server .listen (4000 , function () {
81 | console .log (' JSON Server is running' )
82 | }).catch ((err ) => {console .log (err)})
83 |
84 | });
85 |
86 |
87 | generator Example
88 |
89 | const amount = 100 ;
90 | const func = next => create => {
91 | const path = ` feed/feedList.json` ;
92 | const data = (amount )=> {
93 | let temp = [];
94 | for (let i = 0 ; i < amount; i++ ) {
95 | temp .push ({
96 | id: ` ${ i} N12134` ,
97 | newNotificationCount: i * 3 ,
98 | isRead: (i % 2 == 0 ),
99 | isStarMark: (i % 4 == 0 ),
100 | iconType: " SocialNotifications" ,
101 | description: i + " : this is a new feed " ,
102 | date: new Date (Date .now ()).toLocaleString ()
103 | }
104 | )
105 | }
106 | return temp;
107 | }
108 | create ({data: {feed: data (amount)}, path: path})
109 | next (create);
110 |
111 | }
112 | module .exports = func;
113 |
114 |
115 | api
116 |
117 |
118 | constructor
119 |
120 | constructor({filePath:'string',generatedPath:'string, staticPath:'string'})
121 |
122 |
123 |
124 | fullPath- fullpath for the combined object
125 |
126 | generatedPath- the path where the generated files will be found default
127 | : './generated'
128 |
129 |
130 | staticPath- the path where the static files will be found default
131 | : './static'
132 |
133 |
134 |
135 |
136 | register
137 |
138 | register('path name') / register([...generator scripts])
139 |
140 |
141 |
142 | register('path name') - a path where the generators scripts will be found the package will insatiate the scripts automatically
143 |
144 | register([...generator scripts]) -array of your generators after requiring them manually
145 |
146 |
147 |
148 | generate
149 |
150 | generate(isRun[default:true]) return promise
151 |
152 |
153 |
154 | isRun - there is ability to not generate the db.json each time good when you want to save the state after you close the process the promise will recive the same data so you will not have to change the code
155 |
156 | promise
157 |
158 |
159 |
160 | resolve -{files:array of combined files, filePath:the combined file path }
161 |
162 | reject- error
163 |
164 |
165 |
166 |
167 |
168 | generator
169 |
170 | const func= next =>create => {} - the generator should be initiated as follows first you will have to call for create this is sync function and the for next
171 |
172 |
173 |
174 | create({data: {feed: generatedObject}, path: path})
175 |
176 |
177 |
178 | data - the generated data where the name of the property will be the routing name in this case feed
179 |
180 |
181 | path - a relative path under the generated path that you set in the constructor where you wish to put the output
182 |
183 |
184 |
185 | next(create) - just pass the create function there so it's reference will be passed in the pipeline
186 |
187 |
188 |
189 |
190 |
191 |
197 |
198 |
199 |
200 |
201 |
202 |
--------------------------------------------------------------------------------