@memberjunction/core-entities 5.34.0 → 5.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engines/artifact-content-storage.d.ts +40 -0
- package/dist/engines/artifact-content-storage.d.ts.map +1 -0
- package/dist/engines/artifact-content-storage.js +65 -0
- package/dist/engines/artifact-content-storage.js.map +1 -0
- package/dist/engines/artifact-mime-resolver.d.ts +45 -0
- package/dist/engines/artifact-mime-resolver.d.ts.map +1 -0
- package/dist/engines/artifact-mime-resolver.js +113 -0
- package/dist/engines/artifact-mime-resolver.js.map +1 -0
- package/dist/engines/artifacts.d.ts +14 -4
- package/dist/engines/artifacts.d.ts.map +1 -1
- package/dist/engines/artifacts.js +33 -9
- package/dist/engines/artifacts.js.map +1 -1
- package/dist/generated/entity_subclasses.d.ts +127 -38
- package/dist/generated/entity_subclasses.d.ts.map +1 -1
- package/dist/generated/entity_subclasses.js +199 -58
- package/dist/generated/entity_subclasses.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for how artifact content is stored and unwrapped across the
|
|
3
|
+
* upload, gather, and resolver paths. Living in MJCoreEntities so both the
|
|
4
|
+
* server-side entity hook (MJConversationDetailAttachmentEntityServer) and
|
|
5
|
+
* the agent runtime (AgentRunner.gatherConversationArtifacts) share a single
|
|
6
|
+
* source of truth — and so they're unit-testable without mounting either
|
|
7
|
+
* the entity stack or the agent runtime.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Returns true when bytes for this MIME should be stored as raw UTF-8 text
|
|
11
|
+
* (so artifact tool libraries can JSON.parse / split-by-line directly).
|
|
12
|
+
* Returns false for binary types whose tools work with the data-URL wrapper
|
|
13
|
+
* or a FileID reference.
|
|
14
|
+
*/
|
|
15
|
+
export declare function IsTextyMime(mime: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Decides how to store inline content on the paired ArtifactVersion for a
|
|
18
|
+
* given MIME + base64 InlineData input. Text-y MIMEs get decoded to UTF-8
|
|
19
|
+
* so artifact tool libraries can parse directly; binary MIMEs keep the
|
|
20
|
+
* `data:<mime>;base64,…` wrapper so the resolver can recognize media for
|
|
21
|
+
* inline routing and the gather path can re-decode to a Buffer for binary
|
|
22
|
+
* tool libraries (xlsx, docx, pdf).
|
|
23
|
+
*/
|
|
24
|
+
export declare function DecideInlineStorage(mime: string, inlineData: string | null | undefined): {
|
|
25
|
+
contentMode: 'Text';
|
|
26
|
+
content: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Builds the user-facing error string returned when an attachment's MIME
|
|
30
|
+
* isn't registered with any ArtifactType.
|
|
31
|
+
*/
|
|
32
|
+
export declare function BuildUnregisteredMimeError(fileName: string | null | undefined, _mime: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Decodes a `data:<mime>;base64,<payload>` URL into a raw Buffer when the
|
|
35
|
+
* input matches that shape. Returns the input unchanged otherwise. Used by
|
|
36
|
+
* the AgentRunner gather path so binary tool libraries (xlsx, docx, pdf)
|
|
37
|
+
* receive a parseable Buffer instead of the wrapped data URL string.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ExtractBase64FromDataUrl(input: string): string | Buffer;
|
|
40
|
+
//# sourceMappingURL=artifact-content-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-content-storage.d.ts","sourceRoot":"","sources":["../../src/engines/artifact-content-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG;IACtF,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,CAMA;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIvE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for how artifact content is stored and unwrapped across the
|
|
3
|
+
* upload, gather, and resolver paths. Living in MJCoreEntities so both the
|
|
4
|
+
* server-side entity hook (MJConversationDetailAttachmentEntityServer) and
|
|
5
|
+
* the agent runtime (AgentRunner.gatherConversationArtifacts) share a single
|
|
6
|
+
* source of truth — and so they're unit-testable without mounting either
|
|
7
|
+
* the entity stack or the agent runtime.
|
|
8
|
+
*/
|
|
9
|
+
const TEXTY_NON_TEXT_PREFIXED_MIMES = new Set([
|
|
10
|
+
'application/json',
|
|
11
|
+
'application/xml',
|
|
12
|
+
'application/javascript',
|
|
13
|
+
'application/typescript',
|
|
14
|
+
'application/sql',
|
|
15
|
+
'application/csv',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Returns true when bytes for this MIME should be stored as raw UTF-8 text
|
|
19
|
+
* (so artifact tool libraries can JSON.parse / split-by-line directly).
|
|
20
|
+
* Returns false for binary types whose tools work with the data-URL wrapper
|
|
21
|
+
* or a FileID reference.
|
|
22
|
+
*/
|
|
23
|
+
export function IsTextyMime(mime) {
|
|
24
|
+
const lower = mime.toLowerCase();
|
|
25
|
+
if (lower.startsWith('text/'))
|
|
26
|
+
return true;
|
|
27
|
+
return TEXTY_NON_TEXT_PREFIXED_MIMES.has(lower);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Decides how to store inline content on the paired ArtifactVersion for a
|
|
31
|
+
* given MIME + base64 InlineData input. Text-y MIMEs get decoded to UTF-8
|
|
32
|
+
* so artifact tool libraries can parse directly; binary MIMEs keep the
|
|
33
|
+
* `data:<mime>;base64,…` wrapper so the resolver can recognize media for
|
|
34
|
+
* inline routing and the gather path can re-decode to a Buffer for binary
|
|
35
|
+
* tool libraries (xlsx, docx, pdf).
|
|
36
|
+
*/
|
|
37
|
+
export function DecideInlineStorage(mime, inlineData) {
|
|
38
|
+
if (!inlineData)
|
|
39
|
+
return { contentMode: 'Text', content: '' };
|
|
40
|
+
if (IsTextyMime(mime)) {
|
|
41
|
+
return { contentMode: 'Text', content: Buffer.from(inlineData, 'base64').toString('utf-8') };
|
|
42
|
+
}
|
|
43
|
+
return { contentMode: 'Text', content: `data:${mime};base64,${inlineData}` };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Builds the user-facing error string returned when an attachment's MIME
|
|
47
|
+
* isn't registered with any ArtifactType.
|
|
48
|
+
*/
|
|
49
|
+
export function BuildUnregisteredMimeError(fileName, _mime) {
|
|
50
|
+
const safeName = fileName ?? 'this file';
|
|
51
|
+
return `"${safeName}" can't be attached — its file type isn't supported here. Try a PDF, Word, Excel, image, audio, video, JSON, CSV, XML, or plain-text file.`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Decodes a `data:<mime>;base64,<payload>` URL into a raw Buffer when the
|
|
55
|
+
* input matches that shape. Returns the input unchanged otherwise. Used by
|
|
56
|
+
* the AgentRunner gather path so binary tool libraries (xlsx, docx, pdf)
|
|
57
|
+
* receive a parseable Buffer instead of the wrapped data URL string.
|
|
58
|
+
*/
|
|
59
|
+
export function ExtractBase64FromDataUrl(input) {
|
|
60
|
+
const match = /^data:[^;]+;base64,(.*)$/s.exec(input);
|
|
61
|
+
if (!match)
|
|
62
|
+
return input;
|
|
63
|
+
return Buffer.from(match[1], 'base64');
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=artifact-content-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-content-storage.js","sourceRoot":"","sources":["../../src/engines/artifact-content-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAC;IAC1C,kBAAkB;IAClB,iBAAiB;IACjB,wBAAwB;IACxB,wBAAwB;IACxB,iBAAiB;IACjB,iBAAiB;CACpB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,UAAqC;IAInF,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC7D,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;IACjG,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,IAAI,WAAW,UAAU,EAAE,EAAE,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAmC,EAAE,KAAa;IACzF,MAAM,QAAQ,GAAG,QAAQ,IAAI,WAAW,CAAC;IACzC,OAAO,IAAI,QAAQ,4IAA4I,CAAC;AACpK,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAa;IAClD,MAAM,KAAK,GAAG,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure resolver for matching an upload's MIME type (and optional file
|
|
3
|
+
* extension) to a registered Artifact Type. Has no entity dependency — takes
|
|
4
|
+
* a list of plain matcher records, returns the chosen ID (or undefined when
|
|
5
|
+
* nothing matches).
|
|
6
|
+
*
|
|
7
|
+
* Resolution algorithm (per plans/artifact-attachment-unification.md §6):
|
|
8
|
+
* 1. Filter to types whose ContentType pattern matches the upload MIME.
|
|
9
|
+
* 2. Bucket by specificity: exact > subtype-wildcard (e.g. `image/*`).
|
|
10
|
+
* 3. Within the highest-specificity bucket, sort by Priority desc.
|
|
11
|
+
* 4. Tiebreaker if priorities are equal:
|
|
12
|
+
* a. SystemSupplied = false beats SystemSupplied = true
|
|
13
|
+
* b. otherwise lowest ID wins (deterministic).
|
|
14
|
+
*
|
|
15
|
+
* Octet-stream uploads also consider a file-extension hint when given.
|
|
16
|
+
*
|
|
17
|
+
* Conflict detection: callers can pass the same list to
|
|
18
|
+
* `FindArtifactTypeConflicts` to surface ambiguous registrations at engine
|
|
19
|
+
* boot, where two types share the same (ContentType, Priority, SystemSupplied)
|
|
20
|
+
* triple — almost always a configuration mistake.
|
|
21
|
+
*/
|
|
22
|
+
export interface ArtifactTypeMatcher {
|
|
23
|
+
/** Stable identifier (UUID) — used as the final tiebreaker. */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Display name — for logging only. */
|
|
26
|
+
name: string;
|
|
27
|
+
/** MIME pattern: either an exact MIME or a subtype wildcard like `text/*`. */
|
|
28
|
+
contentType: string;
|
|
29
|
+
/** Higher wins within a specificity tier. */
|
|
30
|
+
priority: number;
|
|
31
|
+
/** System-shipped defaults rank below organization customizations at equal priority. */
|
|
32
|
+
systemSupplied: boolean;
|
|
33
|
+
/** Optional list of file extensions (no leading dot) that map to this type. */
|
|
34
|
+
fileExtensions?: string[];
|
|
35
|
+
}
|
|
36
|
+
export type ArtifactTypeConflict = {
|
|
37
|
+
contentType: string;
|
|
38
|
+
priority: number;
|
|
39
|
+
systemSupplied: boolean;
|
|
40
|
+
matcherIds: string[];
|
|
41
|
+
matcherNames: string[];
|
|
42
|
+
};
|
|
43
|
+
export declare function ResolveArtifactTypeByMime(matchers: ReadonlyArray<ArtifactTypeMatcher>, mimeType: string | null | undefined, fileExtension?: string | null): ArtifactTypeMatcher | undefined;
|
|
44
|
+
export declare function FindArtifactTypeConflicts(matchers: ReadonlyArray<ArtifactTypeMatcher>): ArtifactTypeConflict[];
|
|
45
|
+
//# sourceMappingURL=artifact-mime-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-mime-resolver.d.ts","sourceRoot":"","sources":["../../src/engines/artifact-mime-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,mBAAmB;IAChC,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,cAAc,EAAE,OAAO,CAAC;IACxB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,oBAAoB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAIF,wBAAgB,yBAAyB,CACrC,QAAQ,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAC5C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,mBAAmB,GAAG,SAAS,CASjC;AAED,wBAAgB,yBAAyB,CACrC,QAAQ,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAC7C,oBAAoB,EAAE,CAqBxB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure resolver for matching an upload's MIME type (and optional file
|
|
3
|
+
* extension) to a registered Artifact Type. Has no entity dependency — takes
|
|
4
|
+
* a list of plain matcher records, returns the chosen ID (or undefined when
|
|
5
|
+
* nothing matches).
|
|
6
|
+
*
|
|
7
|
+
* Resolution algorithm (per plans/artifact-attachment-unification.md §6):
|
|
8
|
+
* 1. Filter to types whose ContentType pattern matches the upload MIME.
|
|
9
|
+
* 2. Bucket by specificity: exact > subtype-wildcard (e.g. `image/*`).
|
|
10
|
+
* 3. Within the highest-specificity bucket, sort by Priority desc.
|
|
11
|
+
* 4. Tiebreaker if priorities are equal:
|
|
12
|
+
* a. SystemSupplied = false beats SystemSupplied = true
|
|
13
|
+
* b. otherwise lowest ID wins (deterministic).
|
|
14
|
+
*
|
|
15
|
+
* Octet-stream uploads also consider a file-extension hint when given.
|
|
16
|
+
*
|
|
17
|
+
* Conflict detection: callers can pass the same list to
|
|
18
|
+
* `FindArtifactTypeConflicts` to surface ambiguous registrations at engine
|
|
19
|
+
* boot, where two types share the same (ContentType, Priority, SystemSupplied)
|
|
20
|
+
* triple — almost always a configuration mistake.
|
|
21
|
+
*/
|
|
22
|
+
const SUBTYPE_WILDCARD_SUFFIX = '/*';
|
|
23
|
+
export function ResolveArtifactTypeByMime(matchers, mimeType, fileExtension) {
|
|
24
|
+
const normalizedMime = normalizeMime(mimeType);
|
|
25
|
+
if (!normalizedMime)
|
|
26
|
+
return undefined;
|
|
27
|
+
const candidates = collectCandidates(matchers, normalizedMime, fileExtension);
|
|
28
|
+
if (candidates.length === 0)
|
|
29
|
+
return undefined;
|
|
30
|
+
const ranked = rankCandidates(candidates);
|
|
31
|
+
return ranked[0]?.matcher;
|
|
32
|
+
}
|
|
33
|
+
export function FindArtifactTypeConflicts(matchers) {
|
|
34
|
+
const groups = new Map();
|
|
35
|
+
for (const m of matchers) {
|
|
36
|
+
const key = `${normalizeMime(m.contentType) ?? ''}|${m.priority}|${m.systemSupplied}`;
|
|
37
|
+
const list = groups.get(key) ?? [];
|
|
38
|
+
list.push(m);
|
|
39
|
+
groups.set(key, list);
|
|
40
|
+
}
|
|
41
|
+
const conflicts = [];
|
|
42
|
+
for (const list of groups.values()) {
|
|
43
|
+
if (list.length < 2)
|
|
44
|
+
continue;
|
|
45
|
+
conflicts.push({
|
|
46
|
+
contentType: list[0].contentType,
|
|
47
|
+
priority: list[0].priority,
|
|
48
|
+
systemSupplied: list[0].systemSupplied,
|
|
49
|
+
matcherIds: list.map(m => m.id),
|
|
50
|
+
matcherNames: list.map(m => m.name),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return conflicts;
|
|
54
|
+
}
|
|
55
|
+
function collectCandidates(matchers, mime, fileExtension) {
|
|
56
|
+
const out = [];
|
|
57
|
+
const ext = normalizeExtension(fileExtension);
|
|
58
|
+
const isOctetStream = mime === 'application/octet-stream';
|
|
59
|
+
for (const m of matchers) {
|
|
60
|
+
const pattern = normalizeMime(m.contentType);
|
|
61
|
+
if (!pattern)
|
|
62
|
+
continue;
|
|
63
|
+
if (pattern === mime) {
|
|
64
|
+
out.push({ matcher: m, specificity: 2 });
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (pattern.endsWith(SUBTYPE_WILDCARD_SUFFIX)) {
|
|
68
|
+
const prefix = pattern.slice(0, -SUBTYPE_WILDCARD_SUFFIX.length);
|
|
69
|
+
if (mime.startsWith(prefix + '/')) {
|
|
70
|
+
out.push({ matcher: m, specificity: 1 });
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// octet-stream extension hint: if the upload has no useful MIME but we
|
|
75
|
+
// have an extension hint, allow types that registered the extension.
|
|
76
|
+
if (isOctetStream && ext && m.fileExtensions?.includes(ext)) {
|
|
77
|
+
out.push({ matcher: m, specificity: 2 });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
function rankCandidates(candidates) {
|
|
83
|
+
// Highest specificity first, then Priority desc, then SystemSupplied false
|
|
84
|
+
// wins over true, then lowest ID for determinism.
|
|
85
|
+
const maxSpecificity = Math.max(...candidates.map(c => c.specificity));
|
|
86
|
+
const topBucket = candidates.filter(c => c.specificity === maxSpecificity);
|
|
87
|
+
return [...topBucket].sort((a, b) => {
|
|
88
|
+
if (b.matcher.priority !== a.matcher.priority) {
|
|
89
|
+
return b.matcher.priority - a.matcher.priority;
|
|
90
|
+
}
|
|
91
|
+
if (a.matcher.systemSupplied !== b.matcher.systemSupplied) {
|
|
92
|
+
return a.matcher.systemSupplied ? 1 : -1;
|
|
93
|
+
}
|
|
94
|
+
return a.matcher.id.localeCompare(b.matcher.id);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function normalizeMime(value) {
|
|
98
|
+
if (!value)
|
|
99
|
+
return undefined;
|
|
100
|
+
const trimmed = value.trim().toLowerCase();
|
|
101
|
+
if (!trimmed)
|
|
102
|
+
return undefined;
|
|
103
|
+
// Strip any `; charset=...` parameters that browsers sometimes attach.
|
|
104
|
+
const semi = trimmed.indexOf(';');
|
|
105
|
+
return semi === -1 ? trimmed : trimmed.slice(0, semi).trim();
|
|
106
|
+
}
|
|
107
|
+
function normalizeExtension(value) {
|
|
108
|
+
if (!value)
|
|
109
|
+
return undefined;
|
|
110
|
+
const trimmed = value.trim().toLowerCase().replace(/^\./, '');
|
|
111
|
+
return trimmed || undefined;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=artifact-mime-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-mime-resolver.js","sourceRoot":"","sources":["../../src/engines/artifact-mime-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,10 +35,20 @@ export declare class ArtifactMetadataEngine extends BaseEngine<ArtifactMetadataE
|
|
|
35
35
|
*/
|
|
36
36
|
IsFileArtifact(version: MJArtifactVersionEntity): boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Resolves an upload's MIME type (and optional file extension) to the
|
|
39
|
+
* highest-priority registered Artifact Type. Supports exact matches and
|
|
40
|
+
* subtype wildcards (e.g. `text/*`, `image/*`), with deterministic
|
|
41
|
+
* tiebreaking via Priority → SystemSupplied → ID. See
|
|
42
|
+
* `artifact-mime-resolver.ts` for the full algorithm.
|
|
41
43
|
*/
|
|
42
|
-
GetArtifactTypeByMimeType(mimeType: string): MJArtifactTypeEntity | undefined;
|
|
44
|
+
GetArtifactTypeByMimeType(mimeType: string, fileExtension?: string): MJArtifactTypeEntity | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Logs WARN for any pair of registered Artifact Types that share an
|
|
47
|
+
* identical (ContentType, Priority, SystemSupplied) triple — almost always
|
|
48
|
+
* a configuration mistake, and the ID-tiebreaker would otherwise hide it.
|
|
49
|
+
* Call after Config() to surface registry ambiguity at boot.
|
|
50
|
+
*/
|
|
51
|
+
LogArtifactTypeRegistryConflicts(): void;
|
|
52
|
+
private toMatcher;
|
|
43
53
|
}
|
|
44
54
|
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/engines/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/engines/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAa,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EAC1B,MAAM,gCAAgC,CAAC;AAOxC;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,UAAU,CAAC,sBAAsB,CAAC;IAC1E;;OAEG;IACH,WAAkB,QAAQ,IAAI,sBAAsB,CAEnD;IAED,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,iBAAiB,CAAiC;IAE7C,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB;IAwBhG,IAAW,aAAa,IAAI,oBAAoB,EAAE,CAEjD;IAED,kCAAkC;IAClC,IAAW,SAAS,IAAI,gBAAgB,EAAE,CAEzC;IAED,0CAA0C;IAC1C,IAAW,gBAAgB,IAAI,uBAAuB,EAAE,CAEvD;IAED;;OAEG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAOvE,iCAAiC;IAC1B,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAMjE,yCAAyC;IAClC,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAM/E,gFAAgF;IACzE,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,uBAAuB,EAAE;IAQ5E,sCAAsC;IAC/B,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAMzE;;;OAGG;IACI,cAAc,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO;IAIhE;;;;;;OAMG;IACI,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAM5G;;;;;OAKG;IACI,gCAAgC,IAAI,IAAI;IAU/C,OAAO,CAAC,SAAS;CASpB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { BaseEngine } from "@memberjunction/core";
|
|
1
|
+
import { BaseEngine, LogStatus } from "@memberjunction/core";
|
|
2
|
+
import { ResolveArtifactTypeByMime, FindArtifactTypeConflicts, } from "./artifact-mime-resolver.js";
|
|
2
3
|
/**
|
|
3
4
|
* Caching of metadata for artifacts, artifact versions, and artifact types.
|
|
4
5
|
*/
|
|
@@ -96,15 +97,38 @@ export class ArtifactMetadataEngine extends BaseEngine {
|
|
|
96
97
|
return version?.ContentMode === 'File';
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
100
|
+
* Resolves an upload's MIME type (and optional file extension) to the
|
|
101
|
+
* highest-priority registered Artifact Type. Supports exact matches and
|
|
102
|
+
* subtype wildcards (e.g. `text/*`, `image/*`), with deterministic
|
|
103
|
+
* tiebreaking via Priority → SystemSupplied → ID. See
|
|
104
|
+
* `artifact-mime-resolver.ts` for the full algorithm.
|
|
102
105
|
*/
|
|
103
|
-
GetArtifactTypeByMimeType(mimeType) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
GetArtifactTypeByMimeType(mimeType, fileExtension) {
|
|
107
|
+
const matchers = this._artifactTypes.map(t => this.toMatcher(t));
|
|
108
|
+
const found = ResolveArtifactTypeByMime(matchers, mimeType, fileExtension);
|
|
109
|
+
return found ? this.FindArtifactTypeByID(found.id) : undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Logs WARN for any pair of registered Artifact Types that share an
|
|
113
|
+
* identical (ContentType, Priority, SystemSupplied) triple — almost always
|
|
114
|
+
* a configuration mistake, and the ID-tiebreaker would otherwise hide it.
|
|
115
|
+
* Call after Config() to surface registry ambiguity at boot.
|
|
116
|
+
*/
|
|
117
|
+
LogArtifactTypeRegistryConflicts() {
|
|
118
|
+
const matchers = this._artifactTypes.map(t => this.toMatcher(t));
|
|
119
|
+
const conflicts = FindArtifactTypeConflicts(matchers);
|
|
120
|
+
for (const c of conflicts) {
|
|
121
|
+
LogStatus(`WARN ArtifactMetadataEngine: ${c.matcherNames.length} Artifact Types share (ContentType=${c.contentType}, Priority=${c.priority}, SystemSupplied=${c.systemSupplied}): ${c.matcherNames.join(', ')}. Resolution will use lowest-ID tiebreaker — set Priority explicitly to disambiguate.`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
toMatcher(t) {
|
|
125
|
+
return {
|
|
126
|
+
id: t.ID,
|
|
127
|
+
name: t.Name,
|
|
128
|
+
contentType: t.ContentType,
|
|
129
|
+
priority: t.Priority,
|
|
130
|
+
systemSupplied: t.SystemSupplied,
|
|
131
|
+
};
|
|
108
132
|
}
|
|
109
133
|
}
|
|
110
134
|
//# sourceMappingURL=artifacts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/engines/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/engines/artifacts.ts"],"names":[],"mappings":"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"}
|