mythix 3.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +27 -30
  3. package/{src → lib}/application.d.ts +25 -39
  4. package/{src/application.js → lib/application.mjs} +110 -135
  5. package/lib/cli/cli-utils.d.ts +21 -0
  6. package/lib/cli/cli-utils.mjs +319 -0
  7. package/lib/cli/command-base.d.ts +33 -0
  8. package/lib/cli/command-base.mjs +118 -0
  9. package/lib/cli/command-executor.mjs +14 -0
  10. package/lib/cli/commands/deploy-command.mjs +1010 -0
  11. package/lib/cli/commands/generators/generate-command.mjs +117 -0
  12. package/lib/cli/commands/generators/index.mjs +2 -0
  13. package/{src/cli/generators/migration-generator.js → lib/cli/commands/generators/migration-generator.mjs} +11 -13
  14. package/lib/cli/commands/index.mjs +22 -0
  15. package/lib/cli/commands/migrate-command.mjs +184 -0
  16. package/lib/cli/commands/routes-command.mjs +40 -0
  17. package/lib/cli/commands/serve-command.mjs +63 -0
  18. package/lib/cli/commands/shell-command.mjs +95 -0
  19. package/lib/cli/index.mjs +3 -0
  20. package/{src → lib}/controllers/controller-base.d.ts +1 -1
  21. package/{src/controllers/controller-base.js → lib/controllers/controller-base.mjs} +3 -9
  22. package/{src → lib}/controllers/controller-module.d.ts +3 -3
  23. package/lib/controllers/controller-module.mjs +70 -0
  24. package/lib/controllers/generate-client-api-interface-spec.mjs +44 -0
  25. package/{src → lib}/controllers/generate-client-api-interface.d.ts +1 -0
  26. package/{src/controllers/generate-client-api-interface.js → lib/controllers/generate-client-api-interface.mjs} +39 -16
  27. package/{src → lib}/controllers/index.d.ts +2 -3
  28. package/lib/controllers/index.mjs +4 -0
  29. package/lib/controllers/routes/index.mjs +4 -0
  30. package/{src/controllers/routes/route-capture.js → lib/controllers/routes/route-capture.mjs} +2 -8
  31. package/{src/controllers/routes/route-endpoint.js → lib/controllers/routes/route-endpoint.mjs} +8 -8
  32. package/{src/controllers/routes/route-scope-base.js → lib/controllers/routes/route-scope-base.mjs} +19 -15
  33. package/{src/controllers/routes/route-scope.js → lib/controllers/routes/route-scope.mjs} +10 -12
  34. package/{src/http-server/http-errors.js → lib/http/http-errors.mjs} +9 -20
  35. package/{src/utils/http-interface.js → lib/http/http-interface.mjs} +6 -14
  36. package/{src/http-server → lib/http}/http-server-module.d.ts +2 -2
  37. package/{src/http-server/http-server-module.js → lib/http/http-server-module.mjs} +7 -11
  38. package/{src/http-server/http-server.js → lib/http/http-server.mjs} +17 -21
  39. package/lib/http/index.d.ts +4 -0
  40. package/lib/http/index.mjs +5 -0
  41. package/lib/index.d.ts +30 -0
  42. package/lib/index.mjs +31 -0
  43. package/lib/logger-spec.mjs +121 -0
  44. package/{src → lib}/logger.d.ts +1 -3
  45. package/{src/logger.js → lib/logger.mjs} +10 -24
  46. package/lib/models/index.d.ts +2 -0
  47. package/lib/models/index.mjs +2 -0
  48. package/{src/models/migration-model.js → lib/models/migration-model.mjs} +3 -11
  49. package/lib/models/model.d.ts +10 -0
  50. package/lib/models/model.mjs +28 -0
  51. package/{src → lib}/modules/database-module.d.ts +2 -2
  52. package/{src/modules/database-module.js → lib/modules/database-module.mjs} +19 -14
  53. package/lib/modules/index.d.ts +2 -0
  54. package/lib/modules/index.mjs +2 -0
  55. package/{src/modules/base-module.d.ts → lib/modules/module-base.d.ts} +3 -10
  56. package/{src/modules/base-module.js → lib/modules/module-base.mjs} +16 -6
  57. package/lib/tasks/index.d.ts +2 -0
  58. package/lib/tasks/index.mjs +2 -0
  59. package/{src → lib}/tasks/task-base.d.ts +4 -14
  60. package/lib/tasks/task-base.mjs +73 -0
  61. package/{src → lib}/tasks/task-module.d.ts +3 -3
  62. package/{src/tasks/task-module.js → lib/tasks/task-module.mjs} +43 -98
  63. package/{src/utils/config-utils.js → lib/utils/config-utils.mjs} +2 -10
  64. package/lib/utils/crypto-utils-spec.mjs +24 -0
  65. package/{src/utils/crypto-utils.js → lib/utils/crypto-utils.mjs} +16 -38
  66. package/lib/utils/file-utils-spec.mjs +10 -0
  67. package/{src/utils/file-utils.js → lib/utils/file-utils.mjs} +4 -11
  68. package/{src/utils/http-utils.js → lib/utils/http-utils.mjs} +3 -10
  69. package/{src → lib}/utils/index.d.ts +1 -1
  70. package/lib/utils/index.mjs +6 -0
  71. package/lib/utils/mime-utils-spec.mjs +171 -0
  72. package/{src/utils/mime-utils.js → lib/utils/mime-utils.mjs} +5 -14
  73. package/{src/utils/test-utils.js → lib/utils/test-utils.mjs} +14 -42
  74. package/package.json +5 -5
  75. package/src/cli/cli-utils.d.ts +0 -80
  76. package/src/cli/cli-utils.js +0 -547
  77. package/src/cli/command-executor.js +0 -31
  78. package/src/cli/deploy-command.js +0 -1010
  79. package/src/cli/generators/generate-command.js +0 -149
  80. package/src/cli/index.js +0 -5
  81. package/src/cli/migrate-command.js +0 -181
  82. package/src/cli/routes-command.js +0 -40
  83. package/src/cli/serve-command.js +0 -63
  84. package/src/cli/shell-command.js +0 -96
  85. package/src/controllers/controller-module.js +0 -126
  86. package/src/controllers/controller-utils.d.ts +0 -19
  87. package/src/controllers/controller-utils.js +0 -24
  88. package/src/controllers/index.js +0 -19
  89. package/src/controllers/routes/index.js +0 -31
  90. package/src/http-server/index.d.ts +0 -3
  91. package/src/http-server/index.js +0 -16
  92. package/src/index.d.ts +0 -49
  93. package/src/index.js +0 -47
  94. package/src/models/index.d.ts +0 -4
  95. package/src/models/index.js +0 -17
  96. package/src/models/model-module.d.ts +0 -9
  97. package/src/models/model-module.js +0 -130
  98. package/src/models/model-utils.d.ts +0 -20
  99. package/src/models/model-utils.js +0 -46
  100. package/src/models/model.d.ts +0 -20
  101. package/src/models/model.js +0 -65
  102. package/src/modules/file-watcher-module.d.ts +0 -13
  103. package/src/modules/file-watcher-module.js +0 -220
  104. package/src/modules/index.d.ts +0 -3
  105. package/src/modules/index.js +0 -11
  106. package/src/tasks/index.d.ts +0 -3
  107. package/src/tasks/index.js +0 -11
  108. package/src/tasks/task-base.js +0 -117
  109. package/src/tasks/task-utils.d.ts +0 -46
  110. package/src/tasks/task-utils.js +0 -130
  111. package/src/utils/index.js +0 -25
  112. /package/{src → lib}/cli/index.d.ts +0 -0
  113. /package/{src → lib}/controllers/routes/index.d.ts +0 -0
  114. /package/{src → lib}/controllers/routes/route-capture.d.ts +0 -0
  115. /package/{src → lib}/controllers/routes/route-endpoint.d.ts +0 -0
  116. /package/{src → lib}/controllers/routes/route-scope-base.d.ts +0 -0
  117. /package/{src → lib}/controllers/routes/route-scope.d.ts +0 -0
  118. /package/{src/http-server → lib/http}/http-errors.d.ts +0 -0
  119. /package/{src/utils → lib/http}/http-interface.d.ts +0 -0
  120. /package/{src/http-server → lib/http}/http-server.d.ts +0 -0
  121. /package/{src → lib}/interfaces/common.ts +0 -0
  122. /package/{src → lib}/models/migration-model.d.ts +0 -0
  123. /package/{src → lib}/utils/config-utils.d.ts +0 -0
  124. /package/{src → lib}/utils/crypto-utils.d.ts +0 -0
  125. /package/{src → lib}/utils/file-utils.d.ts +0 -0
  126. /package/{src → lib}/utils/http-utils.d.ts +0 -0
  127. /package/{src → lib}/utils/mime-utils.d.ts +0 -0
  128. /package/{src → lib}/utils/test-utils.d.ts +0 -0
@@ -1,29 +1,19 @@
1
- 'use strict';
2
-
3
- const { DateTime } = require('luxon');
4
- const Nife = require('nife');
5
- const { BaseModule } = require('../modules/base-module');
6
- const {
7
- fileNameWithoutExtension,
8
- walkDir,
9
- } = require('../utils');
1
+ import { DateTime } from 'luxon';
2
+ import Nife from 'nife';
3
+ import { ModuleBase } from '../modules/module-base.mjs';
10
4
 
11
5
  const MILLISECONDS_PER_SECOND = 1000;
12
- const TASK_MAX_FAIL_ATTEMPTS = 5;
13
-
14
- var globalTaskRunID = 1;
6
+ const TASK_MAX_FAIL_ATTEMPTS = 5;
15
7
 
16
8
  function nowInSeconds() {
17
9
  return Date.now() / MILLISECONDS_PER_SECOND;
18
10
  }
19
11
 
20
- class TaskModule extends BaseModule {
21
- static getModuleName() {
22
- return 'TaskModule';
12
+ export class TaskModule extends ModuleBase {
13
+ static getOptionsScopeName() {
14
+ return 'tasks';
23
15
  }
24
16
 
25
- static fileWatcherQueueName = 'tasks';
26
-
27
17
  static shouldUse(application, options) {
28
18
  if (options.runTasks === false)
29
19
  return false;
@@ -50,66 +40,11 @@ class TaskModule extends BaseModule {
50
40
  });
51
41
  }
52
42
 
53
- fileWatcherGetMonitorPaths(options) {
54
- return [ options.tasksPath ];
55
- }
56
-
57
- async fileWatcherHandler(options) {
58
- await this.waitForAllTasksToFinish();
59
-
60
- let tasks = await this.loadTasks(options.tasksPath);
61
-
62
- this.tasks = tasks;
63
- this.taskInfo = { _startTime: nowInSeconds() };
64
-
65
- this.startTasks();
66
- }
67
-
68
- getTaskFilePaths(tasksPath) {
69
- return walkDir(tasksPath, {
70
- filter: (fullFileName, fileName, stats) => {
71
- if (fileName.match(/^_/))
72
- return false;
73
-
74
- if (stats.isFile() && !fileNameWithoutExtension(fileName).match(/-task$/))
75
- return false;
76
-
77
- return true;
78
- },
79
- });
80
- }
81
-
82
- loadTasks(tasksPath) {
83
- let application = this.getApplication();
84
- let taskFiles = this.getTaskFilePaths(tasksPath);
85
- let connection = (typeof application.getConnection === 'function') ? application.getConnection() : null;
86
- let dbConfig = (typeof application.getDBConfig === 'function') ? application.getDBConfig() : null;
87
- let tasks = {};
88
- let args = { application, connection, dbConfig };
89
-
90
- for (let i = 0, il = taskFiles.length; i < il; i++) {
91
- let taskFile = taskFiles[i];
92
-
93
- try {
94
- let taskGenerator = require(taskFile);
95
- if (taskGenerator.__esModule)
96
- taskGenerator = taskGenerator['default'];
97
-
98
- Object.assign(tasks, taskGenerator(args));
99
- } catch (error) {
100
- this.getLogger().error(`Error while loading task ${taskFile}: `, error);
101
- throw error;
102
- }
103
- }
104
-
105
- return tasks;
106
- }
107
-
108
43
  async runTasks() {
109
44
  const executeTask = (TaskKlass, taskIndex, taskInfo, lastTime, currentTime, diff) => {
110
45
  const createTaskLogger = () => {
111
- let logger = this.getLogger();
112
- return logger.clone({ formatter: (output) => `[[ Running task ${taskName}[${taskIndex}](${runID}) @ ${currentTime} ]]: ${output}`});
46
+ let appLogger = this.getLogger();
47
+ return appLogger.clone({ formatter: (output) => `[[ Running task ${taskName}[${taskIndex}] @ ${currentTime} ]]: ${output}`});
113
48
  };
114
49
 
115
50
  const successResult = (value) => {
@@ -134,7 +69,7 @@ class TaskModule extends BaseModule {
134
69
  } catch (error) {
135
70
  errorResult(error);
136
71
  } finally {
137
- taskInfo.nextRunAt = TaskKlass.nextRun(taskIndex, lastTime, currentTime, diff);
72
+ taskInfo.nextRunAt = TaskKlass.nextRun(taskInstance, lastTime, currentTime, diff);
138
73
  }
139
74
  };
140
75
 
@@ -151,25 +86,12 @@ class TaskModule extends BaseModule {
151
86
  let taskName = TaskKlass.taskName;
152
87
  let promise = Nife.createResolvable();
153
88
  let taskInstance = taskInfo.taskInstance;
154
- let runID;
155
89
  let logger;
156
90
 
157
- if (!TaskKlass.keepAlive || !taskInstance) {
158
- globalTaskRunID++;
159
-
160
- // eslint-disable-next-line no-magic-numbers
161
- runID = `${Math.floor(Date.now() + (Math.random() * 1000000)) + globalTaskRunID}-${taskIndex}`;
162
- }
163
-
164
- taskInfo.runID = runID;
165
-
166
- // No op, since promises are handled differently here
167
- promise.then(() => {}, () => {});
168
-
169
91
  try {
170
- if (!TaskKlass.keepAlive || !taskInstance) {
92
+ if (TaskKlass.KEEP_ALIVE === false || !taskInstance) {
171
93
  logger = createTaskLogger();
172
- taskInstance = new TaskKlass(this.getApplication(), logger, runID, { lastTime, currentTime, diff });
94
+ taskInstance = new TaskKlass(this.getApplication(), logger, taskInfo.index);
173
95
 
174
96
  taskInfo.taskInstance = taskInstance;
175
97
 
@@ -220,8 +142,15 @@ class TaskModule extends BaseModule {
220
142
 
221
143
  for (let taskIndex = 0; taskIndex < workers; taskIndex++) {
222
144
  let taskInfo = infoForTasks[taskIndex];
223
- if (!taskInfo)
224
- taskInfo = infoForTasks[taskIndex] = { failedCount: 0, promise: null, stop: false, nextRunAt: taskKlass.nextRun(taskIndex, undefined, DateTime.now()) };
145
+ if (!taskInfo) {
146
+ taskInfo = infoForTasks[taskIndex] = {
147
+ index: taskIndex,
148
+ failedCount: 0,
149
+ promise: null,
150
+ stop: false,
151
+ nextRunAt: taskKlass.nextRun(null, undefined, DateTime.now()),
152
+ };
153
+ }
225
154
 
226
155
  if (taskInfo.stop)
227
156
  continue;
@@ -276,7 +205,6 @@ class TaskModule extends BaseModule {
276
205
  this.taskInfo = { _startTime: nowInSeconds() };
277
206
  else
278
207
  this.taskInfo._startTime = nowInSeconds();
279
-
280
208
  }
281
209
 
282
210
  async stopAllTasks() {
@@ -354,11 +282,30 @@ class TaskModule extends BaseModule {
354
282
  }
355
283
 
356
284
  async start(options) {
357
- if (options.runTasks === false)
285
+ if (options.tasks === false)
358
286
  return;
359
287
 
360
- let tasks = await this.loadTasks(options.tasksPath);
361
- this.tasks = tasks;
288
+ const mapTaskClassesToObject = () => {
289
+ return Nife.iterate(options.tasks, ({ index, key, value, context }) => {
290
+ let taskName = key;
291
+ let TaskClass = value;
292
+
293
+ // If this is an array, then the
294
+ // index will match the task
295
+ // name. In that case, pull the name
296
+ // from the task class directly.
297
+ if (index === taskName) {
298
+ if (typeof TaskClass.getTaskName === 'function')
299
+ taskName = TaskClass.getTaskName();
300
+ else
301
+ taskName = TaskClass.name;
302
+ }
303
+
304
+ context[taskName] = TaskClass;
305
+ }, {});
306
+ };
307
+
308
+ this.tasks = mapTaskClassesToObject();
362
309
 
363
310
  this.startTasks();
364
311
  }
@@ -366,5 +313,3 @@ class TaskModule extends BaseModule {
366
313
  async stop() {
367
314
  }
368
315
  }
369
-
370
- module.exports = { TaskModule };
@@ -1,8 +1,4 @@
1
- 'use strict';
2
-
3
- /* global process */
4
-
5
- const Nife = require('nife');
1
+ import Nife from 'nife';
6
2
 
7
3
  function getConfigKey(CONFIG, key) {
8
4
  return key.replace(/\{([^}]+)\}/g, (m, name) => {
@@ -27,13 +23,9 @@ function ENV(_key, defaultValue) {
27
23
  return (value === undefined) ? defaultValue : value;
28
24
  }
29
25
 
30
- function wrapConfig(CONFIG) {
26
+ export function wrapConfig(CONFIG) {
31
27
  return {
32
28
  CONFIG,
33
29
  ENV: ENV.bind(CONFIG),
34
30
  };
35
31
  }
36
-
37
- module.exports = {
38
- wrapConfig,
39
- };
@@ -0,0 +1,24 @@
1
+ import { CryptoUtils } from './index.mjs';
2
+
3
+ describe('crypto-utils', function() {
4
+ describe('MD5', function() {
5
+ it('should be able to hash input', function() {
6
+ expect(CryptoUtils.MD5('test')).toEqual('098f6bcd4621d373cade4e832627b4f6');
7
+ expect(CryptoUtils.MD5('')).toEqual('d41d8cd98f00b204e9800998ecf8427e');
8
+ });
9
+ });
10
+
11
+ describe('SHA256', function() {
12
+ it('should be able to hash input', function() {
13
+ expect(CryptoUtils.SHA256('test')).toEqual('9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08');
14
+ expect(CryptoUtils.SHA256('')).toEqual('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
15
+ });
16
+ });
17
+
18
+ describe('SHA512', function() {
19
+ it('should be able to hash input', function() {
20
+ expect(CryptoUtils.SHA512('test')).toEqual('ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff');
21
+ expect(CryptoUtils.SHA512('')).toEqual('cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e');
22
+ });
23
+ });
24
+ });
@@ -1,13 +1,9 @@
1
- 'use strict';
2
-
3
- /* global Buffer */
4
-
5
- const { createHash, randomFillSync } = require('node:crypto');
1
+ import { createHash, randomFillSync } from 'node:crypto';
6
2
 
7
3
  const URL_SAFE_ENCODING_KEYS = { '+': '-', '/': '_', '-': '+', '_': '/' };
8
4
  const ENCRYPTION_ALGORITHM = 'aes-256-ctr';
9
5
 
10
- function toBase64(_data) {
6
+ export function toBase64(_data) {
11
7
  var data = _data;
12
8
  if (data instanceof Uint8Array)
13
9
  data = Buffer.from(data);
@@ -18,53 +14,53 @@ function toBase64(_data) {
18
14
  return data.toString('base64');
19
15
  }
20
16
 
21
- function convertBase64ToURLSafe(encodedData) {
17
+ export function convertBase64ToURLSafe(encodedData) {
22
18
  return encodedData.replace(/[+/]/g, (m) => {
23
19
  return URL_SAFE_ENCODING_KEYS[m];
24
20
  });
25
21
  }
26
22
 
27
- function convertBase64FromURLSafe(encodedData) {
23
+ export function convertBase64FromURLSafe(encodedData) {
28
24
  return encodedData.replace(/[_-]/g, (m) => {
29
25
  return URL_SAFE_ENCODING_KEYS[m];
30
26
  });
31
27
  }
32
28
 
33
- function toURLSafeBase64(data) {
29
+ export function toURLSafeBase64(data) {
34
30
  return convertBase64ToURLSafe(toBase64(data));
35
31
  }
36
32
 
37
- function fromURLSafeBase64(data, encoding) {
33
+ export function fromURLSafeBase64(data, encoding) {
38
34
  var buffer = Buffer.from(convertBase64FromURLSafe(data), 'base64');
39
35
  return (encoding == null) ? buffer : buffer.toString(encoding);
40
36
  }
41
37
 
42
- function randomBytes(length) {
38
+ export function randomBytes(length) {
43
39
  let buffer = Buffer.alloc(length);
44
40
  randomFillSync(buffer);
45
41
 
46
42
  return buffer;
47
43
  }
48
44
 
49
- function MD5(data) {
45
+ export function MD5(data) {
50
46
  let hash = createHash('md5');
51
47
  hash.update(data);
52
48
  return hash.digest('hex');
53
49
  }
54
50
 
55
- function SHA256(data) {
51
+ export function SHA256(data) {
56
52
  let hash = createHash('sha256');
57
53
  hash.update(data);
58
54
  return hash.digest('hex');
59
55
  }
60
56
 
61
- function SHA512(data) {
57
+ export function SHA512(data) {
62
58
  let hash = createHash('sha512');
63
59
  hash.update(data);
64
60
  return hash.digest('hex');
65
61
  }
66
62
 
67
- function randomHash(type = 'sha256', length = 128) {
63
+ export function randomHash(type = 'sha256', length = 128) {
68
64
  let bytes = randomBytes(length);
69
65
  let hash = createHash(type);
70
66
 
@@ -73,7 +69,7 @@ function randomHash(type = 'sha256', length = 128) {
73
69
  return hash.digest('hex');
74
70
  }
75
71
 
76
- function hashToken(token, salt) {
72
+ export function hashToken(token, salt) {
77
73
  if (!salt)
78
74
  throw new TypeError('Utils::hashToken: "salt" can not be empty');
79
75
 
@@ -81,13 +77,13 @@ function hashToken(token, salt) {
81
77
  return SHA512(`${salt}${token}`);
82
78
  }
83
79
 
84
- function getSaltProperties(salt) {
80
+ export function getSaltProperties(salt) {
85
81
  let raw = fromURLSafeBase64(salt, 'utf8');
86
82
  let props = JSON.parse(raw);
87
83
  return props;
88
84
  }
89
85
 
90
- function generateSalt() {
86
+ export function generateSalt() {
91
87
  let props = {
92
88
  // eslint-disable-next-line no-magic-numbers
93
89
  secretKey: toURLSafeBase64(randomBytes(32)),
@@ -99,7 +95,7 @@ function generateSalt() {
99
95
 
100
96
  // secretKey = 32 chars (base64)
101
97
  // iv = 32 chars (base64)
102
- function encrypt(value, salt) {
98
+ export function encrypt(value, salt) {
103
99
  const {
104
100
  secretKey,
105
101
  iv,
@@ -111,7 +107,7 @@ function encrypt(value, salt) {
111
107
  return toURLSafeBase64(encrypted);
112
108
  }
113
109
 
114
- function decrypt(value, salt) {
110
+ export function decrypt(value, salt) {
115
111
  const {
116
112
  secretKey,
117
113
  iv,
@@ -122,21 +118,3 @@ function decrypt(value, salt) {
122
118
 
123
119
  return decrpyted.toString('utf8');
124
120
  }
125
-
126
- module.exports = {
127
- toBase64,
128
- convertBase64ToURLSafe,
129
- convertBase64FromURLSafe,
130
- toURLSafeBase64,
131
- fromURLSafeBase64,
132
- getSaltProperties,
133
- generateSalt,
134
- encrypt,
135
- decrypt,
136
- hashToken,
137
- randomBytes,
138
- randomHash,
139
- MD5,
140
- SHA256,
141
- SHA512,
142
- };
@@ -0,0 +1,10 @@
1
+ import * as FileUtils from './file-utils.mjs';
2
+
3
+ describe('file-utils', function() {
4
+ describe('fileNameWithoutExtension', function() {
5
+ it('should be able to remove the extension from a file name', function() {
6
+ expect(FileUtils.fileNameWithoutExtension('test.txt')).toEqual('test');
7
+ expect(FileUtils.fileNameWithoutExtension('test.txt.bin')).toEqual('test.txt');
8
+ });
9
+ });
10
+ });
@@ -1,9 +1,7 @@
1
- 'use strict';
1
+ import Path from 'node:path';
2
+ import FileSystem from 'node:fs';
2
3
 
3
- const Path = require('path');
4
- const FileSystem = require('fs');
5
-
6
- function walkDir(rootPath, _options, _callback, _allFiles, _depth) {
4
+ export function walkDir(rootPath, _options, _callback, _allFiles, _depth) {
7
5
  let depth = _depth || 0;
8
6
  let allFiles = _allFiles || [];
9
7
  let callback = (typeof _options === 'function') ? _options : _callback;
@@ -44,11 +42,6 @@ function walkDir(rootPath, _options, _callback, _allFiles, _depth) {
44
42
  return allFiles;
45
43
  }
46
44
 
47
- function fileNameWithoutExtension(fileName) {
45
+ export function fileNameWithoutExtension(fileName) {
48
46
  return fileName.replace(/\.[^.]*$/, '');
49
47
  }
50
-
51
- module.exports = {
52
- walkDir,
53
- fileNameWithoutExtension,
54
- };
@@ -1,8 +1,6 @@
1
- 'use strict';
1
+ import Nife from 'nife';
2
2
 
3
- const Nife = require('nife');
4
-
5
- function dataToQueryString(data, nameFormatter, resolveInitial) {
3
+ export function dataToQueryString(data, nameFormatter, resolveInitial) {
6
4
  function fromObject(path, data) {
7
5
  let parts = [];
8
6
  let keys = Object.keys(data);
@@ -82,7 +80,7 @@ function dataToQueryString(data, nameFormatter, resolveInitial) {
82
80
  return initial + parts.join('&');
83
81
  }
84
82
 
85
- function statusCodeToMessage(statusCode) {
83
+ export function statusCodeToMessage(statusCode) {
86
84
  let codes = {
87
85
  200: 'OK',
88
86
  204: 'No Content',
@@ -101,8 +99,3 @@ function statusCodeToMessage(statusCode) {
101
99
 
102
100
  return code || 'Unknown';
103
101
  }
104
-
105
- module.exports = {
106
- dataToQueryString,
107
- statusCodeToMessage,
108
- };
@@ -4,4 +4,4 @@ export * as HTTPUtils from './http-utils';
4
4
  export * as CryptoUtils from './crypto-utils';
5
5
  export * as TestUtils from './test-utils';
6
6
  export * as MimeUtils from './mime-utils';
7
- export * from './http-interface';
7
+ export * from '../http/http-interface';
@@ -0,0 +1,6 @@
1
+ export * as ConfigUtils from './config-utils.mjs';
2
+ export * as CryptoUtils from './crypto-utils.mjs';
3
+ export * as FileUtils from './file-utils.mjs';
4
+ export * as HTTPUtils from './http-utils.mjs';
5
+ export * as MimeUtils from './mime-utils.mjs';
6
+ export * as TestUtils from './test-utils.mjs';
@@ -0,0 +1,171 @@
1
+ import * as MimeUtils from './mime-utils.mjs';
2
+
3
+ describe('mime-utils', function() {
4
+ describe('getFilenameExtension', function() {
5
+ it('should be able to get file name extension', function() {
6
+ expect(MimeUtils.getFilenameExtension('/test/derp.txt')).toEqual('txt');
7
+ expect(MimeUtils.getFilenameExtension('/test/derp.test.txt')).toEqual('txt');
8
+ expect(MimeUtils.getFilenameExtension('test.png')).toEqual('png');
9
+ expect(MimeUtils.getFilenameExtension('derp.longext')).toEqual('longext');
10
+ });
11
+ });
12
+
13
+ describe('getMimeTypeFromFilename', function() {
14
+ it('should be able to get mime type from file name', function() {
15
+ expect(MimeUtils.getMimeTypeFromFilename('test.3g2')).toEqual('video/3gpp2');
16
+ expect(MimeUtils.getMimeTypeFromFilename('test.3gp')).toEqual('video/3gpp');
17
+ expect(MimeUtils.getMimeTypeFromFilename('test.7z')).toEqual('application/x-7z-compressed');
18
+ expect(MimeUtils.getMimeTypeFromFilename('test.aac')).toEqual('audio/aac');
19
+ expect(MimeUtils.getMimeTypeFromFilename('test.abw')).toEqual('application/x-abiword');
20
+ expect(MimeUtils.getMimeTypeFromFilename('test.arc')).toEqual('application/x-freearc');
21
+ expect(MimeUtils.getMimeTypeFromFilename('test.avi')).toEqual('video/avi');
22
+ expect(MimeUtils.getMimeTypeFromFilename('test.avif')).toEqual('image/avif');
23
+ expect(MimeUtils.getMimeTypeFromFilename('test.azw')).toEqual('application/vnd.amazon.ebook');
24
+ expect(MimeUtils.getMimeTypeFromFilename('test.bin')).toEqual('application/octet-stream');
25
+ expect(MimeUtils.getMimeTypeFromFilename('test.bmp')).toEqual('image/bmp');
26
+ expect(MimeUtils.getMimeTypeFromFilename('test.bz')).toEqual('application/x-bzip');
27
+ expect(MimeUtils.getMimeTypeFromFilename('test.bz2')).toEqual('application/x-bzip2');
28
+ expect(MimeUtils.getMimeTypeFromFilename('test.cda')).toEqual('application/x-cdf');
29
+ expect(MimeUtils.getMimeTypeFromFilename('test.csh')).toEqual('application/x-csh');
30
+ expect(MimeUtils.getMimeTypeFromFilename('test.css')).toEqual('text/css');
31
+ expect(MimeUtils.getMimeTypeFromFilename('test.csv')).toEqual('text/csv');
32
+ expect(MimeUtils.getMimeTypeFromFilename('test.doc')).toEqual('application/msword');
33
+ expect(MimeUtils.getMimeTypeFromFilename('test.docx')).toEqual('application/vnd.openxmlformats-officedocument.wordprocessingml.document');
34
+ expect(MimeUtils.getMimeTypeFromFilename('test.eot')).toEqual('application/vnd.ms-fontobject');
35
+ expect(MimeUtils.getMimeTypeFromFilename('test.epub')).toEqual('application/epub+zip');
36
+ expect(MimeUtils.getMimeTypeFromFilename('test.gif')).toEqual('image/gif');
37
+ expect(MimeUtils.getMimeTypeFromFilename('test.gz')).toEqual('application/gzip');
38
+ expect(MimeUtils.getMimeTypeFromFilename('test.htm')).toEqual('text/html');
39
+ expect(MimeUtils.getMimeTypeFromFilename('test.html')).toEqual('text/html');
40
+ expect(MimeUtils.getMimeTypeFromFilename('test.ico')).toEqual('image/vnd.microsoft.icon');
41
+ expect(MimeUtils.getMimeTypeFromFilename('test.ics')).toEqual('text/calendar');
42
+ expect(MimeUtils.getMimeTypeFromFilename('test.jar')).toEqual('application/java-archive');
43
+ expect(MimeUtils.getMimeTypeFromFilename('test.jpeg')).toEqual('image/jpeg');
44
+ expect(MimeUtils.getMimeTypeFromFilename('test.jpg')).toEqual('image/jpeg');
45
+ expect(MimeUtils.getMimeTypeFromFilename('test.mjs')).toEqual('text/javascript');
46
+ expect(MimeUtils.getMimeTypeFromFilename('test.json')).toEqual('application/json');
47
+ expect(MimeUtils.getMimeTypeFromFilename('test.jsonld')).toEqual('application/ld+json');
48
+ expect(MimeUtils.getMimeTypeFromFilename('test.mid')).toEqual('audio/midi');
49
+ expect(MimeUtils.getMimeTypeFromFilename('test.mjs')).toEqual('text/javascript');
50
+ expect(MimeUtils.getMimeTypeFromFilename('test.mp3')).toEqual('audio/mpeg3');
51
+ expect(MimeUtils.getMimeTypeFromFilename('test.mp4')).toEqual('video/mp4');
52
+ expect(MimeUtils.getMimeTypeFromFilename('test.mpeg')).toEqual('video/mpeg');
53
+ expect(MimeUtils.getMimeTypeFromFilename('test.mpkg')).toEqual('application/vnd.apple.installer+xml');
54
+ expect(MimeUtils.getMimeTypeFromFilename('test.odp')).toEqual('application/vnd.oasis.opendocument.presentation');
55
+ expect(MimeUtils.getMimeTypeFromFilename('test.ods')).toEqual('application/vnd.oasis.opendocument.spreadsheet');
56
+ expect(MimeUtils.getMimeTypeFromFilename('test.odt')).toEqual('application/vnd.oasis.opendocument.text');
57
+ expect(MimeUtils.getMimeTypeFromFilename('test.oga')).toEqual('audio/ogg');
58
+ expect(MimeUtils.getMimeTypeFromFilename('test.ogv')).toEqual('video/ogg');
59
+ expect(MimeUtils.getMimeTypeFromFilename('test.ogx')).toEqual('application/ogg');
60
+ expect(MimeUtils.getMimeTypeFromFilename('test.opus')).toEqual('audio/opus');
61
+ expect(MimeUtils.getMimeTypeFromFilename('test.otf')).toEqual('font/otf');
62
+ expect(MimeUtils.getMimeTypeFromFilename('test.pdf')).toEqual('application/pdf');
63
+ expect(MimeUtils.getMimeTypeFromFilename('test.php')).toEqual('application/x-httpd-php');
64
+ expect(MimeUtils.getMimeTypeFromFilename('test.png')).toEqual('image/png');
65
+ expect(MimeUtils.getMimeTypeFromFilename('test.ppt')).toEqual('application/vnd.ms-powerpoint');
66
+ expect(MimeUtils.getMimeTypeFromFilename('test.pptx')).toEqual('application/vnd.openxmlformats-officedocument.presentationml.presentation');
67
+ expect(MimeUtils.getMimeTypeFromFilename('test.rar')).toEqual('application/vnd.rar');
68
+ expect(MimeUtils.getMimeTypeFromFilename('test.rtf')).toEqual('application/rtf');
69
+ expect(MimeUtils.getMimeTypeFromFilename('test.sh')).toEqual('application/x-sh');
70
+ expect(MimeUtils.getMimeTypeFromFilename('test.svg')).toEqual('image/svg+xml');
71
+ expect(MimeUtils.getMimeTypeFromFilename('test.swf')).toEqual('application/x-shockwave-flash');
72
+ expect(MimeUtils.getMimeTypeFromFilename('test.tar')).toEqual('application/x-tar');
73
+ expect(MimeUtils.getMimeTypeFromFilename('test.tif')).toEqual('image/tiff');
74
+ expect(MimeUtils.getMimeTypeFromFilename('test.tiff')).toEqual('image/tiff');
75
+ expect(MimeUtils.getMimeTypeFromFilename('test.ts')).toEqual('video/mp2t');
76
+ expect(MimeUtils.getMimeTypeFromFilename('test.ttf')).toEqual('font/ttf');
77
+ expect(MimeUtils.getMimeTypeFromFilename('test.txt')).toEqual('text/plain');
78
+ expect(MimeUtils.getMimeTypeFromFilename('test.vsd')).toEqual('application/vnd.visio');
79
+ expect(MimeUtils.getMimeTypeFromFilename('test.wav')).toEqual('audio/wav');
80
+ expect(MimeUtils.getMimeTypeFromFilename('test.weba')).toEqual('audio/webm');
81
+ expect(MimeUtils.getMimeTypeFromFilename('test.webm')).toEqual('video/webm');
82
+ expect(MimeUtils.getMimeTypeFromFilename('test.webp')).toEqual('image/webp');
83
+ expect(MimeUtils.getMimeTypeFromFilename('test.woff')).toEqual('font/woff');
84
+ expect(MimeUtils.getMimeTypeFromFilename('test.woff2')).toEqual('font/woff2');
85
+ expect(MimeUtils.getMimeTypeFromFilename('test.xhtml')).toEqual('application/xhtml+xml');
86
+ expect(MimeUtils.getMimeTypeFromFilename('test.xls')).toEqual('application/vnd.ms-excel');
87
+ expect(MimeUtils.getMimeTypeFromFilename('test.xlsx')).toEqual('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
88
+ expect(MimeUtils.getMimeTypeFromFilename('test.xml')).toEqual('application/xml');
89
+ expect(MimeUtils.getMimeTypeFromFilename('test.xul')).toEqual('application/vnd.mozilla.xul+xml');
90
+ expect(MimeUtils.getMimeTypeFromFilename('test.zip')).toEqual('application/zip');
91
+ });
92
+ });
93
+
94
+ describe('getFileExtensionFromMimeType', function() {
95
+ it('should be able to get file extension from mime type', function() {
96
+ expect(MimeUtils.getFileExtensionFromMimeType('video/3gpp2')).toEqual('3g2');
97
+ expect(MimeUtils.getFileExtensionFromMimeType('video/3gpp')).toEqual('3gp');
98
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-7z-compressed')).toEqual('7z');
99
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/aac')).toEqual('aac');
100
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-abiword')).toEqual('abw');
101
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-freearc')).toEqual('arc');
102
+ expect(MimeUtils.getFileExtensionFromMimeType('video/avi')).toEqual('avi');
103
+ expect(MimeUtils.getFileExtensionFromMimeType('image/avif')).toEqual('avif');
104
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.amazon.ebook')).toEqual('azw');
105
+ expect(MimeUtils.getFileExtensionFromMimeType('application/octet-stream')).toEqual('bin');
106
+ expect(MimeUtils.getFileExtensionFromMimeType('image/bmp')).toEqual('bmp');
107
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-bzip')).toEqual('bz');
108
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-bzip2')).toEqual('bz2');
109
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-cdf')).toEqual('cda');
110
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-csh')).toEqual('csh');
111
+ expect(MimeUtils.getFileExtensionFromMimeType('text/css')).toEqual('css');
112
+ expect(MimeUtils.getFileExtensionFromMimeType('text/csv')).toEqual('csv');
113
+ expect(MimeUtils.getFileExtensionFromMimeType('application/msword')).toEqual('doc');
114
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')).toEqual('docx');
115
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.ms-fontobject')).toEqual('eot');
116
+ expect(MimeUtils.getFileExtensionFromMimeType('application/epub+zip')).toEqual('epub');
117
+ expect(MimeUtils.getFileExtensionFromMimeType('image/gif')).toEqual('gif');
118
+ expect(MimeUtils.getFileExtensionFromMimeType('application/gzip')).toEqual('gz');
119
+ expect(MimeUtils.getFileExtensionFromMimeType('text/html')).toEqual('html');
120
+ expect(MimeUtils.getFileExtensionFromMimeType('image/vnd.microsoft.icon')).toEqual('ico');
121
+ expect(MimeUtils.getFileExtensionFromMimeType('text/calendar')).toEqual('ics');
122
+ expect(MimeUtils.getFileExtensionFromMimeType('application/java-archive')).toEqual('jar');
123
+ expect(MimeUtils.getFileExtensionFromMimeType('image/jpeg')).toEqual('jpg');
124
+ expect(MimeUtils.getFileExtensionFromMimeType('text/javascript')).toEqual('js');
125
+ expect(MimeUtils.getFileExtensionFromMimeType('application/json')).toEqual('json');
126
+ expect(MimeUtils.getFileExtensionFromMimeType('application/ld+json')).toEqual('jsonld');
127
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/midi')).toEqual('mid');
128
+ expect(MimeUtils.getFileExtensionFromMimeType('text/javascript')).toEqual('js');
129
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/mpeg3')).toEqual('mp3');
130
+ expect(MimeUtils.getFileExtensionFromMimeType('video/mp4')).toEqual('mp4');
131
+ expect(MimeUtils.getFileExtensionFromMimeType('video/mpeg')).toEqual('mpeg');
132
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.apple.installer+xml')).toEqual('mpkg');
133
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.oasis.opendocument.presentation')).toEqual('odp');
134
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.oasis.opendocument.spreadsheet')).toEqual('ods');
135
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.oasis.opendocument.text')).toEqual('odt');
136
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/ogg')).toEqual('oga');
137
+ expect(MimeUtils.getFileExtensionFromMimeType('video/ogg')).toEqual('ogv');
138
+ expect(MimeUtils.getFileExtensionFromMimeType('application/ogg')).toEqual('ogx');
139
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/opus')).toEqual('opus');
140
+ expect(MimeUtils.getFileExtensionFromMimeType('font/otf')).toEqual('otf');
141
+ expect(MimeUtils.getFileExtensionFromMimeType('application/pdf')).toEqual('pdf');
142
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-httpd-php')).toEqual('php');
143
+ expect(MimeUtils.getFileExtensionFromMimeType('image/png')).toEqual('png');
144
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.ms-powerpoint')).toEqual('ppt');
145
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.openxmlformats-officedocument.presentationml.presentation')).toEqual('pptx');
146
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.rar')).toEqual('rar');
147
+ expect(MimeUtils.getFileExtensionFromMimeType('application/rtf')).toEqual('rtf');
148
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-sh')).toEqual('sh');
149
+ expect(MimeUtils.getFileExtensionFromMimeType('image/svg+xml')).toEqual('svg');
150
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-shockwave-flash')).toEqual('swf');
151
+ expect(MimeUtils.getFileExtensionFromMimeType('application/x-tar')).toEqual('tar');
152
+ expect(MimeUtils.getFileExtensionFromMimeType('image/tiff')).toEqual('tiff');
153
+ expect(MimeUtils.getFileExtensionFromMimeType('video/mp2t')).toEqual('ts');
154
+ expect(MimeUtils.getFileExtensionFromMimeType('font/ttf')).toEqual('ttf');
155
+ expect(MimeUtils.getFileExtensionFromMimeType('text/plain')).toEqual('txt');
156
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.visio')).toEqual('vsd');
157
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/wav')).toEqual('wav');
158
+ expect(MimeUtils.getFileExtensionFromMimeType('audio/webm')).toEqual('weba');
159
+ expect(MimeUtils.getFileExtensionFromMimeType('video/webm')).toEqual('webm');
160
+ expect(MimeUtils.getFileExtensionFromMimeType('image/webp')).toEqual('webp');
161
+ expect(MimeUtils.getFileExtensionFromMimeType('font/woff')).toEqual('woff');
162
+ expect(MimeUtils.getFileExtensionFromMimeType('font/woff2')).toEqual('woff2');
163
+ expect(MimeUtils.getFileExtensionFromMimeType('application/xhtml+xml')).toEqual('xhtml');
164
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.ms-excel')).toEqual('xls');
165
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')).toEqual('xlsx');
166
+ expect(MimeUtils.getFileExtensionFromMimeType('application/xml')).toEqual('xml');
167
+ expect(MimeUtils.getFileExtensionFromMimeType('application/vnd.mozilla.xul+xml')).toEqual('xul');
168
+ expect(MimeUtils.getFileExtensionFromMimeType('application/zip')).toEqual('zip');
169
+ });
170
+ });
171
+ });