ask-marcel-office-cli 2.1.0 → 2.2.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/CHANGELOG.md +203 -0
- package/README.md +178 -119
- package/dist/cli.js +44806 -27142
- package/dist/commands.json +371 -52
- package/dist/composition/build-deps.d.ts +8 -0
- package/dist/composition/mcp.d.ts +20 -0
- package/dist/composition/run-registry-command.d.ts +34 -0
- package/dist/domain/tenant-id.d.ts +9 -0
- package/dist/domain/utilities/spo-tenant.d.ts +20 -0
- package/dist/index.js +2735 -1674
- package/dist/infra/auth.d.ts +36 -14
- package/dist/infra/browser-auth.d.ts +7 -2
- package/dist/infra/graph-client.d.ts +52 -16
- package/dist/presenter/graph-cursor.d.ts +2 -0
- package/dist/presenter/output.d.ts +1 -1
- package/dist/presenter/render-to-string.d.ts +15 -0
- package/dist/use-cases/commands/build-command.d.ts +19 -2
- package/dist/use-cases/commands/command-types.d.ts +16 -11
- package/dist/use-cases/commands/convert-calendar-event-attachment-to-markdown.d.ts +4 -0
- package/dist/use-cases/commands/{convert-drive-item-zip.d.ts → convert-drive-item-zip-to-markdown.d.ts} +5 -0
- package/dist/use-cases/commands/{convert-local-file.d.ts → convert-local-file-to-markdown.d.ts} +4 -0
- package/dist/use-cases/commands/convert-mail-attachment-to-markdown.d.ts +10 -2
- package/dist/use-cases/commands/{convert-mail-attachment-zip.d.ts → convert-mail-attachment-zip-to-markdown.d.ts} +5 -1
- package/dist/use-cases/commands/convert-mail-to-markdown.d.ts +35 -1
- package/dist/use-cases/commands/create-forward-draft.d.ts +4 -0
- package/dist/use-cases/commands/create-reply-draft.d.ts +8 -0
- package/dist/use-cases/commands/download-drive-item-as-markdown.d.ts +7 -2
- package/dist/use-cases/commands/download-drive-item-as-pdf.d.ts +1 -0
- package/dist/use-cases/commands/download-drive-item-content.d.ts +1 -0
- package/dist/use-cases/commands/draft-comment-splicer.d.ts +29 -0
- package/dist/use-cases/commands/draft-dedup.d.ts +18 -0
- package/dist/use-cases/commands/draft-response.d.ts +4 -0
- package/dist/use-cases/commands/extract-drive-item-images.d.ts +1 -0
- package/dist/use-cases/commands/extract-local-file-images.d.ts +1 -1
- package/dist/use-cases/commands/fetch-raw-bytes.d.ts +13 -0
- package/dist/use-cases/commands/find-mail-drafts.d.ts +9 -0
- package/dist/use-cases/commands/get-mail-signature.d.ts +8 -0
- package/dist/use-cases/commands/get-user.d.ts +10 -0
- package/dist/use-cases/commands/inline-image-embedder.d.ts +2 -1
- package/dist/use-cases/commands/login-status.d.ts +9 -27
- package/dist/use-cases/commands/login.d.ts +21 -0
- package/dist/use-cases/commands/mail-message-select.d.ts +1 -0
- package/dist/use-cases/commands/mail-quote-stripper.d.ts +16 -15
- package/dist/use-cases/commands/markdown-dispatch.d.ts +2 -1
- package/dist/use-cases/commands/msg-to-markdown.d.ts +10 -1
- package/dist/use-cases/commands/odata-query.d.ts +15 -1
- package/dist/use-cases/commands/office-to-markdown.d.ts +1 -0
- package/dist/use-cases/commands/read-mail-attachment.d.ts +4 -0
- package/dist/use-cases/commands/resolve-command.d.ts +25 -0
- package/dist/use-cases/commands/search-all-files.d.ts +8 -0
- package/dist/use-cases/commands/search-escape.d.ts +23 -0
- package/dist/use-cases/commands/signature-extractor.d.ts +2 -0
- package/dist/use-cases/commands/tenant-option.d.ts +44 -0
- package/dist/use-cases/commands/update-mail-draft.d.ts +1 -0
- package/dist/use-cases/commands/zip-archive-to-markdown.d.ts +10 -5
- package/dist/use-cases/ports/filesystem.d.ts +1 -1
- package/docs/COMMANDS.md +34 -29
- package/docs/USAGE.md +65 -7
- package/package.json +2 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Command, CommandMeta } from './command-types.js';
|
|
3
|
+
declare const schema: z.ZodObject<{
|
|
4
|
+
messageId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
declare const execute: Command['execute'];
|
|
7
|
+
declare const meta: CommandMeta;
|
|
8
|
+
export { execute, meta, schema };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Command, CommandMeta } from './command-types.js';
|
|
3
|
+
declare const schema: z.ZodObject<{
|
|
4
|
+
userId: z.ZodString;
|
|
5
|
+
select: z.ZodOptional<z.ZodString>;
|
|
6
|
+
expand: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
declare const execute: Command['execute'];
|
|
9
|
+
declare const meta: CommandMeta;
|
|
10
|
+
export { execute, meta, schema };
|
|
@@ -16,5 +16,6 @@ type InlineAttachment = {
|
|
|
16
16
|
readonly contentBytes: string;
|
|
17
17
|
};
|
|
18
18
|
declare const embedInlineImages: (html: string, attachments: ReadonlyArray<InlineAttachment>) => string;
|
|
19
|
-
|
|
19
|
+
declare const replaceUnresolvedCidImages: (html: string, labelByContentId: ReadonlyMap<string, string>) => string;
|
|
20
|
+
export { embedInlineImages, replaceUnresolvedCidImages };
|
|
20
21
|
export type { InlineAttachment };
|
|
@@ -1,31 +1,13 @@
|
|
|
1
|
-
type
|
|
2
|
-
type TokenTier = {
|
|
3
|
-
readonly available: boolean;
|
|
4
|
-
readonly expiresInSeconds: number | undefined;
|
|
5
|
-
};
|
|
6
|
-
type TokenView = {
|
|
7
|
-
available: boolean;
|
|
8
|
-
expiresInSeconds?: number;
|
|
9
|
-
refresh: RefreshRoute;
|
|
10
|
-
reason?: string;
|
|
11
|
-
};
|
|
12
|
-
type LoginStatus = {
|
|
1
|
+
type LoginSummary = {
|
|
13
2
|
status: 'authenticated';
|
|
14
|
-
|
|
15
|
-
basic: TokenView;
|
|
16
|
-
elevated: TokenView;
|
|
17
|
-
chatsvcagg: TokenView;
|
|
18
|
-
ic3: TokenView;
|
|
19
|
-
};
|
|
3
|
+
available: ReadonlyArray<string>;
|
|
20
4
|
hint: string;
|
|
21
5
|
};
|
|
22
|
-
type
|
|
23
|
-
readonly
|
|
24
|
-
readonly
|
|
25
|
-
readonly
|
|
26
|
-
readonly ic3: TokenTier;
|
|
27
|
-
readonly elevatedFailureReason?: string;
|
|
6
|
+
type LoginSummaryInput = {
|
|
7
|
+
readonly elevatedAvailable: boolean;
|
|
8
|
+
readonly chatsvcaggAvailable: boolean;
|
|
9
|
+
readonly ic3Available: boolean;
|
|
28
10
|
};
|
|
29
|
-
declare const
|
|
30
|
-
export {
|
|
31
|
-
export type {
|
|
11
|
+
declare const buildLoginSummary: (input: LoginSummaryInput) => LoginSummary;
|
|
12
|
+
export { buildLoginSummary };
|
|
13
|
+
export type { LoginSummary, LoginSummaryInput };
|
|
@@ -2,6 +2,27 @@ import { z } from 'zod';
|
|
|
2
2
|
import type { Result } from '../../domain/result.js';
|
|
3
3
|
import type { AuthManager } from '../../infra/auth.js';
|
|
4
4
|
declare const schema: z.ZodObject<{}, z.core.$strict>;
|
|
5
|
+
/**
|
|
6
|
+
* Sign in, and guarantee the browser-only tier is actually there afterwards.
|
|
7
|
+
*
|
|
8
|
+
* Every other token tier can be renewed headlessly from the shared refresh
|
|
9
|
+
* token. The elevated (M365ChatClient) token cannot — it carries no refresh
|
|
10
|
+
* token of its own and exists only via the browser dance. So a plain `login`
|
|
11
|
+
* that found a valid cached basic token used to return on the cache rung and
|
|
12
|
+
* report `authenticated` with elevated still missing, which left the user in a
|
|
13
|
+
* loop with no exit: the command that needs elevated says "run login", login
|
|
14
|
+
* says "authenticated", the command fails identically, forever.
|
|
15
|
+
*
|
|
16
|
+
* When elevated is confirmed missing we escalate through the SAME
|
|
17
|
+
* `{ force: true }` rung the `--force` flag uses. That matters: the browser
|
|
18
|
+
* adapter has its own `freshCachedToken` probe that short-circuits the dance
|
|
19
|
+
* when a valid token is on disk, and only the forced path suppresses it — a
|
|
20
|
+
* hand-rolled re-capture here would silently no-op (LESSONS 2026-07-13).
|
|
21
|
+
*
|
|
22
|
+
* Supersedes the 2026-07-13 decision that `login` is a slim confirmation and
|
|
23
|
+
* `--force` the only re-capture mechanism: correct about the mechanism, but it
|
|
24
|
+
* left the signpost pointing at a command that could not do the job.
|
|
25
|
+
*/
|
|
5
26
|
declare const execute: (auth: AuthManager, options?: {
|
|
6
27
|
force?: boolean;
|
|
7
28
|
}) => Promise<Result<string, import("../../infra/auth.js").AuthError>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MAIL_MESSAGE_DEFAULT_SELECT = "id,subject,from,toRecipients,ccRecipients,receivedDateTime,hasAttachments,isRead,importance,bodyPreview,conversationId";
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CommandOptionMeta } from './command-types.js';
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `convert-mail-to-markdown` restores the full body. Pure string transform.
|
|
8
|
-
*
|
|
9
|
-
* Only structural, vendor-specific markers are matched (never a bare
|
|
10
|
-
* `<blockquote>`, which legitimate content uses too):
|
|
11
|
-
* - Outlook desktop / OWA reply+forward header block: `<div id="divRplyFwdMsg">`
|
|
12
|
-
* - Outlook "type above this line" boundary: `<div id="appendonsend">`
|
|
13
|
-
* - Outlook mobile reference container: `<div id="mail-editor-reference-message-container">`
|
|
14
|
-
* - Outlook classic separator: `<hr id="stopSpelling">`
|
|
15
|
-
* - Gmail quote container: `<div class="gmail_quote">` / `<blockquote class="gmail_quote">`
|
|
4
|
+
* Index where the quoted history begins in an HTML body, or -1 when the body
|
|
5
|
+
* quotes nothing. Earliest of the structural markers merged with the widened
|
|
6
|
+
* confirmed-header index. Exported because the draft-comment splicer needs the
|
|
7
|
+
* same cut to place a reply ABOVE the quote without disturbing it — the stripper
|
|
8
|
+
* throws the tail away, the splicer keeps it, but both agree on where it starts.
|
|
16
9
|
*/
|
|
10
|
+
declare const findQuoteBoundary: (html: string) => number;
|
|
11
|
+
/** The plain-text counterpart of `findQuoteBoundary`, for `contentType === 'text'` bodies. */
|
|
12
|
+
declare const findPlainTextQuoteBoundary: (text: string) => number;
|
|
17
13
|
declare const stripQuotedReplies: (html: string) => {
|
|
18
14
|
readonly html: string;
|
|
19
15
|
readonly stripped: boolean;
|
|
@@ -22,4 +18,9 @@ declare const stripQuotedPlainText: (text: string) => {
|
|
|
22
18
|
readonly text: string;
|
|
23
19
|
readonly stripped: boolean;
|
|
24
20
|
};
|
|
25
|
-
|
|
21
|
+
declare const keepQuotedSchemaField: z.ZodOptional<z.ZodEnum<{
|
|
22
|
+
true: "true";
|
|
23
|
+
false: "false";
|
|
24
|
+
}>>;
|
|
25
|
+
declare const keepQuotedOption: CommandOptionMeta;
|
|
26
|
+
export { findPlainTextQuoteBoundary, findQuoteBoundary, keepQuotedOption, keepQuotedSchemaField, stripQuotedPlainText, stripQuotedReplies };
|
|
@@ -11,13 +11,14 @@ type BytesToMarkdownOptions = {
|
|
|
11
11
|
readonly includeMetadata?: boolean;
|
|
12
12
|
readonly maxCells?: number;
|
|
13
13
|
readonly inlineImages?: boolean;
|
|
14
|
+
readonly keepQuoted?: boolean;
|
|
14
15
|
readonly depth?: number;
|
|
15
16
|
};
|
|
16
17
|
declare const NESTED_HINTS: ConversionHints;
|
|
17
18
|
/**
|
|
18
19
|
* The single extension→converter dispatch for every markdown command, operating on
|
|
19
20
|
* bytes already in hand: download-drive-item-as-markdown fetches them, convert-mail
|
|
20
|
-
* decodes the attachment, convert-drive-item-zip unpacks the entry. Loop/Fluid/
|
|
21
|
+
* decodes the attachment, convert-drive-item-zip-to-markdown unpacks the entry. Loop/Fluid/
|
|
21
22
|
* Whiteboard (`?format=html`) need a Graph round-trip and are handled by the drive
|
|
22
23
|
* caller BEFORE this — they never reach here. An Outlook `.msg` is rendered to markdown
|
|
23
24
|
* (headers + body) with each of its own attachments recursed through this dispatch.
|
|
@@ -10,6 +10,14 @@ import type { ParsedMsg } from '../../infra/msg-reader-adapter.js';
|
|
|
10
10
|
* user asked ("maybe same way as zip"). Unconvertible attachments (images, binaries)
|
|
11
11
|
* are listed with the dispatch's note instead of failing the whole message.
|
|
12
12
|
*
|
|
13
|
+
* The body goes through the same two passes `convert-mail-to-markdown` applies to a
|
|
14
|
+
* Graph mail body (they share the helpers): the quoted reply chain is stripped by
|
|
15
|
+
* default — `keepQuoted` restores it, and every command that can hand a `.msg` to
|
|
16
|
+
* this renderer exposes that as `--keep-quoted`, so the marker's remedy always
|
|
17
|
+
* works — and any `cid:` image becomes a readable placeholder. A `.msg` carries no
|
|
18
|
+
* contentId on its attachments, so embedding is impossible here and the placeholder
|
|
19
|
+
* falls back to the img alt text or the cid's filename prefix.
|
|
20
|
+
*
|
|
13
21
|
* `recurse` is the attachment converter injected by `markdown-dispatch` (its own
|
|
14
22
|
* `bytesToMarkdown`, with the recursion depth incremented). Injecting it — rather
|
|
15
23
|
* than importing `bytesToMarkdown` here — keeps this use-case off the dispatch's
|
|
@@ -20,9 +28,10 @@ import type { ParsedMsg } from '../../infra/msg-reader-adapter.js';
|
|
|
20
28
|
declare const MAX_MSG_DEPTH = 3;
|
|
21
29
|
type MsgToMarkdownOptions = {
|
|
22
30
|
readonly depth?: number;
|
|
31
|
+
readonly keepQuoted?: boolean;
|
|
23
32
|
};
|
|
24
33
|
type MsgAttachmentConverter = (bytes: Uint8Array, filename: string) => Promise<Result<unknown, GraphError>>;
|
|
25
|
-
declare const renderMsg: (msg: ParsedMsg,
|
|
34
|
+
declare const renderMsg: (msg: ParsedMsg, opts: MsgToMarkdownOptions, recurse: MsgAttachmentConverter) => Promise<string>;
|
|
26
35
|
declare const msgToMarkdown: (bytes: Uint8Array, opts: MsgToMarkdownOptions, recurse: MsgAttachmentConverter) => Promise<Result<unknown, GraphError>>;
|
|
27
36
|
export { MAX_MSG_DEPTH, msgToMarkdown, renderMsg };
|
|
28
37
|
export type { MsgAttachmentConverter, MsgToMarkdownOptions };
|
|
@@ -9,6 +9,20 @@ declare const odataQuerySchema: z.ZodObject<{
|
|
|
9
9
|
expand: z.ZodOptional<z.ZodString>;
|
|
10
10
|
}, z.core.$strip>;
|
|
11
11
|
type ODataQueryParams = z.infer<typeof odataQuerySchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Embed a user-supplied value inside an OData single-quoted string literal
|
|
14
|
+
* (`$filter=mail eq '<here>'`, `contains(title,'<here>')`, `search(q='<here>')`).
|
|
15
|
+
* Two steps, in this order:
|
|
16
|
+
* 1. double any `'` — OData's string-literal escape, so the value cannot
|
|
17
|
+
* terminate the literal early;
|
|
18
|
+
* 2. percent-encode — graph-client concatenates command paths verbatim, so an
|
|
19
|
+
* un-encoded value corrupts the query string. `&`/`#` truncate it outright,
|
|
20
|
+
* and a raw `+` is decoded back to a SPACE server-side, which silently
|
|
21
|
+
* matches nothing (base64 conversationIds and plus-addressed emails both
|
|
22
|
+
* carry `+`). encodeURIComponent leaves `'` unreserved, so the doubled
|
|
23
|
+
* quote survives as the escape OData expects.
|
|
24
|
+
*/
|
|
25
|
+
declare const odataStringLiteral: (value: string) => string;
|
|
12
26
|
declare const appendOData: (path: string, params: ODataQueryParams) => string;
|
|
13
27
|
declare const odataQueryOptions: ReadonlyArray<CommandOptionMeta>;
|
|
14
28
|
/**
|
|
@@ -86,5 +100,5 @@ declare const selectOnlyShape: Pick<{
|
|
|
86
100
|
expand: z.ZodOptional<z.ZodString>;
|
|
87
101
|
}, "select">;
|
|
88
102
|
declare const selectOnlyOptions: readonly CommandOptionMeta[];
|
|
89
|
-
export { appendOData, filterSelectOptions, filterSelectSchema, noSkipOptions, noSkipShape, odataQueryOptions, odataQuerySchema, pickODataOptions, pickODataShape, selectExpandOptions, selectExpandSchema, selectOnlyOptions, selectOnlyShape, topOnlyOptions, topOnlyShape, };
|
|
103
|
+
export { appendOData, filterSelectOptions, filterSelectSchema, noSkipOptions, noSkipShape, odataQueryOptions, odataQuerySchema, odataStringLiteral, pickODataOptions, pickODataShape, selectExpandOptions, selectExpandSchema, selectOnlyOptions, selectOnlyShape, topOnlyOptions, topOnlyShape, };
|
|
90
104
|
export type { FilterSelectParams, ODataKey, ODataQueryParams, SelectExpandParams };
|
|
@@ -5,6 +5,7 @@ type OfficeToMarkdownOptions = FetchOptions & {
|
|
|
5
5
|
readonly includeMetadata?: boolean;
|
|
6
6
|
readonly inlineImages?: boolean;
|
|
7
7
|
readonly maxCells?: number;
|
|
8
|
+
readonly keepQuoted?: boolean;
|
|
8
9
|
};
|
|
9
10
|
declare const officeToMarkdown: (graph: GraphClient, contentPath: string, filename: string, opts?: OfficeToMarkdownOptions) => Promise<Result<unknown, GraphError>>;
|
|
10
11
|
export { officeToMarkdown };
|
|
@@ -9,6 +9,10 @@ declare const schema: z.ZodObject<{
|
|
|
9
9
|
true: "true";
|
|
10
10
|
false: "false";
|
|
11
11
|
}>>;
|
|
12
|
+
keepQuoted: z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
true: "true";
|
|
14
|
+
false: "false";
|
|
15
|
+
}>>;
|
|
12
16
|
}, z.core.$strip>;
|
|
13
17
|
declare const execute: (graph: GraphClient, params: Record<string, string>) => Promise<Result<unknown, GraphError>>;
|
|
14
18
|
declare const meta: CommandMeta;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Result } from '../../domain/result.js';
|
|
2
|
+
import type { Command } from './command-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Name -> command lookup that also honours `meta.commandAliases`.
|
|
5
|
+
*
|
|
6
|
+
* The CLI gets alias resolution for free from commander (`commandDef.alias(...)`
|
|
7
|
+
* in `cli.ts`), so nothing needed this until a second front end appeared. The
|
|
8
|
+
* MCP gateway has no commander, and its three command-taking tools
|
|
9
|
+
* (`get-command-docs`, `run-command`, `run-write-command`) each need the same
|
|
10
|
+
* lookup — Rule of Three, so it lives here rather than inline.
|
|
11
|
+
*
|
|
12
|
+
* Returns the CANONICAL name alongside the command so every downstream concern
|
|
13
|
+
* (docs rendering, the `mutates` read/write gate, error messages) keys off one
|
|
14
|
+
* spelling regardless of which one the caller used.
|
|
15
|
+
*/
|
|
16
|
+
export type ResolveCommandError = {
|
|
17
|
+
readonly type: 'unknown_command';
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly available: ReadonlyArray<string>;
|
|
20
|
+
};
|
|
21
|
+
export type ResolvedCommand = {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly command: Command;
|
|
24
|
+
};
|
|
25
|
+
export declare const resolveCommand: (registry: Readonly<Record<string, Command>>, name: string) => Result<ResolvedCommand, ResolveCommandError>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Command, CommandMeta } from './command-types.js';
|
|
3
|
+
declare const schema: z.ZodObject<{
|
|
4
|
+
query: z.ZodString;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
declare const execute: Command['execute'];
|
|
7
|
+
declare const meta: CommandMeta;
|
|
8
|
+
export { execute, meta, schema };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-safe builder for Graph `$search=` KQL clauses. graph-client
|
|
3
|
+
* concatenates command paths verbatim (`https://graph.microsoft.com/v1.0${path}`)
|
|
4
|
+
* with no percent-encoding pass, so a raw `&`, `#`, `%`, or `+` inside a user
|
|
5
|
+
* query corrupts the query string on the wire: a live ` & ` truncated the KQL
|
|
6
|
+
* mid-phrase (`$search="subject:"Contoso A2` reached Graph). Values are
|
|
7
|
+
* percent-encoded here, at the only layer that knows which part of the path
|
|
8
|
+
* is data.
|
|
9
|
+
*
|
|
10
|
+
* The sibling concern — a value inside a single-quoted OData literal
|
|
11
|
+
* (`$filter=x eq '…'`, `contains(…)`, `search(q='…')`) — is
|
|
12
|
+
* `odataStringLiteral` in odata-query.ts, which owns OData query construction.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Build a `$search=` KQL clause: escape embedded double quotes as `\"`
|
|
16
|
+
* (Graph's documented KQL escaping, so `subject:"multi word"` and whole
|
|
17
|
+
* `"phrase"` queries become phrase matches instead of a BadRequest), wrap the
|
|
18
|
+
* expression in the double quotes Graph requires, then percent-encode the
|
|
19
|
+
* value. Backslashes are NOT pre-escaped: raw quotes are the documented
|
|
20
|
+
* input contract and backslash has no other KQL meaning here.
|
|
21
|
+
*/
|
|
22
|
+
declare const kqlSearchClause: (query: string) => string;
|
|
23
|
+
export { kqlSearchClause };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Result } from '../../domain/result.js';
|
|
3
|
+
import type { TenantId } from '../../domain/tenant-id.js';
|
|
4
|
+
import type { GraphClient, GraphError } from '../../infra/graph-client.js';
|
|
5
|
+
import type { CommandOptionMeta } from './command-types.js';
|
|
6
|
+
/**
|
|
7
|
+
* `--tenant-id`: read a file that lives in a tenant you are only a GUEST in.
|
|
8
|
+
*
|
|
9
|
+
* Without it, such a read dies at `401 invalidAudienceUri` — home-tenant Graph
|
|
10
|
+
* cannot mint a SharePoint token for a foreign tenant, so no home-tier token can
|
|
11
|
+
* reach it. Unlike `resolve-drive-share-link`, these commands cannot recover on
|
|
12
|
+
* their own: they hold only a `driveId` and an `itemId`, and NEITHER carries a
|
|
13
|
+
* tenant. The sharing URL does, which is why `resolve-drive-share-link` returns
|
|
14
|
+
* the `tenantId` for this flag to consume.
|
|
15
|
+
*
|
|
16
|
+
* OPTIONAL, always. That is not a detail — `required: true` compiles straight to
|
|
17
|
+
* commander's `.requiredOption()`, so an optional flag is what keeps the
|
|
18
|
+
* `CommandMeta` contract untouched and every existing invocation working.
|
|
19
|
+
*/
|
|
20
|
+
declare const tenantIdShape: {
|
|
21
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
22
|
+
};
|
|
23
|
+
declare const tenantIdSchema: z.ZodObject<{
|
|
24
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
declare const TENANT_ID_OPTION: CommandOptionMeta;
|
|
27
|
+
/**
|
|
28
|
+
* Route a JSON GET to the right identity: the home token normally, a partner
|
|
29
|
+
* tenant's guest token when `--tenant-id` was given.
|
|
30
|
+
*
|
|
31
|
+
* The guest tier is a RUNTIME choice, not a static one like `elevated` — the same
|
|
32
|
+
* command uses either, depending on this flag. That is why the builders route
|
|
33
|
+
* here instead of growing guest twins (which would take 10 builders to 14+, and
|
|
34
|
+
* would still not express "it depends on the argument").
|
|
35
|
+
*/
|
|
36
|
+
declare const routeGet: (graph: GraphClient, path: string, rawTenantId: string | undefined) => Promise<Result<unknown, GraphError>>;
|
|
37
|
+
/**
|
|
38
|
+
* Validate a caller-supplied tenant id at the boundary. The value reaches an
|
|
39
|
+
* authority URL whose POST carries the refresh token, so it is branded rather
|
|
40
|
+
* than trusted (hard rule 12); a bad one must fail here with a readable message,
|
|
41
|
+
* not further in.
|
|
42
|
+
*/
|
|
43
|
+
declare const brandTenantId: (raw: string) => Result<TenantId, GraphError>;
|
|
44
|
+
export { TENANT_ID_OPTION, brandTenantId, routeGet, tenantIdSchema, tenantIdShape };
|
|
@@ -3,9 +3,9 @@ import type { GraphError } from '../../infra/graph-client.js';
|
|
|
3
3
|
import type { MediaEnvelope } from './media-files.js';
|
|
4
4
|
/**
|
|
5
5
|
* Shared "unzip + convert every contained file" core behind
|
|
6
|
-
* `convert-drive-item-zip` (a OneDrive / SharePoint .zip),
|
|
7
|
-
* `convert-mail-attachment-zip` (an Outlook .zip attachment), and
|
|
8
|
-
* `convert-local-file` (a .zip on disk). Each entry is run through the same
|
|
6
|
+
* `convert-drive-item-zip-to-markdown` (a OneDrive / SharePoint .zip),
|
|
7
|
+
* `convert-mail-attachment-zip-to-markdown` (an Outlook .zip attachment), and
|
|
8
|
+
* `convert-local-file-to-markdown` (a .zip on disk). Each entry is run through the same
|
|
9
9
|
* `bytesToMarkdown` dispatch the markdown commands use; an entry the dispatch
|
|
10
10
|
* can't convert (image, binary, nested archive, scanned PDF) is LISTED with a
|
|
11
11
|
* note instead of failing the whole archive. Notes use the container-neutral
|
|
@@ -27,6 +27,11 @@ type ZipArchiveResult = {
|
|
|
27
27
|
readonly totalEntries?: number;
|
|
28
28
|
readonly files: ReadonlyArray<FileResult>;
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
type ZipArchiveOptions = {
|
|
31
|
+
readonly includeMetadata: boolean;
|
|
32
|
+
readonly includeImages?: boolean;
|
|
33
|
+
readonly keepQuoted?: boolean;
|
|
34
|
+
};
|
|
35
|
+
declare const convertZipArchive: (bytes: Uint8Array, opts: ZipArchiveOptions) => Promise<Result<ZipArchiveResult, GraphError>>;
|
|
31
36
|
export { convertZipArchive, MAX_ENTRIES };
|
|
32
|
-
export type { FileResult, ZipArchiveResult };
|
|
37
|
+
export type { FileResult, ZipArchiveOptions, ZipArchiveResult };
|
|
@@ -11,7 +11,7 @@ export type FileSystemError = {
|
|
|
11
11
|
export type FileSystem = {
|
|
12
12
|
readonly readJson: <T>(path: string) => Promise<Result<T, FileSystemError>>;
|
|
13
13
|
/**
|
|
14
|
-
* Read a file's raw bytes. Used by `convert-local-file` to feed a local
|
|
14
|
+
* Read a file's raw bytes. Used by `convert-local-file-to-markdown` to feed a local
|
|
15
15
|
* document into the same conversion dispatch the Graph-backed commands use.
|
|
16
16
|
*/
|
|
17
17
|
readonly readBytes: (path: string) => Promise<Result<Uint8Array, FileSystemError>>;
|