@certik/skynet 0.25.5 → 0.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/bun.lockb +0 -0
- package/dist/api.js +47 -38
- package/dist/app.js +308 -283
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +4 -0
- package/dist/deploy.js +32 -20
- package/dist/dynamodb.d.ts +2 -1
- package/dist/dynamodb.js +28 -22
- package/dist/email.d.ts +9 -0
- package/dist/email.js +31 -0
- package/dist/indexer.js +154 -132
- package/dist/selector.js +10 -1
- package/examples/api.ts +0 -0
- package/examples/indexer.ts +0 -0
- package/examples/mode-indexer.ts +0 -0
- package/package.json +1 -1
- package/src/selector.ts +11 -1
- package/.vscode/settings.json +0 -5
package/dist/cli.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ declare function getBinaryName(): string;
|
|
|
2
2
|
declare function detectSkynetDirectory(): string;
|
|
3
3
|
declare function detectWorkingDirectory(): string;
|
|
4
4
|
declare function detectBin(): string;
|
|
5
|
-
|
|
5
|
+
declare function getDeployBin(bin: string): string;
|
|
6
|
+
export { getBinaryName, detectSkynetDirectory, detectWorkingDirectory, detectBin, getDeployBin };
|
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,11 @@ function detectBin() {
|
|
|
33
33
|
const wd = detectDirectory(process.argv[1], "package.json");
|
|
34
34
|
return process.argv[1].slice(wd.length + path.sep.length).replace(path.sep, "/");
|
|
35
35
|
}
|
|
36
|
+
function getDeployBin(bin) {
|
|
37
|
+
return bin.endsWith(".ts") ? `bun ${bin}` : bin;
|
|
38
|
+
}
|
|
36
39
|
export {
|
|
40
|
+
getDeployBin,
|
|
37
41
|
getBinaryName,
|
|
38
42
|
detectWorkingDirectory,
|
|
39
43
|
detectSkynetDirectory,
|
package/dist/deploy.js
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
// src/env.ts
|
|
2
|
+
function ensureAndGet(envName, defaultValue) {
|
|
3
|
+
return process.env[envName] || defaultValue;
|
|
4
|
+
}
|
|
5
|
+
function getEnvironment() {
|
|
6
|
+
return ensureAndGet("SKYNET_ENVIRONMENT", "dev");
|
|
7
|
+
}
|
|
8
|
+
function getEnvOrThrow(envName) {
|
|
9
|
+
if (!process.env[envName]) {
|
|
10
|
+
throw new Error(`Must set environment variable ${envName}`);
|
|
11
|
+
}
|
|
12
|
+
return process.env[envName];
|
|
13
|
+
}
|
|
14
|
+
function isProduction() {
|
|
15
|
+
return getEnvironment() === "prd";
|
|
16
|
+
}
|
|
17
|
+
function isDev() {
|
|
18
|
+
return getEnvironment() === "dev";
|
|
19
|
+
}
|
|
1
20
|
// src/selector.ts
|
|
2
21
|
function getSelectorDesc(selector) {
|
|
3
22
|
return Object.keys(selector).map((name) => {
|
|
@@ -25,8 +44,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
25
44
|
function normalizeSelectorValue(v) {
|
|
26
45
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
27
46
|
}
|
|
47
|
+
function includeSelectorValueInJobName(value) {
|
|
48
|
+
if (value === false)
|
|
49
|
+
return false;
|
|
50
|
+
if (value === undefined || value === null)
|
|
51
|
+
return false;
|
|
52
|
+
if (value === "")
|
|
53
|
+
return false;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
28
56
|
function getJobName(name, selectorFlags, mode) {
|
|
29
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
57
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
30
58
|
let jobName = name;
|
|
31
59
|
if (mode) {
|
|
32
60
|
jobName += `-${mode}`;
|
|
@@ -36,25 +64,6 @@ function getJobName(name, selectorFlags, mode) {
|
|
|
36
64
|
}
|
|
37
65
|
return jobName;
|
|
38
66
|
}
|
|
39
|
-
// src/env.ts
|
|
40
|
-
function ensureAndGet(envName, defaultValue) {
|
|
41
|
-
return process.env[envName] || defaultValue;
|
|
42
|
-
}
|
|
43
|
-
function getEnvironment() {
|
|
44
|
-
return ensureAndGet("SKYNET_ENVIRONMENT", "dev");
|
|
45
|
-
}
|
|
46
|
-
function getEnvOrThrow(envName) {
|
|
47
|
-
if (!process.env[envName]) {
|
|
48
|
-
throw new Error(`Must set environment variable ${envName}`);
|
|
49
|
-
}
|
|
50
|
-
return process.env[envName];
|
|
51
|
-
}
|
|
52
|
-
function isProduction() {
|
|
53
|
-
return getEnvironment() === "prd";
|
|
54
|
-
}
|
|
55
|
-
function isDev() {
|
|
56
|
-
return getEnvironment() === "dev";
|
|
57
|
-
}
|
|
58
67
|
// src/cli.ts
|
|
59
68
|
import path from "path";
|
|
60
69
|
import fs from "fs";
|
|
@@ -90,6 +99,9 @@ function detectBin() {
|
|
|
90
99
|
const wd = detectDirectory(process.argv[1], "package.json");
|
|
91
100
|
return process.argv[1].slice(wd.length + path.sep.length).replace(path.sep, "/");
|
|
92
101
|
}
|
|
102
|
+
function getDeployBin(bin) {
|
|
103
|
+
return bin.endsWith(".ts") ? `bun ${bin}` : bin;
|
|
104
|
+
}
|
|
93
105
|
// src/deploy.ts
|
|
94
106
|
import fs2 from "fs/promises";
|
|
95
107
|
import fso from "fs";
|
package/dist/dynamodb.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ declare function getRecordByKey<T>(tableName: string, keys: Record<string, unkno
|
|
|
13
13
|
declare function updateRecordByKey(tableName: string, idKey: Record<string, unknown>, fields: Record<string, unknown>, conditionExpressions?: null, verbose?: boolean): Promise<Record<string, any> | undefined>;
|
|
14
14
|
declare function batchDeleteRecords(tableName: string, keys: Record<string, unknown>[]): Promise<void>;
|
|
15
15
|
declare function deleteRecordsByHashKey(tableName: string, indexName: string | undefined, hashKeyValue: string, verbose?: boolean): Promise<number>;
|
|
16
|
-
|
|
16
|
+
declare function destroyDynamoDB(): void;
|
|
17
|
+
export { getDocClient, destroyDynamoDB, ScanCommand, BatchWriteCommand, GetCommand, PutCommand, QueryCommand, UpdateCommand, scanWholeTable, batchCreateRecords, createRecord, getRecordsByKey, getRecordByKey, updateRecordByKey, batchDeleteRecords, deleteRecordsByHashKey, };
|
package/dist/dynamodb.js
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
// src/util.ts
|
|
2
|
+
function range(startAt, endAt, step) {
|
|
3
|
+
const arr = [];
|
|
4
|
+
for (let i = startAt;i <= endAt; i += step) {
|
|
5
|
+
arr.push([i, Math.min(endAt, i + step - 1)]);
|
|
6
|
+
}
|
|
7
|
+
return arr;
|
|
8
|
+
}
|
|
9
|
+
function arrayGroup(array, groupSize) {
|
|
10
|
+
const groups = [];
|
|
11
|
+
for (let i = 0;i < array.length; i += groupSize) {
|
|
12
|
+
groups.push(array.slice(i, i + groupSize));
|
|
13
|
+
}
|
|
14
|
+
return groups;
|
|
15
|
+
}
|
|
16
|
+
function fillRange(start, end) {
|
|
17
|
+
const result = [];
|
|
18
|
+
for (let i = start;i <= end; i++) {
|
|
19
|
+
result.push(i);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
1
23
|
// src/object-hash.ts
|
|
2
24
|
import xh from "@node-rs/xxhash";
|
|
3
25
|
function getHash(obj) {
|
|
@@ -124,28 +146,6 @@ function memoize(func, options) {
|
|
|
124
146
|
}
|
|
125
147
|
return pMemoize(func, options);
|
|
126
148
|
}
|
|
127
|
-
// src/util.ts
|
|
128
|
-
function range(startAt, endAt, step) {
|
|
129
|
-
const arr = [];
|
|
130
|
-
for (let i = startAt;i <= endAt; i += step) {
|
|
131
|
-
arr.push([i, Math.min(endAt, i + step - 1)]);
|
|
132
|
-
}
|
|
133
|
-
return arr;
|
|
134
|
-
}
|
|
135
|
-
function arrayGroup(array, groupSize) {
|
|
136
|
-
const groups = [];
|
|
137
|
-
for (let i = 0;i < array.length; i += groupSize) {
|
|
138
|
-
groups.push(array.slice(i, i + groupSize));
|
|
139
|
-
}
|
|
140
|
-
return groups;
|
|
141
|
-
}
|
|
142
|
-
function fillRange(start, end) {
|
|
143
|
-
const result = [];
|
|
144
|
-
for (let i = start;i <= end; i++) {
|
|
145
|
-
result.push(i);
|
|
146
|
-
}
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
149
|
// src/dynamodb.ts
|
|
150
150
|
import {
|
|
151
151
|
DynamoDBDocumentClient,
|
|
@@ -460,12 +460,18 @@ async function deleteRecordsByHashKey(tableName, indexName, hashKeyValue, verbos
|
|
|
460
460
|
}
|
|
461
461
|
return totalDeleted;
|
|
462
462
|
}
|
|
463
|
+
function destroyDynamoDB() {
|
|
464
|
+
if (_dynamoDB) {
|
|
465
|
+
_dynamoDB.destroy();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
463
468
|
export {
|
|
464
469
|
updateRecordByKey,
|
|
465
470
|
scanWholeTable,
|
|
466
471
|
getRecordsByKey,
|
|
467
472
|
getRecordByKey,
|
|
468
473
|
getDocClient,
|
|
474
|
+
destroyDynamoDB,
|
|
469
475
|
deleteRecordsByHashKey,
|
|
470
476
|
createRecord,
|
|
471
477
|
batchDeleteRecords,
|
package/dist/email.d.ts
ADDED
package/dist/email.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/email.ts
|
|
2
|
+
import Mailgun from "mailgun.js";
|
|
3
|
+
import formData from "form-data";
|
|
4
|
+
async function sendEmail({ to, subject, html, from, text }) {
|
|
5
|
+
const apiKey = process.env.MAILGUN_API_KEY;
|
|
6
|
+
if (!apiKey) {
|
|
7
|
+
throw new Error("missing MAILGUN_API_KEY");
|
|
8
|
+
}
|
|
9
|
+
const domain = process.env.MAILGUN_DOMAIN;
|
|
10
|
+
if (!domain) {
|
|
11
|
+
throw new Error("missing MAILGUN_DOMAIN");
|
|
12
|
+
}
|
|
13
|
+
const mailgun = new Mailgun(formData);
|
|
14
|
+
const mg = mailgun.client({ username: "api", key: apiKey });
|
|
15
|
+
const recipients = Array.isArray(to) ? to : [to];
|
|
16
|
+
try {
|
|
17
|
+
await mg.messages.create(domain, {
|
|
18
|
+
from,
|
|
19
|
+
to: recipients,
|
|
20
|
+
subject,
|
|
21
|
+
...text ? { text } : {},
|
|
22
|
+
html
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("failed to send email", error);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
sendEmail
|
|
31
|
+
};
|
package/dist/indexer.js
CHANGED
|
@@ -1,41 +1,3 @@
|
|
|
1
|
-
// src/selector.ts
|
|
2
|
-
function getSelectorDesc(selector) {
|
|
3
|
-
return Object.keys(selector).map((name) => {
|
|
4
|
-
return ` --${name.padEnd(14)}${selector[name].desc || selector[name].description || ""}`;
|
|
5
|
-
}).join(`
|
|
6
|
-
`);
|
|
7
|
-
}
|
|
8
|
-
function getSelectorFlags(selector) {
|
|
9
|
-
return Object.keys(selector).reduce((acc, name) => {
|
|
10
|
-
const flag = {
|
|
11
|
-
type: selector[name].type || "string",
|
|
12
|
-
...selector[name]
|
|
13
|
-
};
|
|
14
|
-
if (!selector[name].optional && selector[name].isRequired !== false) {
|
|
15
|
-
flag.isRequired = true;
|
|
16
|
-
}
|
|
17
|
-
return { ...acc, [name]: flag };
|
|
18
|
-
}, {});
|
|
19
|
-
}
|
|
20
|
-
function toSelectorString(selectorFlags, delim = ",") {
|
|
21
|
-
return Object.keys(selectorFlags).sort().map((flag) => {
|
|
22
|
-
return `${flag}=${selectorFlags[flag]}`;
|
|
23
|
-
}).join(delim);
|
|
24
|
-
}
|
|
25
|
-
function normalizeSelectorValue(v) {
|
|
26
|
-
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
27
|
-
}
|
|
28
|
-
function getJobName(name, selectorFlags, mode) {
|
|
29
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((name2) => selectorFlags[name2]).join("-");
|
|
30
|
-
let jobName = name;
|
|
31
|
-
if (mode) {
|
|
32
|
-
jobName += `-${mode}`;
|
|
33
|
-
}
|
|
34
|
-
if (selectorNamePart.length > 0) {
|
|
35
|
-
jobName += `-${normalizeSelectorValue(selectorNamePart)}`;
|
|
36
|
-
}
|
|
37
|
-
return jobName;
|
|
38
|
-
}
|
|
39
1
|
// src/env.ts
|
|
40
2
|
function ensureAndGet(envName, defaultValue) {
|
|
41
3
|
return process.env[envName] || defaultValue;
|
|
@@ -55,63 +17,56 @@ function isProduction() {
|
|
|
55
17
|
function isDev() {
|
|
56
18
|
return getEnvironment() === "dev";
|
|
57
19
|
}
|
|
58
|
-
// src/
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (Array.isArray(o)) {
|
|
64
|
-
return `[${o.map(print).join(", ")}]`;
|
|
20
|
+
// src/util.ts
|
|
21
|
+
function range(startAt, endAt, step) {
|
|
22
|
+
const arr = [];
|
|
23
|
+
for (let i = startAt;i <= endAt; i += step) {
|
|
24
|
+
arr.push([i, Math.min(endAt, i + step - 1)]);
|
|
65
25
|
}
|
|
66
|
-
|
|
67
|
-
|
|
26
|
+
return arr;
|
|
27
|
+
}
|
|
28
|
+
function arrayGroup(array, groupSize) {
|
|
29
|
+
const groups = [];
|
|
30
|
+
for (let i = 0;i < array.length; i += groupSize) {
|
|
31
|
+
groups.push(array.slice(i, i + groupSize));
|
|
68
32
|
}
|
|
69
|
-
return
|
|
33
|
+
return groups;
|
|
70
34
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
for (let i =
|
|
74
|
-
|
|
35
|
+
function fillRange(start, end) {
|
|
36
|
+
const result = [];
|
|
37
|
+
for (let i = start;i <= end; i++) {
|
|
38
|
+
result.push(i);
|
|
75
39
|
}
|
|
76
|
-
return
|
|
40
|
+
return result;
|
|
77
41
|
}
|
|
78
|
-
|
|
79
|
-
|
|
42
|
+
// src/date.ts
|
|
43
|
+
var MS_IN_A_DAY = 3600 * 24 * 1000;
|
|
44
|
+
function getDateOnly(date) {
|
|
45
|
+
return new Date(date).toISOString().split("T")[0];
|
|
80
46
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
},
|
|
92
|
-
error: function(...args) {
|
|
93
|
-
if (true) {
|
|
94
|
-
console.error(`${timestamp()} ${getLine(args)}`);
|
|
95
|
-
}
|
|
47
|
+
function findDateAfter(date, n) {
|
|
48
|
+
const d = new Date(date);
|
|
49
|
+
const after = new Date(d.getTime() + MS_IN_A_DAY * n);
|
|
50
|
+
return getDateOnly(after);
|
|
51
|
+
}
|
|
52
|
+
function daysInRange(from, to) {
|
|
53
|
+
const fromTime = new Date(from).getTime();
|
|
54
|
+
const toTime = new Date(to).getTime();
|
|
55
|
+
if (fromTime > toTime) {
|
|
56
|
+
throw new Error(`range to date couldn't be earlier than range from date`);
|
|
96
57
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
console.log(`[${timestamp()}]`, ...args);
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
log: function(...args) {
|
|
105
|
-
if (true) {
|
|
106
|
-
console.log(`[${timestamp()}]`, ...args);
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
error: function(...args) {
|
|
110
|
-
if (true) {
|
|
111
|
-
console.error(`[${timestamp()}]`, ...args);
|
|
112
|
-
}
|
|
58
|
+
const daysBetween = Math.floor((toTime - fromTime) / MS_IN_A_DAY);
|
|
59
|
+
const dates = [getDateOnly(new Date(fromTime))];
|
|
60
|
+
for (let i = 1;i <= daysBetween; i += 1) {
|
|
61
|
+
dates.push(getDateOnly(new Date(fromTime + i * MS_IN_A_DAY)));
|
|
113
62
|
}
|
|
114
|
-
|
|
63
|
+
return dates;
|
|
64
|
+
}
|
|
65
|
+
function dateRange(from, to, step) {
|
|
66
|
+
const days = daysInRange(from, to);
|
|
67
|
+
const windows = arrayGroup(days, step);
|
|
68
|
+
return windows.map((w) => [w[0], w[w.length - 1]]);
|
|
69
|
+
}
|
|
115
70
|
// src/object-hash.ts
|
|
116
71
|
import xh from "@node-rs/xxhash";
|
|
117
72
|
function getHash(obj) {
|
|
@@ -238,28 +193,63 @@ function memoize(func, options) {
|
|
|
238
193
|
}
|
|
239
194
|
return pMemoize(func, options);
|
|
240
195
|
}
|
|
241
|
-
// src/
|
|
242
|
-
function
|
|
243
|
-
|
|
244
|
-
for (let i = startAt;i <= endAt; i += step) {
|
|
245
|
-
arr.push([i, Math.min(endAt, i + step - 1)]);
|
|
246
|
-
}
|
|
247
|
-
return arr;
|
|
196
|
+
// src/log.ts
|
|
197
|
+
function isObject(a) {
|
|
198
|
+
return !!a && a.constructor === Object;
|
|
248
199
|
}
|
|
249
|
-
function
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
groups.push(array.slice(i, i + groupSize));
|
|
200
|
+
function print(o) {
|
|
201
|
+
if (Array.isArray(o)) {
|
|
202
|
+
return `[${o.map(print).join(", ")}]`;
|
|
253
203
|
}
|
|
254
|
-
|
|
204
|
+
if (isObject(o)) {
|
|
205
|
+
return `{${Object.keys(o).map((k) => `${k}: ${o[k]}`).join(", ")}}`;
|
|
206
|
+
}
|
|
207
|
+
return `${o}`;
|
|
255
208
|
}
|
|
256
|
-
function
|
|
257
|
-
|
|
258
|
-
for (let i =
|
|
259
|
-
|
|
209
|
+
function getLine(params) {
|
|
210
|
+
let line = "";
|
|
211
|
+
for (let i = 0, l = params.length;i < l; i++) {
|
|
212
|
+
line += `${print(params[i])} `.replace(/\n/gm, "\t");
|
|
260
213
|
}
|
|
261
|
-
return
|
|
214
|
+
return line.trim();
|
|
262
215
|
}
|
|
216
|
+
function timestamp() {
|
|
217
|
+
return new Date().toISOString();
|
|
218
|
+
}
|
|
219
|
+
var inline = {
|
|
220
|
+
debug: function(...args) {
|
|
221
|
+
if (true) {
|
|
222
|
+
console.log(`${timestamp()} ${getLine(args)}`);
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
log: function(...args) {
|
|
226
|
+
if (true) {
|
|
227
|
+
console.log(`${timestamp()} ${getLine(args)}`);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
error: function(...args) {
|
|
231
|
+
if (true) {
|
|
232
|
+
console.error(`${timestamp()} ${getLine(args)}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
var logger = {
|
|
237
|
+
debug: function(...args) {
|
|
238
|
+
if (true) {
|
|
239
|
+
console.log(`[${timestamp()}]`, ...args);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
log: function(...args) {
|
|
243
|
+
if (true) {
|
|
244
|
+
console.log(`[${timestamp()}]`, ...args);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
error: function(...args) {
|
|
248
|
+
if (true) {
|
|
249
|
+
console.error(`[${timestamp()}]`, ...args);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
263
253
|
// src/dynamodb.ts
|
|
264
254
|
import {
|
|
265
255
|
DynamoDBDocumentClient,
|
|
@@ -574,6 +564,58 @@ async function deleteRecordsByHashKey(tableName, indexName, hashKeyValue, verbos
|
|
|
574
564
|
}
|
|
575
565
|
return totalDeleted;
|
|
576
566
|
}
|
|
567
|
+
function destroyDynamoDB() {
|
|
568
|
+
if (_dynamoDB) {
|
|
569
|
+
_dynamoDB.destroy();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// src/selector.ts
|
|
573
|
+
function getSelectorDesc(selector) {
|
|
574
|
+
return Object.keys(selector).map((name) => {
|
|
575
|
+
return ` --${name.padEnd(14)}${selector[name].desc || selector[name].description || ""}`;
|
|
576
|
+
}).join(`
|
|
577
|
+
`);
|
|
578
|
+
}
|
|
579
|
+
function getSelectorFlags(selector) {
|
|
580
|
+
return Object.keys(selector).reduce((acc, name) => {
|
|
581
|
+
const flag = {
|
|
582
|
+
type: selector[name].type || "string",
|
|
583
|
+
...selector[name]
|
|
584
|
+
};
|
|
585
|
+
if (!selector[name].optional && selector[name].isRequired !== false) {
|
|
586
|
+
flag.isRequired = true;
|
|
587
|
+
}
|
|
588
|
+
return { ...acc, [name]: flag };
|
|
589
|
+
}, {});
|
|
590
|
+
}
|
|
591
|
+
function toSelectorString(selectorFlags, delim = ",") {
|
|
592
|
+
return Object.keys(selectorFlags).sort().map((flag) => {
|
|
593
|
+
return `${flag}=${selectorFlags[flag]}`;
|
|
594
|
+
}).join(delim);
|
|
595
|
+
}
|
|
596
|
+
function normalizeSelectorValue(v) {
|
|
597
|
+
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
598
|
+
}
|
|
599
|
+
function includeSelectorValueInJobName(value) {
|
|
600
|
+
if (value === false)
|
|
601
|
+
return false;
|
|
602
|
+
if (value === undefined || value === null)
|
|
603
|
+
return false;
|
|
604
|
+
if (value === "")
|
|
605
|
+
return false;
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
608
|
+
function getJobName(name, selectorFlags, mode) {
|
|
609
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
610
|
+
let jobName = name;
|
|
611
|
+
if (mode) {
|
|
612
|
+
jobName += `-${mode}`;
|
|
613
|
+
}
|
|
614
|
+
if (selectorNamePart.length > 0) {
|
|
615
|
+
jobName += `-${normalizeSelectorValue(selectorNamePart)}`;
|
|
616
|
+
}
|
|
617
|
+
return jobName;
|
|
618
|
+
}
|
|
577
619
|
// src/cli.ts
|
|
578
620
|
import path from "path";
|
|
579
621
|
import fs from "fs";
|
|
@@ -609,33 +651,8 @@ function detectBin() {
|
|
|
609
651
|
const wd = detectDirectory(process.argv[1], "package.json");
|
|
610
652
|
return process.argv[1].slice(wd.length + path.sep.length).replace(path.sep, "/");
|
|
611
653
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
function getDateOnly(date) {
|
|
615
|
-
return new Date(date).toISOString().split("T")[0];
|
|
616
|
-
}
|
|
617
|
-
function findDateAfter(date, n) {
|
|
618
|
-
const d = new Date(date);
|
|
619
|
-
const after = new Date(d.getTime() + MS_IN_A_DAY * n);
|
|
620
|
-
return getDateOnly(after);
|
|
621
|
-
}
|
|
622
|
-
function daysInRange(from, to) {
|
|
623
|
-
const fromTime = new Date(from).getTime();
|
|
624
|
-
const toTime = new Date(to).getTime();
|
|
625
|
-
if (fromTime > toTime) {
|
|
626
|
-
throw new Error(`range to date couldn't be earlier than range from date`);
|
|
627
|
-
}
|
|
628
|
-
const daysBetween = Math.floor((toTime - fromTime) / MS_IN_A_DAY);
|
|
629
|
-
const dates = [getDateOnly(new Date(fromTime))];
|
|
630
|
-
for (let i = 1;i <= daysBetween; i += 1) {
|
|
631
|
-
dates.push(getDateOnly(new Date(fromTime + i * MS_IN_A_DAY)));
|
|
632
|
-
}
|
|
633
|
-
return dates;
|
|
634
|
-
}
|
|
635
|
-
function dateRange(from, to, step) {
|
|
636
|
-
const days = daysInRange(from, to);
|
|
637
|
-
const windows = arrayGroup(days, step);
|
|
638
|
-
return windows.map((w) => [w[0], w[w.length - 1]]);
|
|
654
|
+
function getDeployBin(bin) {
|
|
655
|
+
return bin.endsWith(".ts") ? `bun ${bin}` : bin;
|
|
639
656
|
}
|
|
640
657
|
// src/indexer.ts
|
|
641
658
|
import meow from "meow";
|
|
@@ -740,6 +757,7 @@ function createModeIndexerApp({
|
|
|
740
757
|
inline.log(`[MODE INDEXER] mode=${mode}, env=${getEnvironment()}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
741
758
|
if (mode === "reset") {
|
|
742
759
|
await runReset(selectorFlags);
|
|
760
|
+
process.exit(0);
|
|
743
761
|
} else if (mode === "rebuild") {
|
|
744
762
|
const rebuildFrom = from || await finalState.getMinId(selectorFlags);
|
|
745
763
|
const rebuildTo = to || await finalState.getMaxId(selectorFlags);
|
|
@@ -851,6 +869,7 @@ function createModeIndexerApp({
|
|
|
851
869
|
}
|
|
852
870
|
}
|
|
853
871
|
inline.log(`[MODE INDEXER] validated ${offsetRange(from, to)} ${finalState.type} successfully in ${Date.now() - startTime}ms`);
|
|
872
|
+
process.exit(0);
|
|
854
873
|
}
|
|
855
874
|
async function execBuild(selectorFlags, from, to, verbose, shouldSaveState = false) {
|
|
856
875
|
let failedIds = [];
|
|
@@ -926,7 +945,7 @@ function createModeIndexerApp({
|
|
|
926
945
|
const startTime = Date.now();
|
|
927
946
|
if (to < from) {
|
|
928
947
|
inline.log(`[MODE INDEXER] skip delta, there're no more items need to be processed, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}`);
|
|
929
|
-
|
|
948
|
+
process.exit(0);
|
|
930
949
|
}
|
|
931
950
|
inline.log(`[MODE INDEXER] starting delta, from=${from}, to=${to}, ${toSelectorString(selectorFlags, ", ")}, batchSize=${buildBatchSize}, concurrency=${buildConcurrency}`);
|
|
932
951
|
try {
|
|
@@ -1025,6 +1044,8 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1025
1044
|
} catch (err) {
|
|
1026
1045
|
inline.error(err);
|
|
1027
1046
|
process.exit(1);
|
|
1047
|
+
} finally {
|
|
1048
|
+
destroyDynamoDB();
|
|
1028
1049
|
}
|
|
1029
1050
|
}
|
|
1030
1051
|
return { run };
|
|
@@ -1084,6 +1105,7 @@ ${selector ? getSelectorDesc(selector) : ""}
|
|
|
1084
1105
|
throw new Error(`[INDEXER] Build failed due to critical errors`);
|
|
1085
1106
|
}
|
|
1086
1107
|
inline.log(`[INDEXER] build successfully in ${Date.now() - startTime}ms`);
|
|
1108
|
+
process.exit(0);
|
|
1087
1109
|
}
|
|
1088
1110
|
return runBuild(cli.flags).catch((err) => {
|
|
1089
1111
|
inline.error(err);
|
package/dist/selector.js
CHANGED
|
@@ -25,8 +25,17 @@ function toSelectorString(selectorFlags, delim = ",") {
|
|
|
25
25
|
function normalizeSelectorValue(v) {
|
|
26
26
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
27
27
|
}
|
|
28
|
+
function includeSelectorValueInJobName(value) {
|
|
29
|
+
if (value === false)
|
|
30
|
+
return false;
|
|
31
|
+
if (value === undefined || value === null)
|
|
32
|
+
return false;
|
|
33
|
+
if (value === "")
|
|
34
|
+
return false;
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
28
37
|
function getJobName(name, selectorFlags, mode) {
|
|
29
|
-
const selectorNamePart = Object.keys(selectorFlags).sort().map((
|
|
38
|
+
const selectorNamePart = Object.keys(selectorFlags).sort().map((key) => selectorFlags[key]).filter(includeSelectorValueInJobName).map((value) => String(value)).join("-");
|
|
30
39
|
let jobName = name;
|
|
31
40
|
if (mode) {
|
|
32
41
|
jobName += `-${mode}`;
|
package/examples/api.ts
CHANGED
|
File without changes
|
package/examples/indexer.ts
CHANGED
|
File without changes
|
package/examples/mode-indexer.ts
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/src/selector.ts
CHANGED
|
@@ -49,10 +49,20 @@ function normalizeSelectorValue(v: string) {
|
|
|
49
49
|
return v.replace(/[^A-Za-z0-9]+/g, "-");
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/** Values that should not affect Nomad job names (unset / default-off selectors). */
|
|
53
|
+
function includeSelectorValueInJobName(value: unknown): boolean {
|
|
54
|
+
if (value === false) return false;
|
|
55
|
+
if (value === undefined || value === null) return false;
|
|
56
|
+
if (value === "") return false;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
function getJobName<TSelector extends Selector>(name: string, selectorFlags: SelectorFlags<TSelector>, mode?: string) {
|
|
53
61
|
const selectorNamePart = Object.keys(selectorFlags)
|
|
54
62
|
.sort()
|
|
55
|
-
.map((
|
|
63
|
+
.map((key) => selectorFlags[key])
|
|
64
|
+
.filter(includeSelectorValueInJobName)
|
|
65
|
+
.map((value) => String(value))
|
|
56
66
|
.join("-");
|
|
57
67
|
|
|
58
68
|
let jobName = name;
|