@sharadtech/infralytiqs-sdk 1.0.1 → 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 (69) 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/README.md +105 -5
  33. package/clients/publicis/ps/package-lock.json +2 -2
  34. package/clients/publicis/ps/package.json +1 -1
  35. package/clients/publicis/ps/src/index.js +2473 -70
  36. package/clients/publicis/px/README.md +209 -0
  37. package/clients/publicis/px/package-lock.json +808 -0
  38. package/clients/publicis/px/package.json +23 -0
  39. package/clients/publicis/px/rollup.config.mjs +28 -0
  40. package/clients/publicis/px/src/index.js +2899 -0
  41. package/clients/publicis/pxp/README.md +212 -0
  42. package/clients/publicis/pxp/package-lock.json +808 -0
  43. package/clients/publicis/pxp/package.json +23 -0
  44. package/clients/publicis/pxp/rollup.config.mjs +28 -0
  45. package/clients/publicis/pxp/src/index.js +2900 -0
  46. package/clients/publicis/razorfish/README.md +210 -0
  47. package/clients/publicis/razorfish/package-lock.json +808 -0
  48. package/clients/publicis/razorfish/package.json +23 -0
  49. package/clients/publicis/razorfish/rollup.config.mjs +28 -0
  50. package/clients/publicis/razorfish/src/index.js +2900 -0
  51. package/clients/publicis/stellantis/README.md +208 -0
  52. package/clients/publicis/stellantis/package-lock.json +808 -0
  53. package/clients/publicis/stellantis/package.json +23 -0
  54. package/clients/publicis/stellantis/rollup.config.mjs +28 -0
  55. package/clients/publicis/stellantis/src/index.js +2895 -0
  56. package/clients/publicis/visa/README.md +208 -0
  57. package/clients/publicis/visa/package-lock.json +808 -0
  58. package/clients/publicis/visa/package.json +23 -0
  59. package/clients/publicis/visa/rollup.config.mjs +28 -0
  60. package/clients/publicis/visa/src/index.js +2894 -0
  61. package/dist/infralytiqs.js +272 -3
  62. package/dist/infralytiqs.min.js +2 -2
  63. package/package.json +1 -1
  64. package/src/envConfig.ts +1 -1
  65. package/src/index.ts +31 -0
  66. package/src/remoteConfig.ts +164 -0
  67. package/src/token.ts +79 -0
  68. package/src/tracker.ts +30 -0
  69. package/src/types.ts +10 -2
@@ -0,0 +1,212 @@
1
+ # Infralytiqs Client Bootstrap — PXP Studios (`pxp`)
2
+
3
+ Client-specific Infralytiqs bootstrap for the PXP Studios Asset Share
4
+ Commons (ASC) site — **https://sit-dam.pxpstudios.com**.
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_PXP_*` instead of `IL_PXP_*`), and the internal de-dupe flag prefixes.
11
+ 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 (pxp runs on `site_id = SIT`), so nothing is hard-coded here.
14
+
15
+ PXP serves its ASC pages under a **`/global/us/en/` locale prefix**: login
16
+ at `/global/us/en/login.html`, home/search at `/global/us/en/home.html`,
17
+ asset explorer at `/global/us/en/home/asset-explorer.html`, details at
18
+ `/.../details/<type>.html/<assetPath>`. Its DAM content lives under
19
+ `/content/dam/pxp/pxp`. The page-type heuristics match
20
+ `login` / `asset-explorer` / `details` anywhere in the path and accept any
21
+ `/content/dam/...` asset path, so neither the locale prefix nor the nested
22
+ DAM root needs special handling.
23
+
24
+ This project ships a single minified JavaScript file (`dist/infralytiqs-bootstrap.min.js`)
25
+ that is deployed to CloudFront and embedded in the host page **after** the
26
+ shared Infralytiqs SDK has loaded.
27
+
28
+ ```
29
+ Host page <head>
30
+ ├─ <script>window.IL_SERVER_URL = "…"; window.IL_TENANT_ID = "…"; …</script> ← from Sightly
31
+ ├─ <script src="https://assets.infralytiqs.com/cdn/infralytiqs.min.js"></script> ← shared SDK (CDN)
32
+ └─ <script src="https://assets.infralytiqs.com/cl/publicis/pxp/infralytiqs-bootstrap.min.js"></script>
33
+ ```
34
+
35
+ ## Tracked events
36
+
37
+ ### Login page (anonymous)
38
+
39
+ | Event | Trigger | Notes |
40
+ | ------------------ | ------------------------------------------------ | --- |
41
+ | `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(). |
42
+ | `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. |
43
+ | `sso_click` | Click on **Login with Lion Login** SSO button | Sends `method: lion_login`, `sso_provider: lion`. |
44
+ | `terms_click` | Click on **Terms and Conditions** link | Sends the link `href` and visible text. |
45
+
46
+ ### Asset Share Commons (`search_context = "asc"`, authenticated)
47
+
48
+ The user is resolved via `/libs/granite/security/currentuser.json` on every
49
+ page (cached in `localStorage`) and identified to the SDK so every event
50
+ below carries `user_id` in addition to the SDK's `anonymous_id` / `session_id`.
51
+
52
+ | Event | Trigger | Dimensions |
53
+ | ------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
+ | `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. |
55
+ | `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`. |
56
+ | `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. |
57
+ | `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`. |
58
+ | `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`. |
59
+ | `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`. |
60
+ | `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`. |
61
+ | `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`. |
62
+ | `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`. |
63
+ | `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`. |
64
+ | `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`. |
65
+ | `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`. |
66
+
67
+ ### Asset Explorer (`search_context = "asset_explorer"`, authenticated)
68
+
69
+ `/asset-explorer.html#/content/dam/...` is the React SPA front-end. Search,
70
+ folder browsing, and the Search Options modal live entirely in client-side
71
+ state, so the bootstrap routes off DOM events rather than URL parsing.
72
+
73
+ | Event | Trigger | Dimensions |
74
+ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75
+ | `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`. |
76
+ | `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). |
77
+ | `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. |
78
+ | `asset_download`, `asset_add_to_cart`, `asset_share` | Shared with ASC — same network interception and click delegation. | Same as ASC. |
79
+
80
+ Every event also picks up the global enrichment dimensions (browser, viewport,
81
+ screen, timezone, language, color scheme, tenant, site, origin) plus the
82
+ SDK's transport-level fields (timestamps, anonymous_id, session_id, user_id,
83
+ UTM, country) so the Reports UI can slice by them without per-event
84
+ instrumentation.
85
+
86
+ ### How each event is wired
87
+
88
+ Three strategies, picked to be as DOM-independent as practical:
89
+
90
+ 1. **URL-driven** (`search_executed`, `asset_preview`, `login_page_view`) —
91
+ the host page navigates via real GET requests, so the resulting URL is
92
+ the authoritative record of what the user did. The bootstrap parses
93
+ `location.pathname` / `location.search` on every page load and emits
94
+ the event. This survives bookmarks, browser-back, and shared links.
95
+ 2. **Network-driven** (`asset_download`) — `window.fetch` and
96
+ `XMLHttpRequest.prototype.{open,send}` are wrapped once per page. The
97
+ wrapper matches the ASC download endpoint regex and reads the asset
98
+ path + rendition name straight from the form-encoded POST body. No
99
+ DOM dependency at all, so it fires whether the user used the card
100
+ menu, the detail-page button, or a rendition-picker dropdown.
101
+ 3. **Click delegation** (`asset_add_to_cart`, `asset_share`) — a single
102
+ body-level capturing listener uses `closest()` to find a matching
103
+ button regardless of which descendant icon/label the user actually
104
+ clicked. Survives SPA re-renders without needing a `MutationObserver`.
105
+
106
+ ## Configuration contract
107
+
108
+ The bootstrap reads its configuration from `window.IL_*` globals that **must
109
+ be set by the host page before this script runs** (the AEM Sightly fragment
110
+ `Infralytiqs.html` injects them server-side):
111
+
112
+ | Global | Required | Description |
113
+ | ------------------- | -------- | ---------------------------------------- |
114
+ | `IL_SERVER_URL` | Yes | Base URL of the st-ck-server (Infralytiqs API). |
115
+ | `IL_TENANT_ID` | Yes | Tenant id assigned in the Infralytiqs settings. |
116
+ | `IL_SITE_ID` | Yes | Site id assigned in the Infralytiqs settings. |
117
+ | `IL_DB_NAME` | No | ClickHouse DB name for the tenant/site. |
118
+ | `IL_DEBUG` | No | `true` enables SDK console logging. |
119
+ | `IL_CAPTURE_LOCATION` | No | `true` opts the SDK into the browser geolocation prompt. |
120
+ | `IL_PXP_SELECTORS` | No | Object overriding the default selectors (see below). |
121
+
122
+ ### Selector overrides
123
+
124
+ The bootstrap matches DOM controls with a robust default set (id, name,
125
+ data-attribute, href, and visible-text). To opt out of the heuristic, set
126
+ `window.IL_PXP_SELECTORS` before this script loads:
127
+
128
+ ```html
129
+ <script>
130
+ window.IL_PXP_SELECTORS = {
131
+ // Login page
132
+ loginForm: '#loginForm',
133
+ signInButton: '#signInButton',
134
+ userField: 'input[name="username"]',
135
+ ssoButton: '#lionLoginBtn',
136
+ termsLink: 'a#termsAndConditions',
137
+ // Asset Share Commons
138
+ searchInput: 'input[name="fulltext"]',
139
+ filterRail: '#rail',
140
+ searchStatistics: '.cmp.cmp-search-statistics',
141
+ addToCart: '[data-il-cart-add]',
142
+ shareButton: '[data-il-share]',
143
+ // Asset Explorer (React)
144
+ assetExplorerRoot: '[class*="_directoryExplorer_"]',
145
+ assetExplorerForm: '[class*="_directoryExplorer_"] form',
146
+ assetExplorerSearchInput: '[class*="_directoryExplorer_"] input[type="text"]',
147
+ assetExplorerSearchOptionRow: '[class*="_searchOptionRow_"]',
148
+ assetExplorerFilterRail: '[class*="_filterWrapper_"]',
149
+ assetExplorerFilterSection: '[class*="_filterSection_"], [class*="_facet_"]',
150
+ assetExplorerSearchStatistics:'[class*="_statContainer_"]',
151
+ assetExplorerFolderTree: '[class*="_directoryTreeContent_"]'
152
+ };
153
+ </script>
154
+ ```
155
+
156
+ The easiest pattern for ASC components is to add an opt-in
157
+ `data-il-cart-add` / `data-il-share` attribute (or `data-asset-path`
158
+ on the parent card) so the bootstrap stops relying on the visible-text
159
+ fallback altogether.
160
+
161
+ ### User-identity override
162
+
163
+ By default the bootstrap resolves the logged-in user by:
164
+
165
+ 1. Calling `window.IL_PXP_USER_RESOLVER()` if you defined it (sync string
166
+ or a `Promise<string>`).
167
+ 2. Reading `<meta name="cq:user">` (or `name="user"` / `name="user-id"`).
168
+ 3. Falling back to `GET /libs/granite/security/currentuser.json` and
169
+ using its `authorizableId` / `id`.
170
+
171
+ To bypass all three, supply a resolver:
172
+
173
+ ```html
174
+ <script>
175
+ window.IL_PXP_USER_RESOLVER = function () {
176
+ return window.MY_AUTH_PROVIDER.getUsername();
177
+ };
178
+ </script>
179
+ ```
180
+
181
+ ## Building
182
+
183
+ ```bash
184
+ npm install
185
+ npm run build # produces dist/infralytiqs-bootstrap.{js,min.js}
186
+ npm run dev # watch mode
187
+ ```
188
+
189
+ The `dist/` directory contains both an unminified (`infralytiqs-bootstrap.js`)
190
+ and a minified (`infralytiqs-bootstrap.min.js`) IIFE. Only the minified file
191
+ is deployed to CloudFront.
192
+
193
+ ## Deployment
194
+
195
+ Deployment of `dist/infralytiqs-bootstrap.min.js` to the CloudFront-fronted
196
+ S3 bucket is handled by the `Deploy - Infralytiqs SDK` Jenkins pipeline
197
+ (`buildScripts/Jenkinsfile.deploy`). Tick the **`DEPLOY_CLIENT_PUBLICIS_PXP`**
198
+ boolean parameter to build this project and upload it to:
199
+
200
+ ```
201
+ s3://infralytiqs/cl/publicis/pxp/infralytiqs-bootstrap.min.js
202
+ → https://assets.infralytiqs.com/cl/publicis/pxp/infralytiqs-bootstrap.min.js
203
+ ```
204
+
205
+ > **AEM wiring.** The pxp host page did not yet inject
206
+ > `window.IL_CLIENT_BOOTSTRAP_LIB` when last checked live (it was `null` on
207
+ > `sit-dam.pxpstudios.com`). The AEM Infralytiqs domain→bootstrap mapping
208
+ > (OSGi `TenantServiceImpl~groupeDamPlatform.cfg.json`) already contains the
209
+ > pxp entries
210
+ > (`sit-dam.pxpstudios.com:/cl/publicis/pxp/infralytiqs-bootstrap.min.js`),
211
+ > so once that osgiconfig package is deployed to the pxp instance the SDK
212
+ > will resolve and load this bootstrap.