ghost 5.116.0 → 5.116.2
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/components/{tryghost-api-framework-5.116.0.tgz → tryghost-api-framework-5.116.2.tgz} +0 -0
- package/components/tryghost-constants-5.116.2.tgz +0 -0
- package/components/tryghost-custom-fonts-5.116.2.tgz +0 -0
- package/components/{tryghost-custom-theme-settings-service-5.116.0.tgz → tryghost-custom-theme-settings-service-5.116.2.tgz} +0 -0
- package/components/tryghost-domain-events-5.116.2.tgz +0 -0
- package/components/tryghost-donations-5.116.2.tgz +0 -0
- package/components/{tryghost-email-addresses-5.116.0.tgz → tryghost-email-addresses-5.116.2.tgz} +0 -0
- package/components/{tryghost-email-service-5.116.0.tgz → tryghost-email-service-5.116.2.tgz} +0 -0
- package/components/tryghost-email-suppression-list-5.116.2.tgz +0 -0
- package/components/{tryghost-html-to-plaintext-5.116.0.tgz → tryghost-html-to-plaintext-5.116.2.tgz} +0 -0
- package/components/tryghost-i18n-5.116.2.tgz +0 -0
- package/components/{tryghost-job-manager-5.116.0.tgz → tryghost-job-manager-5.116.2.tgz} +0 -0
- package/components/tryghost-link-replacer-5.116.2.tgz +0 -0
- package/components/{tryghost-magic-link-5.116.0.tgz → tryghost-magic-link-5.116.2.tgz} +0 -0
- package/components/{tryghost-member-attribution-5.116.0.tgz → tryghost-member-attribution-5.116.2.tgz} +0 -0
- package/components/{tryghost-member-events-5.116.0.tgz → tryghost-member-events-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-api-5.116.0.tgz → tryghost-members-api-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-csv-5.116.0.tgz → tryghost-members-csv-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-offers-5.116.0.tgz → tryghost-members-offers-5.116.2.tgz} +0 -0
- package/components/tryghost-milestones-5.116.2.tgz +0 -0
- package/components/{tryghost-mw-error-handler-5.116.0.tgz → tryghost-mw-error-handler-5.116.2.tgz} +0 -0
- package/components/{tryghost-mw-vhost-5.116.0.tgz → tryghost-mw-vhost-5.116.2.tgz} +0 -0
- package/components/tryghost-post-events-5.116.2.tgz +0 -0
- package/components/tryghost-post-revisions-5.116.2.tgz +0 -0
- package/components/tryghost-posts-service-5.116.2.tgz +0 -0
- package/components/{tryghost-prometheus-metrics-5.116.0.tgz → tryghost-prometheus-metrics-5.116.2.tgz} +0 -0
- package/components/tryghost-security-5.116.2.tgz +0 -0
- package/components/{tryghost-tiers-5.116.0.tgz → tryghost-tiers-5.116.2.tgz} +0 -0
- package/components/tryghost-webmentions-5.116.2.tgz +0 -0
- package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +9776 -11013
- package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +2 -2
- package/core/built/admin/assets/admin-x-demo/{index-a9601514.mjs → index-09325f38.mjs} +4 -4
- package/core/built/admin/assets/admin-x-demo/{modals-c1789d04.mjs → modals-1a9ae8b7.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{CodeEditorView-e9c9deb8.mjs → CodeEditorView-550846e0.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-f744cab7.mjs → index-4ce2fcd1.mjs} +78 -77
- package/core/built/admin/assets/admin-x-settings/{index-84580c3a.mjs → index-f3cb3f4d.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{modals-d9ca60c5.mjs → modals-6bc20529.mjs} +8 -8
- package/core/built/admin/assets/{chunk.524.8371443ef8f60db429d0.js → chunk.524.578de86e5014b911b05a.js} +8 -8
- package/core/built/admin/assets/{chunk.582.f90151775f2e53dd21d9.js → chunk.582.21bf3e37b5d84ac4b58a.js} +9 -9
- package/core/built/admin/assets/{chunk.713.e9027c0cc3c56110f5da.js → chunk.713.761d11035fe0bf3e557c.js} +2 -2
- package/core/built/admin/assets/{ghost-03b64c086f3c60cabc85fe7a7e2b640a.js → ghost-868c537d5c02ca65323d0122596a67ec.js} +57 -55
- package/core/built/admin/assets/posts/posts.js +5185 -5096
- package/core/built/admin/assets/stats/stats.js +6630 -6541
- package/core/built/admin/assets/{vendor-72026232b36d97babc6320917c16c321.js → vendor-8e3ee8261528bb429cfe78ce79a4a82a.js} +5 -5
- package/core/built/admin/index.html +5 -5
- package/core/frontend/helpers/ghost_head.js +9 -5
- package/core/frontend/public/ghost-stats.js +41 -74
- package/core/server/data/tinybird/datasources/_mv_hits.datasource +23 -0
- package/core/server/data/tinybird/datasources/analytics_events.datasource +14 -0
- package/core/server/data/tinybird/endpoints/api_kpis.pipe +161 -0
- package/core/server/data/tinybird/endpoints/api_top_browsers.pipe +52 -0
- package/core/server/data/tinybird/endpoints/api_top_devices.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_locations.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_os.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_pages.pipe +52 -0
- package/core/server/data/tinybird/endpoints/api_top_sources.pipe +24 -0
- package/core/server/data/tinybird/fixtures/analytics_events.ndjson +31 -0
- package/core/server/data/tinybird/pipes/filtered_sessions.pipe +42 -0
- package/core/server/data/tinybird/pipes/mv_hits.pipe +89 -0
- package/core/server/data/tinybird/pipes/mv_session_data.pipe +28 -0
- package/core/server/data/tinybird/readme.md +47 -0
- package/core/server/data/tinybird/tests/api_kpis.yaml +207 -0
- package/core/server/data/tinybird/tests/api_top_browsers.yaml +89 -0
- package/core/server/data/tinybird/tests/api_top_devices.yaml +69 -0
- package/core/server/data/tinybird/tests/api_top_locations.yaml +95 -0
- package/core/server/data/tinybird/tests/api_top_os.yaml +73 -0
- package/core/server/data/tinybird/tests/api_top_pages.yaml +86 -0
- package/core/server/data/tinybird/tests/api_top_sources.yaml +118 -0
- package/package.json +59 -59
- package/yarn.lock +37 -56
- package/components/tryghost-constants-5.116.0.tgz +0 -0
- package/components/tryghost-custom-fonts-5.116.0.tgz +0 -0
- package/components/tryghost-domain-events-5.116.0.tgz +0 -0
- package/components/tryghost-donations-5.116.0.tgz +0 -0
- package/components/tryghost-email-suppression-list-5.116.0.tgz +0 -0
- package/components/tryghost-i18n-5.116.0.tgz +0 -0
- package/components/tryghost-link-replacer-5.116.0.tgz +0 -0
- package/components/tryghost-milestones-5.116.0.tgz +0 -0
- package/components/tryghost-post-events-5.116.0.tgz +0 -0
- package/components/tryghost-post-revisions-5.116.0.tgz +0 -0
- package/components/tryghost-posts-service-5.116.0.tgz +0 -0
- package/components/tryghost-security-5.116.0.tgz +0 -0
- package/components/tryghost-webmentions-5.116.0.tgz +0 -0
- /package/core/built/admin/assets/{chunk.713.e9027c0cc3c56110f5da.js.LICENSE.txt → chunk.713.761d11035fe0bf3e557c.js.LICENSE.txt} +0 -0
|
@@ -8470,10 +8470,10 @@ if("object"==typeof t[n]){if(!e(t[n],r[n]))return!1}else if(t[n]!==r[n])return!1
|
|
|
8470
8470
|
function r(e){return"object"==typeof e&&Boolean(e)}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
8471
8471
|
class n extends t.default{getStyles(e,t){return[].concat(...[...e.filter(r),t].map((e=>Object.entries(e).map((([e,t])=>[Ember.String.dasherize(e),t])))))}setStyles(e,t){const r=this._oldStyles||new Set
|
|
8472
8472
|
t.forEach((([t,n])=>{let i=""
|
|
8473
|
-
n&&n.includes("!important")&&(i="important",n=n.replace("!important","")),t=Ember.String.dasherize(t),e.style.setProperty(t,n,i),r.delete(t)})),r.forEach((t=>e.style.removeProperty(t))),this._oldStyles=new Set(t.map((e=>e[0])))}modify(e,t,r){this.setStyles(e,this.getStyles(t,r))}}e.default=n})),define("ember-svg-jar/helpers/svg-jar",["exports","ember-svg-jar/utils/make-svg"],(function(e,t){"use strict"
|
|
8474
|
-
function
|
|
8475
|
-
try{t=require(`ember-svg-jar/inlined/${e}`).default}catch(
|
|
8476
|
-
e.default=Ember.Helper.helper((function([e],t){return
|
|
8473
|
+
n&&n.includes("!important")&&(i="important",n=n.replace("!important","")),t=Ember.String.dasherize(t),e.style.setProperty(t,n,i),r.delete(t)})),r.forEach((t=>e.style.removeProperty(t))),this._oldStyles=new Set(t.map((e=>e[0])))}modify(e,t,r){this.setStyles(e,this.getStyles(t,r))}}e.default=n})),define("ember-svg-jar/helpers/svg-jar",["exports","ember-svg-jar/utils/make-svg","@embroider/macros/es-compat2"],(function(e,t,r){"use strict"
|
|
8474
|
+
function n(e){let t=null
|
|
8475
|
+
try{t=require(`ember-svg-jar/inlined/${e}`).default}catch(n){}try{t=(0,r.default)(require(`../inlined/${e}`)).default}catch(n){}return t}function i(e,r){return(0,t.default)(e,r,n)}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.svgJar=i
|
|
8476
|
+
e.default=Ember.Helper.helper((function([e],t){return i(e,t)}))})),define("ember-svg-jar/inlined/activity-placeholder",["exports"],(function(e){"use strict"
|
|
8477
8477
|
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
8478
8478
|
e.default={content:'<path clip-rule="evenodd" d="M9.295.422a11 11 0 0112.924 11.614.5.5 0 11-.998-.072 10 10 0 10-9.257 9.257.5.5 0 11.072.998A11 11 0 019.295.422zm.288 4.546a6.5 6.5 0 017.961 4.657.5.5 0 11-.968.25 5.499 5.499 0 10-6.7 6.7.5.5 0 01-.251.97 6.5 6.5 0 01-.042-12.577zm1.388 5.02a1.21 1.21 0 01.725.087h.002l11.4 5.21a1.19 1.19 0 01-.163 2.187L18.92 18.94l-1.449 3.987v.002a1.18 1.18 0 01-2.117.223.5.5 0 01-.029-.054l-5.217-11.394a1.21 1.21 0 01.863-1.716zm.312.997a.21.21 0 00-.274.284l.006.013 5.203 11.363a.18.18 0 00.31-.052l.002-.004 1.53-4.21a.5.5 0 01.298-.299l4.24-1.55.017-.005a.19.19 0 00.11-.27.19.19 0 00-.066-.07l-11.375-5.2z"/>',attrs:{fill:"none",viewBox:"0 0 24 24"}}})),define("ember-svg-jar/inlined/add-view",["exports"],(function(e){"use strict"
|
|
8479
8479
|
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
@@ -9522,4 +9522,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
|
|
|
9522
9522
|
return this}get(e){let t=this._data[e]
|
|
9523
9523
|
return t===r.UNDEFINED_KEY?void 0:t}set(e,t){return this._data[e]=t,this}delete(e){return this._data[e]=r.UNDEFINED_KEY,!0}}}))
|
|
9524
9524
|
|
|
9525
|
-
//# sourceMappingURL=vendor-
|
|
9525
|
+
//# sourceMappingURL=vendor-ae0ef37383c371db894ddba69e9dfe7c.map
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Ghost Admin</title>
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.116%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2270b6e1c5ab%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%
|
|
11
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.116%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2270b6e1c5ab%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22fd54878445%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22f374d17369%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%22bff4438287%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%222c1461dad3%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%22ffcc9f090c%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
|
|
12
12
|
|
|
13
13
|
<meta name="HandheldFriendly" content="True" />
|
|
14
14
|
<meta name="MobileOptimized" content="320" />
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
|
|
57
57
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
58
58
|
|
|
59
|
-
<script src="assets/vendor-
|
|
60
|
-
<script src="assets/chunk.713.
|
|
61
|
-
<script src="assets/chunk.524.
|
|
62
|
-
<script src="assets/ghost-
|
|
59
|
+
<script src="assets/vendor-8e3ee8261528bb429cfe78ce79a4a82a.js"></script>
|
|
60
|
+
<script src="assets/chunk.713.761d11035fe0bf3e557c.js"></script>
|
|
61
|
+
<script src="assets/chunk.524.578de86e5014b911b05a.js"></script>
|
|
62
|
+
<script src="assets/ghost-868c537d5c02ca65323d0122596a67ec.js"></script>
|
|
63
63
|
</body>
|
|
64
64
|
</html>
|
|
@@ -156,11 +156,15 @@ function getTinybirdTrackerScript(dataRoot) {
|
|
|
156
156
|
return '';
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
const src = getAssetUrl('public/ghost-stats.js');
|
|
159
|
+
const src = getAssetUrl('public/ghost-stats.js', false);
|
|
160
160
|
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
const
|
|
161
|
+
const statsConfig = config.get('tinybird:tracker');
|
|
162
|
+
const localConfig = config.get('tinybird:tracker:local');
|
|
163
|
+
const localEnabled = localConfig?.enabled ?? false;
|
|
164
|
+
|
|
165
|
+
const endpoint = localEnabled ? localConfig.endpoint : statsConfig.endpoint;
|
|
166
|
+
const token = localEnabled ? localConfig.token : statsConfig.token;
|
|
167
|
+
const datasource = localEnabled ? localConfig.datasource : statsConfig.datasource;
|
|
164
168
|
|
|
165
169
|
const tbParams = _.map({
|
|
166
170
|
site_uuid: config.get('tinybird:tracker:id'),
|
|
@@ -360,7 +364,7 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
|
|
|
360
364
|
head.push(tagCodeInjection);
|
|
361
365
|
}
|
|
362
366
|
|
|
363
|
-
if (config.get('tinybird') && config.get('tinybird:tracker')
|
|
367
|
+
if (config.get('tinybird') && config.get('tinybird:tracker')) {
|
|
364
368
|
head.push(getTinybirdTrackerScript(dataRoot));
|
|
365
369
|
}
|
|
366
370
|
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
const STORAGE_KEY = 'session-id'
|
|
4
4
|
let DATASOURCE = 'analytics_events'
|
|
5
5
|
const storageMethods = {
|
|
6
|
-
cookie: 'cookie',
|
|
7
6
|
localStorage: 'localStorage',
|
|
8
7
|
sessionStorage: 'sessionStorage',
|
|
9
8
|
}
|
|
10
|
-
let STORAGE_METHOD = storageMethods.
|
|
9
|
+
let STORAGE_METHOD = storageMethods.localStorage
|
|
11
10
|
let globalAttributes = {}
|
|
12
11
|
let stringifyPayload = true
|
|
13
12
|
|
|
@@ -40,64 +39,37 @@
|
|
|
40
39
|
)
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
function _getSessionIdFromCookie() {
|
|
44
|
-
let cookie = {}
|
|
45
|
-
document.cookie.split(';').forEach(function (el) {
|
|
46
|
-
let [key, value] = el.split('=')
|
|
47
|
-
cookie[key.trim()] = value
|
|
48
|
-
})
|
|
49
|
-
return cookie[STORAGE_KEY]
|
|
50
|
-
}
|
|
51
|
-
|
|
52
42
|
function _getSessionId() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const serializedItem = storage.getItem(STORAGE_KEY)
|
|
63
|
-
|
|
64
|
-
if (!serializedItem) {
|
|
65
|
-
return null
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let item = null;
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
item = JSON.parse(serializedItem)
|
|
72
|
-
} catch (error) {
|
|
73
|
-
return null
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if(typeof item !== 'object' || item === null) {
|
|
77
|
-
return null
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const now = new Date()
|
|
43
|
+
const storage =
|
|
44
|
+
STORAGE_METHOD === storageMethods.localStorage
|
|
45
|
+
? localStorage
|
|
46
|
+
: sessionStorage
|
|
47
|
+
const serializedItem = storage.getItem(STORAGE_KEY)
|
|
48
|
+
|
|
49
|
+
if (!serializedItem) {
|
|
50
|
+
return null
|
|
51
|
+
}
|
|
81
52
|
|
|
82
|
-
|
|
83
|
-
storage.removeItem(STORAGE_KEY)
|
|
84
|
-
return null
|
|
85
|
-
}
|
|
53
|
+
let item = null;
|
|
86
54
|
|
|
87
|
-
|
|
55
|
+
try {
|
|
56
|
+
item = JSON.parse(serializedItem)
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return null
|
|
88
59
|
}
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
if(typeof item !== 'object' || item === null) {
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
92
64
|
|
|
93
|
-
|
|
94
|
-
let cookieValue = `${STORAGE_KEY}=${sessionId}; Max-Age=1800; path=/; secure`
|
|
65
|
+
const now = new Date()
|
|
95
66
|
|
|
96
|
-
if (
|
|
97
|
-
|
|
67
|
+
if (now.getTime() > item.expiry) {
|
|
68
|
+
storage.removeItem(STORAGE_KEY)
|
|
69
|
+
return null
|
|
98
70
|
}
|
|
99
71
|
|
|
100
|
-
|
|
72
|
+
return item.value
|
|
101
73
|
}
|
|
102
74
|
|
|
103
75
|
function _setSessionId() {
|
|
@@ -108,25 +80,17 @@
|
|
|
108
80
|
*/
|
|
109
81
|
|
|
110
82
|
const sessionId = _getSessionId() || _uuidv4()
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
115
|
-
) {
|
|
116
|
-
const now = new Date()
|
|
117
|
-
const item = {
|
|
118
|
-
value: sessionId,
|
|
119
|
-
expiry: now.getTime() + 14400 * 1000, // 4 hours
|
|
120
|
-
}
|
|
121
|
-
const value = JSON.stringify(item)
|
|
122
|
-
const storage =
|
|
123
|
-
STORAGE_METHOD === storageMethods.localStorage
|
|
124
|
-
? localStorage
|
|
125
|
-
: sessionStorage
|
|
126
|
-
return STORAGE_METHOD === storage.setItem(STORAGE_KEY, value)
|
|
83
|
+
const now = new Date()
|
|
84
|
+
const item = {
|
|
85
|
+
value: sessionId,
|
|
86
|
+
expiry: now.getTime() + 14400 * 1000, // 4 hours
|
|
127
87
|
}
|
|
128
|
-
|
|
129
|
-
|
|
88
|
+
const value = JSON.stringify(item)
|
|
89
|
+
const storage =
|
|
90
|
+
STORAGE_METHOD === storageMethods.localStorage
|
|
91
|
+
? localStorage
|
|
92
|
+
: sessionStorage
|
|
93
|
+
storage.setItem(STORAGE_KEY, value)
|
|
130
94
|
}
|
|
131
95
|
|
|
132
96
|
/**
|
|
@@ -176,11 +140,11 @@
|
|
|
176
140
|
*
|
|
177
141
|
* @param { string } name Event name
|
|
178
142
|
* @param { object } payload Event payload
|
|
179
|
-
* @return {
|
|
143
|
+
* @return { Promise<any> } request response
|
|
180
144
|
*/
|
|
181
145
|
async function _sendEvent(name, payload) {
|
|
182
146
|
_setSessionId()
|
|
183
|
-
const url =
|
|
147
|
+
const url = `${host}?name=${DATASOURCE}&token=${token}`
|
|
184
148
|
|
|
185
149
|
let processedPayload
|
|
186
150
|
if (stringifyPayload) {
|
|
@@ -240,14 +204,14 @@
|
|
|
240
204
|
'user-agent': window.navigator.userAgent,
|
|
241
205
|
locale,
|
|
242
206
|
location: country,
|
|
243
|
-
referrer:
|
|
207
|
+
referrer: _getReferrer(),
|
|
244
208
|
pathname: window.location.pathname,
|
|
245
209
|
href: window.location.href,
|
|
246
210
|
})
|
|
247
211
|
}, 300)
|
|
248
212
|
}
|
|
249
213
|
|
|
250
|
-
function
|
|
214
|
+
function _getReferrer() {
|
|
251
215
|
// Fetch referrer data from query params - priority is the following order: ref, source, utm_source, utm_medium, referrer
|
|
252
216
|
let refParam;
|
|
253
217
|
let sourceParam;
|
|
@@ -301,7 +265,10 @@
|
|
|
301
265
|
}
|
|
302
266
|
|
|
303
267
|
// Client
|
|
304
|
-
window.Tinybird = {
|
|
268
|
+
window.Tinybird = {
|
|
269
|
+
trackEvent: _sendEvent,
|
|
270
|
+
_trackPageHit: _trackPageHit
|
|
271
|
+
}
|
|
305
272
|
|
|
306
273
|
// Event listener
|
|
307
274
|
window.addEventListener('hashchange', _trackPageHit)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
SCHEMA >
|
|
4
|
+
`site_uuid` LowCardinality(String),
|
|
5
|
+
`timestamp` DateTime,
|
|
6
|
+
`action` LowCardinality(String),
|
|
7
|
+
`version` LowCardinality(String),
|
|
8
|
+
`session_id` String,
|
|
9
|
+
`member_uuid` String,
|
|
10
|
+
`member_status` String,
|
|
11
|
+
`post_uuid` String,
|
|
12
|
+
`post_type` String,
|
|
13
|
+
`location` String,
|
|
14
|
+
`source` String,
|
|
15
|
+
`pathname` String,
|
|
16
|
+
`href` String,
|
|
17
|
+
`device` String,
|
|
18
|
+
`os` String,
|
|
19
|
+
`browser` String
|
|
20
|
+
|
|
21
|
+
ENGINE "MergeTree"
|
|
22
|
+
ENGINE_PARTITION_KEY "toYYYYMM(timestamp)"
|
|
23
|
+
ENGINE_SORTING_KEY "site_uuid, timestamp, session_id"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
TOKEN "tracker" APPEND
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
SCHEMA >
|
|
5
|
+
`timestamp` DateTime `json:$.timestamp`,
|
|
6
|
+
`session_id` String `json:$.session_id`,
|
|
7
|
+
`action` LowCardinality(String) `json:$.action`,
|
|
8
|
+
`version` LowCardinality(String) `json:$.version`,
|
|
9
|
+
`payload` JSON(max_dynamic_types=4, max_dynamic_paths=32) `json:$.payload`,
|
|
10
|
+
`site_uuid` LowCardinality(String) `json:$.payload.site_uuid`
|
|
11
|
+
|
|
12
|
+
ENGINE "MergeTree"
|
|
13
|
+
ENGINE_PARTITION_KEY "toYYYYMM(timestamp)"
|
|
14
|
+
ENGINE_SORTING_KEY "site_uuid, timestamp"
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE timeseries
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
{% set _single_day = defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
8
|
+
with
|
|
9
|
+
{% if defined(date_from) %}
|
|
10
|
+
toStartOfDay(
|
|
11
|
+
toDate(
|
|
12
|
+
{{
|
|
13
|
+
Date(
|
|
14
|
+
date_from,
|
|
15
|
+
description="Starting day for filtering a date range",
|
|
16
|
+
required=False,
|
|
17
|
+
)
|
|
18
|
+
}}
|
|
19
|
+
)
|
|
20
|
+
) as start,
|
|
21
|
+
{% else %} toStartOfDay(timestampAdd(today(), interval -7 day)) as start,
|
|
22
|
+
{% end %}
|
|
23
|
+
{% if defined(date_to) %}
|
|
24
|
+
toStartOfDay(
|
|
25
|
+
toDate(
|
|
26
|
+
{{
|
|
27
|
+
Date(
|
|
28
|
+
date_to,
|
|
29
|
+
description="Finishing day for filtering a date range",
|
|
30
|
+
required=False,
|
|
31
|
+
)
|
|
32
|
+
}}
|
|
33
|
+
)
|
|
34
|
+
) as end
|
|
35
|
+
{% else %} toStartOfDay(today()) as end
|
|
36
|
+
{% end %}
|
|
37
|
+
{% if _single_day %}
|
|
38
|
+
select
|
|
39
|
+
arrayJoin(
|
|
40
|
+
arrayMap(
|
|
41
|
+
x -> toDateTime(toString(toDateTime(x)), {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}),
|
|
42
|
+
range(
|
|
43
|
+
toUInt32(toDateTime(start)), toUInt32(timestampAdd(end, interval 1 day)), 3600
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
) as date
|
|
47
|
+
{% else %}
|
|
48
|
+
select
|
|
49
|
+
arrayJoin(
|
|
50
|
+
arrayMap(
|
|
51
|
+
x -> toDate(x),
|
|
52
|
+
range(toUInt32(start), toUInt32(timestampAdd(end, interval 1 day)), 24 * 3600)
|
|
53
|
+
)
|
|
54
|
+
) as date
|
|
55
|
+
{% end %}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
NODE session_metrics
|
|
59
|
+
DESCRIPTION >
|
|
60
|
+
Calculate session-level metrics (visits, pageviews, bounce rate, avg session duration)
|
|
61
|
+
|
|
62
|
+
SQL >
|
|
63
|
+
|
|
64
|
+
%
|
|
65
|
+
select
|
|
66
|
+
site_uuid,
|
|
67
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
68
|
+
toStartOfHour(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date,
|
|
69
|
+
{% else %}
|
|
70
|
+
toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date,
|
|
71
|
+
{% end %}
|
|
72
|
+
session_id,
|
|
73
|
+
pageviews,
|
|
74
|
+
is_bounce,
|
|
75
|
+
duration as session_sec
|
|
76
|
+
from mv_session_data sd
|
|
77
|
+
inner join filtered_sessions fs
|
|
78
|
+
on fs.session_id = sd.session_id
|
|
79
|
+
where
|
|
80
|
+
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
81
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
82
|
+
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
83
|
+
{% else %}
|
|
84
|
+
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
85
|
+
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
86
|
+
{% end %}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
NODE data
|
|
90
|
+
DESCRIPTION >
|
|
91
|
+
Calculate KPIs per time period
|
|
92
|
+
|
|
93
|
+
SQL >
|
|
94
|
+
|
|
95
|
+
select
|
|
96
|
+
a.date,
|
|
97
|
+
uniq(distinct s.session_id) as visits,
|
|
98
|
+
sum(s.pageviews) as pageviews,
|
|
99
|
+
truncate(avg(s.is_bounce), 2) as bounce_rate,
|
|
100
|
+
truncate(avg(s.session_sec), 2) as avg_session_sec
|
|
101
|
+
from timeseries a
|
|
102
|
+
inner join session_metrics s on a.date = s.date
|
|
103
|
+
group by a.date
|
|
104
|
+
order by a.date
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
NODE pathname_pageviews
|
|
108
|
+
DESCRIPTION >
|
|
109
|
+
Calculate pageviews for specific pathname with time granularity handling
|
|
110
|
+
|
|
111
|
+
SQL >
|
|
112
|
+
|
|
113
|
+
%
|
|
114
|
+
select
|
|
115
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
116
|
+
toStartOfHour(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date,
|
|
117
|
+
{% else %}
|
|
118
|
+
toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date,
|
|
119
|
+
{% end %}
|
|
120
|
+
count() pageviews
|
|
121
|
+
from timeseries a
|
|
122
|
+
inner join _mv_hits h on
|
|
123
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
124
|
+
a.date = toStartOfHour(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
125
|
+
{% else %}
|
|
126
|
+
a.date = toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
127
|
+
{% end %}
|
|
128
|
+
where
|
|
129
|
+
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
130
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
131
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
132
|
+
{% else %}
|
|
133
|
+
{% if defined(date_from) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
134
|
+
{% if defined(date_to) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
135
|
+
{% end %}
|
|
136
|
+
{% if defined(member_status) %} and member_status IN {{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }} {% end %}
|
|
137
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
138
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
139
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
140
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
141
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
142
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
143
|
+
group by date
|
|
144
|
+
order by date
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
NODE finished_data
|
|
148
|
+
SQL >
|
|
149
|
+
|
|
150
|
+
%
|
|
151
|
+
select
|
|
152
|
+
a.date as date,
|
|
153
|
+
coalesce(b.visits, 0) as visits,
|
|
154
|
+
{% if defined(pathname) %}coalesce(c.pageviews, 0){% else %}coalesce(b.pageviews, 0){% end %} as pageviews,
|
|
155
|
+
coalesce(b.bounce_rate, 0) as bounce_rate,
|
|
156
|
+
coalesce(b.avg_session_sec, 0) as avg_session_sec
|
|
157
|
+
from timeseries a
|
|
158
|
+
left join data b on a.date = b.date
|
|
159
|
+
{% if defined(pathname) %}left join pathname_pageviews c on a.date = c.date{% end %}
|
|
160
|
+
|
|
161
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE _top_browsers_0
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
select
|
|
8
|
+
browser,
|
|
9
|
+
uniqExact(session_id) as visits
|
|
10
|
+
from _mv_hits h
|
|
11
|
+
inner join filtered_sessions fs
|
|
12
|
+
on fs.session_id = h.session_id
|
|
13
|
+
where
|
|
14
|
+
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
15
|
+
{% if defined(date_from) %}
|
|
16
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
17
|
+
>=
|
|
18
|
+
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
19
|
+
{% else %}
|
|
20
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
21
|
+
>=
|
|
22
|
+
timestampAdd(today(), interval -7 day)
|
|
23
|
+
{% end %}
|
|
24
|
+
{% if defined(date_to) %}
|
|
25
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
26
|
+
<=
|
|
27
|
+
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
28
|
+
{% else %}
|
|
29
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
30
|
+
<=
|
|
31
|
+
today()
|
|
32
|
+
{% end %}
|
|
33
|
+
{% if defined(member_status) %}
|
|
34
|
+
and member_status IN (
|
|
35
|
+
select arrayJoin(
|
|
36
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
37
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
{% end %}
|
|
41
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
42
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
43
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
44
|
+
-- added source filter back
|
|
45
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
46
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
47
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
48
|
+
group by browser
|
|
49
|
+
order by visits desc
|
|
50
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
51
|
+
|
|
52
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE _top_devices_0
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
select
|
|
8
|
+
device,
|
|
9
|
+
uniqExact(session_id) as visits
|
|
10
|
+
from _mv_hits h
|
|
11
|
+
inner join filtered_sessions fs
|
|
12
|
+
on fs.session_id = h.session_id
|
|
13
|
+
where
|
|
14
|
+
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
15
|
+
{% if defined(date_from) %}
|
|
16
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
17
|
+
>=
|
|
18
|
+
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
19
|
+
{% else %}
|
|
20
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
21
|
+
>=
|
|
22
|
+
timestampAdd(today(), interval -7 day)
|
|
23
|
+
{% end %}
|
|
24
|
+
{% if defined(date_to) %}
|
|
25
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
26
|
+
<=
|
|
27
|
+
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
28
|
+
{% else %}
|
|
29
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
30
|
+
<=
|
|
31
|
+
today()
|
|
32
|
+
{% end %}
|
|
33
|
+
{% if defined(member_status) %}
|
|
34
|
+
and member_status IN (
|
|
35
|
+
select arrayJoin(
|
|
36
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
37
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
{% end %}
|
|
41
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
42
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
43
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
44
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
45
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
46
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
47
|
+
group by device
|
|
48
|
+
order by visits desc
|
|
49
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
50
|
+
|
|
51
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE _top_locations_0
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
select
|
|
8
|
+
location,
|
|
9
|
+
uniqExact(session_id) as visits
|
|
10
|
+
from _mv_hits h
|
|
11
|
+
inner join filtered_sessions fs
|
|
12
|
+
on fs.session_id = h.session_id
|
|
13
|
+
where
|
|
14
|
+
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
15
|
+
{% if defined(date_from) %}
|
|
16
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
17
|
+
>=
|
|
18
|
+
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
19
|
+
{% else %}
|
|
20
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
21
|
+
>=
|
|
22
|
+
timestampAdd(today(), interval -7 day)
|
|
23
|
+
{% end %}
|
|
24
|
+
{% if defined(date_to) %}
|
|
25
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
26
|
+
<=
|
|
27
|
+
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
28
|
+
{% else %}
|
|
29
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
30
|
+
<=
|
|
31
|
+
today()
|
|
32
|
+
{% end %}
|
|
33
|
+
{% if defined(member_status) %}
|
|
34
|
+
and member_status IN (
|
|
35
|
+
select arrayJoin(
|
|
36
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
37
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
{% end %}
|
|
41
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
42
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
43
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
44
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
45
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
46
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
47
|
+
group by location
|
|
48
|
+
order by visits desc
|
|
49
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
50
|
+
|
|
51
|
+
TYPE ENDPOINT
|