@antelopejs/dms-marketing 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -131
- package/dist/config.d.ts +10 -1
- package/dist/config.js +29 -1
- package/dist/config.js.map +1 -1
- package/dist/db/models/funnels.model.d.ts +2 -0
- package/dist/db/models/funnels.model.js +18 -0
- package/dist/db/models/funnels.model.js.map +1 -1
- package/dist/db/models/index.d.ts +1 -0
- package/dist/db/models/index.js +1 -0
- package/dist/db/models/index.js.map +1 -1
- package/dist/db/models/marketing_events.model.d.ts +1 -0
- package/dist/db/models/marketing_imports.model.d.ts +27 -0
- package/dist/db/models/marketing_imports.model.js +38 -0
- package/dist/db/models/marketing_imports.model.js.map +1 -0
- package/dist/db/models/marketing_preferences.model.d.ts +1 -0
- package/dist/db/models/marketing_sessions.model.d.ts +1 -0
- package/dist/db/models/marketing_settings.model.d.ts +1 -0
- package/dist/db/models/page_snapshots.model.d.ts +2 -0
- package/dist/db/models/page_snapshots.model.js +14 -0
- package/dist/db/models/page_snapshots.model.js.map +1 -1
- package/dist/db/models/website_statistics.model.d.ts +1 -0
- package/dist/db/models/websites.model.d.ts +2 -0
- package/dist/db/models/websites.model.js +29 -0
- package/dist/db/models/websites.model.js.map +1 -1
- package/dist/db/tables/funnels.table.d.ts +1 -0
- package/dist/db/tables/funnels.table.js +4 -0
- package/dist/db/tables/funnels.table.js.map +1 -1
- package/dist/db/tables/index.d.ts +1 -0
- package/dist/db/tables/index.js +1 -0
- package/dist/db/tables/index.js.map +1 -1
- package/dist/db/tables/marketing_imports.table.d.ts +15 -0
- package/dist/db/tables/marketing_imports.table.js +63 -0
- package/dist/db/tables/marketing_imports.table.js.map +1 -0
- package/dist/db/tables/page_snapshots.table.d.ts +1 -0
- package/dist/db/tables/page_snapshots.table.js +4 -0
- package/dist/db/tables/page_snapshots.table.js.map +1 -1
- package/dist/db/tables/websites.table.d.ts +1 -0
- package/dist/db/tables/websites.table.js +4 -0
- package/dist/db/tables/websites.table.js.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/implementations/dms-marketing/index.d.ts +5 -1
- package/dist/implementations/dms-marketing/index.js +25 -0
- package/dist/implementations/dms-marketing/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/routes/dashboard-tracking.d.ts +9 -0
- package/dist/routes/dashboard-tracking.js +57 -0
- package/dist/routes/dashboard-tracking.js.map +1 -0
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/websites.js +12 -25
- package/dist/routes/websites.js.map +1 -1
- package/dist/services/analytics-import.d.ts +2 -0
- package/dist/services/analytics-import.js +294 -0
- package/dist/services/analytics-import.js.map +1 -0
- package/dist/services/collect.d.ts +20 -0
- package/dist/services/collect.js +43 -17
- package/dist/services/collect.js.map +1 -1
- package/dist/services/context.d.ts +8 -3
- package/dist/services/context.js +21 -7
- package/dist/services/context.js.map +1 -1
- package/dist/services/dashboard-tracking.d.ts +25 -0
- package/dist/services/dashboard-tracking.js +85 -0
- package/dist/services/dashboard-tracking.js.map +1 -0
- package/dist/services/dashboard.js +7 -3
- package/dist/services/dashboard.js.map +1 -1
- package/dist/services/declarations.d.ts +11 -0
- package/dist/services/declarations.js +64 -0
- package/dist/services/declarations.js.map +1 -0
- package/dist/services/declared-funnel.d.ts +2 -0
- package/dist/services/declared-funnel.js +230 -0
- package/dist/services/declared-funnel.js.map +1 -0
- package/dist/services/declared-snapshot.d.ts +2 -0
- package/dist/services/declared-snapshot.js +113 -0
- package/dist/services/declared-snapshot.js.map +1 -0
- package/dist/services/declared-website.d.ts +2 -0
- package/dist/services/declared-website.js +118 -0
- package/dist/services/declared-website.js.map +1 -0
- package/dist/services/geoip.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/readiness.d.ts +2 -0
- package/dist/services/readiness.js +15 -0
- package/dist/services/readiness.js.map +1 -0
- package/dist/services/sessionize.d.ts +1 -0
- package/dist/services/sessionize.js +3 -0
- package/dist/services/sessionize.js.map +1 -1
- package/dist/services/snapshots.d.ts +3 -0
- package/dist/services/snapshots.js +6 -0
- package/dist/services/snapshots.js.map +1 -1
- package/dist/services/tenant-website.js +1 -0
- package/dist/services/tenant-website.js.map +1 -1
- package/dist/services/website-report.js +4 -3
- package/dist/services/website-report.js.map +1 -1
- package/dist/services/website-rules.d.ts +8 -0
- package/dist/services/website-rules.js +34 -0
- package/dist/services/website-rules.js.map +1 -0
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/constants.js +5 -2
- package/dist/types/constants.js.map +1 -1
- package/dist/types/snapshots.d.ts +55 -0
- package/dist/types/snapshots.js +8 -1
- package/dist/types/snapshots.js.map +1 -1
- package/frontend-vue/app/components/Context.vue +5 -1
- package/frontend-vue/app/components/FirstRun.vue +1 -1
- package/frontend-vue/app/components/PagePreview.vue +1 -0
- package/frontend-vue/app/components/WebsitesGrid.vue +6 -2
- package/frontend-vue/app/composables/useMarketingApi.ts +12 -0
- package/frontend-vue/app/composables/useMarketingContext.ts +2 -1
- package/frontend-vue/app/composables/useMarketingReads.ts +6 -0
- package/frontend-vue/app/constants.ts +6 -0
- package/frontend-vue/app/plugins/dashboard-tracking.client.ts +44 -0
- package/frontend-vue/app/utils/dashboard-tracker.ts +127 -0
- package/frontend-vue/app/utils/format.ts +6 -3
- package/frontend-vue/dms.frontend.ts +10 -0
- package/frontend-vue/i18n/locales/marketing-en-GB.json +2 -0
- package/frontend-vue/i18n/locales/marketing-fr-FR.json +2 -0
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/tests/dashboard-tracking.test.ts +219 -0
- package/frontend-vue/tests/format.test.ts +9 -0
- package/frontend-vue/tests/marketing-reads.test.ts +23 -0
- package/frontend-vue/tests/server-parity.test.ts +5 -0
- package/frontend-vue/tests/stubs/frontend-module.ts +7 -0
- package/package.json +34 -15
- package/skills/dms-marketing/SKILL.md +107 -0
- package/static/tracker.js +90 -5
- package/frontend-vue/pnpm-workspace.yaml +0 -2
package/README.md
CHANGED
|
@@ -1,147 +1,73 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# @antelopejs/dms-marketing
|
|
2
4
|
|
|
3
|
-
<
|
|
4
|
-
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/
|
|
5
|
-
<a href="https://discord.gg/sjK28QHrA7"><img src="https://img.shields.io/badge/Discord-18181B?logo=discord&style=for-the-badge&color=000000"
|
|
6
|
-
<a href="https://antelopejs.com"><img src="https://img.shields.io/badge/Docs-18181B?style=for-the-badge&color=000000"
|
|
7
|
-
</div>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@antelopejs/dms-marketing"><img alt="npm" src="https://img.shields.io/npm/v/@antelopejs/dms-marketing?style=for-the-badge&labelColor=000000&color=000000"></a>
|
|
6
|
+
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/npm/l/@antelopejs/dms-marketing?style=for-the-badge&labelColor=000000&color=000000"></a>
|
|
7
|
+
<a href="https://discord.gg/sjK28QHrA7"><img alt="Discord" src="https://img.shields.io/badge/Discord-18181B?logo=discord&style=for-the-badge&color=000000"></a>
|
|
8
|
+
<a href="https://dms.antelopejs.com/docs/modules/marketing"><img alt="Documentation" src="https://img.shields.io/badge/Docs-18181B?style=for-the-badge&color=000000"></a>
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
conversion funnels with optional A/B splits, and click heatmaps — fully
|
|
11
|
-
first-party.
|
|
12
|
-
No external service, no cookie; data stays in the project's MongoDB.
|
|
13
|
-
|
|
14
|
-
<p align="center">
|
|
15
|
-
<img src="docs/screenshots/overview.png" alt="Overview: the website and period bar, four KPI cards with their change and sparkline, the session-quality strip, the traffic chart against the previous period, the device split and four tabbed top lists" width="900">
|
|
16
|
-
</p>
|
|
17
|
-
<p align="center">
|
|
18
|
-
<em>The Overview page — every panel reads pre-aggregated daily rollups, never raw events.</em>
|
|
19
|
-
</p>
|
|
20
|
-
|
|
21
|
-
## Features
|
|
22
|
-
|
|
23
|
-
| Feature | Where | Guide |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| **Traffic overview** — pageviews, sessions, new visitors and custom events with their change, session quality, traffic chart, device split, top content/acquisition/audience/event lists | `/modules/marketing/overview` | [usage/overview.md](docs/usage/overview.md) |
|
|
26
|
-
| **Acquisition** — direct/organic/social/email/referral/paid split, UTM campaign table (source × medium × campaign), top referrers and UTM details | `/modules/marketing/acquisition` | [usage/acquisition.md](docs/usage/acquisition.md) |
|
|
27
|
-
| **Pages & heatmaps** — clicks and scroll depth drawn over a snapshot of any tracked page | `/modules/marketing/pages` | [usage/heatmap.md](docs/usage/heatmap.md) |
|
|
28
|
-
| **Funnels & A/B tests** — ordered conversion journeys with per-step drop-off, optionally split into server-assigned variations scored with significance; a report page and a builder per funnel | `/modules/marketing/funnels` | [usage/funnels.md](docs/usage/funnels.md) |
|
|
29
|
-
| **Websites & install guide** — the tracked sites, their live state and capture options; a guided tracker install that checks the first pageview | `/modules/marketing/websites` | [install.md](docs/install.md#2-register-a-website) |
|
|
30
|
-
| **First-party tracker** — cookieless script, SPA-aware, custom events API | visitor sites | [usage/tracking.md](docs/usage/tracking.md) |
|
|
31
|
-
| **Settings** — collection switch, retentions, heatmap sampling | `/modules/marketing/settings` | [usage/settings.md](docs/usage/settings.md) |
|
|
32
|
-
|
|
33
|
-
<p align="center">
|
|
34
|
-
<img src="docs/screenshots/heatmap.png" alt="Pages & heatmaps: the tracked pages with their views and heat bars on the left, and on the right the click heatmap of the selected page drawn over its snapshot, with count pins on the hottest elements and the Most clicked list beside it" width="900">
|
|
35
|
-
</p>
|
|
36
|
-
<p align="center">
|
|
37
|
-
<em>Click heatmap over the page itself. Clicks are anchored to the element
|
|
38
|
-
they hit, so they stay on the right button at every viewport width.</em>
|
|
39
|
-
</p>
|
|
40
|
-
|
|
41
|
-
<p align="center">
|
|
42
|
-
<img src="docs/screenshots/funnel.png" alt="Funnel report: entered, completed, end-to-end and biggest-loss KPIs over the steps figure, each step with its share of entered sessions and the sessions lost before the next one, the worst step flagged" width="900">
|
|
43
|
-
</p>
|
|
44
|
-
<p align="center">
|
|
45
|
-
<em>Conversion funnels with per-step drop-off. Computed at read time over
|
|
46
|
-
the period's sessions, so a new definition immediately scores past traffic.</em>
|
|
47
|
-
</p>
|
|
48
|
-
|
|
49
|
-
<p align="center">
|
|
50
|
-
<img src="docs/screenshots/experiments.png" alt="A/B test report: the verdict sentence with the relative lift, the confidence and the exposed sessions, the sample ratio check, then each arm step by step with A neutral and B in the primary colour" width="900">
|
|
51
|
-
</p>
|
|
52
|
-
<p align="center">
|
|
53
|
-
<em>The same funnel split into A/B arms, arm against arm at every step.
|
|
54
|
-
Verdicts answer "not enough data" rather than overclaim — a sample too
|
|
55
|
-
thin shows raw counts, never bars.</em>
|
|
56
|
-
</p>
|
|
57
|
-
|
|
58
|
-
## What makes it hold
|
|
59
|
-
|
|
60
|
-
- **First-party and cookieless.** Visitors are identified by a server-side
|
|
61
|
-
anonymous hash (salted monthly, raw inputs never stored) — the shape
|
|
62
|
-
audience-measurement consent exemptions ask for. Events store no IP, no
|
|
63
|
-
user agent, no headers. Page content is stored in one place only — the
|
|
64
|
-
heatmap's page snapshots — and that is opt-in per site, form values
|
|
65
|
-
always masked, under a short retention of its own.
|
|
66
|
-
- **Dashboards never scan raw events.** Statistics are rolled up at write
|
|
67
|
-
time into one bounded row per website-day, counters as native server-side
|
|
68
|
-
increments; raw events are kept short-term only for heatmaps and funnel
|
|
69
|
-
computation.
|
|
70
|
-
- **Heatmaps work on any site.** The surface is keyed on the pathnames the
|
|
71
|
-
tracker reports — no route registry, no sitemap, no framework convention —
|
|
72
|
-
clicks are anchored to the element they hit, not to screen coordinates,
|
|
73
|
-
and the backdrop is a snapshot the tracker captured in a visitor's
|
|
74
|
-
browser, so it shows on sites that refuse framing (most of them) and on
|
|
75
|
-
client-rendered ones alike.
|
|
76
|
-
- **A/B without an experiment server or a client SDK.** A split is a
|
|
77
|
-
facet of a funnel, not a second object: variations are assigned
|
|
78
|
-
server-side from the same anonymous visitor hash, the page asks with one
|
|
79
|
-
call (`await dmsMarketing.variation("key")`), and the funnel's own steps
|
|
80
|
-
score the arms — z-test verdicts that answer "not enough data" rather
|
|
81
|
-
than overclaim.
|
|
82
|
-
- **Tenant isolation is structural.** Analytics tables live in per-tenant
|
|
83
|
-
database instances, the same model as the rest of the DMS — not a filter
|
|
84
|
-
someone can forget.
|
|
85
|
-
|
|
86
|
-
The reasoning behind each choice is in
|
|
87
|
-
[docs/architecture.md](docs/architecture.md).
|
|
10
|
+
First-party marketing analytics for the AntelopeJS DMS: traffic, funnels, A/B splits and heatmaps.
|
|
88
11
|
|
|
89
|
-
|
|
12
|
+
</div>
|
|
90
13
|
|
|
91
|
-
|
|
92
|
-
development playground.
|
|
93
|
-
- **[Usage guides](docs/usage/)** — one per feature, linked in the table above.
|
|
94
|
-
- **[Architecture](docs/architecture.md)** — data flow, tenancy, auth model,
|
|
95
|
-
event contract, HTTP surface, heatmap internals, phasing.
|
|
96
|
-
- **[Known issues](KNOWN-ISSUES.md)** — the defects found end-to-end and
|
|
97
|
-
how each was closed; none is open.
|
|
14
|
+

|
|
98
15
|
|
|
99
|
-
##
|
|
16
|
+
## What it does
|
|
100
17
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[architecture.md](docs/architecture.md#phasing).
|
|
18
|
+
- Shows pageviews, sessions, new visitors and custom events against the previous period, with acquisition channels and UTM campaigns.
|
|
19
|
+
- Draws clicks and scroll depth over a snapshot of any tracked page, even on sites that refuse framing.
|
|
20
|
+
- Measures ordered conversion funnels with per-step drop-off, optionally split into server-assigned A/B variations.
|
|
21
|
+
- Stays first-party and cookieless: no external service, no IP or user agent stored, and the data stays in the project's MongoDB.
|
|
106
22
|
|
|
107
|
-
##
|
|
23
|
+
## Install
|
|
108
24
|
|
|
109
|
-
|
|
110
|
-
commands from the repository root.
|
|
25
|
+
Run the AntelopeJS CLI from the root of a project that already loads `@antelopejs/dms`:
|
|
111
26
|
|
|
112
27
|
```bash
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
28
|
+
ajs project modules add @antelopejs/dms-marketing
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
Restart the backend, then the frontend, and open **Modules › Marketing**. Click **Add a website** on the Websites page: the install guide that opens gives the tracker snippet, in HTML, Nuxt or Google Tag Manager form. In HTML:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<script defer src="https://<backend>/api/marketing/tracker.js"
|
|
37
|
+
data-website-id="<website id>"></script>
|
|
120
38
|
```
|
|
121
39
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
`
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
40
|
+
Behind a reverse proxy, set the DMS `auth.trustedProxies` option: see [Installation](https://dms.antelopejs.com/docs/modules/marketing/installation).
|
|
41
|
+
|
|
42
|
+
## Compatibility
|
|
43
|
+
|
|
44
|
+
| Package | Version |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `@antelopejs/dms` | `>=0.9.0 <1.0.0` |
|
|
47
|
+
| `@antelopejs/interface-dms` | `>=0.7.2 <1.0.0` |
|
|
48
|
+
| `@antelopejs/dms-frontend` (renderer) | `>=0.6.0 <0.7.0` |
|
|
49
|
+
| `@antelopejs/interface-dms-marketing` | `>=0.5.0 <0.6.0` |
|
|
50
|
+
| `@antelopejs/core` (development dependency) | `>=1.16.0 <2` |
|
|
51
|
+
| Database (development dependency) | `@antelopejs/mongodb` `1.4.3` |
|
|
52
|
+
|
|
53
|
+
On DMS 0.8, use `@antelopejs/dms-marketing` 0.4.
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
- [Introduction](https://dms.antelopejs.com/docs/modules/marketing/introduction)
|
|
58
|
+
- [Installation](https://dms.antelopejs.com/docs/modules/marketing/installation)
|
|
59
|
+
- [Configuration](https://dms.antelopejs.com/docs/modules/marketing/configuration)
|
|
60
|
+
- [Usage](https://dms.antelopejs.com/docs/modules/marketing/usage/overview)
|
|
61
|
+
- [Extending](https://dms.antelopejs.com/docs/modules/marketing/extending)
|
|
62
|
+
- [FAQ](https://dms.antelopejs.com/docs/modules/marketing/faq)
|
|
63
|
+
- [Architecture](https://dms.antelopejs.com/docs/modules/marketing/architecture)
|
|
64
|
+
|
|
65
|
+
The guide's sources live in [`packages/dms-marketing/docs`](https://github.com/AntelopeJS/dms-marketing/tree/main/packages/dms-marketing/docs); [`KNOWN-ISSUES.md`](https://github.com/AntelopeJS/dms-marketing/tree/main/packages/dms-marketing/KNOWN-ISSUES.md) lists the defects found end to end and how each was closed. The module ships the `dms-marketing` Claude Code skill in [`packages/dms-marketing/skills`](https://github.com/AntelopeJS/dms-marketing/tree/main/packages/dms-marketing/skills), declared under `antelopeJs.skills`.
|
|
66
|
+
|
|
67
|
+
## Contributing
|
|
68
|
+
|
|
69
|
+
This package lives in the [`AntelopeJS/dms-marketing`](https://github.com/AntelopeJS/dms-marketing) pnpm workspace, next to `@antelopejs/interface-dms-marketing`. Read [CONTRIBUTING.md](https://github.com/AntelopeJS/dms-marketing/blob/main/CONTRIBUTING.md) and the [repository README](https://github.com/AntelopeJS/dms-marketing#contributing) for the development commands.
|
|
144
70
|
|
|
145
71
|
## License
|
|
146
72
|
|
|
147
|
-
Apache-2.0
|
|
73
|
+
[Apache-2.0](./LICENSE)
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export interface DashboardTrackingConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
websiteName: string;
|
|
4
|
+
excludePaths: string[];
|
|
5
|
+
}
|
|
1
6
|
export interface DmsMarketingConfig {
|
|
2
7
|
trackerEnabled: boolean;
|
|
3
8
|
rawEventsRetention: number;
|
|
@@ -7,8 +12,12 @@ export interface DmsMarketingConfig {
|
|
|
7
12
|
heatmapSampleRate: number;
|
|
8
13
|
visitorHashSecret: string;
|
|
9
14
|
geoipDatabasePath: string;
|
|
15
|
+
dashboardTracking: DashboardTrackingConfig;
|
|
10
16
|
}
|
|
11
|
-
export
|
|
17
|
+
export type DmsMarketingConfigInput = Partial<Omit<DmsMarketingConfig, "dashboardTracking">> & {
|
|
18
|
+
dashboardTracking?: Partial<DashboardTrackingConfig>;
|
|
19
|
+
};
|
|
20
|
+
export declare function setConfig(input?: DmsMarketingConfigInput): void;
|
|
12
21
|
export declare function applyConfigOverrides(overrides: Partial<DmsMarketingConfig>): void;
|
|
13
22
|
export declare function getBaseConfig(): DmsMarketingConfig;
|
|
14
23
|
export declare function getConfig(): DmsMarketingConfig;
|
package/dist/config.js
CHANGED
|
@@ -6,6 +6,8 @@ exports.getBaseConfig = getBaseConfig;
|
|
|
6
6
|
exports.getConfig = getConfig;
|
|
7
7
|
const defu_1 = require("defu");
|
|
8
8
|
const constants_1 = require("./types/constants");
|
|
9
|
+
const DEFAULT_DASHBOARD_WEBSITE_NAME = "Dashboard";
|
|
10
|
+
const DASHBOARD_PATH_PATTERN = /^\/[^*,\s]*(?:\/\*\*?)?$/;
|
|
9
11
|
const DEFAULT_CONFIG = {
|
|
10
12
|
trackerEnabled: true,
|
|
11
13
|
rawEventsRetention: constants_1.DEFAULT_RAW_EVENTS_RETENTION_MS,
|
|
@@ -15,7 +17,30 @@ const DEFAULT_CONFIG = {
|
|
|
15
17
|
heatmapSampleRate: constants_1.DEFAULT_HEATMAP_SAMPLE_RATIO,
|
|
16
18
|
visitorHashSecret: "",
|
|
17
19
|
geoipDatabasePath: "",
|
|
20
|
+
dashboardTracking: {
|
|
21
|
+
enabled: false,
|
|
22
|
+
websiteName: DEFAULT_DASHBOARD_WEBSITE_NAME,
|
|
23
|
+
excludePaths: [],
|
|
24
|
+
},
|
|
18
25
|
};
|
|
26
|
+
function isDashboardPathPattern(value) {
|
|
27
|
+
return typeof value === "string" && DASHBOARD_PATH_PATTERN.test(value);
|
|
28
|
+
}
|
|
29
|
+
function parseDashboardTracking(input) {
|
|
30
|
+
const value = input && typeof input === "object"
|
|
31
|
+
? input
|
|
32
|
+
: {};
|
|
33
|
+
const name = typeof value.websiteName === "string" ? value.websiteName.trim() : "";
|
|
34
|
+
return {
|
|
35
|
+
enabled: value.enabled === true,
|
|
36
|
+
websiteName: name.length > 0 && name.length <= constants_1.MAX_NAME_LENGTH
|
|
37
|
+
? name
|
|
38
|
+
: DEFAULT_DASHBOARD_WEBSITE_NAME,
|
|
39
|
+
excludePaths: Array.isArray(value.excludePaths)
|
|
40
|
+
? [...new Set(value.excludePaths.filter(isDashboardPathPattern))]
|
|
41
|
+
: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
19
44
|
let baseConfig = DEFAULT_CONFIG;
|
|
20
45
|
let globalConfig = DEFAULT_CONFIG;
|
|
21
46
|
let runtimeOverrides = {};
|
|
@@ -23,7 +48,10 @@ function mergeEffective() {
|
|
|
23
48
|
globalConfig = (0, defu_1.defu)(runtimeOverrides, baseConfig);
|
|
24
49
|
}
|
|
25
50
|
function setConfig(input) {
|
|
26
|
-
baseConfig =
|
|
51
|
+
baseConfig = {
|
|
52
|
+
...(0, defu_1.defu)(input ?? {}, DEFAULT_CONFIG),
|
|
53
|
+
dashboardTracking: parseDashboardTracking(input?.dashboardTracking),
|
|
54
|
+
};
|
|
27
55
|
mergeEffective();
|
|
28
56
|
}
|
|
29
57
|
function applyConfigOverrides(overrides) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAsHA,8BAMC;AAED,oDAKC;AAGD,sCAEC;AAED,8BAEC;AA5ID,+BAA4B;AAC5B,iDAO2B;AAqD3B,MAAM,8BAA8B,GAAG,WAAW,CAAC;AAEnD,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AAE1D,MAAM,cAAc,GAAuB;IACzC,cAAc,EAAE,IAAI;IACpB,kBAAkB,EAAE,2CAA+B;IACnD,mBAAmB,EAAE,2CAA+B;IACpD,iBAAiB,EAAE,yCAA6B;IAChD,kBAAkB,EAAE,2CAA+B;IACnD,iBAAiB,EAAE,wCAA4B;IAC/C,iBAAiB,EAAE,EAAE;IACrB,iBAAiB,EAAE,EAAE;IACrB,iBAAiB,EAAE;QACjB,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,8BAA8B;QAC3C,YAAY,EAAE,EAAE;KACjB;CACF,CAAC;AAEF,SAAS,sBAAsB,CAAC,KAAc;IAC5C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC;AAQD,SAAS,sBAAsB,CAAC,KAAc;IAC5C,MAAM,KAAK,GACT,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAChC,CAAC,CAAE,KAAiE;QACpE,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GACR,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI;QAC/B,WAAW,EACT,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,2BAAe;YAC/C,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,8BAA8B;QACpC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;YAC7C,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;YACjE,CAAC,CAAC,EAAE;KACP,CAAC;AACJ,CAAC;AAED,IAAI,UAAU,GAAuB,cAAc,CAAC;AACpD,IAAI,YAAY,GAAuB,cAAc,CAAC;AACtD,IAAI,gBAAgB,GAAgC,EAAE,CAAC;AAEvD,SAAS,cAAc;IACrB,YAAY,GAAG,IAAA,WAAI,EAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,SAAS,CAAC,KAA+B;IACvD,UAAU,GAAG;QACX,GAAG,IAAA,WAAI,EAAC,KAAK,IAAI,EAAE,EAAE,cAAc,CAAC;QACpC,iBAAiB,EAAE,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,CAAC;KACpE,CAAC;IACF,cAAc,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,oBAAoB,CAClC,SAAsC;IAEtC,gBAAgB,GAAG,SAAS,CAAC;IAC7B,cAAc,EAAE,CAAC;AACnB,CAAC;AAGD,SAAgB,aAAa;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
|
@@ -12,12 +12,14 @@ declare const FunnelsModel_base: {
|
|
|
12
12
|
delete(id: string): Promise<number>;
|
|
13
13
|
};
|
|
14
14
|
readonly schemaName: string;
|
|
15
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<Funnel>;
|
|
15
16
|
fromPlainData(obj: any): Funnel;
|
|
16
17
|
fromDatabase(obj: any): Funnel | undefined;
|
|
17
18
|
toDatabase(obj: any): Record<string, any>;
|
|
18
19
|
validate(obj: unknown, options?: import("@antelopejs/interface-database-decorators").ValidateInputOptions): import("@antelopejs/interface-database-decorators").ValidationResult;
|
|
19
20
|
};
|
|
20
21
|
export declare class FunnelsModel extends FunnelsModel_base {
|
|
22
|
+
compareDeclared(expected: Funnel, patch: Partial<Funnel>): Promise<boolean>;
|
|
21
23
|
deleteByWebsite(websiteId: string): Promise<number>;
|
|
22
24
|
listByWebsite(websiteId: string): Promise<Funnel[]>;
|
|
23
25
|
listRunning(websiteId: string): Promise<Funnel[]>;
|
|
@@ -5,6 +5,24 @@ const interface_database_decorators_1 = require("@antelopejs/interface-database-
|
|
|
5
5
|
const funnels_table_1 = require("../tables/funnels.table");
|
|
6
6
|
const RUNNING_STATUS = "running";
|
|
7
7
|
class FunnelsModel extends (0, interface_database_decorators_1.BasicDataModel)(funnels_table_1.Funnel, funnels_table_1.funnelsTableName) {
|
|
8
|
+
async compareDeclared(expected, patch) {
|
|
9
|
+
const count = await this.table
|
|
10
|
+
.filter((row) => row
|
|
11
|
+
.key("_id")
|
|
12
|
+
.eq(expected._id)
|
|
13
|
+
.and(row.key("websiteId").eq(expected.websiteId))
|
|
14
|
+
.and(row.key("name").eq(expected.name))
|
|
15
|
+
.and(row.key("steps").eq(expected.steps))
|
|
16
|
+
.and(row.key("conversionWindowMs").eq(expected.conversionWindowMs))
|
|
17
|
+
.and(row.key("experiment").eq(expected.experiment))
|
|
18
|
+
.and(row
|
|
19
|
+
.key("declaredHash")
|
|
20
|
+
.default("")
|
|
21
|
+
.eq(expected.declaredHash ?? "")))
|
|
22
|
+
.update(FunnelsModel.toDatabase({ ...patch, updatedAt: new Date() }))
|
|
23
|
+
.run();
|
|
24
|
+
return count === 1;
|
|
25
|
+
}
|
|
8
26
|
async deleteByWebsite(websiteId) {
|
|
9
27
|
return this.table.getAll(websiteId, "websiteId").delete().run();
|
|
10
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnels.model.js","sourceRoot":"","sources":["../../../src/db/models/funnels.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,2DAIiC;AAEjC,MAAM,cAAc,GAAG,SAAS,CAAC;AAEjC,MAAa,YAAa,SAAQ,IAAA,8CAAc,EAAC,sBAAM,EAAE,gCAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"funnels.model.js","sourceRoot":"","sources":["../../../src/db/models/funnels.model.ts"],"names":[],"mappings":"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"}
|
package/dist/db/models/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./funnels.model"), exports);
|
|
18
18
|
__exportStar(require("./marketing_events.model"), exports);
|
|
19
|
+
__exportStar(require("./marketing_imports.model"), exports);
|
|
19
20
|
__exportStar(require("./marketing_preferences.model"), exports);
|
|
20
21
|
__exportStar(require("./marketing_sessions.model"), exports);
|
|
21
22
|
__exportStar(require("./marketing_settings.model"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,2DAAyC;AACzC,gEAA8C;AAC9C,6DAA2C;AAC3C,6DAA2C;AAC3C,yDAAuC;AACvC,6DAA2C;AAC3C,mDAAiC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,2DAAyC;AACzC,4DAA0C;AAC1C,gEAA8C;AAC9C,6DAA2C;AAC3C,6DAA2C;AAC3C,yDAAuC;AACvC,6DAA2C;AAC3C,mDAAiC"}
|
|
@@ -50,6 +50,7 @@ declare const MarketingEventsModel_base: {
|
|
|
50
50
|
delete(id: string): Promise<number>;
|
|
51
51
|
};
|
|
52
52
|
readonly schemaName: string;
|
|
53
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MarketingEvent>;
|
|
53
54
|
fromPlainData(obj: any): MarketingEvent;
|
|
54
55
|
fromDatabase(obj: any): MarketingEvent | undefined;
|
|
55
56
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { MarketingImport } from "../tables/marketing_imports.table";
|
|
2
|
+
declare const MarketingImportsModel_base: {
|
|
3
|
+
new (database: import("@antelopejs/interface-database").SchemaInstance<any>): {
|
|
4
|
+
readonly table: import("@antelopejs/interface-database").Table<MarketingImport>;
|
|
5
|
+
readonly database: import("@antelopejs/interface-database").SchemaInstance<any>;
|
|
6
|
+
get(id: string): PromiseLike<MarketingImport | undefined>;
|
|
7
|
+
getBy(index: keyof MarketingImport, ...keys: any[]): PromiseLike<MarketingImport[]>;
|
|
8
|
+
getAll(): PromiseLike<MarketingImport[]>;
|
|
9
|
+
insert(obj: import("@antelopejs/interface-database-decorators").DeepPartial<MarketingImport> | import("@antelopejs/interface-database-decorators").DeepPartial<MarketingImport>[], options?: import("@antelopejs/interface-database-decorators").ValidateOptions): Promise<string[]>;
|
|
10
|
+
update(id: string, obj: import("@antelopejs/interface-database-decorators").DeepPartial<MarketingImport>, options?: import("@antelopejs/interface-database-decorators").ValidateOptions): Promise<number>;
|
|
11
|
+
update(obj: import("@antelopejs/interface-database-decorators").DeepPartial<MarketingImport>, options?: import("@antelopejs/interface-database-decorators").ValidateOptions): Promise<number>;
|
|
12
|
+
delete(id: string): Promise<number>;
|
|
13
|
+
};
|
|
14
|
+
readonly schemaName: string;
|
|
15
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MarketingImport>;
|
|
16
|
+
fromPlainData(obj: any): MarketingImport;
|
|
17
|
+
fromDatabase(obj: any): MarketingImport | undefined;
|
|
18
|
+
toDatabase(obj: any): Record<string, any>;
|
|
19
|
+
validate(obj: unknown, options?: import("@antelopejs/interface-database-decorators").ValidateInputOptions): import("@antelopejs/interface-database-decorators").ValidationResult;
|
|
20
|
+
};
|
|
21
|
+
export declare class MarketingImportsModel extends MarketingImportsModel_base {
|
|
22
|
+
listByWebsite(websiteId: string): Promise<MarketingImport[]>;
|
|
23
|
+
getImportedThroughByWebsites(websiteIds: string[]): Promise<Map<string, number>>;
|
|
24
|
+
releaseClaim(id: string, token: string): Promise<void>;
|
|
25
|
+
deleteByWebsite(websiteId: string): Promise<number>;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MarketingImportsModel = void 0;
|
|
4
|
+
const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
|
|
5
|
+
const marketing_imports_table_1 = require("../tables/marketing_imports.table");
|
|
6
|
+
class MarketingImportsModel extends (0, interface_database_decorators_1.BasicDataModel)(marketing_imports_table_1.MarketingImport, marketing_imports_table_1.marketingImportsTableName) {
|
|
7
|
+
async listByWebsite(websiteId) {
|
|
8
|
+
return this.table.getAll(websiteId, "websiteId").run();
|
|
9
|
+
}
|
|
10
|
+
async getImportedThroughByWebsites(websiteIds) {
|
|
11
|
+
const rows = await Promise.all(websiteIds.map((websiteId) => this.listByWebsite(websiteId)));
|
|
12
|
+
const through = new Map();
|
|
13
|
+
for (const row of rows.flat()) {
|
|
14
|
+
if (row.status === "done" && row.importedThrough) {
|
|
15
|
+
const at = new Date(row.importedThrough).getTime();
|
|
16
|
+
through.set(row.websiteId, Math.max(through.get(row.websiteId) ?? at, at));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return through;
|
|
20
|
+
}
|
|
21
|
+
async releaseClaim(id, token) {
|
|
22
|
+
const outcome = await this.table
|
|
23
|
+
.atomicMutation(id, {
|
|
24
|
+
type: "deleteIfEqual",
|
|
25
|
+
field: "claimToken",
|
|
26
|
+
expectedValue: token,
|
|
27
|
+
})
|
|
28
|
+
.run();
|
|
29
|
+
if (outcome !== "applied") {
|
|
30
|
+
throw new Error("Analytics import claim release was not confirmed");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async deleteByWebsite(websiteId) {
|
|
34
|
+
return this.table.getAll(websiteId, "websiteId").delete().run();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.MarketingImportsModel = MarketingImportsModel;
|
|
38
|
+
//# sourceMappingURL=marketing_imports.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marketing_imports.model.js","sourceRoot":"","sources":["../../../src/db/models/marketing_imports.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,+EAG2C;AAE3C,MAAa,qBAAsB,SAAQ,IAAA,8CAAc,EACvD,yCAAe,EACf,mDAAyB,CAC1B;IACC,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC;IACzD,CAAC;IAOD,KAAK,CAAC,4BAA4B,CAChC,UAAoB;QAEpB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAC5B,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAC7D,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACjD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC;gBACnD,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,SAAS,EACb,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAC/C,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAGD,KAAK,CAAC,YAAY,CAAC,EAAU,EAAE,KAAa;QAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK;aAC7B,cAAc,CAAC,EAAE,EAAE;YAClB,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,YAAY;YACnB,aAAa,EAAE,KAAK;SACrB,CAAC;aACD,GAAG,EAAE,CAAC;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IAClE,CAAC;CACF;AAjDD,sDAiDC"}
|
|
@@ -12,6 +12,7 @@ declare const MarketingPreferencesModel_base: {
|
|
|
12
12
|
delete(id: string): Promise<number>;
|
|
13
13
|
};
|
|
14
14
|
readonly schemaName: string;
|
|
15
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MarketingPreferences>;
|
|
15
16
|
fromPlainData(obj: any): MarketingPreferences;
|
|
16
17
|
fromDatabase(obj: any): MarketingPreferences | undefined;
|
|
17
18
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -18,6 +18,7 @@ declare const MarketingSessionsModel_base: {
|
|
|
18
18
|
delete(id: string): Promise<number>;
|
|
19
19
|
};
|
|
20
20
|
readonly schemaName: string;
|
|
21
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MarketingSession>;
|
|
21
22
|
fromPlainData(obj: any): MarketingSession;
|
|
22
23
|
fromDatabase(obj: any): MarketingSession | undefined;
|
|
23
24
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -13,6 +13,7 @@ declare const MarketingSettingsModel_base: {
|
|
|
13
13
|
delete(id: string): Promise<number>;
|
|
14
14
|
};
|
|
15
15
|
readonly schemaName: string;
|
|
16
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<MarketingSettings>;
|
|
16
17
|
fromPlainData(obj: any): MarketingSettings;
|
|
17
18
|
fromDatabase(obj: any): MarketingSettings | undefined;
|
|
18
19
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -12,6 +12,7 @@ declare const PageSnapshotsModel_base: {
|
|
|
12
12
|
delete(id: string): Promise<number>;
|
|
13
13
|
};
|
|
14
14
|
readonly schemaName: string;
|
|
15
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<PageSnapshot>;
|
|
15
16
|
fromPlainData(obj: any): PageSnapshot;
|
|
16
17
|
fromDatabase(obj: any): PageSnapshot | undefined;
|
|
17
18
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -21,6 +22,7 @@ export declare class PageSnapshotsModel extends PageSnapshotsModel_base {
|
|
|
21
22
|
getByPath(websiteId: string, url: string): Promise<PageSnapshot[]>;
|
|
22
23
|
countByWebsite(websiteId: string, url?: string): Promise<number>;
|
|
23
24
|
upsert(row: PageSnapshot): Promise<void>;
|
|
25
|
+
replaceIfUnchanged(expected: PageSnapshot, patch: Partial<PageSnapshot>): Promise<boolean>;
|
|
24
26
|
deleteByWebsite(websiteId: string, url?: string): Promise<number>;
|
|
25
27
|
deleteOlderThan(cutoff: Date): Promise<number>;
|
|
26
28
|
private byWebsite;
|
|
@@ -17,6 +17,20 @@ class PageSnapshotsModel extends (0, interface_database_decorators_1.BasicDataMo
|
|
|
17
17
|
async upsert(row) {
|
|
18
18
|
await this.table.insert(row, { conflict: "replace" }).run();
|
|
19
19
|
}
|
|
20
|
+
async replaceIfUnchanged(expected, patch) {
|
|
21
|
+
const count = await this.table
|
|
22
|
+
.filter((row) => row
|
|
23
|
+
.key("_id")
|
|
24
|
+
.eq(expected._id)
|
|
25
|
+
.and(row.key("capturedAt").eq(expected.capturedAt))
|
|
26
|
+
.and(row
|
|
27
|
+
.key("declaredHash")
|
|
28
|
+
.default("")
|
|
29
|
+
.eq(expected.declaredHash ?? "")))
|
|
30
|
+
.update(PageSnapshotsModel.toDatabase(patch))
|
|
31
|
+
.run();
|
|
32
|
+
return count === 1;
|
|
33
|
+
}
|
|
20
34
|
async deleteByWebsite(websiteId, url) {
|
|
21
35
|
return this.byWebsite(websiteId, url).delete().run();
|
|
22
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page_snapshots.model.js","sourceRoot":"","sources":["../../../src/db/models/page_snapshots.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,yEAGwC;AACxC,2CAAgD;AAEhD,MAAa,kBAAmB,SAAQ,IAAA,8CAAc,EACpD,mCAAY,EACZ,6CAAsB,CACvB;IAEC,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,GAAW;QAC5C,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC;aAChC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;aACvC,GAAG,EAAE,CAAC;IACX,CAAC;IAGD,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,GAAY;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAiB;QAC5B,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,GAAY;QACnD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,MAAY;QAChC,OAAO,IAAA,6BAAiB,EAAC,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAGO,SAAS,CAAC,SAAiB,EAAE,GAAY;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,CAAC;QACzD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"page_snapshots.model.js","sourceRoot":"","sources":["../../../src/db/models/page_snapshots.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,yEAGwC;AACxC,2CAAgD;AAEhD,MAAa,kBAAmB,SAAQ,IAAA,8CAAc,EACpD,mCAAY,EACZ,6CAAsB,CACvB;IAEC,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,GAAW;QAC5C,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC;aAChC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;aACvC,GAAG,EAAE,CAAC;IACX,CAAC;IAGD,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,GAAY;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAiB;QAC5B,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAC9D,CAAC;IAOD,KAAK,CAAC,kBAAkB,CACtB,QAAsB,EACtB,KAA4B;QAE5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK;aAC3B,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACd,GAAG;aACA,GAAG,CAAC,KAAK,CAAC;aACV,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;aAChB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;aAClD,GAAG,CACF,GAAG;aACA,GAAG,CAAC,cAAc,CAAC;aACnB,OAAO,CAAC,EAAE,CAAC;aACX,EAAE,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CACnC,CACJ;aACA,MAAM,CAAC,kBAAkB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;aAC5C,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,GAAY;QACnD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,MAAY;QAChC,OAAO,IAAA,6BAAiB,EAAC,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAGO,SAAS,CAAC,SAAiB,EAAE,GAAY;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,CAAC;QACzD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;CACF;AA7DD,gDA6DC"}
|
|
@@ -16,6 +16,7 @@ declare const WebsiteStatisticsModel_base: {
|
|
|
16
16
|
delete(id: string): Promise<number>;
|
|
17
17
|
};
|
|
18
18
|
readonly schemaName: string;
|
|
19
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<WebsiteStatistics>;
|
|
19
20
|
fromPlainData(obj: any): WebsiteStatistics;
|
|
20
21
|
fromDatabase(obj: any): WebsiteStatistics | undefined;
|
|
21
22
|
toDatabase(obj: any): Record<string, any>;
|
|
@@ -12,12 +12,14 @@ declare const WebsitesModel_base: {
|
|
|
12
12
|
delete(id: string): Promise<number>;
|
|
13
13
|
};
|
|
14
14
|
readonly schemaName: string;
|
|
15
|
+
readonly tableClass: import("@antelopejs/interface-database-decorators").Constructible<Website>;
|
|
15
16
|
fromPlainData(obj: any): Website;
|
|
16
17
|
fromDatabase(obj: any): Website | undefined;
|
|
17
18
|
toDatabase(obj: any): Record<string, any>;
|
|
18
19
|
validate(obj: unknown, options?: import("@antelopejs/interface-database-decorators").ValidateInputOptions): import("@antelopejs/interface-database-decorators").ValidationResult;
|
|
19
20
|
};
|
|
20
21
|
export declare class WebsitesModel extends WebsitesModel_base {
|
|
22
|
+
compareDeclared(expected: Website, patch: Partial<Website>): Promise<boolean>;
|
|
21
23
|
getByTenant(tenantId: string): Promise<Website[]>;
|
|
22
24
|
listIdsByTenant(tenantId: string): Promise<string[]>;
|
|
23
25
|
listTenantIds(): Promise<string[]>;
|
|
@@ -4,6 +4,35 @@ exports.WebsitesModel = void 0;
|
|
|
4
4
|
const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
|
|
5
5
|
const websites_table_1 = require("../tables/websites.table");
|
|
6
6
|
class WebsitesModel extends (0, interface_database_decorators_1.BasicDataModel)(websites_table_1.Website, websites_table_1.websitesTableName) {
|
|
7
|
+
async compareDeclared(expected, patch) {
|
|
8
|
+
const count = await this.table
|
|
9
|
+
.filter((row) => row
|
|
10
|
+
.key("_id")
|
|
11
|
+
.eq(expected._id)
|
|
12
|
+
.and(row.key("tenantId").eq(expected.tenantId))
|
|
13
|
+
.and(row.key("name").eq(expected.name))
|
|
14
|
+
.and(row.key("domain").eq(expected.domain))
|
|
15
|
+
.and(row
|
|
16
|
+
.key("extraDomains")
|
|
17
|
+
.default([])
|
|
18
|
+
.eq(expected.extraDomains ?? []))
|
|
19
|
+
.and(row.key("trackingEnabled").eq(expected.trackingEnabled))
|
|
20
|
+
.and(row
|
|
21
|
+
.key("snapshotsEnabled")
|
|
22
|
+
.default(false)
|
|
23
|
+
.eq(expected.snapshotsEnabled ?? false))
|
|
24
|
+
.and(row
|
|
25
|
+
.key("snapshotMaskText")
|
|
26
|
+
.default(false)
|
|
27
|
+
.eq(expected.snapshotMaskText ?? false))
|
|
28
|
+
.and(row
|
|
29
|
+
.key("declaredHash")
|
|
30
|
+
.default("")
|
|
31
|
+
.eq(expected.declaredHash ?? "")))
|
|
32
|
+
.update(WebsitesModel.toDatabase({ ...patch, updatedAt: new Date() }))
|
|
33
|
+
.run();
|
|
34
|
+
return count === 1;
|
|
35
|
+
}
|
|
7
36
|
async getByTenant(tenantId) {
|
|
8
37
|
return this.table
|
|
9
38
|
.getAll(tenantId, "tenantId")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websites.model.js","sourceRoot":"","sources":["../../../src/db/models/websites.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,6DAAsE;AAEtE,MAAa,aAAc,SAAQ,IAAA,8CAAc,EAAC,wBAAO,EAAE,kCAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"websites.model.js","sourceRoot":"","sources":["../../../src/db/models/websites.model.ts"],"names":[],"mappings":";;;AAAA,6FAA2E;AAC3E,6DAAsE;AAEtE,MAAa,aAAc,SAAQ,IAAA,8CAAc,EAAC,wBAAO,EAAE,kCAAiB,CAAC;IAE3E,KAAK,CAAC,eAAe,CACnB,QAAiB,EACjB,KAAuB;QAEvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK;aAC3B,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACd,GAAG;aACA,GAAG,CAAC,KAAK,CAAC;aACV,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;aAChB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aAC9C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aACtC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aAC1C,GAAG,CACF,GAAG;aACA,GAAG,CAAC,cAAc,CAAC;aACnB,OAAO,CAAC,EAAE,CAAC;aACX,EAAE,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CACnC;aACA,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;aAC5D,GAAG,CACF,GAAG;aACA,GAAG,CAAC,kBAAkB,CAAC;aACvB,OAAO,CAAC,KAAK,CAAC;aACd,EAAE,CAAC,QAAQ,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAC1C;aACA,GAAG,CACF,GAAG;aACA,GAAG,CAAC,kBAAkB,CAAC;aACvB,OAAO,CAAC,KAAK,CAAC;aACd,EAAE,CAAC,QAAQ,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAC1C;aACA,GAAG,CACF,GAAG;aACA,GAAG,CAAC,cAAc,CAAC;aACnB,OAAO,CAAC,EAAE,CAAC;aACX,EAAE,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CACnC,CACJ;aACA,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;aACrE,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;aAC5B,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC;aAC5B,GAAG,EAAE,CAAC;IACX,CAAC;IAGD,KAAK,CAAC,eAAe,CAAC,QAAgB;QACpC,OAAO,IAAI,CAAC,KAAK;aACd,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;aAC5B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;aAC5B,GAAG,EAAE,CAAC;IACX,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/D,CAAC;CACF;AAnED,sCAmEC"}
|