@indigoai-us/hq-cloud 6.15.0 → 6.15.2
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/bin/sync-mutation.d.ts +16 -0
- package/dist/bin/sync-mutation.d.ts.map +1 -0
- package/dist/bin/sync-mutation.js +60 -0
- package/dist/bin/sync-mutation.js.map +1 -0
- package/dist/bin/sync-mutation.test.d.ts +2 -0
- package/dist/bin/sync-mutation.test.d.ts.map +1 -0
- package/dist/bin/sync-mutation.test.js +165 -0
- package/dist/bin/sync-mutation.test.js.map +1 -0
- package/dist/bin/sync-runner-company.d.ts +8 -0
- package/dist/bin/sync-runner-company.d.ts.map +1 -1
- package/dist/bin/sync-runner-company.js +16 -0
- package/dist/bin/sync-runner-company.js.map +1 -1
- package/dist/bin/sync-runner-company.test.d.ts +2 -0
- package/dist/bin/sync-runner-company.test.d.ts.map +1 -0
- package/dist/bin/sync-runner-company.test.js +36 -0
- package/dist/bin/sync-runner-company.test.js.map +1 -0
- package/dist/bin/sync-runner-watch-loop.d.ts.map +1 -1
- package/dist/bin/sync-runner-watch-loop.js +98 -8
- package/dist/bin/sync-runner-watch-loop.js.map +1 -1
- package/dist/bin/sync-runner.d.ts +17 -0
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/bin/sync-runner.test.js +109 -0
- package/dist/bin/sync-runner.test.js.map +1 -1
- package/dist/cli/conflict-recovery.test.d.ts +2 -0
- package/dist/cli/conflict-recovery.test.d.ts.map +1 -0
- package/dist/cli/conflict-recovery.test.js +201 -0
- package/dist/cli/conflict-recovery.test.js.map +1 -0
- package/dist/cli/conflict.d.ts +60 -0
- package/dist/cli/conflict.d.ts.map +1 -1
- package/dist/cli/conflict.js +333 -0
- package/dist/cli/conflict.js.map +1 -1
- package/dist/cli/sync.d.ts +35 -0
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +100 -0
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/sync.test.js +85 -1
- package/dist/cli/sync.test.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/skill-telemetry.d.ts +6 -0
- package/dist/skill-telemetry.d.ts.map +1 -1
- package/dist/skill-telemetry.js +14 -2
- package/dist/skill-telemetry.js.map +1 -1
- package/dist/skill-telemetry.test.js +79 -0
- package/dist/skill-telemetry.test.js.map +1 -1
- package/dist/sync/candidate-uploader.d.ts +88 -0
- package/dist/sync/candidate-uploader.d.ts.map +1 -0
- package/dist/sync/candidate-uploader.js +212 -0
- package/dist/sync/candidate-uploader.js.map +1 -0
- package/dist/sync/candidate-uploader.test.d.ts +2 -0
- package/dist/sync/candidate-uploader.test.d.ts.map +1 -0
- package/dist/sync/candidate-uploader.test.js +132 -0
- package/dist/sync/candidate-uploader.test.js.map +1 -0
- package/dist/sync/delta-client.d.ts +73 -0
- package/dist/sync/delta-client.d.ts.map +1 -0
- package/dist/sync/delta-client.js +201 -0
- package/dist/sync/delta-client.js.map +1 -0
- package/dist/sync/delta-client.test.d.ts +2 -0
- package/dist/sync/delta-client.test.d.ts.map +1 -0
- package/dist/sync/delta-client.test.js +97 -0
- package/dist/sync/delta-client.test.js.map +1 -0
- package/dist/sync/durable-apply.d.ts +76 -0
- package/dist/sync/durable-apply.d.ts.map +1 -0
- package/dist/sync/durable-apply.js +530 -0
- package/dist/sync/durable-apply.js.map +1 -0
- package/dist/sync/durable-apply.test.d.ts +2 -0
- package/dist/sync/durable-apply.test.d.ts.map +1 -0
- package/dist/sync/durable-apply.test.js +180 -0
- package/dist/sync/durable-apply.test.js.map +1 -0
- package/dist/sync/event-sync.d.ts +33 -1
- package/dist/sync/event-sync.d.ts.map +1 -1
- package/dist/sync/event-sync.js +149 -1
- package/dist/sync/event-sync.js.map +1 -1
- package/dist/sync/event-sync.test.js +142 -1
- package/dist/sync/event-sync.test.js.map +1 -1
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/multipart-uploader.d.ts +99 -0
- package/dist/sync/multipart-uploader.d.ts.map +1 -0
- package/dist/sync/multipart-uploader.js +447 -0
- package/dist/sync/multipart-uploader.js.map +1 -0
- package/dist/sync/multipart-uploader.test.d.ts +2 -0
- package/dist/sync/multipart-uploader.test.d.ts.map +1 -0
- package/dist/sync/multipart-uploader.test.js +119 -0
- package/dist/sync/multipart-uploader.test.js.map +1 -0
- package/dist/sync/mutation-client.d.ts +85 -0
- package/dist/sync/mutation-client.d.ts.map +1 -0
- package/dist/sync/mutation-client.js +245 -0
- package/dist/sync/mutation-client.js.map +1 -0
- package/dist/sync/mutation-client.test.d.ts +2 -0
- package/dist/sync/mutation-client.test.d.ts.map +1 -0
- package/dist/sync/mutation-client.test.js +51 -0
- package/dist/sync/mutation-client.test.js.map +1 -0
- package/dist/sync/push-receiver.d.ts +45 -0
- package/dist/sync/push-receiver.d.ts.map +1 -1
- package/dist/sync/push-receiver.js +101 -0
- package/dist/sync/push-receiver.js.map +1 -1
- package/dist/sync/push-receiver.test.js +54 -2
- package/dist/sync/push-receiver.test.js.map +1 -1
- package/dist/sync/scope-inventory-client.d.ts +69 -0
- package/dist/sync/scope-inventory-client.d.ts.map +1 -0
- package/dist/sync/scope-inventory-client.js +210 -0
- package/dist/sync/scope-inventory-client.js.map +1 -0
- package/dist/sync/scope-inventory-client.test.d.ts +2 -0
- package/dist/sync/scope-inventory-client.test.d.ts.map +1 -0
- package/dist/sync/scope-inventory-client.test.js +94 -0
- package/dist/sync/scope-inventory-client.test.js.map +1 -0
- package/dist/sync/snapshot-client.d.ts +98 -0
- package/dist/sync/snapshot-client.d.ts.map +1 -0
- package/dist/sync/snapshot-client.js +402 -0
- package/dist/sync/snapshot-client.js.map +1 -0
- package/dist/sync/snapshot-client.test.d.ts +2 -0
- package/dist/sync/snapshot-client.test.d.ts.map +1 -0
- package/dist/sync/snapshot-client.test.js +169 -0
- package/dist/sync/snapshot-client.test.js.map +1 -0
- package/dist/sync/uploader-finalization.d.ts +97 -0
- package/dist/sync/uploader-finalization.d.ts.map +1 -0
- package/dist/sync/uploader-finalization.js +273 -0
- package/dist/sync/uploader-finalization.js.map +1 -0
- package/dist/sync/uploader-finalization.test.d.ts +2 -0
- package/dist/sync/uploader-finalization.test.d.ts.map +1 -0
- package/dist/sync/uploader-finalization.test.js +92 -0
- package/dist/sync/uploader-finalization.test.js.map +1 -0
- package/dist/telemetry.d.ts +11 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +21 -2
- package/dist/telemetry.js.map +1 -1
- package/dist/telemetry.test.js +80 -0
- package/dist/telemetry.test.js.map +1 -1
- package/package.json +6 -1
- package/.claude/policies/hq-cloud-esm-cannot-spy-fs-builtins.md +0 -30
- package/.claude/policies/hq-cloud-strip-types-no-parameter-properties.md +0 -22
- package/.github/workflows/ci.yml +0 -84
- package/.github/workflows/publish.yml +0 -56
- package/.github/workflows/unreleased-commits-nag.yml +0 -256
- package/eslint.config.js +0 -67
- package/pnpm-workspace.yaml +0 -2
- package/scripts/presign-transport-e2e.mjs +0 -250
- package/scripts/vault-rebaseline.sh +0 -323
- package/scripts/vault-rescue.sh +0 -332
- package/src/active-company.test.ts +0 -188
- package/src/active-company.ts +0 -168
- package/src/agent-codex-instructions.test.ts +0 -332
- package/src/agent-codex-instructions.ts +0 -309
- package/src/auth.ts +0 -146
- package/src/backup-prune.test.ts +0 -98
- package/src/backup-prune.ts +0 -182
- package/src/bin/backup-prune-runner.ts +0 -33
- package/src/bin/rescue-runner.ts +0 -25
- package/src/bin/sync-runner-company.ts +0 -695
- package/src/bin/sync-runner-events.test.ts +0 -143
- package/src/bin/sync-runner-events.ts +0 -55
- package/src/bin/sync-runner-planning.test.ts +0 -311
- package/src/bin/sync-runner-planning.ts +0 -258
- package/src/bin/sync-runner-rollup.test.ts +0 -37
- package/src/bin/sync-runner-rollup.ts +0 -97
- package/src/bin/sync-runner-telemetry.ts +0 -15
- package/src/bin/sync-runner-watch-loop.ts +0 -1235
- package/src/bin/sync-runner-watch-routes.test.ts +0 -71
- package/src/bin/sync-runner-watch-routes.ts +0 -184
- package/src/bin/sync-runner.test.ts +0 -8767
- package/src/bin/sync-runner.ts +0 -2190
- package/src/cli/accept.ts +0 -124
- package/src/cli/conflict.ts +0 -119
- package/src/cli/doctor.test.ts +0 -581
- package/src/cli/doctor.ts +0 -642
- package/src/cli/index.ts +0 -49
- package/src/cli/invite.test.ts +0 -250
- package/src/cli/invite.ts +0 -214
- package/src/cli/promote.ts +0 -157
- package/src/cli/reindex-knowledge.test.ts +0 -307
- package/src/cli/reindex-knowledge.ts +0 -450
- package/src/cli/reindex.test.ts +0 -957
- package/src/cli/reindex.ts +0 -979
- package/src/cli/rescue-classify-ordering.test.ts +0 -548
- package/src/cli/rescue-clone-diagnostics.test.ts +0 -120
- package/src/cli/rescue-core.ts +0 -3011
- package/src/cli/rescue-drift-reconcile.test.ts +0 -179
- package/src/cli/rescue-drop-dir-symlink.test.ts +0 -224
- package/src/cli/rescue-exec-bit-preserve.test.ts +0 -187
- package/src/cli/rescue-hq-root-guard.test.ts +0 -232
- package/src/cli/rescue-journal-reconcile.test.ts +0 -215
- package/src/cli/rescue-mtime-preserve.test.ts +0 -203
- package/src/cli/rescue-settings-reconcile.test.ts +0 -637
- package/src/cli/rescue-snapshot.test.ts +0 -57
- package/src/cli/rescue-snapshot.ts +0 -51
- package/src/cli/rescue.reindex.test.ts +0 -63
- package/src/cli/rescue.test.ts +0 -131
- package/src/cli/rescue.ts +0 -182
- package/src/cli/share.test.ts +0 -7843
- package/src/cli/share.ts +0 -3663
- package/src/cli/sync-scope.test.ts +0 -652
- package/src/cli/sync.test.ts +0 -5207
- package/src/cli/sync.ts +0 -3470
- package/src/cli/tombstones.ts +0 -106
- package/src/cli/watch-event-push-conflict.test.ts +0 -234
- package/src/client-info.test.ts +0 -214
- package/src/client-info.ts +0 -121
- package/src/cognito-auth.test.ts +0 -712
- package/src/cognito-auth.ts +0 -1422
- package/src/company-resolver.test.ts +0 -618
- package/src/company-resolver.ts +0 -521
- package/src/context.test.ts +0 -583
- package/src/context.ts +0 -378
- package/src/daemon-worker.ts +0 -26
- package/src/daemon.ts +0 -99
- package/src/entity-resolver.test.ts +0 -315
- package/src/entity-resolver.ts +0 -180
- package/src/ignore.test.ts +0 -466
- package/src/ignore.ts +0 -469
- package/src/index.ts +0 -439
- package/src/journal.test.ts +0 -968
- package/src/journal.ts +0 -765
- package/src/lib/cloud-authoritative.test.ts +0 -45
- package/src/lib/cloud-authoritative.ts +0 -59
- package/src/lib/conflict-file.ts +0 -86
- package/src/lib/conflict-index.ts +0 -289
- package/src/lib/conflict.test.ts +0 -348
- package/src/lib/describe-error.test.ts +0 -100
- package/src/lib/describe-error.ts +0 -58
- package/src/lib/exit-codes.ts +0 -24
- package/src/lib/machine-id.test.ts +0 -231
- package/src/lib/machine-id.ts +0 -175
- package/src/lib/net-errors.test.ts +0 -65
- package/src/lib/net-errors.ts +0 -86
- package/src/lib/readlink-safe.test.ts +0 -43
- package/src/lib/readlink-safe.ts +0 -29
- package/src/local-path-codec.test.ts +0 -138
- package/src/local-path-codec.ts +0 -161
- package/src/machine-auth.test.ts +0 -1323
- package/src/manifest-reconcile.test.ts +0 -1123
- package/src/manifest-reconcile.ts +0 -518
- package/src/object-io.test.ts +0 -1221
- package/src/object-io.ts +0 -1306
- package/src/operation-lock.test.ts +0 -484
- package/src/operation-lock.ts +0 -680
- package/src/outcome-telemetry.test.ts +0 -498
- package/src/outcome-telemetry.ts +0 -639
- package/src/personal-vault-exclusions.test.ts +0 -308
- package/src/personal-vault-exclusions.ts +0 -354
- package/src/personal-vault.test.ts +0 -756
- package/src/personal-vault.ts +0 -496
- package/src/prefix-coalesce.test.ts +0 -240
- package/src/prefix-coalesce.ts +0 -273
- package/src/public-surface.test.ts +0 -117
- package/src/qmd-reindex.test.ts +0 -877
- package/src/qmd-reindex.ts +0 -842
- package/src/read-only-state-dir.test.ts +0 -188
- package/src/remote-pull.test.ts +0 -1130
- package/src/remote-pull.ts +0 -618
- package/src/s3.symlink-materialize.test.ts +0 -492
- package/src/s3.test.ts +0 -1789
- package/src/s3.ts +0 -1532
- package/src/schemas/signal-types.test.ts +0 -82
- package/src/schemas/signal-types.ts +0 -38
- package/src/schemas/source-channels.test.ts +0 -82
- package/src/schemas/source-channels.ts +0 -53
- package/src/scope-shrink.test.ts +0 -633
- package/src/scope-shrink.ts +0 -481
- package/src/signals/get.test.ts +0 -310
- package/src/signals/get.ts +0 -75
- package/src/signals/internals.ts +0 -195
- package/src/signals/list.test.ts +0 -420
- package/src/signals/list.ts +0 -79
- package/src/signals/parse.ts +0 -8
- package/src/signals/types.ts +0 -91
- package/src/skill-telemetry.test.ts +0 -1825
- package/src/skill-telemetry.ts +0 -1439
- package/src/sources/get.test.ts +0 -293
- package/src/sources/get.ts +0 -66
- package/src/sources/internals.ts +0 -198
- package/src/sources/list.test.ts +0 -402
- package/src/sources/list.ts +0 -84
- package/src/sources/parse.ts +0 -43
- package/src/sources/types.ts +0 -84
- package/src/sync/event-sync.test.ts +0 -594
- package/src/sync/event-sync.ts +0 -545
- package/src/sync/feature-flags.test.ts +0 -378
- package/src/sync/feature-flags.ts +0 -62
- package/src/sync/index.ts +0 -76
- package/src/sync/lease-client.test.ts +0 -128
- package/src/sync/lease-client.ts +0 -207
- package/src/sync/logger.test.ts +0 -242
- package/src/sync/logger.ts +0 -79
- package/src/sync/metrics.test.ts +0 -462
- package/src/sync/metrics.ts +0 -213
- package/src/sync/pull-scope.ts +0 -265
- package/src/sync/push-event.test.ts +0 -266
- package/src/sync/push-event.ts +0 -224
- package/src/sync/push-receiver.test.ts +0 -566
- package/src/sync/push-receiver.ts +0 -1048
- package/src/sync/push-transport.ts +0 -231
- package/src/sync/realtime-rollout.test.ts +0 -86
- package/src/sync/realtime-rollout.ts +0 -262
- package/src/sync/state-store.test.ts +0 -194
- package/src/sync/state-store.ts +0 -727
- package/src/sync-core.ts +0 -58
- package/src/sync-progress.test.ts +0 -94
- package/src/sync-progress.ts +0 -140
- package/src/telemetry-events.test.ts +0 -88
- package/src/telemetry-events.ts +0 -205
- package/src/telemetry.test.ts +0 -1280
- package/src/telemetry.ts +0 -1109
- package/src/types.ts +0 -314
- package/src/vault-client.test.ts +0 -1380
- package/src/vault-client.ts +0 -1694
- package/src/version.ts +0 -24
- package/src/watch-roots.test.ts +0 -278
- package/src/watch-roots.ts +0 -162
- package/src/watcher-event-gate.test.ts +0 -212
- package/src/watcher.test.ts +0 -1079
- package/src/watcher.ts +0 -1741
- package/test/e2e/sync/cross-tenant-isolation.test.ts +0 -630
- package/test/e2e/sync/skill-telemetry-oversized-transcript.test.ts +0 -124
- package/test/e2e/sync/transient-company-leg.test.ts +0 -384
- package/test/e2e/sync/windows-unreadable-link-leg.test.ts +0 -191
- package/test/e2e/watcher-real-chokidar.test.ts +0 -165
- package/test/e2e/watcher-recursive-backend.test.ts +0 -181
- package/test/e2e/watcher-scoped-coverage.test.ts +0 -381
- package/test/invite-flow.integration.test.ts +0 -244
- package/test/joiner-manifest-reconcile.integration.test.ts +0 -322
- package/test/share-sync.integration.test.ts +0 -213
- package/tsconfig.json +0 -19
- package/vitest.config.ts +0 -22
package/src/sources/list.test.ts
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for sources/list.ts.
|
|
3
|
-
*
|
|
4
|
-
* Uses an in-memory S3Client stub installed via the internal `_setSourcesS3Factory`
|
|
5
|
-
* hook so we don't have to stand up vi.mock for @aws-sdk/client-s3.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
9
|
-
import { Readable } from "node:stream";
|
|
10
|
-
import {
|
|
11
|
-
GetObjectCommand,
|
|
12
|
-
ListObjectsV2Command,
|
|
13
|
-
type S3Client,
|
|
14
|
-
} from "@aws-sdk/client-s3";
|
|
15
|
-
import { listSources } from "./list.js";
|
|
16
|
-
import {
|
|
17
|
-
_setSourcesS3Factory,
|
|
18
|
-
_resetSourcesS3Factory,
|
|
19
|
-
} from "./internals.js";
|
|
20
|
-
import {
|
|
21
|
-
setPresignedGetTransportForTesting,
|
|
22
|
-
type PresignedGetTransport,
|
|
23
|
-
type PresignTransportClient,
|
|
24
|
-
} from "../object-io.js";
|
|
25
|
-
import type { VaultListedObject } from "../vault-client.js";
|
|
26
|
-
import type { EntityContext } from "../types.js";
|
|
27
|
-
import { InvalidSourceChannelError } from "../schemas/source-channels.js";
|
|
28
|
-
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
// Fixtures + helpers
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
const ENTITY: EntityContext = {
|
|
34
|
-
uid: "cmp_test_001",
|
|
35
|
-
slug: "test",
|
|
36
|
-
bucketName: "hq-vault-test",
|
|
37
|
-
region: "us-east-1",
|
|
38
|
-
credentials: {
|
|
39
|
-
accessKeyId: "ASIATEST",
|
|
40
|
-
secretAccessKey: "secret",
|
|
41
|
-
sessionToken: "session",
|
|
42
|
-
},
|
|
43
|
-
expiresAt: new Date(Date.now() + 3600_000).toISOString(),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const MEETING_MD = `---
|
|
47
|
-
source_id: abc
|
|
48
|
-
source_type: meeting
|
|
49
|
-
channel: meeting
|
|
50
|
-
title: Hello
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
Body text.
|
|
54
|
-
`;
|
|
55
|
-
|
|
56
|
-
interface StoredObject {
|
|
57
|
-
key: string;
|
|
58
|
-
content: string;
|
|
59
|
-
lastModified: Date;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Build an in-memory S3 stub. Pagination is keyed by ContinuationToken (string offset). */
|
|
63
|
-
function buildStub(
|
|
64
|
-
objects: StoredObject[],
|
|
65
|
-
observed: { commands: unknown[] } = { commands: [] },
|
|
66
|
-
): S3Client {
|
|
67
|
-
async function send(command: unknown): Promise<unknown> {
|
|
68
|
-
observed.commands.push(command);
|
|
69
|
-
|
|
70
|
-
if (command instanceof ListObjectsV2Command) {
|
|
71
|
-
const { Prefix, MaxKeys, ContinuationToken } = command.input as {
|
|
72
|
-
Prefix?: string;
|
|
73
|
-
MaxKeys?: number;
|
|
74
|
-
ContinuationToken?: string;
|
|
75
|
-
};
|
|
76
|
-
const filtered = objects.filter((o) => !Prefix || o.key.startsWith(Prefix));
|
|
77
|
-
const offset = ContinuationToken ? parseInt(ContinuationToken, 10) : 0;
|
|
78
|
-
const max = MaxKeys ?? 1000;
|
|
79
|
-
const page = filtered.slice(offset, offset + max);
|
|
80
|
-
const nextOffset = offset + page.length;
|
|
81
|
-
const truncated = nextOffset < filtered.length;
|
|
82
|
-
return {
|
|
83
|
-
Contents: page.map((o) => ({
|
|
84
|
-
Key: o.key,
|
|
85
|
-
Size: Buffer.byteLength(o.content, "utf-8"),
|
|
86
|
-
LastModified: o.lastModified,
|
|
87
|
-
ETag: '"mock"',
|
|
88
|
-
})),
|
|
89
|
-
IsTruncated: truncated,
|
|
90
|
-
NextContinuationToken: truncated ? String(nextOffset) : undefined,
|
|
91
|
-
$metadata: {},
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (command instanceof GetObjectCommand) {
|
|
96
|
-
const { Key } = command.input as { Key: string };
|
|
97
|
-
const found = objects.find((o) => o.key === Key);
|
|
98
|
-
if (!found) {
|
|
99
|
-
const err = new Error(`NoSuchKey: ${Key}`);
|
|
100
|
-
(err as Error & { name: string }).name = "NoSuchKey";
|
|
101
|
-
throw err;
|
|
102
|
-
}
|
|
103
|
-
const content = found.content;
|
|
104
|
-
async function* stream(): AsyncIterable<Uint8Array> {
|
|
105
|
-
yield Buffer.from(content, "utf-8");
|
|
106
|
-
}
|
|
107
|
-
return { Body: stream(), $metadata: {} };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
throw new Error(`unhandled command: ${(command as { constructor?: { name?: string } }).constructor?.name}`);
|
|
111
|
-
}
|
|
112
|
-
return { send } as unknown as S3Client;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function installStub(objects: StoredObject[]): { commands: unknown[] } {
|
|
116
|
-
const observed = { commands: [] as unknown[] };
|
|
117
|
-
const stub = buildStub(objects, observed);
|
|
118
|
-
_setSourcesS3Factory(() => stub);
|
|
119
|
-
return observed;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
beforeEach(() => {
|
|
123
|
-
_resetSourcesS3Factory();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
afterEach(() => {
|
|
127
|
-
_resetSourcesS3Factory();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
// Tests
|
|
132
|
-
// ---------------------------------------------------------------------------
|
|
133
|
-
|
|
134
|
-
describe("listSources", () => {
|
|
135
|
-
it("happy path: lists one source and skips its .raw.json sibling", async () => {
|
|
136
|
-
installStub([
|
|
137
|
-
{
|
|
138
|
-
key: "sources/meetings/abc.md",
|
|
139
|
-
content: MEETING_MD,
|
|
140
|
-
lastModified: new Date("2026-03-15T14:00:00Z"),
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
key: "sources/meetings/abc.raw.json",
|
|
144
|
-
content: '{"raw": true}',
|
|
145
|
-
lastModified: new Date("2026-03-15T14:00:00Z"),
|
|
146
|
-
},
|
|
147
|
-
]);
|
|
148
|
-
|
|
149
|
-
const result = await listSources({ entity: ENTITY, channel: "meeting" });
|
|
150
|
-
|
|
151
|
-
expect(result.entries).toHaveLength(1);
|
|
152
|
-
expect(result.entries[0].sourceId).toBe("abc");
|
|
153
|
-
expect(result.entries[0].channel).toBe("meeting");
|
|
154
|
-
expect(result.entries[0].key).toBe("sources/meetings/abc.md");
|
|
155
|
-
expect(result.entries[0].size).toBeGreaterThan(0);
|
|
156
|
-
expect(result.entries[0].frontmatter).toBeUndefined();
|
|
157
|
-
expect(result.nextToken).toBeUndefined();
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("pagination: returns nextToken and accepts it on the next call", async () => {
|
|
161
|
-
const objects: StoredObject[] = Array.from({ length: 5 }, (_, i) => ({
|
|
162
|
-
key: `sources/meetings/m${i}.md`,
|
|
163
|
-
content: MEETING_MD,
|
|
164
|
-
lastModified: new Date("2026-03-15T14:00:00Z"),
|
|
165
|
-
}));
|
|
166
|
-
installStub(objects);
|
|
167
|
-
|
|
168
|
-
const page1 = await listSources({
|
|
169
|
-
entity: ENTITY,
|
|
170
|
-
channel: "meeting",
|
|
171
|
-
limit: 2,
|
|
172
|
-
});
|
|
173
|
-
expect(page1.entries).toHaveLength(2);
|
|
174
|
-
expect(page1.entries.map((e) => e.sourceId)).toEqual(["m0", "m1"]);
|
|
175
|
-
expect(page1.nextToken).toBe("2");
|
|
176
|
-
|
|
177
|
-
const page2 = await listSources({
|
|
178
|
-
entity: ENTITY,
|
|
179
|
-
channel: "meeting",
|
|
180
|
-
limit: 2,
|
|
181
|
-
continuationToken: page1.nextToken,
|
|
182
|
-
});
|
|
183
|
-
expect(page2.entries.map((e) => e.sourceId)).toEqual(["m2", "m3"]);
|
|
184
|
-
expect(page2.nextToken).toBe("4");
|
|
185
|
-
|
|
186
|
-
const page3 = await listSources({
|
|
187
|
-
entity: ENTITY,
|
|
188
|
-
channel: "meeting",
|
|
189
|
-
limit: 2,
|
|
190
|
-
continuationToken: page2.nextToken,
|
|
191
|
-
});
|
|
192
|
-
expect(page3.entries.map((e) => e.sourceId)).toEqual(["m4"]);
|
|
193
|
-
expect(page3.nextToken).toBeUndefined();
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it("includeFrontmatter:true fetches each object and parses YAML", async () => {
|
|
197
|
-
const observed = installStub([
|
|
198
|
-
{
|
|
199
|
-
key: "sources/meetings/abc.md",
|
|
200
|
-
content: MEETING_MD,
|
|
201
|
-
lastModified: new Date("2026-03-15T14:00:00Z"),
|
|
202
|
-
},
|
|
203
|
-
]);
|
|
204
|
-
|
|
205
|
-
const result = await listSources({
|
|
206
|
-
entity: ENTITY,
|
|
207
|
-
channel: "meeting",
|
|
208
|
-
includeFrontmatter: true,
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
expect(result.entries).toHaveLength(1);
|
|
212
|
-
expect(result.entries[0].frontmatter).toEqual({
|
|
213
|
-
source_id: "abc",
|
|
214
|
-
source_type: "meeting",
|
|
215
|
-
channel: "meeting",
|
|
216
|
-
title: "Hello",
|
|
217
|
-
});
|
|
218
|
-
// 1 list + 1 get for the single entry.
|
|
219
|
-
expect(observed.commands.filter((c) => c instanceof GetObjectCommand)).toHaveLength(1);
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
it("includeFrontmatter:false (default) does not perform GETs", async () => {
|
|
223
|
-
const observed = installStub([
|
|
224
|
-
{
|
|
225
|
-
key: "sources/meetings/abc.md",
|
|
226
|
-
content: MEETING_MD,
|
|
227
|
-
lastModified: new Date(),
|
|
228
|
-
},
|
|
229
|
-
]);
|
|
230
|
-
|
|
231
|
-
await listSources({ entity: ENTITY, channel: "meeting" });
|
|
232
|
-
|
|
233
|
-
expect(observed.commands.filter((c) => c instanceof GetObjectCommand)).toHaveLength(0);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it("uses the correct prefix per channel", async () => {
|
|
237
|
-
const observed = installStub([]);
|
|
238
|
-
await listSources({ entity: ENTITY, channel: "slack" });
|
|
239
|
-
const listCmd = observed.commands[0] as ListObjectsV2Command;
|
|
240
|
-
expect((listCmd.input as { Prefix?: string }).Prefix).toBe("sources/slack/");
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it("rejects an invalid channel via assertSourceChannel BEFORE any S3 call", async () => {
|
|
244
|
-
const observed = installStub([]);
|
|
245
|
-
await expect(
|
|
246
|
-
listSources({
|
|
247
|
-
entity: ENTITY,
|
|
248
|
-
// @ts-expect-error — invalid channel intentional for negative test
|
|
249
|
-
channel: "pigeon",
|
|
250
|
-
}),
|
|
251
|
-
).rejects.toBeInstanceOf(InvalidSourceChannelError);
|
|
252
|
-
expect(observed.commands).toHaveLength(0);
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// ---------------------------------------------------------------------------
|
|
257
|
-
// Presigned transport (vault client + company vault) — HQ-59
|
|
258
|
-
// ---------------------------------------------------------------------------
|
|
259
|
-
|
|
260
|
-
interface PresignVaultStub {
|
|
261
|
-
vault: PresignTransportClient;
|
|
262
|
-
listCalls: Array<{ prefix?: string; cursor?: string }>;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function fetchBackedPresignedGetTransport(): PresignedGetTransport {
|
|
266
|
-
return {
|
|
267
|
-
async get(url, headers) {
|
|
268
|
-
const response = await fetch(url, { method: "GET", headers });
|
|
269
|
-
const body = response.body ? Readable.fromWeb(response.body) : undefined;
|
|
270
|
-
return {
|
|
271
|
-
status: response.status,
|
|
272
|
-
headers: response.headers,
|
|
273
|
-
body,
|
|
274
|
-
destroy: () => body?.destroy(),
|
|
275
|
-
};
|
|
276
|
-
},
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Vault stub for the list path: `listFiles` returns the configured ACL-filtered
|
|
282
|
-
* page (the server is the ACL boundary — only readable keys come back) + an
|
|
283
|
-
* opaque cursor; `presign`+fetch serve per-entry frontmatter GETs.
|
|
284
|
-
*/
|
|
285
|
-
function makePresignVault(
|
|
286
|
-
page: { objects: VaultListedObject[]; cursor: string | null },
|
|
287
|
-
contents: Record<string, string> = {},
|
|
288
|
-
): PresignVaultStub {
|
|
289
|
-
const listCalls: Array<{ prefix?: string; cursor?: string }> = [];
|
|
290
|
-
vi.stubGlobal(
|
|
291
|
-
"fetch",
|
|
292
|
-
vi.fn(async (url: string) => {
|
|
293
|
-
const key = new URL(url).searchParams.get("key") ?? "";
|
|
294
|
-
const c = contents[key];
|
|
295
|
-
if (c === undefined) return new Response(null, { status: 404 });
|
|
296
|
-
return new Response(Buffer.from(c, "utf-8"), { status: 200 });
|
|
297
|
-
}),
|
|
298
|
-
);
|
|
299
|
-
setPresignedGetTransportForTesting(fetchBackedPresignedGetTransport());
|
|
300
|
-
const vault: PresignTransportClient = {
|
|
301
|
-
presign: async (input) => ({
|
|
302
|
-
results: input.keys.map((k) => ({
|
|
303
|
-
key: k.key,
|
|
304
|
-
op: k.op ?? input.op ?? "get",
|
|
305
|
-
url: `https://signed.example/?key=${encodeURIComponent(k.key)}`,
|
|
306
|
-
})),
|
|
307
|
-
expiresAt: "2099-01-01T00:00:00.000Z",
|
|
308
|
-
}),
|
|
309
|
-
listFiles: async (_company, prefix, cursor) => {
|
|
310
|
-
listCalls.push({ prefix, cursor });
|
|
311
|
-
return {
|
|
312
|
-
objects: page.objects,
|
|
313
|
-
cursor: page.cursor,
|
|
314
|
-
truncated: page.cursor != null,
|
|
315
|
-
};
|
|
316
|
-
},
|
|
317
|
-
};
|
|
318
|
-
return { vault, listCalls };
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function listed(key: string): VaultListedObject {
|
|
322
|
-
return {
|
|
323
|
-
key,
|
|
324
|
-
size: 10,
|
|
325
|
-
lastModified: "2026-02-01T00:00:00.000Z",
|
|
326
|
-
etag: "etag",
|
|
327
|
-
permission: "read",
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
describe("listSources — presigned transport (vault + cmp_)", () => {
|
|
332
|
-
afterEach(() => {
|
|
333
|
-
setPresignedGetTransportForTesting(null);
|
|
334
|
-
vi.unstubAllGlobals();
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
it("lists via the ACL-filtered vault endpoint and never touches S3", async () => {
|
|
338
|
-
_setSourcesS3Factory(
|
|
339
|
-
() =>
|
|
340
|
-
({
|
|
341
|
-
send: async () => {
|
|
342
|
-
throw new Error("S3 must not be used on the presign path");
|
|
343
|
-
},
|
|
344
|
-
}) as unknown as S3Client,
|
|
345
|
-
);
|
|
346
|
-
const { vault, listCalls } = makePresignVault({
|
|
347
|
-
objects: [listed("sources/meetings/a.md"), listed("sources/meetings/a.raw.json")],
|
|
348
|
-
cursor: null,
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
const res = await listSources({ entity: ENTITY, channel: "meeting", vault });
|
|
352
|
-
|
|
353
|
-
// .raw.json sibling is skipped; only the .md entry surfaces.
|
|
354
|
-
expect(res.entries.map((e) => e.sourceId)).toEqual(["a"]);
|
|
355
|
-
expect(res.entries[0].key).toBe("sources/meetings/a.md");
|
|
356
|
-
expect(res.nextToken).toBeUndefined();
|
|
357
|
-
// listFiles was called with the channel prefix (ACL filtering is server-side).
|
|
358
|
-
expect(listCalls[0].prefix).toBe("sources/meetings/");
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
it("surfaces the opaque vault cursor as nextToken (advisory limit)", async () => {
|
|
362
|
-
const { vault } = makePresignVault({
|
|
363
|
-
objects: [listed("sources/meetings/a.md")],
|
|
364
|
-
cursor: "OPAQUE_CURSOR",
|
|
365
|
-
});
|
|
366
|
-
const res = await listSources({
|
|
367
|
-
entity: ENTITY,
|
|
368
|
-
channel: "meeting",
|
|
369
|
-
limit: 1,
|
|
370
|
-
vault,
|
|
371
|
-
});
|
|
372
|
-
expect(res.nextToken).toBe("OPAQUE_CURSOR");
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it("includeFrontmatter parses each entry via a presigned GET", async () => {
|
|
376
|
-
const { vault } = makePresignVault(
|
|
377
|
-
{ objects: [listed("sources/meetings/a.md")], cursor: null },
|
|
378
|
-
{ "sources/meetings/a.md": MEETING_MD },
|
|
379
|
-
);
|
|
380
|
-
const res = await listSources({
|
|
381
|
-
entity: ENTITY,
|
|
382
|
-
channel: "meeting",
|
|
383
|
-
includeFrontmatter: true,
|
|
384
|
-
vault,
|
|
385
|
-
});
|
|
386
|
-
expect(res.entries[0].frontmatter).toMatchObject({ title: "Hello" });
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
it("forwards the continuationToken as the vault cursor", async () => {
|
|
390
|
-
const { vault, listCalls } = makePresignVault({
|
|
391
|
-
objects: [],
|
|
392
|
-
cursor: null,
|
|
393
|
-
});
|
|
394
|
-
await listSources({
|
|
395
|
-
entity: ENTITY,
|
|
396
|
-
channel: "meeting",
|
|
397
|
-
continuationToken: "RESUME_HERE",
|
|
398
|
-
vault,
|
|
399
|
-
});
|
|
400
|
-
expect(listCalls[0].cursor).toBe("RESUME_HERE");
|
|
401
|
-
});
|
|
402
|
-
});
|
package/src/sources/list.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* listSources — page through `sources/{channel}/` keys in an entity bucket
|
|
3
|
-
* and return typed summaries.
|
|
4
|
-
*
|
|
5
|
-
* The `.raw.json` siblings written by the sources-pipeline are skipped from
|
|
6
|
-
* the summary (callers fetch them via getSource({ includeRaw: true })).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { assertSourceChannel, sourcePathSegment } from "../schemas/source-channels.js";
|
|
10
|
-
import { listObjects, readObjectText } from "./internals.js";
|
|
11
|
-
import { parseFrontmatter } from "./parse.js";
|
|
12
|
-
import type {
|
|
13
|
-
ListSourcesOptions,
|
|
14
|
-
ListSourcesResult,
|
|
15
|
-
SourceSummary,
|
|
16
|
-
} from "./types.js";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Strip the `sources/{channel}/` prefix and `.md` / `.raw.json` suffix from a key.
|
|
20
|
-
* Returns `null` if the key shape isn't recognised; the `isRawSibling` flag tells
|
|
21
|
-
* callers to skip pipeline-internal `.raw.json` companions from summaries.
|
|
22
|
-
*/
|
|
23
|
-
function deriveSourceId(
|
|
24
|
-
key: string,
|
|
25
|
-
prefix: string,
|
|
26
|
-
): { sourceId: string; isRawSibling: boolean } | null {
|
|
27
|
-
if (!key.startsWith(prefix)) return null;
|
|
28
|
-
const tail = key.slice(prefix.length);
|
|
29
|
-
if (tail.endsWith(".raw.json")) {
|
|
30
|
-
return { sourceId: tail.slice(0, -".raw.json".length), isRawSibling: true };
|
|
31
|
-
}
|
|
32
|
-
if (tail.endsWith(".md")) {
|
|
33
|
-
return { sourceId: tail.slice(0, -".md".length), isRawSibling: false };
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export async function listSources(opts: ListSourcesOptions): Promise<ListSourcesResult> {
|
|
39
|
-
// Validate channel BEFORE any read (acceptance criterion).
|
|
40
|
-
assertSourceChannel(opts.channel);
|
|
41
|
-
|
|
42
|
-
// Use the canonical path segment from the schema; channel "meeting" maps
|
|
43
|
-
// to the plural "meetings/" prefix the sources-pipeline writes to.
|
|
44
|
-
const prefix = `sources/${sourcePathSegment(opts.channel)}/`;
|
|
45
|
-
|
|
46
|
-
// Presign transport ACL-filters server-side and controls page size, so
|
|
47
|
-
// `limit` is advisory there; under direct S3 it maps to MaxKeys. Paginate via
|
|
48
|
-
// the returned nextToken regardless of transport.
|
|
49
|
-
const page = await listObjects(opts, prefix, {
|
|
50
|
-
limit: opts.limit,
|
|
51
|
-
continuationToken: opts.continuationToken,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const entries: SourceSummary[] = [];
|
|
55
|
-
for (const obj of page.contents) {
|
|
56
|
-
const derived = deriveSourceId(obj.key, prefix);
|
|
57
|
-
if (!derived || derived.isRawSibling) continue;
|
|
58
|
-
|
|
59
|
-
const summary: SourceSummary = {
|
|
60
|
-
sourceId: derived.sourceId,
|
|
61
|
-
channel: opts.channel,
|
|
62
|
-
key: obj.key,
|
|
63
|
-
lastModified: obj.lastModified,
|
|
64
|
-
size: obj.size,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (opts.includeFrontmatter) {
|
|
68
|
-
try {
|
|
69
|
-
const text = await readObjectText(opts, obj.key);
|
|
70
|
-
const fm = parseFrontmatter(text);
|
|
71
|
-
if (fm) summary.frontmatter = fm;
|
|
72
|
-
} catch {
|
|
73
|
-
// Frontmatter fetch is best-effort; leave undefined on failure.
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
entries.push(summary);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
entries,
|
|
82
|
-
nextToken: page.nextToken,
|
|
83
|
-
};
|
|
84
|
-
}
|
package/src/sources/parse.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* YAML frontmatter parsing for source markdown documents.
|
|
3
|
-
*
|
|
4
|
-
* Format: a leading `---\n` block terminated by `\n---\n`, followed by the body.
|
|
5
|
-
* Tolerates LF and CRLF. Returns `{ frontmatter: null, body }` when no
|
|
6
|
-
* frontmatter block is present.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { load as yamlLoad } from "js-yaml";
|
|
10
|
-
|
|
11
|
-
export interface ParsedMarkdown {
|
|
12
|
-
frontmatter: Record<string, unknown> | null;
|
|
13
|
-
body: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
17
|
-
|
|
18
|
-
export function parseMarkdown(content: string): ParsedMarkdown {
|
|
19
|
-
const match = FRONTMATTER_RE.exec(content);
|
|
20
|
-
if (!match) {
|
|
21
|
-
return { frontmatter: null, body: content };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const [, yamlBlock, body] = match;
|
|
25
|
-
let frontmatter: Record<string, unknown> | null;
|
|
26
|
-
try {
|
|
27
|
-
const loaded = yamlLoad(yamlBlock);
|
|
28
|
-
frontmatter = loaded && typeof loaded === "object" && !Array.isArray(loaded)
|
|
29
|
-
? (loaded as Record<string, unknown>)
|
|
30
|
-
: null;
|
|
31
|
-
} catch {
|
|
32
|
-
frontmatter = null;
|
|
33
|
-
}
|
|
34
|
-
return { frontmatter, body };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Convenience: parse only the frontmatter (used by listSources includeFrontmatter
|
|
39
|
-
* where we don't need the body).
|
|
40
|
-
*/
|
|
41
|
-
export function parseFrontmatter(content: string): Record<string, unknown> | null {
|
|
42
|
-
return parseMarkdown(content).frontmatter;
|
|
43
|
-
}
|
package/src/sources/types.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public types for the sources read surface.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors the sources-pipeline write path so a meeting source written by
|
|
5
|
-
* hq-pro is readable through this layer without translation.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { SourceChannel } from "../schemas/source-channels.js";
|
|
9
|
-
import type { PresignTransportClient } from "../object-io.js";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Lightweight summary returned by listSources(). `frontmatter` is only
|
|
13
|
-
* populated when the caller passes `includeFrontmatter: true`.
|
|
14
|
-
*/
|
|
15
|
-
export interface SourceSummary {
|
|
16
|
-
/** Stable ID derived from the object key (filename minus `.md`/`.raw.json`). */
|
|
17
|
-
sourceId: string;
|
|
18
|
-
channel: SourceChannel;
|
|
19
|
-
/** Full S3 object key (e.g. "sources/meeting/abc.md"). */
|
|
20
|
-
key: string;
|
|
21
|
-
lastModified: Date;
|
|
22
|
-
size: number;
|
|
23
|
-
/** Parsed YAML frontmatter — only present when listSources(includeFrontmatter:true). */
|
|
24
|
-
frontmatter?: Record<string, unknown>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Full source document returned by getSource(). `frontmatter` is `null` if
|
|
29
|
-
* the document was malformed (no `---` delimiters) — body still contains the
|
|
30
|
-
* raw payload in that case so callers can fall back.
|
|
31
|
-
*/
|
|
32
|
-
export interface SourceDocument {
|
|
33
|
-
key: string;
|
|
34
|
-
/** Parsed YAML frontmatter, or `null` if the document had no frontmatter block. */
|
|
35
|
-
frontmatter: Record<string, unknown> | null;
|
|
36
|
-
/** Markdown body (everything after the closing `---`). */
|
|
37
|
-
body: string;
|
|
38
|
-
/** Sibling `.raw.json` payload, only present when getSource(includeRaw:true). */
|
|
39
|
-
raw?: unknown;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Listing options for listSources().
|
|
44
|
-
*/
|
|
45
|
-
export interface ListSourcesOptions {
|
|
46
|
-
entity: import("../types.js").EntityContext;
|
|
47
|
-
channel: SourceChannel;
|
|
48
|
-
/**
|
|
49
|
-
* Max keys per page. Under direct S3 this maps to `MaxKeys`; under the
|
|
50
|
-
* presigned transport ({@link vault} + a company vault) it is advisory — the
|
|
51
|
-
* vault `list` endpoint controls page size server-side. Defaults to the S3
|
|
52
|
-
* default (1000) on the direct path.
|
|
53
|
-
*/
|
|
54
|
-
limit?: number;
|
|
55
|
-
/** Opaque continuation token returned by a prior page. */
|
|
56
|
-
continuationToken?: string;
|
|
57
|
-
/** When true, fetches+parses each entry's frontmatter (extra GETs). */
|
|
58
|
-
includeFrontmatter?: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Presign-capable vault client. When supplied and {@link entity} is a company
|
|
61
|
-
* vault (cmp_*), reads use the presigned-URL transport (ACL-filtered, no
|
|
62
|
-
* direct S3). Personal vaults and the absent-client path stay on direct S3.
|
|
63
|
-
*/
|
|
64
|
-
vault?: PresignTransportClient;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface ListSourcesResult {
|
|
68
|
-
entries: SourceSummary[];
|
|
69
|
-
/** Present when the result was truncated; pass back as continuationToken. */
|
|
70
|
-
nextToken?: string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface GetSourceOptions {
|
|
74
|
-
entity: import("../types.js").EntityContext;
|
|
75
|
-
channel: SourceChannel;
|
|
76
|
-
sourceId: string;
|
|
77
|
-
/** When true, also fetches the `.raw.json` sibling. */
|
|
78
|
-
includeRaw?: boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Presign-capable vault client. When supplied and {@link entity} is a company
|
|
81
|
-
* vault (cmp_*), reads use the presigned-URL transport (no direct S3).
|
|
82
|
-
*/
|
|
83
|
-
vault?: PresignTransportClient;
|
|
84
|
-
}
|