@akterjs/cli 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +47 -2
- package/dist/Argument-D81dqizB.mjs +57 -0
- package/dist/Array-B4kuTQeW.mjs +2323 -0
- package/dist/Boolean-kILIvmhE.mjs +26 -0
- package/dist/ChildProcess-BCIwxPGc.mjs +577 -0
- package/dist/CliError-Cf5xqkkj.mjs +633 -0
- package/dist/Command-Dzq9KM-h.mjs +5135 -0
- package/dist/Config-B6OND9WR.mjs +854 -0
- package/dist/Console-BKHUkH6a.mjs +141 -0
- package/dist/Data-CeCULr0-.mjs +251 -0
- package/dist/Digest-CBd3uv5B.mjs +348 -0
- package/dist/Duration-EH9Vy4U6.mjs +791 -0
- package/dist/Effect-CKFpqbmw.mjs +12911 -0
- package/dist/FileSystem-4pPcEb_i.mjs +1366 -0
- package/dist/HttpClientError-BUeMWx70.mjs +303 -0
- package/dist/HttpClientResponse-D5ZKICVV.mjs +855 -0
- package/dist/Match-CGPLZYrV.mjs +434 -0
- package/dist/MutableHashMap-f8nW8AJR.mjs +376 -0
- package/dist/MutableHashSet-_HI572Ya.mjs +155 -0
- package/dist/MutableRef-D4Qv592C.mjs +107 -0
- package/dist/Number-BvkRkfc-.mjs +137 -0
- package/dist/Option-DkxSnBhp.mjs +3967 -0
- package/dist/Order-C1JC991I.mjs +481 -0
- package/dist/Path-Djdv_eF5.mjs +130 -0
- package/dist/Queue-CO5UQ6os.mjs +1394 -0
- package/dist/Redacted-RkJrG5Me.mjs +160 -0
- package/dist/Ref-BIPOxJNH.mjs +267 -0
- package/dist/Runtime-BInIAwK3.mjs +297 -0
- package/dist/Schema-MiKt5K1v.mjs +10999 -0
- package/dist/SecureRandom-B_U4ysO3.mjs +279 -0
- package/dist/Semaphore-DOVJ4ZGS.mjs +177 -0
- package/dist/Stdio-KylmOBX_.mjs +74 -0
- package/dist/Stream-bK9QIETN.mjs +4012 -0
- package/dist/String-q5dcsVe4.mjs +351 -0
- package/dist/TerminalCapabilities-w_44MAca.mjs +1769 -0
- package/dist/WebCrypto-ZI_GNVlw.mjs +33 -0
- package/dist/actor-call.service-CGM_vD9u.mjs +1269 -0
- package/dist/actor-client.adapter-Coem7gF1.mjs +3691 -0
- package/dist/akter-program.config-C4cXx4Fr.mjs +7034 -0
- package/dist/akter.cli.mjs +5 -0
- package/dist/app-cli.config.mjs +49 -0
- package/dist/app-entry.pure.mjs +31 -0
- package/dist/archive/akter-archive.schema.mjs +65 -0
- package/dist/archive/akter-archive.service.mjs +309 -0
- package/dist/archive/archive-cli.config.mjs +45 -0
- package/dist/archive/archive-invalid.errors.mjs +5 -0
- package/dist/archive/archived-lineage.pure.mjs +13 -0
- package/dist/archive/tar.pure.mjs +291 -0
- package/dist/archive/zstd.adapter.mjs +46 -0
- package/dist/bench/bench-report.pure.mjs +120 -0
- package/dist/bench/bench-runner.pure.mjs +89 -0
- package/dist/bench/bench.service.mjs +301 -0
- package/dist/cli-runtime.layer-BqK2mmVL.mjs +1191 -0
- package/dist/cli-runtime.layer.mjs +1 -0
- package/dist/cloud-client.adapter-Cy1BjDbG.mjs +3186 -0
- package/dist/cloud-client.adapter-DOVMoYAj.mjs +304 -0
- package/dist/command/akter-commands.config.mjs +32 -0
- package/dist/command/akter-program.config.mjs +1 -0
- package/dist/credentials/credentials.service.mjs +226 -0
- package/dist/credentials/keychain.adapter.mjs +92 -0
- package/dist/credentials/login.config.mjs +251 -0
- package/dist/deploy/auth/api-attempt.service.mjs +30 -0
- package/dist/deploy/auth/token-refresh.errors.mjs +4 -0
- package/dist/deploy/build-bundle.adapter.mjs +133 -0
- package/dist/deploy/build-manifest.pure.mjs +44 -0
- package/dist/deploy/cloud-client.adapter.mjs +1 -0
- package/dist/deploy/cloud-url.pure.mjs +17 -0
- package/dist/deploy/deploy-failed.errors.mjs +17 -0
- package/dist/deploy/deploy.service.mjs +156 -0
- package/dist/deploy/request-failure.pure.mjs +87 -0
- package/dist/dev-runner.pure.mjs +30 -0
- package/dist/docs/doc-topics.pure.mjs +21 -0
- package/dist/docs/docs.config.mjs +1 -0
- package/dist/docs.config-_21Xi6HU.mjs +190 -0
- package/dist/export/actor-export.service.mjs +267 -0
- package/dist/export/export-failed.errors.mjs +4 -0
- package/dist/export/export-failure.pure.mjs +18 -0
- package/dist/export/ordered-lines.pure.mjs +43 -0
- package/dist/export/ranged-download.pure.mjs +66 -0
- package/dist/export/snapshot-download.pure.mjs +86 -0
- package/dist/history-runner.pure.mjs +186 -0
- package/dist/history-since.pure.mjs +17 -0
- package/dist/hosted-runtime.layer-Cx3IPsEd.mjs +16358 -0
- package/dist/local/environment-cli.config.mjs +90 -0
- package/dist/local/environment-runner.pure.mjs +75 -0
- package/dist/local/local-cli.config.mjs +159 -0
- package/dist/logs/log-follow.config.mjs +21 -0
- package/dist/logs/log-follow.service.mjs +87 -0
- package/dist/logs/log-lines.pure.mjs +44 -0
- package/dist/migrate-runner.pure.mjs +28 -0
- package/dist/operation-input.pure-CS9iUhqK.mjs +1383 -0
- package/dist/operation-registry.pure-DVC8EDgj.mjs +283 -0
- package/dist/registry/actor-call.service.mjs +1 -0
- package/dist/registry/actor-commands.config.mjs +127 -0
- package/dist/registry/actor-refusal.pure.mjs +34 -0
- package/dist/registry/approval.service.mjs +80 -0
- package/dist/registry/cloud-commands.config.mjs +151 -0
- package/dist/registry/cloud-served.pure.mjs +31 -0
- package/dist/registry/operation-call.service.mjs +262 -0
- package/dist/registry/operation-input.pure.mjs +1 -0
- package/dist/registry/operation-output.pure.mjs +91 -0
- package/dist/registry/served-command.config.mjs +57 -0
- package/dist/runner-exited.errors.mjs +10 -0
- package/dist/terminal/cli-exit.errors.mjs +38 -0
- package/dist/terminal/cli-failure.pure.mjs +31 -0
- package/dist/terminal/confirm.adapter.mjs +27 -0
- package/package.json +61 -3
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { An as spaced, Dn as max, En as exponential, On as min, Tn as during, ti as isTimeoutError } from "../Effect-CKFpqbmw.mjs";
|
|
2
|
+
import { i as tag, n as exhaustive, s as value } from "../Match-CGPLZYrV.mjs";
|
|
3
|
+
import { S as none, f as getOrElse, in as isNumber, qt as hasProperty, r as exists, un as isTagged, w as some, x as match } from "../Option-DkxSnBhp.mjs";
|
|
4
|
+
import { X as Unknown, Xt as isSchemaError, ct as encodeOption, mt as is, pt as fromJsonString } from "../Schema-MiKt5K1v.mjs";
|
|
5
|
+
import { f as replaceAll, o as isEmpty, p as slice, v as trim } from "../String-q5dcsVe4.mjs";
|
|
6
|
+
import { l as isHttpClientError } from "../HttpClientError-BUeMWx70.mjs";
|
|
7
|
+
import { DeployFailedError } from "./deploy-failed.errors.mjs";
|
|
8
|
+
import { TokenRefreshError } from "./auth/token-refresh.errors.mjs";
|
|
9
|
+
// src/deploy/request-failure.pure.ts
|
|
10
|
+
const progressWait = "30 seconds";
|
|
11
|
+
const reconnectBackoff = min([exponential("1 second"), spaced("30 seconds")]);
|
|
12
|
+
const tooManyRequests = 429;
|
|
13
|
+
const firstServerError = 500;
|
|
14
|
+
const excerptStart = 0;
|
|
15
|
+
const excerptLength = 300;
|
|
16
|
+
const whitespace = /\s+/gu;
|
|
17
|
+
const statusCodeOf = (failure) => {
|
|
18
|
+
if (isHttpClientError(failure) && isTagged(failure.reason, "StatusCodeError")) return some(failure.reason.response.status);
|
|
19
|
+
if (hasProperty(failure, "response") && hasProperty(failure.response, "status") && isNumber(failure.response.status)) return some(failure.response.status);
|
|
20
|
+
return none();
|
|
21
|
+
};
|
|
22
|
+
const statusOf = (failure) => match(statusCodeOf(failure), {
|
|
23
|
+
onNone: () => "request or response error",
|
|
24
|
+
onSome: (status) => `HTTP ${status}`
|
|
25
|
+
});
|
|
26
|
+
const requestFailure = (operation) => (failure) => {
|
|
27
|
+
if (is(DeployFailedError)(failure)) return failure;
|
|
28
|
+
const message = `${operation} failed (${statusOf(failure)}).`;
|
|
29
|
+
return match(statusCodeOf(failure), {
|
|
30
|
+
onNone: () => DeployFailedError.make({ message }),
|
|
31
|
+
onSome: (status) => DeployFailedError.make({
|
|
32
|
+
message,
|
|
33
|
+
status
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const excerpt = (text) => slice(excerptStart, excerptLength)(trim(replaceAll(whitespace, " ")(text)));
|
|
38
|
+
const encodeBody = encodeOption(fromJsonString(Unknown));
|
|
39
|
+
const undecodable = (detail) => `Deploy progress could not be decoded, so this CLI and the API disagree: ${excerpt(detail)}`;
|
|
40
|
+
const httpFailure = (status, body) => {
|
|
41
|
+
const shown = excerpt(body);
|
|
42
|
+
if (isEmpty(shown)) return `Deploy progress failed with HTTP ${String(status)}.`;
|
|
43
|
+
return `Deploy progress failed with HTTP ${String(status)}: ${shown}`;
|
|
44
|
+
};
|
|
45
|
+
const progressStatus = (failure) => {
|
|
46
|
+
if (isTimeoutError(failure) || isSchemaError(failure) || is(DeployFailedError)(failure) || is(TokenRefreshError)(failure)) return none();
|
|
47
|
+
if (!isHttpClientError(failure)) return some(failure.response.status);
|
|
48
|
+
if (isTagged(failure.reason, "StatusCodeError")) return some(failure.reason.response.status);
|
|
49
|
+
return none();
|
|
50
|
+
};
|
|
51
|
+
const retryable = (failure) => {
|
|
52
|
+
if (isTimeoutError(failure) || is(TokenRefreshError)(failure)) return true;
|
|
53
|
+
if (isHttpClientError(failure) && isTagged(failure.reason, "TransportError")) return true;
|
|
54
|
+
return exists(progressStatus(failure), (status) => status === tooManyRequests || status >= firstServerError);
|
|
55
|
+
};
|
|
56
|
+
const refreshMessage = (failure) => {
|
|
57
|
+
if (isTimeoutError(failure)) return `API token refresh got no answer within ${progressWait}.`;
|
|
58
|
+
if (isHttpClientError(failure) && isTagged(failure.reason, "TransportError")) return "API token refresh could not reach the API (connection error).";
|
|
59
|
+
return `API token refresh failed (${statusOf(failure)}).`;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* How a first token exchange that may wait retries: 0.5, 1, 2 and 4 seconds apart, then every 5, for about 30 seconds,
|
|
63
|
+
* long enough for a control plane deploy, whose Cloud API answers 503 and then 520 for about 18 s in all.
|
|
64
|
+
*/
|
|
65
|
+
const signInRetries = max([min([exponential("500 millis"), spaced("5 seconds")]), during("30 seconds")]);
|
|
66
|
+
/**
|
|
67
|
+
* A 5xx, such as AuthUnavailableError's 503 or Cloudflare's 520 while control restarts; never a refused key, another
|
|
68
|
+
* 4xx, a timeout or a transport failure, which a refused redirect, a wrong host or TLS also are, so waiting can't help.
|
|
69
|
+
*/
|
|
70
|
+
const retriedSignIn = (failure) => exists(progressStatus(failure), (status) => status >= firstServerError);
|
|
71
|
+
const exchangeFailure = (refreshing) => (failure) => {
|
|
72
|
+
if (refreshing && retryable(failure)) return TokenRefreshError.make({ message: refreshMessage(failure) });
|
|
73
|
+
return requestFailure("API key exchange")(failure);
|
|
74
|
+
};
|
|
75
|
+
const clientFailure = ({ reason }) => value(reason).pipe(tag("TransportError", () => "Deploy progress could not reach the API (connection error)."), tag("StatusCodeError", (refused) => httpFailure(refused.response.status, refused.description ?? "")), tag("DecodeError", (unreadable) => undecodable(unreadable.description ?? "the body is not JSON")), tag("EmptyBodyError", () => undecodable("the body is empty")), tag("EncodeError", "InvalidUrlError", () => "Deploy progress could not build its request."), exhaustive);
|
|
76
|
+
const progressMessage = (failure) => {
|
|
77
|
+
if (is(DeployFailedError)(failure) || is(TokenRefreshError)(failure)) return failure.message;
|
|
78
|
+
if (isTimeoutError(failure)) return `Deploy progress got no answer within ${progressWait}.`;
|
|
79
|
+
if (isSchemaError(failure)) return undecodable(failure.message);
|
|
80
|
+
if (isHttpClientError(failure)) return clientFailure(failure);
|
|
81
|
+
return httpFailure(failure.response.status, getOrElse(encodeBody(failure.cause), () => ""));
|
|
82
|
+
};
|
|
83
|
+
const progressFailure = (failure) => {
|
|
84
|
+
if (is(DeployFailedError)(failure)) return failure;
|
|
85
|
+
return DeployFailedError.make({ message: progressMessage(failure) });
|
|
86
|
+
};
|
|
87
|
+
export { exchangeFailure, progressFailure, progressMessage, progressStatus, progressWait, reconnectBackoff, refreshMessage, requestFailure, retriedSignIn, retryable, signInRetries, statusOf };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { T as join } from "./Array-B4kuTQeW.mjs";
|
|
2
|
+
import { appEntry } from "./app-entry.pure.mjs";
|
|
3
|
+
// src/dev-runner.pure.ts
|
|
4
|
+
const devRunner = ({ allowedHosts, directory, entry, environment, inspectorPort, port }) => join([
|
|
5
|
+
"import { Effect, Fiber, Layer } from \"effect\";",
|
|
6
|
+
"import { HttpServer } from \"effect/http\";",
|
|
7
|
+
"import { Akter } from \"@akterjs/effect\";",
|
|
8
|
+
...appEntry({
|
|
9
|
+
command: "dev",
|
|
10
|
+
entry
|
|
11
|
+
}),
|
|
12
|
+
"",
|
|
13
|
+
`const local = Akter.local({ directory: ${directory}, environment: ${environment} ?? undefined }).pipe(Layer.provide(app.layer), Layer.provide(Akter.jobs));`,
|
|
14
|
+
`const server = Akter.serve({ actors: app.actors, allowedHosts: ${allowedHosts}, port: ${port} }).pipe(Layer.provide(local));`,
|
|
15
|
+
"const announce = Layer.effectDiscard(",
|
|
16
|
+
` HttpServer.HttpServer.use((server) => Effect.sync(() => console.log("akter dev: http://127.0.0.1:" + server.address.port + ", data in " + ${directory}))),`,
|
|
17
|
+
");",
|
|
18
|
+
`const inspector = Akter.inspector({ allowedHosts: ${allowedHosts}, directory: ${directory}, port: ${inspectorPort} });`,
|
|
19
|
+
"const announceInspector = Layer.effectDiscard(",
|
|
20
|
+
" HttpServer.HttpServer.use((server) => Effect.sync(() => console.log(\"akter inspector: http://127.0.0.1:\" + server.address.port))),",
|
|
21
|
+
");",
|
|
22
|
+
"const served = Layer.mergeAll(announce.pipe(Layer.provide(server)), announceInspector.pipe(Layer.provide(inspector)));",
|
|
23
|
+
"const fiber = Effect.runFork(Layer.launch(served).pipe(Effect.tapCause(Effect.logError)));",
|
|
24
|
+
"const stop = () => Effect.runFork(Effect.ensuring(Fiber.interrupt(fiber), Effect.sync(() => process.exit(0))));",
|
|
25
|
+
"",
|
|
26
|
+
"process.once(\"SIGINT\", stop);",
|
|
27
|
+
"process.once(\"SIGTERM\", stop);",
|
|
28
|
+
""
|
|
29
|
+
], "\n");
|
|
30
|
+
export { devRunner };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { E as last, O as length, Z as fromOption, j as map, l as filter, u as findFirst, y as head } from "../Array-B4kuTQeW.mjs";
|
|
2
|
+
import { C as orElse, Tn as pipe, b as map$1, f as getOrElse, i as filter$1, u as fromNullishOr } from "../Option-DkxSnBhp.mjs";
|
|
3
|
+
import { g as toLowerCase, i as includes, m as split, v as trim } from "../String-q5dcsVe4.mjs";
|
|
4
|
+
// src/docs/doc-topics.pure.ts
|
|
5
|
+
const heading = /^#\s+(?<title>.+)$/mu;
|
|
6
|
+
const titleOf = (page) => pipe(fromNullishOr(heading.exec(page.markdown)?.groups?.title), map$1(trim), getOrElse(() => page.topic));
|
|
7
|
+
const topicsOf = (pages) => map(pages, (page) => ({
|
|
8
|
+
title: titleOf(page),
|
|
9
|
+
topic: page.topic
|
|
10
|
+
}));
|
|
11
|
+
const lastSegment = (topic) => getOrElse(last(split(topic, "/")), () => topic);
|
|
12
|
+
const single = 1;
|
|
13
|
+
const only = (pages) => filter$1(head(pages), () => length(pages) === single);
|
|
14
|
+
const lookup = ({ pages, query }) => {
|
|
15
|
+
const wanted = toLowerCase(trim(query));
|
|
16
|
+
const exact = findFirst(pages, (page) => page.topic === wanted);
|
|
17
|
+
const named = only(filter(pages, (page) => lastSegment(page.topic) === wanted));
|
|
18
|
+
const near = topicsOf(filter(pages, (page) => includes(wanted)(page.topic)));
|
|
19
|
+
return fromOption(orElse(exact, () => named), () => near);
|
|
20
|
+
};
|
|
21
|
+
export { lookup, titleOf, topicsOf };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as docs } from "../docs.config-_21Xi6HU.mjs";
|