superconf 1.5.1 → 1.5.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.
- package/Superconf.js +257 -0
- package/app.js +18 -3
- package/package.json +6 -2
- package/.eslintrc.json +0 -3
- package/.firerc.json +0 -19
- package/.fslintignore +0 -1
- package/.gitlab-ci.yml +0 -4
- package/docs/doxydoc/main.fire +0 -3
- package/docs/doxydoc/superconf.fire +0 -38
- package/docs/superconf.md +0 -68
- package/src/Superconf.fire +0 -258
- package/src/app.fire +0 -15
- package/tests/.eslintrc +0 -6
- package/tests/Superconf.test.fire +0 -156
- package/tests/fixtures/.rcjsontestrc.json +0 -4
- package/tests/fixtures/.rcyamltestrc.yaml +0 -2
- package/tests/fixtures/.rcymltestrc.yml +0 -2
- package/tests/fixtures/defaultConf.json +0 -4
- package/tests/fixtures/fruits.yml +0 -8
- package/tests/fixtures/jsontest.json +0 -4
- package/tests/fixtures/package.json +0 -7
- package/tests/fixtures/yamltest.yaml +0 -2
- package/tests/fixtures/ymltest.yml +0 -2
- package/tests/superconf.spec.js +0 -277
- /package/{src/Legacy.js → Legacy.js} +0 -0
package/Superconf.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
module.exports.__fsLocationMap = [[1, 21, 2, 7], [1, 33, 2, 24], [1, 8, 2, 36], [2, 13, 3, 7], [2, 26, 3, 25], [3, 13, 4, 7], [3, 23, 4, 22], [4, 8, 5, 7], [4, 20, 5, 24], [4, 8, 5, 45], [6, 1, 6, 1], [6, 7, 6, 7], [6, 13, 6, 13], [7, 1, 7, 1], [7, 7, 7, 7], [7, 14, 7, 14], [8, 1, 8, 1], [8, 7, 8, 7], [8, 16, 8, 16], [9, 1, 9, 1], [9, 7, 9, 7], [9, 15, 9, 15], [10, 1, 10, 1], [10, 7, 10, 7], [10, 15, 10, 15], [11, 1, 11, 1], [11, 7, 11, 7], [11, 15, 11, 15], [12, 1, 12, 1], [12, 7, 12, 7], [12, 17, 12, 17], [14, 8, 13, 1], [14, 14, 13, 7], [14, 24, 13, 17], [14, 32, 13, 25], [15, 5, 14, 3], [15, 18, 14, 16], [15, 18, 15, 5], [15, 18, 15, 12], [16, 9, 16, 5], [16, 15, 16, 11], [18, 9, 17, 5], [18, 14, 17, 10], [18, 27, 17, 23], [18, 32, 17, 28], [18, 46, 17, 42], [18, 54, 17, 50], [19, 9, 18, 5], [19, 14, 18, 10], [20, 9, 19, 5], [20, 14, 19, 10], [20, 24, 19, 20], [20, 29, 19, 25], [20, 40, 19, 36], [21, 9, 20, 5], [21, 14, 20, 10], [21, 26, 20, 22], [21, 31, 20, 27], [21, 39, 20, 35], [23, 9, 21, 5], [23, 14, 21, 10], [23, 22, 21, 18], [23, 27, 21, 23], [23, 36, 21, 32], [24, 13, 22, 7], [25, 13, 23, 7], [26, 13, 24, 7], [27, 13, 25, 7], [28, 13, 26, 7], [29, 13, 27, 7], [33, 5, 31, 3], [33, 12, 31, 10], [33, 20, 31, 18], [34, 9, 32, 5], [34, 12, 32, 9], [34, 17, 32, 14], [35, 17, 33, 19], [35, 25, 33, 27], [35, 32, 33, 34], [35, 47, 33, 49], [35, 55, 33, 57], [35, 60, 33, 62], [35, 69, 33, 71], [38, 5, 37, 3], [38, 13, 37, 11], [39, 9, 38, 5], [39, 14, 38, 10], [40, 9, 39, 5], [40, 16, 39, 12], [40, 24, 39, 20], [40, 38, 39, 34], [40, 46, 39, 42], [40, 47, 39, 43], [40, 48, 39, 45], [40, 53, 39, 50], [41, 13, 40, 7], [41, 19, 40, 13], [42, 17, 41, 9], [42, 23, 41, 15], [42, 29, 41, 21], [42, 37, 41, 29], [43, 17, 42, 9], [43, 27, 42, 19], [43, 33, 42, 25], [43, 45, 42, 37], [46, 13, 44, 7], [46, 16, 44, 11], [46, 23, 44, 18], [46, 29, 44, 24], [46, 41, 44, 36], [47, 17, 45, 9], [47, 24, 45, 16], [47, 34, 45, 26], [47, 40, 45, 32], [49, 13, 47, 7], [49, 16, 47, 11], [49, 23, 47, 18], [49, 29, 47, 24], [49, 44, 47, 39], [50, 17, 48, 9], [50, 24, 48, 16], [50, 37, 48, 29], [50, 43, 48, 35], [52, 13, 50, 7], [52, 18, 50, 12], [52, 31, 50, 25], [52, 38, 50, 32], [56, 5, 54, 3], [56, 20, 54, 18], [56, 28, 54, 26], [57, 9, 55, 5], [57, 16, 55, 12], [57, 23, 55, 19], [57, 31, 55, 27], [60, 5, 58, 3], [60, 15, 58, 13], [61, 9, 59, 5], [61, 12, 59, 9], [61, 13, 59, 10], [61, 18, 59, 15], [62, 13, 60, 7], [62, 20, 60, 14], [64, 9, 62, 5], [64, 14, 62, 10], [64, 33, 62, 29], [65, 9, 63, 5], [65, 15, 63, 11], [65, 33, 63, 29], [65, 41, 63, 37], [65, 46, 63, 42], [66, 9, 64, 5], [66, 15, 64, 11], [67, 13, 65, 7], [67, 19, 65, 13], [68, 13, 66, 7], [68, 25, 66, 19], [68, 30, 66, 24], [71, 9, 68, 5], [71, 14, 68, 10], [71, 31, 68, 27], [71, 50, 68, 46], [71, 60, 68, 56], [73, 9, 69, 5], [73, 16, 69, 12], [73, 21, 69, 17], [73, 38, 69, 34], [73, 49, 69, 45], [75, 5, 72, 3], [75, 23, 72, 21], [75, 31, 72, 29], [75, 37, 72, 35], [76, 9, 73, 5], [76, 14, 73, 10], [76, 20, 73, 16], [76, 41, 73, 37], [76, 60, 73, 56], [76, 70, 73, 66], [76, 88, 73, 84], [78, 9, 74, 5], [78, 12, 74, 9], [78, 13, 74, 10], [79, 13, 75, 7], [79, 20, 75, 14], [81, 9, 77, 5], [81, 12, 77, 9], [81, 13, 77, 10], [82, 13, 78, 7], [82, 16, 78, 11], [82, 23, 78, 18], [82, 36, 78, 31], [83, 17, 79, 9], [83, 22, 79, 14], [83, 39, 79, 31], [83, 44, 79, 36], [83, 52, 79, 44], [85, 13, 80, 9], [86, 17, 81, 9], [86, 24, 81, 16], [88, 9, 84, 5], [88, 12, 84, 9], [88, 19, 84, 16], [88, 28, 84, 25], [89, 13, 85, 7], [89, 16, 85, 11], [89, 23, 85, 18], [89, 36, 85, 31], [90, 17, 86, 9], [90, 22, 86, 14], [90, 39, 86, 31], [90, 44, 86, 36], [90, 52, 86, 44], [92, 9, 88, 7], [92, 14, 88, 16], [92, 21, 88, 23], [92, 30, 88, 32], [93, 13, 89, 7], [93, 16, 89, 11], [93, 23, 89, 18], [93, 36, 89, 31], [94, 17, 90, 9], [94, 22, 90, 14], [94, 39, 90, 31], [94, 44, 90, 36], [94, 52, 90, 44], [96, 9, 92, 7], [96, 14, 92, 16], [96, 21, 92, 23], [96, 30, 92, 32], [97, 13, 93, 7], [97, 16, 93, 11], [97, 23, 93, 18], [97, 36, 93, 31], [98, 17, 94, 9], [98, 22, 94, 14], [98, 39, 94, 31], [98, 44, 94, 36], [98, 52, 94, 44], [100, 9, 96, 7], [100, 14, 96, 16], [100, 21, 96, 23], [100, 30, 96, 32], [101, 13, 97, 7], [101, 16, 97, 11], [101, 17, 97, 12], [101, 23, 97, 18], [101, 31, 97, 26], [102, 17, 98, 9], [102, 22, 98, 14], [102, 39, 98, 31], [102, 44, 98, 36], [102, 52, 98, 44], [104, 9, 100, 7], [104, 14, 100, 16], [104, 21, 100, 23], [104, 30, 100, 32], [105, 13, 101, 7], [105, 16, 101, 11], [105, 23, 101, 18], [105, 36, 101, 31], [106, 17, 102, 9], [106, 22, 102, 14], [106, 39, 102, 31], [106, 44, 102, 36], [106, 52, 102, 44], [108, 13, 104, 7], [108, 20, 104, 14], [108, 28, 104, 22], [108, 38, 104, 32], [108, 46, 104, 40], [108, 47, 104, 41], [108, 48, 104, 43], [108, 53, 104, 48], [109, 17, 105, 9], [109, 23, 105, 15], [109, 35, 105, 27], [109, 40, 105, 32], [109, 54, 105, 46], [109, 61, 105, 53], [109, 73, 105, 65], [110, 17, 106, 9], [110, 22, 106, 14], [110, 39, 106, 31], [110, 50, 106, 42], [110, 53, 106, 45], [110, 61, 106, 53], [110, 68, 106, 60], [113, 13, 108, 7], [113, 20, 108, 14], [113, 28, 108, 22], [113, 35, 108, 29], [113, 47, 108, 41], [113, 55, 108, 49], [113, 56, 108, 50], [113, 57, 108, 52], [113, 62, 108, 57], [114, 17, 109, 9], [114, 20, 109, 13], [114, 21, 109, 14], [114, 30, 109, 23], [114, 38, 109, 31], [114, 48, 109, 41], [114, 60, 109, 53], [115, 21, 110, 11], [115, 26, 110, 16], [115, 32, 110, 22], [115, 66, 110, 56], [115, 77, 110, 67], [115, 87, 110, 77], [116, 21, 111, 11], [116, 30, 111, 20], [116, 37, 111, 27], [116, 47, 111, 37], [118, 17, 112, 11], [118, 22, 112, 20], [118, 23, 112, 21], [118, 32, 112, 30], [118, 40, 112, 38], [118, 50, 112, 48], [118, 59, 112, 57], [119, 21, 113, 11], [119, 30, 113, 20], [121, 17, 115, 9], [121, 22, 115, 14], [121, 39, 115, 31], [121, 50, 115, 42], [121, 53, 115, 45], [121, 61, 115, 53], [121, 68, 115, 60], [121, 77, 115, 69], [124, 5, 120, 3], [124, 11, 120, 9], [124, 21, 120, 19], [125, 9, 121, 5], [125, 15, 121, 11], [125, 20, 121, 16], [125, 26, 121, 22], [125, 33, 121, 29], [125, 38, 121, 34], [127, 9, 122, 5], [127, 12, 122, 9], [127, 13, 122, 10], [127, 16, 122, 13], [128, 13, 123, 7], [128, 18, 123, 12], [128, 24, 123, 18], [128, 36, 123, 30], [129, 13, 124, 7], [129, 20, 124, 14], [131, 9, 126, 5], [131, 14, 126, 10], [131, 20, 126, 16], [131, 38, 126, 34], [132, 9, 127, 5], [132, 12, 127, 9], [132, 15, 127, 12], [132, 23, 127, 20], [133, 13, 128, 7], [133, 20, 128, 14], [133, 23, 128, 17], [135, 9, 130, 5], [135, 12, 130, 9], [135, 15, 130, 12], [135, 23, 130, 20], [135, 33, 130, 30], [135, 36, 130, 33], [135, 44, 130, 41], [136, 13, 131, 7], [136, 19, 131, 13], [136, 26, 131, 20], [136, 34, 131, 28], [137, 13, 132, 7], [137, 19, 132, 13], [137, 28, 132, 22], [137, 34, 132, 28], [137, 37, 132, 31], [138, 13, 133, 7], [138, 20, 133, 14], [138, 25, 133, 19], [138, 30, 133, 24], [140, 9, 135, 5], [140, 16, 135, 12], [142, 5, 138, 3], [142, 18, 138, 16], [143, 9, 139, 5], [143, 16, 139, 12], [143, 24, 139, 20], [143, 29, 139, 25], [143, 43, 139, 39], [143, 51, 139, 47], [143, 52, 139, 48], [143, 53, 139, 50], [143, 58, 139, 55], [144, 13, 140, 7], [144, 16, 140, 11], [144, 23, 140, 18], [144, 30, 140, 25], [144, 39, 140, 34], [144, 54, 140, 49], [144, 61, 140, 56], [144, 67, 140, 62], [144, 79, 140, 74], [145, 17, 141, 9], [145, 24, 141, 16], [145, 31, 141, 23], [145, 37, 141, 29], [149, 5, 146, 3], [149, 11, 146, 9], [149, 17, 146, 15], [150, 9, 147, 5], [150, 14, 147, 10], [150, 20, 147, 16], [150, 35, 147, 31], [152, 9, 148, 5], [152, 13, 148, 10], [152, 19, 148, 16], [152, 27, 148, 24], [152, 32, 148, 29], [153, 13, 149, 7], [153, 19, 149, 13], [153, 30, 149, 24], [153, 35, 149, 29], [153, 43, 149, 37], [153, 48, 149, 42], [153, 60, 149, 54], [153, 65, 149, 59], [153, 73, 149, 67], [153, 79, 149, 73], [154, 13, 150, 7], [154, 19, 150, 13], [154, 28, 150, 22], [154, 34, 150, 28], [154, 39, 150, 33], [154, 48, 150, 42], [156, 13, 151, 7], [156, 16, 151, 11], [156, 27, 151, 22], [157, 17, 152, 9], [162, 13, 156, 7], [162, 16, 156, 11], [162, 17, 156, 12], [162, 22, 156, 17], [162, 31, 156, 26], [163, 17, 157, 9], [163, 23, 157, 15], [163, 42, 157, 34], [163, 47, 157, 39], [163, 64, 157, 56], [163, 69, 157, 61], [164, 17, 158, 9], [164, 23, 158, 15], [164, 27, 158, 19], [164, 33, 158, 25], [164, 62, 158, 57], [166, 13, 160, 7], [166, 18, 160, 12], [166, 27, 160, 21], [167, 13, 161, 7], [167, 20, 161, 14], [169, 9, 163, 5], [169, 16, 163, 12], [171, 5, 166, 3], [171, 15, 166, 13], [172, 9, 167, 5], [172, 15, 167, 11], [174, 9, 168, 5], [174, 15, 168, 11], [174, 23, 168, 19], [174, 24, 168, 20], [174, 30, 168, 26], [174, 37, 168, 33], [175, 13, 169, 7], [175, 16, 169, 11], [175, 25, 169, 20], [175, 38, 169, 33], [175, 47, 169, 42], [176, 17, 170, 9], [178, 13, 172, 7], [178, 16, 172, 11], [178, 23, 172, 18], [178, 33, 172, 28], [179, 17, 173, 9], [179, 24, 173, 16], [182, 13, 175, 7], [182, 17, 175, 12], [182, 23, 175, 18], [182, 30, 175, 25], [183, 17, 176, 9], [183, 20, 176, 13], [183, 26, 176, 19], [183, 41, 176, 34], [184, 21, 177, 11], [184, 24, 177, 15], [184, 30, 177, 21], [184, 39, 177, 30], [185, 25, 178, 13], [187, 21, 180, 11], [187, 24, 180, 15], [187, 30, 180, 21], [187, 39, 180, 30], [188, 25, 181, 13], [188, 30, 181, 18], [188, 37, 181, 25], [189, 25, 182, 13], [191, 21, 184, 11], [191, 24, 184, 15], [191, 30, 184, 21], [191, 38, 184, 29], [191, 44, 184, 35], [192, 25, 185, 13], [192, 30, 185, 18], [192, 37, 185, 25], [192, 43, 185, 31], [192, 48, 185, 36], [192, 52, 185, 40], [192, 53, 185, 41], [193, 29, 186, 15], [193, 32, 186, 19], [193, 39, 186, 26], [193, 48, 186, 35], [194, 33, 187, 17], [194, 40, 187, 24], [194, 45, 187, 29], [194, 51, 187, 35], [194, 56, 187, 40], [194, 66, 187, 50], [196, 29, 189, 15], [196, 36, 189, 22], [199, 25, 191, 13], [201, 21, 193, 11], [201, 24, 193, 15], [201, 31, 193, 22], [201, 37, 193, 28], [201, 46, 193, 37], [202, 25, 194, 13], [202, 28, 194, 17], [203, 29, 195, 15], [203, 34, 195, 20], [203, 41, 195, 27], [203, 47, 195, 33], [203, 52, 195, 38], [203, 58, 195, 44], [203, 64, 195, 50], [203, 70, 195, 56], [203, 75, 195, 61], [204, 29, 196, 15], [206, 25, 198, 13], [206, 30, 198, 18], [206, 37, 198, 25], [206, 44, 198, 32], [206, 55, 198, 43], [206, 61, 198, 49], [207, 25, 199, 13], [209, 21, 201, 11], [209, 26, 201, 16], [209, 33, 201, 23], [209, 39, 201, 29], [211, 13, 204, 7], [211, 20, 204, 14], [213, 9, 206, 5], [213, 13, 206, 10], [213, 17, 206, 14], [213, 21, 206, 18], [213, 24, 206, 21], [213, 28, 206, 25], [213, 33, 206, 30], [213, 41, 206, 38], [214, 13, 207, 7], [214, 19, 207, 13], [214, 25, 207, 19], [214, 30, 207, 24], [214, 34, 207, 28], [214, 39, 207, 33], [216, 9, 209, 5], [216, 16, 209, 12], [218, 5, 212, 3], [218, 11, 212, 9], [219, 9, 213, 5], [219, 12, 213, 9], [219, 19, 213, 16], [219, 27, 213, 24], [219, 39, 213, 36], [219, 47, 213, 44], [220, 13, 214, 7], [220, 20, 214, 14], [222, 9, 216, 5], [222, 12, 216, 9], [222, 18, 216, 15], [222, 26, 216, 23], [223, 13, 217, 7], [223, 20, 217, 14], [223, 24, 217, 18], [223, 28, 217, 22], [223, 29, 217, 23], [224, 17, 218, 9], [224, 22, 218, 14], [224, 27, 218, 19], [227, 9, 221, 5], [227, 15, 221, 11], [228, 9, 222, 5], [228, 13, 222, 10], [228, 19, 222, 16], [228, 26, 222, 23], [229, 13, 223, 7], [229, 16, 223, 11], [229, 20, 223, 15], [229, 35, 223, 30], [230, 17, 224, 9], [230, 20, 224, 13], [230, 24, 224, 17], [230, 33, 224, 26], [231, 21, 225, 11], [231, 28, 225, 18], [231, 35, 225, 25], [232, 21, 226, 11], [234, 17, 228, 9], [234, 20, 228, 13], [234, 26, 228, 19], [234, 34, 228, 27], [234, 38, 228, 31], [235, 21, 229, 11], [235, 28, 229, 18], [235, 35, 229, 25], [235, 39, 229, 29], [235, 44, 229, 34], [235, 48, 229, 38], [235, 49, 229, 39], [236, 25, 230, 13], [236, 30, 230, 18], [236, 35, 230, 23], [239, 21, 232, 11], [241, 17, 234, 9], [241, 20, 234, 13], [241, 27, 234, 20], [241, 31, 234, 24], [241, 40, 234, 33], [242, 21, 235, 11], [242, 28, 235, 18], [242, 35, 235, 25], [242, 40, 235, 30], [242, 45, 235, 35], [242, 49, 235, 39], [243, 21, 236, 11], [245, 17, 238, 9], [245, 24, 238, 16], [245, 31, 238, 23], [245, 35, 238, 27], [247, 9, 241, 5], [247, 16, 241, 12], [249, 5, 244, 3], [249, 10, 244, 8], [250, 9, 245, 5], [250, 15, 245, 11], [250, 22, 245, 18], [250, 33, 245, 29], [250, 39, 245, 35], [251, 9, 246, 5], [251, 13, 246, 9], [251, 20, 246, 16], [251, 25, 246, 21], [253, 9, 247, 5], [253, 13, 247, 10], [253, 19, 247, 16], [253, 26, 247, 23], [254, 13, 248, 7], [254, 20, 248, 14], [254, 25, 248, 19], [255, 13, 249, 7], [255, 16, 249, 11], [255, 17, 249, 12], [256, 17, 250, 9], [256, 24, 250, 16], [258, 9, 253, 5], [258, 16, 253, 12], [14, 14, 256, 16], [14, 14, 256, 28]];
|
|
2
|
+
module.exports.__esModule = true;
|
|
3
|
+
const Legacy = require('./Legacy').Superconf;
|
|
4
|
+
const colorfy = require('colorfy');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const FireFS = require('firescript-firefs').FireFS;
|
|
7
|
+
const red = '\u001b[38;5;160m';
|
|
8
|
+
const ored = '\u001b[38;5;202m';
|
|
9
|
+
const yellow = '\u001b[38;5;226m';
|
|
10
|
+
const dgrey = '\u001b[38;5;244m';
|
|
11
|
+
const lgrey = '\u001b[38;5;250m';
|
|
12
|
+
const azure = '\u001b[38;5;39m';
|
|
13
|
+
const uncolor = '\u001b[m';
|
|
14
|
+
class Superconf extends Legacy {
|
|
15
|
+
constructor (opts) {
|
|
16
|
+
opts = opts || {};
|
|
17
|
+
super(opts);
|
|
18
|
+
this.workingDir = opts.workingDir || process.cwd();
|
|
19
|
+
this.config = {};
|
|
20
|
+
this.verbose = opts.verbose || false;
|
|
21
|
+
this.mergeDept = opts.dept || 0;
|
|
22
|
+
this.files = opts.files || [
|
|
23
|
+
'%s.json',
|
|
24
|
+
'%s.yaml',
|
|
25
|
+
'%s.yml',
|
|
26
|
+
'.%src.json',
|
|
27
|
+
'.%src.yaml',
|
|
28
|
+
'.%src.yml'
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
debug (msg, ...data) {
|
|
33
|
+
if (this.verbose) {
|
|
34
|
+
console.log(colorfy.yellow('Superconf:'), colorfy.grey(msg), ...data);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
schema (configSchema) {
|
|
39
|
+
this.configSchema = {};
|
|
40
|
+
Object.entries(configSchema).forEach(([ key, value ]) => {
|
|
41
|
+
const schema = {
|
|
42
|
+
type: value.type || 'str',
|
|
43
|
+
required: value.required || false
|
|
44
|
+
};
|
|
45
|
+
if (typeof value.default !== 'undefined') {
|
|
46
|
+
schema.default = value.default;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value.properties !== 'undefined') {
|
|
49
|
+
schema.properties = value.properties;
|
|
50
|
+
}
|
|
51
|
+
this.configSchema[key] = schema;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getSchemaItem (schema, key) {
|
|
56
|
+
return schema[key] || null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
validate (conf) {
|
|
60
|
+
if (!this.configSchema) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
this.validationErrors = [ ];
|
|
64
|
+
const validateionData = conf || this.config;
|
|
65
|
+
const validateionSchema = {
|
|
66
|
+
type: 'obj',
|
|
67
|
+
properties: this.configSchema
|
|
68
|
+
};
|
|
69
|
+
this.validateProperty(validateionSchema, 'config', validateionData);
|
|
70
|
+
return this.validationErrors.length === 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
validateProperty (schema, name, property) {
|
|
74
|
+
this.debug(`Validate property ${name} with value`, property, 'against schema', schema);
|
|
75
|
+
if (!schema) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (!property) {
|
|
79
|
+
if (schema.required === true) {
|
|
80
|
+
this.validationErrors.push(`Item ${name} is required but not set`);
|
|
81
|
+
} else {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (schema.type === 'str') {
|
|
86
|
+
if (typeof property !== 'string') {
|
|
87
|
+
this.validationErrors.push(`Item ${name} is not of type string`);
|
|
88
|
+
}
|
|
89
|
+
} else if (schema.type === 'num') {
|
|
90
|
+
if (typeof property !== 'number') {
|
|
91
|
+
this.validationErrors.push(`Item ${name} is not of type number`);
|
|
92
|
+
}
|
|
93
|
+
} else if (schema.type === 'bool') {
|
|
94
|
+
if (typeof property !== 'boolean') {
|
|
95
|
+
this.validationErrors.push(`Item ${name} is not of type boolean`);
|
|
96
|
+
}
|
|
97
|
+
} else if (schema.type === 'arr') {
|
|
98
|
+
if (!Array.isArray(property)) {
|
|
99
|
+
this.validationErrors.push(`Item ${name} is not of type array`);
|
|
100
|
+
}
|
|
101
|
+
} else if (schema.type === 'obj') {
|
|
102
|
+
if (typeof property !== 'object') {
|
|
103
|
+
this.validationErrors.push(`Item ${name} is not of type object`);
|
|
104
|
+
}
|
|
105
|
+
Object.entries(property).forEach(([ key, value ]) => {
|
|
106
|
+
const subSchema = this.getSchemaItem(schema.properties, key);
|
|
107
|
+
this.validateProperty(subSchema, `${name}.${key}`, value);
|
|
108
|
+
});
|
|
109
|
+
Object.entries(schema.properties).forEach(([ key, subSchema ]) => {
|
|
110
|
+
if (!property[key] && subSchema.default !== undefined) {
|
|
111
|
+
this.debug(`Set default value for property ${name} to`, subSchema.default);
|
|
112
|
+
property[key] = subSchema.default;
|
|
113
|
+
} else if (!property[key] && subSchema.type === 'obj') {
|
|
114
|
+
property[key] = {};
|
|
115
|
+
}
|
|
116
|
+
this.validateProperty(subSchema, `${name}.${key}`, property[key]);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async fromFile (filepath) {
|
|
122
|
+
const fl = await FireFS.file(filepath);
|
|
123
|
+
if (!fl.exists) {
|
|
124
|
+
this.debug('Try file', filepath);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
this.debug('Load from file', filepath);
|
|
128
|
+
if (fl.ext === 'json') {
|
|
129
|
+
return fl.readJSON();
|
|
130
|
+
}
|
|
131
|
+
if (fl.ext === 'yaml' || fl.ext === 'yml') {
|
|
132
|
+
const yaml = require('js-yaml');
|
|
133
|
+
const source = await fl.read();
|
|
134
|
+
return yaml.load(source);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
setDefaults (config) {
|
|
140
|
+
Object.entries(this.configSchema).forEach(([ key, value ]) => {
|
|
141
|
+
if (typeof config[key] === 'undefined' && typeof value.default !== 'undefined') {
|
|
142
|
+
config[key] = value.default;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async load (name) {
|
|
148
|
+
this.debug('Load config', name);
|
|
149
|
+
for (const file of this.files) {
|
|
150
|
+
const filepath = path.resolve(this.workingDir, file.replace('%s', name));
|
|
151
|
+
const config = await this.fromFile(filepath);
|
|
152
|
+
if (config === null) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
// if config
|
|
156
|
+
// this.setDefaults(config)
|
|
157
|
+
if (!this.validate(config)) {
|
|
158
|
+
const validationErrors = this.validationErrors.join(' \n');
|
|
159
|
+
throw new Error(`Invalid config loaded!////n ${validationErrors}`);
|
|
160
|
+
}
|
|
161
|
+
this.config = config;
|
|
162
|
+
return config;
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
merge (...args) {
|
|
168
|
+
const conf = {};
|
|
169
|
+
const merge = (left, right, curdept) => {
|
|
170
|
+
if (left === undefined || left === null) {
|
|
171
|
+
left = {};
|
|
172
|
+
}
|
|
173
|
+
if (typeof right !== 'object') {
|
|
174
|
+
return left;
|
|
175
|
+
}
|
|
176
|
+
for (const key in right) {
|
|
177
|
+
if (right.hasOwnProperty(key)) {
|
|
178
|
+
if (right[key] === undefined) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (right[key] === null) {
|
|
182
|
+
left[key] = null;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (Array.isArray(right[key])) {
|
|
186
|
+
left[key] = right[key].map((item) => {
|
|
187
|
+
if (typeof item === 'object') {
|
|
188
|
+
return JSON.parse(JSON.stringify(item));
|
|
189
|
+
}
|
|
190
|
+
return item;
|
|
191
|
+
});
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (typeof right[key] === 'object') {
|
|
195
|
+
if (curdept) {
|
|
196
|
+
left[key] = merge(left[key], right[key], left[key]--);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
left[key] = Object.assign({}, right[key]);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
left[key] = right[key];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return left;
|
|
206
|
+
};
|
|
207
|
+
for (let i = 0; i < args.length; i++) {
|
|
208
|
+
merge(conf, args[i], this.mergeDept);
|
|
209
|
+
}
|
|
210
|
+
return conf;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
copy (obj) {
|
|
214
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
215
|
+
return obj;
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(obj)) {
|
|
218
|
+
return obj.map((item) => {
|
|
219
|
+
this.copy(item);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const copied = {};
|
|
223
|
+
for (const key in obj) {
|
|
224
|
+
if (obj.hasOwnProperty(key)) {
|
|
225
|
+
if (obj[key] === null) {
|
|
226
|
+
copied[key] = null;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (Array.isArray(obj[key])) {
|
|
230
|
+
copied[key] = obj[key].map((item) => {
|
|
231
|
+
this.copy(item);
|
|
232
|
+
});
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (typeof obj[key] === 'object') {
|
|
236
|
+
copied[key] = this.copy(obj[key]);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
copied[key] = obj[key];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return copied;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
get (configPath) {
|
|
246
|
+
const keys = configPath.split('.');
|
|
247
|
+
let conf = this.config;
|
|
248
|
+
for (const key of keys) {
|
|
249
|
+
conf = conf[key];
|
|
250
|
+
if (!conf) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return conf;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
module.exports.Superconf = Superconf;
|
package/app.js
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
module.exports.__fsLocationMap = [[1, 8, 2, 7], [1, 23, 2, 27], [1, 8, 2, 42], [3, 1, 3, 1], [3, 8, 3, 8], [3, 18, 3, 18], [3, 19, 3, 19], [3, 25, 3, 25], [4, 9, 4, 15], [5, 5, 5, 3], [5, 11, 5, 9], [5, 20, 5, 18], [5, 24, 5, 22], [5, 34, 5, 32], [6, 5, 6, 3], [6, 12, 6, 10], [6, 19, 6, 17], [6, 28, 6, 26], [8, 8, 8, 16], [8, 8, 8, 28], [10, 8, 9, 1], [10, 13, 9, 10], [10, 21, 9, 18], [12, 5, 11, 3], [12, 12, 11, 10], [12, 16, 11, 14], [12, 26, 11, 24], [10, 13, 13, 16], [10, 13, 13, 25], [14, 8, 14, 1], [14, 14, 14, 7], [14, 22, 14, 15], [14, 32, 14, 25], [14, 42, 14, 35], [14, 14, 15, 16], [14, 14, 15, 24], [15, 8, 16, 1], [15, 14, 16, 7], [15, 21, 16, 14], [15, 31, 16, 24], [15, 41, 16, 34], [15, 14, 17, 16], [15, 14, 17, 23]];
|
|
2
|
+
module.exports.__esModule = true;
|
|
3
|
+
const Superconf = require('./Superconf').Superconf;
|
|
4
|
+
module.exports = (name, opts) => {
|
|
5
|
+
console.log('Superconf: Import namespace method is deprecated. Use named imports instead');
|
|
6
|
+
const config = new Superconf(opts);
|
|
7
|
+
return config.tryFiles(name);
|
|
8
|
+
};
|
|
9
|
+
module.exports.Superconf = Superconf;
|
|
10
|
+
function config (opts) {
|
|
11
|
+
// log 'Superconf: Import of config() method is deprecated. Use named imports instead'
|
|
12
|
+
return new Superconf(opts);
|
|
13
|
+
}
|
|
14
|
+
module.exports.config = config;
|
|
15
|
+
const merge = Superconf.prototype.merge;
|
|
16
|
+
module.exports.merge = merge;
|
|
17
|
+
const copy = Superconf.prototype.copy;
|
|
18
|
+
module.exports.copy = copy;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superconf",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Smart configuration loader",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"scripts": {
|
|
@@ -37,5 +37,9 @@
|
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/Andifeind/superconf/issues"
|
|
39
39
|
},
|
|
40
|
-
"homepage": "https://github.com/Andifeind/superconf#readme"
|
|
40
|
+
"homepage": "https://github.com/Andifeind/superconf#readme",
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"registry": "https://registry.npmjs.com/"
|
|
43
|
+
},
|
|
44
|
+
"firescript": "0.21.2"
|
|
41
45
|
}
|
package/.eslintrc.json
DELETED
package/.firerc.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"build": {
|
|
3
|
-
"destDir": "dist/",
|
|
4
|
-
"srcDir": "src/",
|
|
5
|
-
"copyFiles": [
|
|
6
|
-
"/package.json",
|
|
7
|
-
"/LICENSE",
|
|
8
|
-
"/README.md",
|
|
9
|
-
"Legacy.js"
|
|
10
|
-
]
|
|
11
|
-
},
|
|
12
|
-
"features": {
|
|
13
|
-
"esModules": false,
|
|
14
|
-
"esDefaultParams": false,
|
|
15
|
-
"esClasses": true,
|
|
16
|
-
"esTemplates": true,
|
|
17
|
-
"extendRegExp": true
|
|
18
|
-
}
|
|
19
|
-
}
|
package/.fslintignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
docs/
|
package/.gitlab-ci.yml
DELETED
package/docs/doxydoc/main.fire
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import * as path from 'path'
|
|
2
|
-
import DocGenerator from 'doxydoc'
|
|
3
|
-
import Superconf from '../../'
|
|
4
|
-
|
|
5
|
-
export const doc = new DocGenerator()
|
|
6
|
-
doc.setTitle('Superconf')
|
|
7
|
-
doc.setFilename(path.join(__dirname, '../superconf.md'))
|
|
8
|
-
doc.setAsset('class', 'Superconf')
|
|
9
|
-
|
|
10
|
-
doc.intro = 'Superconf is a smart configuration loader for Node.js. It supports different config formats, ENV variables and validates config against a config schema'
|
|
11
|
-
|
|
12
|
-
# doc.property('obj', 'components', 'Contains app component')
|
|
13
|
-
# doc.property('arr', 'cssStyles', 'Holds all cssStyles used by Components')
|
|
14
|
-
# doc.property('arr', 'dataServices', 'Holdsw all dataservices used by Components')
|
|
15
|
-
# doc.property('arr', 'scripts', 'Contains all necesary scripts and clientLibs')
|
|
16
|
-
# doc.property('arr', 'signals', 'Holds all signals used by Components')
|
|
17
|
-
# doc.property('arr', 'states', 'Holds all states used by Components')
|
|
18
|
-
#
|
|
19
|
-
doc.method('void', 'schema', [{
|
|
20
|
-
type: 'obj', name: 'schemaConf', description: 'Schema config object'
|
|
21
|
-
}], 'Set schema config')
|
|
22
|
-
|
|
23
|
-
doc.method('void', 'fromFile', [{
|
|
24
|
-
type: 'str', name: 'name', description: 'Use `name` as filename'
|
|
25
|
-
}], 'Import config from file')
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Test data
|
|
29
|
-
const sc = new Superconf()
|
|
30
|
-
|
|
31
|
-
doc.setData(sc)
|
|
32
|
-
doc.example('json', sc, 'Superconf structure', 'This shows the data structure of a Superconf instance')
|
|
33
|
-
|
|
34
|
-
doc.generate().then(() =>
|
|
35
|
-
log 'Documentation' doc.filename 'generated'
|
|
36
|
-
).catch((err) =>
|
|
37
|
-
throw err
|
|
38
|
-
)
|
package/docs/superconf.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
Superconf
|
|
2
|
-
=========
|
|
3
|
-
|
|
4
|
-
Superconf is a smart configuration loader for Node.js. It supports different config formats, ENV variables and validates config against a config schema
|
|
5
|
-
|
|
6
|
-
#### Structure
|
|
7
|
-
|
|
8
|
-
```coffee
|
|
9
|
-
class Superconf
|
|
10
|
-
# Methods
|
|
11
|
-
schema(obj schemaConf) : void
|
|
12
|
-
fromFile(str name) : void
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
### Methods
|
|
18
|
-
|
|
19
|
-
#### schema(*obj* schemaConf) : *void*
|
|
20
|
-
Set schema config
|
|
21
|
-
|
|
22
|
-
#### fromFile(*str* name) : *void*
|
|
23
|
-
Import config from file
|
|
24
|
-
|
|
25
|
-
### Examples
|
|
26
|
-
|
|
27
|
-
#### Superconf structure
|
|
28
|
-
|
|
29
|
-
This shows the data structure of a Superconf instance
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"files": [
|
|
34
|
-
"%s.json",
|
|
35
|
-
"%s.cson",
|
|
36
|
-
"%s.yaml",
|
|
37
|
-
"%s.yml",
|
|
38
|
-
".%src",
|
|
39
|
-
".%src.json",
|
|
40
|
-
".%src.cson",
|
|
41
|
-
".%src.yaml",
|
|
42
|
-
".%src.yml",
|
|
43
|
-
"package.json"
|
|
44
|
-
],
|
|
45
|
-
"cwd": "/home/andi/Projects/Nodejs/superconf",
|
|
46
|
-
"workingDir": "/home/andi/Projects/Nodejs/superconf",
|
|
47
|
-
"configData": {},
|
|
48
|
-
"verbose": false
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
### Undocumented
|
|
55
|
-
|
|
56
|
-
#### Undocumented properties and methods
|
|
57
|
-
|
|
58
|
-
| Name | Description |
|
|
59
|
-
|-----------------|----------------------------------------|
|
|
60
|
-
| files | Property files is not documented |
|
|
61
|
-
| cwd | Property cwd is not documented |
|
|
62
|
-
| workingDir | Property workingDir is not documented |
|
|
63
|
-
| configData | Property configData is not documented |
|
|
64
|
-
| verbose | Property verbose is not documented |
|
|
65
|
-
| constructor() | Method constructor is not documented |
|
|
66
|
-
| debug() | Method debug is not documented |
|
|
67
|
-
| getSchemaItem() | Method getSchemaItem is not documented |
|
|
68
|
-
| validate() | Method validate is not documented |
|
package/src/Superconf.fire
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import Superconf as Legacy from './Legacy'
|
|
2
|
-
import * as colorfy from 'colorfy'
|
|
3
|
-
import * as path from 'path'
|
|
4
|
-
import FireFS from 'firescript-firefs'
|
|
5
|
-
|
|
6
|
-
const red = '\u001b[38;5;160m'
|
|
7
|
-
const ored = '\u001b[38;5;202m'
|
|
8
|
-
const yellow = '\u001b[38;5;226m'
|
|
9
|
-
const dgrey = '\u001b[38;5;244m'
|
|
10
|
-
const lgrey = '\u001b[38;5;250m'
|
|
11
|
-
const azure = '\u001b[38;5;39m'
|
|
12
|
-
const uncolor = '\u001b[m'
|
|
13
|
-
|
|
14
|
-
export class Superconf extends Legacy
|
|
15
|
-
constructor (opts = {})
|
|
16
|
-
super(opts)
|
|
17
|
-
|
|
18
|
-
this.workingDir = opts.workingDir || process.cwd()
|
|
19
|
-
this.config = {}
|
|
20
|
-
this.verbose = opts.verbose || false
|
|
21
|
-
this.mergeDept = opts.dept || 0
|
|
22
|
-
|
|
23
|
-
this.files = opts.files || [
|
|
24
|
-
'%s.json'
|
|
25
|
-
'%s.yaml'
|
|
26
|
-
'%s.yml'
|
|
27
|
-
'.%src.json'
|
|
28
|
-
'.%src.yaml'
|
|
29
|
-
'.%src.yml'
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
debug (msg, ...data)
|
|
34
|
-
if this.verbose
|
|
35
|
-
log colorfy.yellow('Superconf:'), colorfy.grey(msg), ...data
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
schema (configSchema)
|
|
39
|
-
this.configSchema = {}
|
|
40
|
-
Object.entries(configSchema).forEach(([key, value]) =>
|
|
41
|
-
const schema = {
|
|
42
|
-
type: value.type || 'str'
|
|
43
|
-
required: value.required || false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if typeof value.default !== 'undefined'
|
|
47
|
-
schema.default = value.default
|
|
48
|
-
|
|
49
|
-
if typeof value.properties !== 'undefined'
|
|
50
|
-
schema.properties = value.properties
|
|
51
|
-
|
|
52
|
-
this.configSchema[key] = schema
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
getSchemaItem (schema, key)
|
|
57
|
-
return schema[key] || null
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
validate (conf)
|
|
61
|
-
if !this.configSchema
|
|
62
|
-
return true
|
|
63
|
-
|
|
64
|
-
this.validationErrors = []
|
|
65
|
-
const validateionData = conf || this.config
|
|
66
|
-
const validateionSchema = {
|
|
67
|
-
type: 'obj'
|
|
68
|
-
properties: this.configSchema
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
this.validateProperty(validateionSchema, 'config', validateionData)
|
|
72
|
-
|
|
73
|
-
return this.validationErrors.length === 0
|
|
74
|
-
|
|
75
|
-
validateProperty (schema, name, property)
|
|
76
|
-
this.debug('Validate property ${name} with value', property, 'against schema', schema)
|
|
77
|
-
|
|
78
|
-
if !schema
|
|
79
|
-
return true
|
|
80
|
-
|
|
81
|
-
if !property
|
|
82
|
-
if schema.required === true
|
|
83
|
-
this.validationErrors.push('Item ${name} is required but not set')
|
|
84
|
-
|
|
85
|
-
else
|
|
86
|
-
return true
|
|
87
|
-
|
|
88
|
-
if schema.type === 'str'
|
|
89
|
-
if typeof property !== 'string'
|
|
90
|
-
this.validationErrors.push('Item ${name} is not of type string')
|
|
91
|
-
|
|
92
|
-
elif schema.type === 'num'
|
|
93
|
-
if typeof property !== 'number'
|
|
94
|
-
this.validationErrors.push('Item ${name} is not of type number')
|
|
95
|
-
|
|
96
|
-
elif schema.type === 'bool'
|
|
97
|
-
if typeof property !== 'boolean'
|
|
98
|
-
this.validationErrors.push('Item ${name} is not of type boolean')
|
|
99
|
-
|
|
100
|
-
elif schema.type === 'arr'
|
|
101
|
-
if !Array.isArray(property)
|
|
102
|
-
this.validationErrors.push('Item ${name} is not of type array')
|
|
103
|
-
|
|
104
|
-
elif schema.type === 'obj'
|
|
105
|
-
if typeof property !== 'object'
|
|
106
|
-
this.validationErrors.push('Item ${name} is not of type object')
|
|
107
|
-
|
|
108
|
-
Object.entries(property).forEach(([key, value]) =>
|
|
109
|
-
const subSchema = this.getSchemaItem(schema.properties, key)
|
|
110
|
-
this.validateProperty(subSchema, '${name}.${key}', value)
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
Object.entries(schema.properties).forEach(([key, subSchema]) =>
|
|
114
|
-
if !property[key] && subSchema.default !== undefined
|
|
115
|
-
this.debug('Set default value for property ${name} to', subSchema.default)
|
|
116
|
-
property[key] = subSchema.default
|
|
117
|
-
|
|
118
|
-
elif !property[key] && subSchema.type === 'obj'
|
|
119
|
-
property[key] = {}
|
|
120
|
-
|
|
121
|
-
this.validateProperty(subSchema, '${name}.${key}', property[key])
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
async fromFile (filepath)
|
|
125
|
-
const fl = await FireFS.file(filepath)
|
|
126
|
-
|
|
127
|
-
if !fl.exists
|
|
128
|
-
this.debug('Try file', filepath)
|
|
129
|
-
return null
|
|
130
|
-
|
|
131
|
-
this.debug('Load from file', filepath)
|
|
132
|
-
if fl.ext === 'json'
|
|
133
|
-
return fl.readJSON()
|
|
134
|
-
|
|
135
|
-
if fl.ext === 'yaml' || fl.ext === 'yml'
|
|
136
|
-
const yaml = require('js-yaml')
|
|
137
|
-
const source = await fl.read()
|
|
138
|
-
return yaml.load(source)
|
|
139
|
-
|
|
140
|
-
return null
|
|
141
|
-
|
|
142
|
-
setDefaults (config)
|
|
143
|
-
Object.entries(this.configSchema).forEach(([key, value]) =>
|
|
144
|
-
if typeof config[key] === 'undefined' && typeof value.default !== 'undefined'
|
|
145
|
-
config[key] = value.default
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
async load (name)
|
|
150
|
-
this.debug('Load config', name)
|
|
151
|
-
|
|
152
|
-
for const file of this.files
|
|
153
|
-
const filepath = path.resolve(this.workingDir, file.replace('%s', name))
|
|
154
|
-
const config = await this.fromFile(filepath)
|
|
155
|
-
|
|
156
|
-
if config === null
|
|
157
|
-
continue
|
|
158
|
-
|
|
159
|
-
# if config
|
|
160
|
-
# this.setDefaults(config)
|
|
161
|
-
|
|
162
|
-
if !this.validate(config)
|
|
163
|
-
const validationErrors = this.validationErrors.join(' \n')
|
|
164
|
-
throw new Error('Invalid config loaded!\n ${validationErrors}')
|
|
165
|
-
|
|
166
|
-
this.config = config
|
|
167
|
-
return config
|
|
168
|
-
|
|
169
|
-
return null
|
|
170
|
-
|
|
171
|
-
merge (...args)
|
|
172
|
-
const conf = {}
|
|
173
|
-
|
|
174
|
-
const merge = (left, right, curdept) =>
|
|
175
|
-
if left === undefined || left === null
|
|
176
|
-
left = {}
|
|
177
|
-
|
|
178
|
-
if typeof right !== 'object'
|
|
179
|
-
return left
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
for const key in right
|
|
183
|
-
if right.hasOwnProperty(key)
|
|
184
|
-
if right[key] === undefined
|
|
185
|
-
continue
|
|
186
|
-
|
|
187
|
-
if right[key] === null
|
|
188
|
-
left[key] = null
|
|
189
|
-
continue
|
|
190
|
-
|
|
191
|
-
if Array.isArray(right[key])
|
|
192
|
-
left[key] = right[key].map((item) =>
|
|
193
|
-
if typeof item === 'object'
|
|
194
|
-
return JSON.parse(JSON.stringify(item))
|
|
195
|
-
|
|
196
|
-
return item
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
continue
|
|
200
|
-
|
|
201
|
-
if typeof right[key] === 'object'
|
|
202
|
-
if curdept
|
|
203
|
-
left[key] = merge(left[key], right[key], left[key]--)
|
|
204
|
-
continue
|
|
205
|
-
|
|
206
|
-
left[key] = Object.assign({}, right[key])
|
|
207
|
-
continue
|
|
208
|
-
|
|
209
|
-
left[key] = right[key]
|
|
210
|
-
|
|
211
|
-
return left
|
|
212
|
-
|
|
213
|
-
for let i = 0; i < args.length; i++
|
|
214
|
-
merge(conf, args[i], this.mergeDept)
|
|
215
|
-
|
|
216
|
-
return conf
|
|
217
|
-
|
|
218
|
-
copy (obj)
|
|
219
|
-
if typeof obj !== 'object' || obj === null
|
|
220
|
-
return obj
|
|
221
|
-
|
|
222
|
-
if Array.isArray(obj)
|
|
223
|
-
return obj.map((item) =>
|
|
224
|
-
this.copy(item)
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
const copied = {}
|
|
228
|
-
for const key in obj
|
|
229
|
-
if obj.hasOwnProperty(key)
|
|
230
|
-
if obj[key] === null
|
|
231
|
-
copied[key] = null
|
|
232
|
-
continue
|
|
233
|
-
|
|
234
|
-
if Array.isArray(obj[key])
|
|
235
|
-
copied[key] = obj[key].map((item) =>
|
|
236
|
-
this.copy(item)
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
continue
|
|
240
|
-
|
|
241
|
-
if typeof obj[key] === 'object'
|
|
242
|
-
copied[key] = this.copy(obj[key])
|
|
243
|
-
continue
|
|
244
|
-
|
|
245
|
-
copied[key] = obj[key]
|
|
246
|
-
|
|
247
|
-
return copied
|
|
248
|
-
|
|
249
|
-
get (configPath)
|
|
250
|
-
const keys = configPath.split('.')
|
|
251
|
-
let conf = this.config
|
|
252
|
-
|
|
253
|
-
for const key of keys
|
|
254
|
-
conf = conf[key]
|
|
255
|
-
if !conf
|
|
256
|
-
return null
|
|
257
|
-
|
|
258
|
-
return conf
|
package/src/app.fire
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import Superconf from './Superconf'
|
|
2
|
-
|
|
3
|
-
module.exports = (name, opts) =>
|
|
4
|
-
log 'Superconf: Import namespace method is deprecated. Use named imports instead'
|
|
5
|
-
const config = new Superconf(opts)
|
|
6
|
-
return config.tryFiles(name)
|
|
7
|
-
|
|
8
|
-
export Superconf
|
|
9
|
-
|
|
10
|
-
export func config (opts)
|
|
11
|
-
# log 'Superconf: Import of config() method is deprecated. Use named imports instead'
|
|
12
|
-
return new Superconf(opts)
|
|
13
|
-
|
|
14
|
-
export const merge = Superconf.prototype.merge
|
|
15
|
-
export const copy = Superconf.prototype.copy
|
package/tests/.eslintrc
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import * as path from 'path'
|
|
2
|
-
import Superconf from '../'
|
|
3
|
-
|
|
4
|
-
export class SuperconfTest
|
|
5
|
-
schemaTest()
|
|
6
|
-
const superconf = new Superconf()
|
|
7
|
-
superconf.schema({
|
|
8
|
-
fruit:
|
|
9
|
-
type: 'str'
|
|
10
|
-
required: true
|
|
11
|
-
|
|
12
|
-
price:
|
|
13
|
-
type: 'num'
|
|
14
|
-
default: 1328
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
inspect(superconf.configSchema).isEql({
|
|
18
|
-
fruit:
|
|
19
|
-
type: 'str'
|
|
20
|
-
required: true
|
|
21
|
-
|
|
22
|
-
price:
|
|
23
|
-
type: 'num'
|
|
24
|
-
required: false
|
|
25
|
-
default: 1328
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
validateTest ()
|
|
29
|
-
const superconf = new Superconf({
|
|
30
|
-
verbose: true
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
superconf.schema({
|
|
34
|
-
fruit:
|
|
35
|
-
type: 'str'
|
|
36
|
-
required: true
|
|
37
|
-
|
|
38
|
-
price:
|
|
39
|
-
type: 'num'
|
|
40
|
-
default: 1328
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
superconf.config = {
|
|
44
|
-
fruit: 'banana'
|
|
45
|
-
price: 1.99
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
inspect(superconf.validate()).isTrue()
|
|
49
|
-
|
|
50
|
-
async loadJSONTest ()
|
|
51
|
-
const superconf = new Superconf({
|
|
52
|
-
verbose: true
|
|
53
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
const json = await superconf.load('jsontest')
|
|
57
|
-
inspect(json).isEql({
|
|
58
|
-
fruit: 'Banana'
|
|
59
|
-
vegetable: 'Tomato'
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
async loadYMLTest ()
|
|
63
|
-
const superconf = new Superconf({
|
|
64
|
-
verbose: true
|
|
65
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const json = await superconf.load('ymltest')
|
|
69
|
-
inspect(json).isEql({
|
|
70
|
-
fruit: 'Banana'
|
|
71
|
-
vegetable: 'Tomato'
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
async loadYAMLTest ()
|
|
75
|
-
const superconf = new Superconf({
|
|
76
|
-
verbose: true
|
|
77
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
const json = await superconf.load('yamltest')
|
|
81
|
-
inspect(json).isEql({
|
|
82
|
-
fruit: 'Banana'
|
|
83
|
-
vegetable: 'Tomato'
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
async loadJSONRCTest ()
|
|
87
|
-
const superconf = new Superconf({
|
|
88
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
const json = await superconf.load('rcjsontest')
|
|
92
|
-
inspect(json).isEql({
|
|
93
|
-
fruit: 'Banana'
|
|
94
|
-
vegetable: 'Tomato'
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
async loadYMLRCTest ()
|
|
98
|
-
const superconf = new Superconf({
|
|
99
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
const json = await superconf.load('rcymltest')
|
|
103
|
-
inspect(json).isEql({
|
|
104
|
-
fruit: 'Banana'
|
|
105
|
-
vegetable: 'Tomato'
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
async loadYAMLRCTest ()
|
|
109
|
-
const superconf = new Superconf({
|
|
110
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const json = await superconf.load('rcyamltest')
|
|
114
|
-
inspect(json).isEql({
|
|
115
|
-
fruit: 'Banana'
|
|
116
|
-
vegetable: 'Tomato'
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
async getSubsetTest ()
|
|
120
|
-
const superconf = new Superconf({
|
|
121
|
-
verbose: true
|
|
122
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
await superconf.load('fruits')
|
|
126
|
-
inspect(superconf.get('fruits')).isEql({
|
|
127
|
-
banana:
|
|
128
|
-
name: 'Banana'
|
|
129
|
-
color: 'yellow'
|
|
130
|
-
|
|
131
|
-
coconut:
|
|
132
|
-
name: 'Coconut'
|
|
133
|
-
color: 'brown'
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
async getSuperSubsetTest ()
|
|
137
|
-
const superconf = new Superconf({
|
|
138
|
-
verbose: true
|
|
139
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
await superconf.load('fruits')
|
|
143
|
-
inspect(superconf.get('fruits.banana')).isEql({
|
|
144
|
-
name: 'Banana'
|
|
145
|
-
color: 'yellow'
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
async getNonExistingSuperSubsetTest ()
|
|
149
|
-
const superconf = new Superconf({
|
|
150
|
-
verbose: true
|
|
151
|
-
workingDir: path.join(__dirname, '/fixtures/')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
await superconf.load('fruits')
|
|
155
|
-
inspect(superconf.get('vegetables')).isNull()
|
|
156
|
-
inspect(superconf.get('fruits.cherry')).isNull()
|
package/tests/superconf.spec.js
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const path = require('path')
|
|
4
|
-
|
|
5
|
-
const inspect = require('inspect.js')
|
|
6
|
-
const superconf = require('../app.js')
|
|
7
|
-
|
|
8
|
-
console.log('SC', superconf)
|
|
9
|
-
|
|
10
|
-
process.chdir(path.join(__dirname, '/fixtures/'))
|
|
11
|
-
|
|
12
|
-
describe('Superconf', () => {
|
|
13
|
-
describe('JSON', () => {
|
|
14
|
-
it('Should load a JSON conf', () => {
|
|
15
|
-
const conf = superconf('pkgtest')
|
|
16
|
-
inspect(conf).isObject()
|
|
17
|
-
inspect(conf).isEql({
|
|
18
|
-
foo: 'bar',
|
|
19
|
-
bla: 'blub'
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('Should load a JSON conf', () => {
|
|
24
|
-
const conf = superconf('pkgtest')
|
|
25
|
-
inspect(conf).isObject()
|
|
26
|
-
inspect(conf).isEql({
|
|
27
|
-
foo: 'bar',
|
|
28
|
-
bla: 'blub'
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('Should load a JSON from defaultConf', () => {
|
|
33
|
-
const conf = superconf('defaulttest', {
|
|
34
|
-
defaultConf: path.join(__dirname, './fixtures/defaultConf.json')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
inspect(conf).isObject()
|
|
38
|
-
inspect(conf).isEql({
|
|
39
|
-
foo: 'bar',
|
|
40
|
-
bla: 'blub'
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('Should not load a JSON from defaultConf', () => {
|
|
45
|
-
const conf = superconf('defaulttest')
|
|
46
|
-
|
|
47
|
-
inspect(conf).isNull()
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('merge()', function () {
|
|
52
|
-
it('Should merge object using Object.assign()', function () {
|
|
53
|
-
const left = {
|
|
54
|
-
fruit: 'Apple',
|
|
55
|
-
vegetable: 'Carrot'
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const right = {
|
|
59
|
-
fruit: 'Banana',
|
|
60
|
-
vegetable: undefined
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const conf = Object.assign(left, right)
|
|
64
|
-
inspect(conf).isEql({
|
|
65
|
-
fruit: 'Banana',
|
|
66
|
-
vegetable: undefined
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('Should merge config objects', function () {
|
|
71
|
-
const left = {
|
|
72
|
-
fruit: 'Apple',
|
|
73
|
-
vegetable: 'Carrot'
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const right = {
|
|
77
|
-
fruit: 'Banana',
|
|
78
|
-
vegetable: undefined
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const conf = superconf.merge(left, right)
|
|
82
|
-
inspect(conf).isEql({
|
|
83
|
-
fruit: 'Banana',
|
|
84
|
-
vegetable: 'Carrot'
|
|
85
|
-
})
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('Should overwrite objects', function () {
|
|
89
|
-
const left = {
|
|
90
|
-
fruit: 'Apple',
|
|
91
|
-
vegetables: {
|
|
92
|
-
red: 'Tomato',
|
|
93
|
-
green: 'Curcumber',
|
|
94
|
-
blue: 'Red cabbage'
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const right = {
|
|
99
|
-
fruit: 'Banana',
|
|
100
|
-
vegetables: {
|
|
101
|
-
red: 'Capsicum'
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const conf = superconf.merge(left, right)
|
|
106
|
-
inspect(conf).isEql({
|
|
107
|
-
fruit: 'Banana',
|
|
108
|
-
vegetables: {
|
|
109
|
-
red: 'Capsicum'
|
|
110
|
-
}
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('Should overwrite arrays', function () {
|
|
115
|
-
const left = {
|
|
116
|
-
fruit: 'Apple',
|
|
117
|
-
vegetables: [
|
|
118
|
-
'Tomato',
|
|
119
|
-
'Curcumber',
|
|
120
|
-
'Red cabbage'
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const right = {
|
|
125
|
-
fruit: 'Banana',
|
|
126
|
-
vegetables: [
|
|
127
|
-
'Capsicum'
|
|
128
|
-
]
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const conf = superconf.merge(left, right)
|
|
132
|
-
inspect(conf).isEql({
|
|
133
|
-
fruit: 'Banana',
|
|
134
|
-
vegetables: [
|
|
135
|
-
'Capsicum'
|
|
136
|
-
]
|
|
137
|
-
})
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('Should merge the first level together', function () {
|
|
141
|
-
const left = {
|
|
142
|
-
fruit: 'Apple',
|
|
143
|
-
vegetables: {
|
|
144
|
-
red: 'Tomato',
|
|
145
|
-
green: 'Curcumber',
|
|
146
|
-
blue: 'Red cabbage'
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const right = {
|
|
151
|
-
fruit: 'Banana',
|
|
152
|
-
vegetables: {
|
|
153
|
-
red: 'Capsicum'
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const conf = superconf.config({
|
|
158
|
-
dept: 1
|
|
159
|
-
}).merge(left, right)
|
|
160
|
-
|
|
161
|
-
inspect(conf).isEql({
|
|
162
|
-
fruit: 'Banana',
|
|
163
|
-
vegetables: {
|
|
164
|
-
red: 'Capsicum',
|
|
165
|
-
green: 'Curcumber',
|
|
166
|
-
blue: 'Red cabbage'
|
|
167
|
-
}
|
|
168
|
-
})
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it('Should merge the first level together, using arrays', function () {
|
|
172
|
-
const left = {
|
|
173
|
-
fruit: 'Apple',
|
|
174
|
-
vegetables: {
|
|
175
|
-
red: [
|
|
176
|
-
'Tomato',
|
|
177
|
-
'Capsicum'
|
|
178
|
-
]
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const right = {
|
|
183
|
-
fruit: 'Banana',
|
|
184
|
-
vegetables: {
|
|
185
|
-
green: [
|
|
186
|
-
'Curcumber'
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const conf = superconf.config({
|
|
192
|
-
dept: 1
|
|
193
|
-
}).merge(left, right)
|
|
194
|
-
inspect(conf).isEql({
|
|
195
|
-
fruit: 'Banana',
|
|
196
|
-
vegetables: {
|
|
197
|
-
red: ['Tomato', 'Capsicum'],
|
|
198
|
-
green: ['Curcumber']
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
})
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
describe('copy()', () => {
|
|
205
|
-
it('copies a config object', () => {
|
|
206
|
-
const obj = {
|
|
207
|
-
foo: 'foo',
|
|
208
|
-
bar: 'bar',
|
|
209
|
-
bla: {
|
|
210
|
-
blub: 123
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const copied = superconf.copy(obj)
|
|
215
|
-
inspect(copied).isEql(obj)
|
|
216
|
-
inspect(copied).isNotEqual(obj)
|
|
217
|
-
inspect(copied.bla).isNotEqual(obj.bla)
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
it('copies a config object with an array', () => {
|
|
221
|
-
const three = {
|
|
222
|
-
number: {
|
|
223
|
-
digit: 3
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const obj = {
|
|
228
|
-
foo: 'foo',
|
|
229
|
-
bar: 'bar',
|
|
230
|
-
bla: [
|
|
231
|
-
'one',
|
|
232
|
-
'zwo',
|
|
233
|
-
three
|
|
234
|
-
]
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const copied = superconf.copy(obj)
|
|
238
|
-
inspect(copied).isEql(obj)
|
|
239
|
-
inspect(copied).isNotEqual(obj)
|
|
240
|
-
inspect(copied.bla).isArray().hasLength(3)
|
|
241
|
-
inspect(copied.bla).isNotEqual(obj.bla)
|
|
242
|
-
inspect(copied.bla[2]).isEql(three).isNotEqual(three)
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('copies a config object with all existing shit', () => {
|
|
246
|
-
const three = {
|
|
247
|
-
number: {
|
|
248
|
-
digit: 3,
|
|
249
|
-
str: 'three',
|
|
250
|
-
used: null,
|
|
251
|
-
none: undefined
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const obj = {
|
|
256
|
-
foo: 'foo',
|
|
257
|
-
bar: 'bar',
|
|
258
|
-
bla: [
|
|
259
|
-
'one',
|
|
260
|
-
'zwo',
|
|
261
|
-
three,
|
|
262
|
-
123,
|
|
263
|
-
null,
|
|
264
|
-
undefined,
|
|
265
|
-
['sub-one']
|
|
266
|
-
]
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const copied = superconf.copy(obj)
|
|
270
|
-
inspect(copied).isEql(obj)
|
|
271
|
-
inspect(copied).isNotEqual(obj)
|
|
272
|
-
inspect(copied.bla).isArray().hasLength(7)
|
|
273
|
-
inspect(copied.bla).isNotEqual(obj.bla)
|
|
274
|
-
inspect(copied.bla[2]).isEql(three).isNotEqual(three)
|
|
275
|
-
})
|
|
276
|
-
})
|
|
277
|
-
})
|
|
File without changes
|