cloudcms-server 4.0.0-beta.2 → 4.0.0-beta.21

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 (78) hide show
  1. package/README.md +0 -5
  2. package/cloudcms-server.iml +1 -0
  3. package/index.js +58 -32
  4. package/middleware/authentication/authentication.js +40 -12
  5. package/middleware/authentication/providers/saml.js +8 -4
  6. package/middleware/awareness/awareness.js +8 -7
  7. package/middleware/awareness/plugins/api_event.js +105 -0
  8. package/middleware/awareness/plugins/editorial.js +54 -3
  9. package/middleware/awareness/plugins/resources.js +13 -5
  10. package/middleware/config/adapter.js +0 -44
  11. package/middleware/deployment/deployment.js +22 -24
  12. package/middleware/driver/driver.js +24 -1
  13. package/middleware/driver-config/driver-config.js +0 -6
  14. package/middleware/modules/modules.js +11 -5
  15. package/middleware/perf/perf.js +3 -2
  16. package/middleware/registration/registration.js +0 -5
  17. package/middleware/stores/engines/empty.js +0 -4
  18. package/middleware/stores/engines/fs-caching-adapter.js +0 -5
  19. package/middleware/stores/engines/fs.js +0 -9
  20. package/middleware/stores/engines/s3.js +0 -5
  21. package/middleware/stores/engines/s3fs.js +0 -5
  22. package/middleware/stores/multistore.js +0 -29
  23. package/middleware/stores/store.js +0 -10
  24. package/middleware/stores/stores.js +2 -2
  25. package/middleware/virtual-config/virtual-config.js +253 -206
  26. package/middleware/virtual-files/virtual-files.js +0 -3
  27. package/middleware/welcome/welcome.js +0 -3
  28. package/notifications/notifications.js +72 -10
  29. package/notifications/providers/kafka.js +182 -0
  30. package/notifications/providers/stomp.js +4 -0
  31. package/package.json +40 -56
  32. package/server/index.js +216 -123
  33. package/server/standalone.js +1 -6
  34. package/util/auth.js +10 -4
  35. package/util/cloudcms.js +77 -35
  36. package/util/loaders.js +113 -0
  37. package/util/proxy-factory.js +143 -168
  38. package/util/request.js +6 -2
  39. package/util/workqueue.js +111 -0
  40. package/.last_command +0 -7
  41. package/duster/helpers/core/cloudcms/associations.js +0 -34
  42. package/duster/helpers/core/cloudcms/beta/markdown.js +0 -46
  43. package/duster/helpers/core/cloudcms/beta/nodeAttachmentText.js +0 -46
  44. package/duster/helpers/core/cloudcms/beta/params.js +0 -33
  45. package/duster/helpers/core/cloudcms/beta/processTemplate.js +0 -82
  46. package/duster/helpers/core/cloudcms/content.js +0 -34
  47. package/duster/helpers/core/cloudcms/expand.js +0 -38
  48. package/duster/helpers/core/cloudcms/form.js +0 -34
  49. package/duster/helpers/core/cloudcms/query.js +0 -34
  50. package/duster/helpers/core/cloudcms/queryOne.js +0 -34
  51. package/duster/helpers/core/cloudcms/relatives.js +0 -34
  52. package/duster/helpers/core/cloudcms/search.js +0 -34
  53. package/duster/helpers/core/cloudcms/searchOne.js +0 -34
  54. package/duster/helpers/core/cloudcms/wcm/dependency.js +0 -83
  55. package/duster/helpers/core/cloudcms/wcm/fragment.js +0 -34
  56. package/duster/helpers/core/dev/debug.js +0 -42
  57. package/duster/helpers/core/dom/block.js +0 -49
  58. package/duster/helpers/core/dom/include.js +0 -38
  59. package/duster/helpers/core/dom/layout.js +0 -49
  60. package/duster/helpers/core/dom/link.js +0 -81
  61. package/duster/helpers/core/dom/resource.js +0 -77
  62. package/duster/helpers/core/engine.js +0 -1580
  63. package/duster/helpers/core/ice/value.js +0 -65
  64. package/duster/helpers/core/index.js +0 -49
  65. package/duster/helpers/core/operators/if.js +0 -64
  66. package/duster/helpers/core/operators/iter.js +0 -45
  67. package/duster/helpers/core/operators/iterate.js +0 -129
  68. package/duster/helpers/sample/nyt.js +0 -114
  69. package/duster/index.js +0 -319
  70. package/duster/support.js +0 -436
  71. package/duster/tracker.js +0 -262
  72. package/middleware/authentication/providers/cas.js +0 -73
  73. package/middleware/authentication/providers/facebook.js +0 -120
  74. package/middleware/authentication/providers/github.js +0 -88
  75. package/middleware/authentication/providers/linkedin.js +0 -112
  76. package/middleware/authentication/providers/twitter.js +0 -120
  77. package/middleware/server-tags/server-tags.js +0 -113
  78. package/middleware/wcm/wcm.js +0 -1437
package/duster/support.js DELETED
@@ -1,436 +0,0 @@
1
- var async = require("async");
2
- var path = require("path");
3
- var fs = require("fs");
4
-
5
- var util = require("../util/util");
6
- var renditions = require("../util/renditions");
7
-
8
- /**
9
- * Helper functions for Dust Tags
10
- *
11
- * @type {Function}
12
- */
13
- exports = module.exports = function(dust)
14
- {
15
- var r = {};
16
-
17
- // used to check whether a parameter is defined, meaning it has a value and the value is NON EMPTY.
18
- var isDefined = r.isDefined = function(thing)
19
- {
20
- return ( (typeof(thing) !== "undefined") && (thing !== "") );
21
- };
22
-
23
- /**
24
- * Determines whether to use the fragment cache. We use this cache if we're instructed to and if we're in
25
- * production model.
26
- *
27
- * @returns {boolean}
28
- */
29
- var isFragmentCacheEnabled = r.isFragmentCacheEnabled = function()
30
- {
31
- if (!process.configuration.duster) {
32
- process.configuration.duster = {};
33
- }
34
- if (!process.configuration.duster.fragments) {
35
- process.configuration.duster.fragments = {};
36
- }
37
- if (typeof(process.configuration.duster.fragments.cache) === "undefined") {
38
- process.configuration.duster.fragments.cache = true;
39
- }
40
-
41
- if (process.env.FORCE_CLOUDCMS_DUST_FRAGMENT_CACHE === "true")
42
- {
43
- process.configuration.duster.fragments.cache = true;
44
- }
45
- else if (process.env.FORCE_CLOUDCMS_DUST_FRAGMENT_CACHE === "false")
46
- {
47
- process.configuration.duster.fragments.cache = false;
48
- }
49
-
50
- if (process.env.CLOUDCMS_APPSERVER_MODE !== "production") {
51
- process.configuration.duster.fragments.cache = false;
52
- }
53
-
54
- return process.configuration.duster.fragments.cache;
55
- };
56
-
57
-
58
- var resolveVariables = r.resolveVariables = function(variables, context, callback)
59
- {
60
- if (!variables) {
61
- callback();
62
- return;
63
- }
64
-
65
- if (variables.length === 0)
66
- {
67
- callback(null, []);
68
- return;
69
- }
70
-
71
- var resolvedVariables = [];
72
-
73
- var fns = [];
74
- for (var i = 0; i < variables.length; i++)
75
- {
76
- var fn = function(variable) {
77
- return function(done) {
78
-
79
- dust.renderSource("" + variable, context, function (err, value) {
80
-
81
- if (err) {
82
- done(err);
83
- return;
84
- }
85
-
86
- value = value.trim();
87
-
88
- resolvedVariables.push(value);
89
- done();
90
- });
91
-
92
- }
93
- }(variables[i]);
94
- fns.push(fn);
95
- }
96
-
97
- async.series(fns, function(err) {
98
- callback(err, resolvedVariables);
99
- });
100
- };
101
-
102
- /**
103
- * Helper function that sets the dust cursor to flushable.
104
- * This is to get around an apparent bug with dust:
105
- *
106
- * https://github.com/linkedin/dustjs/issues/303
107
- *
108
- * @param chunk
109
- * @param callback
110
- * @returns {*}
111
- */
112
- var map = r.map = function(chunk, callback)
113
- {
114
- var cursor = chunk.map(function(branch) {
115
- callback(branch);
116
- });
117
- cursor.flushable = true;
118
-
119
- return cursor;
120
- };
121
-
122
- /**
123
- * Helper function to end the chunk. This is in place because it's unclear exactly what is needed to counter
124
- * the issue mentioned in:
125
- *
126
- * https://github.com/linkedin/dustjs/issues/303
127
- *
128
- * At one point, it seemed that some throttling of the end() call was required. It may still be at some point.
129
- * So for now, we use this helper method to end() since it lets us inject our own behaviors if needed.
130
- *
131
- * @param chunk
132
- * @param context
133
- * @param err
134
- */
135
- var end = r.end = function(chunk, context, err)
136
- {
137
- if (err)
138
- {
139
- chunk.setError(err);
140
- }
141
- else
142
- {
143
- chunk.end();
144
- }
145
- };
146
-
147
- var _MARK_INSIGHT = r._MARK_INSIGHT = function(node, result)
148
- {
149
- if (result)
150
- {
151
- result.insightNode = node.getRepositoryId() + "/" + node.getBranchId() + "/" + node.getId();
152
- }
153
- else
154
- {
155
- console.log("WARN: result node should not be null");
156
- console.trace();
157
- }
158
- };
159
-
160
-
161
- //
162
- // tracker related stuff
163
- //
164
-
165
- var buildRequirements = r.buildRequirements = function(context, requirements)
166
- {
167
- var badKeys = [];
168
-
169
- for (var key in requirements)
170
- {
171
- if (!requirements[key])
172
- {
173
- badKeys.push(key);
174
- }
175
- }
176
-
177
- for (var i = 0; i < badKeys.length; i++)
178
- {
179
- delete requirements[badKeys[i]];
180
- }
181
-
182
- // add in stuff from request if available
183
- var req = context.get("req");
184
- if (req)
185
- {
186
- if (req.repositoryId)
187
- {
188
- requirements["repository"] = req.repositoryId;
189
- }
190
-
191
- if (req.branchId)
192
- {
193
- requirements["branch"] = req.branchId;
194
- }
195
- }
196
-
197
- return requirements;
198
- };
199
-
200
- var handleCacheFragmentRead = r.handleCacheFragmentRead = function(context, fragmentId, requirements, callback)
201
- {
202
- if (!isFragmentCacheEnabled())
203
- {
204
- return callback();
205
- }
206
-
207
- var req = context.get("req");
208
-
209
- var contentStore = req.stores.content;
210
-
211
- var fragmentsBasePath = context.get("_fragments_base_path");
212
- if (!fragmentsBasePath) {
213
- fragmentsBasePath = path.join("duster", "repositories", req.repositoryId, "branches", req.branchId, "fragments");
214
- }
215
-
216
- // fragment cache key
217
- var fragmentCacheKey = util.generateFragmentCacheKey(fragmentId, requirements);
218
-
219
- // disk location
220
- var fragmentFilePath = path.join(fragmentsBasePath, fragmentCacheKey, "fragment.html");
221
- util.safeReadStream(contentStore, fragmentFilePath, function(err, stream) {
222
- callback(err, stream, fragmentFilePath, fragmentCacheKey);
223
- });
224
- };
225
-
226
- var handleCacheFragmentWrite = r.handleCacheFragmentWrite = function(context, fragmentDescriptor, fragmentDependencies, requirements, text, callback)
227
- {
228
- // if fragment cache not enabled, return right away
229
- if (!isFragmentCacheEnabled())
230
- {
231
- return callback();
232
- }
233
-
234
- var req = context.get("req");
235
-
236
- var contentStore = req.stores.content;
237
-
238
- var fragmentsBasePath = context.get("_fragments_base_path");
239
- if (!fragmentsBasePath) {
240
- fragmentsBasePath = path.join("duster", "repositories", req.repositoryId, "branches", req.branchId, "fragments");
241
- }
242
-
243
- // fragment cache key
244
- var fragmentCacheKey = util.generateFragmentCacheKey(fragmentDescriptor.fragmentId, requirements);
245
-
246
- // store this
247
- fragmentDescriptor.fragmentCacheKey = fragmentCacheKey;
248
-
249
- // mark the rendition
250
- if (fragmentDependencies)
251
- {
252
- console.log("marking rendition from dust. fragmentId: " + fragmentDescriptor.fragmentId);
253
- renditions.markRendition(req, fragmentDescriptor, fragmentDependencies, function (err) {
254
-
255
- // if we got an error writing the rendition, then we have to roll back and invalidate disk cache
256
- if (err)
257
- {
258
- var fragmentFolderPath = path.join(fragmentsBasePath, fragmentCacheKey);
259
-
260
- console.log("Caught error on fragment markRendition, invalidating: " + fragmentFolderPath + ", err:" + err);
261
-
262
- _handleCacheFragmentInvalidate(contentStore, fragmentFolderPath, function() {
263
- // done
264
- });
265
- }
266
-
267
- });
268
- }
269
-
270
- // disk location
271
- var fragmentFilePath = path.join(fragmentsBasePath, fragmentCacheKey, "fragment.html");
272
- contentStore.writeFile(fragmentFilePath, text, function(err) {
273
- callback(err, fragmentFilePath, fragmentCacheKey);
274
- });
275
- };
276
-
277
- var handleCacheFragmentInvalidate = r.handleCacheFragmentInvalidate = function(host, fragmentsBasePath, fragmentCacheKey, callback)
278
- {
279
- var fragmentFolderPath = path.join(fragmentsBasePath, fragmentCacheKey);
280
-
281
- // list all of the hosts
282
- var stores = require("../middleware/stores/stores");
283
- stores.produce(host, function (err, stores) {
284
-
285
- if (err) {
286
- return callback(err, fragmentFolderPath);
287
- }
288
-
289
- _handleCacheFragmentInvalidate(stores.content, fragmentFolderPath, function(err, fragmentFolderPath) {
290
- return callback(null, fragmentFolderPath);
291
- });
292
- });
293
- };
294
-
295
- var _handleCacheFragmentInvalidate = function(contentStore, fragmentFolderPath, callback)
296
- {
297
- contentStore.existsDirectory(fragmentFolderPath, function (exists) {
298
-
299
- if (!exists) {
300
- return callback();
301
- }
302
-
303
- contentStore.removeDirectory(fragmentFolderPath, function () {
304
- callback();
305
- });
306
- });
307
- };
308
-
309
- var loadFragment = r.loadFragment = function(context, fragmentId, requirements, callback)
310
- {
311
- if (!isFragmentCacheEnabled())
312
- {
313
- return callback();
314
- }
315
-
316
- if (!fragmentId)
317
- {
318
- return callback();
319
- }
320
-
321
- var req = context.get("req");
322
-
323
- handleCacheFragmentRead(context, fragmentId, requirements, function(err, readStream, readPath, fragmentCacheKey) {
324
-
325
- if (!err && readStream)
326
- {
327
- var req = context.get("req");
328
-
329
- // yes, we found it in cache, so we'll simply pipe it back from disk
330
- req.log("Fragment Cache Hit: " + req.url + "#" + fragmentCacheKey);
331
-
332
- // read stream in
333
- var bufs = [];
334
- readStream.on('data', function(d){ bufs.push(d);});
335
- readStream.on('end', function(){
336
-
337
- var fragment = "" + Buffer.concat(bufs).toString();
338
-
339
- callback(null, fragment);
340
- });
341
-
342
- return;
343
- }
344
-
345
- callback({
346
- "message": "Unable to read fragment: " + fragmentId
347
- });
348
-
349
- });
350
- };
351
-
352
- var renderFragment = r.renderFragment = function(context, fragmentId, requirements, chunk, bodies, callback)
353
- {
354
- if (!isFragmentCacheEnabled() || !fragmentId)
355
- {
356
- chunk.render(bodies.block, context);
357
- end(chunk, context);
358
-
359
- return callback();
360
- }
361
-
362
- var c = chunk.capture(bodies.block, context, function(text, chunk2) {
363
-
364
- // we leave a timeout here so that things can catch up internally within Dust (more oddness!)
365
- setTimeout(function() {
366
-
367
- // for reasons that have everything to do with Dust oddness...
368
- // write to "c" and be sure to end "c" then "chunk2"
369
- c.write(text);
370
- c.end();
371
- chunk2.end();
372
- // NOTE: normally, we'd expect to do something like this
373
- //chunk2.write(text);
374
- //end(chunk2);
375
- // but this doesn't work and it has something to do with dust.map and chunk.capture intermingling weirdly
376
-
377
- // now let's cache it
378
- var fragmentDescriptor = {};
379
- var pageDescriptor = context.get("_page_descriptor");
380
- if (pageDescriptor) {
381
- fragmentDescriptor = util.clone(pageDescriptor, true);
382
- }
383
- fragmentDescriptor.fragmentId = fragmentId;
384
- fragmentDescriptor.scope = "FRAGMENT";
385
-
386
- var tracker = context.get("__tracker");
387
-
388
- var fragmentDependencies = {};
389
- fragmentDependencies.requires = tracker.requires;
390
- fragmentDependencies.produces = tracker.produces;
391
-
392
- // write to cache
393
- handleCacheFragmentWrite(context, fragmentDescriptor, fragmentDependencies, requirements, text, function(err, writtenPath, writtenCacheKey) {
394
-
395
- var req = context.get("req");
396
-
397
- if (err) {
398
- req.log("Fragment Cache Write Failed for URL: " + req.url + ", err: " + JSON.stringify(err, null, " "));
399
- return callback(err);
400
- }
401
-
402
- req.log("Fragment Cache Write: " + req.url + "#" + writtenCacheKey);
403
-
404
- callback();
405
- });
406
- }, 1);
407
- });
408
-
409
- return c;
410
- };
411
-
412
- var addHelpers = r.addHelpers = function(app, dust, filepaths, callback) {
413
-
414
- var fns = [];
415
- for (var i = 0; i < filepaths.length; i++)
416
- {
417
- var fn = function(filepath, app, dust) {
418
- return function(done) {
419
-
420
- require(filepath)(app, dust, function() {
421
- //console.log("Loaded dust helper: " + filepath);
422
- done();
423
- });
424
- }
425
- }(filepaths[i], app, dust);
426
- fns.push(fn);
427
- }
428
-
429
- async.series(fns, function() {
430
- callback();
431
- });
432
-
433
- };
434
-
435
- return r;
436
- };
package/duster/tracker.js DELETED
@@ -1,262 +0,0 @@
1
- var exports = module.exports;
2
-
3
- var util = require("../util/util");
4
-
5
- var trackerInstance = function(context)
6
- {
7
- return context.get("__tracker");
8
- };
9
-
10
- var getParentContext = function(context)
11
- {
12
- var parentContext = null;
13
-
14
- // if this context has a parent...
15
- if (context.stack && context.stack.tail && context.stack.tail.length > 0)
16
- {
17
- // the current tip context
18
- // pop it off and "context" modifies
19
- var currentContext = context.pop();
20
-
21
- // the new tip is the parent
22
- parentContext = context.current();
23
-
24
- // restore the current context as tip
25
- context.push(currentContext);
26
- }
27
-
28
- return parentContext;
29
- };
30
-
31
- var id = exports.id = function(context)
32
- {
33
- var instance = trackerInstance(context);
34
-
35
- return instance.id;
36
- };
37
-
38
- /**
39
- * Starts a tracker within the current context.
40
- *
41
- * The tracker is bound to the Dust context's push and pop methods. A "__tracker" instance holds the dependency
42
- * tracker instance for that particular frame in the stack.
43
- *
44
- * When the context is popped, the tracker for the current frame copies some of it's dependency state from the child
45
- * to the parent. Dependency state is either of type "produces" or "requires".
46
- *
47
- * PRODUCES
48
- * --------
49
- *
50
- * The "produces" dependencies usually identify the content items or display assets that the current execution
51
- * rendered on the screen. It identifies which objects produced the rendered view.
52
- *
53
- * When the context pops, these dependencies always copy from the child context to the parent. Any wrapping fragments
54
- * inherit the produced dependencies of their children, all the way up to the page.
55
- *
56
- * That way, if a product dependency (i.e. a Cloud CMS content node) invalidates, all pages and nested fragments can be
57
- * detected and invalidated at once.
58
- *
59
- * In this sense, it is fair to think of produced dependencies as serving the purpose of how to optimize
60
- * invalidation.
61
- *
62
- * REQUIRES
63
- * --------
64
- *
65
- * The "requires" dependencies identify the required state of the parent such that the cached state of the
66
- * current execution context can be used.
67
- *
68
- * These dependencies are a list of "what must be true" about the outer variables such that we can use the cache
69
- * fragment.
70
- *
71
- * All requires variables are local. They do not propagate up to the parent in the same way as "produces" dependencies.
72
- * Rather, the nested nature of HTML ensures that outer HTML fragments will contain the HTML of inner HTML fragments.
73
- *
74
- * The "requires" dependencies serve as a kind of footprint that allows for a very fast pattern match against the
75
- * current set of known runtime variables at any point in the execution chain. For the top-level page, these include
76
- * things like the repository ID, the branchID and any other request state that was used to produce the page.
77
- *
78
- * All "requires" dependencies pass down to children but they do not pass back up to parents.
79
- *
80
- *
81
- * Requirements should look like:
82
- *
83
- * {
84
- * "param1": "abc",
85
- * "param2": "def"
86
- * }
87
- *
88
- * @param childContext
89
- * @param _id
90
- * @param _requirements
91
- */
92
- var start = exports.start = function(childContext, _id, _requirements)
93
- {
94
- var childTracker = {
95
- "requires": {},
96
- "produces": {}
97
- };
98
-
99
- var fc = function(parentTracker, childTracker, key)
100
- {
101
- if (parentTracker[key] && parentTracker[key].length > 0)
102
- {
103
- for (var k in parentTracker[key])
104
- {
105
- if (!childTracker[key][k]) {
106
- childTracker[key][k] = [];
107
- }
108
-
109
- for (var i = 0; i < parentTracker[key][k].length; i++)
110
- {
111
- childTracker[key][k].push(parentTracker[key][k][i]);
112
- }
113
- }
114
- }
115
- };
116
-
117
- // find the parent context
118
- var parentContext = getParentContext(childContext);
119
- if (parentContext)
120
- {
121
- // copy parent "requires" and "produces" into new child tracker object
122
- var parentTracker = trackerInstance(parentContext);
123
- if (parentTracker)
124
- {
125
- fc(parentTracker, childTracker, "requires");
126
- fc(parentTracker, childTracker, "produces");
127
- }
128
- }
129
-
130
- if (_id)
131
- {
132
- childTracker.id = _id;
133
- }
134
-
135
- if (_requirements)
136
- {
137
- requirements(childContext, _requirements);
138
- }
139
- };
140
-
141
- /**
142
- * Finishes a tracker.
143
- *
144
- * This hands back the tracker state. It also copies tracker dependencies up to the parent tracker.
145
- *
146
- * @param parentContext
147
- * @param childContext
148
- * @returns the tracker context
149
- */
150
- var finish = exports.finish = function(childContext)
151
- {
152
- // child tracker
153
- var childTracker = trackerInstance(childContext);
154
-
155
- // find the parent context
156
- var parentContext = getParentContext(childContext);
157
- if (parentContext)
158
- {
159
- // parent tracker
160
- var parentTracker = trackerInstance(parentContext);
161
-
162
- // now copy stuff back up
163
- if (parentTracker)
164
- {
165
- // any "produces" dependencies always copies up
166
- for (var name in childTracker.produces)
167
- {
168
- var array = childTracker.produces[name];
169
- if (array)
170
- {
171
- if (!parentTracker["produces"][name])
172
- {
173
- parentTracker["produces"][name] = [];
174
- }
175
-
176
- for (var i = 0; i < array.length; i++)
177
- {
178
- if (parentTracker["produces"][name].indexOf(array[i]) === -1)
179
- {
180
- parentTracker["produces"][name].push(array[i]);
181
- }
182
- }
183
- }
184
- }
185
- }
186
- }
187
- };
188
-
189
- /**
190
- * Marks that the current rendering requires the following requirements.
191
- *
192
- * @param context
193
- * @param requirements
194
- */
195
- var requirements = exports.requirements = function(context, requirements)
196
- {
197
- for (var k in requirements)
198
- {
199
- var v = requirements[k];
200
- if (v)
201
- {
202
- requires(context, k, v.value);
203
- }
204
- }
205
- };
206
-
207
- /**
208
- * Marks that the current rendering requires the following key=value to be in place.
209
- *
210
- * @param context
211
- * @param key
212
- * @param value
213
- */
214
- var requires = exports.requires = function(context, key, value)
215
- {
216
- if (typeof(value) !== "undefined" && value !== null)
217
- {
218
- var instance = trackerInstance(context);
219
-
220
- var requires = instance["requires"];
221
-
222
- var array = requires[key];
223
- if (!array)
224
- {
225
- requires[key] = array = [];
226
- }
227
-
228
- if (array.indexOf(value) === -1)
229
- {
230
- array.push(value);
231
- }
232
- }
233
- };
234
-
235
- /**
236
- * Marks that the current rendering produces a result that features the given key=value as part of its output.
237
- *
238
- * @param context
239
- * @param key
240
- * @param value
241
- */
242
- var produces = exports.produces = function(context, key, value)
243
- {
244
- if (typeof(value) !== "undefined" && value !== null)
245
- {
246
- var instance = trackerInstance(context);
247
-
248
- var produces = instance["produces"];
249
-
250
- var array = produces[key];
251
- if (!array)
252
- {
253
- array = [];
254
- produces[key] = array;
255
- }
256
-
257
- if (array.indexOf(value) === -1)
258
- {
259
- array.push(value);
260
- }
261
- }
262
- };