alchemymvc 1.3.22 → 1.4.0-alpha.2

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.
Files changed (155) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -3
  3. package/lib/app/behaviour/publishable_behaviour.js +5 -5
  4. package/lib/app/behaviour/revision_behaviour.js +96 -59
  5. package/lib/app/behaviour/sluggable_behaviour.js +14 -14
  6. package/lib/app/conduit/electron_conduit.js +9 -9
  7. package/lib/app/conduit/http_conduit.js +13 -13
  8. package/lib/app/conduit/loopback_conduit.js +15 -15
  9. package/lib/app/conduit/socket_conduit.js +43 -43
  10. package/lib/app/config/routes.js +26 -0
  11. package/lib/app/controller/00-default_app_controller.js +21 -0
  12. package/lib/app/controller/alchemy_info_controller.js +12 -12
  13. package/lib/app/datasource/mongo_datasource.js +27 -18
  14. package/lib/app/element/00-default_app_element.js +19 -0
  15. package/lib/app/element/time_ago.js +5 -5
  16. package/lib/app/helper/00-default_app_helper.js +11 -0
  17. package/lib/app/helper/alchemy_helper.js +22 -22
  18. package/lib/app/helper/backed_map.js +1 -1
  19. package/lib/app/helper/breadcrumb.js +10 -10
  20. package/lib/app/helper/client_collection.js +3 -3
  21. package/lib/app/helper/cron.js +29 -29
  22. package/lib/app/helper/enum_values.js +6 -6
  23. package/lib/app/helper/pagination_helper.js +36 -36
  24. package/lib/app/helper/router_helper.js +35 -35
  25. package/lib/app/helper/socket_helper.js +57 -57
  26. package/lib/app/helper/syncable.js +62 -62
  27. package/lib/app/helper_component/paginate_component.js +9 -9
  28. package/lib/app/helper_controller/component.js +1 -1
  29. package/lib/app/helper_controller/conduit.js +31 -31
  30. package/lib/app/helper_controller/controller.js +54 -39
  31. package/lib/app/helper_datasource/00-nosql_datasource.js +624 -70
  32. package/lib/app/helper_datasource/05-fallback_datasource.js +10 -10
  33. package/lib/app/helper_datasource/idb_datasource.js +6 -6
  34. package/lib/app/helper_datasource/indexed_db.js +22 -22
  35. package/lib/app/helper_datasource/remote_datasource.js +5 -5
  36. package/lib/app/helper_error/http_error.js +4 -4
  37. package/lib/app/helper_error/model_error.js +2 -2
  38. package/lib/app/helper_error/validation_error.js +12 -12
  39. package/lib/app/helper_field/00-objectid_field.js +7 -7
  40. package/lib/app/helper_field/05-string_field.js +16 -12
  41. package/lib/app/helper_field/06-text_field.js +2 -4
  42. package/lib/app/helper_field/10-number_field.js +9 -12
  43. package/lib/app/helper_field/11-date_field.js +15 -15
  44. package/lib/app/helper_field/15-local_temporal_field.js +10 -10
  45. package/lib/app/helper_field/20-decimal_field.js +8 -9
  46. package/lib/app/helper_field/belongsto_field.js +1 -1
  47. package/lib/app/helper_field/big_int_field.js +8 -8
  48. package/lib/app/helper_field/boolean_field.js +9 -11
  49. package/lib/app/helper_field/datetime_field.js +3 -3
  50. package/lib/app/helper_field/enum_field.js +13 -8
  51. package/lib/app/helper_field/fixed_decimal_field.js +6 -7
  52. package/lib/app/helper_field/geopoint_field.js +9 -10
  53. package/lib/app/helper_field/habtm_field.js +3 -3
  54. package/lib/app/helper_field/hasoneparent_field.js +1 -1
  55. package/lib/app/helper_field/html_field.js +2 -4
  56. package/lib/app/helper_field/integer_field.js +8 -11
  57. package/lib/app/helper_field/local_date_field.js +5 -5
  58. package/lib/app/helper_field/local_date_time_field.js +5 -5
  59. package/lib/app/helper_field/local_time_field.js +5 -5
  60. package/lib/app/helper_field/mixed_field.js +5 -5
  61. package/lib/app/helper_field/object_field.js +6 -6
  62. package/lib/app/helper_field/password_field.js +3 -3
  63. package/lib/app/helper_field/regexp_field.js +7 -9
  64. package/lib/app/helper_field/schema_field.js +91 -88
  65. package/lib/app/helper_field/settings_field.js +92 -0
  66. package/lib/app/helper_field/time_field.js +6 -6
  67. package/lib/app/helper_field/url_field.js +2 -4
  68. package/lib/app/helper_model/00-base_criteria.js +662 -0
  69. package/lib/app/helper_model/05-criteria_expressions.js +605 -0
  70. package/lib/app/helper_model/10-model_criteria.js +1182 -0
  71. package/lib/app/helper_model/data_provider.js +2 -2
  72. package/lib/app/helper_model/document.js +103 -92
  73. package/lib/app/helper_model/document_list.js +14 -14
  74. package/lib/app/helper_model/field_config.js +11 -11
  75. package/lib/app/helper_model/field_set.js +17 -17
  76. package/lib/app/helper_model/model.js +201 -123
  77. package/lib/app/helper_model/remote_data_provider.js +2 -2
  78. package/lib/app/helper_validator/00_validator.js +16 -16
  79. package/lib/app/helper_validator/not_empty_validator.js +9 -9
  80. package/lib/app/model/00-default_app_model.js +18 -0
  81. package/lib/app/model/05-system_model.js +27 -0
  82. package/lib/app/model/{alchemy_migration_model.js → system_migration_model.js} +4 -4
  83. package/lib/app/model/system_setting_model.js +154 -0
  84. package/lib/app/model/{alchemy_task_history_model.js → system_task_history_model.js} +7 -7
  85. package/lib/app/model/{alchemy_task_model.js → system_task_model.js} +11 -11
  86. package/lib/bootstrap.js +22 -312
  87. package/lib/class/accumulator.js +5 -5
  88. package/lib/class/behaviour.js +5 -5
  89. package/lib/class/component.js +3 -3
  90. package/lib/class/conduit.js +152 -150
  91. package/lib/class/controller.js +42 -42
  92. package/lib/class/datasource.js +74 -79
  93. package/lib/class/document.js +74 -95
  94. package/lib/class/document_list.js +5 -5
  95. package/lib/class/element.js +17 -17
  96. package/lib/class/error.js +3 -3
  97. package/lib/class/field.js +169 -91
  98. package/lib/class/field_value.js +6 -6
  99. package/lib/class/helper.js +3 -3
  100. package/lib/class/inode.js +17 -17
  101. package/lib/class/inode_dir.js +12 -12
  102. package/lib/class/inode_file.js +26 -26
  103. package/lib/class/inode_list.js +4 -4
  104. package/lib/class/migration.js +4 -4
  105. package/lib/class/model.js +146 -165
  106. package/lib/class/path_definition.js +22 -22
  107. package/lib/class/path_evaluator.js +5 -5
  108. package/lib/class/path_param_definition.js +7 -7
  109. package/lib/class/plugin.js +312 -0
  110. package/lib/class/postponement.js +29 -29
  111. package/lib/class/reciprocal.js +8 -8
  112. package/lib/class/route.js +33 -33
  113. package/lib/class/router.js +73 -73
  114. package/lib/class/schema.js +21 -21
  115. package/lib/class/schema_client.js +105 -82
  116. package/lib/class/session.js +63 -29
  117. package/lib/class/session_scene.js +4 -4
  118. package/lib/class/sitemap.js +16 -16
  119. package/lib/class/task.js +39 -39
  120. package/lib/class/task_service.js +43 -47
  121. package/lib/{init → core}/alchemy.js +411 -373
  122. package/lib/{init/functions.js → core/alchemy_functions.js} +113 -91
  123. package/lib/core/alchemy_load_functions.js +715 -0
  124. package/lib/core/base.js +50 -62
  125. package/lib/core/client_alchemy.js +144 -152
  126. package/lib/core/client_base.js +27 -50
  127. package/lib/core/discovery.js +16 -18
  128. package/lib/core/middleware.js +54 -43
  129. package/lib/core/{routing.js → prefix.js} +14 -16
  130. package/lib/core/setting.js +1684 -0
  131. package/lib/core/stage.js +758 -0
  132. package/lib/scripts/create_constants.js +119 -0
  133. package/lib/{init/languages.js → scripts/create_languages.js} +5 -5
  134. package/lib/scripts/create_settings.js +449 -0
  135. package/lib/scripts/create_shared_constants.js +95 -0
  136. package/lib/scripts/create_stages.js +55 -0
  137. package/lib/scripts/init_alchemy.js +51 -0
  138. package/lib/{init/requirements.js → scripts/preload_modules.js} +15 -2
  139. package/lib/scripts/setup_devwatch.js +238 -0
  140. package/lib/stages/00-load_core.js +342 -0
  141. package/lib/stages/05-load_app.js +57 -0
  142. package/lib/stages/10-datasource.js +61 -0
  143. package/lib/stages/15-tasks.js +27 -0
  144. package/lib/stages/20-settings.js +68 -0
  145. package/lib/stages/50-routes.js +218 -0
  146. package/lib/stages/90-server.js +347 -0
  147. package/package.json +5 -7
  148. package/lib/app/helper_model/criteria.js +0 -2294
  149. package/lib/app/helper_model/db_query.js +0 -1488
  150. package/lib/app/routes.js +0 -11
  151. package/lib/core/socket.js +0 -171
  152. package/lib/init/constants.js +0 -158
  153. package/lib/init/devwatch.js +0 -238
  154. package/lib/init/load_functions.js +0 -979
  155. package/lib/stages.js +0 -515
package/lib/app/routes.js DELETED
@@ -1,11 +0,0 @@
1
- Router.add(['get', 'post'], 'APIResource', '/api/{action}', 'Api#{action}');
2
- Router.get('AlchemyInfo', '/alchemy-info', 'AlchemyInfo#info');
3
-
4
- Router.POSTPONED_ROUTE = Router.add({
5
- name : 'AlchemyInfo#postponed',
6
- paths : '/alchemy/postponed/{id}',
7
- methods : ['get'],
8
- can_be_postponed : false,
9
- });
10
-
11
- Router.linkup('Syncable#linkup', 'syncablelink', 'AlchemyInfo#syncable');
@@ -1,171 +0,0 @@
1
- 'use strict';
2
-
3
- let msgpack_parser,
4
- iostream,
5
- types = alchemy.shared('Socket.types'),
6
- path = alchemy.use('path'),
7
- fs = alchemy.use('fs');
8
-
9
- /**
10
- * The "socket" stage:
11
- *
12
- * Create the socket.io listener
13
- *
14
- * @author Jelle De Loecker <jelle@elevenways.be>
15
- * @since 0.1.0
16
- * @version 1.3.5
17
- */
18
- alchemy.sputnik.add(function socket() {
19
-
20
- if (!alchemy.settings.websockets) {
21
- log.info('Websockets have been disabled');
22
- return;
23
- } else {
24
- if (alchemy.settings.websockets == 'optional') {
25
- log.info('Websockets have been enabled optionally');
26
- } else {
27
- log.info('Websockets have been enabled, clients will automatically connect');
28
- }
29
- }
30
-
31
- const socket_io = alchemy.use('socket.io');
32
-
33
- if (!socket_io) {
34
- return log.error('Could not load socket.io!');
35
- }
36
-
37
- iostream = alchemy.use('socket.io-stream');
38
- msgpack_parser = alchemy.use('socket.io-msgpack-parser');
39
-
40
- let socket_io_options = {
41
- serveClient : false,
42
- };
43
-
44
- if (msgpack_parser) {
45
- socket_io_options.parser = msgpack_parser;
46
- }
47
-
48
- // Create the Socket.io listener
49
- alchemy.io = socket_io(alchemy.server, socket_io_options);
50
-
51
- // Get the core client path
52
- let client_path = alchemy.findModule('socket.io-client').module_dir;
53
-
54
- if (msgpack_parser) {
55
- client_path = path.join(client_path, 'dist', 'socket.io.msgpack.min.js');
56
- } else {
57
- client_path = path.join(client_path, 'dist', 'socket.io.min.js');
58
- }
59
-
60
- // Get the stream client path
61
- let stream_path = path.dirname(alchemy.findModule('@11ways/socket.io-stream').module_path);
62
- stream_path = path.resolve(stream_path, 'socket.io-stream.js');
63
-
64
- // Serve the socket io core file
65
- Router.use('/scripts/socket.io.js', function getSocketIo(req, res, next) {
66
- alchemy.minifyScript(client_path, function gotMinifiedPath(err, mpath) {
67
- req.conduit.serveFile(mpath || client_path);
68
- });
69
- });
70
-
71
- // Serve the socket io stream file
72
- Router.use('/scripts/socket.io-stream.js', function getSocketStream(req, res, next) {
73
- alchemy.minifyScript(stream_path, function gotMinifiedPath(err, mpath) {
74
- req.conduit.serveFile(mpath || stream_path);
75
- });
76
- });
77
-
78
- /**
79
- * Handle connections
80
- *
81
- * @author Jelle De Loecker <jelle@develry.be>
82
- * @since 0.0.1
83
- * @version 0.2.0
84
- */
85
- alchemy.io.sockets.on('connection', function onConnect(socket){
86
-
87
- var syncs = {},
88
- latencies = [],
89
- latency_avg = 2,
90
- offset = 0;
91
-
92
- socket.on('timesync', function gotTimesyncRequest(data) {
93
-
94
- var received = Date.now(),
95
- latency;
96
-
97
- // This is the initial request
98
- if (data.count == null) {
99
- data.count = 0;
100
- data.latency_trip = 0;
101
-
102
- // Reset the latencies array
103
- latencies.length = 0;
104
- }
105
-
106
- // Do 8 round trips to determine latency
107
- if (data.latency_trip <= 8) {
108
-
109
- if (data.last_sent) {
110
-
111
- // Latency is the timestamp when we received the response
112
- // minus the timestamp when we sent the request
113
- latency = received - data.last_sent;
114
- latencies.push(latency);
115
- }
116
-
117
- // Wait before responding
118
- setTimeout(function waitForLatency() {
119
- data.last_sent = Date.now();
120
- socket.emit('timesync', data);
121
- }, 100 + (data.latency_trip * 150));
122
-
123
- data.latency_trip++;
124
- } else if (data.latency_trip) {
125
-
126
- latency_avg = ~~(Math.median(latencies) / 2);
127
- offset = (received - latency_avg) - data.client_time;
128
-
129
- socket.emit('timesync', {offset: offset, latency: latency_avg});
130
- }
131
- });
132
-
133
- // Wait for the announcement
134
- socket.once('announce', function gotAnnouncement(data) {
135
-
136
- var SocketClass,
137
- class_name;
138
-
139
- // Try getting the socket class of this type
140
- if (typeof data.type == 'string') {
141
- class_name = data.type.classify();
142
- SocketClass = Classes.Alchemy.Conduit[class_name + 'Socket'];
143
- }
144
-
145
- // If no socket class was found get the regular class
146
- if (!SocketClass) {
147
- SocketClass = Classes.Alchemy.Conduit.Socket;
148
- }
149
-
150
- new SocketClass(socket, data);
151
- });
152
- });
153
- });
154
-
155
- /**
156
- * Connect to another alchemy instance
157
- *
158
- * @author Jelle De Loecker <jelle@develry.be>
159
- * @since 0.1.0
160
- * @version 0.4.0
161
- */
162
- Alchemy.setMethod(function callServer(address, data, callback) {
163
-
164
- var server = new Classes.ClientSocket();
165
-
166
- server.reconnect = false;
167
-
168
- server.connect(address, data, callback);
169
-
170
- return server;
171
- });
@@ -1,158 +0,0 @@
1
- 'use strict';
2
-
3
- var libpath = require('path');
4
-
5
- /**
6
- * Function to define global constants
7
- *
8
- * @author Jelle De Loecker <jelle@develry.be>
9
- * @since 0.4.0
10
- * @version 0.4.0
11
- *
12
- * @type {Function}
13
- */
14
- function DEFINE(name, value) {
15
- Object.defineProperty(global, name, {value: value});
16
- };
17
-
18
- /**
19
- * Use DEFINE for itself
20
- *
21
- * @author Jelle De Loecker <jelle@develry.be>
22
- * @since 0.4.0
23
- * @version 0.4.0
24
- *
25
- * @type {Function}
26
- */
27
- DEFINE('DEFINE', DEFINE);
28
-
29
- /**
30
- * Create a global to __Protoblast
31
- *
32
- * @author Jelle De Loecker <jelle@develry.be>
33
- * @since 0.2.0
34
- * @version 0.4.0
35
- *
36
- * @type {Informer}
37
- */
38
- DEFINE('Blast', __Protoblast);
39
-
40
- /**
41
- * All classes will be collected here
42
- *
43
- * @author Jelle De Loecker <jelle@develry.be>
44
- * @since 0.3.0
45
- * @version 0.3.0
46
- *
47
- * @type {Object}
48
- */
49
- DEFINE('Classes', Blast.Classes);
50
-
51
- /**
52
- * Available types
53
- *
54
- * @author Jelle De Loecker <jelle@elevenways.be>
55
- * @since 1.3.0
56
- * @version 1.3.0
57
- *
58
- * @type {Object}
59
- */
60
- DEFINE('Types', Blast.Types);
61
-
62
- /**
63
- * The new Local Date/Time classes
64
- *
65
- * @author Jelle De Loecker <jelle@elevenways.be>
66
- * @since 1.3.20
67
- * @version 1.3.20
68
- */
69
- DEFINE('LocalDateTime', Blast.Classes.Develry.LocalDateTime);
70
- DEFINE('LocalDate', Blast.Classes.Develry.LocalDate);
71
- DEFINE('LocalTime', Blast.Classes.Develry.LocalTime);
72
-
73
- /**
74
- * The new Decimal classes
75
- *
76
- * @author Jelle De Loecker <jelle@elevenways.be>
77
- * @since 1.3.20
78
- * @version 1.3.20
79
- */
80
- DEFINE('Decimal', Blast.Classes.Develry.Decimal);
81
- DEFINE('MutableDecimal', Blast.Classes.Develry.MutableDecimal);
82
- DEFINE('FixedDecimal', Blast.Classes.Develry.FixedDecimal);
83
- DEFINE('MutableFixedDecimal', Blast.Classes.Develry.MutableFixedDecimal);
84
-
85
- /**
86
- * Path to the directory of the server.js file
87
- *
88
- * @author Jelle De Loecker <jelle@develry.be>
89
- * @since 0.0.1
90
- * @version 1.0.4
91
- *
92
- * @type {String}
93
- */
94
- DEFINE('PATH_ROOT', process.env.PATH_ROOT || libpath.dirname(require.main.janeway_required || require.main.filename));
95
-
96
- /**
97
- * Path to the directory of the base app folder
98
- *
99
- * @author Jelle De Loecker <jelle@develry.be>
100
- * @since 0.0.1
101
- * @version 0.4.0
102
- *
103
- * @type {String}
104
- */
105
- DEFINE('PATH_APP', libpath.resolve(PATH_ROOT, 'app'));
106
-
107
- /**
108
- * Path to the temporary directory
109
- *
110
- * @author Jelle De Loecker <jelle@develry.be>
111
- * @since 0.0.1
112
- * @version 0.4.0
113
- *
114
- * @type {String}
115
- */
116
- DEFINE('PATH_TEMP', libpath.resolve(PATH_ROOT, 'temp'));
117
-
118
- /**
119
- * Path to the core lib path
120
- *
121
- * @author Jelle De Loecker <jelle@develry.be>
122
- * @since 0.0.1
123
- * @version 0.4.0
124
- *
125
- * @type {String}
126
- */
127
- DEFINE('PATH_CORE', libpath.resolve(__dirname, '..'));
128
-
129
- /**
130
- * Debug value
131
- * Actually not a constant, will be changed later
132
- *
133
- * @author Jelle De Loecker <jelle@develry.be>
134
- * @since 0.2.0
135
- * @version 0.4.0
136
- *
137
- * @type {Boolean}
138
- */
139
- global.DEBUG = false;
140
-
141
- /**
142
- * Exit the application with an error message
143
- *
144
- * @author Jelle De Loecker <jelle@develry.be>
145
- * @since 0.0.1
146
- * @version 0.4.0
147
- *
148
- * @type {Function}
149
- */
150
- DEFINE('die', function die(...args) {
151
-
152
- // Print the log
153
- // @TODO: destroy Janeway first
154
- // (but blessed can't revert to original state without segfaulting)
155
- alchemy.Janeway.print(alchemy.SEVERE, args, {level: 2});
156
-
157
- process.exit();
158
- });
@@ -1,238 +0,0 @@
1
- 'use strict';
2
-
3
- var allowedPattern,
4
- extensions,
5
- prevcount,
6
- watchlog,
7
- chokidar,
8
- watcher,
9
- allowed,
10
- ignored,
11
- count,
12
- cwd,
13
- fs;
14
-
15
- if (process.argv.indexOf('--disable-devwatch') > -1) {
16
- return;
17
- }
18
-
19
- if (alchemy.settings.kill_on_file_change) {
20
-
21
- chokidar = alchemy.use('chokidar');
22
-
23
- if (!chokidar) {
24
- log.warn('Can not watch files because Chokidar is not installed');
25
- return;
26
- }
27
-
28
- fs = alchemy.use('fs');
29
-
30
- prevcount = 0;
31
- count = 0;
32
-
33
- ignored = /^app\/public\/views|^temp/;
34
- extensions = ['js', 'json'];
35
- cwd = process.cwd();
36
-
37
- // Get the extensions allowed to kill the server
38
- if (Array.isArray(alchemy.settings.kill_extensions)) {
39
- extensions = alchemy.settings.kill_extensions;
40
- }
41
-
42
- allowedPattern = '';
43
-
44
- // Go over every extensionin the array
45
- extensions.forEach(function eachExtension(extension) {
46
-
47
- if (allowedPattern) {
48
- allowedPattern += '|';
49
- }
50
-
51
- allowedPattern += '\\.' + extension + '$';
52
- });
53
-
54
- // Create the regex
55
- allowed = new RegExp(allowedPattern);
56
-
57
- watchlog = Function.throttle(function watchlog() {
58
-
59
- if (prevcount == count) {
60
- return;
61
- }
62
-
63
- log.warn(count, 'files are being monitored for changes');
64
- prevcount = count;
65
- }, 1500, false, true);
66
-
67
- // Use a map to log path results, because chokidar calls the `ignored`
68
- // option multiple times for each file
69
- let seen_map = new Map();
70
-
71
- // Start watching all the files, starting with the current working directory
72
- watcher = chokidar.watch(cwd, {ignored: function ignoreThisPath(_path) {
73
-
74
- let cached = seen_map.get(_path);
75
-
76
- if (cached != null) {
77
- return cached;
78
- }
79
-
80
- let isAllowed,
81
- path = _path,
82
- stat = arguments[1],
83
- file;
84
-
85
- // Ignore git folders
86
- if (~path.indexOf('.git')) {
87
- seen_map.set(_path, true);
88
- return true;
89
- }
90
-
91
- // Ignore non-stylesheet files in asset or public folders
92
- if (~path.indexOf('/assets/') || ~path.indexOf('/public/')) {
93
- // DO watch less files, for the stylesheet reload!
94
- if (path.indexOf('.') > -1 && !path.endsWith('.less') && !path.endsWith('.css') && !path.endsWith('.scss')) {
95
- seen_map.set(_path, true);
96
- return true;
97
- } else {
98
- isAllowed = true;
99
- }
100
- }
101
-
102
- // Skip some big module folders by default
103
- if (path.endsWith('/less') || path.endsWith('/caniuse-lite') || path.endsWith('/bcrypt') || path.endsWith('/sass') || path.endsWith('/mmmagic') || path.endsWith('/node-gyp') || path.endsWith('/lodash')) {
104
- seen_map.set(_path, true);
105
- return true;
106
- }
107
-
108
- watchlog();
109
-
110
- if (count > 4999) {
111
- if (count == 5000) {
112
- count++
113
- log.warn('Already watching 5000 files, not watching any more');
114
- }
115
-
116
- seen_map.set(_path, true);
117
- return true;
118
- }
119
-
120
- path = path.replace(cwd+'/', '');
121
- file = path.split('/');
122
- file = file[file.length-1];
123
-
124
- if (file == 'package.json' || file == 'package-lock.json' || file.startsWith('scratch')) {
125
- seen_map.set(_path, true);
126
- return true;
127
- }
128
-
129
- if (path.count('/coverage/') || path.count('/.') || path.count('/test/') || path.count('/benchmark/') || path.count('/deoptigate/')) {
130
- seen_map.set(_path, true);
131
- return true;
132
- }
133
-
134
- if (isAllowed == null) {
135
- // Only allow the specified extensions
136
- isAllowed = allowed.exec(file);
137
- }
138
-
139
- // If it's already false, return it
140
- if (!isAllowed) {
141
- // Only disallow if it's not a directory
142
- try {
143
-
144
- // The stat supplied by chokidar (if it is suppliad at all)
145
- // does not follow symlinks, so *sigh* get it again
146
- stat = fs.statSync(path);
147
-
148
- if (!stat.isDirectory()) {
149
- seen_map.set(_path, true);
150
- return true;
151
- }
152
- } catch (err) {
153
- seen_map.set(_path, true);
154
- // Ignore files that have been removed
155
- return true;
156
- }
157
- }
158
-
159
- // See if it's still allowed based on patterns to ignore
160
- isAllowed = !ignored.exec(path);
161
-
162
- if (isAllowed && path.count('/plugins/') == 1 && path.count('node_modules')) {
163
- isAllowed = false;
164
- }
165
-
166
- if (isAllowed && path.count('node_modules')) {
167
- if (path.count('/codecov/') || path.count('/mocha/') || path.count('/nyc/')) {
168
- isAllowed = false;
169
- }
170
- }
171
-
172
- // If it's still allowed, make sure it isn't 2 or more node_modules deep
173
- if (isAllowed && path.count('node_modules') > 1) {
174
-
175
- if (path.count('node_modules') == 2 && path.endsWith('node_modules')) {
176
- isAllowed = true;
177
- } else if (path.count('protoblast') || path.count('hawkejs') || path.count('janeway')) {
178
- if (path.count('node_modules') > 2) {
179
- isAllowed = false;
180
- }
181
- } else {
182
- isAllowed = false;
183
- }
184
- }
185
-
186
- // If it's still allowed, increase the watch count
187
- if (isAllowed) {
188
- count++;
189
- }
190
-
191
- seen_map.set(_path, !isAllowed);
192
-
193
- // Return if it should be ignored or not
194
- return !isAllowed;
195
-
196
- }, persistent: true});
197
-
198
- // Kill the server when any of the files change
199
- watcher.on('change', function onFileChange(path, stats) {
200
-
201
- // Skip hawkejs client file
202
- if (path.indexOf('hawkejs-client-side.js') > -1) {
203
- return false;
204
- }
205
-
206
- // Skip protoblast client files
207
- if (path.indexOf('protoblast/client-file') > -1) {
208
- return false;
209
- }
210
-
211
- // Also skip files in the temp directory
212
- if (path.indexOf('temp/') === 0) {
213
- return false;
214
- }
215
-
216
- // Skip assets or public files
217
- if (path.indexOf('/assets/') > -1 || path.indexOf('/public/') > -1) {
218
-
219
- if (path.endsWith('.css') || path.endsWith('.scss') || path.endsWith('.less')) {
220
- broadcastReload(path);
221
- }
222
-
223
- return false;
224
- }
225
-
226
- // Only allow defined extensions
227
- if (!allowed.exec(path)) {
228
- return false;
229
- }
230
-
231
- // Kill the process, run together with something like "forever" to restart
232
- die('Killing server because', JSON.stringify(path.replace(cwd + '/', '')), 'has been modified');
233
- });
234
-
235
- let broadcastReload = Function.throttle(function broadcastReload(path) {
236
- alchemy.broadcast('css_reload', path);
237
- }, 10, false, true);
238
- }