@memberjunction/metadata-sync 2.112.0 → 2.113.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/README.md +136 -61
- package/dist/constants/metadata-keywords.d.ts +282 -0
- package/dist/constants/metadata-keywords.js +364 -0
- package/dist/constants/metadata-keywords.js.map +1 -0
- package/dist/lib/EntityPropertyExtractor.d.ts +1 -1
- package/dist/lib/EntityPropertyExtractor.js +4 -18
- package/dist/lib/EntityPropertyExtractor.js.map +1 -1
- package/dist/lib/FieldExternalizer.d.ts +1 -1
- package/dist/lib/FieldExternalizer.js +6 -5
- package/dist/lib/FieldExternalizer.js.map +1 -1
- package/dist/lib/RecordProcessor.d.ts +1 -1
- package/dist/lib/RecordProcessor.js +14 -12
- package/dist/lib/RecordProcessor.js.map +1 -1
- package/dist/lib/RelatedEntityHandler.d.ts +1 -1
- package/dist/lib/RelatedEntityHandler.js +5 -5
- package/dist/lib/RelatedEntityHandler.js.map +1 -1
- package/dist/lib/json-preprocessor.js +7 -6
- package/dist/lib/json-preprocessor.js.map +1 -1
- package/dist/lib/provider-utils.d.ts +1 -1
- package/dist/lib/provider-utils.js +19 -16
- package/dist/lib/provider-utils.js.map +1 -1
- package/dist/lib/record-dependency-analyzer.js +44 -37
- package/dist/lib/record-dependency-analyzer.js.map +1 -1
- package/dist/lib/singleton-manager.d.ts +1 -1
- package/dist/lib/singleton-manager.js.map +1 -1
- package/dist/lib/sync-engine.d.ts +1 -1
- package/dist/lib/sync-engine.js +36 -44
- package/dist/lib/sync-engine.js.map +1 -1
- package/dist/services/PullService.d.ts +1 -1
- package/dist/services/PullService.js +18 -22
- package/dist/services/PullService.js.map +1 -1
- package/dist/services/PushService.d.ts +1 -1
- package/dist/services/PushService.js +21 -15
- package/dist/services/PushService.js.map +1 -1
- package/dist/services/ValidationService.js +32 -44
- package/dist/services/ValidationService.js.map +1 -1
- package/dist/services/WatchService.d.ts +1 -1
- package/dist/services/WatchService.js +14 -13
- package/dist/services/WatchService.js.map +1 -1
- package/dist/types/validation.d.ts +6 -1
- package/dist/types/validation.js.map +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -212,7 +212,7 @@ Entity classes are located in:
|
|
|
212
212
|
|
|
213
213
|
3. **Runtime Metadata Discovery**:
|
|
214
214
|
```typescript
|
|
215
|
-
import { Metadata } from '@memberjunction/
|
|
215
|
+
import { Metadata } from '@memberjunction/core';
|
|
216
216
|
|
|
217
217
|
const md = new Metadata();
|
|
218
218
|
const entityInfo = md.EntityByName('Templates');
|
|
@@ -474,13 +474,13 @@ With `"filePattern": ".*.json"`:
|
|
|
474
474
|
|
|
475
475
|
### Troubleshooting Quick Reference
|
|
476
476
|
|
|
477
|
-
| Error Message
|
|
478
|
-
|
|
479
|
-
| `No entity directories found`
|
|
480
|
-
| `Field 'X' does not exist on entity 'Y'` | Using non-existent field
|
|
481
|
-
| `User ID cannot be null`
|
|
482
|
-
| `Processing 0 records`
|
|
483
|
-
| Failed validation
|
|
477
|
+
| Error Message | Cause | Solution |
|
|
478
|
+
|---------------|-------|----------|
|
|
479
|
+
| `No entity directories found` | Missing .mj-sync.json or wrong filePattern | Check .mj-sync.json exists and uses `"*.json"` |
|
|
480
|
+
| `Field 'X' does not exist on entity 'Y'` | Using non-existent field | Check BaseEntity class in entity_subclasses.ts |
|
|
481
|
+
| `User ID cannot be null` | Missing required UserID | Add `"UserID": "ECAFCCEC-6A37-EF11-86D4-000D3A4E707E"` |
|
|
482
|
+
| `Processing 0 records` | Files don't match filePattern | Check files match pattern in .mj-sync.json |
|
|
483
|
+
| Failed validation | Wrong data type or format | Check BaseEntity class for field types |
|
|
484
484
|
|
|
485
485
|
### System User ID Reference
|
|
486
486
|
|
|
@@ -828,13 +828,16 @@ Support environment-specific values:
|
|
|
828
828
|
- `@env:VARIABLE_NAME`
|
|
829
829
|
- Useful for different environments (dev/staging/prod)
|
|
830
830
|
|
|
831
|
-
### Automatic JSON Stringification
|
|
832
|
-
When a field value is an array or object, the tool automatically converts it to a JSON string for database storage:
|
|
833
|
-
- Arrays and objects are detected and stringified with pretty formatting (2-space indentation)
|
|
834
|
-
- Maintains clean, readable JSON in source files while storing as strings in database
|
|
835
|
-
- Works seamlessly with all field types that accept text content
|
|
831
|
+
### Automatic JSON Stringification with Reference Processing
|
|
836
832
|
|
|
837
|
-
|
|
833
|
+
When a field value is an array or object, the tool automatically:
|
|
834
|
+
1. **Recursively processes** all `@lookup:`, `@file:`, `@parent:`, `@root:` references inside the object
|
|
835
|
+
2. **Converts to JSON string** with pretty formatting (2-space indentation) for database storage
|
|
836
|
+
3. **Maintains clean structure** in source files while storing as strings in database
|
|
837
|
+
|
|
838
|
+
This is extremely powerful for JSON-typed fields like `Configuration`, `Settings`, `Metadata`, etc.
|
|
839
|
+
|
|
840
|
+
#### Basic Example
|
|
838
841
|
```json
|
|
839
842
|
{
|
|
840
843
|
"fields": {
|
|
@@ -846,16 +849,88 @@ Examples:
|
|
|
846
849
|
"items": [1, 2, 3]
|
|
847
850
|
}
|
|
848
851
|
},
|
|
849
|
-
"Tags": ["tag1", "tag2", "tag3"]
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
852
|
+
"Tags": ["tag1", "tag2", "tag3"]
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
The `Configuration` and `Tags` fields will automatically be converted to JSON strings when pushed to the database.
|
|
858
|
+
|
|
859
|
+
#### Advanced Example: References Inside JSON Fields
|
|
860
|
+
|
|
861
|
+
**This is the powerful part** - you can use `@lookup:` and other references INSIDE object-typed fields:
|
|
862
|
+
|
|
863
|
+
```json
|
|
864
|
+
{
|
|
865
|
+
"fields": {
|
|
866
|
+
"Name": "Agent Memory Manager Job",
|
|
867
|
+
"CronExpression": "0 */15 * * * *",
|
|
868
|
+
"Configuration": {
|
|
869
|
+
"AgentID": "@lookup:AI Agents.Name=Memory Manager",
|
|
870
|
+
"InitialMessage": "Analyze recent conversations",
|
|
871
|
+
"Settings": {
|
|
872
|
+
"MaxNotes": 5,
|
|
873
|
+
"Strategy": "Relevant",
|
|
874
|
+
"TargetAgentID": "@lookup:AI Agents.Name=Sage"
|
|
875
|
+
}
|
|
853
876
|
}
|
|
854
877
|
}
|
|
855
878
|
}
|
|
856
879
|
```
|
|
857
880
|
|
|
858
|
-
|
|
881
|
+
When pushed to the database, this becomes:
|
|
882
|
+
```json
|
|
883
|
+
{
|
|
884
|
+
"Configuration": "{\"AgentID\":\"actual-uuid-here\",\"InitialMessage\":\"Analyze recent conversations\",\"Settings\":{\"MaxNotes\":5,\"Strategy\":\"Relevant\",\"TargetAgentID\":\"another-uuid-here\"}}"
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
**Benefits:**
|
|
889
|
+
- ✅ **Human-readable**: Use agent names, not UUIDs in your metadata
|
|
890
|
+
- ✅ **Maintainable**: Changes to entity names don't break references
|
|
891
|
+
- ✅ **Type-safe**: Structured objects in source, properly stringified for DB
|
|
892
|
+
- ✅ **Nested support**: References work at any depth in the object tree
|
|
893
|
+
|
|
894
|
+
#### Common Use Cases
|
|
895
|
+
|
|
896
|
+
**Scheduled Job Configuration:**
|
|
897
|
+
```json
|
|
898
|
+
{
|
|
899
|
+
"Configuration": {
|
|
900
|
+
"AgentID": "@lookup:AI Agents.Name=Report Generator",
|
|
901
|
+
"Schedule": "daily",
|
|
902
|
+
"Recipients": "@lookup:Users.Email=admin@company.com"
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
**Action Parameters:**
|
|
908
|
+
```json
|
|
909
|
+
{
|
|
910
|
+
"DefaultParameters": {
|
|
911
|
+
"TargetEntityID": "@lookup:Entities.Name=Customers",
|
|
912
|
+
"TemplateID": "@lookup:Templates.Name=Welcome Email",
|
|
913
|
+
"Settings": {
|
|
914
|
+
"SendImmediate": true,
|
|
915
|
+
"Priority": "High"
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
**AI Configuration:**
|
|
922
|
+
```json
|
|
923
|
+
{
|
|
924
|
+
"AIConfig": {
|
|
925
|
+
"PreferredModelID": "@lookup:AI Models.Name=GPT 4.1",
|
|
926
|
+
"FallbackModels": [
|
|
927
|
+
"@lookup:AI Models.Name=Claude Sonnet 3.7",
|
|
928
|
+
"@lookup:AI Models.Name=Gemini Pro"
|
|
929
|
+
],
|
|
930
|
+
"Temperature": 0.7
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
```
|
|
859
934
|
|
|
860
935
|
### {@include} References in Files
|
|
861
936
|
Enable content composition within non-JSON files (like .md, .html, .txt) using JSDoc-style include syntax:
|
|
@@ -1510,13 +1585,13 @@ SQL logging is configured in the root-level `.mj-sync.json` file only (not inher
|
|
|
1510
1585
|
|
|
1511
1586
|
#### SQL Logging Options
|
|
1512
1587
|
|
|
1513
|
-
| Option
|
|
1514
|
-
|
|
1515
|
-
| `enabled`
|
|
1516
|
-
| `outputDirectory`
|
|
1517
|
-
| `formatAsMigration` | boolean
|
|
1518
|
-
| `filterPatterns`
|
|
1519
|
-
| `filterType`
|
|
1588
|
+
| Option | Type | Default | Description |
|
|
1589
|
+
|--------|------|---------|-------------|
|
|
1590
|
+
| `enabled` | boolean | false | Whether to enable SQL logging during push operations |
|
|
1591
|
+
| `outputDirectory` | string | "./sql_logging" | Directory to output SQL log files (relative to command execution directory) |
|
|
1592
|
+
| `formatAsMigration` | boolean | false | Whether to format SQL as migration-ready files with Flyway schema placeholders |
|
|
1593
|
+
| `filterPatterns` | string[] | undefined | Array of patterns to filter SQL statements (see below) |
|
|
1594
|
+
| `filterType` | "exclude" \| "include" | "exclude" | How to apply filter patterns |
|
|
1520
1595
|
|
|
1521
1596
|
#### SQL Log File Format
|
|
1522
1597
|
|
|
@@ -1633,11 +1708,11 @@ Add the `userRoleValidation` configuration to your root `.mj-sync.json` file:
|
|
|
1633
1708
|
|
|
1634
1709
|
#### Configuration Options
|
|
1635
1710
|
|
|
1636
|
-
| Option
|
|
1637
|
-
|
|
1638
|
-
| `enabled`
|
|
1639
|
-
| `allowedRoles`
|
|
1640
|
-
| `allowUsersWithoutRoles` | boolean
|
|
1711
|
+
| Option | Type | Default | Description |
|
|
1712
|
+
|--------|------|---------|-------------|
|
|
1713
|
+
| `enabled` | boolean | false | Enable user role validation for UserID fields |
|
|
1714
|
+
| `allowedRoles` | string[] | [] | List of role names that are allowed |
|
|
1715
|
+
| `allowUsersWithoutRoles` | boolean | false | Allow users without any assigned roles |
|
|
1641
1716
|
|
|
1642
1717
|
#### How It Works
|
|
1643
1718
|
|
|
@@ -1864,10 +1939,10 @@ When `recursive: true` is set:
|
|
|
1864
1939
|
|
|
1865
1940
|
### Configuration Options
|
|
1866
1941
|
|
|
1867
|
-
| Option
|
|
1868
|
-
|
|
1869
|
-
| `recursive` | boolean | false
|
|
1870
|
-
| `maxDepth`
|
|
1942
|
+
| Option | Type | Default | Description |
|
|
1943
|
+
|--------|------|---------|-------------|
|
|
1944
|
+
| `recursive` | boolean | false | Enable automatic recursive fetching |
|
|
1945
|
+
| `maxDepth` | number | 10 | Maximum recursion depth to prevent infinite loops |
|
|
1871
1946
|
|
|
1872
1947
|
### Safeguards
|
|
1873
1948
|
|
|
@@ -1934,24 +2009,24 @@ The pull command now supports smart update capabilities with extensive configura
|
|
|
1934
2009
|
|
|
1935
2010
|
#### Pull Configuration Options
|
|
1936
2011
|
|
|
1937
|
-
| Option
|
|
1938
|
-
|
|
1939
|
-
| `filePattern`
|
|
1940
|
-
| `createNewFileIfNotFound`
|
|
1941
|
-
| `newFileName`
|
|
1942
|
-
| `appendRecordsToExistingFile` | boolean
|
|
1943
|
-
| `updateExistingRecords`
|
|
1944
|
-
| `preserveFields`
|
|
1945
|
-
| `mergeStrategy`
|
|
1946
|
-
| `backupBeforeUpdate`
|
|
1947
|
-
| `backupDirectory`
|
|
1948
|
-
| `filter`
|
|
1949
|
-
| `externalizeFields`
|
|
1950
|
-
| `excludeFields`
|
|
1951
|
-
| `lookupFields`
|
|
1952
|
-
| `relatedEntities`
|
|
1953
|
-
| `ignoreNullFields`
|
|
1954
|
-
| `ignoreVirtualFields`
|
|
2012
|
+
| Option | Type | Default | Description |
|
|
2013
|
+
|--------|------|---------|-------------|
|
|
2014
|
+
| `filePattern` | string | Entity filePattern | Pattern for finding existing files to update |
|
|
2015
|
+
| `createNewFileIfNotFound` | boolean | true | Create files for records not found locally |
|
|
2016
|
+
| `newFileName` | string | - | Filename for new records when appending (see warning below) |
|
|
2017
|
+
| `appendRecordsToExistingFile` | boolean | false | Append new records to a single file |
|
|
2018
|
+
| `updateExistingRecords` | boolean | true | Update existing records found in local files |
|
|
2019
|
+
| `preserveFields` | string[] | [] | Fields that retain local values during updates (see detailed explanation below) |
|
|
2020
|
+
| `mergeStrategy` | string | "merge" | How to merge updates: "merge", "overwrite", or "skip" |
|
|
2021
|
+
| `backupBeforeUpdate` | boolean | false | Create timestamped backups before updating files |
|
|
2022
|
+
| `backupDirectory` | string | ".backups" | Directory name for backup files (relative to entity directory) |
|
|
2023
|
+
| `filter` | string | - | SQL WHERE clause for filtering records |
|
|
2024
|
+
| `externalizeFields` | array/object | - | Fields to save as external files with optional patterns |
|
|
2025
|
+
| `excludeFields` | string[] | [] | Fields to completely omit from pulled data (see detailed explanation below) |
|
|
2026
|
+
| `lookupFields` | object | - | Foreign keys to convert to @lookup references |
|
|
2027
|
+
| `relatedEntities` | object | - | Related entities to pull as embedded collections |
|
|
2028
|
+
| `ignoreNullFields` | boolean | false | Exclude fields with null values from pulled data |
|
|
2029
|
+
| `ignoreVirtualFields` | boolean | false | Exclude virtual fields (view-only fields) from pulled data |
|
|
1955
2030
|
|
|
1956
2031
|
> **⚠️ Important Configuration Warning**
|
|
1957
2032
|
>
|
|
@@ -2459,14 +2534,14 @@ When using virtual properties, related required fields are skipped:
|
|
|
2459
2534
|
|
|
2460
2535
|
### Common Validation Errors
|
|
2461
2536
|
|
|
2462
|
-
| Error
|
|
2463
|
-
|
|
2464
|
-
| `Field "X" does not exist` | Typo or wrong entity
|
|
2465
|
-
| `Entity "X" not found`
|
|
2466
|
-
| `File not found`
|
|
2467
|
-
| `Lookup not found`
|
|
2468
|
-
| `Circular dependency`
|
|
2469
|
-
| `Required field missing`
|
|
2537
|
+
| Error | Cause | Solution |
|
|
2538
|
+
|-------|-------|----------|
|
|
2539
|
+
| `Field "X" does not exist` | Typo or wrong entity | Check entity definition in generated files |
|
|
2540
|
+
| `Entity "X" not found` | Wrong entity name | Use exact entity name from database |
|
|
2541
|
+
| `File not found` | Bad @file: reference | Check file path is relative and exists |
|
|
2542
|
+
| `Lookup not found` | No matching record | Verify lookup value or use ?create |
|
|
2543
|
+
| `Circular dependency` | A→B→A references | Restructure to avoid cycles |
|
|
2544
|
+
| `Required field missing` | Missing required field | Add field with appropriate value |
|
|
2470
2545
|
|
|
2471
2546
|
### Validation Configuration
|
|
2472
2547
|
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized metadata keyword constants for MemberJunction MetadataSync package.
|
|
3
|
+
*
|
|
4
|
+
* These keywords are special prefixes used in metadata JSON files to reference external
|
|
5
|
+
* content, perform lookups, access environment variables, and establish hierarchical relationships.
|
|
6
|
+
*
|
|
7
|
+
* @module metadata-keywords
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // Using @file: to reference external content
|
|
11
|
+
* {
|
|
12
|
+
* "Prompt": "@file:greeting.prompt.md"
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Using @lookup: to find an entity by field value
|
|
17
|
+
* {
|
|
18
|
+
* "CategoryID": "@lookup:AI Prompt Categories.Name=Examples"
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Using @parent: to reference parent entity fields
|
|
23
|
+
* {
|
|
24
|
+
* "PromptID": "@parent:ID"
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Metadata keyword constants.
|
|
29
|
+
* These are the special @ prefixes recognized by MetadataSync for field value processing.
|
|
30
|
+
*/
|
|
31
|
+
export declare const METADATA_KEYWORDS: {
|
|
32
|
+
/**
|
|
33
|
+
* @file: - Loads content from an external file
|
|
34
|
+
*
|
|
35
|
+
* Reads the contents of a file (relative to the JSON metadata file) and uses it as the field value.
|
|
36
|
+
* Supports text files, markdown, JSON, and other formats.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* "@file:greeting.prompt.md"
|
|
40
|
+
* "@file:./shared/common-prompt.md"
|
|
41
|
+
* "@file:../templates/standard-header.md"
|
|
42
|
+
*/
|
|
43
|
+
readonly FILE: "@file:";
|
|
44
|
+
/**
|
|
45
|
+
* @lookup: - Looks up an entity record by field value(s)
|
|
46
|
+
*
|
|
47
|
+
* Finds an entity record matching the specified criteria and uses its ID.
|
|
48
|
+
* Supports single-field and multi-field lookups, with optional auto-creation.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* "@lookup:AI Prompt Types.Name=Chat"
|
|
52
|
+
* "@lookup:Users.Email=john@example.com&Department=Sales"
|
|
53
|
+
* "@lookup:Categories.Name=Examples?create"
|
|
54
|
+
* "@lookup:Categories.Name=Examples?create&Description=Example prompts"
|
|
55
|
+
*/
|
|
56
|
+
readonly LOOKUP: "@lookup:";
|
|
57
|
+
/**
|
|
58
|
+
* @parent: - References a field from the parent entity
|
|
59
|
+
*
|
|
60
|
+
* In nested/related entity structures, accesses a field value from the immediate parent record.
|
|
61
|
+
* Only valid when processing nested entities that have a parent context.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* "@parent:ID"
|
|
65
|
+
* "@parent:Name"
|
|
66
|
+
* "@parent:CategoryID"
|
|
67
|
+
*/
|
|
68
|
+
readonly PARENT: "@parent:";
|
|
69
|
+
/**
|
|
70
|
+
* @root: - References a field from the root entity
|
|
71
|
+
*
|
|
72
|
+
* In nested/related entity structures, accesses a field value from the top-level root record.
|
|
73
|
+
* Only valid when processing nested entities that have a root context.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* "@root:ID"
|
|
77
|
+
* "@root:Name"
|
|
78
|
+
*/
|
|
79
|
+
readonly ROOT: "@root:";
|
|
80
|
+
/**
|
|
81
|
+
* @env: - Reads an environment variable
|
|
82
|
+
*
|
|
83
|
+
* Gets the value of an environment variable at runtime.
|
|
84
|
+
* Useful for configuration values that differ between environments.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* "@env:VARIABLE_NAME"
|
|
88
|
+
* "@env:NODE_ENV"
|
|
89
|
+
*/
|
|
90
|
+
readonly ENV: "@env:";
|
|
91
|
+
/**
|
|
92
|
+
* @url: - Fetches content from a URL
|
|
93
|
+
*
|
|
94
|
+
* Downloads content from a remote URL and uses it as the field value.
|
|
95
|
+
* Supports HTTP/HTTPS URLs and file:// URLs.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* "@url:https://example.com/prompts/greeting.md"
|
|
99
|
+
* "@url:https://raw.githubusercontent.com/company/prompts/main/customer.md"
|
|
100
|
+
*/
|
|
101
|
+
readonly URL: "@url:";
|
|
102
|
+
/**
|
|
103
|
+
* @template: - Loads a template JSON file
|
|
104
|
+
*
|
|
105
|
+
* Loads a JSON template file and uses its contents, replacing any template variables.
|
|
106
|
+
* Useful for standardizing common configurations across multiple records.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* "@template:templates/standard-ai-models.json"
|
|
110
|
+
*/
|
|
111
|
+
readonly TEMPLATE: "@template:";
|
|
112
|
+
/**
|
|
113
|
+
* @include or @include.* - Includes content from another file
|
|
114
|
+
*
|
|
115
|
+
* Special directive (not a field value) that merges content from external files.
|
|
116
|
+
* Can be used in both objects and arrays. Supports spread and property modes.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* { "@include": "common-fields.json" }
|
|
120
|
+
* [ "@include:items.json" ]
|
|
121
|
+
* { "@include.models": { "file": "models.json", "mode": "property" } }
|
|
122
|
+
*/
|
|
123
|
+
readonly INCLUDE: "@include";
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Type representing all metadata keyword values.
|
|
127
|
+
*/
|
|
128
|
+
export type MetadataKeyword = typeof METADATA_KEYWORDS[keyof typeof METADATA_KEYWORDS];
|
|
129
|
+
/**
|
|
130
|
+
* Type representing metadata keyword types (without the colon for keywords that have it).
|
|
131
|
+
*/
|
|
132
|
+
export type MetadataKeywordType = 'file' | 'lookup' | 'parent' | 'root' | 'env' | 'url' | 'template' | 'include';
|
|
133
|
+
/**
|
|
134
|
+
* Array of all metadata keyword prefixes for iteration.
|
|
135
|
+
* This array maintains the order of keywords for consistent processing.
|
|
136
|
+
*/
|
|
137
|
+
export declare const METADATA_KEYWORD_PREFIXES: ReadonlyArray<string>;
|
|
138
|
+
/**
|
|
139
|
+
* Checks if a value is a string that starts with any recognized metadata keyword.
|
|
140
|
+
*
|
|
141
|
+
* This is a type-safe check that handles non-string values gracefully.
|
|
142
|
+
* Returns false for null, undefined, objects, numbers, etc.
|
|
143
|
+
*
|
|
144
|
+
* @param value - The value to check (can be any type)
|
|
145
|
+
* @returns true if value is a string starting with a metadata keyword, false otherwise
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* isMetadataKeyword('@file:template.md') // true
|
|
149
|
+
* isMetadataKeyword('@lookup:Users.Email=test@example.com') // true
|
|
150
|
+
* isMetadataKeyword('@parent:ID') // true
|
|
151
|
+
* isMetadataKeyword('regular string') // false
|
|
152
|
+
* isMetadataKeyword(123) // false
|
|
153
|
+
* isMetadataKeyword(null) // false
|
|
154
|
+
* isMetadataKeyword('@unknown:value') // false
|
|
155
|
+
*/
|
|
156
|
+
export declare function isMetadataKeyword(value: unknown): value is string;
|
|
157
|
+
/**
|
|
158
|
+
* Determines which metadata keyword type a string value uses.
|
|
159
|
+
*
|
|
160
|
+
* Examines the prefix of a string and returns the corresponding keyword type.
|
|
161
|
+
* Returns null if the value doesn't use any recognized metadata keyword.
|
|
162
|
+
*
|
|
163
|
+
* @param value - The string value to analyze
|
|
164
|
+
* @returns The keyword type ('file', 'lookup', etc.) or null if no keyword is found
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* getMetadataKeywordType('@file:template.md') // 'file'
|
|
168
|
+
* getMetadataKeywordType('@lookup:Users.Name=John') // 'lookup'
|
|
169
|
+
* getMetadataKeywordType('@parent:ID') // 'parent'
|
|
170
|
+
* getMetadataKeywordType('@include') // 'include'
|
|
171
|
+
* getMetadataKeywordType('regular string') // null
|
|
172
|
+
* getMetadataKeywordType('@unknown:value') // null
|
|
173
|
+
*/
|
|
174
|
+
export declare function getMetadataKeywordType(value: string): MetadataKeywordType | null;
|
|
175
|
+
/**
|
|
176
|
+
* Type-safe check for metadata keywords that handles any value type.
|
|
177
|
+
*
|
|
178
|
+
* This is an alias for isMetadataKeyword() provided for semantic clarity
|
|
179
|
+
* when you want to explicitly check if a value has a metadata keyword.
|
|
180
|
+
*
|
|
181
|
+
* @param value - Any value to check
|
|
182
|
+
* @returns true if value is a string with a metadata keyword, false otherwise
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* const fieldValue = record.Get('SomeField');
|
|
186
|
+
* if (hasMetadataKeyword(fieldValue)) {
|
|
187
|
+
* // fieldValue is guaranteed to be a string with a metadata keyword
|
|
188
|
+
* const type = getMetadataKeywordType(fieldValue);
|
|
189
|
+
* }
|
|
190
|
+
*/
|
|
191
|
+
export declare function hasMetadataKeyword(value: unknown): value is string;
|
|
192
|
+
/**
|
|
193
|
+
* Checks if a string starts with @ but is NOT a metadata keyword.
|
|
194
|
+
*
|
|
195
|
+
* This is useful for filtering out @ strings that are not metadata keywords,
|
|
196
|
+
* such as npm package names (@mui/material, @angular/core) or email addresses.
|
|
197
|
+
*
|
|
198
|
+
* @param value - The value to check
|
|
199
|
+
* @returns true if value starts with @ but is not a metadata keyword
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* isNonKeywordAtSymbol('@mui/material') // true
|
|
203
|
+
* isNonKeywordAtSymbol('@angular/core') // true
|
|
204
|
+
* isNonKeywordAtSymbol('@file:template.md') // false
|
|
205
|
+
* isNonKeywordAtSymbol('regular string') // false
|
|
206
|
+
*/
|
|
207
|
+
export declare function isNonKeywordAtSymbol(value: unknown): boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Extracts the value portion after a metadata keyword prefix.
|
|
210
|
+
*
|
|
211
|
+
* Removes the keyword prefix from a string and returns the remaining value.
|
|
212
|
+
* Returns null if the string doesn't use a metadata keyword.
|
|
213
|
+
*
|
|
214
|
+
* @param value - The string containing a metadata keyword
|
|
215
|
+
* @returns The value after the keyword prefix, or null if no keyword found
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* extractKeywordValue('@file:template.md') // 'template.md'
|
|
219
|
+
* extractKeywordValue('@lookup:Users.Email=test@example.com') // 'Users.Email=test@example.com'
|
|
220
|
+
* extractKeywordValue('@parent:ID') // 'ID'
|
|
221
|
+
* extractKeywordValue('regular string') // null
|
|
222
|
+
*/
|
|
223
|
+
export declare function extractKeywordValue(value: string): string | null;
|
|
224
|
+
/**
|
|
225
|
+
* List of metadata keywords that require a parent context to function.
|
|
226
|
+
* These keywords cannot be used at the top level of metadata - they only work
|
|
227
|
+
* in nested/related entities where a parent record exists.
|
|
228
|
+
*/
|
|
229
|
+
export declare const CONTEXT_DEPENDENT_KEYWORDS: readonly ["@parent:", "@root:"];
|
|
230
|
+
/**
|
|
231
|
+
* List of metadata keywords that reference external resources.
|
|
232
|
+
* These keywords load content from files, URLs, or other external sources.
|
|
233
|
+
*/
|
|
234
|
+
export declare const EXTERNAL_REFERENCE_KEYWORDS: readonly ["@file:", "@url:", "@template:"];
|
|
235
|
+
/**
|
|
236
|
+
* List of metadata keywords that perform database lookups.
|
|
237
|
+
*/
|
|
238
|
+
export declare const LOOKUP_KEYWORDS: readonly ["@lookup:"];
|
|
239
|
+
/**
|
|
240
|
+
* List of metadata keywords that access runtime configuration.
|
|
241
|
+
*/
|
|
242
|
+
export declare const RUNTIME_KEYWORDS: readonly ["@env:"];
|
|
243
|
+
/**
|
|
244
|
+
* Checks if a keyword requires a parent/root context.
|
|
245
|
+
*
|
|
246
|
+
* @param keyword - The keyword to check
|
|
247
|
+
* @returns true if the keyword requires context (parent or root)
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* isContextDependentKeyword('@parent:') // true
|
|
251
|
+
* isContextDependentKeyword('@root:') // true
|
|
252
|
+
* isContextDependentKeyword('@file:') // false
|
|
253
|
+
*/
|
|
254
|
+
export declare function isContextDependentKeyword(keyword: string): boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Checks if a keyword references an external resource.
|
|
257
|
+
*
|
|
258
|
+
* @param keyword - The keyword to check
|
|
259
|
+
* @returns true if the keyword loads external content
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* isExternalReferenceKeyword('@file:') // true
|
|
263
|
+
* isExternalReferenceKeyword('@url:') // true
|
|
264
|
+
* isExternalReferenceKeyword('@lookup:') // false
|
|
265
|
+
*/
|
|
266
|
+
export declare function isExternalReferenceKeyword(keyword: string): boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Creates a metadata keyword reference string.
|
|
269
|
+
*
|
|
270
|
+
* Helper function to construct properly formatted keyword references.
|
|
271
|
+
* This ensures consistent formatting across the codebase.
|
|
272
|
+
*
|
|
273
|
+
* @param type - The keyword type
|
|
274
|
+
* @param value - The value after the keyword
|
|
275
|
+
* @returns Formatted keyword reference string
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* createKeywordReference('file', 'template.md') // '@file:template.md'
|
|
279
|
+
* createKeywordReference('lookup', 'Users.Email=test@example.com') // '@lookup:Users.Email=test@example.com'
|
|
280
|
+
* createKeywordReference('parent', 'ID') // '@parent:ID'
|
|
281
|
+
*/
|
|
282
|
+
export declare function createKeywordReference(type: MetadataKeywordType, value: string): string;
|