@baravak/risloo-profile-cli 3.1.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 (200) hide show
  1. package/.github/workflows/push.yml +14 -0
  2. package/.prettierrc +16 -0
  3. package/.yarn/releases/yarn-1.22.19.cjs +147529 -0
  4. package/.yarnrc.yml +1 -0
  5. package/README.md +98 -0
  6. package/bin/risloo.js +9 -0
  7. package/package.json +44 -0
  8. package/src/Gift.js +29 -0
  9. package/src/Profile.js +405 -0
  10. package/src/cli-commands/Executor.js +118 -0
  11. package/src/cli-commands/ExtractExecutor.js +194 -0
  12. package/src/cli-commands/GiftExecutor.js +56 -0
  13. package/src/cli-commands/utilities/BaseOps.js +71 -0
  14. package/src/cli-commands/utilities/Benchmarker.js +88 -0
  15. package/src/cli-commands/utilities/CustomErrors.js +14 -0
  16. package/src/cli-commands/utilities/Response.js +59 -0
  17. package/src/cli-commands/utilities/STATUSES.js +16 -0
  18. package/src/cli-commands/utilities/Status.js +9 -0
  19. package/src/cli.js +125 -0
  20. package/src/handlebars/helpers/abs.js +8 -0
  21. package/src/handlebars/helpers/addCommas.js +8 -0
  22. package/src/handlebars/helpers/array.js +8 -0
  23. package/src/handlebars/helpers/assignGlobal.js +9 -0
  24. package/src/handlebars/helpers/boolean.js +19 -0
  25. package/src/handlebars/helpers/ceil.js +8 -0
  26. package/src/handlebars/helpers/concat.js +8 -0
  27. package/src/handlebars/helpers/cos.js +8 -0
  28. package/src/handlebars/helpers/displacePoint.js +11 -0
  29. package/src/handlebars/helpers/ellipsisChars.js +10 -0
  30. package/src/handlebars/helpers/ellipsisLines.js +11 -0
  31. package/src/handlebars/helpers/first.js +11 -0
  32. package/src/handlebars/helpers/floor.js +8 -0
  33. package/src/handlebars/helpers/forLoop.js +15 -0
  34. package/src/handlebars/helpers/getArrOfProp.js +8 -0
  35. package/src/handlebars/helpers/isArray.js +8 -0
  36. package/src/handlebars/helpers/join.js +10 -0
  37. package/src/handlebars/helpers/last.js +11 -0
  38. package/src/handlebars/helpers/lineWrap.js +28 -0
  39. package/src/handlebars/helpers/math.js +24 -0
  40. package/src/handlebars/helpers/modulo.js +8 -0
  41. package/src/handlebars/helpers/normalizeAngle.js +7 -0
  42. package/src/handlebars/helpers/object.js +8 -0
  43. package/src/handlebars/helpers/objectEntries.js +8 -0
  44. package/src/handlebars/helpers/polarToCartesian.js +14 -0
  45. package/src/handlebars/helpers/prepend.js +10 -0
  46. package/src/handlebars/helpers/profiles/bar.js +45 -0
  47. package/src/handlebars/helpers/profiles/calcGaugeSidePoints.js +34 -0
  48. package/src/handlebars/helpers/profiles/gauge.js +61 -0
  49. package/src/handlebars/helpers/profiles/polygon.js +40 -0
  50. package/src/handlebars/helpers/reverse.js +9 -0
  51. package/src/handlebars/helpers/roundToTwo.js +8 -0
  52. package/src/handlebars/helpers/setVar.js +8 -0
  53. package/src/handlebars/helpers/sin.js +8 -0
  54. package/src/handlebars/helpers/split.js +8 -0
  55. package/src/handlebars/helpers/tan.js +8 -0
  56. package/src/handlebars/helpers/ternary.js +9 -0
  57. package/src/handlebars/helpers/toDeg.js +8 -0
  58. package/src/handlebars/helpers/toRad.js +8 -0
  59. package/src/handlebars/helpers/withGroup.js +20 -0
  60. package/src/handlebars/helpers/wrapOnNewline.js +11 -0
  61. package/src/handlebars/helpers.js +86 -0
  62. package/src/handlebars/importPartials.js +40 -0
  63. package/src/handlebars/init.js +15 -0
  64. package/src/publish/bot.js +91 -0
  65. package/src/publish/json/gift/gift.json +16 -0
  66. package/src/publish/json/profiles/16PF93.json +201 -0
  67. package/src/publish/json/profiles/AEQ93.json +96 -0
  68. package/src/publish/json/profiles/AMS93.json +102 -0
  69. package/src/publish/json/profiles/AMS9A.json +102 -0
  70. package/src/publish/json/profiles/BAOMEIS93.json +99 -0
  71. package/src/publish/json/profiles/BEQI93.json +1589 -0
  72. package/src/publish/json/profiles/CAATS93.json +11355 -0
  73. package/src/publish/json/profiles/CADS93.json +351 -0
  74. package/src/publish/json/profiles/CARSP93.json +96 -0
  75. package/src/publish/json/profiles/CERQ93.json +106 -0
  76. package/src/publish/json/profiles/CRAAS93.json +98 -0
  77. package/src/publish/json/profiles/CSI93.json +143 -0
  78. package/src/publish/json/profiles/DSWLS93.json +93 -0
  79. package/src/publish/json/profiles/EMSS93.json +116 -0
  80. package/src/publish/json/profiles/FACES93.json +106 -0
  81. package/src/publish/json/profiles/FTEPT93.json +102 -0
  82. package/src/publish/json/profiles/GMIT93.json +98 -0
  83. package/src/publish/json/profiles/HPL93.json +102 -0
  84. package/src/publish/json/profiles/IBT93.json +106 -0
  85. package/src/publish/json/profiles/IUS93.json +93 -0
  86. package/src/publish/json/profiles/JCSI93.json +102 -0
  87. package/src/publish/json/profiles/JPFQ93.json +1 -0
  88. package/src/publish/json/profiles/KJGI93.json +100 -0
  89. package/src/publish/json/profiles/LMIQ93.json +109 -0
  90. package/src/publish/json/profiles/MMFAD93.json +103 -0
  91. package/src/publish/json/profiles/MMFAD9A.json +103 -0
  92. package/src/publish/json/profiles/MOCI93.json +100 -0
  93. package/src/publish/json/profiles/OBQ4493.json +96 -0
  94. package/src/publish/json/profiles/PIES93.json +104 -0
  95. package/src/publish/json/profiles/PIES9A.json +104 -0
  96. package/src/publish/json/profiles/PMCIEF93.json +1 -0
  97. package/src/publish/json/profiles/PSWQ93.json +97 -0
  98. package/src/publish/json/profiles/RIASEC93.json +2511 -0
  99. package/src/publish/json/profiles/SAFE93.json +110 -0
  100. package/src/publish/json/profiles/SASQ93.json +92 -0
  101. package/src/publish/json/profiles/SCASP93.json +611 -0
  102. package/src/publish/json/profiles/SDCAQ93.json +96 -0
  103. package/src/publish/json/profiles/STAIY93.json +98 -0
  104. package/src/publish/json/profiles/WAQ93.json +100 -0
  105. package/src/publish/json/profiles/YBOCS93.json +1322 -0
  106. package/src/publish/json/profiles/empty.json +139 -0
  107. package/src/publish/new-version.hbs +11 -0
  108. package/src/publish/test.js +109 -0
  109. package/src/qrcode/qrCodeGenerator.js +14 -0
  110. package/src/qrcode/qrRender.js +229 -0
  111. package/src/samples/16PF93.js +158 -0
  112. package/src/samples/AEQ93.js +121 -0
  113. package/src/samples/AMS93.js +139 -0
  114. package/src/samples/AMS9A.js +9 -0
  115. package/src/samples/BAOMEIS93.js +146 -0
  116. package/src/samples/BEQI93.js +255 -0
  117. package/src/samples/CAATS93.js +218 -0
  118. package/src/samples/CADS93.js +161 -0
  119. package/src/samples/CARSP93.js +134 -0
  120. package/src/samples/CERQ93.js +195 -0
  121. package/src/samples/CRAAS93.js +141 -0
  122. package/src/samples/CSI93.js +315 -0
  123. package/src/samples/DSWLS93.js +112 -0
  124. package/src/samples/EMSS93.js +178 -0
  125. package/src/samples/FACES93.js +225 -0
  126. package/src/samples/FTEPT93.js +167 -0
  127. package/src/samples/GMIT93.js +142 -0
  128. package/src/samples/HPL93.js +132 -0
  129. package/src/samples/IBT93.js +99 -0
  130. package/src/samples/IUS93.js +204 -0
  131. package/src/samples/JCSI93.js +174 -0
  132. package/src/samples/JPFQ93.js +74 -0
  133. package/src/samples/KJGI93.js +136 -0
  134. package/src/samples/LMIQ93.js +188 -0
  135. package/src/samples/MMFAD93.js +135 -0
  136. package/src/samples/MMFAD9A.js +31 -0
  137. package/src/samples/MOCI93.js +128 -0
  138. package/src/samples/OBQ4493.js +132 -0
  139. package/src/samples/PIES93.js +228 -0
  140. package/src/samples/PIES9A.js +32 -0
  141. package/src/samples/PMCIEF93.js +64 -0
  142. package/src/samples/PSWQ93.js +126 -0
  143. package/src/samples/RIASEC93.js +144 -0
  144. package/src/samples/SAFE93.js +64 -0
  145. package/src/samples/SASQ93.js +130 -0
  146. package/src/samples/SCASP93.js +207 -0
  147. package/src/samples/SDCAQ93.js +174 -0
  148. package/src/samples/STAIY93.js +159 -0
  149. package/src/samples/WAQ93.js +208 -0
  150. package/src/samples/YBOCS93.js +583 -0
  151. package/src/samples/empty.js +53 -0
  152. package/views/gift.hbs +160 -0
  153. package/views/profiles/fonts.css +18 -0
  154. package/views/profiles/layout.hbs +27 -0
  155. package/views/profiles/samples/16PF93.hbs +54 -0
  156. package/views/profiles/samples/AEQ93.hbs +31 -0
  157. package/views/profiles/samples/AMS93.hbs +97 -0
  158. package/views/profiles/samples/AMS9A.hbs +1 -0
  159. package/views/profiles/samples/BAOMEIS93.hbs +48 -0
  160. package/views/profiles/samples/BEQI93.hbs +118 -0
  161. package/views/profiles/samples/CAATS93.hbs +251 -0
  162. package/views/profiles/samples/CADS93.hbs +104 -0
  163. package/views/profiles/samples/CARSP93.hbs +26 -0
  164. package/views/profiles/samples/CERQ93.hbs +115 -0
  165. package/views/profiles/samples/CRAAS93.hbs +88 -0
  166. package/views/profiles/samples/CSI93_1.hbs +110 -0
  167. package/views/profiles/samples/CSI93_2.hbs +76 -0
  168. package/views/profiles/samples/DSWLS93.hbs +26 -0
  169. package/views/profiles/samples/EMSS93.hbs +101 -0
  170. package/views/profiles/samples/FACES93_1.hbs +107 -0
  171. package/views/profiles/samples/FACES93_2.hbs +51 -0
  172. package/views/profiles/samples/FTEPT93.hbs +67 -0
  173. package/views/profiles/samples/GMIT93.hbs +45 -0
  174. package/views/profiles/samples/HPL93.hbs +36 -0
  175. package/views/profiles/samples/IBT93.hbs +67 -0
  176. package/views/profiles/samples/IUS93.hbs +123 -0
  177. package/views/profiles/samples/JCSI93.hbs +65 -0
  178. package/views/profiles/samples/JPFQ93.hbs +44 -0
  179. package/views/profiles/samples/KJGI93.hbs +57 -0
  180. package/views/profiles/samples/LMIQ93.hbs +82 -0
  181. package/views/profiles/samples/MMFAD93.hbs +35 -0
  182. package/views/profiles/samples/MMFAD9A.hbs +1 -0
  183. package/views/profiles/samples/MOCI93.hbs +60 -0
  184. package/views/profiles/samples/OBQ4493.hbs +61 -0
  185. package/views/profiles/samples/PIES93.hbs +67 -0
  186. package/views/profiles/samples/PIES9A.hbs +1 -0
  187. package/views/profiles/samples/PMCIEF93.hbs +8 -0
  188. package/views/profiles/samples/PSWQ93.hbs +32 -0
  189. package/views/profiles/samples/RIASEC93.hbs +38 -0
  190. package/views/profiles/samples/SAFE93.hbs +118 -0
  191. package/views/profiles/samples/SASQ93.hbs +45 -0
  192. package/views/profiles/samples/SCASP93.hbs +94 -0
  193. package/views/profiles/samples/SDCAQ93.hbs +68 -0
  194. package/views/profiles/samples/STAIY93.hbs +67 -0
  195. package/views/profiles/samples/WAQ93.hbs +74 -0
  196. package/views/profiles/samples/YBOCS93_1.hbs +96 -0
  197. package/views/profiles/samples/YBOCS93_2.hbs +115 -0
  198. package/views/profiles/samples/YBOCS93_3.hbs +93 -0
  199. package/views/profiles/samples/empty.hbs +10 -0
  200. package/views/profiles/sidebar.hbs +193 -0
@@ -0,0 +1,194 @@
1
+ const path = require("path");
2
+ const chokidar = require("chokidar");
3
+ const Executor = require("./Executor");
4
+ const { checkAndImport, checkAndLoad } = require("./utilities/BaseOps");
5
+ const { EXTRACT_STATUS } = require("./utilities/STATUSES");
6
+ const { FileNotFoundError } = require("./utilities/CustomErrors");
7
+
8
+ class ExtractExecutor extends Executor {
9
+ samplesJSDir = path.join(__dirname, "..", "samples");
10
+ profilesTemplatesDir = path.join(__dirname, "..", "..", "views", "profiles", "samples");
11
+
12
+ constructor(options) {
13
+ super(options);
14
+ this.sample = {
15
+ name: options.sampleName,
16
+ outputs: options.sampleOutputs,
17
+ };
18
+
19
+ this.dirs = {};
20
+
21
+ this._addJSPromise();
22
+ this._initSettings(options);
23
+
24
+ this._extract();
25
+
26
+ if (options.watch) this._watch();
27
+ }
28
+
29
+ _addJSPromise() {
30
+ const { sample, dirs, samplesJSDir, response, promises } = this;
31
+
32
+ const sampleJSDir = path.join(samplesJSDir, `${sample.name}.js`);
33
+
34
+ dirs["sampleJS"] = sampleJSDir;
35
+
36
+ promises["js"] = checkAndImport(sampleJSDir).catch((err) => {
37
+ if (err instanceof FileNotFoundError) response.setStatus(EXTRACT_STATUS["INVALID_SAMPLE_NAME"], err);
38
+ else response.setStatus(EXTRACT_STATUS["GENERAL_ERROR"], err);
39
+ });
40
+ }
41
+
42
+ _addProfilesTemplatePromises() {
43
+ const { sample, dirs, profilesTemplatesDir, promises, response } = this;
44
+
45
+ promises["templates"] = [];
46
+
47
+ dirs["templates"] = [];
48
+
49
+ promises["miscellaneous_1"] = promises["js"].then((Profile) => {
50
+ let n = Profile.pages;
51
+ for (let i = 0; i < n; i++) {
52
+ let templateFileDir = path.join(profilesTemplatesDir, `${sample.name}${n !== 1 ? "_" + (i + 1) : ""}.hbs`);
53
+ dirs["templates"].push(templateFileDir);
54
+ promises["templates"].push(
55
+ checkAndLoad(templateFileDir).catch((err) => response.setStatus(EXTRACT_STATUS["TEMPLATE_NOT_FOUND"], err))
56
+ );
57
+ }
58
+ return Promise.all(promises.templates);
59
+ });
60
+ }
61
+
62
+ _initSettings(options) {
63
+ const { sample } = this;
64
+
65
+ let settings = {};
66
+
67
+ if (sample.outputs.includes("profile")) {
68
+ let variants = {
69
+ both: ["raw", "with-sidebar"],
70
+ raw: ["raw"],
71
+ "with-sidebar": ["with-sidebar"],
72
+ }[options.profileVariant];
73
+
74
+ settings["profile"] = {
75
+ measure: options.measure,
76
+ variants,
77
+ name: options.name,
78
+ };
79
+
80
+ this._addProfilesTemplatePromises();
81
+ }
82
+
83
+ this.settings = settings;
84
+ }
85
+
86
+ _extract() {
87
+ const { sample, promises, response, benchmarker, settings } = this;
88
+
89
+ const extractPromises = [];
90
+
91
+ if (sample.outputs.includes("profile")) {
92
+ let { variants } = settings["profile"];
93
+
94
+ extractPromises.push(Promise.all(variants.map((variant) => this._createProfile(variant))));
95
+ }
96
+
97
+ if (sample.outputs.includes("report")) extractPromises.push(this._createReport(options));
98
+
99
+ if (sample.outputs.includes("sheet")) extractPromises.push(this._createSheet(options));
100
+
101
+ promises["extract"] = Promise.all(extractPromises).then(() => {
102
+ benchmarker?.end();
103
+ response.setTime(benchmarker?.totalTime);
104
+ response.setStatus(EXTRACT_STATUS["SUCCESS"]);
105
+ });
106
+ }
107
+
108
+ async _createProfile(variant, exts = ["svg", "png"]) {
109
+ const {
110
+ promises,
111
+ response,
112
+ settings: {
113
+ profile: { measure },
114
+ },
115
+ } = this;
116
+
117
+ const outputFileName = this._createProfileOutputName(variant);
118
+
119
+ return Promise.all([promises.input, promises.js])
120
+ .then(([dataset, Profile]) => new Profile(dataset, { variant, measure }).getTemplateEngineParams())
121
+ .catch((err) => response.setStatus(EXTRACT_STATUS["JS_ERROR"], err))
122
+ .then((contexts) => this._renderAndCreateOutputs(contexts, promises.templates, outputFileName, exts))
123
+ .then((pages) => pages.map((dirs) => dirs.map((dir) => response.addOutput(dir, "profiles"))));
124
+ }
125
+
126
+ _watch() {
127
+ const { command, dirs, input, response, benchmarker, promises } = this;
128
+
129
+ const opts = {
130
+ awaitWriteFinish: {
131
+ stabilityThreshold: 500,
132
+ pollInterval: 100,
133
+ },
134
+ };
135
+
136
+ promises["js"].then(() => {
137
+ dirs.templates.map((templateFileDir, index) => {
138
+ chokidar.watch(templateFileDir, opts).on("change", () => {
139
+ promises["templates"][index] = checkAndLoad(templateFileDir);
140
+ benchmarker?.restart(command);
141
+ this._createProfile("with-sidebar", ["svg"]).then(() => {
142
+ benchmarker?.end();
143
+ response.setTime(benchmarker?.totalTime);
144
+ response.showOutput();
145
+ });
146
+ });
147
+ });
148
+ });
149
+
150
+ chokidar.watch(dirs.sampleJS, opts).on("change", () => {
151
+ promises["js"] = checkAndImport(dirs.sampleJS);
152
+ benchmarker?.restart(command);
153
+ this._createProfile("with-sidebar", ["svg"]).then(() => {
154
+ benchmarker?.end();
155
+ response.setTime(benchmarker?.totalTime);
156
+ response.showOutput();
157
+ });
158
+ });
159
+
160
+ if(input.type === 'local') chokidar.watch(input.data, opts).on('change', () => {
161
+ promises["input"] = checkAndLoad(input.data).then((json) => Promise.resolve(JSON.parse(json)));
162
+ benchmarker?.restart(command);
163
+ this._createProfile("with-sidebar", ["svg"]).then(() => {
164
+ benchmarker?.end();
165
+ response.setTime(benchmarker?.totalTime);
166
+ response.showOutput();
167
+ });
168
+
169
+ })
170
+ }
171
+
172
+ _createProfileOutputName(variant) {
173
+ const {
174
+ settings: {
175
+ profile: { measure, name },
176
+ },
177
+ input,
178
+ } = this;
179
+
180
+ let variantSuffix = {
181
+ raw: ".raw",
182
+ "with-sidebar": "",
183
+ }[variant];
184
+ let measureSuffix = measure ? "-m" : "";
185
+
186
+ const fileName = input.type === "local" ? path.parse(input.data).name : "";
187
+
188
+ if (!(name || fileName)) throw new Error("No Name Provided for Profile Output Files!");
189
+
190
+ return `${name || fileName}${variantSuffix}${measureSuffix}`;
191
+ }
192
+ }
193
+
194
+ module.exports = ExtractExecutor;
@@ -0,0 +1,56 @@
1
+ const fs = require("fs/promises");
2
+ const path = require("path");
3
+ const Executor = require("./Executor");
4
+ const { GIFT_STATUS } = require("./utilities/STATUSES");
5
+ const Gift = require("../Gift");
6
+ const { loadStdin } = require("./utilities/BaseOps");
7
+
8
+ class GiftExecutor extends Executor {
9
+ giftTemplateFile = path.join(__dirname, "..", "..", "views", "gift.hbs");
10
+
11
+ constructor(options) {
12
+ super(options);
13
+
14
+ this._addTemplatePromise();
15
+ this._addAvatarPromise();
16
+
17
+ this._gift();
18
+ }
19
+
20
+ _addTemplatePromise() {
21
+ const { promises, giftTemplateFile } = this;
22
+
23
+ promises["template"] = fs.readFile(giftTemplateFile);
24
+ }
25
+
26
+ _addAvatarPromise() {
27
+ const { promises } = this;
28
+
29
+ promises["avatar"] = loadStdin("binary");
30
+ }
31
+
32
+ _gift() {
33
+ const { promises, response, benchmarker } = this;
34
+
35
+ response.addBranch("gifts");
36
+
37
+ promises["gift"] = this._createGift().then(() => {
38
+ if (benchmarker) {
39
+ benchmarker.end();
40
+ response.setTime(benchmarker.totalTime);
41
+ }
42
+ response.setStatus(GIFT_STATUS["SUCCESS"]);
43
+ });
44
+ }
45
+
46
+ async _createGift() {
47
+ const { promises, response } = this;
48
+
49
+ return Promise.all([promises.input, promises.avatar])
50
+ .then(([dataset, avatar]) => new Gift(dataset, avatar))
51
+ .then((ctx) => this._renderAndCreateOutput(ctx, promises.template, ctx.name, ["png"]))
52
+ .then((dirs) => dirs.map((dir) => response.addOutput(dir, "gifts")));
53
+ }
54
+ }
55
+
56
+ module.exports = GiftExecutor;
@@ -0,0 +1,71 @@
1
+ const { FileNotFoundError } = require("./CustomErrors");
2
+ const fs = require("fs/promises");
3
+ const { writeFile, constants } = require("fs");
4
+ const sharp = require("sharp");
5
+
6
+ const checkAndLoad = async (dir) =>
7
+ fs
8
+ .access(dir, constants.F_OK)
9
+ .catch(() => {
10
+ throw new FileNotFoundError(dir);
11
+ })
12
+ .then(() => fs.readFile(dir));
13
+
14
+ function requireUncached(dir) {
15
+ delete require.cache[require.resolve(dir)];
16
+ return require(dir);
17
+ }
18
+
19
+ const checkAndImport = async (dir) =>
20
+ fs
21
+ .access(dir, constants.F_OK)
22
+ .catch(() => {
23
+ throw new FileNotFoundError(dir);
24
+ })
25
+ .then(() => requireUncached(dir));
26
+
27
+ const loadStdin = async (encoding) => {
28
+ process.stdin.setEncoding(encoding);
29
+
30
+ let data = "";
31
+
32
+ if (!process.stdin.isTTY) process.stdin.on("data", (chunk) => (data += chunk));
33
+
34
+ return new Promise(function (resolve, reject) {
35
+ if (!process.stdin.readableFlowing) resolve(data);
36
+ process.stdin.on("end", () => resolve(data));
37
+ process.stdin.on("error", (err) => reject(err));
38
+ });
39
+ };
40
+
41
+ const ensureDirExistence = async (dir) =>
42
+ fs.access(dir, constants.F_OK).catch(() => fs.mkdir(dir, { recursive: true }));
43
+
44
+ async function createSVG(xml, dir) {
45
+ return new Promise((resolve, reject) => {
46
+ writeFile(dir, xml, (err) => {
47
+ if (err) reject(err);
48
+ resolve(dir);
49
+ });
50
+ });
51
+ }
52
+
53
+ async function createPNG(xml, dir) {
54
+ xml = xml.replace(/<style.*?>.*?<\/style>/s, "");
55
+ const buf = Buffer.from(xml, "utf8");
56
+ return new Promise((resolve, reject) => {
57
+ sharp(buf, { density: 100 }).toFile(dir, (err) => {
58
+ if (err) return reject(err);
59
+ resolve(dir);
60
+ });
61
+ });
62
+ }
63
+
64
+ module.exports = {
65
+ checkAndLoad,
66
+ checkAndImport,
67
+ loadStdin,
68
+ ensureDirExistence,
69
+ createSVG,
70
+ createPNG,
71
+ };
@@ -0,0 +1,88 @@
1
+ const chalk = require("chalk");
2
+
3
+ class Benchmarker {
4
+ constructor() {
5
+ this.depth = 0;
6
+ this.branches = [];
7
+ // this.branches = [{ name, timeSteps: [], currentStep: 0 }];
8
+ }
9
+
10
+ start(name) {
11
+ const newBranch = {
12
+ name,
13
+ timeSteps: [],
14
+ currentStep: 0,
15
+ depth: this.depth++,
16
+ };
17
+ newBranch.timeSteps.push(Date.now());
18
+ this.branches.push(newBranch);
19
+
20
+ // console.log(
21
+ // chalk`${"".padStart(newBranch.depth * 2)}{magenta.bold ${
22
+ // newBranch.name
23
+ // }}${newBranch.depth ? "" : " Benchmarking"} Started!`
24
+ // );
25
+ }
26
+
27
+ addStep(stepName) {
28
+ const { branches, depth } = this;
29
+
30
+ let lastBranch = branches[depth - 1];
31
+ lastBranch.timeSteps.push(Date.now());
32
+ lastBranch.currentStep++;
33
+
34
+ const time =
35
+ (lastBranch.timeSteps[lastBranch.currentStep] - lastBranch.timeSteps[lastBranch.currentStep - 1]) / 1000;
36
+ const timeColor = this._timeColor(time);
37
+
38
+ // console.log(
39
+ // chalk`${"".padStart(lastBranch.depth * 2 + 2)}{italic Step #${
40
+ // lastBranch.currentStep
41
+ // }:} {blue.bold ${stepName}}: {${timeColor}.bold ${time}} Seconds.`.padStart(
42
+ // lastBranch.depth * 2,
43
+ // " "
44
+ // )
45
+ // );
46
+ }
47
+
48
+ end() {
49
+ const { branches } = this;
50
+
51
+ this.depth--;
52
+
53
+ let lastBranch = branches.pop();
54
+ const totalTime = (Date.now() - lastBranch.timeSteps[0]) / 1000;
55
+ const timeColor = this._timeColor(totalTime);
56
+
57
+ this.totalTime = totalTime;
58
+
59
+ // console.log(
60
+ // chalk`${"".padStart(lastBranch.depth * 2)}{magenta.bold ${
61
+ // lastBranch.name
62
+ // }}${
63
+ // lastBranch.depth ? "" : " Benchmarking"
64
+ // } Completed. Total Time: {${timeColor}.bgGrey.bold ${totalTime} } Seconds`
65
+ // );
66
+ }
67
+
68
+ restart(name) {
69
+ this.depth = 0;
70
+ this.branches = [];
71
+ this.start(name)
72
+ }
73
+
74
+ _timeColor(time) {
75
+ // time <= 0.4s ==> Good
76
+ // 0.4s < time <= 1s ==> Medium
77
+ // 1s < time ==> Bad
78
+
79
+ const interpret = time <= 0.4 ? "Good" : time <= 1 ? "Medium" : "Bad";
80
+ return {
81
+ Good: "green",
82
+ Medium: "yellow",
83
+ Bad: "red",
84
+ }[interpret];
85
+ }
86
+ }
87
+
88
+ module.exports = Benchmarker;
@@ -0,0 +1,14 @@
1
+ class MyError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = this.constructor.name;
5
+ }
6
+ }
7
+
8
+ class FileNotFoundError extends MyError {
9
+ constructor(dir) {
10
+ super(`File Not Found in ${dir}`);
11
+ }
12
+ }
13
+
14
+ module.exports = { MyError, FileNotFoundError };
@@ -0,0 +1,59 @@
1
+ const path = require("path");
2
+
3
+ class Response {
4
+ constructor() {
5
+ this.files = {};
6
+ }
7
+
8
+ addBranch(name) {
9
+ this.files[name] = {};
10
+ }
11
+
12
+ addOutput(dir, branch) {
13
+ const base = path.parse(dir).base.split(".").slice(1);
14
+ let ext = base.pop();
15
+ let name = base.join(".") || "_";
16
+
17
+ if (!this.files[branch]) this.addBranch(branch)
18
+
19
+ this.files[branch][name] = [...(this.files[branch][name] || []), ext];
20
+ }
21
+
22
+ setStatus({ code, label, message }, err = null) {
23
+ if (!this.status) {
24
+ this.status = {
25
+ code,
26
+ label,
27
+ message,
28
+ };
29
+ }
30
+ process.exitCode = code;
31
+
32
+ if (err) throw err;
33
+ }
34
+
35
+ setTime(time) {
36
+ if (!this.time) this.time = time;
37
+ }
38
+
39
+ showOutput() {
40
+ const { files, status, time } = this;
41
+ const output = {
42
+ ...files,
43
+ message_code: status && status.code,
44
+ message: status && `(${status.label}) ${status.message}`,
45
+ time,
46
+ };
47
+
48
+ console.log(JSON.stringify(output));
49
+ this._clear();
50
+ }
51
+
52
+ _clear() {
53
+ this.files = {};
54
+ this.status = null;
55
+ this.time = null;
56
+ }
57
+ }
58
+
59
+ module.exports = Response;
@@ -0,0 +1,16 @@
1
+ const Status = require("./Status");
2
+
3
+ const EXTRACT_STATUS = {
4
+ SUCCESS: new Status(0, "Success", "Outputs Successfully Extracted!"),
5
+ "INPUT_NOT_FOUND": new Status(1, "Not Found", "Input Data File Does Not Exist!"),
6
+ "JS_ERROR": new Status(2, "Profile JS Error", "Error in Instantiating the Profile Object"),
7
+ "INVALID_SAMPLE_NAME": new Status(3, "Invalid Name", "Sample Name Is Not Valid"),
8
+ "TEMPLATE_NOT_FOUND": new Status(4, "Not Found", "Profile Template File Does Not Exist"),
9
+ "GENERAL_ERROR": new Status(5, "General Error", "Something Went Wrong!"),
10
+ };
11
+
12
+ const GIFT_STATUS = {
13
+ SUCCESS: new Status(0, "Success", "Gift Successfully Created!"),
14
+ };
15
+
16
+ module.exports = { EXTRACT_STATUS, GIFT_STATUS };
@@ -0,0 +1,9 @@
1
+ class Status {
2
+ constructor(code, label, message) {
3
+ this.code = code;
4
+ this.label = label;
5
+ this.message = message;
6
+ }
7
+ }
8
+
9
+ module.exports = Status;
package/src/cli.js ADDED
@@ -0,0 +1,125 @@
1
+ const { Argument, Command, Option } = require("commander");
2
+
3
+ const program = new Command();
4
+
5
+ function parseArgumentsIntoOptions(rawArgs) {
6
+ let output = {};
7
+
8
+ program
9
+ .command("extract")
10
+ .alias("E")
11
+ .argument("<sampleName>", "sample name")
12
+ .addArgument(
13
+ new Argument("[sampleOutputs...]", "sample outputs").choices(["profile", "report", "sheet"]).default(["profile"])
14
+ )
15
+ .description("Extract outputs of a sample")
16
+ .addOption(
17
+ new Option("-p, --profile-variant <variant>", "profile variant")
18
+ .choices(["both", "raw", "with-sidebar"])
19
+ .default("both")
20
+ .makeOptionMandatory()
21
+ )
22
+ .addOption(
23
+ new Option("-i, --input-type <type>", "input type")
24
+ .choices(["local", "remote", "raw-json", "stdin"])
25
+ .default("local")
26
+ .makeOptionMandatory()
27
+ )
28
+
29
+ .addOption(new Option("-d, --input-data <data>", "input data"))
30
+
31
+ .addOption(
32
+ new Option("-o, --output-type <type>", "output type")
33
+ .choices(["local", "remote"])
34
+ .default("local")
35
+ .makeOptionMandatory()
36
+ )
37
+
38
+ .addOption(new Option("-a, --output-address <address>", "output address").makeOptionMandatory())
39
+
40
+ .addOption(new Option("-m, --measure", "measure feature in SVG").default(false))
41
+
42
+ .addOption(new Option("-n, --name <name>", "name of output profile"))
43
+
44
+ .addOption(new Option("-b, --benchmark", "time benchmarking").default(false))
45
+
46
+ .addOption(new Option("-w, --watch", "watch files").default(false))
47
+
48
+ .action((sampleName, sampleOutputs, options, command) => {
49
+ output = {
50
+ command: command.name(),
51
+ sampleName,
52
+ sampleOutputs,
53
+ ...options,
54
+ };
55
+ });
56
+
57
+ program
58
+ .command("test")
59
+ .alias("T")
60
+ .description("Test Commands of CLI")
61
+ .addOption(
62
+ new Option("-c, --command-test <name>", "command name to be tested").choices(["extract"]).makeOptionMandatory()
63
+ )
64
+ .action((options, command) => {
65
+ output = {
66
+ command: command.name(),
67
+ ...options,
68
+ };
69
+ });
70
+
71
+ program
72
+ .command("gift")
73
+ .alias("G")
74
+ .description("Create Gift Card")
75
+ .addOption(
76
+ new Option("-i, --input-type <type>", "input type")
77
+ .choices(["raw-json", "local"])
78
+ .default("raw-json")
79
+ .makeOptionMandatory()
80
+ )
81
+ .addOption(new Option("-d, --input-data <data>", "input data"))
82
+ .addOption(
83
+ new Option("-o, --output-type <type>", "output type")
84
+ .choices(["local", "remote"])
85
+ .default("local")
86
+ .makeOptionMandatory()
87
+ )
88
+ .addOption(new Option("-a, --output-address <address>", "output address").makeOptionMandatory())
89
+ .addOption(new Option("-b, --benchmark", "time benchmarking").default(false))
90
+ .action((options, command) => {
91
+ output = {
92
+ command: command.name(),
93
+ ...options,
94
+ };
95
+ });
96
+
97
+ program.showHelpAfterError();
98
+
99
+ program.showSuggestionAfterError();
100
+
101
+ program.parse(rawArgs);
102
+
103
+ return output;
104
+ }
105
+
106
+ async function cli(args) {
107
+ let options = parseArgumentsIntoOptions(args);
108
+
109
+ switch (options.command) {
110
+ case "extract":
111
+ const ExtractExecutor = require("./cli-commands/ExtractExecutor");
112
+ return new ExtractExecutor(options).getFinalPromise();
113
+ case "gift":
114
+ const GiftExecutor = require("./cli-commands/GiftExecutor");
115
+ return new GiftExecutor(options).getFinalPromise();
116
+ case "test":
117
+ const test = require("./cli-commands/test");
118
+ test(options)
119
+ .then(() => console.log("0 (Success): Draw Command Tested Completely!"))
120
+ .catch((err) => console.error(err));
121
+ break;
122
+ }
123
+ }
124
+
125
+ module.exports = { cli };
@@ -0,0 +1,8 @@
1
+ // abs Helper
2
+ // Get Absolute Value of a Number
3
+
4
+ function abs(num) {
5
+ return Math.abs(num);
6
+ }
7
+
8
+ module.exports = abs;
@@ -0,0 +1,8 @@
1
+ // addCommas Helper
2
+ // Add Commas to Numbers
3
+
4
+ function addCommas(num) {
5
+ return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
6
+ };
7
+
8
+ module.exports = addCommas;
@@ -0,0 +1,8 @@
1
+ // array Helper
2
+ // This helper is used to defined array literals in handlebars
3
+
4
+ function array() {
5
+ return Array.from(arguments).slice(0, arguments.length - 1);
6
+ }
7
+
8
+ module.exports = array;
@@ -0,0 +1,9 @@
1
+ // assignGlobal Helper
2
+ // Globally assign a variable that can be accessed via root in handlebars
3
+
4
+ function assignGlobal(name, val, options) {
5
+ if (!options.data.root) options.data.root = {};
6
+ options.data.root[name] = val;
7
+ }
8
+
9
+ module.exports = assignGlobal;
@@ -0,0 +1,19 @@
1
+ // boolean Helper
2
+ // Evaluates Comparison and Logical Operations
3
+
4
+ function boolean(v1, operator, v2, options) {
5
+ return {
6
+ "==": v1 == v2,
7
+ "===": v1 === v2,
8
+ "!=": v1 != v2,
9
+ "!==": v1 !== v2,
10
+ "<": v1 < v2,
11
+ "<=": v1 <= v2,
12
+ ">": v1 > v2,
13
+ ">=": v1 >= v2,
14
+ "&&": v1 && v2,
15
+ "||": v1 || v2,
16
+ }[operator]
17
+ }
18
+
19
+ module.exports = boolean;