docs/lib/schema-event.js

489 строки
12 KiB
JavaScript

import { languageKeys } from './languages.js'
import { allVersionKeys } from './all-versions.js'
import { productIds } from './all-products.js'
import { allTools } from './all-tools.js'
const context = {
type: 'object',
additionalProperties: false,
required: ['event_id', 'user', 'version', 'created', 'path'],
properties: {
// Required of all events
event_id: {
type: 'string',
description: 'The unique identifier of the event.',
format: 'uuid',
},
user: {
type: 'string',
description:
"The unique identifier of the current user performing the event. Please use randomly generated values or hashed values; we don't want to be able to look up in a database.",
format: 'uuid',
},
version: {
type: 'string',
description: 'The version of the event schema.',
pattern: '^\\d+(\\.\\d+)?(\\.\\d+)?$', // eslint-disable-line
},
created: {
type: 'string',
format: 'date-time',
description: 'The time we created the event; please reference UTC.',
},
page_event_id: {
type: 'string',
description: 'The id of the corresponding `page` event.',
format: 'uuid',
},
// Content information
path: {
type: 'string',
description: 'The browser value of `location.pathname`.',
format: 'uri-reference',
},
hostname: {
type: 'string',
description: 'The browser value of `location.hostname.`',
format: 'uri-reference',
},
referrer: {
type: 'string',
description: 'The browser value of `document.referrer`.',
format: 'uri-reference',
},
search: {
type: 'string',
description: 'The browser value of `location.search`.',
},
href: {
type: 'string',
description: 'The browser value of `location.href`.',
format: 'uri',
},
path_language: {
type: 'string',
description: 'The language the user is viewing, from the URL path.',
enum: languageKeys,
},
path_version: {
type: 'string',
description: 'The GitHub version of the docs, from the URL path.',
enum: allVersionKeys,
},
path_product: {
type: 'string',
description: 'The GitHub product the docs are for, from the URL path.',
enum: productIds.concat(['homepage']),
},
path_article: {
type: 'string',
description: 'The article path without language or version, from the URL path.',
},
page_document_type: {
type: 'string',
description: 'The generic page document type based on URL path.',
enum: ['homepage', 'early-access', 'product', 'category', 'mapTopic', 'article'], // get-document-type.js
},
page_type: {
type: 'string',
description: 'Optional page type from the content frontmatter.',
enum: ['overview', 'quick_start', 'tutorial', 'how_to', 'reference'], // frontmatter.js
},
status: {
type: 'number',
description: 'The HTTP response status code of the main page HTML.',
minimum: 0,
maximum: 999,
},
// Device information
os: {
type: 'string',
description: 'The type of operating system the user is working with.',
enum: ['windows', 'mac', 'linux', 'ios', 'android', 'cros', 'other'],
default: 'other',
},
os_version: {
type: 'string',
description: 'The version of the operating system the user is using.',
},
browser: {
type: 'string',
description: 'The type of browser the user is browsing with.',
enum: ['chrome', 'safari', 'firefox', 'edge', 'ie', 'other'],
default: 'other',
},
browser_version: {
type: 'string',
description: 'The version of the browser the user is browsing with.',
},
viewport_width: {
type: 'number',
description: 'The viewport width, not the overall device size.',
minimum: 1,
},
viewport_height: {
type: 'number',
description: 'The viewport height, not the overall device height.',
minimum: 1,
},
// Location information
timezone: {
type: 'number',
description: 'The timezone the user is in, as `new Date().getTimezoneOffset() / -60`.',
},
user_language: {
type: 'string',
description: 'The browser value of `navigator.language`.',
},
// Preference information
os_preference: {
type: 'string',
enum: ['linux', 'mac', 'windows'],
description: 'The os for examples selected by the user.',
},
application_preference: {
type: 'string',
enum: Object.keys(allTools),
description: 'The application selected by the user.',
},
color_mode_preference: {
enum: ['dark', 'light', 'auto', 'auto:dark', 'auto:light'],
description: 'The color mode selected by the user.',
},
},
}
const pageSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context'],
properties: {
context,
type: {
type: 'string',
pattern: '^page$',
},
},
}
const exitSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context'],
properties: {
context,
type: {
type: 'string',
pattern: '^exit$',
},
exit_render_duration: {
type: 'number',
description: 'How long the server took to render the page content, in seconds.',
minimum: 0.001,
},
exit_first_paint: {
type: 'number',
minimum: 0.001,
description:
'The duration until `first-contentful-paint`, in seconds. Informs CSS performance.',
},
exit_dom_interactive: {
type: 'number',
minimum: 0.001,
description:
'The duration until `PerformanceNavigationTiming.domInteractive`, in seconds. Informs JavaScript loading performance.',
},
exit_dom_complete: {
type: 'number',
minimum: 0.001,
description:
'The duration until `PerformanceNavigationTiming.domComplete`, in seconds. Informs JavaScript execution performance.',
},
exit_visit_duration: {
type: 'number',
minimum: 0.001,
description:
'The duration of exit.timestamp - page.timestamp, in seconds. Informs bounce rate.',
},
exit_scroll_length: {
type: 'number',
minimum: 0,
maximum: 1,
description: 'The percentage of how far the user scrolled on the page.',
},
},
}
const linkSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'link_url'],
properties: {
context,
type: {
type: 'string',
pattern: '^link$',
},
link_url: {
type: 'string',
format: 'uri',
description:
'The href of the anchor tag the user clicked, or the page or object they directed their browser to.',
},
},
}
const searchSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'search_query'],
properties: {
context,
type: {
type: 'string',
pattern: '^search$',
},
search_query: {
type: 'string',
description: 'The actual text content of the query string the user sent to the service.',
},
search_context: {
type: 'string',
description: 'Any additional search context, such as component searched.',
},
},
}
const searchResultSchema = {
type: 'object',
additionalProperties: false,
required: [
'type',
'context',
'search_result_query',
'search_result_index',
'search_result_total',
'search_result_rank',
'search_result_url',
],
properties: {
context,
type: {
type: 'string',
pattern: '^searchResult$',
},
search_result_query: {
type: 'string',
description: 'The query the user searched for.',
},
search_result_index: {
type: 'number',
description: 'The order position of the user selected search result.',
},
search_result_total: {
type: 'number',
description: 'The total number of search results we returned for the query.',
},
search_result_rank: {
type: 'number',
description:
'The rank score of the order position of the search result, example: `(total - index) / total`.',
},
search_result_url: {
type: 'string',
description: 'The destination url of the search result the user selected.',
},
},
}
const navigateSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context'],
properties: {
context,
type: {
type: 'string',
pattern: '^navigate$',
},
navigate_label: {
type: 'string',
description: 'An identifier for where the user is navigating.',
},
},
}
const surveySchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'survey_vote'],
properties: {
context,
type: {
type: 'string',
pattern: '^survey$',
},
survey_vote: {
type: 'boolean',
description: 'Whether the user found the page helpful.',
},
survey_comment: {
type: 'string',
description: 'Any textual comments the user wanted to provide.',
},
survey_email: {
type: 'string',
format: 'email',
description: "The user's email address, if the user provided and consented.",
},
},
}
const experimentSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'experiment_name', 'experiment_variation'],
properties: {
context,
type: {
type: 'string',
pattern: '^experiment$',
},
experiment_name: {
type: 'string',
description: 'The test that this event is part of.',
},
experiment_variation: {
type: 'string',
enum: ['control', 'treatment'],
description: 'The variation this user we bucketed in, such as control or treatment.',
},
experiment_success: {
type: 'boolean',
default: true,
description: 'Whether or not the user successfully performed the test goal.',
},
},
}
const redirectSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'redirect_from', 'redirect_to'],
properties: {
context,
type: {
type: 'string',
pattern: '^redirect$',
},
redirect_from: {
type: 'string',
description: 'The requested href.',
format: 'uri-reference',
},
redirect_to: {
type: 'string',
description: 'The destination href of the redirect.',
format: 'uri-reference',
},
},
}
const clipboardSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'clipboard_operation'],
properties: {
context,
type: {
type: 'string',
pattern: '^clipboard$',
},
clipboard_operation: {
type: 'string',
description: 'Which clipboard operation the user is performing.',
enum: ['copy', 'paste', 'cut'],
},
},
}
const printSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context'],
properties: {
context,
type: {
type: 'string',
pattern: '^print$',
},
},
}
const preferenceSchema = {
type: 'object',
additionalProperties: false,
required: ['type', 'context', 'preference_name', 'preference_value'],
properties: {
context,
type: {
type: 'string',
pattern: '^preference$',
},
preference_name: {
type: 'string',
enum: ['application', 'color_mode', 'os'],
description: 'The preference name, such as os, application, or color_mode',
},
preference_value: {
type: 'string',
enum: Object.keys(allTools).concat(
'dark',
'light',
'auto',
'auto:dark',
'auto:light',
'linux',
'mac',
'windows'
),
description: 'The application, color_mode, or os selected by the user.',
},
},
}
export const eventSchema = {
oneOf: [
pageSchema,
exitSchema,
linkSchema,
searchSchema,
searchResultSchema,
navigateSchema,
surveySchema,
experimentSchema,
redirectSchema,
clipboardSchema,
printSchema,
preferenceSchema,
],
}
export const hydroNames = {
page: 'docs.v0.PageEvent',
exit: 'docs.v0.ExitEvent',
link: 'docs.v0.LinkEvent',
search: 'docs.v0.SearchEvent',
searchResult: 'docs.v0.SearchResultEvent',
navigate: 'docs.v0.NavigateEvent',
survey: 'docs.v0.SurveyEvent',
experiment: 'docs.v0.ExperimentEvent',
redirect: 'docs.v0.RedirectEvent',
clipboard: 'docs.v0.ClipboardEvent',
print: 'docs.v0.PrintEvent',
preference: 'docs.v0.PreferenceEvent',
}