@karmaniverous/jeeves-server-core 0.3.0 → 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/README.md +58 -13
- package/dist/openapi.json.js +4038 -0
- package/dist/scripts/openapiInfo.d.ts +15 -0
- package/dist/src/catalog/browserSafe.test.d.ts +4 -0
- package/dist/src/catalog/contentEntries.d.ts +468 -0
- package/dist/src/catalog/contentEntries.js +150 -0
- package/dist/src/catalog/contentSchemas.d.ts +179 -0
- package/dist/src/catalog/contentSchemas.js +195 -0
- package/dist/src/catalog/descriptions.d.ts +52 -0
- package/dist/src/catalog/descriptions.js +54 -0
- package/dist/src/catalog/eventEntries.d.ts +70 -0
- package/dist/src/catalog/eventEntries.js +59 -0
- package/dist/src/catalog/fileMutateSchema.d.ts +41 -0
- package/dist/src/catalog/fileMutateSchema.js +77 -0
- package/dist/src/catalog/index.d.ts +15 -0
- package/dist/src/catalog/index.js +10 -0
- package/dist/src/catalog/oauthEntries.d.ts +125 -0
- package/dist/src/catalog/oauthEntries.js +92 -0
- package/dist/src/catalog/route.d.ts +137 -0
- package/dist/src/catalog/route.js +92 -0
- package/dist/src/catalog/runnerEntries.d.ts +145 -0
- package/dist/src/catalog/runnerEntries.js +69 -0
- package/dist/src/catalog/schemas.test.d.ts +4 -0
- package/dist/src/catalog/serverCatalog.d.ts +1143 -0
- package/dist/src/catalog/serverCatalog.js +37 -0
- package/dist/src/catalog/serverCatalog.test.d.ts +4 -0
- package/dist/src/catalog/sharingEntries.d.ts +200 -0
- package/dist/src/catalog/sharingEntries.js +146 -0
- package/dist/src/catalog/statusSchemas.d.ts +87 -0
- package/dist/src/catalog/statusSchemas.js +119 -0
- package/dist/src/catalog/utilityEntries.d.ts +151 -0
- package/dist/src/catalog/utilityEntries.js +62 -0
- package/dist/src/catalog/utilitySchemas.d.ts +98 -0
- package/dist/src/catalog/utilitySchemas.js +131 -0
- package/dist/src/configAuthSchema.d.ts +100 -0
- package/dist/src/configAuthSchema.js +119 -0
- package/dist/src/configFeatureSchemas.d.ts +43 -0
- package/dist/src/configFeatureSchemas.js +53 -0
- package/dist/src/configPrintStyles.d.ts +63 -0
- package/dist/src/configPrintStyles.js +98 -0
- package/dist/src/configPrintStyles.test.d.ts +1 -0
- package/dist/src/crypto.d.ts +6 -13
- package/dist/src/crypto.js +7 -32
- package/dist/src/crypto.test.d.ts +7 -0
- package/dist/src/errors.d.ts +51 -0
- package/dist/src/errors.js +97 -0
- package/dist/src/errors.test.d.ts +4 -0
- package/dist/src/index.d.ts +5 -2
- package/dist/src/index.js +18 -3
- package/dist/src/openapi.d.ts +13 -0
- package/dist/src/openapi.js +17 -0
- package/dist/src/openapi.test.d.ts +4 -0
- package/dist/src/schema.d.ts +21 -122
- package/dist/src/schema.js +39 -153
- package/dist/src/schema.publicUrl.test.d.ts +1 -0
- package/dist/src/schema.test.d.ts +1 -0
- package/dist/src/types.d.ts +7 -0
- package/dist/src/urlKey.d.ts +24 -0
- package/dist/src/urlKey.js +43 -0
- package/dist/src/urlKey.test.d.ts +1 -0
- package/openapi.json +3934 -0
- package/package.json +31 -16
- package/dist/src/endpoints.d.ts +0 -34
- package/dist/src/endpoints.js +0 -235
- /package/dist/src/{endpoints.test.d.ts → configAuthSchema.test.d.ts} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `fileMutate` request body: one object with an `action` enum and the union of the actions' fields, each action's required fields checked by a refinement (catalog bodies must be Zod objects). Pure.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/** The mutation actions. */
|
|
9
|
+
const FILE_MUTATION_ACTIONS = [
|
|
10
|
+
'edit-block',
|
|
11
|
+
'delete-block',
|
|
12
|
+
'insert-block',
|
|
13
|
+
'edit-cell',
|
|
14
|
+
'toggle-checkbox',
|
|
15
|
+
];
|
|
16
|
+
/** Fields each action requires. */
|
|
17
|
+
const FILE_MUTATION_REQUIRED_FIELDS = {
|
|
18
|
+
'edit-block': ['startLine', 'endLine', 'content'],
|
|
19
|
+
'delete-block': ['startLine', 'endLine'],
|
|
20
|
+
'insert-block': ['atLine', 'position', 'content'],
|
|
21
|
+
'edit-cell': ['line', 'col', 'content'],
|
|
22
|
+
'toggle-checkbox': ['index', 'checked'],
|
|
23
|
+
};
|
|
24
|
+
/** A whole line number (1-based) or index. */
|
|
25
|
+
const whole = (description) => z.number().int().optional().describe(description);
|
|
26
|
+
/** `fileMutate` body. */
|
|
27
|
+
const fileMutateBodySchema = z
|
|
28
|
+
.object({
|
|
29
|
+
/** Mutation to perform. */
|
|
30
|
+
action: z
|
|
31
|
+
.enum(FILE_MUTATION_ACTIONS)
|
|
32
|
+
.describe('Mutation action to perform'),
|
|
33
|
+
/** First line of the block (edit-block, delete-block). */
|
|
34
|
+
startLine: whole('Start line (1-based) for edit-block/delete-block'),
|
|
35
|
+
/** Last line of the block (edit-block, delete-block). */
|
|
36
|
+
endLine: whole('End line (1-based) for edit-block/delete-block'),
|
|
37
|
+
/** New text (edit-block, insert-block, edit-cell). */
|
|
38
|
+
content: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe('Content for edit-block, insert-block, or edit-cell'),
|
|
42
|
+
/** Target line (insert-block). */
|
|
43
|
+
atLine: whole('Target line (1-based) for insert-block'),
|
|
44
|
+
/** Insert before or after `atLine` (insert-block). */
|
|
45
|
+
position: z
|
|
46
|
+
.enum(['before', 'after'])
|
|
47
|
+
.optional()
|
|
48
|
+
.describe('Insert position for insert-block'),
|
|
49
|
+
/** Insert context (insert-block): `table-row` adds no blank lines. */
|
|
50
|
+
context: z
|
|
51
|
+
.string()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('Optional context for insert-block (e.g. "table-row")'),
|
|
54
|
+
/** Table line (edit-cell). */
|
|
55
|
+
line: whole('Line number (1-based) for edit-cell'),
|
|
56
|
+
/** Table column (edit-cell). */
|
|
57
|
+
col: whole('Column index (0-based) for edit-cell'),
|
|
58
|
+
/** Checkbox index (toggle-checkbox). */
|
|
59
|
+
index: whole('Checkbox index (0-based) for toggle-checkbox'),
|
|
60
|
+
/** Desired state (toggle-checkbox). */
|
|
61
|
+
checked: z
|
|
62
|
+
.boolean()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Desired checked state for toggle-checkbox'),
|
|
65
|
+
})
|
|
66
|
+
.superRefine((body, ctx) => {
|
|
67
|
+
for (const field of FILE_MUTATION_REQUIRED_FIELDS[body.action]) {
|
|
68
|
+
if (body[field] === undefined)
|
|
69
|
+
ctx.addIssue({
|
|
70
|
+
code: 'custom',
|
|
71
|
+
path: [field],
|
|
72
|
+
message: `${body.action} requires ${field}`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export { FILE_MUTATION_ACTIONS, FILE_MUTATION_REQUIRED_FIELDS, fileMutateBodySchema };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe entry point of jeeves-server-core (`@karmaniverous/jeeves-server-core/catalog`): the endpoint catalog, its request and response schemas and the error codes. Imports only `zod` and `@karmaniverous/jeeves/catalog`, never Node built-ins, so the SDK and the web client can bundle it.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { SERVER_ERROR_CODES, SERVER_ERROR_STATUS, type ServerErrorCode, } from '../errors.js';
|
|
7
|
+
export { breadcrumbSchema, browseResponseSchema, directoryEntrySchema, directoryListingSchema, driveSchema, drivesResponseSchema, exportCacheClearResponseSchema, exportLinkSchema, fileContentQuerySchema, fileContentResponseSchema, fileMetadataSchema, fileWriteBodySchema, fileWriteResponseSchema, headingSchema, linkInfoResponseSchema, okResponseSchema, } from './contentSchemas.js';
|
|
8
|
+
export { eventLogEntrySchema, receiveEventResponseSchema, } from './eventEntries.js';
|
|
9
|
+
export { FILE_MUTATION_ACTIONS, FILE_MUTATION_REQUIRED_FIELDS, type FileMutateBody, fileMutateBodySchema, } from './fileMutateSchema.js';
|
|
10
|
+
export { oauthCredentialQuerySchema, oauthStartBodySchema, oauthStartResponseSchema, oauthStatusResponseSchema, oauthTokenResponseSchema, } from './oauthEntries.js';
|
|
11
|
+
export { shareQuerySchema } from './route.js';
|
|
12
|
+
export { SERVER_CATALOG, type ServerCatalog, type ServerEntry, type ServerEntryName, type ServerHealth, type ServerInput, type ServerResponse, } from './serverCatalog.js';
|
|
13
|
+
export { linkResponseSchema, resolvePathResponseSchema, rotateKeyResponseSchema, shareBodySchema, shareForBodySchema, shareForResponseSchema, shareResponseSchema, } from './sharingEntries.js';
|
|
14
|
+
export { eventQueueHealthSchema, serverHealthSchema, serviceProbeSchema, } from './statusSchemas.js';
|
|
15
|
+
export { authStatusQuerySchema, authStatusResponseSchema, healthResponseSchema, insiderKeyResponseSchema, pathKeyResponseSchema, searchBodySchema, searchResponseSchema, searchResultSchema, sendMagicLinkBodySchema, sendMagicLinkResponseSchema, } from './utilitySchemas.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { SERVER_ERROR_CODES, SERVER_ERROR_STATUS } from '../errors.js';
|
|
2
|
+
export { breadcrumbSchema, browseResponseSchema, directoryEntrySchema, directoryListingSchema, driveSchema, drivesResponseSchema, exportCacheClearResponseSchema, exportLinkSchema, fileContentQuerySchema, fileContentResponseSchema, fileMetadataSchema, fileWriteBodySchema, fileWriteResponseSchema, headingSchema, linkInfoResponseSchema, okResponseSchema } from './contentSchemas.js';
|
|
3
|
+
export { eventLogEntrySchema, receiveEventResponseSchema } from './eventEntries.js';
|
|
4
|
+
export { FILE_MUTATION_ACTIONS, FILE_MUTATION_REQUIRED_FIELDS, fileMutateBodySchema } from './fileMutateSchema.js';
|
|
5
|
+
export { oauthCredentialQuerySchema, oauthStartBodySchema, oauthStartResponseSchema, oauthStatusResponseSchema, oauthTokenResponseSchema } from './oauthEntries.js';
|
|
6
|
+
export { shareQuerySchema } from './route.js';
|
|
7
|
+
export { SERVER_CATALOG } from './serverCatalog.js';
|
|
8
|
+
export { linkResponseSchema, resolvePathResponseSchema, rotateKeyResponseSchema, shareBodySchema, shareForBodySchema, shareForResponseSchema, shareResponseSchema } from './sharingEntries.js';
|
|
9
|
+
export { eventQueueHealthSchema, serverHealthSchema, serviceProbeSchema } from './statusSchemas.js';
|
|
10
|
+
export { authStatusQuerySchema, authStatusResponseSchema, healthResponseSchema, insiderKeyResponseSchema, pathKeyResponseSchema, searchBodySchema, searchResponseSchema, searchResultSchema, sendMagicLinkBodySchema, sendMagicLinkResponseSchema } from './utilitySchemas.js';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OAuth entries of the server catalog: start an authorization code flow, check stored credentials and get an access token. Pure.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/** `oauthStart` body. */
|
|
8
|
+
export declare const oauthStartBodySchema: z.ZodObject<{
|
|
9
|
+
provider: z.ZodString;
|
|
10
|
+
account: z.ZodString;
|
|
11
|
+
authUrl: z.ZodOptional<z.ZodString>;
|
|
12
|
+
tokenUrl: z.ZodOptional<z.ZodString>;
|
|
13
|
+
clientId: z.ZodString;
|
|
14
|
+
clientSecret: z.ZodString;
|
|
15
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
|
+
pkce: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
/** `oauthStart` response. */
|
|
20
|
+
export declare const oauthStartResponseSchema: z.ZodObject<{
|
|
21
|
+
authUrl: z.ZodString;
|
|
22
|
+
state: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
/** `oauthStatus` and `oauthToken` query. */
|
|
25
|
+
export declare const oauthCredentialQuerySchema: z.ZodObject<{
|
|
26
|
+
provider: z.ZodString;
|
|
27
|
+
account: z.ZodString;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
/** `oauthStatus` response. */
|
|
30
|
+
export declare const oauthStatusResponseSchema: z.ZodObject<{
|
|
31
|
+
exists: z.ZodBoolean;
|
|
32
|
+
expired: z.ZodBoolean;
|
|
33
|
+
provider: z.ZodString;
|
|
34
|
+
account: z.ZodString;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
/** `oauthToken` response. */
|
|
37
|
+
export declare const oauthTokenResponseSchema: z.ZodObject<{
|
|
38
|
+
access_token: z.ZodString;
|
|
39
|
+
token_type: z.ZodString;
|
|
40
|
+
expires_in_seconds: z.ZodNullable<z.ZodNumber>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
/** The OAuth entries. */
|
|
43
|
+
export declare const OAUTH_ENTRIES: readonly [{
|
|
44
|
+
readonly body: z.ZodObject<{
|
|
45
|
+
provider: z.ZodString;
|
|
46
|
+
account: z.ZodString;
|
|
47
|
+
authUrl: z.ZodOptional<z.ZodString>;
|
|
48
|
+
tokenUrl: z.ZodOptional<z.ZodString>;
|
|
49
|
+
clientId: z.ZodString;
|
|
50
|
+
clientSecret: z.ZodString;
|
|
51
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
52
|
+
pkce: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
readonly response: z.ZodObject<{
|
|
56
|
+
authUrl: z.ZodString;
|
|
57
|
+
state: z.ZodString;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
readonly auth: {
|
|
60
|
+
readonly schemes: readonly [{
|
|
61
|
+
readonly in: "query";
|
|
62
|
+
readonly name: "k";
|
|
63
|
+
}, {
|
|
64
|
+
readonly in: "cookie";
|
|
65
|
+
readonly name: "jeeves_session";
|
|
66
|
+
}];
|
|
67
|
+
readonly insiderOnly: true;
|
|
68
|
+
};
|
|
69
|
+
readonly kind: "write";
|
|
70
|
+
readonly name: "oauthStart";
|
|
71
|
+
readonly method: "POST";
|
|
72
|
+
readonly path: "/api/oauth/start";
|
|
73
|
+
readonly description: "Start an OAuth2 authorization code flow; returns the URL to open in a browser.";
|
|
74
|
+
}, {
|
|
75
|
+
readonly query: z.ZodObject<{
|
|
76
|
+
provider: z.ZodString;
|
|
77
|
+
account: z.ZodString;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
readonly response: z.ZodObject<{
|
|
80
|
+
exists: z.ZodBoolean;
|
|
81
|
+
expired: z.ZodBoolean;
|
|
82
|
+
provider: z.ZodString;
|
|
83
|
+
account: z.ZodString;
|
|
84
|
+
}, z.core.$strip>;
|
|
85
|
+
readonly auth: {
|
|
86
|
+
readonly schemes: readonly [{
|
|
87
|
+
readonly in: "query";
|
|
88
|
+
readonly name: "k";
|
|
89
|
+
}, {
|
|
90
|
+
readonly in: "cookie";
|
|
91
|
+
readonly name: "jeeves_session";
|
|
92
|
+
}];
|
|
93
|
+
readonly insiderOnly: true;
|
|
94
|
+
};
|
|
95
|
+
readonly kind: "read";
|
|
96
|
+
readonly name: "oauthStatus";
|
|
97
|
+
readonly method: "GET";
|
|
98
|
+
readonly path: "/api/oauth/status";
|
|
99
|
+
readonly description: "Check whether valid OAuth2 credentials exist for a provider/account.";
|
|
100
|
+
}, {
|
|
101
|
+
readonly query: z.ZodObject<{
|
|
102
|
+
provider: z.ZodString;
|
|
103
|
+
account: z.ZodString;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
readonly response: z.ZodObject<{
|
|
106
|
+
access_token: z.ZodString;
|
|
107
|
+
token_type: z.ZodString;
|
|
108
|
+
expires_in_seconds: z.ZodNullable<z.ZodNumber>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
readonly auth: {
|
|
111
|
+
readonly schemes: readonly [{
|
|
112
|
+
readonly in: "query";
|
|
113
|
+
readonly name: "k";
|
|
114
|
+
}, {
|
|
115
|
+
readonly in: "cookie";
|
|
116
|
+
readonly name: "jeeves_session";
|
|
117
|
+
}];
|
|
118
|
+
readonly insiderOnly: true;
|
|
119
|
+
};
|
|
120
|
+
readonly kind: "read";
|
|
121
|
+
readonly name: "oauthToken";
|
|
122
|
+
readonly method: "GET";
|
|
123
|
+
readonly path: "/api/oauth/token";
|
|
124
|
+
readonly description: "Get a valid access token for a provider/account, refreshing it when expired.";
|
|
125
|
+
}];
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { INSIDER_ONLY, route } from './route.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The OAuth entries of the server catalog: start an authorization code flow, check stored credentials and get an access token. Pure.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/** `oauthStart` body. */
|
|
10
|
+
const oauthStartBodySchema = z.object({
|
|
11
|
+
/** Provider name (a configured provider supplies the defaults). */
|
|
12
|
+
provider: z.string().describe('Provider name.'),
|
|
13
|
+
/** Account name the credential is stored under. */
|
|
14
|
+
account: z.string().describe('Account name.'),
|
|
15
|
+
/** Authorization endpoint (default: the configured provider's). */
|
|
16
|
+
authUrl: z.string().optional().describe('Authorization endpoint URL.'),
|
|
17
|
+
/** Token endpoint (default: the configured provider's). */
|
|
18
|
+
tokenUrl: z.string().optional().describe('Token endpoint URL.'),
|
|
19
|
+
/** Client id. */
|
|
20
|
+
clientId: z.string().describe('OAuth client id.'),
|
|
21
|
+
/** Client secret. */
|
|
22
|
+
clientSecret: z.string().describe('OAuth client secret.'),
|
|
23
|
+
/** Scopes (default: the configured provider's). */
|
|
24
|
+
scopes: z.array(z.string()).optional().describe('Scopes to request.'),
|
|
25
|
+
/** Use PKCE (default: the configured provider's, else false). */
|
|
26
|
+
pkce: z.boolean().optional().describe('Use PKCE.'),
|
|
27
|
+
/** Origin of the redirect URI (default: the configured public URL). */
|
|
28
|
+
origin: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Origin for the redirect URI (default: the public URL).'),
|
|
32
|
+
});
|
|
33
|
+
/** `oauthStart` response. */
|
|
34
|
+
const oauthStartResponseSchema = z.object({
|
|
35
|
+
/** URL to open in a browser. */
|
|
36
|
+
authUrl: z.string(),
|
|
37
|
+
/** The flow's state value. */
|
|
38
|
+
state: z.string(),
|
|
39
|
+
});
|
|
40
|
+
/** `oauthStatus` and `oauthToken` query. */
|
|
41
|
+
const oauthCredentialQuerySchema = z.object({
|
|
42
|
+
/** Provider name. */
|
|
43
|
+
provider: z.string().describe('Provider name.'),
|
|
44
|
+
/** Account name. */
|
|
45
|
+
account: z.string().describe('Account name.'),
|
|
46
|
+
});
|
|
47
|
+
/** `oauthStatus` response. */
|
|
48
|
+
const oauthStatusResponseSchema = z.object({
|
|
49
|
+
/** A credential file exists. */
|
|
50
|
+
exists: z.boolean(),
|
|
51
|
+
/** It has expired (or can't be read). */
|
|
52
|
+
expired: z.boolean(),
|
|
53
|
+
/** Provider asked for. */
|
|
54
|
+
provider: z.string(),
|
|
55
|
+
/** Account asked for. */
|
|
56
|
+
account: z.string(),
|
|
57
|
+
});
|
|
58
|
+
/** `oauthToken` response. */
|
|
59
|
+
const oauthTokenResponseSchema = z.object({
|
|
60
|
+
/** Access token. */
|
|
61
|
+
access_token: z.string(),
|
|
62
|
+
/** Token type (normally `Bearer`). */
|
|
63
|
+
token_type: z.string(),
|
|
64
|
+
/** Seconds until expiry, or null when unknown. */
|
|
65
|
+
expires_in_seconds: z.number().nullable(),
|
|
66
|
+
});
|
|
67
|
+
/** The OAuth entries. */
|
|
68
|
+
const OAUTH_ENTRIES = [
|
|
69
|
+
{
|
|
70
|
+
...route('oauthStart', 'POST', '/api/oauth/start'),
|
|
71
|
+
body: oauthStartBodySchema,
|
|
72
|
+
response: oauthStartResponseSchema,
|
|
73
|
+
auth: INSIDER_ONLY,
|
|
74
|
+
kind: 'write',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
...route('oauthStatus', 'GET', '/api/oauth/status'),
|
|
78
|
+
query: oauthCredentialQuerySchema,
|
|
79
|
+
response: oauthStatusResponseSchema,
|
|
80
|
+
auth: INSIDER_ONLY,
|
|
81
|
+
kind: 'read',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
...route('oauthToken', 'GET', '/api/oauth/token'),
|
|
85
|
+
query: oauthCredentialQuerySchema,
|
|
86
|
+
response: oauthTokenResponseSchema,
|
|
87
|
+
auth: INSIDER_ONLY,
|
|
88
|
+
kind: 'read',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
export { OAUTH_ENTRIES, oauthCredentialQuerySchema, oauthStartBodySchema, oauthStartResponseSchema, oauthStatusResponseSchema, oauthTokenResponseSchema };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared parts of the jeeves-server catalog entries: the `route` helper (name, method, path, description), the auth specs of the access classes, the `*` path params and the share-credential query (`shareQuerySchema`). Pure.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Auth specs are descriptive (jeeves spec Decision 80): the service's access
|
|
6
|
+
* hook enforces the access model. Identity and share credentials travel as
|
|
7
|
+
* the `k` query parameter or the `jeeves_session` cookie; the key-exchange
|
|
8
|
+
* routes take the raw machine seed in `X-API-Key`.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { ENTRY_DESCRIPTIONS } from './descriptions.js';
|
|
14
|
+
/** The server's own entry names (other than the three standard ones). */
|
|
15
|
+
export type ServerRouteName = keyof typeof ENTRY_DESCRIPTIONS;
|
|
16
|
+
/**
|
|
17
|
+
* Name, method, path and description of a server entry.
|
|
18
|
+
*
|
|
19
|
+
* @param name - Entry name (also the SDK method, the plugin tool's base name
|
|
20
|
+
* and the OpenAPI `operationId`).
|
|
21
|
+
* @param method - HTTP method.
|
|
22
|
+
* @param path - Route path (Fastify syntax).
|
|
23
|
+
* @returns The entry's identity fields.
|
|
24
|
+
*/
|
|
25
|
+
export declare function route<const N extends ServerRouteName, const M extends 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT', const P extends string>(name: N, method: M, path: P): {
|
|
26
|
+
readonly name: N;
|
|
27
|
+
readonly method: M;
|
|
28
|
+
readonly path: P;
|
|
29
|
+
readonly description: {
|
|
30
|
+
readonly health: "Liveness check: returns { ok: true }, with no downstream checks.";
|
|
31
|
+
readonly authStatus: "Check current authentication status. Returns whether authenticated, email, insider status, and key metadata.";
|
|
32
|
+
readonly sendMagicLink: "Request a sign-in link by email. Always answers with a verification URL, whether or not the email belongs to an insider.";
|
|
33
|
+
readonly drives: "List available root drives/labels configured on the server.";
|
|
34
|
+
readonly browse: "Get file or directory metadata. For files: size, mtime, content type, rendered HTML availability. For directories: listing of entries.";
|
|
35
|
+
readonly fileContent: "Get a file with type-specific handling: Markdown, CSV and diagrams rendered to HTML, other text as is, images and binaries by name. `raw=1` skips rendering.";
|
|
36
|
+
readonly fileWrite: "Overwrite the content of an existing file. Insider-only; the file must already exist.";
|
|
37
|
+
readonly fileMutate: "Apply a structured mutation to a .md file. Insider-only. Supports: edit-block, delete-block, insert-block, edit-cell, toggle-checkbox.";
|
|
38
|
+
readonly raw: "Download a file as is, with its own content type. `download=1` always sends it as an attachment.";
|
|
39
|
+
readonly export: "Export a Markdown document as PDF or DOCX, or a directory as a ZIP or Tar archive (archives for insiders only).";
|
|
40
|
+
readonly exportCacheClear: "Clear the export and diagram caches for a given path.";
|
|
41
|
+
readonly exportMermaid: "Export a Mermaid diagram file as SVG, PNG or PDF.";
|
|
42
|
+
readonly exportPlantUml: "Export a PlantUML diagram file in one of the formats the configured renderers support (SVG, PNG, PDF, EPS).";
|
|
43
|
+
readonly linkInfo: "Query available link types for a path (exists, page URL, raw URL, export links for PDF/DOCX/SVG/PNG).";
|
|
44
|
+
readonly diagram: "Get a diagram embedded in a rendered document, as SVG, by its type and content hash.";
|
|
45
|
+
readonly publicContent: "Get one of the public pages of the server (readme, privacy, terms) rendered as Markdown.";
|
|
46
|
+
readonly share: "Sign a share link for a path: a path key, optionally expiring, or a deep share (`depth`, `dirs`). The response reports whether the path is a directory.";
|
|
47
|
+
readonly shareFor: "Sign a share link for a path aimed at named insiders: an insider link when every recipient is an insider with access, else an outsider share checked against the outsider policy.";
|
|
48
|
+
readonly contentLink: "Pre-computed share link for one of the pinned content pages of the server (privacy, terms).";
|
|
49
|
+
readonly readmeLink: "Pre-computed share link for the README of the server.";
|
|
50
|
+
readonly resolvePath: "Convert an absolute filesystem path to a server browse path and optional public URL.";
|
|
51
|
+
readonly rotateKey: "Rotate the key of the calling insider. The old insider key and every outsider link the insider signed stop working.";
|
|
52
|
+
readonly pathKey: "Compute the outsider path key for a path from the machine seed sent in X-API-Key.";
|
|
53
|
+
readonly insiderKey: "Compute the insider key for the machine seed sent in X-API-Key.";
|
|
54
|
+
readonly search: "Semantic search through jeeves-watcher, grouped by file and filtered to the scopes of the caller.";
|
|
55
|
+
readonly searchFacets: "Search facets from jeeves-watcher, passed through unchanged.";
|
|
56
|
+
readonly receiveEvent: "Event gateway webhook receiver: matches a JSON object against the configured event schemas and queues the matching command.";
|
|
57
|
+
readonly listEvents: "Recent event log entries, newest last (insiders with no scopes configured; limit capped at 100).";
|
|
58
|
+
readonly oauthStart: "Start an OAuth2 authorization code flow; returns the URL to open in a browser.";
|
|
59
|
+
readonly oauthStatus: "Check whether valid OAuth2 credentials exist for a provider/account.";
|
|
60
|
+
readonly oauthToken: "Get a valid access token for a provider/account, refreshing it when expired.";
|
|
61
|
+
readonly runnerListJobs: "List the jeeves-runner jobs (runner GET /jobs).";
|
|
62
|
+
readonly runnerGetJob: "One jeeves-runner job (runner GET /jobs/:id).";
|
|
63
|
+
readonly runnerListRuns: "A jeeves-runner job's recent runs (runner GET /jobs/:id/runs).";
|
|
64
|
+
readonly runnerRunJob: "Run a jeeves-runner job now (runner POST /jobs/:id/run).";
|
|
65
|
+
readonly runnerEnableJob: "Enable a jeeves-runner job (runner PATCH /jobs/:id/enable).";
|
|
66
|
+
readonly runnerDisableJob: "Disable a jeeves-runner job (runner PATCH /jobs/:id/disable).";
|
|
67
|
+
readonly runnerStatus: "jeeves-runner status (runner GET /status).";
|
|
68
|
+
}[N];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* `navigation` and `content` entries: an identity (session or insider key)
|
|
72
|
+
* or a share credential.
|
|
73
|
+
*/
|
|
74
|
+
export declare const KEY_OR_SESSION: {
|
|
75
|
+
readonly schemes: readonly [{
|
|
76
|
+
readonly in: "query";
|
|
77
|
+
readonly name: "k";
|
|
78
|
+
}, {
|
|
79
|
+
readonly in: "cookie";
|
|
80
|
+
readonly name: "jeeves_session";
|
|
81
|
+
}];
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* `insider`, `admin` and `content + insider` entries: an identity only
|
|
85
|
+
* (the service narrows `admin` to identities with no scopes).
|
|
86
|
+
*/
|
|
87
|
+
export declare const INSIDER_ONLY: {
|
|
88
|
+
readonly schemes: readonly [{
|
|
89
|
+
readonly in: "query";
|
|
90
|
+
readonly name: "k";
|
|
91
|
+
}, {
|
|
92
|
+
readonly in: "cookie";
|
|
93
|
+
readonly name: "jeeves_session";
|
|
94
|
+
}];
|
|
95
|
+
readonly insiderOnly: true;
|
|
96
|
+
};
|
|
97
|
+
/** `machineSeed` entries: the raw machine seed in `X-API-Key`. */
|
|
98
|
+
export declare const MACHINE_SEED: {
|
|
99
|
+
readonly schemes: readonly [{
|
|
100
|
+
readonly in: "header";
|
|
101
|
+
readonly name: "X-API-Key";
|
|
102
|
+
}];
|
|
103
|
+
};
|
|
104
|
+
/** `eventKey` entries: a machine key valid for `/event`, as `k`. */
|
|
105
|
+
export declare const EVENT_KEY: {
|
|
106
|
+
readonly schemes: readonly [{
|
|
107
|
+
readonly in: "query";
|
|
108
|
+
readonly name: "k";
|
|
109
|
+
}];
|
|
110
|
+
};
|
|
111
|
+
/** `public` entries. */
|
|
112
|
+
export declare const PUBLIC: "none";
|
|
113
|
+
/**
|
|
114
|
+
* Share-link parameters other than `k`, accepted by every content and
|
|
115
|
+
* navigation entry (and read by `authStatus`): an expiry, the deep-share
|
|
116
|
+
* fields and the legacy key parameter. All optional strings.
|
|
117
|
+
*/
|
|
118
|
+
export declare const shareQuerySchema: z.ZodObject<{
|
|
119
|
+
exp: z.ZodOptional<z.ZodString>;
|
|
120
|
+
d: z.ZodOptional<z.ZodString>;
|
|
121
|
+
dirs: z.ZodOptional<z.ZodString>;
|
|
122
|
+
s: z.ZodOptional<z.ZodString>;
|
|
123
|
+
key: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
/**
|
|
126
|
+
* The `*` path parameter: a browse path (`<root>/<path>`).
|
|
127
|
+
*
|
|
128
|
+
* @param description - What the path addresses.
|
|
129
|
+
* @returns The params schema.
|
|
130
|
+
*/
|
|
131
|
+
export declare const wildcardParams: (description: string) => z.ZodObject<{
|
|
132
|
+
'*': z.ZodString;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
/** `*` of the content entries that address a file or a directory. */
|
|
135
|
+
export declare const browsePathParams: z.ZodObject<{
|
|
136
|
+
'*': z.ZodString;
|
|
137
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ENTRY_DESCRIPTIONS } from './descriptions.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Shared parts of the jeeves-server catalog entries: the `route` helper (name, method, path, description), the auth specs of the access classes, the `*` path params and the share-credential query (`shareQuerySchema`). Pure.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Auth specs are descriptive (jeeves spec Decision 80): the service's access
|
|
9
|
+
* hook enforces the access model. Identity and share credentials travel as
|
|
10
|
+
* the `k` query parameter or the `jeeves_session` cookie; the key-exchange
|
|
11
|
+
* routes take the raw machine seed in `X-API-Key`.
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Name, method, path and description of a server entry.
|
|
17
|
+
*
|
|
18
|
+
* @param name - Entry name (also the SDK method, the plugin tool's base name
|
|
19
|
+
* and the OpenAPI `operationId`).
|
|
20
|
+
* @param method - HTTP method.
|
|
21
|
+
* @param path - Route path (Fastify syntax).
|
|
22
|
+
* @returns The entry's identity fields.
|
|
23
|
+
*/
|
|
24
|
+
function route(name, method, path) {
|
|
25
|
+
return {
|
|
26
|
+
name,
|
|
27
|
+
method,
|
|
28
|
+
path,
|
|
29
|
+
description: ENTRY_DESCRIPTIONS[name],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** The URL key (`k`): an insider, machine or share key. */
|
|
33
|
+
const URL_KEY = { in: 'query', name: 'k' };
|
|
34
|
+
/** The browser session cookie. */
|
|
35
|
+
const SESSION_COOKIE = { in: 'cookie', name: 'jeeves_session' };
|
|
36
|
+
/**
|
|
37
|
+
* `navigation` and `content` entries: an identity (session or insider key)
|
|
38
|
+
* or a share credential.
|
|
39
|
+
*/
|
|
40
|
+
const KEY_OR_SESSION = {
|
|
41
|
+
schemes: [URL_KEY, SESSION_COOKIE],
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* `insider`, `admin` and `content + insider` entries: an identity only
|
|
45
|
+
* (the service narrows `admin` to identities with no scopes).
|
|
46
|
+
*/
|
|
47
|
+
const INSIDER_ONLY = {
|
|
48
|
+
schemes: [URL_KEY, SESSION_COOKIE],
|
|
49
|
+
insiderOnly: true,
|
|
50
|
+
};
|
|
51
|
+
/** `machineSeed` entries: the raw machine seed in `X-API-Key`. */
|
|
52
|
+
const MACHINE_SEED = {
|
|
53
|
+
schemes: [{ in: 'header', name: 'X-API-Key' }],
|
|
54
|
+
};
|
|
55
|
+
/** `eventKey` entries: a machine key valid for `/event`, as `k`. */
|
|
56
|
+
const EVENT_KEY = { schemes: [URL_KEY] };
|
|
57
|
+
/** `public` entries. */
|
|
58
|
+
const PUBLIC = 'none';
|
|
59
|
+
/**
|
|
60
|
+
* Share-link parameters other than `k`, accepted by every content and
|
|
61
|
+
* navigation entry (and read by `authStatus`): an expiry, the deep-share
|
|
62
|
+
* fields and the legacy key parameter. All optional strings.
|
|
63
|
+
*/
|
|
64
|
+
const shareQuerySchema = z.object({
|
|
65
|
+
/** Expiry (Unix ms) of an expiring share key. */
|
|
66
|
+
exp: z
|
|
67
|
+
.string()
|
|
68
|
+
.optional()
|
|
69
|
+
.describe('Share link expiry (Unix milliseconds), for expiring keys.'),
|
|
70
|
+
/** Deep share depth. */
|
|
71
|
+
d: z.string().optional().describe('Deep share depth.'),
|
|
72
|
+
/** Deep share: `1` when directories may be listed. */
|
|
73
|
+
dirs: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('Deep share: 1 when directories below the shared path open.'),
|
|
77
|
+
/** Deep share stack (compressed). */
|
|
78
|
+
s: z.string().optional().describe('Deep share path stack.'),
|
|
79
|
+
/** Legacy name of `k`. */
|
|
80
|
+
key: z.string().optional().describe('Legacy name of the k parameter.'),
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* The `*` path parameter: a browse path (`<root>/<path>`).
|
|
84
|
+
*
|
|
85
|
+
* @param description - What the path addresses.
|
|
86
|
+
* @returns The params schema.
|
|
87
|
+
*/
|
|
88
|
+
const wildcardParams = (description) => z.object({ '*': z.string().describe(description) });
|
|
89
|
+
/** `*` of the content entries that address a file or a directory. */
|
|
90
|
+
const browsePathParams = wildcardParams('Browse path (e.g. "<drive>/path/to/file.md")');
|
|
91
|
+
|
|
92
|
+
export { EVENT_KEY, INSIDER_ONLY, KEY_OR_SESSION, MACHINE_SEED, PUBLIC, browsePathParams, route, shareQuerySchema, wildcardParams };
|