@gjermundgaraba/clankercreds-api 0.0.0-stage → 0.5.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/dist/shared.js ADDED
@@ -0,0 +1,87 @@
1
+ import { Option, Schema } from "effect";
2
+ /** Every route is `POST /v1/<action>`: both bindings mount here, each on its own listener. */
3
+ export const apiPath = "/v1";
4
+ /**
5
+ * What a credential of the clankercreds resource may carry. `machine` admits the
6
+ * public actions and nothing else; `read` and `admin` admit the admin actions.
7
+ */
8
+ export const scopes = {
9
+ machine: "clankercreds:machine",
10
+ read: "clankercreds:read",
11
+ admin: "clankercreds:admin",
12
+ };
13
+ /**
14
+ * What was asked for does not exist: a key, credential or sign-in by that name, or a
15
+ * credential the calling machine key is not granted, which it is not told apart from one
16
+ * that does not exist.
17
+ */
18
+ export class NotFound extends Schema.TaggedError()("NotFound", { message: Schema.String }, { httpApiStatus: 404 }) {
19
+ }
20
+ /** The change collides with what is stored: a taken name, or a credential still in use. */
21
+ export class Conflict extends Schema.TaggedError()("Conflict", { message: Schema.String }, { httpApiStatus: 409 }) {
22
+ }
23
+ /** The login is dead, or was never completed. Only a new sign-in revives it. */
24
+ export class NeedsSignIn extends Schema.TaggedError()("NeedsSignIn", { message: Schema.String }, { httpApiStatus: 409 }) {
25
+ }
26
+ /** The provider could not be reached and no valid token is held. Waiting helps; retrying now does not. */
27
+ export class UpstreamUnavailable extends Schema.TaggedError()("UpstreamUnavailable", { message: Schema.String }, { httpApiStatus: 503 }) {
28
+ }
29
+ /**
30
+ * Credential names: lowercase labels, because they are typed by hand and are
31
+ * identities. SQLite compares them case-sensitively, so mixed case would let `GitHub-Main`
32
+ * and `github-main` be two credentials.
33
+ */
34
+ export const Name = Schema.String.check(Schema.isPattern(/^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/));
35
+ /**
36
+ * What an operator stores a value for: a GitHub token, a Claude token, or `token`, any other
37
+ * service's API key, which a service such as clankerusage reads and no machine places.
38
+ */
39
+ export const SecretKind = Schema.Literals(["gh", "claude", "token"]);
40
+ /**
41
+ * What a sign-in creates and the service keeps refreshed. The refresh token never leaves
42
+ * the service; only access tokens are delivered.
43
+ */
44
+ export const LoginKind = Schema.Literals(["chatgpt", "grok", "cursor"]);
45
+ export const CredentialKind = Schema.Literals([...SecretKind.literals, ...LoginKind.literals]);
46
+ /** A GitHub host, lowercase: it is written into `gh`'s and git's configuration as is. */
47
+ export const Host = Schema.String.check(Schema.isPattern(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/), Schema.isMaxLength(253));
48
+ /**
49
+ * The machine's self-generated label. It identifies nothing; it only groups audit rows.
50
+ * It excludes `:` because the Codex refresh token is `<clientId>:<credential>:<key>`.
51
+ */
52
+ export const ClientId = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9_-]{1,64}$/));
53
+ /**
54
+ * The one id the service records for a caller, whichever way clankerauth names it: the
55
+ * process itself, which no surface here admits, by its subject.
56
+ */
57
+ export const keyIdOf = ({ actor, subject }) => {
58
+ switch (actor.kind) {
59
+ case "key":
60
+ return actor.keyId;
61
+ case "client":
62
+ return actor.clientId;
63
+ case "local":
64
+ return subject;
65
+ }
66
+ };
67
+ const Claims = Schema.Struct({
68
+ exp: Schema.optionalKey(Schema.Number),
69
+ email: Schema.optionalKey(Schema.String),
70
+ "https://api.openai.com/auth": Schema.optionalKey(Schema.Struct({ chatgpt_account_id: Schema.optionalKey(Schema.String) })),
71
+ });
72
+ /**
73
+ * The claims of a JWT, unverified: they are read for their timing, email and, in OpenAI's,
74
+ * account, never trusted for anything. Anything unreadable is simply no claims.
75
+ */
76
+ export const claimsOf = (jwt) => {
77
+ const payload = Buffer.from(jwt.split(".")[1] ?? "", "base64url").toString("utf8");
78
+ const claims = Schema.decodeUnknownOption(Schema.fromJsonString(Claims))(payload);
79
+ return Option.match(claims, {
80
+ onNone: () => ({ exp: undefined, email: undefined, accountId: undefined }),
81
+ onSome: (value) => ({
82
+ exp: value.exp,
83
+ email: value.email,
84
+ accountId: value["https://api.openai.com/auth"]?.chatgpt_account_id,
85
+ }),
86
+ });
87
+ };
package/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "@gjermundgaraba/clankercreds-api",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.5.0",
4
+ "description": "The clankercreds wire contract: the machine and admin actions and the typed credentials they deliver, for a typed client of either API.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/gjermundgaraba/clankercreds.git",
9
+ "directory": "packages/api"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "type": "module",
15
+ "sideEffects": false,
16
+ "exports": {
17
+ "./machine": {
18
+ "types": "./dist/machine.d.ts",
19
+ "import": "./dist/machine.js"
20
+ },
21
+ "./admin": {
22
+ "types": "./dist/admin.d.ts",
23
+ "import": "./dist/admin.js"
24
+ }
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "devDependencies": {
30
+ "@gjermundgaraba/clankerauth-sdk": "0.16.0",
31
+ "@gjermundgaraba/effect-actions": "0.11.0",
32
+ "@types/node": "26.6.5",
33
+ "effect": "4.0.2",
34
+ "typescript": "7.0.2",
35
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
36
+ "vite-plus": "1.1.0"
37
+ },
38
+ "peerDependencies": {
39
+ "@gjermundgaraba/clankerauth-sdk": ">=0.16.0 <1",
40
+ "@gjermundgaraba/effect-actions": ">=0.11.0 <1",
41
+ "effect": "^4.0.2"
42
+ },
43
+ "engines": {
44
+ "node": ">=26"
45
+ },
46
+ "scripts": {
47
+ "test": "vp test --passWithNoTests",
48
+ "check": "vp check"
49
+ }
6
50
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.