traits 0.3.0 → 0.5.0

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 (106) hide show
  1. package/Assessment.ts +14 -0
  2. package/LICENSE +203 -0
  3. package/Source.ts +13 -0
  4. package/Trait.ts +51 -0
  5. package/TraitConflict.ts +52 -0
  6. package/TraitDerivation.ts +137 -0
  7. package/TraitEvaluation.ts +69 -0
  8. package/TraitStore.ts +88 -0
  9. package/TraitsConfig.ts +57 -0
  10. package/TraitsContext.ts +11 -0
  11. package/_util/Approval.ts +59 -0
  12. package/_util/Git.ts +25 -0
  13. package/_util/TraitsConfigProvider.ts +22 -0
  14. package/_util/TraitsTelemetry.ts +20 -0
  15. package/_util/words.ts +555 -0
  16. package/commands/init.ts +73 -0
  17. package/dist/Assessment.d.ts +12 -0
  18. package/dist/Assessment.d.ts.map +1 -0
  19. package/dist/Assessment.js +12 -0
  20. package/dist/Assessment.js.map +1 -0
  21. package/dist/Source.d.ts +21 -0
  22. package/dist/Source.d.ts.map +1 -0
  23. package/dist/Source.js +10 -0
  24. package/dist/Source.js.map +1 -0
  25. package/dist/Trait.d.ts +12 -0
  26. package/dist/Trait.d.ts.map +1 -0
  27. package/dist/Trait.js +44 -0
  28. package/dist/Trait.js.map +1 -0
  29. package/dist/TraitConflict.d.ts +56 -0
  30. package/dist/TraitConflict.d.ts.map +1 -0
  31. package/dist/TraitConflict.js +47 -0
  32. package/dist/TraitConflict.js.map +1 -0
  33. package/dist/TraitDerivation.d.ts +99 -0
  34. package/dist/TraitDerivation.d.ts.map +1 -0
  35. package/dist/TraitDerivation.js +109 -0
  36. package/dist/TraitDerivation.js.map +1 -0
  37. package/dist/TraitEvaluation.d.ts +68 -0
  38. package/dist/TraitEvaluation.d.ts.map +1 -0
  39. package/dist/TraitEvaluation.js +61 -0
  40. package/dist/TraitEvaluation.js.map +1 -0
  41. package/dist/TraitStore.d.ts +17 -0
  42. package/dist/TraitStore.d.ts.map +1 -0
  43. package/dist/TraitStore.js +57 -0
  44. package/dist/TraitStore.js.map +1 -0
  45. package/dist/TraitsConfig.d.ts +14 -0
  46. package/dist/TraitsConfig.d.ts.map +1 -0
  47. package/dist/TraitsConfig.js +40 -0
  48. package/dist/TraitsConfig.js.map +1 -0
  49. package/dist/TraitsContext.d.ts +11 -0
  50. package/dist/TraitsContext.d.ts.map +1 -0
  51. package/dist/TraitsContext.js +4 -0
  52. package/dist/TraitsContext.js.map +1 -0
  53. package/dist/_util/Approval.d.ts +28 -0
  54. package/dist/_util/Approval.d.ts.map +1 -0
  55. package/dist/_util/Approval.js +48 -0
  56. package/dist/_util/Approval.js.map +1 -0
  57. package/dist/_util/Git.d.ts +15 -0
  58. package/dist/_util/Git.d.ts.map +1 -0
  59. package/dist/_util/Git.js +17 -0
  60. package/dist/_util/Git.js.map +1 -0
  61. package/dist/_util/TraitsConfigProvider.d.ts +3 -0
  62. package/dist/_util/TraitsConfigProvider.d.ts.map +1 -0
  63. package/dist/_util/TraitsConfigProvider.js +17 -0
  64. package/dist/_util/TraitsConfigProvider.js.map +1 -0
  65. package/dist/_util/TraitsTelemetry.d.ts +3 -0
  66. package/dist/_util/TraitsTelemetry.d.ts.map +1 -0
  67. package/dist/_util/TraitsTelemetry.js +12 -0
  68. package/dist/_util/TraitsTelemetry.js.map +1 -0
  69. package/dist/_util/words.d.ts +2 -0
  70. package/dist/_util/words.d.ts.map +1 -0
  71. package/dist/_util/words.js +556 -0
  72. package/dist/_util/words.js.map +1 -0
  73. package/dist/commands/init.d.ts +4 -0
  74. package/dist/commands/init.d.ts.map +1 -0
  75. package/dist/commands/init.js +67 -0
  76. package/dist/commands/init.js.map +1 -0
  77. package/dist/index.d.ts +10 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +10 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/main.d.ts +3 -0
  82. package/dist/main.d.ts.map +1 -0
  83. package/dist/main.js +73 -0
  84. package/dist/main.js.map +1 -0
  85. package/dist/package.json +53 -0
  86. package/dist/toolkit/CheckTraits.d.ts +79 -0
  87. package/dist/toolkit/CheckTraits.d.ts.map +1 -0
  88. package/dist/toolkit/CheckTraits.js +110 -0
  89. package/dist/toolkit/CheckTraits.js.map +1 -0
  90. package/dist/toolkit/DeriveTrait.d.ts +108 -0
  91. package/dist/toolkit/DeriveTrait.d.ts.map +1 -0
  92. package/dist/toolkit/DeriveTrait.js +54 -0
  93. package/dist/toolkit/DeriveTrait.js.map +1 -0
  94. package/dist/toolkit/toolkit.d.ts +3 -0
  95. package/dist/toolkit/toolkit.d.ts.map +1 -0
  96. package/dist/toolkit/toolkit.js +6 -0
  97. package/dist/toolkit/toolkit.js.map +1 -0
  98. package/index.ts +9 -0
  99. package/main.ts +113 -0
  100. package/package.json +46 -0
  101. package/skills/traits/SKILL.md +307 -0
  102. package/toolkit/CheckTraits.ts +150 -0
  103. package/toolkit/DeriveTrait.ts +59 -0
  104. package/toolkit/toolkit.ts +9 -0
  105. 1289345810861-0.06061636237427592/lib/traits.js +0 -665
  106. 1289345810861-0.06061636237427592/package.json +0 -7
@@ -1,665 +0,0 @@
1
- // Copyright (C) 2010 Google Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- // See http://code.google.com/p/es-lab/wiki/Traits
16
- // for background on traits and a description of this library
17
-
18
- var Trait = (function(){
19
-
20
- // == Ancillary functions ==
21
-
22
- var SUPPORTS_DEFINEPROP = (function() {
23
- try {
24
- var test = {};
25
- Object.defineProperty(test, 'x', {get: function() { return 0; } } );
26
- return test.x === 0;
27
- } catch(e) {
28
- return false;
29
- }
30
- })();
31
-
32
- // IE8 implements Object.defineProperty and Object.getOwnPropertyDescriptor
33
- // only for DOM objects. These methods don't work on plain objects.
34
- // Hence, we need a more elaborate feature-test to see whether the
35
- // browser truly supports these methods:
36
- function supportsGOPD() {
37
- try {
38
- if (Object.getOwnPropertyDescriptor) {
39
- var test = {x:0};
40
- return !!Object.getOwnPropertyDescriptor(test,'x');
41
- }
42
- } catch(e) {}
43
- return false;
44
- };
45
- function supportsDP() {
46
- try {
47
- if (Object.defineProperty) {
48
- var test = {};
49
- Object.defineProperty(test,'x',{value:0});
50
- return test.x === 0;
51
- }
52
- } catch(e) {}
53
- return false;
54
- };
55
-
56
- var call = Function.prototype.call;
57
-
58
- /**
59
- * An ad hoc version of bind that only binds the 'this' parameter.
60
- */
61
- var bindThis = Function.prototype.bind ?
62
- function(fun, self) { return Function.prototype.bind.call(fun, self); } :
63
- function(fun, self) {
64
- function funcBound(var_args) {
65
- return fun.apply(self, arguments);
66
- }
67
- return funcBound;
68
- };
69
-
70
- var hasOwnProperty = bindThis(call, Object.prototype.hasOwnProperty);
71
- var slice = bindThis(call, Array.prototype.slice);
72
-
73
- // feature testing such that traits.js runs on both ES3 and ES5
74
- var forEach = Array.prototype.forEach ?
75
- bindThis(call, Array.prototype.forEach) :
76
- function(arr, fun) {
77
- for (var i = 0, len = arr.length; i < len; i++) { fun(arr[i]); }
78
- };
79
-
80
- // on v8 version 2.3.4.1, Object.freeze(obj) returns undefined instead of obj
81
- var freeze = (Object.freeze ? function(obj) { Object.freeze(obj); return obj; }
82
- : function(obj) { return obj; });
83
- var getPrototypeOf = Object.getPrototypeOf || function(obj) {
84
- return Object.prototype;
85
- };
86
- var getOwnPropertyNames = Object.getOwnPropertyNames ||
87
- function(obj) {
88
- var props = [];
89
- for (var p in obj) { if (hasOwnProperty(obj,p)) { props.push(p); } }
90
- return props;
91
- };
92
- var getOwnPropertyDescriptor = supportsGOPD() ?
93
- Object.getOwnPropertyDescriptor :
94
- function(obj, name) {
95
- return {
96
- value: obj[name],
97
- enumerable: true,
98
- writable: true,
99
- configurable: true
100
- };
101
- };
102
- var defineProperty = supportsDP() ? Object.defineProperty :
103
- function(obj, name, pd) {
104
- obj[name] = pd.value;
105
- };
106
- var defineProperties = Object.defineProperties ||
107
- function(obj, propMap) {
108
- for (var name in propMap) {
109
- if (hasOwnProperty(propMap, name)) {
110
- defineProperty(obj, name, propMap[name]);
111
- }
112
- }
113
- };
114
- var Object_create = Object.create ||
115
- function(proto, propMap) {
116
- var self;
117
- function dummy() {};
118
- dummy.prototype = proto || Object.prototype;
119
- self = new dummy();
120
- if (propMap) {
121
- defineProperties(self, propMap);
122
- }
123
- return self;
124
- };
125
- var getOwnProperties = Object.getOwnProperties ||
126
- function(obj) {
127
- var map = {};
128
- forEach(getOwnPropertyNames(obj), function (name) {
129
- map[name] = getOwnPropertyDescriptor(obj, name);
130
- });
131
- return map;
132
- };
133
-
134
- // end of ES3 - ES5 compatibility functions
135
-
136
- function makeConflictAccessor(name) {
137
- var accessor = function(var_args) {
138
- throw new Error("Conflicting property: "+name);
139
- };
140
- freeze(accessor.prototype);
141
- return freeze(accessor);
142
- };
143
-
144
- function makeRequiredPropDesc(name) {
145
- return freeze({
146
- value: undefined,
147
- enumerable: false,
148
- required: true
149
- });
150
- }
151
-
152
- function makeConflictingPropDesc(name) {
153
- var conflict = makeConflictAccessor(name);
154
- if (SUPPORTS_DEFINEPROP) {
155
- return freeze({
156
- get: conflict,
157
- set: conflict,
158
- enumerable: false,
159
- conflict: true
160
- });
161
- } else {
162
- return freeze({
163
- value: conflict,
164
- enumerable: false,
165
- conflict: true
166
- });
167
- }
168
- }
169
-
170
- /**
171
- * Are x and y not observably distinguishable?
172
- */
173
- function identical(x, y) {
174
- if (x === y) {
175
- // 0 === -0, but they are not identical
176
- return x !== 0 || 1/x === 1/y;
177
- } else {
178
- // NaN !== NaN, but they are identical.
179
- // NaNs are the only non-reflexive value, i.e., if x !== x,
180
- // then x is a NaN.
181
- return x !== x && y !== y;
182
- }
183
- }
184
-
185
- // Note: isSameDesc should return true if both
186
- // desc1 and desc2 represent a 'required' property
187
- // (otherwise two composed required properties would be turned into
188
- // a conflict)
189
- function isSameDesc(desc1, desc2) {
190
- // for conflicting properties, don't compare values because
191
- // the conflicting property values are never equal
192
- if (desc1.conflict && desc2.conflict) {
193
- return true;
194
- } else {
195
- return ( desc1.get === desc2.get
196
- && desc1.set === desc2.set
197
- && identical(desc1.value, desc2.value)
198
- && desc1.enumerable === desc2.enumerable
199
- && desc1.required === desc2.required
200
- && desc1.conflict === desc2.conflict);
201
- }
202
- }
203
-
204
- function freezeAndBind(meth, self) {
205
- return freeze(bindThis(meth, self));
206
- }
207
-
208
- /* makeSet(['foo', ...]) => { foo: true, ...}
209
- *
210
- * makeSet returns an object whose own properties represent a set.
211
- *
212
- * Each string in the names array is added to the set.
213
- *
214
- * To test whether an element is in the set, perform:
215
- * hasOwnProperty(set, element)
216
- */
217
- function makeSet(names) {
218
- var set = {};
219
- forEach(names, function (name) {
220
- set[name] = true;
221
- });
222
- return freeze(set);
223
- }
224
-
225
- // == singleton object to be used as the placeholder for a required
226
- // property ==
227
-
228
- var required = freeze({
229
- toString: function() { return '<Trait.required>'; }
230
- });
231
-
232
- // == The public API methods ==
233
-
234
- /**
235
- * var newTrait = trait({ foo:required, ... })
236
- *
237
- * @param object an object record (in principle an object literal)
238
- * @returns a new trait describing all of the own properties of the object
239
- * (both enumerable and non-enumerable)
240
- *
241
- * As a general rule, 'trait' should be invoked with an object
242
- * literal, since the object merely serves as a record
243
- * descriptor. Both its identity and its prototype chain are
244
- * irrelevant.
245
- *
246
- * Data properties bound to function objects in the argument will be
247
- * flagged as 'method' properties. The prototype of these function
248
- * objects is frozen.
249
- *
250
- * Data properties bound to the 'required' singleton exported by
251
- * this module will be marked as 'required' properties.
252
- *
253
- * The <tt>trait</tt> function is pure if no other code can witness
254
- * the side-effects of freezing the prototypes of the methods. If
255
- * <tt>trait</tt> is invoked with an object literal whose methods
256
- * are represented as in-place anonymous functions, this should
257
- * normally be the case.
258
- */
259
- function trait(obj) {
260
- var map = {};
261
- forEach(getOwnPropertyNames(obj), function (name) {
262
- var pd = getOwnPropertyDescriptor(obj, name);
263
- if (pd.value === required) {
264
- pd = makeRequiredPropDesc(name);
265
- } else if (typeof pd.value === 'function') {
266
- pd.method = true;
267
- if ('prototype' in pd.value) {
268
- freeze(pd.value.prototype);
269
- }
270
- } else {
271
- if (pd.get && pd.get.prototype) { freeze(pd.get.prototype); }
272
- if (pd.set && pd.set.prototype) { freeze(pd.set.prototype); }
273
- }
274
- map[name] = pd;
275
- });
276
- return map;
277
- }
278
-
279
- /**
280
- * var newTrait = compose(trait_1, trait_2, ..., trait_N)
281
- *
282
- * @param trait_i a trait object
283
- * @returns a new trait containing the combined own properties of
284
- * all the trait_i.
285
- *
286
- * If two or more traits have own properties with the same name, the new
287
- * trait will contain a 'conflict' property for that name. 'compose' is
288
- * a commutative and associative operation, and the order of its
289
- * arguments is not significant.
290
- *
291
- * If 'compose' is invoked with < 2 arguments, then:
292
- * compose(trait_1) returns a trait equivalent to trait_1
293
- * compose() returns an empty trait
294
- */
295
- function compose(var_args) {
296
- var traits = slice(arguments, 0);
297
- var newTrait = {};
298
-
299
- forEach(traits, function (trait) {
300
- forEach(getOwnPropertyNames(trait), function (name) {
301
- var pd = trait[name];
302
- if (hasOwnProperty(newTrait, name) &&
303
- !newTrait[name].required) {
304
-
305
- // a non-required property with the same name was previously
306
- // defined this is not a conflict if pd represents a
307
- // 'required' property itself:
308
- if (pd.required) {
309
- return; // skip this property, the required property is
310
- // now present
311
- }
312
-
313
- if (!isSameDesc(newTrait[name], pd)) {
314
- // a distinct, non-required property with the same name
315
- // was previously defined by another trait => mark as
316
- // conflicting property
317
- newTrait[name] = makeConflictingPropDesc(name);
318
- } // else,
319
- // properties are not in conflict if they refer to the same value
320
-
321
- } else {
322
- newTrait[name] = pd;
323
- }
324
- });
325
- });
326
-
327
- return freeze(newTrait);
328
- }
329
-
330
- /* var newTrait = exclude(['name', ...], trait)
331
- *
332
- * @param names a list of strings denoting property names.
333
- * @param trait a trait some properties of which should be excluded.
334
- * @returns a new trait with the same own properties as the original trait,
335
- * except that all property names appearing in the first argument
336
- * are replaced by required property descriptors.
337
- *
338
- * Note: exclude(A, exclude(B,t)) is equivalent to exclude(A U B, t)
339
- */
340
- function exclude(names, trait) {
341
- var exclusions = makeSet(names);
342
- var newTrait = {};
343
-
344
- forEach(getOwnPropertyNames(trait), function (name) {
345
- // required properties are not excluded but ignored
346
- if (!hasOwnProperty(exclusions, name) || trait[name].required) {
347
- newTrait[name] = trait[name];
348
- } else {
349
- // excluded properties are replaced by required properties
350
- newTrait[name] = makeRequiredPropDesc(name);
351
- }
352
- });
353
-
354
- return freeze(newTrait);
355
- }
356
-
357
- /**
358
- * var newTrait = override(trait_1, trait_2, ..., trait_N)
359
- *
360
- * @returns a new trait with all of the combined properties of the
361
- * argument traits. In contrast to 'compose', 'override'
362
- * immediately resolves all conflicts resulting from this
363
- * composition by overriding the properties of later
364
- * traits. Trait priority is from left to right. I.e. the
365
- * properties of the leftmost trait are never overridden.
366
- *
367
- * override is associative:
368
- * override(t1,t2,t3) is equivalent to override(t1, override(t2, t3)) or
369
- * to override(override(t1, t2), t3)
370
- * override is not commutative: override(t1,t2) is not equivalent
371
- * to override(t2,t1)
372
- *
373
- * override() returns an empty trait
374
- * override(trait_1) returns a trait equivalent to trait_1
375
- */
376
- function override(var_args) {
377
- var traits = slice(arguments, 0);
378
- var newTrait = {};
379
- forEach(traits, function (trait) {
380
- forEach(getOwnPropertyNames(trait), function (name) {
381
- var pd = trait[name];
382
- // add this trait's property to the composite trait only if
383
- // - the trait does not yet have this property
384
- // - or, the trait does have the property, but it's a required property
385
- if (!hasOwnProperty(newTrait, name) || newTrait[name].required) {
386
- newTrait[name] = pd;
387
- }
388
- });
389
- });
390
- return freeze(newTrait);
391
- }
392
-
393
- /**
394
- * var newTrait = override(dominantTrait, recessiveTrait)
395
- *
396
- * @returns a new trait with all of the properties of dominantTrait
397
- * and all of the properties of recessiveTrait not in dominantTrait
398
- *
399
- * Note: override is associative:
400
- * override(t1, override(t2, t3)) is equivalent to
401
- * override(override(t1, t2), t3)
402
- */
403
- /*function override(frontT, backT) {
404
- var newTrait = {};
405
- // first copy all of backT's properties into newTrait
406
- forEach(getOwnPropertyNames(backT), function (name) {
407
- newTrait[name] = backT[name];
408
- });
409
- // now override all these properties with frontT's properties
410
- forEach(getOwnPropertyNames(frontT), function (name) {
411
- var pd = frontT[name];
412
- // frontT's required property does not override the provided property
413
- if (!(pd.required && hasOwnProperty(newTrait, name))) {
414
- newTrait[name] = pd;
415
- }
416
- });
417
-
418
- return freeze(newTrait);
419
- }*/
420
-
421
- /**
422
- * var newTrait = rename(map, trait)
423
- *
424
- * @param map an object whose own properties serve as a mapping from
425
- old names to new names.
426
- * @param trait a trait object
427
- * @returns a new trait with the same properties as the original trait,
428
- * except that all properties whose name is an own property
429
- * of map will be renamed to map[name], and a 'required' property
430
- * for name will be added instead.
431
- *
432
- * rename({a: 'b'}, t) eqv compose(exclude(['a'],t),
433
- * { a: { required: true },
434
- * b: t[a] })
435
- *
436
- * For each renamed property, a required property is generated. If
437
- * the map renames two properties to the same name, a conflict is
438
- * generated. If the map renames a property to an existing
439
- * unrenamed property, a conflict is generated.
440
- *
441
- * Note: rename(A, rename(B, t)) is equivalent to rename(\n ->
442
- * A(B(n)), t) Note: rename({...},exclude([...], t)) is not eqv to
443
- * exclude([...],rename({...}, t))
444
- */
445
- function rename(map, trait) {
446
- var renamedTrait = {};
447
- forEach(getOwnPropertyNames(trait), function (name) {
448
- // required props are never renamed
449
- if (hasOwnProperty(map, name) && !trait[name].required) {
450
- var alias = map[name]; // alias defined in map
451
- if (hasOwnProperty(renamedTrait, alias) &&
452
- !renamedTrait[alias].required) {
453
- // could happen if 2 props are mapped to the same alias
454
- renamedTrait[alias] = makeConflictingPropDesc(alias);
455
- } else {
456
- // add the property under an alias
457
- renamedTrait[alias] = trait[name];
458
- }
459
- // add a required property under the original name
460
- // but only if a property under the original name does not exist
461
- // such a prop could exist if an earlier prop in the trait was
462
- // previously aliased to this name
463
- if (!hasOwnProperty(renamedTrait, name)) {
464
- renamedTrait[name] = makeRequiredPropDesc(name);
465
- }
466
- } else { // no alias defined
467
- if (hasOwnProperty(renamedTrait, name)) {
468
- // could happen if another prop was previously aliased to name
469
- if (!trait[name].required) {
470
- renamedTrait[name] = makeConflictingPropDesc(name);
471
- }
472
- // else required property overridden by a previously aliased
473
- // property and otherwise ignored
474
- } else {
475
- renamedTrait[name] = trait[name];
476
- }
477
- }
478
- });
479
-
480
- return freeze(renamedTrait);
481
- }
482
-
483
- /**
484
- * var newTrait = resolve({ oldName: 'newName', excludeName:
485
- * undefined, ... }, trait)
486
- *
487
- * This is a convenience function combining renaming and
488
- * exclusion. It can be implemented as <tt>rename(map,
489
- * exclude(exclusions, trait))</tt> where map is the subset of
490
- * mappings from oldName to newName and exclusions is an array of
491
- * all the keys that map to undefined (or another falsy value).
492
- *
493
- * @param resolutions an object whose own properties serve as a
494
- mapping from old names to new names, or to undefined if
495
- the property should be excluded
496
- * @param trait a trait object
497
- * @returns a resolved trait with the same own properties as the
498
- * original trait.
499
- *
500
- * In a resolved trait, all own properties whose name is an own property
501
- * of resolutions will be renamed to resolutions[name] if it is truthy,
502
- * or their value is changed into a required property descriptor if
503
- * resolutions[name] is falsy.
504
- *
505
- * Note, it's important to _first_ exclude, _then_ rename, since exclude
506
- * and rename are not associative, for example:
507
- * rename({a: 'b'}, exclude(['b'], trait({ a:1,b:2 }))) eqv trait({b:1})
508
- * exclude(['b'], rename({a: 'b'}, trait({ a:1,b:2 }))) eqv
509
- * trait({b:Trait.required})
510
- *
511
- * writing resolve({a:'b', b: undefined},trait({a:1,b:2})) makes it
512
- * clear that what is meant is to simply drop the old 'b' and rename
513
- * 'a' to 'b'
514
- */
515
- function resolve(resolutions, trait) {
516
- var renames = {};
517
- var exclusions = [];
518
- // preprocess renamed and excluded properties
519
- for (var name in resolutions) {
520
- if (hasOwnProperty(resolutions, name)) {
521
- if (resolutions[name]) { // old name -> new name
522
- renames[name] = resolutions[name];
523
- } else { // name -> undefined
524
- exclusions.push(name);
525
- }
526
- }
527
- }
528
- return rename(renames, exclude(exclusions, trait));
529
- }
530
-
531
- /**
532
- * var obj = create(proto, trait)
533
- *
534
- * @param proto denotes the prototype of the completed object
535
- * @param trait a trait object to be turned into a complete object
536
- * @returns an object with all of the properties described by the trait.
537
- * @throws 'Missing required property' the trait still contains a
538
- * required property.
539
- * @throws 'Remaining conflicting property' if the trait still
540
- * contains a conflicting property.
541
- *
542
- * Trait.create is like Object.create, except that it generates
543
- * high-integrity or final objects. In addition to creating a new object
544
- * from a trait, it also ensures that:
545
- * - an exception is thrown if 'trait' still contains required properties
546
- * - an exception is thrown if 'trait' still contains conflicting
547
- * properties
548
- * - the object is and all of its accessor and method properties are frozen
549
- * - the 'this' pseudovariable in all accessors and methods of
550
- * the object is bound to the composed object.
551
- *
552
- * Use Object.create instead of Trait.create if you want to create
553
- * abstract or malleable objects. Keep in mind that for such objects:
554
- * - no exception is thrown if 'trait' still contains required properties
555
- * (the properties are simply dropped from the composite object)
556
- * - no exception is thrown if 'trait' still contains conflicting
557
- * properties (these properties remain as conflicting
558
- * properties in the composite object)
559
- * - neither the object nor its accessor and method properties are frozen
560
- * - the 'this' pseudovariable in all accessors and methods of
561
- * the object is left unbound.
562
- */
563
- function create(proto, trait) {
564
- var self = Object_create(proto);
565
- var properties = {};
566
-
567
- forEach(getOwnPropertyNames(trait), function (name) {
568
- var pd = trait[name];
569
- // check for remaining 'required' properties
570
- // Note: it's OK for the prototype to provide the properties
571
- if (pd.required) {
572
- if (!(name in proto)) {
573
- throw new Error('Missing required property: '+name);
574
- }
575
- } else if (pd.conflict) { // check for remaining conflicting properties
576
- throw new Error('Remaining conflicting property: '+name);
577
- } else if ('value' in pd) { // data property
578
- // freeze all function properties and their prototype
579
- if (pd.method) { // the property is meant to be used as a method
580
- // bind 'this' in trait method to the composite object
581
- properties[name] = {
582
- value: freezeAndBind(pd.value, self),
583
- enumerable: pd.enumerable,
584
- configurable: pd.configurable,
585
- writable: pd.writable
586
- };
587
- } else {
588
- properties[name] = pd;
589
- }
590
- } else { // accessor property
591
- properties[name] = {
592
- get: pd.get ? freezeAndBind(pd.get, self) : undefined,
593
- set: pd.set ? freezeAndBind(pd.set, self) : undefined,
594
- enumerable: pd.enumerable,
595
- configurable: pd.configurable,
596
- writable: pd.writable
597
- };
598
- }
599
- });
600
-
601
- defineProperties(self, properties);
602
- return freeze(self);
603
- }
604
-
605
- /** A shorthand for create(Object.prototype, trait({...}), options) */
606
- function object(record, options) {
607
- return create(Object.prototype, trait(record), options);
608
- }
609
-
610
- /**
611
- * Tests whether two traits are equivalent. T1 is equivalent to T2 iff
612
- * both describe the same set of property names and for all property
613
- * names n, T1[n] is equivalent to T2[n]. Two property descriptors are
614
- * equivalent if they have the same value, accessors and attributes.
615
- *
616
- * @return a boolean indicating whether the two argument traits are
617
- * equivalent.
618
- */
619
- function eqv(trait1, trait2) {
620
- var names1 = getOwnPropertyNames(trait1);
621
- var names2 = getOwnPropertyNames(trait2);
622
- var name;
623
- if (names1.length !== names2.length) {
624
- return false;
625
- }
626
- for (var i = 0; i < names1.length; i++) {
627
- name = names1[i];
628
- if (!trait2[name] || !isSameDesc(trait1[name], trait2[name])) {
629
- return false;
630
- }
631
- }
632
- return true;
633
- }
634
-
635
- // if this code is ran in ES3 without an Object.create function, this
636
- // library will define it on Object:
637
- if (!Object.create) {
638
- Object.create = Object_create;
639
- }
640
- // ES5 does not by default provide Object.getOwnProperties
641
- // if it's not defined, the Traits library defines this utility
642
- // function on Object
643
- if(!Object.getOwnProperties) {
644
- Object.getOwnProperties = getOwnProperties;
645
- }
646
-
647
- // expose the public API of this module
648
- function Trait(record) {
649
- // calling Trait as a function creates a new atomic trait
650
- return trait(record);
651
- }
652
- Trait.required = freeze(required);
653
- Trait.compose = freeze(compose);
654
- Trait.resolve = freeze(resolve);
655
- Trait.override = freeze(override);
656
- Trait.create = freeze(create);
657
- Trait.eqv = freeze(eqv);
658
- Trait.object = freeze(object); // not essential, cf. create + trait
659
- return freeze(Trait);
660
-
661
- })();
662
-
663
- if (typeof exports !== "undefined") { // CommonJS module support
664
- exports.Trait = Trait;
665
- }
@@ -1,7 +0,0 @@
1
- {
2
- "name": "traits",
3
- "version": "0.3.0",
4
- "author": "Tom Van Cutsem",
5
- "main": "./lib/traits",
6
- "directories": "./lib"
7
- }