@sharadtech/infralytiqs-sdk 1.0.2 → 1.0.3

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.
Files changed (65) hide show
  1. package/buildScripts/Jenkinsfile.deploy +241 -125
  2. package/clients/publicis/arc/README.md +212 -0
  3. package/clients/publicis/arc/package-lock.json +808 -0
  4. package/clients/publicis/arc/package.json +23 -0
  5. package/clients/publicis/arc/rollup.config.mjs +28 -0
  6. package/clients/publicis/arc/src/index.js +2900 -0
  7. package/clients/publicis/atl/README.md +203 -0
  8. package/clients/publicis/atl/package-lock.json +808 -0
  9. package/clients/publicis/atl/package.json +23 -0
  10. package/clients/publicis/atl/rollup.config.mjs +28 -0
  11. package/clients/publicis/atl/src/index.js +2902 -0
  12. package/clients/publicis/colab/README.md +213 -0
  13. package/clients/publicis/colab/package-lock.json +808 -0
  14. package/clients/publicis/colab/package.json +23 -0
  15. package/clients/publicis/colab/rollup.config.mjs +28 -0
  16. package/clients/publicis/colab/src/index.js +2901 -0
  17. package/clients/publicis/fnacdarty/README.md +210 -0
  18. package/clients/publicis/fnacdarty/package-lock.json +808 -0
  19. package/clients/publicis/fnacdarty/package.json +23 -0
  20. package/clients/publicis/fnacdarty/rollup.config.mjs +28 -0
  21. package/clients/publicis/fnacdarty/src/index.js +2900 -0
  22. package/clients/publicis/garnier/README.md +206 -0
  23. package/clients/publicis/garnier/package-lock.json +808 -0
  24. package/clients/publicis/garnier/package.json +23 -0
  25. package/clients/publicis/garnier/rollup.config.mjs +28 -0
  26. package/clients/publicis/garnier/src/index.js +2894 -0
  27. package/clients/publicis/pmigtr/README.md +212 -0
  28. package/clients/publicis/pmigtr/package-lock.json +808 -0
  29. package/clients/publicis/pmigtr/package.json +23 -0
  30. package/clients/publicis/pmigtr/rollup.config.mjs +28 -0
  31. package/clients/publicis/pmigtr/src/index.js +2903 -0
  32. package/clients/publicis/ps/package-lock.json +2 -2
  33. package/clients/publicis/ps/package.json +1 -1
  34. package/clients/publicis/px/README.md +209 -0
  35. package/clients/publicis/px/package-lock.json +808 -0
  36. package/clients/publicis/px/package.json +23 -0
  37. package/clients/publicis/px/rollup.config.mjs +28 -0
  38. package/clients/publicis/px/src/index.js +2899 -0
  39. package/clients/publicis/pxp/README.md +212 -0
  40. package/clients/publicis/pxp/package-lock.json +808 -0
  41. package/clients/publicis/pxp/package.json +23 -0
  42. package/clients/publicis/pxp/rollup.config.mjs +28 -0
  43. package/clients/publicis/pxp/src/index.js +2900 -0
  44. package/clients/publicis/razorfish/README.md +210 -0
  45. package/clients/publicis/razorfish/package-lock.json +808 -0
  46. package/clients/publicis/razorfish/package.json +23 -0
  47. package/clients/publicis/razorfish/rollup.config.mjs +28 -0
  48. package/clients/publicis/razorfish/src/index.js +2900 -0
  49. package/clients/publicis/stellantis/README.md +208 -0
  50. package/clients/publicis/stellantis/package-lock.json +808 -0
  51. package/clients/publicis/stellantis/package.json +23 -0
  52. package/clients/publicis/stellantis/rollup.config.mjs +28 -0
  53. package/clients/publicis/stellantis/src/index.js +2895 -0
  54. package/clients/publicis/visa/README.md +208 -0
  55. package/clients/publicis/visa/package-lock.json +808 -0
  56. package/clients/publicis/visa/package.json +23 -0
  57. package/clients/publicis/visa/rollup.config.mjs +28 -0
  58. package/clients/publicis/visa/src/index.js +2894 -0
  59. package/dist/infralytiqs.js +243 -71
  60. package/dist/infralytiqs.min.js +2 -2
  61. package/package.json +1 -1
  62. package/src/envConfig.ts +1 -1
  63. package/src/remoteConfig.ts +164 -0
  64. package/src/tracker.ts +30 -0
  65. package/src/types.ts +10 -2
@@ -0,0 +1,206 @@
1
+ # Infralytiqs Client Bootstrap — Garnier (`garnier`)
2
+
3
+ Client-specific Infralytiqs bootstrap for the Garnier Asset Share Commons
4
+ (ASC) site — **https://garnier-sit.productioncloud.io**.
5
+
6
+ This is a sibling of [`publicis/ps`](../ps/README.md). Both target the same
7
+ Adobe DAM Asset Share Commons platform (the `groupe-dam` tenant), so the
8
+ tracked-event taxonomy, selectors, and DOM heuristics are identical. The
9
+ only differences are the host domain, the client-override global namespace
10
+ (`IL_GARNIER_*` instead of `IL_GARNIER_*`), and the internal de-dupe flag
11
+ prefixes. The per-tenant `server / tenant / site / db` values are read from
12
+ `window.IL_*` injected server-side by the AEM Sightly `Infralytiqs.html`
13
+ fragment (garnier runs on `site_id = SIT`), so nothing is hard-coded here.
14
+
15
+ Garnier uses the same URL shape as ps: login at `/login.html`, asset
16
+ explorer at `/asset-explorer.html`, details at
17
+ `/details/<type>.html/<assetPath>` — no path-prefix handling required.
18
+
19
+ This project ships a single minified JavaScript file (`dist/infralytiqs-bootstrap.min.js`)
20
+ that is deployed to CloudFront and embedded in the host page **after** the
21
+ shared Infralytiqs SDK has loaded.
22
+
23
+ ```
24
+ Host page <head>
25
+ ├─ <script>window.IL_SERVER_URL = "…"; window.IL_TENANT_ID = "…"; …</script> ← from Sightly
26
+ ├─ <script src="https://assets.infralytiqs.com/cdn/infralytiqs.min.js"></script> ← shared SDK (CDN)
27
+ └─ <script src="https://assets.infralytiqs.com/cl/publicis/garnier/infralytiqs-bootstrap.min.js"></script>
28
+ ```
29
+
30
+ ## Tracked events
31
+
32
+ ### Login page (anonymous)
33
+
34
+ | Event | Trigger | Notes |
35
+ | ------------------ | ------------------------------------------------ | --- |
36
+ | `login_page_view` | Anonymous user lands on the login page | Fired in addition to the SDK's auto `page_view` so the Reports login funnel can segment login-page traffic before identify(). |
37
+ | `login_attempt` | Click on **Sign in** or form submit | Captures the typed username only — **never** the password. Calls `identify(username)` so subsequent events carry it. |
38
+ | `sso_click` | Click on **Login with Lion Login** SSO button | Sends `method: lion_login`, `sso_provider: lion`. |
39
+ | `terms_click` | Click on **Terms and Conditions** link | Sends the link `href` and visible text. |
40
+
41
+ ### Asset Share Commons (`search_context = "asc"`, authenticated)
42
+
43
+ The user is resolved via `/libs/granite/security/currentuser.json` on every
44
+ page (cached in `localStorage`) and identified to the SDK so every event
45
+ below carries `user_id` in addition to the SDK's `anonymous_id` / `session_id`.
46
+
47
+ | Event | Trigger | Dimensions |
48
+ | ------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
49
+ | `search_executed` | Any page load whose URL carries `?fulltext=…` | `search_term`, `semantic_search`, `fuzzy_search`, `filters_json` (JSON array of `{group, name, property, operation, values[]}` — `name` is the right-rail section heading like `"ASSET TYPE"`, resolved by cross-referencing the URL property against the rail's `cmp-predicate` blocks), `filters_dom_json` (belt-and-braces JSON of `{name, values[]}` produced by sweeping the rail for checked inputs — catches DOM-only state the URL didn't carry), `orderby`, `order_dir`, `layout`, `search_context="asc"`, `page_url`, `page_referrer`, `search_stats_ready` (`"true"` when the search-statistics widget had populated before we fired). Metrics: `filter_count`, `filter_dom_count`, `result_offset`, `result_limit`, **`search_time_ms`** (server-reported search latency read from the right-rail statistics widget), **`result_total`** (total asset count), **`result_pages`** (total page count, when the widget exposes one), **`result_displayed`** (assets shown on the current results page). The bootstrap briefly observes the statistics container with a `MutationObserver` so the timing reflects the search that just executed, not a stale value left over from the previous in-page navigation; if the widget never populates within 3 s the event still fires with `search_stats_ready=false`. The raw label→value tuples (first 240 chars of JSON) are also emitted as `search_stats_raw_json` so any future label change in ASC can be diagnosed from ClickHouse without re-instrumenting the page. |
50
+ | `asset_preview` | Any page load matching `/details/<type>.html/<assetPath>` | `asset_path` (`/content/dam/…`), `asset_type` (`image`, `video`, `document`, `3d`, …), `asset_name`, `asset_extension`, `page_url`, `page_referrer`. |
51
+ | `asset_download` | Network `POST` to ASC `…/actions/download/.../download.download-asset-renditions.zip` | `asset_path` (from form body `path`), `rendition_name` (from `renditionName`), `download_endpoint`, `page_url`. **Intercepts `fetch` and `XMLHttpRequest`** so it fires whether the user used the card menu, the detail-page button, or a rendition picker. |
52
+ | `asset_add_to_cart` | Click on a per-tile / per-card Add-to-Cart button. Detected primarily by `data-asset-share-id="add-to-cart"` (the ASC convention), with `[data-il-cart-add]` / `[data-cmp-cart-action="add"]` and a visible-text `/add to cart/i` regex as fallbacks. The icon-only variant is detected via data-attrs alone (no text required). | `asset_path` — read from `data-asset-share-asset` directly when the button is the ASC variant, or walked up the DOM via `data-asset-path` / `data-asset` / `data-foundation-collection-item-id` / nearest `<a href="/details/…">`. `page_url`. |
53
+ | `asset_share` | Click on an asset-level Share button (`data-asset-share-id="share-asset"`, `[data-il-share]`, `[data-cmp-share-action]`, or visible-text `/share/i`). Explicitly excludes the cart-level Share Cart button so a click on it cannot fall through. | `asset_path`, `page_url`. |
54
+ | `cart_open` | Click anywhere inside the header cart icon link (`a.item > i.cart.icon`, `[data-asset-share-id="cart"]`). | `page_url`. Subtype: `cart_action`. |
55
+ | `cart_share_initiated` | Click on the cart-modal "Share Cart" button (`data-asset-share-id="share-all"`). Funnel-only intent — the actual share happens when the user fills the share modal and submits. | `cart_asset_paths_json` (JSON array of `/content/dam/...` paths scraped from the cart modal). Metric: `cart_item_count`. Subtype: `cart_action`. |
56
+ | `cart_share` | Submit of the share-modal form (`form.cmp-modal-share` / `form[class*="cmp-modal-share"]`). Fires the moment the user submits, BEFORE jQuery validation may cancel — so the funnel captures every share attempt. | `share_emails` (comma-joined, deduped, lowercase-key dedupe, 480-char cap), `share_is_public` (`"true"` / `"false"` — taken from the "Share Publicly" checkbox OR inferred from non-empty dates), `share_start_date`, `share_end_date` (`yyyy-mm-dd`, only set when `share_is_public="true"`), `cart_asset_paths_json` (carried over from the cart snapshot captured at button-click time so it survives the cart modal closing). Metrics: `share_emails_count`, `share_date_range_days` (`end - start`, clamped to ≥ 0), `cart_item_count`. Subtype: `cart_action`. |
57
+ | `cart_download` | Click on the cart-modal "Download Cart" button (`data-asset-share-id="download-all"`). The user's confirmed intent to start the cart-download pipeline — the actual binaries arrive asynchronously and emit `asset_download` events when the user clicks the per-row download anchors in the downloads modal. | Same shape as `cart_share`: `cart_asset_paths_json`, `cart_item_count`. Subtype: `cart_action`. |
58
+ | `downloads_open` | Click anywhere inside the header download icon link (`a.item > i.download.icon`, `[data-asset-share-id="downloads"]`). | `page_url`. Subtype: `cart_action`. |
59
+ | `asset_download` | (a) Network `POST` to ASC `…/actions/download/.../download.download-asset-renditions.zip` — `download_method="ajax"`. (b) Click on a per-artifact download anchor in the downloads modal (`a[href*="downloadbinaries.json"]`) — `download_method="binary_link_click"`, with `download_source="downloads_modal"`. | (a) `asset_path` (form body `path`), `rendition_name` (form body `renditionName`), `download_endpoint`, `page_url`. (b) `download_id` and `artifact_id` (parsed off the anchor's query string), `download_endpoint` (URL minus query), `download_source`, `download_method`, `page_url`. |
60
+ | `download_removed` | Click on the per-row "remove from downloads" button (`data-asset-share-id="remove-from-downloads"`). | `download_id` (from `data-asset-share-download-id`), `page_url`. Subtype: `cart_action`. |
61
+
62
+ ### Asset Explorer (`search_context = "asset_explorer"`, authenticated)
63
+
64
+ `/asset-explorer.html#/content/dam/...` is the React SPA front-end. Search,
65
+ folder browsing, and the Search Options modal live entirely in client-side
66
+ state, so the bootstrap routes off DOM events rather than URL parsing.
67
+
68
+ | Event | Trigger | Dimensions |
69
+ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `search_executed` | Any of: Enter inside the search input, native form submit, Search Options modal close, right-rail filter click, debounced live-typing pause (800 ms). Overlapping triggers on the same user action collapse into one event via `(term, semantic, fuzzy, folder, filters)` dedup. | `search_term`, `semantic_search` / `fuzzy_search` (read from the toggles in the open Search Options modal — falls back through native checkbox → `aria-checked` → `data-state` → class-name heuristic; emits `""` when the row isn't currently rendered), `folder_path` (the `#/content/dam/...` hash), `filters_dom_json` (JSON of `{name, values[]}` blocks scraped from the right-rail facet panel via native-checkbox / ARIA / data-state / class-name heuristics — grouped under the section heading the chip lives under), `search_context="asset_explorer"`, `search_trigger` (which hook fired: `enter` / `submit` / `options_close` / `filter_click` / `input_debounced`), `page_url`, `page_referrer`. Metrics: `filter_dom_count`, same `search_*` stats as ASC populated from the rail's `_statContainer_` (`<N> DISPLAYED <N> TOTAL <N> MILLISECONDS` tiles paired via `_value_` / `_label_` siblings; regex fallback over the container's text if structured markup isn't present). Subtype: `asset_search`. |
71
+ | `folder_navigation` | Any of: `hashchange`, click on a folder in the left-side directory tree, expand a tree node, collapse a tree node, initial page load (when a folder is already in the hash route). | `folder_path` (current hash route), `search_context="asset_explorer"`, `tree_action` (`page_load` / `hash_change` / `click` / `expand` / `collapse` — derived from `aria-expanded` mutation when available, otherwise `click`), `tree_target_label` (visible text of the clicked tree node), `tree_target_class_hint` (first 240 chars of the clicked element's className — diagnostic, to refine action detection from data later), `page_url`, `page_referrer`. Subtype: `asset_browse`. No stats wait. A single user gesture can emit one `click`/`expand`/`collapse` event AND a `hash_change` event when the click also navigates — they are intentionally NOT deduped so dashboards can split intent (the user opened a node) from outcome (the route changed). |
72
+ | `asset_preview` | Shared with ASC — fires on a `/details/<type>.html/<assetPath>` navigation (the explorer hands off to ASC for full detail views), and on body-level clicks that resolve to an asset path attribute. | Same as ASC. |
73
+ | `asset_download`, `asset_add_to_cart`, `asset_share` | Shared with ASC — same network interception and click delegation. | Same as ASC. |
74
+
75
+ Every event also picks up the global enrichment dimensions (browser, viewport,
76
+ screen, timezone, language, color scheme, tenant, site, origin) plus the
77
+ SDK's transport-level fields (timestamps, anonymous_id, session_id, user_id,
78
+ UTM, country) so the Reports UI can slice by them without per-event
79
+ instrumentation.
80
+
81
+ ### How each event is wired
82
+
83
+ Three strategies, picked to be as DOM-independent as practical:
84
+
85
+ 1. **URL-driven** (`search_executed`, `asset_preview`, `login_page_view`) —
86
+ the host page navigates via real GET requests, so the resulting URL is
87
+ the authoritative record of what the user did. The bootstrap parses
88
+ `location.pathname` / `location.search` on every page load and emits
89
+ the event. This survives bookmarks, browser-back, and shared links.
90
+ 2. **Network-driven** (`asset_download`) — `window.fetch` and
91
+ `XMLHttpRequest.prototype.{open,send}` are wrapped once per page. The
92
+ wrapper matches the ASC download endpoint regex and reads the asset
93
+ path + rendition name straight from the form-encoded POST body. No
94
+ DOM dependency at all, so it fires whether the user used the card
95
+ menu, the detail-page button, or a rendition-picker dropdown.
96
+ 3. **Click delegation** (`asset_add_to_cart`, `asset_share`) — a single
97
+ body-level capturing listener uses `closest()` to find a matching
98
+ button regardless of which descendant icon/label the user actually
99
+ clicked. Survives SPA re-renders without needing a `MutationObserver`.
100
+
101
+ ## Configuration contract
102
+
103
+ The bootstrap reads its configuration from `window.IL_*` globals that **must
104
+ be set by the host page before this script runs** (the AEM Sightly fragment
105
+ `Infralytiqs.html` injects them server-side):
106
+
107
+ | Global | Required | Description |
108
+ | ------------------- | -------- | ---------------------------------------- |
109
+ | `IL_SERVER_URL` | Yes | Base URL of the st-ck-server (Infralytiqs API). |
110
+ | `IL_TENANT_ID` | Yes | Tenant id assigned in the Infralytiqs settings. |
111
+ | `IL_SITE_ID` | Yes | Site id assigned in the Infralytiqs settings. |
112
+ | `IL_DB_NAME` | No | ClickHouse DB name for the tenant/site. |
113
+ | `IL_DEBUG` | No | `true` enables SDK console logging. |
114
+ | `IL_CAPTURE_LOCATION` | No | `true` opts the SDK into the browser geolocation prompt. |
115
+ | `IL_GARNIER_SELECTORS` | No | Object overriding the default selectors (see below). |
116
+
117
+ ### Selector overrides
118
+
119
+ The bootstrap matches DOM controls with a robust default set (id, name,
120
+ data-attribute, href, and visible-text). To opt out of the heuristic, set
121
+ `window.IL_GARNIER_SELECTORS` before this script loads:
122
+
123
+ ```html
124
+ <script>
125
+ window.IL_GARNIER_SELECTORS = {
126
+ // Login page
127
+ loginForm: '#loginForm',
128
+ signInButton: '#signInButton',
129
+ userField: 'input[name="username"]',
130
+ ssoButton: '#lionLoginBtn',
131
+ termsLink: 'a#termsAndConditions',
132
+ // Asset Share Commons
133
+ searchInput: 'input[name="fulltext"]',
134
+ filterRail: '#rail',
135
+ searchStatistics: '.cmp.cmp-search-statistics',
136
+ addToCart: '[data-il-cart-add]',
137
+ shareButton: '[data-il-share]',
138
+ // Asset Explorer (React)
139
+ assetExplorerRoot: '[class*="_directoryExplorer_"]',
140
+ assetExplorerForm: '[class*="_directoryExplorer_"] form',
141
+ assetExplorerSearchInput: '[class*="_directoryExplorer_"] input[type="text"]',
142
+ assetExplorerSearchOptionRow: '[class*="_searchOptionRow_"]',
143
+ assetExplorerFilterRail: '[class*="_filterWrapper_"]',
144
+ assetExplorerFilterSection: '[class*="_filterSection_"], [class*="_facet_"]',
145
+ assetExplorerSearchStatistics:'[class*="_statContainer_"]',
146
+ assetExplorerFolderTree: '[class*="_directoryTreeContent_"]'
147
+ };
148
+ </script>
149
+ ```
150
+
151
+ The easiest pattern for ASC components is to add an opt-in
152
+ `data-il-cart-add` / `data-il-share` attribute (or `data-asset-path`
153
+ on the parent card) so the bootstrap stops relying on the visible-text
154
+ fallback altogether.
155
+
156
+ ### User-identity override
157
+
158
+ By default the bootstrap resolves the logged-in user by:
159
+
160
+ 1. Calling `window.IL_GARNIER_USER_RESOLVER()` if you defined it (sync string
161
+ or a `Promise<string>`).
162
+ 2. Reading `<meta name="cq:user">` (or `name="user"` / `name="user-id"`).
163
+ 3. Falling back to `GET /libs/granite/security/currentuser.json` and
164
+ using its `authorizableId` / `id`.
165
+
166
+ To bypass all three, supply a resolver:
167
+
168
+ ```html
169
+ <script>
170
+ window.IL_GARNIER_USER_RESOLVER = function () {
171
+ return window.MY_AUTH_PROVIDER.getUsername();
172
+ };
173
+ </script>
174
+ ```
175
+
176
+ ## Building
177
+
178
+ ```bash
179
+ npm install
180
+ npm run build # produces dist/infralytiqs-bootstrap.{js,min.js}
181
+ npm run dev # watch mode
182
+ ```
183
+
184
+ The `dist/` directory contains both an unminified (`infralytiqs-bootstrap.js`)
185
+ and a minified (`infralytiqs-bootstrap.min.js`) IIFE. Only the minified file
186
+ is deployed to CloudFront.
187
+
188
+ ## Deployment
189
+
190
+ Deployment of `dist/infralytiqs-bootstrap.min.js` to the CloudFront-fronted
191
+ S3 bucket is handled by the `Deploy - Infralytiqs SDK` Jenkins pipeline
192
+ (`buildScripts/Jenkinsfile.deploy`). Tick the **`DEPLOY_CLIENT_PUBLICIS_GARNIER`**
193
+ boolean parameter to build this project and upload it to:
194
+
195
+ ```
196
+ s3://infralytiqs/cl/publicis/garnier/infralytiqs-bootstrap.min.js
197
+ → https://assets.infralytiqs.com/cl/publicis/garnier/infralytiqs-bootstrap.min.js
198
+ ```
199
+
200
+ > **AEM wiring required.** Unlike the ps/atl domains, the garnier host page
201
+ > does **not** yet inject `window.IL_CLIENT_BOOTSTRAP_LIB` for this bootstrap
202
+ > (verified live: it is `null` on `garnier-sit.productioncloud.io`). After
203
+ > this artifact is on the CDN, the AEM Infralytiqs domain→bootstrap mapping
204
+ > (OSGi `TenantServiceImpl` / Sightly `Infralytiqs.html`) must be updated to
205
+ > point the garnier domain at `/cl/publicis/garnier/infralytiqs-bootstrap.min.js`,
206
+ > otherwise the SDK will load but this client bootstrap will not.