@knpkv/alchemy-console 0.1.0 → 0.2.1
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/README.md +71 -4
- package/dist/api.d.ts +126 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +62 -0
- package/dist/api.js.map +1 -0
- package/dist/client/bootstrap.js +2834 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +39 -0
- package/dist/main.js.map +1 -0
- package/dist/s3-live.d.ts +7 -2
- package/dist/s3-live.d.ts.map +1 -1
- package/dist/s3-live.js +3 -2
- package/dist/s3-live.js.map +1 -1
- package/dist/server/Bootstrap.d.ts +4 -0
- package/dist/server/Bootstrap.d.ts.map +1 -0
- package/dist/server/Bootstrap.js +12 -0
- package/dist/server/Bootstrap.js.map +1 -0
- package/dist/server/Catalog.d.ts +27 -0
- package/dist/server/Catalog.d.ts.map +1 -0
- package/dist/server/Catalog.js +83 -0
- package/dist/server/Catalog.js.map +1 -0
- package/dist/server/Config.d.ts +17 -0
- package/dist/server/Config.d.ts.map +1 -0
- package/dist/server/Config.js +23 -0
- package/dist/server/Config.js.map +1 -0
- package/dist/server/ControlSocket.d.ts +19 -0
- package/dist/server/ControlSocket.d.ts.map +1 -0
- package/dist/server/ControlSocket.js +147 -0
- package/dist/server/ControlSocket.js.map +1 -0
- package/dist/server/HttpApplication.d.ts +7 -0
- package/dist/server/HttpApplication.d.ts.map +1 -0
- package/dist/server/HttpApplication.js +46 -0
- package/dist/server/HttpApplication.js.map +1 -0
- package/dist/server/Launch.d.ts +7 -0
- package/dist/server/Launch.d.ts.map +1 -0
- package/dist/server/Launch.js +17 -0
- package/dist/server/Launch.js.map +1 -0
- package/dist/server/OwnerSession.d.ts +9 -0
- package/dist/server/OwnerSession.d.ts.map +1 -0
- package/dist/server/OwnerSession.js +27 -0
- package/dist/server/OwnerSession.js.map +1 -0
- package/dist/server/Server.d.ts +6 -0
- package/dist/server/Server.d.ts.map +1 -0
- package/dist/server/Server.js +22 -0
- package/dist/server/Server.js.map +1 -0
- package/dist/server/Sources.d.ts +12 -0
- package/dist/server/Sources.d.ts.map +1 -0
- package/dist/server/Sources.js +118 -0
- package/dist/server/Sources.js.map +1 -0
- package/package.json +17 -6
package/README.md
CHANGED
|
@@ -1,9 +1,76 @@
|
|
|
1
1
|
# @knpkv/alchemy-console
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Run `alchemy-console` to serve the read-only API on `127.0.0.1:3114` and open a
|
|
4
|
+
one-time login link. `alchemy-console login` behaves the same way: it asks an
|
|
5
|
+
existing server for a fresh link, or starts one in the foreground. `--no-open`
|
|
6
|
+
prints the link without opening a browser. CI, non-interactive stdout and
|
|
7
|
+
`BROWSER=none` also skip opening. `--port` selects a port from 1024 through 65535.
|
|
8
|
+
`alchemy-console serve` always prints only and runs until SIGINT or SIGTERM.
|
|
9
|
+
Closing a browser tab leaves the foreground server running.
|
|
10
|
+
|
|
11
|
+
The current browser page performs login, then navigates to JSON at `/api/stacks`.
|
|
12
|
+
Stack screens will follow the approved design references in a separate change.
|
|
13
|
+
|
|
14
|
+
Configuration is read at startup:
|
|
15
|
+
|
|
16
|
+
| Variable | Default | Boundary |
|
|
17
|
+
| ---------------------- | ---------------------------------------------- | ------------------------------------- |
|
|
18
|
+
| `ALCHEMY_CONSOLE_ROOT` | `Work/dev` under the user's home | Server-private project discovery path |
|
|
19
|
+
| `AWS_CONFIG_FILE` | `.aws/config` under the user's home | Server-private SSO configuration path |
|
|
20
|
+
| `ALCHEMY_CONSOLE_HOME` | `.cache/alchemy-console` under the user's home | Server-private control directory |
|
|
21
|
+
|
|
22
|
+
Login reuse is per port. A reused server keeps its startup configuration. The
|
|
23
|
+
control directory must be owned by the current user with mode `0700`; each
|
|
24
|
+
`serve-<port>.sock` is `0600`. Symlinks, foreign owners and pre-existing stale
|
|
25
|
+
sockets fail explicitly. For an abandoned socket, confirm its server has stopped
|
|
26
|
+
before removing that entry and restarting. The control channel currently requires
|
|
27
|
+
POSIX ownership and Unix sockets.
|
|
28
|
+
|
|
29
|
+
## Authenticated API
|
|
30
|
+
|
|
31
|
+
The client-safe contracts are exported from `@knpkv/alchemy-console/api` and may be
|
|
32
|
+
used with Effect's `HttpApiClient`. Both endpoints require the process's owner
|
|
33
|
+
cookie, and all responses are private and uncacheable:
|
|
34
|
+
|
|
35
|
+
The cookie name includes the bound listener port, so sessions on different ports
|
|
36
|
+
can coexist in one browser. Both API boundaries select that listener's cookie.
|
|
37
|
+
Cookies still share the loopback host and travel across ports; the name separates
|
|
38
|
+
sessions and does not provide port confidentiality. The API middleware resolves
|
|
39
|
+
the name at runtime rather than declaring a fixed OpenAPI cookie scheme.
|
|
40
|
+
|
|
41
|
+
| Route | Result |
|
|
42
|
+
| --------------------- | ------------------------------------------------------ |
|
|
43
|
+
| `GET /api/stacks` | Stack summaries and explicit local/S3 discovery issues |
|
|
44
|
+
| `GET /api/stacks/:id` | Current normalized resource state for a listed stack |
|
|
45
|
+
|
|
46
|
+
Listing runs discovery on demand, without polling or schedules. IDs are random,
|
|
47
|
+
process-scoped identifiers with no encoded locator. They remain stable across
|
|
48
|
+
scans while a stack remains present, then expire when it disappears or the server
|
|
49
|
+
restarts. They are normalized, authenticated client-visible identifiers; the
|
|
50
|
+
server never persists them. Do not emit them or stack metadata through public
|
|
51
|
+
routes or telemetry. Browsers must not persist private provider coordinates.
|
|
52
|
+
|
|
53
|
+
Discovery reports sanitized reason codes for failed projects, SSO profiles and
|
|
54
|
+
buckets while continuing other sources. A discovered entrypoint with no state
|
|
55
|
+
cannot supply an app or stage and contributes no stack row. Remote resource
|
|
56
|
+
counts and Alchemy versions remain unknown until the corresponding state or
|
|
57
|
+
lockfile establishes them. Discovery is capped at 1000 projects/stacks, 100 SSO
|
|
58
|
+
profiles, 1000 candidate buckets per profile and two minutes per list request.
|
|
59
|
+
|
|
60
|
+
The one public authentication route, `POST /auth/bootstrap`, exchanges a code
|
|
61
|
+
from the URL fragment for an HttpOnly, SameSite=Strict owner cookie. Codes are
|
|
62
|
+
single-use and expire after 60 seconds; a fresh mint replaces an unspent code.
|
|
63
|
+
The page removes the fragment before exchanging it. Codes are minted and
|
|
64
|
+
announced only after the authenticated HTTP listener is ready. Credential URLs
|
|
65
|
+
go only to stdout and the browser opener, never logs or telemetry. Session tokens
|
|
66
|
+
remain in the server and HttpOnly cookie. Every unsafe API method is refused,
|
|
67
|
+
including apply and destroy. Reads reject foreign origins and cross-site browser
|
|
68
|
+
requests. Listener and request Host are restricted to the bound loopback address.
|
|
69
|
+
|
|
70
|
+
## Data readers
|
|
71
|
+
|
|
72
|
+
The root export provides project discovery, lockfile version lookup, local
|
|
73
|
+
state metadata and SSO/S3 readers for server-side consumers.
|
|
7
74
|
|
|
8
75
|
`discoverProjects(directory)` scans an explicit root for `alchemy.run.ts` without
|
|
9
76
|
importing or executing it. It skips `.git`, `node_modules`, `.alchemy`, `.direnv`,
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/** Client-safe contracts. IDs and metadata cross only the authenticated owner API, never public telemetry. */
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware } from "effect/http-api";
|
|
4
|
+
/** Random, process-scoped identity; contains no encoded provider locator. Not persisted by the server. */
|
|
5
|
+
export declare const StackId: Schema.String;
|
|
6
|
+
export type StackId = typeof StackId.Type;
|
|
7
|
+
export declare const SourceFailureReason: Schema.Literals<readonly ["io", "invalid-state", "invalid-lockfile", "unsupported-version", "limit", "outside-root", "invalid-config", "authentication", "denied", "not-found", "provider", "invalid-response", "invalid-source"]>;
|
|
8
|
+
export declare const DiscoveryIssue: Schema.Struct<{
|
|
9
|
+
readonly source: Schema.Literals<readonly ["local", "s3"]>;
|
|
10
|
+
readonly reason: Schema.Literals<readonly ["io", "invalid-state", "invalid-lockfile", "unsupported-version", "limit", "outside-root", "invalid-config", "authentication", "denied", "not-found", "provider", "invalid-response", "invalid-source"]>;
|
|
11
|
+
}>;
|
|
12
|
+
export type DiscoveryIssue = typeof DiscoveryIssue.Type;
|
|
13
|
+
export declare const StackSummary: Schema.Struct<{
|
|
14
|
+
readonly id: Schema.String;
|
|
15
|
+
readonly app: Schema.NonEmptyString;
|
|
16
|
+
readonly stage: Schema.NonEmptyString;
|
|
17
|
+
readonly backend: Schema.Literals<readonly ["local", "s3"]>;
|
|
18
|
+
readonly alchemyVersion: Schema.NullOr<Schema.String>;
|
|
19
|
+
readonly lastDeploy: Schema.NullOr<Schema.String>;
|
|
20
|
+
readonly resourceCount: Schema.NullOr<Schema.Int>;
|
|
21
|
+
}>;
|
|
22
|
+
export type StackSummary = typeof StackSummary.Type;
|
|
23
|
+
export declare const StackList: Schema.Struct<{
|
|
24
|
+
readonly stacks: Schema.$Array<Schema.Struct<{
|
|
25
|
+
readonly id: Schema.String;
|
|
26
|
+
readonly app: Schema.NonEmptyString;
|
|
27
|
+
readonly stage: Schema.NonEmptyString;
|
|
28
|
+
readonly backend: Schema.Literals<readonly ["local", "s3"]>;
|
|
29
|
+
readonly alchemyVersion: Schema.NullOr<Schema.String>;
|
|
30
|
+
readonly lastDeploy: Schema.NullOr<Schema.String>;
|
|
31
|
+
readonly resourceCount: Schema.NullOr<Schema.Int>;
|
|
32
|
+
}>>;
|
|
33
|
+
readonly issues: Schema.$Array<Schema.Struct<{
|
|
34
|
+
readonly source: Schema.Literals<readonly ["local", "s3"]>;
|
|
35
|
+
readonly reason: Schema.Literals<readonly ["io", "invalid-state", "invalid-lockfile", "unsupported-version", "limit", "outside-root", "invalid-config", "authentication", "denied", "not-found", "provider", "invalid-response", "invalid-source"]>;
|
|
36
|
+
}>>;
|
|
37
|
+
}>;
|
|
38
|
+
export type StackList = typeof StackList.Type;
|
|
39
|
+
export declare const StackDetail: Schema.Struct<{
|
|
40
|
+
readonly id: Schema.String;
|
|
41
|
+
readonly state: Schema.Struct<{
|
|
42
|
+
readonly app: Schema.NonEmptyString;
|
|
43
|
+
readonly stage: Schema.NonEmptyString;
|
|
44
|
+
readonly backend: Schema.Literals<readonly ["local", "s3"]>;
|
|
45
|
+
readonly alchemyVersion: Schema.NullOr<Schema.String>;
|
|
46
|
+
readonly lastDeploy: Schema.NullOr<Schema.String>;
|
|
47
|
+
readonly resources: Schema.$Array<Schema.Struct<{
|
|
48
|
+
readonly fqn: Schema.NonEmptyString;
|
|
49
|
+
readonly logicalId: Schema.NonEmptyString;
|
|
50
|
+
readonly resourceType: Schema.NonEmptyString;
|
|
51
|
+
readonly status: Schema.Literals<readonly ["creating", "created", "updating", "updated", "deleting", "replacing", "replaced"]>;
|
|
52
|
+
readonly parent: Schema.NullOr<Schema.String>;
|
|
53
|
+
readonly providerId: Schema.NullOr<Schema.String>;
|
|
54
|
+
readonly account: Schema.NullOr<Schema.String>;
|
|
55
|
+
readonly region: Schema.NullOr<Schema.String>;
|
|
56
|
+
readonly consoleUrl: Schema.NullOr<Schema.String>;
|
|
57
|
+
}>>;
|
|
58
|
+
}>;
|
|
59
|
+
}>;
|
|
60
|
+
export type StackDetail = typeof StackDetail.Type;
|
|
61
|
+
declare const CatalogReadError_base: Schema.Class<CatalogReadError, Schema.TaggedStruct<"CatalogReadError", {
|
|
62
|
+
readonly reason: Schema.Literals<readonly ["io", "invalid-state", "invalid-lockfile", "unsupported-version", "limit", "outside-root", "invalid-config", "authentication", "denied", "not-found", "provider", "invalid-response", "invalid-source"]>;
|
|
63
|
+
}>, import("effect/Cause").YieldableError>;
|
|
64
|
+
export declare class CatalogReadError extends CatalogReadError_base {
|
|
65
|
+
}
|
|
66
|
+
declare const StackNotFound_base: Schema.Class<StackNotFound, Schema.TaggedStruct<"StackNotFound", {}>, import("effect/Cause").YieldableError>;
|
|
67
|
+
export declare class StackNotFound extends StackNotFound_base {
|
|
68
|
+
}
|
|
69
|
+
declare const Unauthorized_base: Schema.Class<Unauthorized, Schema.TaggedStruct<"Unauthorized", {}>, import("effect/Cause").YieldableError>;
|
|
70
|
+
export declare class Unauthorized extends Unauthorized_base {
|
|
71
|
+
}
|
|
72
|
+
declare const Forbidden_base: Schema.Class<Forbidden, Schema.TaggedStruct<"Forbidden", {}>, import("effect/Cause").YieldableError>;
|
|
73
|
+
export declare class Forbidden extends Forbidden_base {
|
|
74
|
+
}
|
|
75
|
+
declare const OwnerAuth_base: HttpApiMiddleware.ServiceClass<OwnerAuth, "@knpkv/alchemy-console/OwnerAuth", {
|
|
76
|
+
requires: never;
|
|
77
|
+
provides: never;
|
|
78
|
+
error: readonly [typeof Unauthorized, typeof Forbidden];
|
|
79
|
+
clientError: never;
|
|
80
|
+
requiredForClient: false;
|
|
81
|
+
security: never;
|
|
82
|
+
}, HttpApiMiddleware.HttpApiMiddleware<never, readonly [typeof Unauthorized, typeof Forbidden], never>>;
|
|
83
|
+
/** The server resolves its listener-specific cookie name at request time. */
|
|
84
|
+
export declare class OwnerAuth extends OwnerAuth_base {
|
|
85
|
+
}
|
|
86
|
+
declare const AlchemyConsoleApi_base: HttpApi.HttpApi<"AlchemyConsoleApi", HttpApiGroup.HttpApiGroup<"stacks", HttpApiEndpoint.HttpApiEndpoint<"list", "GET", "/api/stacks", never, never, never, never, Schema.toCodecJson<Schema.Struct<{
|
|
87
|
+
readonly stacks: Schema.$Array<Schema.Struct<{
|
|
88
|
+
readonly id: Schema.String;
|
|
89
|
+
readonly app: Schema.NonEmptyString;
|
|
90
|
+
readonly stage: Schema.NonEmptyString;
|
|
91
|
+
readonly backend: Schema.Literals<readonly ["local", "s3"]>;
|
|
92
|
+
readonly alchemyVersion: Schema.NullOr<Schema.String>;
|
|
93
|
+
readonly lastDeploy: Schema.NullOr<Schema.String>;
|
|
94
|
+
readonly resourceCount: Schema.NullOr<Schema.Int>;
|
|
95
|
+
}>>;
|
|
96
|
+
readonly issues: Schema.$Array<Schema.Struct<{
|
|
97
|
+
readonly source: Schema.Literals<readonly ["local", "s3"]>;
|
|
98
|
+
readonly reason: Schema.Literals<readonly ["io", "invalid-state", "invalid-lockfile", "unsupported-version", "limit", "outside-root", "invalid-config", "authentication", "denied", "not-found", "provider", "invalid-response", "invalid-source"]>;
|
|
99
|
+
}>>;
|
|
100
|
+
}>>, Schema.toCodecJson<typeof CatalogReadError>, OwnerAuth, never> | HttpApiEndpoint.HttpApiEndpoint<"get", "GET", "/api/stacks/:id", Schema.toCodecStringTree<Schema.Struct<{
|
|
101
|
+
readonly id: Schema.String;
|
|
102
|
+
}>>, never, never, never, Schema.toCodecJson<Schema.Struct<{
|
|
103
|
+
readonly id: Schema.String;
|
|
104
|
+
readonly state: Schema.Struct<{
|
|
105
|
+
readonly app: Schema.NonEmptyString;
|
|
106
|
+
readonly stage: Schema.NonEmptyString;
|
|
107
|
+
readonly backend: Schema.Literals<readonly ["local", "s3"]>;
|
|
108
|
+
readonly alchemyVersion: Schema.NullOr<Schema.String>;
|
|
109
|
+
readonly lastDeploy: Schema.NullOr<Schema.String>;
|
|
110
|
+
readonly resources: Schema.$Array<Schema.Struct<{
|
|
111
|
+
readonly fqn: Schema.NonEmptyString;
|
|
112
|
+
readonly logicalId: Schema.NonEmptyString;
|
|
113
|
+
readonly resourceType: Schema.NonEmptyString;
|
|
114
|
+
readonly status: Schema.Literals<readonly ["creating", "created", "updating", "updated", "deleting", "replacing", "replaced"]>;
|
|
115
|
+
readonly parent: Schema.NullOr<Schema.String>;
|
|
116
|
+
readonly providerId: Schema.NullOr<Schema.String>;
|
|
117
|
+
readonly account: Schema.NullOr<Schema.String>;
|
|
118
|
+
readonly region: Schema.NullOr<Schema.String>;
|
|
119
|
+
readonly consoleUrl: Schema.NullOr<Schema.String>;
|
|
120
|
+
}>>;
|
|
121
|
+
}>;
|
|
122
|
+
}>>, Schema.toCodecJson<typeof CatalogReadError | typeof StackNotFound>, OwnerAuth, never>, false>>;
|
|
123
|
+
export declare class AlchemyConsoleApi extends AlchemyConsoleApi_base {
|
|
124
|
+
}
|
|
125
|
+
export {};
|
|
126
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAG3F,0GAA0G;AAC1G,eAAO,MAAM,OAAO,eAAuC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,eAAO,MAAM,mBAAmB,oOAc9B,CAAA;AAEF,eAAO,MAAM,cAAc;;;EAGzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD,eAAO,MAAM,YAAY;;;;;;;;EAQvB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,eAAO,MAAM,SAAS;;;;;;;;;;;;;;EAA8F,CAAA;AACpH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;AAC7C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;EAAoD,CAAA;AAC5E,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;;;;AAEjD,qBAAa,gBAAiB,SAAQ,qBAEZ;CAAG;;AAE7B,qBAAa,aAAc,SAAQ,kBAAgF;CAAG;;AAEtH,qBAAa,YAAa,SAAQ,iBAA8E;CAAG;;AAEnH,qBAAa,SAAU,SAAQ,cAAwE;CAAG;;;;;;;;;AAE1G,6EAA6E;AAC7E,qBAAa,SAAU,SAAQ,cAE7B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWL,qBAAa,iBAAkB,SAAQ,sBAAmE;CAAG"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Client-safe contracts. IDs and metadata cross only the authenticated owner API, never public telemetry. */
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware } from "effect/http-api";
|
|
4
|
+
import { StackState } from "./schema.js";
|
|
5
|
+
/** Random, process-scoped identity; contains no encoded provider locator. Not persisted by the server. */
|
|
6
|
+
export const StackId = Schema.String.check(Schema.isUUID());
|
|
7
|
+
export const SourceFailureReason = Schema.Literals([
|
|
8
|
+
"io",
|
|
9
|
+
"invalid-state",
|
|
10
|
+
"invalid-lockfile",
|
|
11
|
+
"unsupported-version",
|
|
12
|
+
"limit",
|
|
13
|
+
"outside-root",
|
|
14
|
+
"invalid-config",
|
|
15
|
+
"authentication",
|
|
16
|
+
"denied",
|
|
17
|
+
"not-found",
|
|
18
|
+
"provider",
|
|
19
|
+
"invalid-response",
|
|
20
|
+
"invalid-source"
|
|
21
|
+
]);
|
|
22
|
+
export const DiscoveryIssue = Schema.Struct({
|
|
23
|
+
source: Schema.Literals(["local", "s3"]),
|
|
24
|
+
reason: SourceFailureReason
|
|
25
|
+
});
|
|
26
|
+
export const StackSummary = Schema.Struct({
|
|
27
|
+
id: StackId,
|
|
28
|
+
app: Schema.NonEmptyString,
|
|
29
|
+
stage: Schema.NonEmptyString,
|
|
30
|
+
backend: Schema.Literals(["local", "s3"]),
|
|
31
|
+
alchemyVersion: Schema.NullOr(Schema.String),
|
|
32
|
+
lastDeploy: Schema.NullOr(Schema.String),
|
|
33
|
+
resourceCount: Schema.NullOr(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)))
|
|
34
|
+
});
|
|
35
|
+
export const StackList = Schema.Struct({ stacks: Schema.Array(StackSummary), issues: Schema.Array(DiscoveryIssue) });
|
|
36
|
+
export const StackDetail = Schema.Struct({ id: StackId, state: StackState });
|
|
37
|
+
export class CatalogReadError extends Schema.TaggedError()("CatalogReadError", {
|
|
38
|
+
reason: SourceFailureReason
|
|
39
|
+
}, { httpApiStatus: 503 }) {
|
|
40
|
+
}
|
|
41
|
+
export class StackNotFound extends Schema.TaggedError()("StackNotFound", {}, { httpApiStatus: 404 }) {
|
|
42
|
+
}
|
|
43
|
+
export class Unauthorized extends Schema.TaggedError()("Unauthorized", {}, { httpApiStatus: 401 }) {
|
|
44
|
+
}
|
|
45
|
+
export class Forbidden extends Schema.TaggedError()("Forbidden", {}, { httpApiStatus: 403 }) {
|
|
46
|
+
}
|
|
47
|
+
/** The server resolves its listener-specific cookie name at request time. */
|
|
48
|
+
export class OwnerAuth extends HttpApiMiddleware.Service()("@knpkv/alchemy-console/OwnerAuth", {
|
|
49
|
+
error: [Unauthorized, Forbidden]
|
|
50
|
+
}) {
|
|
51
|
+
}
|
|
52
|
+
const stacks = HttpApiGroup.make("stacks")
|
|
53
|
+
.add(HttpApiEndpoint.get("list", "/stacks", { success: StackList, error: CatalogReadError }))
|
|
54
|
+
.add(HttpApiEndpoint.get("get", "/stacks/:id", {
|
|
55
|
+
params: Schema.Struct({ id: StackId }),
|
|
56
|
+
success: StackDetail,
|
|
57
|
+
error: [StackNotFound, CatalogReadError]
|
|
58
|
+
}))
|
|
59
|
+
.prefix("/api");
|
|
60
|
+
export class AlchemyConsoleApi extends HttpApi.make("AlchemyConsoleApi").add(stacks).middleware(OwnerAuth) {
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|