@aglyn/aglyn 1.0.0-beta.198 → 1.0.0-beta.200
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/package.json +11 -11
- package/src/lib/app-utils/activity-search.d.ts +39 -0
- package/src/lib/app-utils/activity-search.js +85 -0
- package/src/lib/app-utils/activity-search.js.map +1 -0
- package/src/lib/app-utils/admin-audit-index.d.ts +104 -0
- package/src/lib/app-utils/admin-audit-index.js +177 -0
- package/src/lib/app-utils/admin-audit-index.js.map +1 -0
- package/src/lib/app-utils/artifact-list-keys.d.ts +51 -0
- package/src/lib/app-utils/artifact-list-keys.js +144 -0
- package/src/lib/app-utils/artifact-list-keys.js.map +1 -0
- package/src/lib/app-utils/content-query-fields.d.ts +69 -0
- package/src/lib/app-utils/content-query-fields.js +79 -0
- package/src/lib/app-utils/content-query-fields.js.map +1 -0
- package/src/lib/app-utils/crm.d.ts +151 -1
- package/src/lib/app-utils/crm.js +388 -1
- package/src/lib/app-utils/crm.js.map +1 -1
- package/src/lib/app-utils/dataset-models.d.ts +75 -24
- package/src/lib/app-utils/dataset-models.js +107 -40
- package/src/lib/app-utils/dataset-models.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +40 -40
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/email-search.d.ts +36 -0
- package/src/lib/app-utils/email-search.js +53 -0
- package/src/lib/app-utils/email-search.js.map +1 -0
- package/src/lib/app-utils/forms.d.ts +83 -3
- package/src/lib/app-utils/forms.js +67 -0
- package/src/lib/app-utils/forms.js.map +1 -1
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +7 -6
- package/src/lib/app-utils/marketplace-listing-visibility.js +12 -10
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -1
- package/src/lib/app-utils/media-embedded-fields.d.ts +471 -0
- package/src/lib/app-utils/media-embedded-fields.js +619 -0
- package/src/lib/app-utils/media-embedded-fields.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.d.ts +160 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.js +1267 -0
- package/src/lib/app-utils/media-embedded-metadata/exif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.d.ts +44 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.js +134 -0
- package/src/lib/app-utils/media-embedded-metadata/gif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.d.ts +23 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.js +354 -0
- package/src/lib/app-utils/media-embedded-metadata/heif.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.d.ts +22 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.js +85 -0
- package/src/lib/app-utils/media-embedded-metadata/icc.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.d.ts +145 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.js +200 -0
- package/src/lib/app-utils/media-embedded-metadata/image-blocks.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/index.d.ts +93 -0
- package/src/lib/app-utils/media-embedded-metadata/index.js +744 -0
- package/src/lib/app-utils/media-embedded-metadata/index.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.d.ts +59 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.js +529 -0
- package/src/lib/app-utils/media-embedded-metadata/iptc.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.d.ts +43 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.js +456 -0
- package/src/lib/app-utils/media-embedded-metadata/jpeg.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.d.ts +37 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.js +621 -0
- package/src/lib/app-utils/media-embedded-metadata/mp4.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.d.ts +131 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.js +1058 -0
- package/src/lib/app-utils/media-embedded-metadata/ooxml.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.d.ts +223 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js +936 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.d.ts +82 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.js +1167 -0
- package/src/lib/app-utils/media-embedded-metadata/pdf.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/png.d.ts +41 -0
- package/src/lib/app-utils/media-embedded-metadata/png.js +512 -0
- package/src/lib/app-utils/media-embedded-metadata/png.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.d.ts +30 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.js +154 -0
- package/src/lib/app-utils/media-embedded-metadata/svg.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.d.ts +40 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.js +158 -0
- package/src/lib/app-utils/media-embedded-metadata/tiff.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/types.d.ts +60 -0
- package/src/lib/app-utils/media-embedded-metadata/types.js +32 -0
- package/src/lib/app-utils/media-embedded-metadata/types.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.d.ts +26 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.js +417 -0
- package/src/lib/app-utils/media-embedded-metadata/webm.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.d.ts +37 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.js +272 -0
- package/src/lib/app-utils/media-embedded-metadata/webp.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.d.ts +231 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.js +598 -0
- package/src/lib/app-utils/media-embedded-metadata/xml.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.d.ts +100 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.js +1475 -0
- package/src/lib/app-utils/media-embedded-metadata/xmp.js.map +1 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.d.ts +93 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.js +531 -0
- package/src/lib/app-utils/media-embedded-metadata/zip.js.map +1 -0
- package/src/lib/app-utils/media-metadata.d.ts +79 -0
- package/src/lib/app-utils/media-metadata.js +74 -0
- package/src/lib/app-utils/media-metadata.js.map +1 -1
- package/src/lib/app-utils/message-search.d.ts +40 -0
- package/src/lib/app-utils/message-search.js +168 -0
- package/src/lib/app-utils/message-search.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +95 -0
- package/src/lib/app-utils/name-search.js +108 -0
- package/src/lib/app-utils/name-search.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +2 -0
- package/src/lib/app-utils/server.js +2 -0
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +11 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/server.d.ts +1 -0
- package/src/server.js +7 -0
- package/src/server.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/aglyn",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.200",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"./package.json": "./package.json"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@aglyn/shared-data-enums": "1.0.0-beta.
|
|
37
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
38
|
-
"@aglyn/shared-data-types": "1.0.0-beta.
|
|
39
|
-
"@aglyn/shared-util-email": "1.0.0-beta.
|
|
40
|
-
"@aglyn/shared-util-first-touch": "1.0.0-beta.
|
|
41
|
-
"@aglyn/shared-util-http": "1.0.0-beta.
|
|
42
|
-
"@aglyn/shared-util-logger": "1.0.0-beta.
|
|
43
|
-
"@aglyn/shared-util-timestamp": "1.0.0-beta.
|
|
44
|
-
"@aglyn/shared-util-tools": "1.0.0-beta.
|
|
45
|
-
"@aglyn/shared-util-vendor": "1.0.0-beta.
|
|
36
|
+
"@aglyn/shared-data-enums": "1.0.0-beta.200",
|
|
37
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.200",
|
|
38
|
+
"@aglyn/shared-data-types": "1.0.0-beta.200",
|
|
39
|
+
"@aglyn/shared-util-email": "1.0.0-beta.200",
|
|
40
|
+
"@aglyn/shared-util-first-touch": "1.0.0-beta.200",
|
|
41
|
+
"@aglyn/shared-util-http": "1.0.0-beta.200",
|
|
42
|
+
"@aglyn/shared-util-logger": "1.0.0-beta.200",
|
|
43
|
+
"@aglyn/shared-util-timestamp": "1.0.0-beta.200",
|
|
44
|
+
"@aglyn/shared-util-tools": "1.0.0-beta.200",
|
|
45
|
+
"@aglyn/shared-util-vendor": "1.0.0-beta.200",
|
|
46
46
|
"@data-driven-forms/react-form-renderer": "^4.2.0",
|
|
47
47
|
"@msgpack/msgpack": "^3.1.3",
|
|
48
48
|
"@types/unist": "^3.0.3",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/** The written field every activity search reads. */
|
|
18
|
+
export declare const ACTIVITY_SEARCH_TOKENS_PATH = "searchTokens";
|
|
19
|
+
/** What an entry's search tokens are derived from; every field may be absent. */
|
|
20
|
+
export interface ActivitySearchSource {
|
|
21
|
+
actorEmail?: unknown;
|
|
22
|
+
apiKeyName?: unknown;
|
|
23
|
+
/** The entry's target as stored — only its `name` is read. */
|
|
24
|
+
target?: {
|
|
25
|
+
name?: unknown;
|
|
26
|
+
} | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* An address as the words a reader might start typing it by: the whole
|
|
30
|
+
* address, its local part, its domain, and each run of letters and digits.
|
|
31
|
+
* Shared by every search that finds a record by an address — the activity
|
|
32
|
+
* logs' actor, and a site account's own address (the Site users list).
|
|
33
|
+
*/
|
|
34
|
+
export declare function addressSearchWords(address: unknown): string[];
|
|
35
|
+
/**
|
|
36
|
+
* The search tokens one activity entry carries. Stamped by every writer as
|
|
37
|
+
* `searchTokens`; see the note at the top of this file for what it promises.
|
|
38
|
+
*/
|
|
39
|
+
export declare function activitySearchTokens(entry: ActivitySearchSource): string[];
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { nameSearchTokens } from "./name-search.js";
|
|
17
|
+
/*
|
|
18
|
+
* WHAT AN ACTIVITY LOG'S SEARCH BOX FINDS (AGL-3321).
|
|
19
|
+
*
|
|
20
|
+
* Every activity log — a site's (`hosts/{hostId}/activity`), an
|
|
21
|
+
* organization's (`orgs/{orgId}/activity`), and the person-centred feeds read
|
|
22
|
+
* across both — searches the same written token array, so the box promises
|
|
23
|
+
* the same thing wherever it appears: a word typed there finds an entry when
|
|
24
|
+
* it is the START of
|
|
25
|
+
*
|
|
26
|
+
* - the address the actor had when the entry was written, of its local
|
|
27
|
+
* part or its domain, or of any run of letters and digits in it —
|
|
28
|
+
* `ada`, `lovelace`, `ada.lovelace@`, `example.com`, `example` all find
|
|
29
|
+
* `ada.lovelace@example.com`;
|
|
30
|
+
* - a word of the API key's name, for an entry an integration wrote;
|
|
31
|
+
* - a word of the name of what changed (`target.name`) — the screen, the
|
|
32
|
+
* member, the workflow.
|
|
33
|
+
*
|
|
34
|
+
* Not the action sentence: it is prose written by forty call sites, some of
|
|
35
|
+
* it three hundred characters of run errors, and every word of it would be
|
|
36
|
+
* an index entry. Action is a Filters field instead.
|
|
37
|
+
*
|
|
38
|
+
* The array is `nameSearchTokens` over those words — the same normalizer the
|
|
39
|
+
* query plan asks with (`nameSearchNormalizers`), so a typed word and a
|
|
40
|
+
* stored token cannot disagree about case, whitespace or prefix length.
|
|
41
|
+
*
|
|
42
|
+
* ⚠️ Every writer stamps it, through `activitySearchTokens`: the site logger
|
|
43
|
+
* in the browser, the two server loggers, the workflow engine's run rows, the
|
|
44
|
+
* inbound-webhook runner, the site importer and the reconstruction backfill.
|
|
45
|
+
* A writer that forgets writes an entry the log still LISTS and that no
|
|
46
|
+
* search can find. The scripts that write or backfill entries use its
|
|
47
|
+
* script-side twin, `tools/scripts/lib/activity-search-tokens.mjs`, held to
|
|
48
|
+
* the same worked examples (`activity-search-tokens.fixtures.json` beside
|
|
49
|
+
* it), which this library's spec asserts too.
|
|
50
|
+
*/ /** The written field every activity search reads. */ export const ACTIVITY_SEARCH_TOKENS_PATH = 'searchTokens';
|
|
51
|
+
const text = (value)=>typeof value === 'string' ? value.trim() : '';
|
|
52
|
+
/**
|
|
53
|
+
* An address as the words a reader might start typing it by: the whole
|
|
54
|
+
* address, its local part, its domain, and each run of letters and digits.
|
|
55
|
+
* Shared by every search that finds a record by an address — the activity
|
|
56
|
+
* logs' actor, and a site account's own address (the Site users list).
|
|
57
|
+
*/ export function addressSearchWords(address) {
|
|
58
|
+
const whole = text(address).toLowerCase();
|
|
59
|
+
if (!whole) return [];
|
|
60
|
+
const at = whole.lastIndexOf('@');
|
|
61
|
+
const halves = at > 0 ? [
|
|
62
|
+
whole.slice(0, at),
|
|
63
|
+
whole.slice(at + 1)
|
|
64
|
+
] : [];
|
|
65
|
+
const runs = whole.split(RegExp("[^\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]+", "u")).filter(Boolean);
|
|
66
|
+
return [
|
|
67
|
+
whole,
|
|
68
|
+
...halves,
|
|
69
|
+
...runs
|
|
70
|
+
].filter(Boolean);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The search tokens one activity entry carries. Stamped by every writer as
|
|
74
|
+
* `searchTokens`; see the note at the top of this file for what it promises.
|
|
75
|
+
*/ export function activitySearchTokens(entry) {
|
|
76
|
+
var _entry_target;
|
|
77
|
+
const words = [
|
|
78
|
+
...addressSearchWords(entry.actorEmail),
|
|
79
|
+
text(entry.apiKeyName),
|
|
80
|
+
text((_entry_target = entry.target) == null ? void 0 : _entry_target.name)
|
|
81
|
+
].filter(Boolean);
|
|
82
|
+
return nameSearchTokens(words.join(' '));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=activity-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/activity-search.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { nameSearchTokens } from './name-search'\n\n/*\n * WHAT AN ACTIVITY LOG'S SEARCH BOX FINDS (AGL-3321).\n *\n * Every activity log — a site's (`hosts/{hostId}/activity`), an\n * organization's (`orgs/{orgId}/activity`), and the person-centred feeds read\n * across both — searches the same written token array, so the box promises\n * the same thing wherever it appears: a word typed there finds an entry when\n * it is the START of\n *\n * - the address the actor had when the entry was written, of its local\n * part or its domain, or of any run of letters and digits in it —\n * `ada`, `lovelace`, `ada.lovelace@`, `example.com`, `example` all find\n * `ada.lovelace@example.com`;\n * - a word of the API key's name, for an entry an integration wrote;\n * - a word of the name of what changed (`target.name`) — the screen, the\n * member, the workflow.\n *\n * Not the action sentence: it is prose written by forty call sites, some of\n * it three hundred characters of run errors, and every word of it would be\n * an index entry. Action is a Filters field instead.\n *\n * The array is `nameSearchTokens` over those words — the same normalizer the\n * query plan asks with (`nameSearchNormalizers`), so a typed word and a\n * stored token cannot disagree about case, whitespace or prefix length.\n *\n * ⚠️ Every writer stamps it, through `activitySearchTokens`: the site logger\n * in the browser, the two server loggers, the workflow engine's run rows, the\n * inbound-webhook runner, the site importer and the reconstruction backfill.\n * A writer that forgets writes an entry the log still LISTS and that no\n * search can find. The scripts that write or backfill entries use its\n * script-side twin, `tools/scripts/lib/activity-search-tokens.mjs`, held to\n * the same worked examples (`activity-search-tokens.fixtures.json` beside\n * it), which this library's spec asserts too.\n */\n\n/** The written field every activity search reads. */\nexport const ACTIVITY_SEARCH_TOKENS_PATH = 'searchTokens'\n\n/** What an entry's search tokens are derived from; every field may be absent. */\nexport interface ActivitySearchSource {\n actorEmail?: unknown\n apiKeyName?: unknown\n /** The entry's target as stored — only its `name` is read. */\n target?: { name?: unknown } | null\n}\n\nconst text = (value: unknown): string =>\n typeof value === 'string' ? value.trim() : ''\n\n/**\n * An address as the words a reader might start typing it by: the whole\n * address, its local part, its domain, and each run of letters and digits.\n * Shared by every search that finds a record by an address — the activity\n * logs' actor, and a site account's own address (the Site users list).\n */\nexport function addressSearchWords(address: unknown): string[] {\n const whole = text(address).toLowerCase()\n if (!whole) return []\n const at = whole.lastIndexOf('@')\n const halves = at > 0 ? [whole.slice(0, at), whole.slice(at + 1)] : []\n const runs = whole.split(/[^\\p{L}\\p{N}]+/u).filter(Boolean)\n return [whole, ...halves, ...runs].filter(Boolean)\n}\n\n/**\n * The search tokens one activity entry carries. Stamped by every writer as\n * `searchTokens`; see the note at the top of this file for what it promises.\n */\nexport function activitySearchTokens(entry: ActivitySearchSource): string[] {\n const words = [\n ...addressSearchWords(entry.actorEmail),\n text(entry.apiKeyName),\n text(entry.target?.name),\n ].filter(Boolean)\n return nameSearchTokens(words.join(' '))\n}\n"],"names":["nameSearchTokens","ACTIVITY_SEARCH_TOKENS_PATH","text","value","trim","addressSearchWords","address","whole","toLowerCase","at","lastIndexOf","halves","slice","runs","split","filter","Boolean","activitySearchTokens","entry","words","actorEmail","apiKeyName","target","name","join"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,gBAAgB,QAAQ,mBAAe;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCC,GAED,mDAAmD,GACnD,OAAO,MAAMC,8BAA8B,eAAc;AAUzD,MAAMC,OAAO,CAACC,QACZ,OAAOA,UAAU,WAAWA,MAAMC,IAAI,KAAK;AAE7C;;;;;CAKC,GACD,OAAO,SAASC,mBAAmBC,OAAgB;IACjD,MAAMC,QAAQL,KAAKI,SAASE,WAAW;IACvC,IAAI,CAACD,OAAO,OAAO,EAAE;IACrB,MAAME,KAAKF,MAAMG,WAAW,CAAC;IAC7B,MAAMC,SAASF,KAAK,IAAI;QAACF,MAAMK,KAAK,CAAC,GAAGH;QAAKF,MAAMK,KAAK,CAACH,KAAK;KAAG,GAAG,EAAE;IACtE,MAAMI,OAAON,MAAMO,KAAK,CAAC,8maAAmBC,MAAM,CAACC;IACnD,OAAO;QAACT;WAAUI;WAAWE;KAAK,CAACE,MAAM,CAACC;AAC5C;AAEA;;;CAGC,GACD,OAAO,SAASC,qBAAqBC,KAA2B;QAIvDA;IAHP,MAAMC,QAAQ;WACTd,mBAAmBa,MAAME,UAAU;QACtClB,KAAKgB,MAAMG,UAAU;QACrBnB,MAAKgB,gBAAAA,MAAMI,MAAM,qBAAZJ,cAAcK,IAAI;KACxB,CAACR,MAAM,CAACC;IACT,OAAOhB,iBAAiBmB,MAAMK,IAAI,CAAC;AACrC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/** The row's group, as the Action group filter asks for it. */
|
|
18
|
+
export declare const ADMIN_AUDIT_GROUP_FIELD = "actionGroup";
|
|
19
|
+
/** Whether the row only looked, as the account page's two tables ask for it. */
|
|
20
|
+
export declare const ADMIN_AUDIT_KIND_FIELD = "kind";
|
|
21
|
+
/** The kind of record acted on, as the Target type filter asks for it. */
|
|
22
|
+
export declare const ADMIN_AUDIT_TARGET_KIND_FIELD = "targetKind";
|
|
23
|
+
/** The site acted on, as the Site filter asks for it. */
|
|
24
|
+
export declare const ADMIN_AUDIT_SITE_FIELD = "targetHostId";
|
|
25
|
+
/** The row's search tokens, as the search asks for one. */
|
|
26
|
+
export declare const ADMIN_AUDIT_SEARCH_FIELD = "searchTokens";
|
|
27
|
+
/**
|
|
28
|
+
* The fields a search reaches, in the order they claim the token budget:
|
|
29
|
+
* what was done, who did it, what it was done to, then why.
|
|
30
|
+
*/
|
|
31
|
+
export declare const ADMIN_AUDIT_SEARCHED_FIELDS: readonly ["action", "actorEmail", "target", "actorUid", "scope", "reason", "note"];
|
|
32
|
+
/**
|
|
33
|
+
* The most tokens one row stores. A free-text note is the only field that
|
|
34
|
+
* can run long, and it is searched last, so it is the one that loses reach
|
|
35
|
+
* past the cap.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ADMIN_AUDIT_SEARCH_TOKEN_LIMIT = 200;
|
|
38
|
+
/** Access looked at data; change altered something or acted on someone. */
|
|
39
|
+
export type AdminAuditKind = 'access' | 'change';
|
|
40
|
+
/**
|
|
41
|
+
* The core actions that only LOOKED.
|
|
42
|
+
*
|
|
43
|
+
* An exception list, not a classification of everything, and the default
|
|
44
|
+
* matters more than the membership: anything absent is a `change`. A change
|
|
45
|
+
* is the louder half of the console's audit card, so an action nobody has
|
|
46
|
+
* classified yet gets the MORE prominent treatment rather than the quieter
|
|
47
|
+
* one. The failure mode of the opposite default is an unclassified
|
|
48
|
+
* impersonation rendering as routine browsing.
|
|
49
|
+
*
|
|
50
|
+
* An export is deliberately NOT here. Data leaving the platform is a
|
|
51
|
+
* high-consequence act even though it mutates nothing, and it belongs beside
|
|
52
|
+
* the impersonations rather than beside the record views.
|
|
53
|
+
*/
|
|
54
|
+
export declare const ADMIN_AUDIT_ACCESS_ACTIONS: readonly string[];
|
|
55
|
+
/** What a row carries that the stamped fields are derived from. */
|
|
56
|
+
export type AdminAuditIndexSource = Partial<Record<(typeof ADMIN_AUDIT_SEARCHED_FIELDS)[number], unknown>>;
|
|
57
|
+
/** The fields the lists query. */
|
|
58
|
+
export interface AdminAuditIndexFields {
|
|
59
|
+
actionGroup: string;
|
|
60
|
+
kind: AdminAuditKind;
|
|
61
|
+
targetKind: string;
|
|
62
|
+
targetHostId: string | null;
|
|
63
|
+
searchTokens: string[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The search tokens for one row.
|
|
67
|
+
*
|
|
68
|
+
* Each value is tokenized twice: as written, so a typed address or code
|
|
69
|
+
* (`jane@acme`, `org.override`) matches from its start, and split at its
|
|
70
|
+
* separators, so a reader finds `org.override` by `override` and an address
|
|
71
|
+
* by its domain.
|
|
72
|
+
*/
|
|
73
|
+
export declare function adminAuditSearchTokens(entry: AdminAuditIndexSource): string[];
|
|
74
|
+
/**
|
|
75
|
+
* The group an action is filed under — the same answer the page's facet
|
|
76
|
+
* offers. Empty for a row with no action.
|
|
77
|
+
*/
|
|
78
|
+
export declare function adminAuditActionGroup(action: unknown): string;
|
|
79
|
+
/**
|
|
80
|
+
* An access when the platform or a plugin declares the action a read — a
|
|
81
|
+
* plugin's staff card opening on an org or an account names its own read
|
|
82
|
+
* actions through its activity group (AGL-2939) — and a change otherwise.
|
|
83
|
+
*/
|
|
84
|
+
export declare function adminAuditKind(action: unknown): AdminAuditKind;
|
|
85
|
+
/**
|
|
86
|
+
* The kind of record acted on: the target's first segment, which for every
|
|
87
|
+
* path-shaped target is its collection (`orgs/{id}` → `orgs`). A target
|
|
88
|
+
* that is an identifier rather than a path (`sso-domains:acme.com`) is its
|
|
89
|
+
* own type up to the first `:`. Empty for a row with no target.
|
|
90
|
+
*/
|
|
91
|
+
export declare function adminAuditTargetKind(target: unknown): string;
|
|
92
|
+
/**
|
|
93
|
+
* The site acted on: the id after a `hosts` segment in the target path —
|
|
94
|
+
* `hosts/{id}` and anything under it, and a site filed under its
|
|
95
|
+
* organization (`orgs/{org}/hosts/{id}`). Null when the act was not on a site.
|
|
96
|
+
*/
|
|
97
|
+
export declare function adminAuditTargetHostId(target: unknown): string | null;
|
|
98
|
+
/** Every stamped field for one row. */
|
|
99
|
+
export declare function adminAuditIndexFields(entry: AdminAuditIndexSource): AdminAuditIndexFields;
|
|
100
|
+
/**
|
|
101
|
+
* The row as it is stored: the entry, with the fields its lists query.
|
|
102
|
+
* Every write to `adminAudit` passes its data through this.
|
|
103
|
+
*/
|
|
104
|
+
export declare function withAdminAuditIndex<Entry extends AdminAuditIndexSource>(entry: Entry): Entry & AdminAuditIndexFields;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { isPluginStaffAuditAccess, pluginStaffAuditActionGroup } from "../plugin-manager/plugin-activity-actions.js";
|
|
18
|
+
import { nameSearchTokens } from "./name-search.js";
|
|
19
|
+
/*
|
|
20
|
+
* WHAT THE STAFF AUDIT LOG IS QUERIED BY, WRITTEN WITH EVERY ROW (AGL-3321).
|
|
21
|
+
*
|
|
22
|
+
* The staff audit page and the audit tables on a staff account's page filter
|
|
23
|
+
* `adminAudit` by fields no writer used to store — the action's group, the
|
|
24
|
+
* kind of thing acted on, the site, whether the act only looked — and search
|
|
25
|
+
* it. All of that used to be answered by reading the log in batches and
|
|
26
|
+
* keeping the rows that matched, and a match read that way stops wherever
|
|
27
|
+
* the batches stop, so an entry past them was reported as not there. On an
|
|
28
|
+
* audit trail that is the one wrong answer that matters.
|
|
29
|
+
*
|
|
30
|
+
* So each is stored on the row as it is written, and the query asks for it:
|
|
31
|
+
*
|
|
32
|
+
* actionGroup the facet's group for the action, answered by the plugin
|
|
33
|
+
* activity registry (`pluginStaffAuditActionGroup`): a
|
|
34
|
+
* registered group by code or by `staffAuditPrefixes`,
|
|
35
|
+
* otherwise the action's leading namespace.
|
|
36
|
+
* kind `access` for an act that only looked (a core read action,
|
|
37
|
+
* or one a plugin declares in `staffAuditAccessActions`),
|
|
38
|
+
* `change` for everything else.
|
|
39
|
+
* targetKind the kind of record acted on: the first segment of the
|
|
40
|
+
* target path (`orgs`, `users`, `hosts`, `lockdowns`).
|
|
41
|
+
* targetHostId the site acted on, when the target is a site or a record
|
|
42
|
+
* under one (`hosts/{id}/…`, `orgs/{org}/hosts/{id}/…`);
|
|
43
|
+
* null otherwise, so "no site" is a value a query can ask for.
|
|
44
|
+
* searchTokens word-prefix tokens (`nameSearchTokens`) of the fields a
|
|
45
|
+
* reviewer searches by, for `array-contains` on one word.
|
|
46
|
+
*
|
|
47
|
+
* Every write goes through `withAdminAuditIndex`, on the server through
|
|
48
|
+
* `addAdminAudit` / `setAdminAudit` / `recordAdminAudit` in
|
|
49
|
+
* `@aglyn/tenant-data-admin`. `apps/console/specs/admin-audit-writes-are-stamped.spec.ts`
|
|
50
|
+
* refuses a write to the collection anywhere else, and
|
|
51
|
+
* `apps/console/specs/admin-audit-action-groups.spec.ts` pins the registry's
|
|
52
|
+
* groups and reads to `tools/scripts/lib/admin-audit-index.fixtures.json`,
|
|
53
|
+
* the mapping `tools/scripts/backfill-admin-audit-index.mjs` restamps old
|
|
54
|
+
* rows with. A plugin adding a code, a prefix or a read action therefore
|
|
55
|
+
* fails CI until the fixture names it, and the backfill is re-run.
|
|
56
|
+
*/ /** The row's group, as the Action group filter asks for it. */ export const ADMIN_AUDIT_GROUP_FIELD = 'actionGroup';
|
|
57
|
+
/** Whether the row only looked, as the account page's two tables ask for it. */ export const ADMIN_AUDIT_KIND_FIELD = 'kind';
|
|
58
|
+
/** The kind of record acted on, as the Target type filter asks for it. */ export const ADMIN_AUDIT_TARGET_KIND_FIELD = 'targetKind';
|
|
59
|
+
/** The site acted on, as the Site filter asks for it. */ export const ADMIN_AUDIT_SITE_FIELD = 'targetHostId';
|
|
60
|
+
/** The row's search tokens, as the search asks for one. */ export const ADMIN_AUDIT_SEARCH_FIELD = 'searchTokens';
|
|
61
|
+
/**
|
|
62
|
+
* The fields a search reaches, in the order they claim the token budget:
|
|
63
|
+
* what was done, who did it, what it was done to, then why.
|
|
64
|
+
*/ export const ADMIN_AUDIT_SEARCHED_FIELDS = [
|
|
65
|
+
'action',
|
|
66
|
+
'actorEmail',
|
|
67
|
+
'target',
|
|
68
|
+
'actorUid',
|
|
69
|
+
'scope',
|
|
70
|
+
'reason',
|
|
71
|
+
'note'
|
|
72
|
+
];
|
|
73
|
+
/**
|
|
74
|
+
* The most tokens one row stores. A free-text note is the only field that
|
|
75
|
+
* can run long, and it is searched last, so it is the one that loses reach
|
|
76
|
+
* past the cap.
|
|
77
|
+
*/ export const ADMIN_AUDIT_SEARCH_TOKEN_LIMIT = 200;
|
|
78
|
+
/**
|
|
79
|
+
* The core actions that only LOOKED.
|
|
80
|
+
*
|
|
81
|
+
* An exception list, not a classification of everything, and the default
|
|
82
|
+
* matters more than the membership: anything absent is a `change`. A change
|
|
83
|
+
* is the louder half of the console's audit card, so an action nobody has
|
|
84
|
+
* classified yet gets the MORE prominent treatment rather than the quieter
|
|
85
|
+
* one. The failure mode of the opposite default is an unclassified
|
|
86
|
+
* impersonation rendering as routine browsing.
|
|
87
|
+
*
|
|
88
|
+
* An export is deliberately NOT here. Data leaving the platform is a
|
|
89
|
+
* high-consequence act even though it mutates nothing, and it belongs beside
|
|
90
|
+
* the impersonations rather than beside the record views.
|
|
91
|
+
*/ export const ADMIN_AUDIT_ACCESS_ACTIONS = [
|
|
92
|
+
'email.message-viewed',
|
|
93
|
+
// The acquisition card (AGL-3289): where an account or a workspace came
|
|
94
|
+
// from, cross-checked against the sales workspace's people. Read only.
|
|
95
|
+
'user.acquisition-viewed',
|
|
96
|
+
'org.acquisition-viewed'
|
|
97
|
+
];
|
|
98
|
+
/** Separators inside a value: an address's `@` and `.`, a path's `/`, a code's `.`. */ const SEPARATORS = RegExp("[^\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]+", "gu");
|
|
99
|
+
/**
|
|
100
|
+
* The search tokens for one row.
|
|
101
|
+
*
|
|
102
|
+
* Each value is tokenized twice: as written, so a typed address or code
|
|
103
|
+
* (`jane@acme`, `org.override`) matches from its start, and split at its
|
|
104
|
+
* separators, so a reader finds `org.override` by `override` and an address
|
|
105
|
+
* by its domain.
|
|
106
|
+
*/ export function adminAuditSearchTokens(entry) {
|
|
107
|
+
const tokens = new Set();
|
|
108
|
+
for (const field of ADMIN_AUDIT_SEARCHED_FIELDS){
|
|
109
|
+
const value = entry[field];
|
|
110
|
+
if (typeof value !== 'string' || !value.trim()) continue;
|
|
111
|
+
const words = [
|
|
112
|
+
...nameSearchTokens(value),
|
|
113
|
+
...nameSearchTokens(value.replace(SEPARATORS, ' '))
|
|
114
|
+
];
|
|
115
|
+
for (const token of words){
|
|
116
|
+
tokens.add(token);
|
|
117
|
+
if (tokens.size >= ADMIN_AUDIT_SEARCH_TOKEN_LIMIT) return [
|
|
118
|
+
...tokens
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return [
|
|
123
|
+
...tokens
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The group an action is filed under — the same answer the page's facet
|
|
128
|
+
* offers. Empty for a row with no action.
|
|
129
|
+
*/ export function adminAuditActionGroup(action) {
|
|
130
|
+
return pluginStaffAuditActionGroup(action);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* An access when the platform or a plugin declares the action a read — a
|
|
134
|
+
* plugin's staff card opening on an org or an account names its own read
|
|
135
|
+
* actions through its activity group (AGL-2939) — and a change otherwise.
|
|
136
|
+
*/ export function adminAuditKind(action) {
|
|
137
|
+
return typeof action === 'string' && action && (ADMIN_AUDIT_ACCESS_ACTIONS.includes(action) || isPluginStaffAuditAccess(action)) ? 'access' : 'change';
|
|
138
|
+
}
|
|
139
|
+
/** The segments of a target path; empty for a target that is not one. */ const segmentsOf = (target)=>typeof target === 'string' ? target.trim().split('/').filter(Boolean) : [];
|
|
140
|
+
/**
|
|
141
|
+
* The kind of record acted on: the target's first segment, which for every
|
|
142
|
+
* path-shaped target is its collection (`orgs/{id}` → `orgs`). A target
|
|
143
|
+
* that is an identifier rather than a path (`sso-domains:acme.com`) is its
|
|
144
|
+
* own type up to the first `:`. Empty for a row with no target.
|
|
145
|
+
*/ export function adminAuditTargetKind(target) {
|
|
146
|
+
const [first = ''] = segmentsOf(target);
|
|
147
|
+
const colon = first.indexOf(':');
|
|
148
|
+
return colon > 0 ? first.slice(0, colon) : first;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The site acted on: the id after a `hosts` segment in the target path —
|
|
152
|
+
* `hosts/{id}` and anything under it, and a site filed under its
|
|
153
|
+
* organization (`orgs/{org}/hosts/{id}`). Null when the act was not on a site.
|
|
154
|
+
*/ export function adminAuditTargetHostId(target) {
|
|
155
|
+
const segments = segmentsOf(target);
|
|
156
|
+
for(let at = 0; at < segments.length - 1; at += 2){
|
|
157
|
+
if (segments[at] === 'hosts') return segments[at + 1] || null;
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/** Every stamped field for one row. */ export function adminAuditIndexFields(entry) {
|
|
162
|
+
return {
|
|
163
|
+
actionGroup: adminAuditActionGroup(entry.action),
|
|
164
|
+
kind: adminAuditKind(entry.action),
|
|
165
|
+
targetKind: adminAuditTargetKind(entry.target),
|
|
166
|
+
targetHostId: adminAuditTargetHostId(entry.target),
|
|
167
|
+
searchTokens: adminAuditSearchTokens(entry)
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The row as it is stored: the entry, with the fields its lists query.
|
|
172
|
+
* Every write to `adminAudit` passes its data through this.
|
|
173
|
+
*/ export function withAdminAuditIndex(entry) {
|
|
174
|
+
return _extends({}, entry, adminAuditIndexFields(entry));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=admin-audit-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/admin-audit-index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n isPluginStaffAuditAccess,\n pluginStaffAuditActionGroup,\n} from '../plugin-manager/plugin-activity-actions'\nimport { nameSearchTokens } from './name-search'\n\n/*\n * WHAT THE STAFF AUDIT LOG IS QUERIED BY, WRITTEN WITH EVERY ROW (AGL-3321).\n *\n * The staff audit page and the audit tables on a staff account's page filter\n * `adminAudit` by fields no writer used to store — the action's group, the\n * kind of thing acted on, the site, whether the act only looked — and search\n * it. All of that used to be answered by reading the log in batches and\n * keeping the rows that matched, and a match read that way stops wherever\n * the batches stop, so an entry past them was reported as not there. On an\n * audit trail that is the one wrong answer that matters.\n *\n * So each is stored on the row as it is written, and the query asks for it:\n *\n * actionGroup the facet's group for the action, answered by the plugin\n * activity registry (`pluginStaffAuditActionGroup`): a\n * registered group by code or by `staffAuditPrefixes`,\n * otherwise the action's leading namespace.\n * kind `access` for an act that only looked (a core read action,\n * or one a plugin declares in `staffAuditAccessActions`),\n * `change` for everything else.\n * targetKind the kind of record acted on: the first segment of the\n * target path (`orgs`, `users`, `hosts`, `lockdowns`).\n * targetHostId the site acted on, when the target is a site or a record\n * under one (`hosts/{id}/…`, `orgs/{org}/hosts/{id}/…`);\n * null otherwise, so \"no site\" is a value a query can ask for.\n * searchTokens word-prefix tokens (`nameSearchTokens`) of the fields a\n * reviewer searches by, for `array-contains` on one word.\n *\n * Every write goes through `withAdminAuditIndex`, on the server through\n * `addAdminAudit` / `setAdminAudit` / `recordAdminAudit` in\n * `@aglyn/tenant-data-admin`. `apps/console/specs/admin-audit-writes-are-stamped.spec.ts`\n * refuses a write to the collection anywhere else, and\n * `apps/console/specs/admin-audit-action-groups.spec.ts` pins the registry's\n * groups and reads to `tools/scripts/lib/admin-audit-index.fixtures.json`,\n * the mapping `tools/scripts/backfill-admin-audit-index.mjs` restamps old\n * rows with. A plugin adding a code, a prefix or a read action therefore\n * fails CI until the fixture names it, and the backfill is re-run.\n */\n\n/** The row's group, as the Action group filter asks for it. */\nexport const ADMIN_AUDIT_GROUP_FIELD = 'actionGroup'\n\n/** Whether the row only looked, as the account page's two tables ask for it. */\nexport const ADMIN_AUDIT_KIND_FIELD = 'kind'\n\n/** The kind of record acted on, as the Target type filter asks for it. */\nexport const ADMIN_AUDIT_TARGET_KIND_FIELD = 'targetKind'\n\n/** The site acted on, as the Site filter asks for it. */\nexport const ADMIN_AUDIT_SITE_FIELD = 'targetHostId'\n\n/** The row's search tokens, as the search asks for one. */\nexport const ADMIN_AUDIT_SEARCH_FIELD = 'searchTokens'\n\n/**\n * The fields a search reaches, in the order they claim the token budget:\n * what was done, who did it, what it was done to, then why.\n */\nexport const ADMIN_AUDIT_SEARCHED_FIELDS = [\n 'action',\n 'actorEmail',\n 'target',\n 'actorUid',\n 'scope',\n 'reason',\n 'note',\n] as const\n\n/**\n * The most tokens one row stores. A free-text note is the only field that\n * can run long, and it is searched last, so it is the one that loses reach\n * past the cap.\n */\nexport const ADMIN_AUDIT_SEARCH_TOKEN_LIMIT = 200\n\n/** Access looked at data; change altered something or acted on someone. */\nexport type AdminAuditKind = 'access' | 'change'\n\n/**\n * The core actions that only LOOKED.\n *\n * An exception list, not a classification of everything, and the default\n * matters more than the membership: anything absent is a `change`. A change\n * is the louder half of the console's audit card, so an action nobody has\n * classified yet gets the MORE prominent treatment rather than the quieter\n * one. The failure mode of the opposite default is an unclassified\n * impersonation rendering as routine browsing.\n *\n * An export is deliberately NOT here. Data leaving the platform is a\n * high-consequence act even though it mutates nothing, and it belongs beside\n * the impersonations rather than beside the record views.\n */\nexport const ADMIN_AUDIT_ACCESS_ACTIONS: readonly string[] = [\n 'email.message-viewed',\n // The acquisition card (AGL-3289): where an account or a workspace came\n // from, cross-checked against the sales workspace's people. Read only.\n 'user.acquisition-viewed',\n 'org.acquisition-viewed',\n]\n\n/** What a row carries that the stamped fields are derived from. */\nexport type AdminAuditIndexSource = Partial<\n Record<(typeof ADMIN_AUDIT_SEARCHED_FIELDS)[number], unknown>\n>\n\n/** The fields the lists query. */\nexport interface AdminAuditIndexFields {\n actionGroup: string\n kind: AdminAuditKind\n targetKind: string\n targetHostId: string | null\n searchTokens: string[]\n}\n\n/** Separators inside a value: an address's `@` and `.`, a path's `/`, a code's `.`. */\nconst SEPARATORS = /[^\\p{L}\\p{N}]+/gu\n\n/**\n * The search tokens for one row.\n *\n * Each value is tokenized twice: as written, so a typed address or code\n * (`jane@acme`, `org.override`) matches from its start, and split at its\n * separators, so a reader finds `org.override` by `override` and an address\n * by its domain.\n */\nexport function adminAuditSearchTokens(entry: AdminAuditIndexSource): string[] {\n const tokens = new Set<string>()\n for (const field of ADMIN_AUDIT_SEARCHED_FIELDS) {\n const value = entry[field]\n if (typeof value !== 'string' || !value.trim()) continue\n const words = [\n ...nameSearchTokens(value),\n ...nameSearchTokens(value.replace(SEPARATORS, ' ')),\n ]\n for (const token of words) {\n tokens.add(token)\n if (tokens.size >= ADMIN_AUDIT_SEARCH_TOKEN_LIMIT) return [...tokens]\n }\n }\n return [...tokens]\n}\n\n/**\n * The group an action is filed under — the same answer the page's facet\n * offers. Empty for a row with no action.\n */\nexport function adminAuditActionGroup(action: unknown): string {\n return pluginStaffAuditActionGroup(action)\n}\n\n/**\n * An access when the platform or a plugin declares the action a read — a\n * plugin's staff card opening on an org or an account names its own read\n * actions through its activity group (AGL-2939) — and a change otherwise.\n */\nexport function adminAuditKind(action: unknown): AdminAuditKind {\n return typeof action === 'string' &&\n action &&\n (ADMIN_AUDIT_ACCESS_ACTIONS.includes(action) || isPluginStaffAuditAccess(action))\n ? 'access'\n : 'change'\n}\n\n/** The segments of a target path; empty for a target that is not one. */\nconst segmentsOf = (target: unknown): string[] =>\n typeof target === 'string' ? target.trim().split('/').filter(Boolean) : []\n\n/**\n * The kind of record acted on: the target's first segment, which for every\n * path-shaped target is its collection (`orgs/{id}` → `orgs`). A target\n * that is an identifier rather than a path (`sso-domains:acme.com`) is its\n * own type up to the first `:`. Empty for a row with no target.\n */\nexport function adminAuditTargetKind(target: unknown): string {\n const [first = ''] = segmentsOf(target)\n const colon = first.indexOf(':')\n return colon > 0 ? first.slice(0, colon) : first\n}\n\n/**\n * The site acted on: the id after a `hosts` segment in the target path —\n * `hosts/{id}` and anything under it, and a site filed under its\n * organization (`orgs/{org}/hosts/{id}`). Null when the act was not on a site.\n */\nexport function adminAuditTargetHostId(target: unknown): string | null {\n const segments = segmentsOf(target)\n for (let at = 0; at < segments.length - 1; at += 2) {\n if (segments[at] === 'hosts') return segments[at + 1] || null\n }\n return null\n}\n\n/** Every stamped field for one row. */\nexport function adminAuditIndexFields(\n entry: AdminAuditIndexSource,\n): AdminAuditIndexFields {\n return {\n actionGroup: adminAuditActionGroup(entry.action),\n kind: adminAuditKind(entry.action),\n targetKind: adminAuditTargetKind(entry.target),\n targetHostId: adminAuditTargetHostId(entry.target),\n searchTokens: adminAuditSearchTokens(entry),\n }\n}\n\n/**\n * The row as it is stored: the entry, with the fields its lists query.\n * Every write to `adminAudit` passes its data through this.\n */\nexport function withAdminAuditIndex<Entry extends AdminAuditIndexSource>(\n entry: Entry,\n): Entry & AdminAuditIndexFields {\n return { ...entry, ...adminAuditIndexFields(entry) }\n}\n"],"names":["isPluginStaffAuditAccess","pluginStaffAuditActionGroup","nameSearchTokens","ADMIN_AUDIT_GROUP_FIELD","ADMIN_AUDIT_KIND_FIELD","ADMIN_AUDIT_TARGET_KIND_FIELD","ADMIN_AUDIT_SITE_FIELD","ADMIN_AUDIT_SEARCH_FIELD","ADMIN_AUDIT_SEARCHED_FIELDS","ADMIN_AUDIT_SEARCH_TOKEN_LIMIT","ADMIN_AUDIT_ACCESS_ACTIONS","SEPARATORS","adminAuditSearchTokens","entry","tokens","Set","field","value","trim","words","replace","token","add","size","adminAuditActionGroup","action","adminAuditKind","includes","segmentsOf","target","split","filter","Boolean","adminAuditTargetKind","first","colon","indexOf","slice","adminAuditTargetHostId","segments","at","length","adminAuditIndexFields","actionGroup","kind","targetKind","targetHostId","searchTokens","withAdminAuditIndex"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,wBAAwB,EACxBC,2BAA2B,QACtB,+CAA2C;AAClD,SAASC,gBAAgB,QAAQ,mBAAe;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCC,GAED,6DAA6D,GAC7D,OAAO,MAAMC,0BAA0B,cAAa;AAEpD,8EAA8E,GAC9E,OAAO,MAAMC,yBAAyB,OAAM;AAE5C,wEAAwE,GACxE,OAAO,MAAMC,gCAAgC,aAAY;AAEzD,uDAAuD,GACvD,OAAO,MAAMC,yBAAyB,eAAc;AAEpD,yDAAyD,GACzD,OAAO,MAAMC,2BAA2B,eAAc;AAEtD;;;CAGC,GACD,OAAO,MAAMC,8BAA8B;IACzC;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAS;AAEV;;;;CAIC,GACD,OAAO,MAAMC,iCAAiC,IAAG;AAKjD;;;;;;;;;;;;;CAaC,GACD,OAAO,MAAMC,6BAAgD;IAC3D;IACA,wEAAwE;IACxE,uEAAuE;IACvE;IACA;CACD,CAAA;AAgBD,qFAAqF,GACrF,MAAMC,aAAa;AAEnB;;;;;;;CAOC,GACD,OAAO,SAASC,uBAAuBC,KAA4B;IACjE,MAAMC,SAAS,IAAIC;IACnB,KAAK,MAAMC,SAASR,4BAA6B;QAC/C,MAAMS,QAAQJ,KAAK,CAACG,MAAM;QAC1B,IAAI,OAAOC,UAAU,YAAY,CAACA,MAAMC,IAAI,IAAI;QAChD,MAAMC,QAAQ;eACTjB,iBAAiBe;eACjBf,iBAAiBe,MAAMG,OAAO,CAACT,YAAY;SAC/C;QACD,KAAK,MAAMU,SAASF,MAAO;YACzBL,OAAOQ,GAAG,CAACD;YACX,IAAIP,OAAOS,IAAI,IAAId,gCAAgC,OAAO;mBAAIK;aAAO;QACvE;IACF;IACA,OAAO;WAAIA;KAAO;AACpB;AAEA;;;CAGC,GACD,OAAO,SAASU,sBAAsBC,MAAe;IACnD,OAAOxB,4BAA4BwB;AACrC;AAEA;;;;CAIC,GACD,OAAO,SAASC,eAAeD,MAAe;IAC5C,OAAO,OAAOA,WAAW,YACvBA,UACCf,CAAAA,2BAA2BiB,QAAQ,CAACF,WAAWzB,yBAAyByB,OAAM,IAC7E,WACA;AACN;AAEA,uEAAuE,GACvE,MAAMG,aAAa,CAACC,SAClB,OAAOA,WAAW,WAAWA,OAAOX,IAAI,GAAGY,KAAK,CAAC,KAAKC,MAAM,CAACC,WAAW,EAAE;AAE5E;;;;;CAKC,GACD,OAAO,SAASC,qBAAqBJ,MAAe;IAClD,MAAM,CAACK,QAAQ,EAAE,CAAC,GAAGN,WAAWC;IAChC,MAAMM,QAAQD,MAAME,OAAO,CAAC;IAC5B,OAAOD,QAAQ,IAAID,MAAMG,KAAK,CAAC,GAAGF,SAASD;AAC7C;AAEA;;;;CAIC,GACD,OAAO,SAASI,uBAAuBT,MAAe;IACpD,MAAMU,WAAWX,WAAWC;IAC5B,IAAK,IAAIW,KAAK,GAAGA,KAAKD,SAASE,MAAM,GAAG,GAAGD,MAAM,EAAG;QAClD,IAAID,QAAQ,CAACC,GAAG,KAAK,SAAS,OAAOD,QAAQ,CAACC,KAAK,EAAE,IAAI;IAC3D;IACA,OAAO;AACT;AAEA,qCAAqC,GACrC,OAAO,SAASE,sBACd7B,KAA4B;IAE5B,OAAO;QACL8B,aAAanB,sBAAsBX,MAAMY,MAAM;QAC/CmB,MAAMlB,eAAeb,MAAMY,MAAM;QACjCoB,YAAYZ,qBAAqBpB,MAAMgB,MAAM;QAC7CiB,cAAcR,uBAAuBzB,MAAMgB,MAAM;QACjDkB,cAAcnC,uBAAuBC;IACvC;AACF;AAEA;;;CAGC,GACD,OAAO,SAASmC,oBACdnC,KAAY;IAEZ,OAAO,aAAKA,OAAU6B,sBAAsB7B;AAC9C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/** The site artifact collections whose lists query these keys. */
|
|
18
|
+
export declare const LISTED_ARTIFACT_COLLECTIONS: readonly ["screens", "layouts", "components", "templates"];
|
|
19
|
+
export type ListedArtifactCollection = (typeof LISTED_ARTIFACT_COLLECTIONS)[number];
|
|
20
|
+
/** Whether a host subcollection is one whose lists query these keys. */
|
|
21
|
+
export declare const isListedArtifactCollection: (collection: string) => collection is ListedArtifactCollection;
|
|
22
|
+
/**
|
|
23
|
+
* The name a list finds an artifact by.
|
|
24
|
+
*
|
|
25
|
+
* Its `displayName` — except a page of a multi-page STARTER, which the
|
|
26
|
+
* templates library lists as ONE row under the starter's name
|
|
27
|
+
* (`source.starterName`), so every page of it carries that name's keys and a
|
|
28
|
+
* search for the starter finds the row whichever page leads it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function artifactSearchName(collection: string, doc: Record<string, unknown>): unknown;
|
|
31
|
+
/**
|
|
32
|
+
* The list keys a CREATE of `doc` into `collection` stamps: the name keys,
|
|
33
|
+
* and the stored default of a kind a reader otherwise infers. Nothing for a
|
|
34
|
+
* collection no artifact list queries.
|
|
35
|
+
*
|
|
36
|
+
* Spread AFTER the document's own fields: the keys are derived from them.
|
|
37
|
+
*/
|
|
38
|
+
export declare function artifactCreateListKeys(collection: string, doc: Record<string, unknown>): Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* The list keys a SOFT DELETE writes beside `deletedAt`: a deleted template
|
|
41
|
+
* is no longer a library row. A caller deleting the page that LEADS a
|
|
42
|
+
* starter's row gives the lead to the next live page (`libraryRow: true`),
|
|
43
|
+
* or the starter disappears from the library with pages still in it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function artifactDeleteListKeys(collection: string): Record<string, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* The name keys a RENAME writes beside the new `displayName`. `doc` is the
|
|
48
|
+
* document as read, for the one case whose search name is not its display
|
|
49
|
+
* name (a starter page — see `artifactSearchName`).
|
|
50
|
+
*/
|
|
51
|
+
export declare function artifactRenameListKeys(collection: string, displayName: unknown, doc?: Record<string, unknown>): Record<string, unknown>;
|