@mesadev/sdk 0.42.1 → 0.44.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/api/access-token.d.ts +57 -24
- package/dist/api/access-token.d.ts.map +1 -1
- package/dist/api/access-token.js +137 -19
- package/dist/api/access-token.js.map +1 -1
- package/dist/api/client.d.ts +3 -5
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +4 -19
- package/dist/api/client.js.map +1 -1
- package/dist/api/credentials.d.ts +4 -0
- package/dist/api/credentials.d.ts.map +1 -0
- package/dist/api/credentials.js +8 -0
- package/dist/api/credentials.js.map +1 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/resources.d.ts +61 -29
- package/dist/api/resources.d.ts.map +1 -1
- package/dist/api/resources.js +47 -14
- package/dist/api/resources.js.map +1 -1
- package/dist/api/signing-key.d.ts +15 -0
- package/dist/api/signing-key.d.ts.map +1 -0
- package/dist/api/signing-key.js +38 -0
- package/dist/api/signing-key.js.map +1 -0
- package/dist/fs/index.d.ts +2 -1
- package/dist/fs/index.d.ts.map +1 -1
- package/dist/fs/index.js +1 -0
- package/dist/fs/index.js.map +1 -1
- package/dist/fs/layout.d.ts +87 -0
- package/dist/fs/layout.d.ts.map +1 -0
- package/dist/fs/layout.js +78 -0
- package/dist/fs/layout.js.map +1 -0
- package/dist/fs/mesa-file-system.d.ts +41 -2
- package/dist/fs/mesa-file-system.d.ts.map +1 -1
- package/dist/fs/mesa-file-system.js +23 -5
- package/dist/fs/mesa-file-system.js.map +1 -1
- package/dist/fs/native-loader.d.ts +8 -1
- package/dist/fs/native-loader.d.ts.map +1 -1
- package/dist/fs/native-loader.js +26 -4
- package/dist/fs/native-loader.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +5 -2
- package/dist/lib/errors.js.map +1 -1
- package/dist/mesa.d.ts +163 -23
- package/dist/mesa.d.ts.map +1 -1
- package/dist/mesa.js +302 -45
- package/dist/mesa.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -3
|
@@ -1,44 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Local access-token signing
|
|
3
|
-
*
|
|
4
|
-
* that holds an API key can sign them entirely offline — no network round-trip
|
|
5
|
-
* to the server.
|
|
2
|
+
* Local access-token signing for API keys and Ed25519 signing private keys.
|
|
3
|
+
* Both formats are produced entirely offline with no network round trip.
|
|
6
4
|
*
|
|
7
|
-
* This is the SDK-side counterpart to the server
|
|
8
|
-
* `packages/core/src/auth/access-token-legacy.ts
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* order
|
|
5
|
+
* This is the SDK-side counterpart to the server implementations in
|
|
6
|
+
* `packages/core/src/auth/access-token-legacy.ts` and
|
|
7
|
+
* `packages/core/src/auth/signing-key-access-token.ts`. Their wire contracts
|
|
8
|
+
* live in `context/auth/legacy-access-token-protocol.md` and
|
|
9
|
+
* `context/auth/signing-key-access-token-protocol.md`. JSON key order does not
|
|
10
|
+
* affect verification; each implementation may emit claims in any order.
|
|
12
11
|
*
|
|
13
12
|
* Secret derivation:
|
|
14
13
|
* secret = base64url_nopad(SHA-256(utf8(raw_api_key)))
|
|
15
14
|
* This is byte-identical to the value stored in the server's `apikey.key`
|
|
16
15
|
* column. The HMAC key is the UTF-8 bytes of this base64url string.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
* API key row at verification time
|
|
20
|
-
* the key's current permissions.
|
|
21
|
-
*
|
|
17
|
+
* Legacy HS256 tokens carry no org or user info. The server derives both from
|
|
18
|
+
* the API key row at verification time and clamps the requested scopes/repos
|
|
19
|
+
* to the key's current permissions. New callers should use canonical
|
|
20
|
+
* `repo_ids`; the backward-compatible `repos` claim carries full `org/repo`
|
|
21
|
+
* names.
|
|
22
22
|
*
|
|
23
|
-
* Implemented with `node:crypto` only
|
|
24
|
-
* dependency.
|
|
23
|
+
* Implemented with `node:crypto` only so the published SDK retains Node 18
|
|
24
|
+
* support without adding a JWT dependency.
|
|
25
25
|
*/
|
|
26
|
+
import { z } from 'zod';
|
|
27
|
+
import type { PrivateKeyCredential } from './signing-key.js';
|
|
26
28
|
/** Default token lifetime when the caller does not request one. */
|
|
27
29
|
export declare const ACCESS_TOKEN_DEFAULT_TTL_SECONDS: number;
|
|
28
30
|
/** Hard cap on token lifetime; the server rejects anything longer at verify time. */
|
|
29
31
|
export declare const ACCESS_TOKEN_MAX_TTL_SECONDS: number;
|
|
30
|
-
|
|
32
|
+
declare const signingKeyAuthorSchema: z.ZodObject<{
|
|
33
|
+
name: z.ZodString;
|
|
34
|
+
email: z.ZodPipe<z.ZodDefault<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
export type SigningKeyAuthorInput = z.input<typeof signingKeyAuthorSchema>;
|
|
37
|
+
export declare function normalizeSigningKeyAuthors(authors: readonly SigningKeyAuthorInput[]): readonly [z.output<typeof signingKeyAuthorSchema>, ...z.output<typeof signingKeyAuthorSchema>[]];
|
|
38
|
+
export type RepositoryNameRestriction<NameField extends string = 'repos', IdField extends string = 'repoIds'> = {
|
|
39
|
+
[Key in NameField]: string[] | null;
|
|
40
|
+
} & {
|
|
41
|
+
[Key in IdField]?: never;
|
|
42
|
+
};
|
|
43
|
+
export type RepositoryIdRestriction<NameField extends string = 'repos', IdField extends string = 'repoIds'> = {
|
|
44
|
+
[Key in NameField]?: never;
|
|
45
|
+
} & {
|
|
46
|
+
[Key in IdField]: string[] | null;
|
|
47
|
+
};
|
|
48
|
+
export type RepositoryRestriction<NameField extends string = 'repos', IdField extends string = 'repoIds'> = RepositoryNameRestriction<NameField, IdField> | RepositoryIdRestriction<NameField, IdField>;
|
|
49
|
+
export type OptionalRepositoryRestriction<NameField extends string, IdField extends string> = Partial<RepositoryNameRestriction<NameField, IdField>> | RepositoryIdRestriction<NameField, IdField>;
|
|
50
|
+
export type ApiRepositoryRestriction = OptionalRepositoryRestriction<'repos', 'repo_ids'>;
|
|
51
|
+
export type SignAccessTokenInput = RepositoryRestriction & {
|
|
31
52
|
/** The API key ID that signs this token; encoded into the `kid` header. */
|
|
32
53
|
apiKeyId: string;
|
|
33
54
|
/** The raw API key (`mesa_...`) the client holds; the signing secret is derived from it. */
|
|
34
55
|
rawApiKey: string;
|
|
35
56
|
/** Requested scopes; clamped to the key's current scopes at verify time. */
|
|
36
57
|
scopes: string[];
|
|
37
|
-
/**
|
|
38
|
-
* Requested repo restriction as full `org/repo` names; resolved to ids and
|
|
39
|
-
* clamped to the key's at verify time. null = no restriction.
|
|
40
|
-
*/
|
|
41
|
-
repos: string[] | null;
|
|
58
|
+
/** Repository restrictions are supplied by the mutually exclusive `repos` or `repoIds` fields. */
|
|
42
59
|
/** Token lifetime in seconds. Defaults to {@link ACCESS_TOKEN_DEFAULT_TTL_SECONDS}. */
|
|
43
60
|
ttlSeconds?: number;
|
|
44
61
|
};
|
|
@@ -48,11 +65,24 @@ export type SignedAccessToken = {
|
|
|
48
65
|
expiresAt: string;
|
|
49
66
|
/** Effective scopes encoded into the token. */
|
|
50
67
|
scopes: string[];
|
|
51
|
-
/**
|
|
52
|
-
repos
|
|
68
|
+
/** Backward-compatible name restriction, when used. */
|
|
69
|
+
repos?: string[] | null;
|
|
70
|
+
/** Canonical repository-ID restriction, when used. */
|
|
71
|
+
repoIds?: string[] | null;
|
|
53
72
|
/** The token's unique id (`jti`), for auditing without re-decoding the JWT. */
|
|
54
73
|
jti: string;
|
|
55
74
|
};
|
|
75
|
+
type SignPrivateKeyAccessTokenInput = OptionalRepositoryRestriction<'repos', 'repoIds'> & {
|
|
76
|
+
credential: PrivateKeyCredential;
|
|
77
|
+
authors?: readonly [SigningKeyAuthorInput, ...SigningKeyAuthorInput[]];
|
|
78
|
+
/** Defaults to organization-root admin authority. */
|
|
79
|
+
scopes?: string[];
|
|
80
|
+
ttlSeconds?: number;
|
|
81
|
+
};
|
|
82
|
+
/** Convert the public snake-case token fields to the signer restriction. */
|
|
83
|
+
export declare function toSignerRepositoryRestriction(input: ApiRepositoryRestriction): RepositoryRestriction;
|
|
84
|
+
/** Convert signer metadata back to the public snake-case token fields. */
|
|
85
|
+
export declare function toApiRepositoryRestriction(input: Pick<SignedAccessToken, 'repos' | 'repoIds'>): RepositoryRestriction<'repos', 'repo_ids'>;
|
|
56
86
|
/**
|
|
57
87
|
* Derive the HMAC signing secret from a raw API key. Byte-identical to the
|
|
58
88
|
* value stored in the server's `apikey.key` column. The HMAC key is the UTF-8
|
|
@@ -62,8 +92,11 @@ export declare function deriveAccessTokenSigningSecret(rawApiKey: string): strin
|
|
|
62
92
|
/**
|
|
63
93
|
* Sign an access token with HS256 entirely client-side. The `iss` claim is the
|
|
64
94
|
* minting API key id (mirrors the `kid` header). JSON key order is not
|
|
65
|
-
* semantically meaningful
|
|
95
|
+
* semantically meaningful because the server verifies the signature, not a byte-exact
|
|
66
96
|
* string.
|
|
67
97
|
*/
|
|
68
98
|
export declare function signAccessToken(input: SignAccessTokenInput): SignedAccessToken;
|
|
99
|
+
/** Sign the minimal Ed25519 access-token contract accepted by the server. */
|
|
100
|
+
export declare function signPrivateKeyAccessToken(input: SignPrivateKeyAccessTokenInput): SignedAccessToken;
|
|
101
|
+
export {};
|
|
69
102
|
//# sourceMappingURL=access-token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-token.d.ts","sourceRoot":"","sources":["../../src/api/access-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;
|
|
1
|
+
{"version":3,"file":"access-token.d.ts","sourceRoot":"","sources":["../../src/api/access-token.ts"],"names":[],"mappings":"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"}
|
package/dist/api/access-token.js
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Local access-token signing
|
|
3
|
-
*
|
|
4
|
-
* that holds an API key can sign them entirely offline — no network round-trip
|
|
5
|
-
* to the server.
|
|
2
|
+
* Local access-token signing for API keys and Ed25519 signing private keys.
|
|
3
|
+
* Both formats are produced entirely offline with no network round trip.
|
|
6
4
|
*
|
|
7
|
-
* This is the SDK-side counterpart to the server
|
|
8
|
-
* `packages/core/src/auth/access-token-legacy.ts
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* order
|
|
5
|
+
* This is the SDK-side counterpart to the server implementations in
|
|
6
|
+
* `packages/core/src/auth/access-token-legacy.ts` and
|
|
7
|
+
* `packages/core/src/auth/signing-key-access-token.ts`. Their wire contracts
|
|
8
|
+
* live in `context/auth/legacy-access-token-protocol.md` and
|
|
9
|
+
* `context/auth/signing-key-access-token-protocol.md`. JSON key order does not
|
|
10
|
+
* affect verification; each implementation may emit claims in any order.
|
|
12
11
|
*
|
|
13
12
|
* Secret derivation:
|
|
14
13
|
* secret = base64url_nopad(SHA-256(utf8(raw_api_key)))
|
|
15
14
|
* This is byte-identical to the value stored in the server's `apikey.key`
|
|
16
15
|
* column. The HMAC key is the UTF-8 bytes of this base64url string.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
* API key row at verification time
|
|
20
|
-
* the key's current permissions.
|
|
21
|
-
*
|
|
17
|
+
* Legacy HS256 tokens carry no org or user info. The server derives both from
|
|
18
|
+
* the API key row at verification time and clamps the requested scopes/repos
|
|
19
|
+
* to the key's current permissions. New callers should use canonical
|
|
20
|
+
* `repo_ids`; the backward-compatible `repos` claim carries full `org/repo`
|
|
21
|
+
* names.
|
|
22
22
|
*
|
|
23
|
-
* Implemented with `node:crypto` only
|
|
24
|
-
* dependency.
|
|
23
|
+
* Implemented with `node:crypto` only so the published SDK retains Node 18
|
|
24
|
+
* support without adding a JWT dependency.
|
|
25
25
|
*/
|
|
26
|
-
import { createHash, createHmac, randomUUID } from 'node:crypto';
|
|
26
|
+
import { createHash, createHmac, randomUUID, sign as signEd25519 } from 'node:crypto';
|
|
27
|
+
import { z } from 'zod';
|
|
27
28
|
import { InvalidOptionsError } from '../lib/errors.js';
|
|
29
|
+
import { looksLikePrivateKey } from './credentials.js';
|
|
28
30
|
/** Audience claim: access tokens are only valid when presented to the Mesa API. */
|
|
31
|
+
// Protocol values mirror packages/core/src/auth/constants.ts. The published SDK
|
|
32
|
+
// cannot import the private server package at runtime.
|
|
29
33
|
const ACCESS_TOKEN_AUD = 'mesa-api';
|
|
30
34
|
/** JOSE `typ` header (RFC 9068 style) distinguishing access tokens. */
|
|
31
35
|
const ACCESS_TOKEN_TYP = 'mesa-at+jwt';
|
|
@@ -41,6 +45,83 @@ const ACCESS_TOKEN_DERIVATION_VERSION = 'v1';
|
|
|
41
45
|
export const ACCESS_TOKEN_DEFAULT_TTL_SECONDS = 60 * 60; // 1 hour
|
|
42
46
|
/** Hard cap on token lifetime; the server rejects anything longer at verify time. */
|
|
43
47
|
export const ACCESS_TOKEN_MAX_TTL_SECONDS = 24 * 60 * 60; // 24 hours
|
|
48
|
+
/** Default and maximum lifetimes accepted by the signing-key verifier. */
|
|
49
|
+
const SIGNING_KEY_ACCESS_TOKEN_DEFAULT_TTL_SECONDS = 15 * 60; // 15 minutes
|
|
50
|
+
const SIGNING_KEY_ACCESS_TOKEN_MAX_TTL_SECONDS = 4 * 60 * 60; // 4 hours
|
|
51
|
+
const MAX_SIGNING_KEY_AUTHORS = 100;
|
|
52
|
+
const SIGNING_KEY_TOKEN_SCOPES = ['read', 'write', 'admin'];
|
|
53
|
+
const signingKeyAuthorSchema = z.object({
|
|
54
|
+
name: z
|
|
55
|
+
.string()
|
|
56
|
+
.trim()
|
|
57
|
+
.min(1, { error: 'Author names must not be blank.' })
|
|
58
|
+
.refine((name) => !/[<>\r\n]/.test(name), {
|
|
59
|
+
error: 'Author names must not contain angle brackets or newlines.',
|
|
60
|
+
}),
|
|
61
|
+
email: z
|
|
62
|
+
.string()
|
|
63
|
+
.trim()
|
|
64
|
+
.refine((email) => !/[<>\r\n]/.test(email), {
|
|
65
|
+
error: 'Author emails must not contain angle brackets or newlines.',
|
|
66
|
+
})
|
|
67
|
+
.nullable()
|
|
68
|
+
.default(null)
|
|
69
|
+
.transform((email) => email || null),
|
|
70
|
+
});
|
|
71
|
+
const signingKeyAuthorsSchema = z
|
|
72
|
+
.array(signingKeyAuthorSchema)
|
|
73
|
+
.min(1, {
|
|
74
|
+
error: 'At least one author is required.',
|
|
75
|
+
})
|
|
76
|
+
.max(MAX_SIGNING_KEY_AUTHORS, { error: `At most ${MAX_SIGNING_KEY_AUTHORS} authors are allowed.` });
|
|
77
|
+
export function normalizeSigningKeyAuthors(authors) {
|
|
78
|
+
const parsed = signingKeyAuthorsSchema.safeParse(authors);
|
|
79
|
+
if (!parsed.success) {
|
|
80
|
+
const issue = parsed.error.issues[0];
|
|
81
|
+
const path = issue?.path.length ? `.${issue.path.join('.')}` : '';
|
|
82
|
+
throw new InvalidOptionsError(`Invalid authors${path}: ${issue?.message ?? 'invalid value'}`);
|
|
83
|
+
}
|
|
84
|
+
return parsed.data;
|
|
85
|
+
}
|
|
86
|
+
const signingKeyTokenInputSchema = z
|
|
87
|
+
.object({
|
|
88
|
+
authors: signingKeyAuthorsSchema.optional(),
|
|
89
|
+
scopes: z
|
|
90
|
+
.array(z.enum(SIGNING_KEY_TOKEN_SCOPES))
|
|
91
|
+
.min(1)
|
|
92
|
+
.transform((scopes) => [...new Set(scopes)])
|
|
93
|
+
.default(['admin']),
|
|
94
|
+
repos: z
|
|
95
|
+
.array(z
|
|
96
|
+
.string()
|
|
97
|
+
.min(1)
|
|
98
|
+
.refine((repo) => !looksLikePrivateKey(repo), {
|
|
99
|
+
error: 'Token repos must not contain Mesa private keys.',
|
|
100
|
+
}))
|
|
101
|
+
.nullable()
|
|
102
|
+
.optional(),
|
|
103
|
+
repoIds: z.array(z.string().min(1)).max(250).nullable().optional(),
|
|
104
|
+
ttlSeconds: z
|
|
105
|
+
.number()
|
|
106
|
+
.int()
|
|
107
|
+
.min(1)
|
|
108
|
+
.max(SIGNING_KEY_ACCESS_TOKEN_MAX_TTL_SECONDS)
|
|
109
|
+
.default(SIGNING_KEY_ACCESS_TOKEN_DEFAULT_TTL_SECONDS),
|
|
110
|
+
})
|
|
111
|
+
.refine((input) => input.repos === undefined || input.repoIds === undefined, {
|
|
112
|
+
error: 'Token repos and repoIds restrictions are mutually exclusive.',
|
|
113
|
+
});
|
|
114
|
+
/** Convert the public snake-case token fields to the signer restriction. */
|
|
115
|
+
export function toSignerRepositoryRestriction(input) {
|
|
116
|
+
if (input.repos !== undefined && input.repo_ids !== undefined) {
|
|
117
|
+
throw new InvalidOptionsError('Token repos and repo_ids restrictions are mutually exclusive');
|
|
118
|
+
}
|
|
119
|
+
return input.repo_ids !== undefined ? { repoIds: input.repo_ids } : { repos: input.repos ?? null };
|
|
120
|
+
}
|
|
121
|
+
/** Convert signer metadata back to the public snake-case token fields. */
|
|
122
|
+
export function toApiRepositoryRestriction(input) {
|
|
123
|
+
return input.repoIds !== undefined ? { repo_ids: input.repoIds } : { repos: input.repos ?? null };
|
|
124
|
+
}
|
|
44
125
|
/**
|
|
45
126
|
* Derive the HMAC signing secret from a raw API key. Byte-identical to the
|
|
46
127
|
* value stored in the server's `apikey.key` column. The HMAC key is the UTF-8
|
|
@@ -60,7 +141,7 @@ function base64UrlJson(value) {
|
|
|
60
141
|
/**
|
|
61
142
|
* Sign an access token with HS256 entirely client-side. The `iss` claim is the
|
|
62
143
|
* minting API key id (mirrors the `kid` header). JSON key order is not
|
|
63
|
-
* semantically meaningful
|
|
144
|
+
* semantically meaningful because the server verifies the signature, not a byte-exact
|
|
64
145
|
* string.
|
|
65
146
|
*/
|
|
66
147
|
export function signAccessToken(input) {
|
|
@@ -71,12 +152,16 @@ export function signAccessToken(input) {
|
|
|
71
152
|
const iat = Math.floor(Date.now() / 1000);
|
|
72
153
|
const exp = iat + ttlSeconds;
|
|
73
154
|
const jti = randomUUID();
|
|
155
|
+
if (input.repos !== undefined && input.repoIds !== undefined) {
|
|
156
|
+
throw new InvalidOptionsError('Token repos and repoIds restrictions are mutually exclusive');
|
|
157
|
+
}
|
|
158
|
+
const repoRestriction = input.repoIds !== undefined ? { repo_ids: input.repoIds } : { repos: input.repos ?? null };
|
|
74
159
|
const header = { alg: ACCESS_TOKEN_ALG, typ: ACCESS_TOKEN_TYP, kid: buildKid(input.apiKeyId) };
|
|
75
160
|
const payload = {
|
|
76
161
|
iss: input.apiKeyId,
|
|
77
162
|
aud: ACCESS_TOKEN_AUD,
|
|
78
163
|
scopes: input.scopes,
|
|
79
|
-
|
|
164
|
+
...repoRestriction,
|
|
80
165
|
iat,
|
|
81
166
|
exp,
|
|
82
167
|
jti,
|
|
@@ -89,7 +174,40 @@ export function signAccessToken(input) {
|
|
|
89
174
|
token,
|
|
90
175
|
expiresAt: new Date(exp * 1000).toISOString(),
|
|
91
176
|
scopes: input.scopes,
|
|
92
|
-
repos: input.repos,
|
|
177
|
+
...(input.repoIds !== undefined ? { repoIds: input.repoIds } : { repos: input.repos ?? null }),
|
|
178
|
+
jti,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/** Sign the minimal Ed25519 access-token contract accepted by the server. */
|
|
182
|
+
export function signPrivateKeyAccessToken(input) {
|
|
183
|
+
const parsed = signingKeyTokenInputSchema.safeParse(input);
|
|
184
|
+
if (!parsed.success) {
|
|
185
|
+
const issue = parsed.error.issues[0];
|
|
186
|
+
throw new InvalidOptionsError(`Invalid ${issue?.path.join('.') || 'token options'}: ${issue?.message ?? 'invalid value'}`);
|
|
187
|
+
}
|
|
188
|
+
const { authors, scopes, repos, repoIds, ttlSeconds } = parsed.data;
|
|
189
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
190
|
+
const exp = iat + ttlSeconds;
|
|
191
|
+
const jti = randomUUID();
|
|
192
|
+
const repoRestriction = repoIds !== undefined ? { repo_ids: repoIds } : { repos: repos ?? null };
|
|
193
|
+
const header = { alg: 'EdDSA', typ: ACCESS_TOKEN_TYP, jwk: input.credential.publicJwk };
|
|
194
|
+
const payload = {
|
|
195
|
+
iss: input.credential.org,
|
|
196
|
+
aud: ACCESS_TOKEN_AUD,
|
|
197
|
+
...(authors === undefined ? {} : { author: authors.map(({ name, email }) => [name, email]) }),
|
|
198
|
+
scopes,
|
|
199
|
+
...repoRestriction,
|
|
200
|
+
iat,
|
|
201
|
+
exp,
|
|
202
|
+
jti,
|
|
203
|
+
};
|
|
204
|
+
const signingInput = `${base64UrlJson(header)}.${base64UrlJson(payload)}`;
|
|
205
|
+
const signature = signEd25519(null, Buffer.from(signingInput, 'utf8'), input.credential.privateKey).toString('base64url');
|
|
206
|
+
return {
|
|
207
|
+
token: `${signingInput}.${signature}`,
|
|
208
|
+
expiresAt: new Date(exp * 1000).toISOString(),
|
|
209
|
+
scopes,
|
|
210
|
+
...(repoIds !== undefined ? { repoIds } : { repos: repos ?? null }),
|
|
93
211
|
jti,
|
|
94
212
|
};
|
|
95
213
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-token.js","sourceRoot":"","sources":["../../src/api/access-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"access-token.js","sourceRoot":"","sources":["../../src/api/access-token.ts"],"names":[],"mappings":"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"}
|
package/dist/api/client.d.ts
CHANGED
|
@@ -12,16 +12,14 @@ export type RestDataShape = {
|
|
|
12
12
|
export type RestOperation = (options: never) => Promise<unknown>;
|
|
13
13
|
export type RestRequestOptions<TData extends RestDataShape> = Simplify<Omit<RestOptions<TData, boolean>, 'baseUrl' | 'fetch' | 'headers' | 'responseStyle' | 'throwOnError'>>;
|
|
14
14
|
export type RestClientConfig = {
|
|
15
|
-
/** Bearer credential
|
|
16
|
-
credential: string;
|
|
15
|
+
/** Bearer credential, or a local signer that returns one for each request. */
|
|
16
|
+
credential: string | (() => string);
|
|
17
17
|
apiUrl: string;
|
|
18
18
|
fetch?: typeof globalThis.fetch;
|
|
19
19
|
userAgent?: string;
|
|
20
|
-
vcsUrl?: string;
|
|
21
20
|
};
|
|
22
|
-
export declare function isVcsRsUrl(value: string | undefined): boolean;
|
|
23
21
|
export type RestClient = {
|
|
24
|
-
request<TData extends RestDataShape, TResult>(operation: RestOperation, options?: RestRequestOptions<TData
|
|
22
|
+
request<TData extends RestDataShape, TResult>(operation: RestOperation, options?: RestRequestOptions<TData>, credentialOverride?: string): Promise<TResult>;
|
|
25
23
|
whoami(): Promise<WhoamiResponse>;
|
|
26
24
|
};
|
|
27
25
|
export declare function createRestClient(config: RestClientConfig): RestClient;
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,IAAI,WAAW,EAAmB,KAAK,cAAc,EAAU,MAAM,eAAe,CAAC;AAM1G,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,EAAE,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjE,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,aAAa,IAAI,QAAQ,CACpE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,eAAe,GAAG,cAAc,CAAC,CACtG,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,IAAI,WAAW,EAAmB,KAAK,cAAc,EAAU,MAAM,eAAe,CAAC;AAM1G,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,EAAE,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjE,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,aAAa,IAAI,QAAQ,CACpE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,eAAe,GAAG,cAAc,CAAC,CACtG,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAOF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,KAAK,SAAS,aAAa,EAAE,OAAO,EAC1C,SAAS,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,EACnC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;CACnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CA+CrE"}
|
package/dist/api/client.js
CHANGED
|
@@ -2,37 +2,22 @@ import { whoami } from '@mesadev/rest';
|
|
|
2
2
|
import { SDK_VERSION } from '../version.js';
|
|
3
3
|
import { normalizeApiError } from './errors.js';
|
|
4
4
|
const SDK_USER_AGENT = `mesa-sdk-ts/${SDK_VERSION}`;
|
|
5
|
-
export function isVcsRsUrl(value) {
|
|
6
|
-
if (!value)
|
|
7
|
-
return false;
|
|
8
|
-
try {
|
|
9
|
-
const url = new URL(value);
|
|
10
|
-
return url.hostname === '127.0.0.1';
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
5
|
export function createRestClient(config) {
|
|
17
6
|
const userAgent = config.userAgent?.trim();
|
|
18
|
-
const defaultHeaders = {
|
|
19
|
-
Authorization: `Bearer ${config.credential}`,
|
|
20
|
-
};
|
|
7
|
+
const defaultHeaders = {};
|
|
21
8
|
if (typeof process === 'undefined') {
|
|
22
9
|
defaultHeaders['X-Mesa-User-Agent'] = userAgent ? `${SDK_USER_AGENT} ${userAgent}` : SDK_USER_AGENT;
|
|
23
10
|
}
|
|
24
11
|
else {
|
|
25
12
|
defaultHeaders['User-Agent'] = userAgent ? `${SDK_USER_AGENT} ${userAgent}` : SDK_USER_AGENT;
|
|
26
13
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
const request = async (operation, options = {}) => {
|
|
14
|
+
const request = async (operation, options = {}, credentialOverride) => {
|
|
15
|
+
const credential = credentialOverride ?? (typeof config.credential === 'function' ? config.credential() : config.credential);
|
|
31
16
|
const requestOptions = {
|
|
32
17
|
...options,
|
|
33
18
|
baseUrl: config.apiUrl,
|
|
34
19
|
fetch: config.fetch,
|
|
35
|
-
headers: defaultHeaders,
|
|
20
|
+
headers: { ...defaultHeaders, Authorization: `Bearer ${credential}` },
|
|
36
21
|
responseStyle: 'fields',
|
|
37
22
|
throwOnError: false,
|
|
38
23
|
};
|
package/dist/api/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,cAAc,GAAG,eAAe,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,cAAc,GAAG,eAAe,WAAW,EAAE,CAAC;AAwCpD,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IAC3C,MAAM,cAAc,GAA2B,EAAE,CAAC;IAElD,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACnC,cAAc,CAAC,mBAAmB,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;IACtG,CAAC;SAAM,CAAC;QACN,cAAc,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;IAC/F,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,EACnB,SAAwB,EACxB,UAAqC,EAA+B,EACpE,kBAA2B,EACT,EAAE;QACpB,MAAM,UAAU,GACd,kBAAkB,IAAI,CAAC,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5G,MAAM,cAAc,GAAG;YACrB,GAAG,OAAO;YACV,OAAO,EAAE,MAAM,CAAC,MAAM;YACtB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,aAAa,EAAE,UAAU,UAAU,EAAE,EAAE;YACrE,aAAa,EAAE,QAAQ;YACvB,YAAY,EAAE,KAAK;SACW,CAAC;QAEjC,MAAM,QAAQ,GAAG,MAAO,SAAwE,CAAC,cAAc,CAAC,CAAC;QAEjH,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,aAAa,GAAG,QAAkD,CAAC;YAEzE,IAAI,aAAa,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACtC,MAAM,iBAAiB,CAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;YACvE,CAAC;YAED,IAAI,MAAM,IAAI,aAAa,EAAE,CAAC;gBAC5B,OAAO,aAAa,CAAC,IAAe,CAAC;YACvC,CAAC;QACH,CAAC;QAED,OAAO,QAAmB,CAAC;IAC7B,CAAC,CAAC;IAEF,OAAO;QACL,OAAO;QACP,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAA6B,MAAM,CAAC;KAC1D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM1D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const MESA_PRIVATE_KEY_PREFIX = 'mesa_private_key_';
|
|
2
|
+
/** Recognize private-key formats before a value reaches an outbound request. */
|
|
3
|
+
export function looksLikePrivateKey(input) {
|
|
4
|
+
const value = input.trim();
|
|
5
|
+
return (value.toLowerCase().includes(MESA_PRIVATE_KEY_PREFIX) ||
|
|
6
|
+
/^-----(?:BEGIN|END) (?:[A-Z0-9]+ )*PRIVATE KEY-----$/im.test(value));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAE3D,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,OAAO,CACL,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACrD,wDAAwD,CAAC,IAAI,CAAC,KAAK,CAAC,CACrE,CAAC;AACJ,CAAC"}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { type ApiKeysCreateInput, type ApiKeysListInput, type ApiKeysRevokeInput, type ApiResources, type BookmarksCreateInput, type BookmarksDeleteInput, type BookmarksListInput, type ChangesCreateInput, type ChangesGetInput, type ChangesListInput, type ContentGetInput, createApiResources, type DiffsGetInput, type OrgGetInput, type ReposCreateInput, type ReposDeleteInput, type ReposGetInput, type ReposListInput, type ReposUpdateInput, type WebhookTargetsCreateInput, type WebhookTargetsDeleteInput, type WebhookTargetsListInput, type WebhookTargetsUpdateInput, } from './resources.js';
|
|
1
|
+
export { type ApiKeysCreateInput, type ApiKeysListInput, type ApiKeysRevokeInput, type ApiResources, type BookmarksCreateInput, type BookmarksDeleteInput, type BookmarksListInput, type ChangesCreateInput, type ChangesGetInput, type ChangesListInput, type ContentGetInput, createApiResources, type DiffsGetInput, type OrgGetInput, type ReposCreateInput, type ReposDeleteInput, type ReposGetInput, type ReposListInput, type ReposUpdateInput, type TokensCreateAuthor, type TokensCreateInput, type TokensCreateLegacyInput, type TokensCreatePrivateKeyInput, type TokensCreateResponse, type WebhookTargetsCreateInput, type WebhookTargetsDeleteInput, type WebhookTargetsListInput, type WebhookTargetsUpdateInput, } from './resources.js';
|
|
2
2
|
export { type RepoTagFilter, type RepoTagValueFilter } from './repo-tag-filter.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/api/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAYL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAYL,kBAAkB,GAiBnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAA+C,MAAM,sBAAsB,CAAC"}
|