poe-code 3.0.307 → 3.0.309
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/dist/index.js +140 -15
- package/dist/index.js.map +3 -3
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/process-launcher/dist/health/health-check.js +12 -0
- package/packages/process-launcher/dist/launcher.js +120 -4
- package/packages/process-launcher/dist/process-id.js +15 -1
- package/packages/process-launcher/dist/state/state-store.d.ts +2 -1
- package/packages/process-launcher/dist/state/state-store.js +18 -6
package/dist/index.js
CHANGED
|
@@ -74873,10 +74873,19 @@ var init_path_safety3 = __esm({
|
|
|
74873
74873
|
// packages/process-launcher/src/process-id.ts
|
|
74874
74874
|
import path104 from "node:path";
|
|
74875
74875
|
function assertValidManagedProcessId(id) {
|
|
74876
|
-
if (id.length === 0 || id === "." || id === ".." || path104.basename(id) !== id) {
|
|
74876
|
+
if (id.length === 0 || id !== id.trim() || id === "." || id === ".." || path104.basename(id) !== id || hasControlCharacter(id)) {
|
|
74877
74877
|
throw new Error(`Invalid managed process id: ${id}`);
|
|
74878
74878
|
}
|
|
74879
74879
|
}
|
|
74880
|
+
function hasControlCharacter(value) {
|
|
74881
|
+
for (const char of value) {
|
|
74882
|
+
const code = char.charCodeAt(0);
|
|
74883
|
+
if (code <= 31 || code === 127) {
|
|
74884
|
+
return true;
|
|
74885
|
+
}
|
|
74886
|
+
}
|
|
74887
|
+
return false;
|
|
74888
|
+
}
|
|
74880
74889
|
var init_process_id = __esm({
|
|
74881
74890
|
"packages/process-launcher/src/process-id.ts"() {
|
|
74882
74891
|
"use strict";
|
|
@@ -74958,10 +74967,7 @@ function createStateStore(stateDir, fs28 = nodeFs7) {
|
|
|
74958
74967
|
await assertPathHasNoSymbolicLinks3(fs28, statePath);
|
|
74959
74968
|
const content = await fs28.readFile(statePath, "utf8");
|
|
74960
74969
|
const parsed = JSON.parse(content);
|
|
74961
|
-
|
|
74962
|
-
throw new Error(`Invalid process state document: ${id}`);
|
|
74963
|
-
}
|
|
74964
|
-
return parsed;
|
|
74970
|
+
return assertValidProcessStateDocument(parsed, id);
|
|
74965
74971
|
} catch (error3) {
|
|
74966
74972
|
if (isNotFoundError7(error3)) {
|
|
74967
74973
|
return null;
|
|
@@ -75045,12 +75051,24 @@ function createStateStore(stateDir, fs28 = nodeFs7) {
|
|
|
75045
75051
|
}
|
|
75046
75052
|
return { read, write: write2, list, remove: remove2 };
|
|
75047
75053
|
}
|
|
75054
|
+
function assertValidProcessStateDocument(value, id) {
|
|
75055
|
+
if (!isProcessState(value, id)) {
|
|
75056
|
+
throw new Error(`Invalid process state document: ${id}`);
|
|
75057
|
+
}
|
|
75058
|
+
return value;
|
|
75059
|
+
}
|
|
75048
75060
|
function isProcessState(value, id) {
|
|
75049
75061
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
75050
75062
|
return false;
|
|
75051
75063
|
}
|
|
75052
75064
|
const state = value;
|
|
75053
|
-
return state.id === id && (state.pid === null || typeof state.pid === "number") && (state.status === "running" || state.status === "stopped" || state.status === "crashed" || state.status === "restarting") && (state.runtime === "host" || state.runtime === "docker") &&
|
|
75065
|
+
return state.id === id && (state.pid === null || typeof state.pid === "number") && (state.status === "running" || state.status === "stopped" || state.status === "crashed" || state.status === "restarting") && (state.runtime === "host" || state.runtime === "docker") && isPositiveSafeIntegerOrNull(state.pid) && isNonNegativeSafeInteger(state.restartCount) && (state.lastExitCode === null || isNonNegativeSafeInteger(state.lastExitCode)) && (state.lastStartedAt === null || typeof state.lastStartedAt === "string") && (state.lastStoppedAt === null || typeof state.lastStoppedAt === "string") && typeof state.command === "string" && Array.isArray(state.args) && state.args.every((argument) => typeof argument === "string");
|
|
75066
|
+
}
|
|
75067
|
+
function isPositiveSafeIntegerOrNull(value) {
|
|
75068
|
+
return value === null || typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
75069
|
+
}
|
|
75070
|
+
function isNonNegativeSafeInteger(value) {
|
|
75071
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
75054
75072
|
}
|
|
75055
75073
|
var init_state_store = __esm({
|
|
75056
75074
|
"packages/process-launcher/src/state/state-store.ts"() {
|
|
@@ -75277,8 +75295,10 @@ import net from "node:net";
|
|
|
75277
75295
|
async function waitForReady(check, options) {
|
|
75278
75296
|
assertValidTimeout(options.timeoutMs, "readiness timeout");
|
|
75279
75297
|
if (check.kind === "log-pattern") {
|
|
75298
|
+
assertValidLogPattern(check.pattern);
|
|
75280
75299
|
return waitForLogPattern(check.pattern, options);
|
|
75281
75300
|
}
|
|
75301
|
+
assertValidTcpPort(check.port);
|
|
75282
75302
|
return waitForTcp(check, options);
|
|
75283
75303
|
}
|
|
75284
75304
|
function waitForLogPattern(pattern, options) {
|
|
@@ -75399,6 +75419,16 @@ function assertValidTimeout(value, description) {
|
|
|
75399
75419
|
throw new Error(`Invalid ${description}: ${value}`);
|
|
75400
75420
|
}
|
|
75401
75421
|
}
|
|
75422
|
+
function assertValidLogPattern(value) {
|
|
75423
|
+
if (value.trim().length === 0) {
|
|
75424
|
+
throw new Error("Invalid log pattern readiness check: pattern must not be blank.");
|
|
75425
|
+
}
|
|
75426
|
+
}
|
|
75427
|
+
function assertValidTcpPort(value) {
|
|
75428
|
+
if (!Number.isSafeInteger(value) || value <= 0 || value > 65535) {
|
|
75429
|
+
throw new Error(`Invalid TCP readiness port: ${value}`);
|
|
75430
|
+
}
|
|
75431
|
+
}
|
|
75402
75432
|
var init_health_check = __esm({
|
|
75403
75433
|
"packages/process-launcher/src/health/health-check.ts"() {
|
|
75404
75434
|
"use strict";
|
|
@@ -76019,6 +76049,7 @@ import path108 from "node:path";
|
|
|
76019
76049
|
import { TextDecoder as TextDecoder2 } from "node:util";
|
|
76020
76050
|
async function startManagedProcess(options) {
|
|
76021
76051
|
assertOptionalFiniteDuration(options.startupTimeoutMs, "startup timeout");
|
|
76052
|
+
assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
|
|
76022
76053
|
const fs28 = options.fs ?? defaultFs3();
|
|
76023
76054
|
const spec10 = normalizeSpec(options.spec);
|
|
76024
76055
|
const existing = await readManagedProcess({
|
|
@@ -76060,6 +76091,8 @@ async function startManagedProcess(options) {
|
|
|
76060
76091
|
}
|
|
76061
76092
|
}
|
|
76062
76093
|
async function stopManagedProcess(options) {
|
|
76094
|
+
assertOptionalFiniteDuration(options.stopTimeoutMs, "stop timeout");
|
|
76095
|
+
assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
|
|
76063
76096
|
const fs28 = options.fs ?? defaultFs3();
|
|
76064
76097
|
const record = await readManagedProcess({
|
|
76065
76098
|
baseDir: options.baseDir,
|
|
@@ -76184,7 +76217,16 @@ async function* followManagedLogs(options) {
|
|
|
76184
76217
|
throw new Error(`Invalid managed log poll interval: ${pollIntervalMs}`);
|
|
76185
76218
|
}
|
|
76186
76219
|
const cursor2 = createFollowLogCursor();
|
|
76187
|
-
await
|
|
76220
|
+
const initialLines = options.lines === void 0 ? [] : await readInitialFollowLogWindow(fs28, options.baseDir, options.id, stream, options.lines, cursor2);
|
|
76221
|
+
if (options.lines === void 0) {
|
|
76222
|
+
await primeFollowCursor(fs28, options.baseDir, options.id, stream, cursor2);
|
|
76223
|
+
}
|
|
76224
|
+
for (const line of initialLines) {
|
|
76225
|
+
if (options.signal?.aborted) {
|
|
76226
|
+
return;
|
|
76227
|
+
}
|
|
76228
|
+
yield line;
|
|
76229
|
+
}
|
|
76188
76230
|
while (!options.signal?.aborted) {
|
|
76189
76231
|
await sleep4(pollIntervalMs);
|
|
76190
76232
|
if (options.signal?.aborted) {
|
|
@@ -76204,6 +76246,30 @@ function createFollowLogCursor() {
|
|
|
76204
76246
|
remainder: ""
|
|
76205
76247
|
};
|
|
76206
76248
|
}
|
|
76249
|
+
async function readInitialFollowLogWindow(fs28, baseDir, id, stream, lines, cursor2) {
|
|
76250
|
+
assertValidLogLineCount(lines);
|
|
76251
|
+
const stat33 = await statFollowedLog(fs28, baseDir, id, stream);
|
|
76252
|
+
resetFollowCursor(cursor2, stat33?.fileId ?? null);
|
|
76253
|
+
if (stat33 === null) {
|
|
76254
|
+
return [];
|
|
76255
|
+
}
|
|
76256
|
+
const bytes = await readFollowedLogBytes(
|
|
76257
|
+
fs28,
|
|
76258
|
+
resolveCurrentLogPath(baseDir, id, stream),
|
|
76259
|
+
0
|
|
76260
|
+
);
|
|
76261
|
+
cursor2.offset = bytes.byteLength;
|
|
76262
|
+
const allLines = consumeFollowedLogBytes(cursor2, bytes);
|
|
76263
|
+
if (lines === 0) {
|
|
76264
|
+
return [];
|
|
76265
|
+
}
|
|
76266
|
+
return allLines.slice(-lines);
|
|
76267
|
+
}
|
|
76268
|
+
function assertValidLogLineCount(lines) {
|
|
76269
|
+
if (!Number.isFinite(lines) || !Number.isInteger(lines) || lines < 0) {
|
|
76270
|
+
throw new Error("lines must be a finite non-negative integer");
|
|
76271
|
+
}
|
|
76272
|
+
}
|
|
76207
76273
|
async function primeFollowCursor(fs28, baseDir, id, stream, cursor2) {
|
|
76208
76274
|
const stat33 = await statFollowedLog(fs28, baseDir, id, stream);
|
|
76209
76275
|
resetFollowCursor(cursor2, stat33?.fileId ?? null);
|
|
@@ -76320,6 +76386,7 @@ async function runManagedProcess(options) {
|
|
|
76320
76386
|
if (options.signal?.aborted) {
|
|
76321
76387
|
return;
|
|
76322
76388
|
}
|
|
76389
|
+
assertOptionalFiniteDuration(options.pollIntervalMs, "poll interval");
|
|
76323
76390
|
const fs28 = options.fs ?? defaultFs3();
|
|
76324
76391
|
await assertProcessDirectorySafe(fs28, options.baseDir, options.id);
|
|
76325
76392
|
await assertPathNotSymbolicLink(fs28, resolveLogDir2(options.baseDir, options.id));
|
|
@@ -76527,13 +76594,71 @@ async function readSpec(fs28, baseDir, id) {
|
|
|
76527
76594
|
if (!isRecord31(spec10) || typeof spec10.id !== "string" || spec10.id !== id) {
|
|
76528
76595
|
throw new Error(`Invalid managed process specification for "${id}".`);
|
|
76529
76596
|
}
|
|
76530
|
-
return spec10;
|
|
76597
|
+
return assertValidProcessSpec(spec10, id);
|
|
76598
|
+
}
|
|
76599
|
+
function assertValidProcessSpec(value, id) {
|
|
76600
|
+
if (value.id !== id || !isNonEmptyString4(value.command) || !isOptionalStringArray(value.args) || !isOptionalString(value.cwd) || !isOptionalStringRecord(value.env) || !isRestartPolicy(value.restart) || !isOptionalNonNegativeSafeInteger(value.maxRestarts) || !isOptionalFiniteDurationValue(value.backoffMs) || !isOptionalFiniteDurationValue(value.maxBackoffMs) || !isOptionalPositiveSafeInteger(value.logRetainCount) || !isOptionalReadyCheck(value.readyCheck) || !isOptionalRecord(value.docker)) {
|
|
76601
|
+
throw new Error(`Invalid managed process specification for "${id}".`);
|
|
76602
|
+
}
|
|
76603
|
+
return value;
|
|
76604
|
+
}
|
|
76605
|
+
function isNonEmptyString4(value) {
|
|
76606
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
76607
|
+
}
|
|
76608
|
+
function isOptionalString(value) {
|
|
76609
|
+
return value === void 0 || typeof value === "string";
|
|
76610
|
+
}
|
|
76611
|
+
function isOptionalStringArray(value) {
|
|
76612
|
+
return value === void 0 || Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
76613
|
+
}
|
|
76614
|
+
function isOptionalStringRecord(value) {
|
|
76615
|
+
if (value === void 0) {
|
|
76616
|
+
return true;
|
|
76617
|
+
}
|
|
76618
|
+
if (!isPlainRecord4(value)) {
|
|
76619
|
+
return false;
|
|
76620
|
+
}
|
|
76621
|
+
return Object.values(value).every((entry) => typeof entry === "string");
|
|
76622
|
+
}
|
|
76623
|
+
function isRestartPolicy(value) {
|
|
76624
|
+
return value === "never" || value === "on-failure" || value === "always";
|
|
76625
|
+
}
|
|
76626
|
+
function isOptionalNonNegativeSafeInteger(value) {
|
|
76627
|
+
return value === void 0 || typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
76628
|
+
}
|
|
76629
|
+
function isOptionalPositiveSafeInteger(value) {
|
|
76630
|
+
return value === void 0 || typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
76631
|
+
}
|
|
76632
|
+
function isOptionalFiniteDurationValue(value) {
|
|
76633
|
+
return value === void 0 || typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
76634
|
+
}
|
|
76635
|
+
function isOptionalReadyCheck(value) {
|
|
76636
|
+
if (value === void 0) {
|
|
76637
|
+
return true;
|
|
76638
|
+
}
|
|
76639
|
+
if (!isPlainRecord4(value)) {
|
|
76640
|
+
return false;
|
|
76641
|
+
}
|
|
76642
|
+
if (value.kind === "log-pattern") {
|
|
76643
|
+
return isNonEmptyString4(value.pattern);
|
|
76644
|
+
}
|
|
76645
|
+
if (value.kind === "tcp") {
|
|
76646
|
+
return typeof value.port === "number" && Number.isSafeInteger(value.port) && value.port > 0 && value.port <= 65535 && isOptionalString(value.host) && isOptionalFiniteDurationValue(value.timeoutMs);
|
|
76647
|
+
}
|
|
76648
|
+
return false;
|
|
76649
|
+
}
|
|
76650
|
+
function isOptionalRecord(value) {
|
|
76651
|
+
return value === void 0 || isPlainRecord4(value);
|
|
76652
|
+
}
|
|
76653
|
+
function isPlainRecord4(value) {
|
|
76654
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
76531
76655
|
}
|
|
76532
76656
|
async function writeSpec(fs28, baseDir, spec10) {
|
|
76533
76657
|
await writeJsonFile(fs28, resolveSpecPath(baseDir, spec10.id), spec10);
|
|
76534
76658
|
}
|
|
76535
76659
|
async function readState(fs28, baseDir, id) {
|
|
76536
|
-
|
|
76660
|
+
const state = await readJsonFile(fs28, resolveStatePath(baseDir, id));
|
|
76661
|
+
return state === null ? null : assertValidProcessStateDocument(state, id);
|
|
76537
76662
|
}
|
|
76538
76663
|
async function writeState(fs28, baseDir, state) {
|
|
76539
76664
|
await writeJsonFile(fs28, resolveStatePath(baseDir, state.id), state);
|
|
@@ -90312,7 +90437,7 @@ function isHttpErrorLike(error3) {
|
|
|
90312
90437
|
function hasTypedOptionalField(value, field, type) {
|
|
90313
90438
|
return !hasOwnProperty11(value, field) || typeof value[field] === type;
|
|
90314
90439
|
}
|
|
90315
|
-
function
|
|
90440
|
+
function isNonEmptyString5(value) {
|
|
90316
90441
|
return typeof value === "string" && value.trim().length > 0;
|
|
90317
90442
|
}
|
|
90318
90443
|
function isProblemDetailsLike(body) {
|
|
@@ -90365,7 +90490,7 @@ function hasOwnProperty11(value, name) {
|
|
|
90365
90490
|
return Object.prototype.hasOwnProperty.call(value, name);
|
|
90366
90491
|
}
|
|
90367
90492
|
function hasOwnNonEmptyString(value, name) {
|
|
90368
|
-
return hasOwnProperty11(value, name) &&
|
|
90493
|
+
return hasOwnProperty11(value, name) && isNonEmptyString5(value[name]);
|
|
90369
90494
|
}
|
|
90370
90495
|
function styleHttpErrorLine(value, style) {
|
|
90371
90496
|
return process.stdout.isTTY !== true ? value : style(value);
|
|
@@ -136215,7 +136340,7 @@ function resolveStringValues2(value) {
|
|
|
136215
136340
|
resolved[key2] = entry.map(
|
|
136216
136341
|
(item) => typeof item === "string" ? resolveStringValue2(item) : item
|
|
136217
136342
|
);
|
|
136218
|
-
} else if (
|
|
136343
|
+
} else if (isPlainRecord5(entry)) {
|
|
136219
136344
|
resolved[key2] = resolveStringValues2(entry);
|
|
136220
136345
|
} else {
|
|
136221
136346
|
resolved[key2] = entry;
|
|
@@ -136234,7 +136359,7 @@ function resolveWorkflowRelativePath(value, workflowPath) {
|
|
|
136234
136359
|
return path173.isAbsolute(value) ? value : path173.resolve(path173.dirname(workflowPath), value);
|
|
136235
136360
|
}
|
|
136236
136361
|
function asRecord6(value) {
|
|
136237
|
-
return
|
|
136362
|
+
return isPlainRecord5(value) ? value : void 0;
|
|
136238
136363
|
}
|
|
136239
136364
|
function hasOwnEntry4(record, key2) {
|
|
136240
136365
|
return Object.prototype.hasOwnProperty.call(record, key2);
|
|
@@ -136242,7 +136367,7 @@ function hasOwnEntry4(record, key2) {
|
|
|
136242
136367
|
function getOwnEntry37(record, key2) {
|
|
136243
136368
|
return hasOwnEntry4(record, key2) ? record[key2] : void 0;
|
|
136244
136369
|
}
|
|
136245
|
-
function
|
|
136370
|
+
function isPlainRecord5(value) {
|
|
136246
136371
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
136247
136372
|
}
|
|
136248
136373
|
function isFileNotFoundError2(error3) {
|
|
@@ -137096,7 +137221,7 @@ var init_package2 = __esm({
|
|
|
137096
137221
|
"package.json"() {
|
|
137097
137222
|
package_default2 = {
|
|
137098
137223
|
name: "poe-code",
|
|
137099
|
-
version: "3.0.
|
|
137224
|
+
version: "3.0.309",
|
|
137100
137225
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
137101
137226
|
type: "module",
|
|
137102
137227
|
main: "./dist/index.js",
|