@collage-dam/mcp-server 0.1.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/.env.example +56 -0
- package/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +512 -0
- package/dist/client.d.ts +497 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1162 -0
- package/dist/client.js.map +1 -0
- package/dist/conventions/confirmation.d.ts +89 -0
- package/dist/conventions/confirmation.d.ts.map +1 -0
- package/dist/conventions/confirmation.js +132 -0
- package/dist/conventions/confirmation.js.map +1 -0
- package/dist/conventions/dry-run/batch-executor.d.ts +36 -0
- package/dist/conventions/dry-run/batch-executor.d.ts.map +1 -0
- package/dist/conventions/dry-run/batch-executor.js +89 -0
- package/dist/conventions/dry-run/batch-executor.js.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts +34 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.js +158 -0
- package/dist/conventions/dry-run/diff-renderer.js.map +1 -0
- package/dist/conventions/dry-run/index.d.ts +13 -0
- package/dist/conventions/dry-run/index.d.ts.map +1 -0
- package/dist/conventions/dry-run/index.js +10 -0
- package/dist/conventions/dry-run/index.js.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts +64 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.js +88 -0
- package/dist/conventions/dry-run/mutating-tool.js.map +1 -0
- package/dist/conventions/dry-run/summary.d.ts +66 -0
- package/dist/conventions/dry-run/summary.d.ts.map +1 -0
- package/dist/conventions/dry-run/summary.js +185 -0
- package/dist/conventions/dry-run/summary.js.map +1 -0
- package/dist/conventions/dry-run/types.d.ts +597 -0
- package/dist/conventions/dry-run/types.d.ts.map +1 -0
- package/dist/conventions/dry-run/types.js +108 -0
- package/dist/conventions/dry-run/types.js.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts +66 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.js +219 -0
- package/dist/conventions/dry-run/with-dry-run.js.map +1 -0
- package/dist/conventions/env.d.ts +49 -0
- package/dist/conventions/env.d.ts.map +1 -0
- package/dist/conventions/env.js +84 -0
- package/dist/conventions/env.js.map +1 -0
- package/dist/conventions/errors.d.ts +68 -0
- package/dist/conventions/errors.d.ts.map +1 -0
- package/dist/conventions/errors.js +81 -0
- package/dist/conventions/errors.js.map +1 -0
- package/dist/conventions/logger.d.ts +28 -0
- package/dist/conventions/logger.d.ts.map +1 -0
- package/dist/conventions/logger.js +105 -0
- package/dist/conventions/logger.js.map +1 -0
- package/dist/conventions/pagination.d.ts +37 -0
- package/dist/conventions/pagination.d.ts.map +1 -0
- package/dist/conventions/pagination.js +53 -0
- package/dist/conventions/pagination.js.map +1 -0
- package/dist/conventions/rate-limiter.d.ts +54 -0
- package/dist/conventions/rate-limiter.d.ts.map +1 -0
- package/dist/conventions/rate-limiter.js +143 -0
- package/dist/conventions/rate-limiter.js.map +1 -0
- package/dist/conventions/response-budget.d.ts +66 -0
- package/dist/conventions/response-budget.d.ts.map +1 -0
- package/dist/conventions/response-budget.js +89 -0
- package/dist/conventions/response-budget.js.map +1 -0
- package/dist/conventions/schema-version.d.ts +27 -0
- package/dist/conventions/schema-version.d.ts.map +1 -0
- package/dist/conventions/schema-version.js +29 -0
- package/dist/conventions/schema-version.js.map +1 -0
- package/dist/conventions/state-store-redis.d.ts +32 -0
- package/dist/conventions/state-store-redis.d.ts.map +1 -0
- package/dist/conventions/state-store-redis.js +77 -0
- package/dist/conventions/state-store-redis.js.map +1 -0
- package/dist/conventions/state-store.d.ts +46 -0
- package/dist/conventions/state-store.d.ts.map +1 -0
- package/dist/conventions/state-store.js +105 -0
- package/dist/conventions/state-store.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/collection-audit.d.ts +13 -0
- package/dist/prompts/collection-audit.d.ts.map +1 -0
- package/dist/prompts/collection-audit.js +168 -0
- package/dist/prompts/collection-audit.js.map +1 -0
- package/dist/prompts/create-distribution.d.ts +15 -0
- package/dist/prompts/create-distribution.d.ts.map +1 -0
- package/dist/prompts/create-distribution.js +111 -0
- package/dist/prompts/create-distribution.js.map +1 -0
- package/dist/prompts/helpers.d.ts +20 -0
- package/dist/prompts/helpers.d.ts.map +1 -0
- package/dist/prompts/helpers.js +53 -0
- package/dist/prompts/helpers.js.map +1 -0
- package/dist/prompts/library-health-audit.d.ts +13 -0
- package/dist/prompts/library-health-audit.d.ts.map +1 -0
- package/dist/prompts/library-health-audit.js +131 -0
- package/dist/prompts/library-health-audit.js.map +1 -0
- package/dist/prompts/usage-insights.d.ts +13 -0
- package/dist/prompts/usage-insights.d.ts.map +1 -0
- package/dist/prompts/usage-insights.js +98 -0
- package/dist/prompts/usage-insights.js.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts +48 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.js +61 -0
- package/dist/prompts/wrap-prompt-as-tool.js.map +1 -0
- package/dist/resources/asset-by-id.d.ts +4 -0
- package/dist/resources/asset-by-id.d.ts.map +1 -0
- package/dist/resources/asset-by-id.js +27 -0
- package/dist/resources/asset-by-id.js.map +1 -0
- package/dist/resources/collections.d.ts +5 -0
- package/dist/resources/collections.d.ts.map +1 -0
- package/dist/resources/collections.js +48 -0
- package/dist/resources/collections.js.map +1 -0
- package/dist/resources/custom-fields.d.ts +4 -0
- package/dist/resources/custom-fields.d.ts.map +1 -0
- package/dist/resources/custom-fields.js +30 -0
- package/dist/resources/custom-fields.js.map +1 -0
- package/dist/resources/folders.d.ts +5 -0
- package/dist/resources/folders.d.ts.map +1 -0
- package/dist/resources/folders.js +73 -0
- package/dist/resources/folders.js.map +1 -0
- package/dist/resources/helpers.d.ts +17 -0
- package/dist/resources/helpers.d.ts.map +1 -0
- package/dist/resources/helpers.js +59 -0
- package/dist/resources/helpers.js.map +1 -0
- package/dist/resources/portals.d.ts +5 -0
- package/dist/resources/portals.d.ts.map +1 -0
- package/dist/resources/portals.js +81 -0
- package/dist/resources/portals.js.map +1 -0
- package/dist/resources/recent-and-dashboard.d.ts +5 -0
- package/dist/resources/recent-and-dashboard.d.ts.map +1 -0
- package/dist/resources/recent-and-dashboard.js +42 -0
- package/dist/resources/recent-and-dashboard.js.map +1 -0
- package/dist/tools/asset-selection.d.ts +102 -0
- package/dist/tools/asset-selection.d.ts.map +1 -0
- package/dist/tools/asset-selection.js +133 -0
- package/dist/tools/asset-selection.js.map +1 -0
- package/dist/tools/audit/audit-folder-structure.d.ts +108 -0
- package/dist/tools/audit/audit-folder-structure.d.ts.map +1 -0
- package/dist/tools/audit/audit-folder-structure.js +260 -0
- package/dist/tools/audit/audit-folder-structure.js.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts +83 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.js +238 -0
- package/dist/tools/audit/audit-naming-conventions.js.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts +77 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.js +402 -0
- package/dist/tools/audit/audit-tagging-hygiene.js.map +1 -0
- package/dist/tools/audit/detect-duplicates.d.ts +62 -0
- package/dist/tools/audit/detect-duplicates.d.ts.map +1 -0
- package/dist/tools/audit/detect-duplicates.js +0 -0
- package/dist/tools/audit/detect-duplicates.js.map +1 -0
- package/dist/tools/audit/types.d.ts +526 -0
- package/dist/tools/audit/types.d.ts.map +1 -0
- package/dist/tools/audit/types.js +188 -0
- package/dist/tools/audit/types.js.map +1 -0
- package/dist/tools/bulk-move-assets.d.ts +78 -0
- package/dist/tools/bulk-move-assets.d.ts.map +1 -0
- package/dist/tools/bulk-move-assets.js +122 -0
- package/dist/tools/bulk-move-assets.js.map +1 -0
- package/dist/tools/bulk-normalize-filenames.d.ts +62 -0
- package/dist/tools/bulk-normalize-filenames.d.ts.map +1 -0
- package/dist/tools/bulk-normalize-filenames.js +237 -0
- package/dist/tools/bulk-normalize-filenames.js.map +1 -0
- package/dist/tools/bulk-rename-assets.d.ts +79 -0
- package/dist/tools/bulk-rename-assets.d.ts.map +1 -0
- package/dist/tools/bulk-rename-assets.js +139 -0
- package/dist/tools/bulk-rename-assets.js.map +1 -0
- package/dist/tools/bulk-tags.d.ts +107 -0
- package/dist/tools/bulk-tags.d.ts.map +1 -0
- package/dist/tools/bulk-tags.js +220 -0
- package/dist/tools/bulk-tags.js.map +1 -0
- package/dist/tools/client-adapters.d.ts +76 -0
- package/dist/tools/client-adapters.d.ts.map +1 -0
- package/dist/tools/client-adapters.js +648 -0
- package/dist/tools/client-adapters.js.map +1 -0
- package/dist/tools/collection-membership.d.ts +90 -0
- package/dist/tools/collection-membership.d.ts.map +1 -0
- package/dist/tools/collection-membership.js +195 -0
- package/dist/tools/collection-membership.js.map +1 -0
- package/dist/tools/create-collection.d.ts +63 -0
- package/dist/tools/create-collection.d.ts.map +1 -0
- package/dist/tools/create-collection.js +151 -0
- package/dist/tools/create-collection.js.map +1 -0
- package/dist/tools/create-folder.d.ts +46 -0
- package/dist/tools/create-folder.d.ts.map +1 -0
- package/dist/tools/create-folder.js +83 -0
- package/dist/tools/create-folder.js.map +1 -0
- package/dist/tools/create-share-link.d.ts +107 -0
- package/dist/tools/create-share-link.d.ts.map +1 -0
- package/dist/tools/create-share-link.js +239 -0
- package/dist/tools/create-share-link.js.map +1 -0
- package/dist/tools/get-asset-details.d.ts +401 -0
- package/dist/tools/get-asset-details.d.ts.map +1 -0
- package/dist/tools/get-asset-details.js +56 -0
- package/dist/tools/get-asset-details.js.map +1 -0
- package/dist/tools/get-collection.d.ts +126 -0
- package/dist/tools/get-collection.d.ts.map +1 -0
- package/dist/tools/get-collection.js +52 -0
- package/dist/tools/get-collection.js.map +1 -0
- package/dist/tools/get-embed-code.d.ts +195 -0
- package/dist/tools/get-embed-code.d.ts.map +1 -0
- package/dist/tools/get-embed-code.js +214 -0
- package/dist/tools/get-embed-code.js.map +1 -0
- package/dist/tools/insights/analyze-share-links.d.ts +159 -0
- package/dist/tools/insights/analyze-share-links.d.ts.map +1 -0
- package/dist/tools/insights/analyze-share-links.js +314 -0
- package/dist/tools/insights/analyze-share-links.js.map +1 -0
- package/dist/tools/insights/insight-cache.d.ts +36 -0
- package/dist/tools/insights/insight-cache.d.ts.map +1 -0
- package/dist/tools/insights/insight-cache.js +98 -0
- package/dist/tools/insights/insight-cache.js.map +1 -0
- package/dist/tools/insights/report-asset-activation.d.ts +149 -0
- package/dist/tools/insights/report-asset-activation.d.ts.map +1 -0
- package/dist/tools/insights/report-asset-activation.js +380 -0
- package/dist/tools/insights/report-asset-activation.js.map +1 -0
- package/dist/tools/insights/report-stale-assets.d.ts +120 -0
- package/dist/tools/insights/report-stale-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-stale-assets.js +281 -0
- package/dist/tools/insights/report-stale-assets.js.map +1 -0
- package/dist/tools/insights/report-top-assets.d.ts +139 -0
- package/dist/tools/insights/report-top-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-top-assets.js +407 -0
- package/dist/tools/insights/report-top-assets.js.map +1 -0
- package/dist/tools/list-categories.d.ts +127 -0
- package/dist/tools/list-categories.d.ts.map +1 -0
- package/dist/tools/list-categories.js +68 -0
- package/dist/tools/list-categories.js.map +1 -0
- package/dist/tools/list-collections.d.ts +127 -0
- package/dist/tools/list-collections.d.ts.map +1 -0
- package/dist/tools/list-collections.js +53 -0
- package/dist/tools/list-collections.js.map +1 -0
- package/dist/tools/list-custom-fields.d.ts +125 -0
- package/dist/tools/list-custom-fields.d.ts.map +1 -0
- package/dist/tools/list-custom-fields.js +51 -0
- package/dist/tools/list-custom-fields.js.map +1 -0
- package/dist/tools/list-share-links.d.ts +192 -0
- package/dist/tools/list-share-links.d.ts.map +1 -0
- package/dist/tools/list-share-links.js +92 -0
- package/dist/tools/list-share-links.js.map +1 -0
- package/dist/tools/list-workspaces.d.ts +88 -0
- package/dist/tools/list-workspaces.d.ts.map +1 -0
- package/dist/tools/list-workspaces.js +71 -0
- package/dist/tools/list-workspaces.js.map +1 -0
- package/dist/tools/move-asset.d.ts +48 -0
- package/dist/tools/move-asset.d.ts.map +1 -0
- package/dist/tools/move-asset.js +85 -0
- package/dist/tools/move-asset.js.map +1 -0
- package/dist/tools/rename-asset.d.ts +88 -0
- package/dist/tools/rename-asset.d.ts.map +1 -0
- package/dist/tools/rename-asset.js +100 -0
- package/dist/tools/rename-asset.js.map +1 -0
- package/dist/tools/rename-folder.d.ts +55 -0
- package/dist/tools/rename-folder.d.ts.map +1 -0
- package/dist/tools/rename-folder.js +101 -0
- package/dist/tools/rename-folder.js.map +1 -0
- package/dist/tools/revoke-share-link.d.ts +55 -0
- package/dist/tools/revoke-share-link.d.ts.map +1 -0
- package/dist/tools/revoke-share-link.js +77 -0
- package/dist/tools/revoke-share-link.js.map +1 -0
- package/dist/tools/search/facets.d.ts +34 -0
- package/dist/tools/search/facets.d.ts.map +1 -0
- package/dist/tools/search/facets.js +147 -0
- package/dist/tools/search/facets.js.map +1 -0
- package/dist/tools/search/filter-builder.d.ts +33 -0
- package/dist/tools/search/filter-builder.d.ts.map +1 -0
- package/dist/tools/search/filter-builder.js +111 -0
- package/dist/tools/search/filter-builder.js.map +1 -0
- package/dist/tools/search/search-assets.d.ts +41 -0
- package/dist/tools/search/search-assets.d.ts.map +1 -0
- package/dist/tools/search/search-assets.js +162 -0
- package/dist/tools/search/search-assets.js.map +1 -0
- package/dist/tools/search/search-collections.d.ts +35 -0
- package/dist/tools/search/search-collections.d.ts.map +1 -0
- package/dist/tools/search/search-collections.js +103 -0
- package/dist/tools/search/search-collections.js.map +1 -0
- package/dist/tools/search/types.d.ts +1047 -0
- package/dist/tools/search/types.d.ts.map +1 -0
- package/dist/tools/search/types.js +216 -0
- package/dist/tools/search/types.js.map +1 -0
- package/dist/tools/update-asset-metadata.d.ts +78 -0
- package/dist/tools/update-asset-metadata.d.ts.map +1 -0
- package/dist/tools/update-asset-metadata.js +203 -0
- package/dist/tools/update-asset-metadata.js.map +1 -0
- package/dist/tools/update-collection.d.ts +69 -0
- package/dist/tools/update-collection.d.ts.map +1 -0
- package/dist/tools/update-collection.js +142 -0
- package/dist/tools/update-collection.js.map +1 -0
- package/dist/tools/view-category-contents.d.ts +231 -0
- package/dist/tools/view-category-contents.d.ts.map +1 -0
- package/dist/tools/view-category-contents.js +97 -0
- package/dist/tools/view-category-contents.js.map +1 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +288 -0
- package/dist/types.js.map +1 -0
- package/dist/typesense.d.ts +84 -0
- package/dist/typesense.d.ts.map +1 -0
- package/dist/typesense.js +243 -0
- package/dist/typesense.js.map +1 -0
- package/docs/api-field-verification.md +244 -0
- package/docs/deployment-runbook.md +446 -0
- package/docs/security-review.md +195 -0
- package/docs/typesense-filter-schema.md +262 -0
- package/docs/verified-endpoints.md +38 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Phase-1 zod schemas for the Collage REST API surface.
|
|
4
|
+
*
|
|
5
|
+
* Sources of truth, in order of trust:
|
|
6
|
+
* 1. Live API responses against workspace 6307594138 (BREZ demo)
|
|
7
|
+
* 2. Backend-API Laravel migrations (`database/migrations/`)
|
|
8
|
+
* 3. Admin-Frontend usage (`api/index.js`, `api/typesense.js`)
|
|
9
|
+
* 4. Swagger (incomplete — covers ~31 of 150+ endpoints)
|
|
10
|
+
*
|
|
11
|
+
* The shapes here are *defensive*: optional/nullable for any field we have
|
|
12
|
+
* not confirmed against live data. Contract tests in `tests/contract/`
|
|
13
|
+
* tighten these as fields are verified.
|
|
14
|
+
*
|
|
15
|
+
* Numeric IDs come back as either `number` or `string` from Laravel
|
|
16
|
+
* depending on column type and serialiser; we accept both via
|
|
17
|
+
* `IdSchema` and let callers coerce as needed.
|
|
18
|
+
*/
|
|
19
|
+
export const IdSchema = z.union([z.number().int().positive(), z.string().min(1)]);
|
|
20
|
+
export const TimestampSchema = z.string().datetime({ offset: true }).or(z.string());
|
|
21
|
+
/**
|
|
22
|
+
* Standard envelope used by most endpoints — `{ status, message, data: ... }`.
|
|
23
|
+
* Some routes return the data directly; both shapes are accepted by
|
|
24
|
+
* `unwrapEnvelope()`.
|
|
25
|
+
*/
|
|
26
|
+
export const ApiEnvelopeSchema = z.object({
|
|
27
|
+
status: z.union([z.boolean(), z.number(), z.string()]).optional(),
|
|
28
|
+
message: z.string().optional(),
|
|
29
|
+
data: z.unknown(),
|
|
30
|
+
});
|
|
31
|
+
export function unwrapEnvelope(raw, schema) {
|
|
32
|
+
if (raw !== null &&
|
|
33
|
+
typeof raw === 'object' &&
|
|
34
|
+
'data' in raw &&
|
|
35
|
+
ApiEnvelopeSchema.safeParse(raw).success) {
|
|
36
|
+
return schema.parse(raw.data);
|
|
37
|
+
}
|
|
38
|
+
return schema.parse(raw);
|
|
39
|
+
}
|
|
40
|
+
// ── Digital Asset ────────────────────────────────────────────────────────
|
|
41
|
+
// API source of truth: POST /digital-assets/view-detail (verified 2026-04-28
|
|
42
|
+
// against asset 280220 in workspace 1927483178). The `view-detail` response
|
|
43
|
+
// is a richer projection than the raw row in `digital_assets` — it joins in
|
|
44
|
+
// breadcrumb, tag rows, formatted file metadata, and signed S3 URLs.
|
|
45
|
+
export const AssetTagSchema = z.object({
|
|
46
|
+
id: IdSchema,
|
|
47
|
+
tag_name: z.string(),
|
|
48
|
+
});
|
|
49
|
+
export const AssetBreadcrumbSchema = z.object({
|
|
50
|
+
id: IdSchema,
|
|
51
|
+
folder_name: z.string().nullable(),
|
|
52
|
+
parent_id: IdSchema.nullable(),
|
|
53
|
+
instance_visibility: z.array(IdSchema).optional(),
|
|
54
|
+
parent: z.unknown().nullable().optional(),
|
|
55
|
+
});
|
|
56
|
+
export const AssetFileMetadataSchema = z.object({
|
|
57
|
+
DateUploaded: z.string().optional(),
|
|
58
|
+
LastModified: z.string().optional(),
|
|
59
|
+
Credit: z.string().optional(),
|
|
60
|
+
// Video-asset shape returns null here per live BREZ test (asset 141648,
|
|
61
|
+
// 2026-04-29). Image assets return a "WxH" string. Tolerate both.
|
|
62
|
+
Dimensions: z.string().nullable().optional(),
|
|
63
|
+
}).passthrough();
|
|
64
|
+
export const DigitalAssetSchema = z.object({
|
|
65
|
+
id: IdSchema,
|
|
66
|
+
version: z.number().int().nullable().optional(),
|
|
67
|
+
assets_version_id: IdSchema.nullable().optional(),
|
|
68
|
+
workspace_id: IdSchema.nullable().optional(),
|
|
69
|
+
user_id: IdSchema.nullable().optional(),
|
|
70
|
+
display_file_name: z.string(),
|
|
71
|
+
file_name: z.string(),
|
|
72
|
+
file_type: z.string().nullable().optional(),
|
|
73
|
+
file_size: z.number().nullable().optional(),
|
|
74
|
+
height: z.union([z.string(), z.number()]).nullable().optional(),
|
|
75
|
+
width: z.union([z.string(), z.number()]).nullable().optional(),
|
|
76
|
+
description: z.string().nullable().optional(),
|
|
77
|
+
// Video assets return empty string "" per live BREZ test (asset 141648,
|
|
78
|
+
// 2026-04-29). Treat empty string as "unset" — neither true nor false.
|
|
79
|
+
auto_tag: z.union([z.boolean(), z.enum(['0', '1', ''])]).nullable().optional(),
|
|
80
|
+
type: z.string().nullable().optional(),
|
|
81
|
+
category_id: IdSchema.nullable().optional(),
|
|
82
|
+
is_categorized: z.union([z.boolean(), z.enum(['0', '1'])]).optional(),
|
|
83
|
+
is_public: z.union([z.boolean(), z.number()]).optional(),
|
|
84
|
+
is_archive: z.union([z.boolean(), z.number()]).optional(),
|
|
85
|
+
is_deleted: z.union([z.boolean(), z.number()]).optional(),
|
|
86
|
+
is_editorial_use: z.union([z.boolean(), z.number()]).optional(),
|
|
87
|
+
is_external_upload: z.union([z.boolean(), z.number()]).optional(),
|
|
88
|
+
thumbnail_file: z.string().nullable().optional(),
|
|
89
|
+
compress_file: z.string().nullable().optional(),
|
|
90
|
+
video_preview: z.string().nullable().optional(),
|
|
91
|
+
watermark_file: z.string().nullable().optional(),
|
|
92
|
+
watermark_original_file: z.string().nullable().optional(),
|
|
93
|
+
checksum: z.string().nullable().optional(),
|
|
94
|
+
file_preview_id: z.string().nullable().optional(),
|
|
95
|
+
file_preview_status: z
|
|
96
|
+
.enum(['pending', 'started', 'success', 'failure'])
|
|
97
|
+
.optional(),
|
|
98
|
+
share_id: z.array(z.union([z.string(), z.number()])).optional(),
|
|
99
|
+
acl_permission: z.array(z.unknown()).optional(),
|
|
100
|
+
tags: z.array(AssetTagSchema).optional(),
|
|
101
|
+
breadcrumb: AssetBreadcrumbSchema.nullable().optional(),
|
|
102
|
+
file_meta_data: AssetFileMetadataSchema.nullable().optional(),
|
|
103
|
+
modified_at: TimestampSchema.nullable().optional(),
|
|
104
|
+
created_at: TimestampSchema.nullable().optional(),
|
|
105
|
+
updated_at: TimestampSchema.nullable().optional(),
|
|
106
|
+
custom_fields: z.array(z.unknown()).nullable().optional(),
|
|
107
|
+
});
|
|
108
|
+
// ── Category (Folder) ────────────────────────────────────────────────────
|
|
109
|
+
// Source: 2020_09_03_162951_create_digital_assets_categories_table.php
|
|
110
|
+
// `digital_assets_categories` doubles as the folder hierarchy via `parent_id`.
|
|
111
|
+
export const CategorySchema = z.object({
|
|
112
|
+
id: IdSchema,
|
|
113
|
+
workspace_id: IdSchema,
|
|
114
|
+
user_id: IdSchema.nullable().optional(),
|
|
115
|
+
parent_id: IdSchema.nullable().optional(),
|
|
116
|
+
folder_name: z.string().nullable().optional(),
|
|
117
|
+
category_path: z.string().nullable().optional(),
|
|
118
|
+
integration_type: z.number().int().min(0).max(3).optional(),
|
|
119
|
+
created_at: TimestampSchema.nullable().optional(),
|
|
120
|
+
updated_at: TimestampSchema.nullable().optional(),
|
|
121
|
+
});
|
|
122
|
+
// ── Collection ───────────────────────────────────────────────────────────
|
|
123
|
+
// API source of truth: GET /digital-assets/collection/get-all (verified
|
|
124
|
+
// 2026-04-27 against workspace 1927483178). The endpoint returns a derived
|
|
125
|
+
// projection — NOT the raw `dam_collections` row — so workspace_id /
|
|
126
|
+
// instance_id / timestamps are absent from the response. Treat those as
|
|
127
|
+
// optional even though the DB column is NOT NULL.
|
|
128
|
+
export const CollectionSchema = z.object({
|
|
129
|
+
id: IdSchema,
|
|
130
|
+
name: z.string(),
|
|
131
|
+
assets_id: z.array(IdSchema).optional(),
|
|
132
|
+
instance_visibility: z.array(IdSchema).optional(),
|
|
133
|
+
description: z.string().nullable().optional(),
|
|
134
|
+
workspace_id: IdSchema.optional(),
|
|
135
|
+
instance_id: IdSchema.optional(),
|
|
136
|
+
user_id: IdSchema.nullable().optional(),
|
|
137
|
+
is_backend_user: z.union([z.boolean(), z.number()]).optional(),
|
|
138
|
+
created_at: TimestampSchema.nullable().optional(),
|
|
139
|
+
updated_at: TimestampSchema.nullable().optional(),
|
|
140
|
+
});
|
|
141
|
+
// ── Custom Field ─────────────────────────────────────────────────────────
|
|
142
|
+
// API source of truth: GET /digital-assets/custom-field/list (verified
|
|
143
|
+
// against Admin-Frontend pages/_workspace_id/workspace-settings/custom-fields/index.vue).
|
|
144
|
+
// The endpoint returns `{ data: [{ id, field_label, field_type, status, ... }] }`.
|
|
145
|
+
// We keep `name` as an optional alias for backward compatibility with
|
|
146
|
+
// other call sites that synthesise it from `field_label`.
|
|
147
|
+
export const CustomFieldSchema = z.object({
|
|
148
|
+
id: IdSchema,
|
|
149
|
+
workspace_id: IdSchema.optional(),
|
|
150
|
+
name: z.string().optional(),
|
|
151
|
+
field_label: z.string().optional(),
|
|
152
|
+
field_type: z.string().optional(),
|
|
153
|
+
is_required: z.union([z.boolean(), z.number()]).optional(),
|
|
154
|
+
status: z.union([z.boolean(), z.number()]).optional(),
|
|
155
|
+
options: z.array(z.unknown()).nullable().optional(),
|
|
156
|
+
values: z.array(z.unknown()).nullable().optional(),
|
|
157
|
+
created_at: TimestampSchema.nullable().optional(),
|
|
158
|
+
updated_at: TimestampSchema.nullable().optional(),
|
|
159
|
+
}).passthrough();
|
|
160
|
+
// ── Workspace ────────────────────────────────────────────────────────────
|
|
161
|
+
// Sourced from Admin-Frontend usage (`accessibleWorkspaces[].id`).
|
|
162
|
+
export const WorkspaceSchema = z.object({
|
|
163
|
+
id: IdSchema,
|
|
164
|
+
name: z.string().optional(),
|
|
165
|
+
brand_name: z.string().optional(),
|
|
166
|
+
});
|
|
167
|
+
// ── List response shapes ─────────────────────────────────────────────────
|
|
168
|
+
// Used by the Phase-1 smoke endpoints listed in `reference_collage_api`:
|
|
169
|
+
// /digital-assets/category/all-category-list
|
|
170
|
+
// /digital-assets/collection/get-all
|
|
171
|
+
// /digital-assets/get-custom-fields
|
|
172
|
+
export const CategoryListSchema = z.array(CategorySchema);
|
|
173
|
+
export const CollectionListSchema = z.array(CollectionSchema);
|
|
174
|
+
export const CustomFieldListSchema = z.array(CustomFieldSchema);
|
|
175
|
+
// ── Folder-scoped asset listing ──────────────────────────────────────────
|
|
176
|
+
// API source of truth: GET /digital-assets/category/view-files-with-category
|
|
177
|
+
// (verified via Admin-Frontend `pages/_workspace_id/dam/folders/_id/index.vue`).
|
|
178
|
+
// The response wraps a Laravel paginator under `assets_with_folder`. Each
|
|
179
|
+
// asset row in `data` is the raw `digital_assets` row (NOT the richer
|
|
180
|
+
// `view-detail` projection) so the field set is intentionally permissive.
|
|
181
|
+
//
|
|
182
|
+
// Used by `enumerateAssets()` to paginate across every folder when the audit
|
|
183
|
+
// tool needs a flat workspace-wide list. Workspace-wide flat enumeration is
|
|
184
|
+
// otherwise Typesense-only; iterating categories is the REST fallback.
|
|
185
|
+
export const PaginatedAssetRowSchema = z.object({
|
|
186
|
+
id: IdSchema,
|
|
187
|
+
display_file_name: z.string().optional(),
|
|
188
|
+
file_name: z.string().optional(),
|
|
189
|
+
category_id: IdSchema.nullable().optional(),
|
|
190
|
+
tags: z.array(AssetTagSchema).optional(),
|
|
191
|
+
}).passthrough();
|
|
192
|
+
export const PaginatedAssetsEnvelopeSchema = z.object({
|
|
193
|
+
assets_with_folder: z.object({
|
|
194
|
+
data: z.array(PaginatedAssetRowSchema),
|
|
195
|
+
current_page: z.number().int().optional(),
|
|
196
|
+
last_page: z.number().int().optional(),
|
|
197
|
+
total: z.number().int().optional(),
|
|
198
|
+
per_page: z.union([z.number().int(), z.string()]).optional(),
|
|
199
|
+
}).passthrough(),
|
|
200
|
+
all_assets_ids: z.array(IdSchema).optional(),
|
|
201
|
+
all_folder_ids: z.array(IdSchema).optional(),
|
|
202
|
+
}).passthrough();
|
|
203
|
+
// ── Asset write response shapes ──────────────────────────────────────────
|
|
204
|
+
// `update-with-field`, `add-tags-to-multiple-file`, and
|
|
205
|
+
// `delete-tag-from-multiple-file` all return a plain envelope with a
|
|
206
|
+
// human-readable `message`. We accept any shape and pull out the message
|
|
207
|
+
// for surfacing in adapter results.
|
|
208
|
+
export const SimpleMessageEnvelopeSchema = z.object({
|
|
209
|
+
status: z.union([z.boolean(), z.number(), z.string()]).optional(),
|
|
210
|
+
message: z.string().optional(),
|
|
211
|
+
data: z.unknown().optional(),
|
|
212
|
+
}).passthrough();
|
|
213
|
+
// ── Custom-field projection ──────────────────────────────────────────────
|
|
214
|
+
// `get-custom-fields` (when sourced via `view-detail.custom_fields`) is an
|
|
215
|
+
// array of `{ id, name, field_type, value, ... }`. We keep the shape
|
|
216
|
+
// permissive and let callers project into their own value types.
|
|
217
|
+
export const AssetCustomFieldSchema = z.object({
|
|
218
|
+
id: IdSchema,
|
|
219
|
+
name: z.string().optional(),
|
|
220
|
+
field_name: z.string().optional(),
|
|
221
|
+
field_type: z.string().optional(),
|
|
222
|
+
value: z.unknown().optional(),
|
|
223
|
+
}).passthrough();
|
|
224
|
+
// ── Share Link ───────────────────────────────────────────────────────────
|
|
225
|
+
// API source of truth: GET /digital-assets/dashboard/list-share-assets-url
|
|
226
|
+
// (Admin-Frontend: pages/_workspace_id/dam/sharing/index.vue:784) and
|
|
227
|
+
// POST /digital-assets/dashboard/generate-share-assets-url
|
|
228
|
+
// (Admin-Frontend: components/dam/Dialogs/ShareAssetDialog/index.vue:399).
|
|
229
|
+
//
|
|
230
|
+
// The list endpoint returns a Laravel paginator under `data` containing rows
|
|
231
|
+
// shaped roughly like the Admin-Frontend's `shareTableListItem` consumer
|
|
232
|
+
// (`id`, `title`, `description`, `share_new_url`, `share_origin`, `created_at`,
|
|
233
|
+
// `total_visited`, `expiration`, `password`, `hide_download`, `user`, ...).
|
|
234
|
+
// We model the fields the share tool actually surfaces and let the rest pass
|
|
235
|
+
// through. The create endpoint returns `{ id, share_url, ... }`.
|
|
236
|
+
export const ShareLinkSchema = z.object({
|
|
237
|
+
id: IdSchema,
|
|
238
|
+
title: z.string().nullable().optional(),
|
|
239
|
+
description: z.string().nullable().optional(),
|
|
240
|
+
share_url: z.string().nullable().optional(),
|
|
241
|
+
share_new_url: z.string().nullable().optional(),
|
|
242
|
+
share_origin: z.string().nullable().optional(),
|
|
243
|
+
expiration: z.string().nullable().optional(),
|
|
244
|
+
password: z.string().nullable().optional(),
|
|
245
|
+
hide_download: z.union([z.boolean(), z.number(), z.string()]).nullable().optional(),
|
|
246
|
+
total_visited: z.union([z.number(), z.string()]).nullable().optional(),
|
|
247
|
+
created_at: TimestampSchema.nullable().optional(),
|
|
248
|
+
updated_at: TimestampSchema.nullable().optional(),
|
|
249
|
+
generated_source: z.string().nullable().optional(),
|
|
250
|
+
workspace_id: IdSchema.nullable().optional(),
|
|
251
|
+
user_id: IdSchema.nullable().optional(),
|
|
252
|
+
asset_ids: z.array(IdSchema).nullable().optional(),
|
|
253
|
+
}).passthrough();
|
|
254
|
+
/**
|
|
255
|
+
* Laravel paginator envelope returned by `list-share-assets-url`.
|
|
256
|
+
* Shape verified via Admin-Frontend `pages/_workspace_id/dam/sharing/index.vue:789`
|
|
257
|
+
* (uses `data.last_page`, `data.total`, `data.data`).
|
|
258
|
+
*/
|
|
259
|
+
export const ShareLinkListEnvelopeSchema = z.object({
|
|
260
|
+
data: z.array(ShareLinkSchema),
|
|
261
|
+
current_page: z.number().int().optional(),
|
|
262
|
+
last_page: z.number().int().optional(),
|
|
263
|
+
total: z.number().int().optional(),
|
|
264
|
+
per_page: z.union([z.number().int(), z.string()]).optional(),
|
|
265
|
+
}).passthrough();
|
|
266
|
+
/**
|
|
267
|
+
* Response from `generate-share-assets-url` and
|
|
268
|
+
* `collection/generate-share-url`. Verified via Admin-Frontend
|
|
269
|
+
* `components/dam/Dialogs/ShareAssetDialog/index.vue:402`
|
|
270
|
+
* (uses `data.share_url`, `data.id`, optionally `data.asset_ids`).
|
|
271
|
+
*/
|
|
272
|
+
export const GenerateShareLinkResponseSchema = z.object({
|
|
273
|
+
id: IdSchema,
|
|
274
|
+
share_url: z.string(),
|
|
275
|
+
share_new_url: z.string().nullable().optional(),
|
|
276
|
+
asset_ids: z.array(IdSchema).nullable().optional(),
|
|
277
|
+
title: z.string().nullable().optional(),
|
|
278
|
+
description: z.string().nullable().optional(),
|
|
279
|
+
expiration: z.string().nullable().optional(),
|
|
280
|
+
}).passthrough();
|
|
281
|
+
// ── Embed Code ───────────────────────────────────────────────────────────
|
|
282
|
+
// API source of truth: GET /digital-assets/{id}/generate-embed-code
|
|
283
|
+
// (Admin-Frontend: components/dam/Dialogs/ShareAssetDialog/index.vue:476).
|
|
284
|
+
// Response shape: `{ data: { embed_code: '<iframe ...>' } }`.
|
|
285
|
+
export const GenerateEmbedCodeResponseSchema = z.object({
|
|
286
|
+
embed_code: z.string(),
|
|
287
|
+
}).passthrough();
|
|
288
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { AppConfig } from './conventions/env.js';
|
|
2
|
+
import { type McpToolError } from './conventions/errors.js';
|
|
3
|
+
import type { ScopedSearchRequest } from './tools/search/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Default search parameters applied unless a caller overrides them.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_SEARCH_PARAMS: {
|
|
8
|
+
readonly per_page: 25;
|
|
9
|
+
readonly page: 1;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Opaque handle to the Nuxt-proxied search endpoint. Built once at
|
|
13
|
+
* server startup via `createCollageSearchClient(config)` and threaded
|
|
14
|
+
* through to the search tools the same way the legacy Typesense client
|
|
15
|
+
* was. Tests construct one with arbitrary `baseUrl` + `apiKey`.
|
|
16
|
+
*/
|
|
17
|
+
export interface CollageSearchClient {
|
|
18
|
+
readonly baseUrl: string;
|
|
19
|
+
readonly apiKey: string;
|
|
20
|
+
readonly workspaceId: string;
|
|
21
|
+
readonly timeoutMs: number;
|
|
22
|
+
/** Override for tests; defaults to `globalThis.fetch` when undefined. */
|
|
23
|
+
readonly fetchImpl?: typeof fetch;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Construct the search client from app config.
|
|
27
|
+
*
|
|
28
|
+
* The default base URL is `https://app.collage.inc` — the Nuxt frontend
|
|
29
|
+
* host that runs the `/typesense` middleware. Override via
|
|
30
|
+
* `COLLAGE_SEARCH_BASE` for staging/local proxies.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createCollageSearchClient(config: AppConfig): CollageSearchClient;
|
|
33
|
+
/**
|
|
34
|
+
* Shape of a raw Typesense facet count entry. Mirrors the upstream
|
|
35
|
+
* `SearchResponseFacetCountSchema` — exposed here so callers don't need to
|
|
36
|
+
* import from inside `typesense/lib/...`.
|
|
37
|
+
*/
|
|
38
|
+
export interface RawFacetCount {
|
|
39
|
+
field_name: string;
|
|
40
|
+
counts: Array<{
|
|
41
|
+
value: string;
|
|
42
|
+
count: number;
|
|
43
|
+
highlighted?: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export interface ScopedSearchSuccess<T> {
|
|
47
|
+
ok: true;
|
|
48
|
+
hits: T[];
|
|
49
|
+
found: number;
|
|
50
|
+
page: number;
|
|
51
|
+
per_page: number;
|
|
52
|
+
facet_counts: RawFacetCount[];
|
|
53
|
+
/** Raw `filter_by` string actually sent to the proxy — for debugging/tests. */
|
|
54
|
+
filter_by: string;
|
|
55
|
+
}
|
|
56
|
+
export type ScopedSearchResult<T> = ScopedSearchSuccess<T> | {
|
|
57
|
+
ok: false;
|
|
58
|
+
error: McpToolError;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Workspace-scoped search wrapper.
|
|
62
|
+
*
|
|
63
|
+
* **Workspace scoping is enforced by the proxy, not by us.** The Nuxt
|
|
64
|
+
* `/typesense/search` middleware verifies the Bearer token via Laravel's
|
|
65
|
+
* `/user` endpoint, resolves the caller's `workspace_unique_id` from the
|
|
66
|
+
* accessibleWorkspaces list, and appends `workspace_id: <unique_id>`
|
|
67
|
+
* to whatever `filterQuery` we send. Note the unique_id is the
|
|
68
|
+
* Typesense-indexed `workspace_id` (e.g. `178`), NOT the DB id
|
|
69
|
+
* (`1927483178`) we hold in env. We do not have access to the unique_id
|
|
70
|
+
* client-side, so we cannot prepend our own `workspace_id` clause —
|
|
71
|
+
* doing so would `&&` two non-matching clauses and return zero results.
|
|
72
|
+
*
|
|
73
|
+
* The caller's `filter_by` is forwarded verbatim. The proxy is the
|
|
74
|
+
* single seam at which workspace scope is enforced; this surface
|
|
75
|
+
* cannot construct a cross-workspace query because the proxy refuses
|
|
76
|
+
* any workspace the Bearer token's user is not a member of.
|
|
77
|
+
*
|
|
78
|
+
* The wrapper is generic over the document type so the search tools can
|
|
79
|
+
* narrow the projection at the call site. It returns the parsed hits, the
|
|
80
|
+
* total `found`, the page, the raw `facet_counts`, and the literal
|
|
81
|
+
* `filter_by` string actually sent (the caller's filter, unchanged).
|
|
82
|
+
*/
|
|
83
|
+
export declare function searchWorkspaceScoped<T extends Record<string, unknown>>(client: CollageSearchClient, collection: string, workspaceId: string, request: ScopedSearchRequest): Promise<ScopedSearchResult<T>>;
|
|
84
|
+
//# sourceMappingURL=typesense.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typesense.d.ts","sourceRoot":"","sources":["../src/typesense.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;CAGxB,CAAC;AAEX;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,GAChB,mBAAmB,CAarB;AAID;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B,mBAAmB,CAAC,CAAC,CAAC,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3E,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CA4GhC"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// ── Search client (Nuxt /typesense proxy) ────────────────────────────
|
|
2
|
+
// Workspace-scoped search wrapper for the `digital_assets` and
|
|
3
|
+
// `dam_collections` Typesense indices.
|
|
4
|
+
//
|
|
5
|
+
// HISTORY: The original implementation used the official `typesense`
|
|
6
|
+
// npm client to talk directly to a Typesense node. That path was not
|
|
7
|
+
// viable: Collage's Typesense node is firewalled internally, and the
|
|
8
|
+
// host we were pointed at only serves the Laravel REST API. Diagnosed
|
|
9
|
+
// 2026-05-04 (see `.mm/issues/search-assets-tls-cert-mismatch-05-01-2026.md`):
|
|
10
|
+
// search lives behind a Nuxt server middleware
|
|
11
|
+
// (`Admin-Frontend/api/typesense.js`) mounted at `/typesense` on the
|
|
12
|
+
// frontend host (`app.collage.inc`).
|
|
13
|
+
//
|
|
14
|
+
// This module now POSTs to that proxy with the existing Collage Bearer
|
|
15
|
+
// token. The middleware verifies the token via Laravel's `/user`
|
|
16
|
+
// endpoint, resolves the caller's `workspace_unique_id` server-side,
|
|
17
|
+
// and rewrites the Typesense filter to scope every query to that
|
|
18
|
+
// workspace. We still apply our own `workspace_id:=…` clause as a
|
|
19
|
+
// defence-in-depth measure — the wrapper is the single seam at which
|
|
20
|
+
// the workspace scope is enforced.
|
|
21
|
+
import { createToolError } from './conventions/errors.js';
|
|
22
|
+
/**
|
|
23
|
+
* Default search parameters applied unless a caller overrides them.
|
|
24
|
+
*/
|
|
25
|
+
export const DEFAULT_SEARCH_PARAMS = {
|
|
26
|
+
per_page: 25,
|
|
27
|
+
page: 1,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Construct the search client from app config.
|
|
31
|
+
*
|
|
32
|
+
* The default base URL is `https://app.collage.inc` — the Nuxt frontend
|
|
33
|
+
* host that runs the `/typesense` middleware. Override via
|
|
34
|
+
* `COLLAGE_SEARCH_BASE` for staging/local proxies.
|
|
35
|
+
*/
|
|
36
|
+
export function createCollageSearchClient(config) {
|
|
37
|
+
const baseUrl = (process.env['COLLAGE_SEARCH_BASE'] ?? 'https://app.collage.inc').replace(/\/+$/, '');
|
|
38
|
+
const timeoutMs = Number(process.env['COLLAGE_SEARCH_TIMEOUT_MS']) || 15_000;
|
|
39
|
+
return {
|
|
40
|
+
baseUrl,
|
|
41
|
+
apiKey: config.collageApiKey,
|
|
42
|
+
workspaceId: config.collageWorkspaceId,
|
|
43
|
+
timeoutMs,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Workspace-scoped search wrapper.
|
|
48
|
+
*
|
|
49
|
+
* **Workspace scoping is enforced by the proxy, not by us.** The Nuxt
|
|
50
|
+
* `/typesense/search` middleware verifies the Bearer token via Laravel's
|
|
51
|
+
* `/user` endpoint, resolves the caller's `workspace_unique_id` from the
|
|
52
|
+
* accessibleWorkspaces list, and appends `workspace_id: <unique_id>`
|
|
53
|
+
* to whatever `filterQuery` we send. Note the unique_id is the
|
|
54
|
+
* Typesense-indexed `workspace_id` (e.g. `178`), NOT the DB id
|
|
55
|
+
* (`1927483178`) we hold in env. We do not have access to the unique_id
|
|
56
|
+
* client-side, so we cannot prepend our own `workspace_id` clause —
|
|
57
|
+
* doing so would `&&` two non-matching clauses and return zero results.
|
|
58
|
+
*
|
|
59
|
+
* The caller's `filter_by` is forwarded verbatim. The proxy is the
|
|
60
|
+
* single seam at which workspace scope is enforced; this surface
|
|
61
|
+
* cannot construct a cross-workspace query because the proxy refuses
|
|
62
|
+
* any workspace the Bearer token's user is not a member of.
|
|
63
|
+
*
|
|
64
|
+
* The wrapper is generic over the document type so the search tools can
|
|
65
|
+
* narrow the projection at the call site. It returns the parsed hits, the
|
|
66
|
+
* total `found`, the page, the raw `facet_counts`, and the literal
|
|
67
|
+
* `filter_by` string actually sent (the caller's filter, unchanged).
|
|
68
|
+
*/
|
|
69
|
+
export async function searchWorkspaceScoped(client, collection, workspaceId, request) {
|
|
70
|
+
const filterBy = (request.filter_by ?? '').trim();
|
|
71
|
+
const innerRequest = {
|
|
72
|
+
q: request.q,
|
|
73
|
+
collections: [collection],
|
|
74
|
+
};
|
|
75
|
+
if (request.facet_by !== undefined && request.facet_by.length > 0) {
|
|
76
|
+
innerRequest['facet_by'] = request.facet_by;
|
|
77
|
+
}
|
|
78
|
+
if (request.max_facet_values !== undefined) {
|
|
79
|
+
innerRequest['max_facet_values'] = request.max_facet_values;
|
|
80
|
+
}
|
|
81
|
+
if (request.infix !== undefined)
|
|
82
|
+
innerRequest['infix'] = request.infix;
|
|
83
|
+
if (request.prefix !== undefined)
|
|
84
|
+
innerRequest['prefix'] = request.prefix;
|
|
85
|
+
if (request.num_typos !== undefined) {
|
|
86
|
+
innerRequest['num_typos'] = request.num_typos;
|
|
87
|
+
}
|
|
88
|
+
if (request.typo_tokens_threshold !== undefined) {
|
|
89
|
+
innerRequest['typo_tokens_threshold'] = request.typo_tokens_threshold;
|
|
90
|
+
}
|
|
91
|
+
if (request.include_fields !== undefined) {
|
|
92
|
+
innerRequest['include_fields'] = { [collection]: request.include_fields };
|
|
93
|
+
}
|
|
94
|
+
if (request.sort_by !== undefined && request.sort_by.length > 0) {
|
|
95
|
+
innerRequest['sort_by'] = request.sort_by;
|
|
96
|
+
}
|
|
97
|
+
const body = {
|
|
98
|
+
request: innerRequest,
|
|
99
|
+
commonSearchParams: {
|
|
100
|
+
query_by: request.query_by,
|
|
101
|
+
per_page: request.per_page,
|
|
102
|
+
page: request.page,
|
|
103
|
+
},
|
|
104
|
+
workspace_id: Number(workspaceId),
|
|
105
|
+
filterQuery: { [collection]: filterBy },
|
|
106
|
+
};
|
|
107
|
+
try {
|
|
108
|
+
const response = await postJson(client, '/typesense/search', body);
|
|
109
|
+
if (!response.ok)
|
|
110
|
+
return response;
|
|
111
|
+
const collectionResult = response.data[collection];
|
|
112
|
+
if (collectionResult === undefined || collectionResult === null) {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
error: createToolError('UPSTREAM', `Search proxy response missing collection "${collection}"`),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const wrapped = collectionResult;
|
|
119
|
+
const inner = wrapped.data;
|
|
120
|
+
if (inner === undefined) {
|
|
121
|
+
return {
|
|
122
|
+
ok: false,
|
|
123
|
+
error: createToolError('UPSTREAM', `Search proxy response missing "data" for collection "${collection}"`),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const hits = (inner.hits ?? [])
|
|
127
|
+
.map((hit) => hit.document)
|
|
128
|
+
.filter((doc) => doc !== null && typeof doc === 'object');
|
|
129
|
+
const facetCounts = (inner.facet_counts ?? []).map((fc) => ({
|
|
130
|
+
field_name: String(fc.field_name ?? ''),
|
|
131
|
+
counts: (fc.counts ?? []).map((c) => ({
|
|
132
|
+
value: String(c.value ?? ''),
|
|
133
|
+
count: c.count ?? 0,
|
|
134
|
+
...(c.highlighted !== undefined ? { highlighted: c.highlighted } : {}),
|
|
135
|
+
})),
|
|
136
|
+
}));
|
|
137
|
+
return {
|
|
138
|
+
ok: true,
|
|
139
|
+
hits,
|
|
140
|
+
found: inner.found ?? 0,
|
|
141
|
+
page: inner.page ?? request.page,
|
|
142
|
+
per_page: request.per_page,
|
|
143
|
+
facet_counts: facetCounts,
|
|
144
|
+
filter_by: filterBy,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return { ok: false, error: mapSearchError(err) };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function postJson(client, path, body) {
|
|
152
|
+
const fetchFn = client.fetchImpl ?? globalThis.fetch;
|
|
153
|
+
const url = `${client.baseUrl}${path}`;
|
|
154
|
+
const controller = new AbortController();
|
|
155
|
+
const timer = setTimeout(() => controller.abort(), client.timeoutMs);
|
|
156
|
+
try {
|
|
157
|
+
const res = await fetchFn(url, {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: {
|
|
160
|
+
'Content-Type': 'application/json',
|
|
161
|
+
Authorization: `Bearer ${client.apiKey}`,
|
|
162
|
+
},
|
|
163
|
+
body: JSON.stringify(body),
|
|
164
|
+
signal: controller.signal,
|
|
165
|
+
});
|
|
166
|
+
const text = await res.text();
|
|
167
|
+
let parsed = undefined;
|
|
168
|
+
try {
|
|
169
|
+
parsed = text.length > 0 ? JSON.parse(text) : undefined;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
parsed = text;
|
|
173
|
+
}
|
|
174
|
+
if (!res.ok) {
|
|
175
|
+
return { ok: false, error: mapHttpError(res.status, parsed, sanitizeProxyBody(text)) };
|
|
176
|
+
}
|
|
177
|
+
return { ok: true, data: parsed };
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
clearTimeout(timer);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function mapHttpError(status, parsed, fallback) {
|
|
184
|
+
const message = extractErrorMessage(parsed) ?? fallback ?? `HTTP ${status}`;
|
|
185
|
+
if (status === 401 || status === 403) {
|
|
186
|
+
return createToolError('UNAUTHORIZED', message, {
|
|
187
|
+
cause: { upstream_status: status },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (status === 404) {
|
|
191
|
+
return createToolError('NOT_FOUND', message, {
|
|
192
|
+
cause: { upstream_status: status },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (status === 400 || status === 422) {
|
|
196
|
+
return createToolError('VALIDATION', message, {
|
|
197
|
+
cause: { upstream_status: status },
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (status === 429) {
|
|
201
|
+
return createToolError('RATE_LIMITED', message, {
|
|
202
|
+
cause: { upstream_status: status },
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return createToolError('UPSTREAM', message, {
|
|
206
|
+
cause: { upstream_status: status },
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function extractErrorMessage(parsed) {
|
|
210
|
+
if (parsed === null || typeof parsed !== 'object')
|
|
211
|
+
return null;
|
|
212
|
+
const obj = parsed;
|
|
213
|
+
if (typeof obj['error'] === 'string')
|
|
214
|
+
return obj['error'];
|
|
215
|
+
if (typeof obj['message'] === 'string')
|
|
216
|
+
return obj['message'];
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
function mapSearchError(err) {
|
|
220
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
221
|
+
return createToolError('UPSTREAM', 'Search request timed out');
|
|
222
|
+
}
|
|
223
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
224
|
+
return createToolError('UPSTREAM', sanitizeProxyBody(message));
|
|
225
|
+
}
|
|
226
|
+
const PROXY_BODY_MAX_CHARS = 512;
|
|
227
|
+
/**
|
|
228
|
+
* Mirror of the REST-client sanitiser; applied to proxy responses before
|
|
229
|
+
* they reach `McpToolError.message`. See `client.ts` for rationale.
|
|
230
|
+
*/
|
|
231
|
+
function sanitizeProxyBody(text) {
|
|
232
|
+
if (text === '')
|
|
233
|
+
return text;
|
|
234
|
+
const scrubbed = text
|
|
235
|
+
.replace(/Bearer\s+[A-Za-z0-9._-]+/gi, 'Bearer [REDACTED]')
|
|
236
|
+
.replace(/eyJ[A-Za-z0-9._-]{20,}/g, '[REDACTED_JWT]')
|
|
237
|
+
.replace(/(api[_-]?key|token|secret)\s*[:=]\s*"?[A-Za-z0-9._-]{8,}"?/gi, '$1=[REDACTED]')
|
|
238
|
+
.replace(/X-Amz-Signature=[^&\s"'<>]+/gi, 'X-Amz-Signature=[REDACTED]');
|
|
239
|
+
return scrubbed.length > PROXY_BODY_MAX_CHARS
|
|
240
|
+
? `${scrubbed.slice(0, PROXY_BODY_MAX_CHARS)}…`
|
|
241
|
+
: scrubbed;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=typesense.js.map
|