@memberjunction/core-entities 2.104.0 → 2.106.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.
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @fileoverview TypeScript types for artifact extract rules system.
3
+ *
4
+ * This module defines the structure for extract rules that enable artifact types
5
+ * to declaratively specify how to extract attributes from artifact content.
6
+ * Extract rules support hierarchical inheritance through parent artifact types.
7
+ *
8
+ * @module @memberjunction/core-entities
9
+ * @since 2.105.0
10
+ */
11
+ /**
12
+ * Standard properties that extracted attributes can map to for UI rendering.
13
+ * These provide semantic meaning to extracted values beyond custom attributes.
14
+ */
15
+ export type ArtifactStandardProperty = 'name' | 'description' | 'displayMarkdown' | 'displayHtml';
16
+ /**
17
+ * Definition of a single extraction rule that defines how to extract an attribute
18
+ * from artifact content.
19
+ *
20
+ * Extract rules are stored as JSON in the ArtifactType.ExtractRules column and
21
+ * support hierarchical inheritance where child types can override parent rules.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const emailSubjectRule: ArtifactExtractRule = {
26
+ * name: 'subject',
27
+ * description: 'Email subject line',
28
+ * type: 'string',
29
+ * standardProperty: 'name',
30
+ * extractor: `
31
+ * // content is the artifact content (JSON, text, etc.)
32
+ * const parsed = JSON.parse(content);
33
+ * return parsed.subject;
34
+ * `
35
+ * };
36
+ * ```
37
+ */
38
+ export interface ArtifactExtractRule {
39
+ /**
40
+ * Unique name for this extraction rule within the artifact type hierarchy.
41
+ * Used as the key for overriding parent rules and for storing extracted values.
42
+ */
43
+ name: string;
44
+ /**
45
+ * Human-readable description of what this rule extracts.
46
+ */
47
+ description: string;
48
+ /**
49
+ * TypeScript type definition for the extracted value.
50
+ *
51
+ * Can be:
52
+ * - Primitive types: 'string', 'number', 'boolean', 'Date'
53
+ * - Complex types: 'Array<string>', 'Record<string, any>'
54
+ * - Custom interfaces: 'Array<{x: number, y: string}>'
55
+ *
56
+ * @example 'string'
57
+ * @example 'number'
58
+ * @example 'Array<{id: string, name: string}>'
59
+ */
60
+ type: string;
61
+ /**
62
+ * Optional mapping to a standard property for UI rendering.
63
+ *
64
+ * When set, this extracted value can be used by the UI for specific purposes:
65
+ * - 'name': Display name of the artifact
66
+ * - 'description': Description/summary of the artifact
67
+ * - 'displayMarkdown': Markdown-formatted display content
68
+ * - 'displayHtml': HTML-formatted display content
69
+ *
70
+ * If undefined, this is a custom attribute specific to the artifact type.
71
+ */
72
+ standardProperty?: ArtifactStandardProperty;
73
+ /**
74
+ * JavaScript code that performs the extraction.
75
+ *
76
+ * The extractor function receives the artifact content as input and returns
77
+ * the extracted value. The function body should be valid JavaScript that:
78
+ *
79
+ * 1. Receives a 'content' variable (string) containing the artifact content
80
+ * 2. Performs necessary parsing/extraction logic
81
+ * 3. Returns a value matching the declared 'type'
82
+ *
83
+ * Security Note: This code is executed in a sandboxed environment.
84
+ * You may not access external resources or do anything that would result in side effects.
85
+ *
86
+ * @example
87
+ * ```javascript
88
+ * // Extract subject from JSON email
89
+ * const parsed = JSON.parse(content);
90
+ * return parsed.subject || 'Untitled';
91
+ * ```
92
+ *
93
+ * @example
94
+ * ```javascript
95
+ * // Extract first heading from Markdown
96
+ * const match = content.match(/^#\s+(.+)$/m);
97
+ * return match ? match[1] : null;
98
+ * ```
99
+ */
100
+ extractor: string;
101
+ }
102
+ /**
103
+ * Result of extracting attributes from artifact content using extract rules.
104
+ * This is the runtime representation of extracted values.
105
+ */
106
+ export interface ExtractedArtifactAttribute {
107
+ /** Name of the extracted attribute (from rule.name) */
108
+ name: string;
109
+ /** TypeScript type of the value (from rule.type) */
110
+ type: string;
111
+ /** The extracted value (JSON-serializable) */
112
+ value: any;
113
+ /** Optional mapping to standard property (from rule.standardProperty) */
114
+ standardProperty?: ArtifactStandardProperty;
115
+ }
116
+ /**
117
+ * Configuration for running artifact extraction.
118
+ * Provides context and options for the extraction process.
119
+ */
120
+ export interface ArtifactExtractionConfig {
121
+ /**
122
+ * The artifact content to extract from.
123
+ * This is typically the Content field from ArtifactVersion.
124
+ */
125
+ content: string;
126
+ /**
127
+ * Array of extract rules to apply.
128
+ * These should be the resolved rules after inheritance from parent types.
129
+ */
130
+ extractRules: ArtifactExtractRule[];
131
+ /**
132
+ * Whether to throw errors on extraction failures or continue with null values.
133
+ * Default: false (continue on errors)
134
+ */
135
+ throwOnError?: boolean;
136
+ /**
137
+ * Maximum execution time for each extractor function in milliseconds.
138
+ * Default: 5000ms (5 seconds)
139
+ */
140
+ timeout?: number;
141
+ /**
142
+ * Whether to enable verbose logging during extraction.
143
+ * Default: false
144
+ */
145
+ verbose?: boolean;
146
+ }
147
+ /**
148
+ * Result of running artifact extraction on content.
149
+ */
150
+ export interface ArtifactExtractionResult {
151
+ /** Whether the extraction completed successfully */
152
+ success: boolean;
153
+ /** Array of successfully extracted attributes */
154
+ attributes: ExtractedArtifactAttribute[];
155
+ /** Array of errors that occurred during extraction */
156
+ errors: Array<{
157
+ ruleName: string;
158
+ error: string;
159
+ }>;
160
+ /** Total extraction time in milliseconds */
161
+ executionTimeMs: number;
162
+ }
163
+ //# sourceMappingURL=artifact-extract-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-extract-rules.d.ts","sourceRoot":"","sources":["../../src/artifact-extraction/artifact-extract-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACvC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IAEb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IAEb,8CAA8C;IAC9C,KAAK,EAAE,GAAG,CAAC;IAEX,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACrC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,EAAE,mBAAmB,EAAE,CAAC;IAEpC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IAEjB,iDAAiD;IACjD,UAAU,EAAE,0BAA0B,EAAE,CAAC;IAEzC,sDAAsD;IACtD,MAAM,EAAE,KAAK,CAAC;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview TypeScript types for artifact extract rules system.
4
+ *
5
+ * This module defines the structure for extract rules that enable artifact types
6
+ * to declaratively specify how to extract attributes from artifact content.
7
+ * Extract rules support hierarchical inheritance through parent artifact types.
8
+ *
9
+ * @module @memberjunction/core-entities
10
+ * @since 2.105.0
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ //# sourceMappingURL=artifact-extract-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-extract-rules.js","sourceRoot":"","sources":["../../src/artifact-extraction/artifact-extract-rules.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @fileoverview Artifact attribute extraction utilities with hierarchical rule inheritance.
3
+ *
4
+ * This module provides functionality for extracting attributes from artifact content
5
+ * based on extract rules defined in artifact types. Supports hierarchical inheritance
6
+ * where child artifact types can override parent rules.
7
+ *
8
+ * @module @memberjunction/core-entities
9
+ * @since 2.105.0
10
+ */
11
+ import { ArtifactExtractRule, ExtractedArtifactAttribute, ArtifactExtractionConfig, ArtifactExtractionResult } from './artifact-extract-rules';
12
+ /**
13
+ * Utility class for managing artifact extract rules and performing extraction.
14
+ *
15
+ * Handles:
16
+ * - Hierarchical rule inheritance from parent artifact types
17
+ * - Rule override resolution (child rules override parent rules by name)
18
+ * - Safe execution of extractor JavaScript code
19
+ * - Error handling and timeout management
20
+ */
21
+ export declare class ArtifactExtractor {
22
+ /**
23
+ * Resolves extract rules with hierarchical inheritance.
24
+ *
25
+ * Child artifact types inherit all rules from their parent/grandparent types,
26
+ * but can override rules with the same name. This method resolves the final
27
+ * set of rules by walking up the hierarchy and merging rules.
28
+ *
29
+ * @param artifactTypeChain - Array of artifact types from most specific (child) to least specific (root parent)
30
+ * Each element should have an ExtractRules JSON string
31
+ * @returns Resolved array of extract rules with overrides applied
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Parent type has rules: [{ name: 'title', ... }, { name: 'author', ... }]
36
+ * // Child type has rules: [{ name: 'title', ... (override) }, { name: 'date', ... (new) }]
37
+ * const resolved = ArtifactExtractor.ResolveExtractRules([
38
+ * childType.ExtractRules,
39
+ * parentType.ExtractRules
40
+ * ]);
41
+ * // Result: [{ name: 'title' (from child), ... }, { name: 'author' (from parent), ... }, { name: 'date' (from child), ... }]
42
+ * ```
43
+ */
44
+ static ResolveExtractRules(artifactTypeChain: Array<{
45
+ ExtractRules?: string | null;
46
+ }>): ArtifactExtractRule[];
47
+ /**
48
+ * Extracts attributes from artifact content using the provided extract rules.
49
+ *
50
+ * Executes each extractor function in a controlled environment with timeout
51
+ * and error handling. Failed extractors can either throw or return null values
52
+ * based on configuration.
53
+ *
54
+ * @param config - Extraction configuration including content and rules
55
+ * @returns Extraction result with attributes, errors, and timing information
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const result = await ArtifactExtractor.ExtractAttributes({
60
+ * content: '{"subject": "Hello", "body": "World"}',
61
+ * extractRules: [
62
+ * {
63
+ * name: 'subject',
64
+ * type: 'string',
65
+ * standardProperty: 'name',
66
+ * extractor: 'const parsed = JSON.parse(content); return parsed.subject;'
67
+ * }
68
+ * ]
69
+ * });
70
+ * // result.attributes = [{ name: 'subject', type: 'string', value: 'Hello', standardProperty: 'name' }]
71
+ * ```
72
+ */
73
+ static ExtractAttributes(config: ArtifactExtractionConfig): Promise<ArtifactExtractionResult>;
74
+ /**
75
+ * Executes an extractor function with timeout protection.
76
+ *
77
+ * Creates a sandboxed environment where the extractor code can run safely
78
+ * with access to the content but isolated from the global scope.
79
+ *
80
+ * @param content - The artifact content to extract from
81
+ * @param extractorCode - JavaScript code that performs the extraction
82
+ * @param timeoutMs - Maximum execution time in milliseconds
83
+ * @returns The extracted value
84
+ * @throws Error if execution times out or fails
85
+ *
86
+ * @private
87
+ */
88
+ private static ExecuteExtractor;
89
+ /**
90
+ * Serializes extracted attributes for storage in ArtifactVersionAttribute table.
91
+ *
92
+ * Converts extracted attribute values to JSON strings suitable for database storage.
93
+ *
94
+ * @param attributes - Array of extracted attributes
95
+ * @returns Array of objects ready for database insertion
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const serialized = ArtifactExtractor.SerializeForStorage(result.attributes);
100
+ * // Can now insert these into ArtifactVersionAttribute table
101
+ * for (const attr of serialized) {
102
+ * await artifactVersionAttribute.save({
103
+ * ArtifactVersionID: versionId,
104
+ * Name: attr.name,
105
+ * Type: attr.type,
106
+ * Value: attr.value,
107
+ * StandardProperty: attr.standardProperty
108
+ * });
109
+ * }
110
+ * ```
111
+ */
112
+ static SerializeForStorage(attributes: ExtractedArtifactAttribute[]): Array<{
113
+ name: string;
114
+ type: string;
115
+ value: string;
116
+ standardProperty?: string;
117
+ }>;
118
+ /**
119
+ * Deserializes stored attributes from ArtifactVersionAttribute records.
120
+ *
121
+ * Converts JSON strings back to their original types for use in application.
122
+ *
123
+ * @param storedAttributes - Array of attribute records from database
124
+ * @returns Array of extracted attributes with deserialized values
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const stored = await artifactVersionAttributes.load();
129
+ * const attributes = ArtifactExtractor.DeserializeFromStorage(stored);
130
+ * // attributes have parsed JSON values, not strings
131
+ * ```
132
+ */
133
+ static DeserializeFromStorage(storedAttributes: Array<{
134
+ Name: string;
135
+ Type: string;
136
+ Value: string;
137
+ StandardProperty?: string | null;
138
+ }>): ExtractedArtifactAttribute[];
139
+ /**
140
+ * Finds a specific standard property value from extracted attributes.
141
+ *
142
+ * Convenience method for retrieving attributes mapped to standard properties
143
+ * like 'name', 'description', etc.
144
+ *
145
+ * @param attributes - Array of extracted attributes
146
+ * @param standardProperty - The standard property to find
147
+ * @returns The value of the attribute, or null if not found
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const name = ArtifactExtractor.GetStandardProperty(attributes, 'name');
152
+ * const description = ArtifactExtractor.GetStandardProperty(attributes, 'description');
153
+ * ```
154
+ */
155
+ static GetStandardProperty(attributes: ExtractedArtifactAttribute[], standardProperty: 'name' | 'description' | 'displayMarkdown' | 'displayHtml'): any | null;
156
+ }
157
+ //# sourceMappingURL=artifact-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-extractor.d.ts","sourceRoot":"","sources":["../../src/artifact-extraction/artifact-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACH,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EAC3B,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC1B;;;;;;;;;;;;;;;;;;;;;OAqBG;WACW,mBAAmB,CAAC,iBAAiB,EAAE,KAAK,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,GAAG,mBAAmB,EAAE;IA4BpH;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACiB,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA+D1G;;;;;;;;;;;;;OAaG;mBACkB,gBAAgB;IA6BrC;;;;;;;;;;;;;;;;;;;;;;OAsBG;WACW,mBAAmB,CAAC,UAAU,EAAE,0BAA0B,EAAE,GAAG,KAAK,CAAC;QAC/E,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IASF;;;;;;;;;;;;;;OAcG;WACW,sBAAsB,CAAC,gBAAgB,EAAE,KAAK,CAAC;QACzD,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,CAAC,GAAG,0BAA0B,EAAE;IASjC;;;;;;;;;;;;;;;OAeG;WACW,mBAAmB,CAC7B,UAAU,EAAE,0BAA0B,EAAE,EACxC,gBAAgB,EAAE,MAAM,GAAG,aAAa,GAAG,iBAAiB,GAAG,aAAa,GAC7E,GAAG,GAAG,IAAI;CAIhB"}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Artifact attribute extraction utilities with hierarchical rule inheritance.
4
+ *
5
+ * This module provides functionality for extracting attributes from artifact content
6
+ * based on extract rules defined in artifact types. Supports hierarchical inheritance
7
+ * where child artifact types can override parent rules.
8
+ *
9
+ * @module @memberjunction/core-entities
10
+ * @since 2.105.0
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.ArtifactExtractor = void 0;
14
+ /**
15
+ * Utility class for managing artifact extract rules and performing extraction.
16
+ *
17
+ * Handles:
18
+ * - Hierarchical rule inheritance from parent artifact types
19
+ * - Rule override resolution (child rules override parent rules by name)
20
+ * - Safe execution of extractor JavaScript code
21
+ * - Error handling and timeout management
22
+ */
23
+ class ArtifactExtractor {
24
+ /**
25
+ * Resolves extract rules with hierarchical inheritance.
26
+ *
27
+ * Child artifact types inherit all rules from their parent/grandparent types,
28
+ * but can override rules with the same name. This method resolves the final
29
+ * set of rules by walking up the hierarchy and merging rules.
30
+ *
31
+ * @param artifactTypeChain - Array of artifact types from most specific (child) to least specific (root parent)
32
+ * Each element should have an ExtractRules JSON string
33
+ * @returns Resolved array of extract rules with overrides applied
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Parent type has rules: [{ name: 'title', ... }, { name: 'author', ... }]
38
+ * // Child type has rules: [{ name: 'title', ... (override) }, { name: 'date', ... (new) }]
39
+ * const resolved = ArtifactExtractor.ResolveExtractRules([
40
+ * childType.ExtractRules,
41
+ * parentType.ExtractRules
42
+ * ]);
43
+ * // Result: [{ name: 'title' (from child), ... }, { name: 'author' (from parent), ... }, { name: 'date' (from child), ... }]
44
+ * ```
45
+ */
46
+ static ResolveExtractRules(artifactTypeChain) {
47
+ const rulesMap = new Map();
48
+ // Process from root parent to child (reverse order)
49
+ // This way child rules naturally override parent rules
50
+ for (let i = artifactTypeChain.length - 1; i >= 0; i--) {
51
+ const artifactType = artifactTypeChain[i];
52
+ if (!artifactType.ExtractRules) {
53
+ continue;
54
+ }
55
+ try {
56
+ const rules = JSON.parse(artifactType.ExtractRules);
57
+ if (Array.isArray(rules)) {
58
+ for (const rule of rules) {
59
+ // Child rules override parent rules by name
60
+ rulesMap.set(rule.name, rule);
61
+ }
62
+ }
63
+ }
64
+ catch (error) {
65
+ console.error(`Failed to parse ExtractRules for artifact type at index ${i}:`, error);
66
+ // Continue processing other levels
67
+ }
68
+ }
69
+ return Array.from(rulesMap.values());
70
+ }
71
+ /**
72
+ * Extracts attributes from artifact content using the provided extract rules.
73
+ *
74
+ * Executes each extractor function in a controlled environment with timeout
75
+ * and error handling. Failed extractors can either throw or return null values
76
+ * based on configuration.
77
+ *
78
+ * @param config - Extraction configuration including content and rules
79
+ * @returns Extraction result with attributes, errors, and timing information
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const result = await ArtifactExtractor.ExtractAttributes({
84
+ * content: '{"subject": "Hello", "body": "World"}',
85
+ * extractRules: [
86
+ * {
87
+ * name: 'subject',
88
+ * type: 'string',
89
+ * standardProperty: 'name',
90
+ * extractor: 'const parsed = JSON.parse(content); return parsed.subject;'
91
+ * }
92
+ * ]
93
+ * });
94
+ * // result.attributes = [{ name: 'subject', type: 'string', value: 'Hello', standardProperty: 'name' }]
95
+ * ```
96
+ */
97
+ static async ExtractAttributes(config) {
98
+ const startTime = Date.now();
99
+ const attributes = [];
100
+ const errors = [];
101
+ const timeout = config.timeout ?? 5000;
102
+ const throwOnError = config.throwOnError ?? false;
103
+ const verbose = config.verbose ?? false;
104
+ for (const rule of config.extractRules) {
105
+ try {
106
+ if (verbose) {
107
+ console.log(`Extracting attribute '${rule.name}' using rule:`, rule);
108
+ }
109
+ // Execute the extractor function with timeout
110
+ const value = await this.ExecuteExtractor(config.content, rule.extractor, timeout);
111
+ attributes.push({
112
+ name: rule.name,
113
+ type: rule.type,
114
+ value,
115
+ standardProperty: rule.standardProperty
116
+ });
117
+ if (verbose) {
118
+ console.log(`Successfully extracted '${rule.name}':`, value);
119
+ }
120
+ }
121
+ catch (error) {
122
+ const errorMessage = error instanceof Error ? error.message : String(error);
123
+ errors.push({
124
+ ruleName: rule.name,
125
+ error: errorMessage
126
+ });
127
+ if (verbose) {
128
+ console.error(`Failed to extract '${rule.name}':`, errorMessage);
129
+ }
130
+ if (throwOnError) {
131
+ throw new Error(`Extraction failed for rule '${rule.name}': ${errorMessage}`);
132
+ }
133
+ // Add null value for failed extraction when not throwing
134
+ attributes.push({
135
+ name: rule.name,
136
+ type: rule.type,
137
+ value: null,
138
+ standardProperty: rule.standardProperty
139
+ });
140
+ }
141
+ }
142
+ const executionTimeMs = Date.now() - startTime;
143
+ return {
144
+ success: errors.length === 0,
145
+ attributes,
146
+ errors,
147
+ executionTimeMs
148
+ };
149
+ }
150
+ /**
151
+ * Executes an extractor function with timeout protection.
152
+ *
153
+ * Creates a sandboxed environment where the extractor code can run safely
154
+ * with access to the content but isolated from the global scope.
155
+ *
156
+ * @param content - The artifact content to extract from
157
+ * @param extractorCode - JavaScript code that performs the extraction
158
+ * @param timeoutMs - Maximum execution time in milliseconds
159
+ * @returns The extracted value
160
+ * @throws Error if execution times out or fails
161
+ *
162
+ * @private
163
+ */
164
+ static async ExecuteExtractor(content, extractorCode, timeoutMs) {
165
+ return new Promise((resolve, reject) => {
166
+ // Set up timeout
167
+ const timeoutId = setTimeout(() => {
168
+ reject(new Error(`Extractor execution timed out after ${timeoutMs}ms`));
169
+ }, timeoutMs);
170
+ try {
171
+ // Create a function from the extractor code
172
+ // The extractor receives 'content' as a parameter
173
+ const extractorFn = new Function('content', extractorCode);
174
+ // Execute the extractor
175
+ let result = extractorFn(content);
176
+ // Handle the case where extractor returns string "null" instead of null
177
+ if (typeof result === "string" && result.trim().toLowerCase() === "null") {
178
+ result = null;
179
+ }
180
+ clearTimeout(timeoutId);
181
+ resolve(result);
182
+ }
183
+ catch (error) {
184
+ clearTimeout(timeoutId);
185
+ reject(error);
186
+ }
187
+ });
188
+ }
189
+ /**
190
+ * Serializes extracted attributes for storage in ArtifactVersionAttribute table.
191
+ *
192
+ * Converts extracted attribute values to JSON strings suitable for database storage.
193
+ *
194
+ * @param attributes - Array of extracted attributes
195
+ * @returns Array of objects ready for database insertion
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * const serialized = ArtifactExtractor.SerializeForStorage(result.attributes);
200
+ * // Can now insert these into ArtifactVersionAttribute table
201
+ * for (const attr of serialized) {
202
+ * await artifactVersionAttribute.save({
203
+ * ArtifactVersionID: versionId,
204
+ * Name: attr.name,
205
+ * Type: attr.type,
206
+ * Value: attr.value,
207
+ * StandardProperty: attr.standardProperty
208
+ * });
209
+ * }
210
+ * ```
211
+ */
212
+ static SerializeForStorage(attributes) {
213
+ return attributes.map(attr => ({
214
+ name: attr.name,
215
+ type: attr.type,
216
+ value: JSON.stringify(attr.value),
217
+ standardProperty: attr.standardProperty
218
+ }));
219
+ }
220
+ /**
221
+ * Deserializes stored attributes from ArtifactVersionAttribute records.
222
+ *
223
+ * Converts JSON strings back to their original types for use in application.
224
+ *
225
+ * @param storedAttributes - Array of attribute records from database
226
+ * @returns Array of extracted attributes with deserialized values
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * const stored = await artifactVersionAttributes.load();
231
+ * const attributes = ArtifactExtractor.DeserializeFromStorage(stored);
232
+ * // attributes have parsed JSON values, not strings
233
+ * ```
234
+ */
235
+ static DeserializeFromStorage(storedAttributes) {
236
+ return storedAttributes.map(attr => ({
237
+ name: attr.Name,
238
+ type: attr.Type,
239
+ value: JSON.parse(attr.Value),
240
+ standardProperty: attr.StandardProperty
241
+ }));
242
+ }
243
+ /**
244
+ * Finds a specific standard property value from extracted attributes.
245
+ *
246
+ * Convenience method for retrieving attributes mapped to standard properties
247
+ * like 'name', 'description', etc.
248
+ *
249
+ * @param attributes - Array of extracted attributes
250
+ * @param standardProperty - The standard property to find
251
+ * @returns The value of the attribute, or null if not found
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * const name = ArtifactExtractor.GetStandardProperty(attributes, 'name');
256
+ * const description = ArtifactExtractor.GetStandardProperty(attributes, 'description');
257
+ * ```
258
+ */
259
+ static GetStandardProperty(attributes, standardProperty) {
260
+ const attr = attributes.find(a => a.standardProperty === standardProperty);
261
+ return attr?.value ?? null;
262
+ }
263
+ }
264
+ exports.ArtifactExtractor = ArtifactExtractor;
265
+ //# sourceMappingURL=artifact-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-extractor.js","sourceRoot":"","sources":["../../src/artifact-extraction/artifact-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { ValidationResult } from "@memberjunction/core";
2
+ import { TemplateContentEntity, TemplateEntity, TemplateParamEntity } from "../generated/entity_subclasses";
3
+ export declare class TemplateEntityExtended extends TemplateEntity {
4
+ private _Content;
5
+ get Content(): TemplateContentEntity[];
6
+ set Content(value: TemplateContentEntity[]);
7
+ private _Params;
8
+ get Params(): TemplateParamEntity[];
9
+ set Params(value: TemplateParamEntity[]);
10
+ /**
11
+ * Returns all content for a given type for the template
12
+ * @param type
13
+ * @returns
14
+ */
15
+ GetContentByType(type: string): TemplateContentEntity[];
16
+ /**
17
+ * Returns the highest priority content for the template
18
+ * @param type If provided, returns the highest priority content of the specified type
19
+ * @returns
20
+ */
21
+ GetHighestPriorityContent(type?: string): TemplateContentEntity;
22
+ /**
23
+ * Returns all parameters that apply to a specific template content.
24
+ * This includes both global parameters (where TemplateContentID is NULL)
25
+ * and content-specific parameters for the given contentId.
26
+ *
27
+ * @param contentId - The ID of the template content. If not provided, returns only global parameters.
28
+ * @returns Array of TemplateParamEntity objects that apply to the specified content
29
+ *
30
+ * @example
31
+ * // Get all parameters for a specific content
32
+ * const params = template.GetParametersForContent('content-uuid');
33
+ *
34
+ * @example
35
+ * // Get only global parameters (that apply to all contents)
36
+ * const globalParams = template.GetParametersForContent();
37
+ */
38
+ GetParametersForContent(contentId?: string): TemplateParamEntity[];
39
+ /**
40
+ * This method is different from the Validate() method which validates the state of the Template itself.
41
+ * This method validates the data object provided meets the requirements for the template's parameter definitions.
42
+ *
43
+ * @param data - the data object to validate against the template's parameter definitions
44
+ * @param contentId - Optional: The ID of the template content to validate against.
45
+ * If provided, validates against parameters specific to that content.
46
+ * If not provided, validates against all parameters.
47
+ * @returns ValidationResult with success status and any validation errors
48
+ *
49
+ * @example
50
+ * // Validate against all parameters
51
+ * const result = template.ValidateTemplateInput(inputData);
52
+ *
53
+ * @example
54
+ * // Validate against parameters for a specific content
55
+ * const result = template.ValidateTemplateInput(inputData, 'content-uuid');
56
+ */
57
+ ValidateTemplateInput(data: any, contentId?: string): ValidationResult;
58
+ }
59
+ //# sourceMappingURL=TemplateEntityExtended.d.ts.map