teraslice 3.3.0 → 3.3.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 (108) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +25 -28
  3. package/dist/src/interfaces.js +0 -12
  4. package/dist/src/lib/cluster/cluster_master.js +0 -246
  5. package/dist/src/lib/cluster/node_master.js +0 -355
  6. package/dist/src/lib/cluster/services/api.js +0 -663
  7. package/dist/src/lib/cluster/services/assets.js +0 -224
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +0 -192
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +0 -2
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +0 -419
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +0 -60
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +0 -55
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +0 -357
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +0 -37
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +0 -60
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +0 -170
  17. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +0 -13
  18. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +0 -526
  19. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +0 -548
  20. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +0 -26
  21. package/dist/src/lib/cluster/services/cluster/index.js +0 -13
  22. package/dist/src/lib/cluster/services/execution.js +0 -435
  23. package/dist/src/lib/cluster/services/index.js +0 -6
  24. package/dist/src/lib/cluster/services/interfaces.js +0 -2
  25. package/dist/src/lib/cluster/services/jobs.js +0 -458
  26. package/dist/src/lib/config/default-sysconfig.js +0 -25
  27. package/dist/src/lib/config/index.js +0 -20
  28. package/dist/src/lib/config/schemas/system.js +0 -360
  29. package/dist/src/lib/storage/analytics.js +0 -86
  30. package/dist/src/lib/storage/assets.js +0 -401
  31. package/dist/src/lib/storage/backends/elasticsearch_store.js +0 -496
  32. package/dist/src/lib/storage/backends/mappings/analytics.js +0 -20
  33. package/dist/src/lib/storage/backends/mappings/asset.js +0 -32
  34. package/dist/src/lib/storage/backends/mappings/ex.js +0 -53
  35. package/dist/src/lib/storage/backends/mappings/job.js +0 -42
  36. package/dist/src/lib/storage/backends/mappings/state.js +0 -16
  37. package/dist/src/lib/storage/backends/s3_store.js +0 -237
  38. package/dist/src/lib/storage/execution.js +0 -302
  39. package/dist/src/lib/storage/index.js +0 -7
  40. package/dist/src/lib/storage/jobs.js +0 -81
  41. package/dist/src/lib/storage/state.js +0 -254
  42. package/dist/src/lib/utils/api_utils.js +0 -128
  43. package/dist/src/lib/utils/asset_utils.js +0 -94
  44. package/dist/src/lib/utils/date_utils.js +0 -52
  45. package/dist/src/lib/utils/encoding_utils.js +0 -27
  46. package/dist/src/lib/utils/events.js +0 -4
  47. package/dist/src/lib/utils/file_utils.js +0 -124
  48. package/dist/src/lib/utils/id_utils.js +0 -15
  49. package/dist/src/lib/utils/port_utils.js +0 -32
  50. package/dist/src/lib/workers/assets/index.js +0 -3
  51. package/dist/src/lib/workers/assets/loader-executable.js +0 -40
  52. package/dist/src/lib/workers/assets/loader.js +0 -73
  53. package/dist/src/lib/workers/assets/spawn.js +0 -55
  54. package/dist/src/lib/workers/context/execution-context.js +0 -12
  55. package/dist/src/lib/workers/context/terafoundation-context.js +0 -8
  56. package/dist/src/lib/workers/execution-controller/execution-analytics.js +0 -188
  57. package/dist/src/lib/workers/execution-controller/index.js +0 -1024
  58. package/dist/src/lib/workers/execution-controller/recovery.js +0 -151
  59. package/dist/src/lib/workers/execution-controller/scheduler.js +0 -390
  60. package/dist/src/lib/workers/execution-controller/slice-analytics.js +0 -96
  61. package/dist/src/lib/workers/helpers/job.js +0 -80
  62. package/dist/src/lib/workers/helpers/op-analytics.js +0 -22
  63. package/dist/src/lib/workers/helpers/terafoundation.js +0 -34
  64. package/dist/src/lib/workers/helpers/worker-shutdown.js +0 -147
  65. package/dist/src/lib/workers/metrics/index.js +0 -108
  66. package/dist/src/lib/workers/worker/index.js +0 -378
  67. package/dist/src/lib/workers/worker/slice.js +0 -122
  68. package/dist/test/config/schemas/system_schema-spec.js +0 -26
  69. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +0 -458
  70. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +0 -818
  71. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +0 -67
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +0 -84
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +0 -320
  74. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +0 -37
  75. package/dist/test/node_master-spec.js +0 -194
  76. package/dist/test/services/api-spec.js +0 -79
  77. package/dist/test/services/assets-spec.js +0 -158
  78. package/dist/test/services/messaging-spec.js +0 -440
  79. package/dist/test/storage/assets_storage-spec.js +0 -95
  80. package/dist/test/storage/s3_store-spec.js +0 -149
  81. package/dist/test/test.config.js +0 -23
  82. package/dist/test/test.setup.js +0 -6
  83. package/dist/test/utils/api_utils-spec.js +0 -25
  84. package/dist/test/utils/asset_utils-spec.js +0 -141
  85. package/dist/test/utils/elastic_utils-spec.js +0 -25
  86. package/dist/test/workers/execution-controller/execution-controller-spec.js +0 -371
  87. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +0 -519
  88. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +0 -343
  89. package/dist/test/workers/execution-controller/recovery-spec.js +0 -160
  90. package/dist/test/workers/execution-controller/scheduler-spec.js +0 -249
  91. package/dist/test/workers/execution-controller/slice-analytics-spec.js +0 -121
  92. package/dist/test/workers/fixtures/ops/example-op/processor.js +0 -20
  93. package/dist/test/workers/fixtures/ops/example-op/schema.js +0 -19
  94. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +0 -20
  95. package/dist/test/workers/fixtures/ops/example-reader/schema.js +0 -41
  96. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +0 -37
  97. package/dist/test/workers/fixtures/ops/new-op/processor.js +0 -29
  98. package/dist/test/workers/fixtures/ops/new-op/schema.js +0 -18
  99. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +0 -19
  100. package/dist/test/workers/fixtures/ops/new-reader/schema.js +0 -23
  101. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +0 -13
  102. package/dist/test/workers/helpers/configs.js +0 -128
  103. package/dist/test/workers/helpers/execution-controller-helper.js +0 -49
  104. package/dist/test/workers/helpers/index.js +0 -5
  105. package/dist/test/workers/helpers/test-context.js +0 -210
  106. package/dist/test/workers/helpers/zip-directory.js +0 -25
  107. package/dist/test/workers/worker/slice-spec.js +0 -333
  108. package/dist/test/workers/worker/worker-spec.js +0 -356
@@ -1,254 +0,0 @@
1
- import { RecoveryCleanupType } from '@terascope/job-components';
2
- import { TSError, pRetry, toString, isRetryableError, parseErrorInfo, isTest, times, getFullErrorStack, isKey } from '@terascope/core-utils';
3
- import { timeseriesIndex } from '../utils/date_utils.js';
4
- import { makeLogger } from '../workers/helpers/terafoundation.js';
5
- import { TerasliceElasticsearchStorage } from './backends/elasticsearch_store.js';
6
- export const SliceState = Object.freeze({
7
- pending: 'pending',
8
- start: 'start',
9
- error: 'error',
10
- completed: 'completed',
11
- });
12
- export class StateStorage {
13
- backend;
14
- logger;
15
- recordType;
16
- timeseriesFormat;
17
- baseIndex;
18
- index;
19
- constructor(context) {
20
- const recordType = 'state';
21
- const logger = makeLogger(context, 'state_storage');
22
- const config = context.sysconfig.teraslice;
23
- const _index = `${config.name}__state`;
24
- // making this to pass down to backend for dynamic index searches
25
- const indexName = `${_index}*`;
26
- const timeseriesFormat = config.index_rollover_frequency.state;
27
- const backendConfig = {
28
- context,
29
- indexName,
30
- recordType,
31
- idField: 'slice_id',
32
- fullResponse: false,
33
- logRecord: true,
34
- forceRefresh: false,
35
- storageName: 'state',
36
- logger
37
- };
38
- this.backend = new TerasliceElasticsearchStorage(backendConfig);
39
- this.logger = logger;
40
- this.recordType = recordType;
41
- this.timeseriesFormat = timeseriesFormat;
42
- this.baseIndex = _index;
43
- this.index = indexName;
44
- }
45
- async initialize() {
46
- await this.backend.initialize();
47
- this.logger.info('state storage initialized');
48
- }
49
- async createState(exId, slice, state, error) {
50
- const { record, index } = this._createSliceRecord(exId, slice, state, error);
51
- return this.backend.indexWithId(slice.slice_id, record, index);
52
- }
53
- async createSlices(exId, slices) {
54
- const bulkRequest = slices.map((slice) => {
55
- const { record, index } = this._createSliceRecord(exId, slice, SliceState.pending);
56
- return {
57
- action: {
58
- index: {
59
- _index: index,
60
- _id: record.slice_id,
61
- },
62
- },
63
- data: record
64
- };
65
- });
66
- return this.backend.bulkSend(bulkRequest);
67
- }
68
- _createSliceRecord(exId, slice, state, error) {
69
- if (!isKey(SliceState, state)) {
70
- throw new Error(`Unknown slice state "${state}" on create`);
71
- }
72
- const { index } = timeseriesIndex(this.timeseriesFormat, this.baseIndex, slice._created);
73
- // TODO: type this better
74
- const record = {
75
- slice_id: slice.slice_id,
76
- slicer_id: slice.slicer_id,
77
- slicer_order: slice.slicer_order,
78
- request: JSON.stringify(slice.request),
79
- state,
80
- ex_id: exId,
81
- _created: slice._created,
82
- _updated: slice._created,
83
- };
84
- if (error) {
85
- record.error = toString(error);
86
- }
87
- return { record, index };
88
- }
89
- // TODO: type this better
90
- async updateState(slice, state, error) {
91
- if (!isKey(SliceState, state)) {
92
- throw new Error(`Unknown slice state "${state}" on update`);
93
- }
94
- const indexData = timeseriesIndex(this.timeseriesFormat, this.baseIndex, slice._created);
95
- // TODO: type this better
96
- const record = {
97
- _updated: indexData.timestamp,
98
- state
99
- };
100
- // it will usaully just be error
101
- if (state === SliceState.error || error) {
102
- if (error) {
103
- record.error = getFullErrorStack(error);
104
- }
105
- else {
106
- record.error = new Error('Unknown slice error').stack;
107
- }
108
- }
109
- let notFoundErrCount = 0;
110
- const updateFn = this.backend.update.bind(this.backend);
111
- async function update() {
112
- try {
113
- return await updateFn(slice.slice_id, record, indexData.index);
114
- }
115
- catch (_err) {
116
- const { statusCode, message } = parseErrorInfo(_err);
117
- let retryable = isRetryableError(_err);
118
- if (statusCode === 404) {
119
- notFoundErrCount++;
120
- retryable = notFoundErrCount < 3;
121
- }
122
- else if (message.includes('Request Timeout')) {
123
- retryable = true;
124
- }
125
- throw new TSError(_err, {
126
- retryable,
127
- reason: `Failure to update ${state} state`
128
- });
129
- }
130
- }
131
- return pRetry(update, {
132
- retries: 10000,
133
- delay: isTest ? 100 : 1000,
134
- backoff: 5,
135
- endWithFatal: true,
136
- });
137
- }
138
- /**
139
- * Get the starting position for the slicer
140
- *
141
- * @param {string} exId
142
- * @param {number} slicerId
143
- * @returns {Promise<import('@terascope/job-components').SlicerRecoveryData>}
144
- */
145
- async _getSlicerStartingPoint(exId, slicerId) {
146
- const startQuery = `ex_id:"${exId}" AND slicer_id:"${slicerId}" AND state:${SliceState.completed}`;
147
- try {
148
- const [slice] = await this.search(startQuery, 0, 1, 'slicer_order:desc');
149
- const recoveryData = {
150
- slicer_id: slicerId,
151
- lastSlice: undefined
152
- };
153
- if (slice) {
154
- recoveryData.lastSlice = JSON.parse(slice.request);
155
- this.logger.info(`last slice process for slicer_id ${slicerId}, ex_id: ${exId} is`, slice.lastSlice);
156
- }
157
- return recoveryData;
158
- }
159
- catch (err) {
160
- throw new TSError(err, {
161
- reason: 'Failure getting the newest record'
162
- });
163
- }
164
- }
165
- /**
166
- * Get the starting positions for all of the slicers
167
- *
168
- * @param {string} exId
169
- * @param {number} slicer
170
- * @returns {Promise<import('@terascope/job-components').SlicerRecoveryData[]>}
171
- */
172
- async getStartingPoints(exId, slicers) {
173
- const recoveredSlices = times(slicers, (i) => this._getSlicerStartingPoint(exId, i));
174
- return Promise.all(recoveredSlices);
175
- }
176
- // TODO: fix types
177
- /**
178
- * @private
179
- * @param {string} exId
180
- * @param {number} slicerId
181
- * @param {import('@terascope/job-components').RecoveryCleanupType} [cleanupType]
182
- * @returns {string}
183
- */
184
- _getRecoverSlicesQuery(exId, slicerId, cleanupType) {
185
- let query = `ex_id:"${exId}"`;
186
- if (slicerId !== -1) {
187
- query = `${query} AND slicer_id:"${slicerId}"`;
188
- }
189
- if (cleanupType && cleanupType === RecoveryCleanupType.errors) {
190
- query = `${query} AND state:"${SliceState.error}"`;
191
- }
192
- else if (cleanupType && cleanupType === RecoveryCleanupType.pending) {
193
- query = `${query} AND state:"${SliceState.pending}"`;
194
- }
195
- else {
196
- query = `${query} AND NOT state:"${SliceState.completed}"`;
197
- }
198
- this.logger.debug('recovery slices query:', query);
199
- return query;
200
- }
201
- /**
202
- * @param {string} exId
203
- * @param {number} slicerId
204
- * @param {import('@terascope/job-components').RecoveryCleanupType} [cleanupType]
205
- * @returns {Promise<import('@terascope/job-components').Slice[]>}
206
- */
207
- async recoverSlices(exId, slicerId, cleanupType) {
208
- const query = this._getRecoverSlicesQuery(exId, slicerId, cleanupType);
209
- // Look for all slices that haven't been completed so they can be retried.
210
- try {
211
- await this.backend.refresh(this.index);
212
- const results = await this.search(query, 0, 5000, 'slicer_order:desc');
213
- return results.map((doc) => ({
214
- slice_id: doc.slice_id,
215
- slicer_id: doc.slicer_id,
216
- request: JSON.parse(doc.request),
217
- _created: doc._created
218
- }));
219
- }
220
- catch (err) {
221
- throw new TSError(err, {
222
- reason: 'Failure to get recovered slices'
223
- });
224
- }
225
- }
226
- async search(query, from, size, sort, fields) {
227
- return this.backend.search(query, from, size, sort || '_updated:desc', fields);
228
- }
229
- async count(query, from = 0, sort = '_updated:desc') {
230
- return this.backend.count(query, from, sort);
231
- }
232
- async countByState(exId, state) {
233
- if (!isKey(SliceState, state)) {
234
- throw new Error(`Unknown slice state "${state}" on update`);
235
- }
236
- const query = `ex_id:"${exId}" AND state:${state}`;
237
- return this.count(query);
238
- }
239
- async shutdown(forceShutdown) {
240
- this.logger.info('shutting down');
241
- return this.backend.shutdown(forceShutdown);
242
- }
243
- async refresh() {
244
- const { index } = timeseriesIndex(this.timeseriesFormat, this.baseIndex);
245
- return this.backend.refresh(index);
246
- }
247
- verifyClient() {
248
- return this.backend.verifyClient();
249
- }
250
- async waitForClient() {
251
- return this.backend.waitForClient();
252
- }
253
- }
254
- //# sourceMappingURL=state.js.map
@@ -1,128 +0,0 @@
1
- import Table from 'easy-table';
2
- import { parseErrorInfo, parseList, logError, isString, get, toInteger, TSError } from '@terascope/core-utils';
3
- export function makeTable(req, defaults, data, mappingFn) {
4
- const query = fieldsQuery(req.query, defaults);
5
- let emptyChar = 'N/A';
6
- // used to create an empty table if there are no jobs
7
- if (data.length === 0) {
8
- emptyChar = '';
9
- data.push({});
10
- }
11
- return Table.print(data, (item, cell) => {
12
- const fn = mappingFn ? mappingFn(item) : (field) => get(item, field, emptyChar);
13
- query.forEach((field) => {
14
- cell(field, fn(field));
15
- });
16
- }, (table) => {
17
- if (('headers' in req.query) && req.query.headers === 'false') {
18
- return table.print();
19
- }
20
- return table.toString();
21
- });
22
- }
23
- function fieldsQuery(query, defaults) {
24
- if (!query.fields) {
25
- return defaults || [];
26
- }
27
- const results = parseList(query.fields);
28
- if (results.length === 0) {
29
- return defaults;
30
- }
31
- return results;
32
- }
33
- export function handleTerasliceRequest(req, res, defaultErrorMsg = 'Failure to process TerasliceRequest', { errorCode = 500, successCode = 200 } = {}) {
34
- logTerasliceRequest(req);
35
- return async (fn) => {
36
- try {
37
- const result = await fn();
38
- if (isString(result)) {
39
- res.status(successCode).send(result);
40
- }
41
- else {
42
- res.status(successCode).json(result);
43
- }
44
- }
45
- catch (err) {
46
- const { statusCode, message } = parseErrorInfo(err, {
47
- defaultErrorMsg,
48
- defaultStatusCode: errorCode,
49
- });
50
- if (statusCode >= 500) {
51
- logError(req.logger, err);
52
- }
53
- else {
54
- logError(req.logger, message);
55
- }
56
- sendError(res, statusCode, message, req.logger);
57
- }
58
- };
59
- }
60
- export function sendError(res, code, message, logger) {
61
- if (res.headersSent) {
62
- const error = new TSError(message);
63
- error.statusCode = code;
64
- if (logger) {
65
- logger.error(error, 'TerasliceRequest send error after headers sent');
66
- }
67
- else {
68
- console.error(error, 'TerasliceRequest send error after headers sent');
69
- }
70
- return;
71
- }
72
- res.status(code).json({
73
- error: code,
74
- message
75
- });
76
- }
77
- function parseQueryInt(req, key, defaultVal) {
78
- const val = req.query[key];
79
- if (val == null || val === '')
80
- return defaultVal;
81
- const parsed = toInteger(val);
82
- // allow the invalid prop to be passed through
83
- // (because an error should thrown downstream)
84
- if (parsed === false) {
85
- return req.query[key];
86
- }
87
- return parsed;
88
- }
89
- export function getSearchOptions(req, defaultSort = '_updated:desc') {
90
- const sort = req.query.sort || defaultSort;
91
- const size = parseQueryInt(req, 'size', 100);
92
- const from = parseQueryInt(req, 'from', 0);
93
- const filter = req.query.filter || '';
94
- return { size, from, sort, filter };
95
- }
96
- export function logTerasliceRequest(req) {
97
- const queryInfo = Object.entries(req.query)
98
- .map(([key, val]) => `${key}: ${val}`)
99
- .join(', ');
100
- const { method, path } = req;
101
- req.logger.trace(`${method.toUpperCase()} ${path} endpoint has been called, ${queryInfo}`);
102
- }
103
- export function createJobActiveQuery(active) {
104
- if (active === 'true') {
105
- return 'job_id:* AND !active:false';
106
- }
107
- if (active === 'false') {
108
- return 'job_id:* AND active:false';
109
- }
110
- return 'job_id:*';
111
- }
112
- export function addDeletedToQuery(deleted, query) {
113
- if (deleted === 'false') {
114
- return `${query} AND (_deleted:false OR (* AND -_deleted:*))`;
115
- }
116
- return `${query} AND _deleted:true`;
117
- }
118
- /**
119
- * Combines a base query from an endpoint with an optional filter using AND from lucene.
120
- * @param query - The base Lucene query string
121
- * @param filter - Optional filter query to append. getSearchOptions() will return an empty string
122
- * if no filter is present.
123
- * @returns The combined query, or original query if filter is empty
124
- */
125
- export function addFilterToQuery(query, filter) {
126
- return filter ? `(${query}) AND (${filter})` : query;
127
- }
128
- //# sourceMappingURL=api_utils.js.map
@@ -1,94 +0,0 @@
1
- import { isInteger, trimStart, trim, getFirst, joinList } from '@terascope/core-utils';
2
- import * as semver from 'semver';
3
- export function findMatchingAsset(records, name, version) {
4
- const range = toSemverRange(version);
5
- const assets = records
6
- .filter(_isCompatibleAsset(name, range, false))
7
- .sort((a, b) => semver.rcompare(a.version, b.version));
8
- return getFirst(assets);
9
- }
10
- export function findSimilarAssets(records, name, version) {
11
- const range = toSemverRange(version);
12
- const assets = records
13
- .filter(_isCompatibleAsset(name, range, true))
14
- .sort((a, b) => semver.rcompare(a.version, b.version));
15
- return assets;
16
- }
17
- export function getInCompatibilityReason(assets, prefix) {
18
- if (!assets || !assets.length)
19
- return '';
20
- const reasons = [];
21
- assets.slice(0, 3).forEach((asset) => {
22
- if (!isCompatibleNodeVersion(asset.node_version)) {
23
- reasons.push('node_version');
24
- }
25
- if (asset.platform != null && asset.platform !== process.platform) {
26
- reasons.push('platform');
27
- }
28
- if (asset.arch != null && asset.arch !== process.arch) {
29
- reasons.push('arch');
30
- }
31
- });
32
- if (!reasons.length)
33
- return '';
34
- return `${prefix ? `${trim(prefix)} ` : ''}${joinList(reasons, ',', 'or')} mismatch`;
35
- }
36
- export function getMajorVersion(version) {
37
- if (version == null)
38
- return version;
39
- if (isInteger(version))
40
- return version;
41
- return semver.major(version);
42
- }
43
- const SYSTEM_NODE_VERSION = getMajorVersion(process.version);
44
- /**
45
- * This just compares the major version
46
- */
47
- function isCompatibleNodeVersion(version) {
48
- if (version == null)
49
- return true;
50
- // anything less than or equal to current node version
51
- return getMajorVersion(version) <= SYSTEM_NODE_VERSION;
52
- }
53
- function _isCompatibleAsset(name, range, skipRestrictions = false) {
54
- return function checkIfCompatibleAsset(record) {
55
- if (record.name !== name)
56
- return false;
57
- if (!semver.satisfies(record.version, range, { includePrerelease: true })) {
58
- return false;
59
- }
60
- if (skipRestrictions)
61
- return true;
62
- if (!isCompatibleNodeVersion(record.node_version)) {
63
- return false;
64
- }
65
- if (record.arch != null && record.arch !== process.arch) {
66
- return false;
67
- }
68
- if (record.platform != null && record.platform !== process.platform) {
69
- return false;
70
- }
71
- return true;
72
- };
73
- }
74
- export function toSemverRange(version) {
75
- if (!version || version === 'latest')
76
- return '*';
77
- if (semver.validRange(version)) {
78
- return trimStart(trim(version), 'v');
79
- }
80
- throw new Error(`Version "${version}" is not a valid semver range`);
81
- }
82
- export function toVersionQuery(_version) {
83
- const version = trimStart(trim(_version));
84
- if (!version || version === 'latest' || version === '*') {
85
- return 'version:*';
86
- }
87
- // if there a number and * next to each other that is not valid
88
- // so lets just return the query: 12.34*.55
89
- if (/\d\*/.test(version))
90
- return `version:${version}`;
91
- const range = new semver.Range(version);
92
- return `version:${range.range.split(' ').join(' AND version:')}`;
93
- }
94
- //# sourceMappingURL=asset_utils.js.map
@@ -1,52 +0,0 @@
1
- import { isKey, makeISODate } from '@terascope/core-utils';
2
- const options = {
3
- year: 'y',
4
- years: 'y',
5
- y: 'y',
6
- months: 'M',
7
- month: 'M',
8
- mo: 'M',
9
- mos: 'M',
10
- M: 'M',
11
- weeks: 'w',
12
- week: 'w',
13
- wks: 'w',
14
- wk: 'w',
15
- w: 'w',
16
- days: 'd',
17
- day: 'd',
18
- d: 'd',
19
- hours: 'h',
20
- hour: 'h',
21
- hr: 'h',
22
- hrs: 'h',
23
- h: 'h',
24
- minutes: 'm',
25
- minute: 'm',
26
- min: 'm',
27
- mins: 'm',
28
- m: 'm',
29
- seconds: 's',
30
- second: 's',
31
- s: 's',
32
- milliseconds: 'ms',
33
- millisecond: 'ms',
34
- ms: 'ms'
35
- };
36
- const formatter = {
37
- daily: 10,
38
- monthly: 7,
39
- yearly: 4
40
- };
41
- export function dateOptions(value) {
42
- if (value && isKey(options, value)) {
43
- return options[value];
44
- }
45
- throw new Error(`the time descriptor of "${value}" for the interval is malformed`);
46
- }
47
- export function timeseriesIndex(timeseriesFormat, index, dateStr) {
48
- const timestamp = makeISODate();
49
- const dateString = dateStr || timestamp;
50
- return { index: `${index}-${dateString.slice(0, formatter[timeseriesFormat]).replace(/-/g, '.')}`, timestamp };
51
- }
52
- //# sourceMappingURL=date_utils.js.map
@@ -1,27 +0,0 @@
1
- import { isString, isObjectEntity, getTypeOf, isArrayLike } from '@terascope/core-utils';
2
- export function safeEncode(obj) {
3
- let str;
4
- if (isString(obj)) {
5
- str = obj;
6
- }
7
- else if (isObjectEntity(obj) || isArrayLike(obj)) {
8
- str = JSON.stringify(obj);
9
- }
10
- else {
11
- throw new Error(`unprocessable entity to encode: ${getTypeOf(obj)}`);
12
- }
13
- return Buffer.from(str).toString('base64');
14
- }
15
- // TODO: proper types for this
16
- export function safeDecode(str) {
17
- if (!isString(str) && isObjectEntity(str)) {
18
- return str;
19
- }
20
- try {
21
- return JSON.parse(Buffer.from(str, 'base64').toString('utf-8'));
22
- }
23
- catch (err) {
24
- throw new Error(`Unable to decode ${str}`);
25
- }
26
- }
27
- //# sourceMappingURL=encoding_utils.js.map
@@ -1,4 +0,0 @@
1
- import events from 'node:events';
2
- const eventEmitter = new events.EventEmitter();
3
- export { eventEmitter };
4
- //# sourceMappingURL=events.js.map
@@ -1,124 +0,0 @@
1
- import { accessSync, readFileSync } from 'node:fs';
2
- import path from 'node:path';
3
- import fse from 'fs-extra';
4
- import semver from 'semver';
5
- import { Mutex } from 'async-mutex';
6
- import { TSError } from '@terascope/core-utils';
7
- import decompress from 'decompress';
8
- import { getMajorVersion } from './asset_utils.js';
9
- const mutex = new Mutex();
10
- const packagePath = path.join(process.cwd(), './package.json');
11
- let _packageJSON;
12
- export function getPackageJSON() {
13
- if (_packageJSON)
14
- return _packageJSON;
15
- const file = readFileSync(packagePath, { encoding: 'utf8' });
16
- const results = JSON.parse(file);
17
- _packageJSON = results;
18
- return results;
19
- }
20
- export function existsSync(filename) {
21
- try {
22
- accessSync(filename);
23
- return true;
24
- }
25
- catch (ex) {
26
- return false;
27
- }
28
- }
29
- export function deleteDir(dirPath) {
30
- return fse.remove(dirPath);
31
- }
32
- export async function verifyAssetJSON(id, newPath) {
33
- const hasAssetJSONTopLevel = await fse.pathExists(path.join(newPath, 'asset.json'));
34
- if (!hasAssetJSONTopLevel) {
35
- const err = new TSError('asset.json was not found in root directory of asset bundle', { statusCode: 422 });
36
- throw err;
37
- }
38
- let packageData;
39
- try {
40
- packageData = await fse.readJson(path.join(newPath, 'asset.json'));
41
- }
42
- catch (_err) {
43
- const err = new TSError(_err, {
44
- message: 'Failure parsing asset.json, please ensure that\'s it formatted correctly',
45
- statusCode: 422
46
- });
47
- throw err;
48
- }
49
- const metadata = Object.assign({ id }, packageData);
50
- if (!metadata.name) {
51
- throw new Error('Missing name');
52
- }
53
- metadata.version = semver.clean(metadata.version);
54
- if (!semver.valid(metadata.version)) {
55
- throw new Error(`Invalid version "${metadata.version}"`);
56
- }
57
- /**
58
- * If node_version, platform, or arch is set to a falsey
59
- * value we should delete it so it is considered a wildcard.
60
- *
61
- * This is useful for making an asset bundle that isn't
62
- * locked down.
63
- */
64
- if (metadata.node_version) {
65
- metadata.node_version = getMajorVersion(metadata.node_version);
66
- }
67
- else {
68
- delete metadata.node_version;
69
- }
70
- if (!metadata.platform) {
71
- delete metadata.platform;
72
- }
73
- if (!metadata.arch) {
74
- delete metadata.arch;
75
- }
76
- if (metadata.minimum_teraslice_version) {
77
- const terasliceVersion = getPackageJSON().version;
78
- if (semver.gt(metadata.minimum_teraslice_version, terasliceVersion)) {
79
- throw new Error(`Asset requires teraslice version ${metadata.minimum_teraslice_version} or greater.`);
80
- }
81
- }
82
- return metadata;
83
- }
84
- async function _saveAsset(logger, assetsPath, id, binaryData, metaCheck) {
85
- const newPath = path.join(assetsPath, id);
86
- try {
87
- if (await fse.pathExists(newPath)) {
88
- await fse.emptyDir(newPath);
89
- }
90
- else {
91
- await fse.mkdir(newPath);
92
- }
93
- logger.info(`decompressing and saving asset ${id} to ${newPath}`);
94
- await decompress(binaryData, newPath);
95
- logger.info(`decompressed asset ${id} to ${newPath}`);
96
- const metadata = await verifyAssetJSON(id, newPath);
97
- logger.info(`asset ${id} saved to file ${newPath}`, metadata);
98
- // storage/assets save fn needs to check the return metadata for uniqueness
99
- if (metaCheck) {
100
- return await metaCheck(metadata);
101
- }
102
- return metadata;
103
- }
104
- catch (err) {
105
- await deleteDir(newPath);
106
- throw err;
107
- }
108
- }
109
- export async function saveAsset(logger, assetsPath, id, binaryData, metaCheck) {
110
- return mutex.runExclusive(() => _saveAsset(logger, assetsPath, id, binaryData, metaCheck));
111
- }
112
- /**
113
- * Check if a buffer contains a zip file.
114
- * Note that file extension and mime type are not checked.
115
- * Any file type that is actually a zip (.xlsx, .jar, .apk,
116
- * .epub) will return true.
117
- * @param {Buffer} buffer A buffer containing a file file
118
- * @returns {boolean}
119
- */
120
- export function isZipFile(buffer) {
121
- const zipSignature = [0x50, 0x4B, 0x03, 0x04];
122
- return zipSignature.every((byte, index) => buffer[index] === byte);
123
- }
124
- //# sourceMappingURL=file_utils.js.map