@encodeagent/platform-helper-util 1.2603.1071502 → 1.2603.1311023
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 +277 -153
- package/dist/api.d.ts +38 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +38 -2
- package/dist/api.js.map +1 -1
- package/dist/auth.d.ts +93 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +93 -2
- package/dist/auth.js.map +1 -1
- package/dist/colors.d.ts +41 -0
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +41 -0
- package/dist/colors.js.map +1 -1
- package/dist/core.d.ts +262 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +264 -2
- package/dist/core.js.map +1 -1
- package/dist/cost.d.ts +26 -0
- package/dist/cost.d.ts.map +1 -1
- package/dist/cost.js +27 -1
- package/dist/cost.js.map +1 -1
- package/dist/file.d.ts +38 -0
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +42 -2
- package/dist/file.js.map +1 -1
- package/dist/html.d.ts +83 -0
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +89 -37
- package/dist/html.js.map +1 -1
- package/dist/logger.d.ts +17 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +28 -2
- package/dist/logger.js.map +1 -1
- package/dist/markdown.d.ts +20 -0
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +20 -0
- package/dist/markdown.js.map +1 -1
- package/dist/metadata.js +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/record.d.ts +141 -3
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +161 -65
- package/dist/record.js.map +1 -1
- package/dist/shortid.d.ts +21 -8
- package/dist/shortid.d.ts.map +1 -1
- package/dist/shortid.js +9 -5
- package/dist/shortid.js.map +1 -1
- package/dist/slug.d.ts +10 -0
- package/dist/slug.d.ts.map +1 -1
- package/dist/slug.js +10 -0
- package/dist/slug.js.map +1 -1
- package/dist/token.d.ts +1 -1
- package/dist/tree.d.ts +43 -0
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +43 -5
- package/dist/tree.js.map +1 -1
- package/dist/value-of-object.d.ts +41 -0
- package/dist/value-of-object.d.ts.map +1 -1
- package/dist/value-of-object.js +59 -17
- package/dist/value-of-object.js.map +1 -1
- package/dist/web-content.d.ts +52 -0
- package/dist/web-content.d.ts.map +1 -1
- package/dist/web-content.js +52 -0
- package/dist/web-content.js.map +1 -1
- package/dist/web.d.ts +51 -0
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +54 -1
- package/dist/web.js.map +1 -1
- package/package.json +10 -5
package/dist/record.d.ts
CHANGED
|
@@ -23,25 +23,72 @@ export interface IRecord {
|
|
|
23
23
|
organizationId: string;
|
|
24
24
|
solutionId: string;
|
|
25
25
|
createdBy: string;
|
|
26
|
-
|
|
26
|
+
createdAt: number;
|
|
27
27
|
ownedBy: string;
|
|
28
|
-
|
|
28
|
+
ownedAt: number;
|
|
29
29
|
modifiedBy: string;
|
|
30
|
-
|
|
30
|
+
modifiedAt: number;
|
|
31
31
|
partitionKey: string;
|
|
32
32
|
isPublished?: boolean;
|
|
33
33
|
isGlobal?: boolean;
|
|
34
|
+
isPublishedBy?: string;
|
|
35
|
+
isPublishedAt?: string;
|
|
36
|
+
isGlobalBy?: string;
|
|
37
|
+
isGlobalAt?: string;
|
|
38
|
+
stateCode: number;
|
|
39
|
+
statusCode: number;
|
|
34
40
|
[key: string]: any;
|
|
35
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Strips server-managed and identity fields from a record so it can be submitted as a
|
|
44
|
+
* new create payload. Removes audit timestamps, CosmosDB system properties (`_rid`,
|
|
45
|
+
* `_self`, etc.), computed fields (`slug`, `searchDisplay`, `display`), and platform
|
|
46
|
+
* fields (`stateCode`, `statusCode`, `organizationId`, `solutionId`, `partitionKey`).
|
|
47
|
+
* Assigns a fresh GUID as `id`.
|
|
48
|
+
*/
|
|
36
49
|
export declare const convertRecordForCreate: (record: Record<string, any>) => Record<string, any>;
|
|
37
50
|
export interface IGetBaseRecordProps extends IContext {
|
|
38
51
|
entityName: string;
|
|
39
52
|
entityType?: string;
|
|
40
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a minimal valid `IRecord` shell with a new GUID and audit fields populated
|
|
56
|
+
* from the provided context. All timestamps are set to the current moment.
|
|
57
|
+
* `partitionKey` is set to `organizationId` (CosmosDB convention).
|
|
58
|
+
*/
|
|
41
59
|
export declare const getBaseRecord: (context: IGetBaseRecordProps) => IRecord;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the first non-empty string value found by iterating `displayFields` in order.
|
|
62
|
+
* Used internally by `getRecordDisplay` when an entity defines explicit display field names.
|
|
63
|
+
*/
|
|
42
64
|
export declare const getRecordDisplayByDisplayFields: (record: Record<string, any>, displayFields?: string[]) => string;
|
|
65
|
+
/**
|
|
66
|
+
* Returns a folder path string derived from a record's `entityName` and `entityType`.
|
|
67
|
+
* Format: `"entityName/entityType"` or just `"entityName"` when `entityNameOnly` is true
|
|
68
|
+
* or when `entityType` is absent. Returns `"Unknown"` when both are empty.
|
|
69
|
+
*/
|
|
43
70
|
export declare const getRecordEntityFolder: (data: Record<string, any>, entityNameOnly: boolean) => string;
|
|
71
|
+
/**
|
|
72
|
+
* Builds a storage folder path from explicit `entityName` and optional `entityType` strings
|
|
73
|
+
* (rather than reading from a record object). Returns `"Unknown"` when `entityName` is empty.
|
|
74
|
+
*/
|
|
44
75
|
export declare const getEntityFolder: (entityName: string, entityType?: string) => string;
|
|
76
|
+
/**
|
|
77
|
+
* Resolves the best human-readable display label for a record.
|
|
78
|
+
*
|
|
79
|
+
* Resolution priority:
|
|
80
|
+
* 1. Search highlight title (`_ui.highlight.title`)
|
|
81
|
+
* 2. `searchDisplay` (when `includeSearchDisplay` is true)
|
|
82
|
+
* 3. Entity `displayFields` (first non-empty field)
|
|
83
|
+
* 4. `firstName + lastName` full name
|
|
84
|
+
* 5. `displayValue`
|
|
85
|
+
* 6. `number – title` / `number – name` / `number – subject`
|
|
86
|
+
* 7. `display`, `text`, `symbol`, `code`
|
|
87
|
+
*
|
|
88
|
+
* The result is cleaned (normalizes whitespace and punctuation spacing) and optionally
|
|
89
|
+
* truncated to `maxLength` characters. Returns the record `id` when `allowUseRecordId`
|
|
90
|
+
* is true and no other value could be resolved.
|
|
91
|
+
*/
|
|
45
92
|
export declare const getRecordDisplay: (record: Record<string, any>, settings?: {
|
|
46
93
|
entity?: Record<string, any>;
|
|
47
94
|
displayFields?: string[];
|
|
@@ -50,13 +97,38 @@ export declare const getRecordDisplay: (record: Record<string, any>, settings?:
|
|
|
50
97
|
emptyReturnUndefined?: boolean;
|
|
51
98
|
allowUseRecordId?: boolean;
|
|
52
99
|
}) => string | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Resolves the best short abstract/description text for a record.
|
|
102
|
+
*
|
|
103
|
+
* Resolution priority:
|
|
104
|
+
* 1. Search highlight (`highlight.searchContent[0]`)
|
|
105
|
+
* 2. `summary`, `description`, `abstract`
|
|
106
|
+
* 3. `searchContent` (only when `settings.includeContent` is true)
|
|
107
|
+
*
|
|
108
|
+
* Whitespace and punctuation are normalized before returning.
|
|
109
|
+
* Truncates to `settings.maxLength` characters when provided.
|
|
110
|
+
*/
|
|
53
111
|
export declare const getRecordAbstract: (record: Record<string, any>, settings?: {
|
|
54
112
|
entity?: Record<string, any>;
|
|
55
113
|
abstractFields?: string[];
|
|
56
114
|
maxLength?: number;
|
|
57
115
|
includeContent?: boolean;
|
|
58
116
|
}) => string;
|
|
117
|
+
/**
|
|
118
|
+
* Returns the first non-empty string value found by iterating `contentFields` in order.
|
|
119
|
+
* Used internally by `getRecordContent` when an entity defines explicit content field names.
|
|
120
|
+
*/
|
|
59
121
|
export declare const getRecordContentByContentFields: (record: Record<string, any>, contentFields?: string[]) => string;
|
|
122
|
+
/**
|
|
123
|
+
* Resolves the main body content for a record, suitable for indexing or display.
|
|
124
|
+
*
|
|
125
|
+
* Resolution priority:
|
|
126
|
+
* 1. Search highlight (`_ui.highlight.content`)
|
|
127
|
+
* 2. `searchContent` (when `includeSearchDisplay` is true)
|
|
128
|
+
* 3. Entity/settings `contentFields` (defaults to description, note, detail, content, …)
|
|
129
|
+
*
|
|
130
|
+
* Truncates to `maxLength` when provided.
|
|
131
|
+
*/
|
|
60
132
|
export declare const getRecordContent: (record: Record<string, any>, settings?: {
|
|
61
133
|
entity?: Record<string, any>;
|
|
62
134
|
contentFields?: string[];
|
|
@@ -64,18 +136,60 @@ export declare const getRecordContent: (record: Record<string, any>, settings?:
|
|
|
64
136
|
maxLength?: number;
|
|
65
137
|
emptyReturnUndefined?: boolean;
|
|
66
138
|
}) => string | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Formats a complete postal address from prefixed address fields on a record
|
|
141
|
+
* (e.g. `prefix = "billing"` reads `billingLine1`, `billingCity`, `billingState`, …).
|
|
142
|
+
* Returns `""` when the record does not contain the minimum required fields
|
|
143
|
+
* (city + state + country, or postalCode + country).
|
|
144
|
+
*/
|
|
67
145
|
export declare const getRecordAddress: (record: Record<string, any>, prefix: string) => string;
|
|
146
|
+
/**
|
|
147
|
+
* Returns the primary media URL for a record, trying `media`, `photoUrl`, and
|
|
148
|
+
* `source.photoUrl` in that order. Returns `""` when none are set.
|
|
149
|
+
*/
|
|
68
150
|
export declare const getRecordMedia: (record: Record<string, any>) => string;
|
|
151
|
+
/**
|
|
152
|
+
* Constructs a display name for a user-like record.
|
|
153
|
+
*
|
|
154
|
+
* Resolution order: `fullName` → `firstName + lastName` → `name` → `email`.
|
|
155
|
+
* `skipFullNameProp`, `skipNameProp`, `skipEmailProp` let callers exclude specific steps.
|
|
156
|
+
* Simplified Chinese locale (Windows locale code 2052) has spaces stripped from the assembled name.
|
|
157
|
+
* Multiple consecutive spaces are collapsed to a single space.
|
|
158
|
+
*/
|
|
69
159
|
export declare const getRecordFullName: (user: Record<string, any>, settings?: {
|
|
70
160
|
skipFullNameProp?: boolean;
|
|
71
161
|
skipNameProp?: boolean;
|
|
72
162
|
skipEmailProp?: boolean;
|
|
73
163
|
}) => string;
|
|
164
|
+
/**
|
|
165
|
+
* Returns a formatted email address string for a record that has a valid `email` field.
|
|
166
|
+
* Format: `"Full Name <email@example.com>"`, or just `"email@example.com"` when
|
|
167
|
+
* `emailOnly` is true or no display name is available.
|
|
168
|
+
* Returns `undefined` when the record has no valid email.
|
|
169
|
+
*/
|
|
74
170
|
export declare const getRecordEmailAddress: (record: Record<string, any>, emailOnly?: boolean) => string | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Builds an Open Graph / page metadata object for a record, suitable for `<head>` tags.
|
|
173
|
+
* Returns `{ id, title, description, type: "article", image? }`.
|
|
174
|
+
* Title is derived from `getRecordDisplay` (or `getRecordAbstract` when display is empty),
|
|
175
|
+
* optionally prefixed with `settings.siteName`.
|
|
176
|
+
*/
|
|
75
177
|
export declare const getRecordPageMetadata: (record: Record<string, any>, settings?: {
|
|
76
178
|
siteName?: string;
|
|
77
179
|
}) => Record<string, any>;
|
|
180
|
+
/**
|
|
181
|
+
* Computes the current slug via `getRecordSlug` and ensures it is present in both
|
|
182
|
+
* `record.slug` (current) and `record.slugs` (historical list, deduplicated).
|
|
183
|
+
* Call this before persisting a record to keep slug history intact for redirects.
|
|
184
|
+
*/
|
|
78
185
|
export declare const applyRecordSlug: (record: Record<string, any>) => Record<string, any>;
|
|
186
|
+
/**
|
|
187
|
+
* Derives a URL slug for a record.
|
|
188
|
+
* Uses `record.customSlug` when set; otherwise derives from `getRecordDisplay`.
|
|
189
|
+
* The slug is truncated to 128 characters and suffixed with the second GUID segment
|
|
190
|
+
* of the record ID (e.g. `"my-post-e29b"`) to guarantee global uniqueness.
|
|
191
|
+
* Returns `undefined` when the record has no `id`.
|
|
192
|
+
*/
|
|
79
193
|
export declare const getRecordSlug: (record: Record<string, any>) => string | undefined;
|
|
80
194
|
export type TRecordFilePath = {
|
|
81
195
|
solutionId: string;
|
|
@@ -84,9 +198,33 @@ export type TRecordFilePath = {
|
|
|
84
198
|
entityName: string;
|
|
85
199
|
fieldName?: string;
|
|
86
200
|
};
|
|
201
|
+
/**
|
|
202
|
+
* Builds the storage path for a file attached to a record.
|
|
203
|
+
* Format: `"{solutionId}/{organizationId}/{entityName}/{recordId}/{fieldName}"`.
|
|
204
|
+
* `fieldName` defaults to `"file"` when not provided.
|
|
205
|
+
*/
|
|
87
206
|
export declare const getRecordFilePath: (props: TRecordFilePath) => string;
|
|
207
|
+
/**
|
|
208
|
+
* Extracts an `IContext` from a record that carries context fields directly
|
|
209
|
+
* (e.g. an API request body that has been enriched with caller context).
|
|
210
|
+
* Picks `solutionId`, `domain`, `sourceIp`, `userId`, `organizationId`,
|
|
211
|
+
* `user`, `organization`, and `solution`.
|
|
212
|
+
*/
|
|
88
213
|
export declare const getContextFromRecord: (record: Record<string, any>) => IContext;
|
|
214
|
+
/**
|
|
215
|
+
* Returns true when a record is marked global but belongs to a different organization
|
|
216
|
+
* than the one in the current context. Used to identify marketplace/shared content.
|
|
217
|
+
*/
|
|
89
218
|
export declare const fromOtherOrganization: (context: IContext, record: Record<string, any>) => boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Returns true when the record's ID appears in the current user's favorites list
|
|
221
|
+
* for the record's entity type (`context.user.favorites[entityName]`).
|
|
222
|
+
*/
|
|
90
223
|
export declare const isFavorite: (context: IContext, record: Record<string, any>) => boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Returns true when a record is global and its owning organization differs from the
|
|
226
|
+
* current context's organization. Equivalent to `fromOtherOrganization` but compares
|
|
227
|
+
* against `context.organization.id` instead of `context.organizationId`.
|
|
228
|
+
*/
|
|
91
229
|
export declare const isFromMarketplace: (context: Record<string, any>, record: Record<string, any>) => boolean;
|
|
92
230
|
//# sourceMappingURL=record.d.ts.map
|
package/dist/record.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,wBA6BjE,CAAC;AAEF,MAAM,WAAW,mBAAoB,SAAQ,QAAQ;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,GAAI,SAAS,mBAAmB,KAAG,OAkB5D,
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,wBA6BjE,CAAC;AAEF,MAAM,WAAW,mBAAoB,SAAQ,QAAQ;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,mBAAmB,KAAG,OAkB5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GACxC,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,gBAAgB,MAAM,EAAE,WAS3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAC9B,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,gBAAgB,OAAO,KACxB,MAOF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,MAAM,EAAE,aAAa,MAAM,KAAG,MAIzE,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB,GACzB,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW;IACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,KACF,MAAM,GAAG,SAkFX,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAC1B,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW;IACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B,KACF,MAqCF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GACxC,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,gBAAgB,MAAM,EAAE,WAS3B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GACzB,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW;IACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC,KACF,MAAM,GAAG,SA4CX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,MAAM,KAAG,MAoB9E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAM5D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC1B,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,WAAW;IACP,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,KACF,MA2BF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAC9B,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,OAAO,KACpB,MAAM,GAAG,SAWX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAC9B,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,WAAW;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,wBA0BnC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAU/E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAAM,GAAG,SAapE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,eAAe,KAAG,MAI1D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,QAalE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,QAAQ,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAEtF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,QAAQ,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAG3E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC1B,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC5B,OAEF,CAAC"}
|
package/dist/record.js
CHANGED
|
@@ -21,14 +21,21 @@ exports.isFromMarketplace = exports.isFavorite = exports.fromOtherOrganization =
|
|
|
21
21
|
const lodash_1 = require("lodash");
|
|
22
22
|
const core_1 = require("./core");
|
|
23
23
|
const slug_1 = require("./slug");
|
|
24
|
+
/**
|
|
25
|
+
* Strips server-managed and identity fields from a record so it can be submitted as a
|
|
26
|
+
* new create payload. Removes audit timestamps, CosmosDB system properties (`_rid`,
|
|
27
|
+
* `_self`, etc.), computed fields (`slug`, `searchDisplay`, `display`), and platform
|
|
28
|
+
* fields (`stateCode`, `statusCode`, `organizationId`, `solutionId`, `partitionKey`).
|
|
29
|
+
* Assigns a fresh GUID as `id`.
|
|
30
|
+
*/
|
|
24
31
|
const convertRecordForCreate = (record) => {
|
|
25
32
|
const newRecord = (0, lodash_1.cloneDeep)(record);
|
|
26
33
|
delete newRecord.createdBy;
|
|
27
|
-
delete newRecord.
|
|
34
|
+
delete newRecord.createdAt;
|
|
28
35
|
delete newRecord.ownedBy;
|
|
29
|
-
delete newRecord.
|
|
36
|
+
delete newRecord.ownedAt;
|
|
30
37
|
delete newRecord.modifiedBy;
|
|
31
|
-
delete newRecord.
|
|
38
|
+
delete newRecord.modifiedAt;
|
|
32
39
|
delete newRecord["_rid"];
|
|
33
40
|
delete newRecord["_self"];
|
|
34
41
|
delete newRecord["_etag"];
|
|
@@ -52,6 +59,11 @@ const convertRecordForCreate = (record) => {
|
|
|
52
59
|
return newRecord;
|
|
53
60
|
};
|
|
54
61
|
exports.convertRecordForCreate = convertRecordForCreate;
|
|
62
|
+
/**
|
|
63
|
+
* Creates a minimal valid `IRecord` shell with a new GUID and audit fields populated
|
|
64
|
+
* from the provided context. All timestamps are set to the current moment.
|
|
65
|
+
* `partitionKey` is set to `organizationId` (CosmosDB convention).
|
|
66
|
+
*/
|
|
55
67
|
const getBaseRecord = (context) => {
|
|
56
68
|
const { userId, organizationId, solutionId, entityName, entityType } = context;
|
|
57
69
|
return {
|
|
@@ -59,11 +71,11 @@ const getBaseRecord = (context) => {
|
|
|
59
71
|
entityName,
|
|
60
72
|
entityType,
|
|
61
73
|
createdBy: userId,
|
|
62
|
-
|
|
74
|
+
createdAt: (0, core_1.getTimestamp)(),
|
|
63
75
|
ownedBy: userId,
|
|
64
|
-
|
|
76
|
+
ownedAt: (0, core_1.getTimestamp)(),
|
|
65
77
|
modifiedBy: userId,
|
|
66
|
-
|
|
78
|
+
modifiedAt: (0, core_1.getTimestamp)(),
|
|
67
79
|
stateCode: 0,
|
|
68
80
|
statusCode: 0,
|
|
69
81
|
organizationId,
|
|
@@ -72,6 +84,10 @@ const getBaseRecord = (context) => {
|
|
|
72
84
|
};
|
|
73
85
|
};
|
|
74
86
|
exports.getBaseRecord = getBaseRecord;
|
|
87
|
+
/**
|
|
88
|
+
* Returns the first non-empty string value found by iterating `displayFields` in order.
|
|
89
|
+
* Used internally by `getRecordDisplay` when an entity defines explicit display field names.
|
|
90
|
+
*/
|
|
75
91
|
const getRecordDisplayByDisplayFields = (record, displayFields) => {
|
|
76
92
|
let result = "";
|
|
77
93
|
if (displayFields && (0, lodash_1.isArray)(displayFields) && !(0, core_1.isNonEmptyString)(result)) {
|
|
@@ -82,24 +98,47 @@ const getRecordDisplayByDisplayFields = (record, displayFields) => {
|
|
|
82
98
|
return result;
|
|
83
99
|
};
|
|
84
100
|
exports.getRecordDisplayByDisplayFields = getRecordDisplayByDisplayFields;
|
|
101
|
+
/**
|
|
102
|
+
* Returns a folder path string derived from a record's `entityName` and `entityType`.
|
|
103
|
+
* Format: `"entityName/entityType"` or just `"entityName"` when `entityNameOnly` is true
|
|
104
|
+
* or when `entityType` is absent. Returns `"Unknown"` when both are empty.
|
|
105
|
+
*/
|
|
85
106
|
const getRecordEntityFolder = (data, entityNameOnly) => {
|
|
86
107
|
let entityFolder = (0, core_1.isNonEmptyString)(data.entityType) && !entityNameOnly
|
|
87
108
|
? `${data.entityName ?? ""}/${data.entityType}`
|
|
88
|
-
: data.entityName ?? "";
|
|
109
|
+
: (data.entityName ?? "");
|
|
89
110
|
if (entityFolder.length == 0)
|
|
90
111
|
entityFolder = "Unknown";
|
|
91
112
|
return entityFolder;
|
|
92
113
|
};
|
|
93
114
|
exports.getRecordEntityFolder = getRecordEntityFolder;
|
|
115
|
+
/**
|
|
116
|
+
* Builds a storage folder path from explicit `entityName` and optional `entityType` strings
|
|
117
|
+
* (rather than reading from a record object). Returns `"Unknown"` when `entityName` is empty.
|
|
118
|
+
*/
|
|
94
119
|
const getEntityFolder = (entityName, entityType) => {
|
|
95
|
-
let entityFolder = (0, core_1.isNonEmptyString)(entityType)
|
|
96
|
-
? `${entityName}/${entityType}`
|
|
97
|
-
: entityName;
|
|
120
|
+
let entityFolder = (0, core_1.isNonEmptyString)(entityType) ? `${entityName}/${entityType}` : entityName;
|
|
98
121
|
if (entityFolder.length == 0)
|
|
99
122
|
entityFolder = "Unknown";
|
|
100
123
|
return entityFolder;
|
|
101
124
|
};
|
|
102
125
|
exports.getEntityFolder = getEntityFolder;
|
|
126
|
+
/**
|
|
127
|
+
* Resolves the best human-readable display label for a record.
|
|
128
|
+
*
|
|
129
|
+
* Resolution priority:
|
|
130
|
+
* 1. Search highlight title (`_ui.highlight.title`)
|
|
131
|
+
* 2. `searchDisplay` (when `includeSearchDisplay` is true)
|
|
132
|
+
* 3. Entity `displayFields` (first non-empty field)
|
|
133
|
+
* 4. `firstName + lastName` full name
|
|
134
|
+
* 5. `displayValue`
|
|
135
|
+
* 6. `number – title` / `number – name` / `number – subject`
|
|
136
|
+
* 7. `display`, `text`, `symbol`, `code`
|
|
137
|
+
*
|
|
138
|
+
* The result is cleaned (normalizes whitespace and punctuation spacing) and optionally
|
|
139
|
+
* truncated to `maxLength` characters. Returns the record `id` when `allowUseRecordId`
|
|
140
|
+
* is true and no other value could be resolved.
|
|
141
|
+
*/
|
|
103
142
|
const getRecordDisplay = (record, settings) => {
|
|
104
143
|
if (!(0, core_1.isObject)(record))
|
|
105
144
|
return "";
|
|
@@ -115,15 +154,12 @@ const getRecordDisplay = (record, settings) => {
|
|
|
115
154
|
if (includeSearchDisplay && !(0, core_1.isNonEmptyString)(result, true)) {
|
|
116
155
|
result = record.searchDisplay;
|
|
117
156
|
}
|
|
118
|
-
if (displayFields &&
|
|
119
|
-
(0, lodash_1.isArray)(displayFields) &&
|
|
120
|
-
!(0, core_1.isNonEmptyString)(result, true)) {
|
|
157
|
+
if (displayFields && (0, lodash_1.isArray)(displayFields) && !(0, core_1.isNonEmptyString)(result, true)) {
|
|
121
158
|
result = (0, exports.getRecordDisplayByDisplayFields)(record, displayFields);
|
|
122
159
|
}
|
|
123
160
|
if (!(0, core_1.isNonEmptyString)(result, true))
|
|
124
161
|
result = (0, exports.getRecordFullName)(record);
|
|
125
|
-
if (!(0, core_1.isNonEmptyString)(result, true) &&
|
|
126
|
-
(0, core_1.isNonEmptyString)(record.displayValue, true)) {
|
|
162
|
+
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.displayValue, true)) {
|
|
127
163
|
result = record.displayValue;
|
|
128
164
|
}
|
|
129
165
|
const number = !(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.number, true)
|
|
@@ -135,8 +171,7 @@ const getRecordDisplay = (record, settings) => {
|
|
|
135
171
|
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.name, true)) {
|
|
136
172
|
result = `${number}${record.name}`;
|
|
137
173
|
}
|
|
138
|
-
if (!(0, core_1.isNonEmptyString)(result, true) &&
|
|
139
|
-
(0, core_1.isNonEmptyString)(record.subject, true)) {
|
|
174
|
+
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.subject, true)) {
|
|
140
175
|
result = `${number}${record.subject}`;
|
|
141
176
|
}
|
|
142
177
|
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.display, true)) {
|
|
@@ -145,8 +180,7 @@ const getRecordDisplay = (record, settings) => {
|
|
|
145
180
|
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.text, true)) {
|
|
146
181
|
result = record.text;
|
|
147
182
|
}
|
|
148
|
-
if (!(0, core_1.isNonEmptyString)(result, true) &&
|
|
149
|
-
(0, core_1.isNonEmptyString)(record.symbol, true)) {
|
|
183
|
+
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.symbol, true)) {
|
|
150
184
|
result = record.symbol;
|
|
151
185
|
}
|
|
152
186
|
if (!(0, core_1.isNonEmptyString)(result, true) && (0, core_1.isNonEmptyString)(record.code, true)) {
|
|
@@ -167,19 +201,26 @@ const getRecordDisplay = (record, settings) => {
|
|
|
167
201
|
if ((0, lodash_1.isNumber)(maxLength) && result.length > maxLength) {
|
|
168
202
|
result = `${result.substring(0, maxLength)} ...`;
|
|
169
203
|
}
|
|
170
|
-
return (((0, core_1.isNonEmptyString)(result, true)
|
|
171
|
-
?
|
|
172
|
-
: allowUseRecordId
|
|
173
|
-
? record.id
|
|
174
|
-
: "") ?? (settings?.emptyReturnUndefined ? undefined : ""));
|
|
204
|
+
return (((0, core_1.isNonEmptyString)(result, true) ? result : allowUseRecordId ? record.id : "") ??
|
|
205
|
+
(settings?.emptyReturnUndefined ? undefined : ""));
|
|
175
206
|
};
|
|
176
207
|
exports.getRecordDisplay = getRecordDisplay;
|
|
208
|
+
/**
|
|
209
|
+
* Resolves the best short abstract/description text for a record.
|
|
210
|
+
*
|
|
211
|
+
* Resolution priority:
|
|
212
|
+
* 1. Search highlight (`highlight.searchContent[0]`)
|
|
213
|
+
* 2. `summary`, `description`, `abstract`
|
|
214
|
+
* 3. `searchContent` (only when `settings.includeContent` is true)
|
|
215
|
+
*
|
|
216
|
+
* Whitespace and punctuation are normalized before returning.
|
|
217
|
+
* Truncates to `settings.maxLength` characters when provided.
|
|
218
|
+
*/
|
|
177
219
|
const getRecordAbstract = (record, settings) => {
|
|
178
220
|
if (!(0, core_1.isObject)(record))
|
|
179
221
|
return "";
|
|
180
222
|
let result = "";
|
|
181
|
-
if ((0, lodash_1.isArray)(record?.highlight?.searchContent) &&
|
|
182
|
-
record?.highlight?.searchContent?.length > 0) {
|
|
223
|
+
if ((0, lodash_1.isArray)(record?.highlight?.searchContent) && record?.highlight?.searchContent?.length > 0) {
|
|
183
224
|
result = record.highlight.searchContent[0];
|
|
184
225
|
}
|
|
185
226
|
if (!(0, core_1.isNonEmptyString)(result) && (0, core_1.isNonEmptyString)(record.summary))
|
|
@@ -205,14 +246,16 @@ const getRecordAbstract = (record, settings) => {
|
|
|
205
246
|
.replace(/;/g, "; ")
|
|
206
247
|
.replace(new RegExp(`( ){2,}`, "g"), " ")
|
|
207
248
|
.trim();
|
|
208
|
-
if (settings &&
|
|
209
|
-
(0, lodash_1.isNumber)(settings?.maxLength) &&
|
|
210
|
-
result.length > settings?.maxLength) {
|
|
249
|
+
if (settings && (0, lodash_1.isNumber)(settings?.maxLength) && result.length > settings?.maxLength) {
|
|
211
250
|
result = `${result.substring(0, settings?.maxLength)} ...`;
|
|
212
251
|
}
|
|
213
252
|
return result;
|
|
214
253
|
};
|
|
215
254
|
exports.getRecordAbstract = getRecordAbstract;
|
|
255
|
+
/**
|
|
256
|
+
* Returns the first non-empty string value found by iterating `contentFields` in order.
|
|
257
|
+
* Used internally by `getRecordContent` when an entity defines explicit content field names.
|
|
258
|
+
*/
|
|
216
259
|
const getRecordContentByContentFields = (record, contentFields) => {
|
|
217
260
|
let result = "";
|
|
218
261
|
if (contentFields && (0, lodash_1.isArray)(contentFields) && !(0, core_1.isNonEmptyString)(result)) {
|
|
@@ -223,6 +266,16 @@ const getRecordContentByContentFields = (record, contentFields) => {
|
|
|
223
266
|
return result;
|
|
224
267
|
};
|
|
225
268
|
exports.getRecordContentByContentFields = getRecordContentByContentFields;
|
|
269
|
+
/**
|
|
270
|
+
* Resolves the main body content for a record, suitable for indexing or display.
|
|
271
|
+
*
|
|
272
|
+
* Resolution priority:
|
|
273
|
+
* 1. Search highlight (`_ui.highlight.content`)
|
|
274
|
+
* 2. `searchContent` (when `includeSearchDisplay` is true)
|
|
275
|
+
* 3. Entity/settings `contentFields` (defaults to description, note, detail, content, …)
|
|
276
|
+
*
|
|
277
|
+
* Truncates to `maxLength` when provided.
|
|
278
|
+
*/
|
|
226
279
|
const getRecordContent = (record, settings) => {
|
|
227
280
|
if (!(0, core_1.isObject)(record))
|
|
228
281
|
return "";
|
|
@@ -251,14 +304,10 @@ const getRecordContent = (record, settings) => {
|
|
|
251
304
|
if (includeSearchDisplay && !(0, core_1.isNonEmptyString)(result, true)) {
|
|
252
305
|
result = record.searchContent;
|
|
253
306
|
}
|
|
254
|
-
if (contentFields &&
|
|
255
|
-
(0, lodash_1.isArray)(contentFields) &&
|
|
256
|
-
!(0, core_1.isNonEmptyString)(result, true)) {
|
|
307
|
+
if (contentFields && (0, lodash_1.isArray)(contentFields) && !(0, core_1.isNonEmptyString)(result, true)) {
|
|
257
308
|
result = (0, exports.getRecordContentByContentFields)(record, contentFields);
|
|
258
309
|
}
|
|
259
|
-
if ((0, lodash_1.isNumber)(maxLength) &&
|
|
260
|
-
(0, core_1.isNonEmptyString)(result, true) &&
|
|
261
|
-
result.length > maxLength) {
|
|
310
|
+
if ((0, lodash_1.isNumber)(maxLength) && (0, core_1.isNonEmptyString)(result, true) && result.length > maxLength) {
|
|
262
311
|
result = `${result.substring(0, maxLength)} ...`;
|
|
263
312
|
}
|
|
264
313
|
return (0, core_1.isNonEmptyString)(result, true)
|
|
@@ -268,37 +317,34 @@ const getRecordContent = (record, settings) => {
|
|
|
268
317
|
: "";
|
|
269
318
|
};
|
|
270
319
|
exports.getRecordContent = getRecordContent;
|
|
320
|
+
/**
|
|
321
|
+
* Formats a complete postal address from prefixed address fields on a record
|
|
322
|
+
* (e.g. `prefix = "billing"` reads `billingLine1`, `billingCity`, `billingState`, …).
|
|
323
|
+
* Returns `""` when the record does not contain the minimum required fields
|
|
324
|
+
* (city + state + country, or postalCode + country).
|
|
325
|
+
*/
|
|
271
326
|
const getRecordAddress = (record, prefix) => {
|
|
272
327
|
if (!(0, core_1.isObject)(record))
|
|
273
328
|
return "";
|
|
274
|
-
const line1 = (0, core_1.isNonEmptyString)(record[`${prefix}Line1`])
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const line2 = (0, core_1.isNonEmptyString)(record[`${prefix}Line2`])
|
|
278
|
-
? record[`${prefix}Line2`]
|
|
279
|
-
: "";
|
|
280
|
-
const city = (0, core_1.isNonEmptyString)(record[`${prefix}City`])
|
|
281
|
-
? record[`${prefix}City`]
|
|
282
|
-
: "";
|
|
329
|
+
const line1 = (0, core_1.isNonEmptyString)(record[`${prefix}Line1`]) ? record[`${prefix}Line1`] : "";
|
|
330
|
+
const line2 = (0, core_1.isNonEmptyString)(record[`${prefix}Line2`]) ? record[`${prefix}Line2`] : "";
|
|
331
|
+
const city = (0, core_1.isNonEmptyString)(record[`${prefix}City`]) ? record[`${prefix}City`] : "";
|
|
283
332
|
const postalCode = (0, core_1.isNonEmptyString)(record[`${prefix}PostalCode`])
|
|
284
333
|
? record[`${prefix}PostalCode`]
|
|
285
334
|
: "";
|
|
286
|
-
const state = (0, core_1.isNonEmptyString)(record[`${prefix}State`])
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const country = (0, core_1.isNonEmptyString)(record[`${prefix}Country`])
|
|
290
|
-
? record[`${prefix}Country`]
|
|
291
|
-
: "";
|
|
292
|
-
if ((line1.length > 0 &&
|
|
293
|
-
city.length > 0 &&
|
|
294
|
-
state.length > 0 &&
|
|
295
|
-
country.length > 0) ||
|
|
335
|
+
const state = (0, core_1.isNonEmptyString)(record[`${prefix}State`]) ? record[`${prefix}State`] : "";
|
|
336
|
+
const country = (0, core_1.isNonEmptyString)(record[`${prefix}Country`]) ? record[`${prefix}Country`] : "";
|
|
337
|
+
if ((line1.length > 0 && city.length > 0 && state.length > 0 && country.length > 0) ||
|
|
296
338
|
(postalCode.length > 0 && country.length > 0)) {
|
|
297
339
|
return `${line1} ${line2},${city},${state},${postalCode},${country}`;
|
|
298
340
|
}
|
|
299
341
|
return "";
|
|
300
342
|
};
|
|
301
343
|
exports.getRecordAddress = getRecordAddress;
|
|
344
|
+
/**
|
|
345
|
+
* Returns the primary media URL for a record, trying `media`, `photoUrl`, and
|
|
346
|
+
* `source.photoUrl` in that order. Returns `""` when none are set.
|
|
347
|
+
*/
|
|
302
348
|
const getRecordMedia = (record) => {
|
|
303
349
|
if (!(0, core_1.isObject)(record))
|
|
304
350
|
return "";
|
|
@@ -311,21 +357,23 @@ const getRecordMedia = (record) => {
|
|
|
311
357
|
return "";
|
|
312
358
|
};
|
|
313
359
|
exports.getRecordMedia = getRecordMedia;
|
|
360
|
+
/**
|
|
361
|
+
* Constructs a display name for a user-like record.
|
|
362
|
+
*
|
|
363
|
+
* Resolution order: `fullName` → `firstName + lastName` → `name` → `email`.
|
|
364
|
+
* `skipFullNameProp`, `skipNameProp`, `skipEmailProp` let callers exclude specific steps.
|
|
365
|
+
* Simplified Chinese locale (Windows locale code 2052) has spaces stripped from the assembled name.
|
|
366
|
+
* Multiple consecutive spaces are collapsed to a single space.
|
|
367
|
+
*/
|
|
314
368
|
const getRecordFullName = (user, settings) => {
|
|
315
369
|
const { skipFullNameProp, skipNameProp, skipEmailProp } = settings ?? {};
|
|
316
370
|
if (!(0, core_1.isObject)(user))
|
|
317
371
|
return "";
|
|
318
372
|
const email = (0, core_1.isNonEmptyString)(user.email) ? user.email.trim() : "";
|
|
319
373
|
const name = (0, core_1.isNonEmptyString)(user.name) ? user.name.trim() : "";
|
|
320
|
-
let fullName = (0, core_1.isNonEmptyString)(user.fullName) && !skipFullNameProp
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const firstName = (0, core_1.isNonEmptyString)(user.firstName)
|
|
324
|
-
? user.firstName.trim()
|
|
325
|
-
: "";
|
|
326
|
-
const lastName = (0, core_1.isNonEmptyString)(user.lastName)
|
|
327
|
-
? user.lastName.trim()
|
|
328
|
-
: "";
|
|
374
|
+
let fullName = (0, core_1.isNonEmptyString)(user.fullName) && !skipFullNameProp ? user.fullName.trim() : "";
|
|
375
|
+
const firstName = (0, core_1.isNonEmptyString)(user.firstName) ? user.firstName.trim() : "";
|
|
376
|
+
const lastName = (0, core_1.isNonEmptyString)(user.lastName) ? user.lastName.trim() : "";
|
|
329
377
|
if (fullName.length == 0 ||
|
|
330
378
|
(firstName.length > 0 && lastName.length > 0) ||
|
|
331
379
|
(fullName.length > 0 && fullName == email)) {
|
|
@@ -341,6 +389,12 @@ const getRecordFullName = (user, settings) => {
|
|
|
341
389
|
return fullName;
|
|
342
390
|
};
|
|
343
391
|
exports.getRecordFullName = getRecordFullName;
|
|
392
|
+
/**
|
|
393
|
+
* Returns a formatted email address string for a record that has a valid `email` field.
|
|
394
|
+
* Format: `"Full Name <email@example.com>"`, or just `"email@example.com"` when
|
|
395
|
+
* `emailOnly` is true or no display name is available.
|
|
396
|
+
* Returns `undefined` when the record has no valid email.
|
|
397
|
+
*/
|
|
344
398
|
const getRecordEmailAddress = (record, emailOnly) => {
|
|
345
399
|
if ((0, core_1.isObject)(record) && (0, core_1.isEmail)(record.email)) {
|
|
346
400
|
const fullName = (0, exports.getRecordFullName)(record);
|
|
@@ -354,6 +408,12 @@ const getRecordEmailAddress = (record, emailOnly) => {
|
|
|
354
408
|
return undefined;
|
|
355
409
|
};
|
|
356
410
|
exports.getRecordEmailAddress = getRecordEmailAddress;
|
|
411
|
+
/**
|
|
412
|
+
* Builds an Open Graph / page metadata object for a record, suitable for `<head>` tags.
|
|
413
|
+
* Returns `{ id, title, description, type: "article", image? }`.
|
|
414
|
+
* Title is derived from `getRecordDisplay` (or `getRecordAbstract` when display is empty),
|
|
415
|
+
* optionally prefixed with `settings.siteName`.
|
|
416
|
+
*/
|
|
357
417
|
const getRecordPageMetadata = (record, settings) => {
|
|
358
418
|
const result = {};
|
|
359
419
|
const recordDisplay = (0, exports.getRecordDisplay)(record);
|
|
@@ -380,6 +440,11 @@ const getRecordPageMetadata = (record, settings) => {
|
|
|
380
440
|
return result;
|
|
381
441
|
};
|
|
382
442
|
exports.getRecordPageMetadata = getRecordPageMetadata;
|
|
443
|
+
/**
|
|
444
|
+
* Computes the current slug via `getRecordSlug` and ensures it is present in both
|
|
445
|
+
* `record.slug` (current) and `record.slugs` (historical list, deduplicated).
|
|
446
|
+
* Call this before persisting a record to keep slug history intact for redirects.
|
|
447
|
+
*/
|
|
383
448
|
const applyRecordSlug = (record) => {
|
|
384
449
|
const curSlug = (0, exports.getRecordSlug)(record);
|
|
385
450
|
if (curSlug) {
|
|
@@ -393,6 +458,13 @@ const applyRecordSlug = (record) => {
|
|
|
393
458
|
return record;
|
|
394
459
|
};
|
|
395
460
|
exports.applyRecordSlug = applyRecordSlug;
|
|
461
|
+
/**
|
|
462
|
+
* Derives a URL slug for a record.
|
|
463
|
+
* Uses `record.customSlug` when set; otherwise derives from `getRecordDisplay`.
|
|
464
|
+
* The slug is truncated to 128 characters and suffixed with the second GUID segment
|
|
465
|
+
* of the record ID (e.g. `"my-post-e29b"`) to guarantee global uniqueness.
|
|
466
|
+
* Returns `undefined` when the record has no `id`.
|
|
467
|
+
*/
|
|
396
468
|
const getRecordSlug = (record) => {
|
|
397
469
|
if (!record.id)
|
|
398
470
|
return undefined;
|
|
@@ -406,12 +478,23 @@ const getRecordSlug = (record) => {
|
|
|
406
478
|
return curSlug;
|
|
407
479
|
};
|
|
408
480
|
exports.getRecordSlug = getRecordSlug;
|
|
481
|
+
/**
|
|
482
|
+
* Builds the storage path for a file attached to a record.
|
|
483
|
+
* Format: `"{solutionId}/{organizationId}/{entityName}/{recordId}/{fieldName}"`.
|
|
484
|
+
* `fieldName` defaults to `"file"` when not provided.
|
|
485
|
+
*/
|
|
409
486
|
const getRecordFilePath = (props) => {
|
|
410
487
|
const { solutionId, organizationId, recordId, entityName } = props;
|
|
411
488
|
const fieldName = props.fieldName ?? "file";
|
|
412
489
|
return `${solutionId}/${organizationId}/${entityName}/${recordId}/${fieldName}`;
|
|
413
490
|
};
|
|
414
491
|
exports.getRecordFilePath = getRecordFilePath;
|
|
492
|
+
/**
|
|
493
|
+
* Extracts an `IContext` from a record that carries context fields directly
|
|
494
|
+
* (e.g. an API request body that has been enriched with caller context).
|
|
495
|
+
* Picks `solutionId`, `domain`, `sourceIp`, `userId`, `organizationId`,
|
|
496
|
+
* `user`, `organization`, and `solution`.
|
|
497
|
+
*/
|
|
415
498
|
const getContextFromRecord = (record) => {
|
|
416
499
|
const { solutionId, domain, sourceIp, userId, organizationId, user, organization, solution } = record;
|
|
417
500
|
return {
|
|
@@ -426,17 +509,30 @@ const getContextFromRecord = (record) => {
|
|
|
426
509
|
};
|
|
427
510
|
};
|
|
428
511
|
exports.getContextFromRecord = getContextFromRecord;
|
|
512
|
+
/**
|
|
513
|
+
* Returns true when a record is marked global but belongs to a different organization
|
|
514
|
+
* than the one in the current context. Used to identify marketplace/shared content.
|
|
515
|
+
*/
|
|
429
516
|
const fromOtherOrganization = (context, record) => {
|
|
430
|
-
return
|
|
517
|
+
return record.isGlobal && record.organizationId != context.organizationId;
|
|
431
518
|
};
|
|
432
519
|
exports.fromOtherOrganization = fromOtherOrganization;
|
|
520
|
+
/**
|
|
521
|
+
* Returns true when the record's ID appears in the current user's favorites list
|
|
522
|
+
* for the record's entity type (`context.user.favorites[entityName]`).
|
|
523
|
+
*/
|
|
433
524
|
const isFavorite = (context, record) => {
|
|
434
525
|
const favorites = context.user?.favorites ? context.user?.favorites[record.entityName] : [];
|
|
435
526
|
return favorites.includes(record.id);
|
|
436
527
|
};
|
|
437
528
|
exports.isFavorite = isFavorite;
|
|
529
|
+
/**
|
|
530
|
+
* Returns true when a record is global and its owning organization differs from the
|
|
531
|
+
* current context's organization. Equivalent to `fromOtherOrganization` but compares
|
|
532
|
+
* against `context.organization.id` instead of `context.organizationId`.
|
|
533
|
+
*/
|
|
438
534
|
const isFromMarketplace = (context, record) => {
|
|
439
|
-
return
|
|
535
|
+
return record.isGlobal && record.organizationId != context?.organization?.id;
|
|
440
536
|
};
|
|
441
537
|
exports.isFromMarketplace = isFromMarketplace;
|
|
442
538
|
//# sourceMappingURL=record.js.map
|