Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ [RUMF-1396] migrate extension to manifest v3 #1828

Merged
merged 5 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dev,@wdio/junit-reporter,MIT,Copyright (c) OpenJS Foundation and other contribut
dev,@wdio/local-runner,MIT,Copyright JS Foundation and other contributors
dev,@wdio/selenium-standalone-service,MIT,Copyright JS Foundation and other contributors
dev,@wdio/spec-reporter,MIT,Copyright JS Foundation and other contributors
dev,@webextension-toolbox/webpack-webextension-plugin,MIT,Copyright 2018 Henrik Wenz ([email protected])
dev,ajv,MIT,Copyright 2015-2017 Evgeny Poberezkin
dev,browserstack-local,MIT,Copyright 2016 BrowserStack
dev,connect-busboy,MIT,Copyright Brian White
Expand Down Expand Up @@ -77,5 +78,4 @@ dev,webdriverio,MIT,Copyright JS Foundation and other contributors
dev,webpack,MIT,Copyright JS Foundation and other contributors
dev,webpack-cli,MIT,Copyright JS Foundation and other contributors
dev,webpack-dev-middleware,MIT,Copyright JS Foundation and other contributors
dev,webpack-webextension-plugin,MIT,Copyright 2018 Henrik Wenz ([email protected])
dev,node-fetch,MIT,Copyright 2016-2020 Node Fetch Team
9 changes: 5 additions & 4 deletions developer-extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"manifest_version": 2,
"manifest_version": 3,
"name": "Datadog Browser SDK developer extension",
"permissions": ["<all_urls>", "tabs", "webRequest", "webRequestBlocking", "storage", "browsingData"],
"permissions": ["webRequest", "storage", "browsingData", "declarativeNetRequest"],
"host_permissions": ["<all_urls>"],
"icons": {
"256": "icon.png"
},
"background": {
"scripts": ["background.js"],
"persistent": true
"service_worker": "background.js",
"type": "module"
},
"devtools_page": "devtools.html"
}
6 changes: 3 additions & 3 deletions developer-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"dev": "webpack --mode development --watch"
},
"devDependencies": {
"@types/chrome": "0.0.180",
"@types/chrome": "0.0.202",
"@types/react": "18.0.1",
"@types/react-dom": "18.0.0",
"@webextension-toolbox/webpack-webextension-plugin": "2.1.3",
"copy-webpack-plugin": "8.1.0",
"html-webpack-plugin": "5.3.1",
"webpack": "5.28.0",
"webpack-webextension-plugin": "0.4.1"
"webpack": "5.28.0"
},
"dependencies": {
"@emotion/react": "11.10.0",
Expand Down
2 changes: 1 addition & 1 deletion developer-extension/src/background/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import { createListenAction, createSendAction } from '../common/actions'
import type { BackgroundActions, PopupActions } from '../common/types'

export const listenAction = createListenAction<BackgroundActions>()
export const sendAction = createSendAction<PopupActions>()
export const sendAction = createSendAction<PopupActions>().sendAction
13 changes: 13 additions & 0 deletions developer-extension/src/background/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
export const DEV_LOGS_URL = 'http://localhost:8080/datadog-logs.js'
export const DEV_RUM_URL = 'http://localhost:8080/datadog-rum.js'
export const DEV_RUM_SLIM_URL = 'http://localhost:8080/datadog-rum-slim.js'

export const INTAKE_DOMAINS = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

'browser-intake-datadoghq.com',
'browser-intake-datadoghq.eu',
'browser-intake-ddog-gov.com',
'browser-intake-us3-datadoghq.com',
'browser-intake-us5-datadoghq.com',
...['com', 'eu'].flatMap((tld) => [
`public-trace-http-intake.logs.datadoghq.${tld}`,
`rum-http-intake.logs.datadoghq.${tld}`,
`browser-http-intake.logs.datadoghq.${tld}`,
]),
]

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { listenAction } from '../actions'
import { DEV_LOGS_URL } from '../constants'
import { setStore } from '../store'

listenAction('getStore', () => {
refreshDevServerStatus().catch((error) =>
console.error('refreshDevServerStatus: Unexpected error while refreshing dev server status:', error)
)
})

async function refreshDevServerStatus() {
const timeoutId = setTimeout(() => setStore({ devServerStatus: 'checking' }), 500)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you not want to phase out store?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I want but not in this PR :) I only moved this function in another file.

let isAvailable = false
try {
const response = await fetch(DEV_LOGS_URL, { method: 'HEAD' })
isAvailable = response.status === 200
} catch {
// The request can fail if nothing is listening on the URL port. In this case, consider the dev
// server 'unavailable'.
}
clearTimeout(timeoutId)
setStore({ devServerStatus: isAvailable ? 'available' : 'unavailable' })
}
69 changes: 0 additions & 69 deletions developer-extension/src/background/domain/replaceBundles.ts

This file was deleted.

72 changes: 72 additions & 0 deletions developer-extension/src/background/domain/syncRules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { listenAction } from '../actions'
import { DEV_LOGS_URL, DEV_RUM_SLIM_URL, DEV_RUM_URL, INTAKE_DOMAINS } from '../constants'
import { store } from '../store'

listenAction('setStore', (newStore) => {
if ('useDevBundles' in newStore || 'useRumSlim' in newStore || 'blockIntakeRequests' in newStore) {
void chrome.browsingData.removeCache({})
syncRules()
}
})

function syncRules() {
console.log('syncRules: Syncing rules')
chrome.declarativeNetRequest
.getSessionRules()
.then((existingRules) =>
chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: existingRules.map((rule) => rule.id),
addRules: getRules(),
})
)
.catch((error) => console.error('syncRules: Error while syncing rules:', error))
}

function getRules() {
const rules: chrome.declarativeNetRequest.Rule[] = []
let id = 1

if (store.useDevBundles) {
const devRumUrl = store.useRumSlim ? DEV_RUM_SLIM_URL : DEV_RUM_URL
console.log('syncRules: add redirect to dev bundles rules')
rules.push(
createRedirectRule(id++, /^https:\/\/.*\/datadog-rum(-v\d|canary|staging)?\.js$/, { url: devRumUrl }),
createRedirectRule(id++, /^https:\/\/.*\/datadog-rum-slim(-v\d|canary|staging)?\.js$/, { url: DEV_RUM_SLIM_URL }),
createRedirectRule(id++, /^https:\/\/.*\/datadog-logs(-v\d|canary|staging)?\.js$/, { url: DEV_LOGS_URL }),
createRedirectRule(id++, 'https://localhost:8443/static/datadog-rum-hotdog.js', { url: devRumUrl })
)
} else if (store.useRumSlim) {
console.log('syncRules: add redirect to rum slim rule')
rules.push(createRedirectRule(id++, /^(https:\/\/.*\/datadog-rum)(-slim)?/, { regexSubstitution: '\\1-slim' }))
}

if (store.blockIntakeRequests) {
console.log('syncRules: add block intake rules')
for (const intakeDomain of INTAKE_DOMAINS) {
rules.push({
id: id++,
condition: { urlFilter: `||${intakeDomain}` },
action: {
type: chrome.declarativeNetRequest.RuleActionType.BLOCK,
},
})
}
}

return rules
}

function createRedirectRule(
id: number,
filter: RegExp | string,
redirect: chrome.declarativeNetRequest.Redirect
): chrome.declarativeNetRequest.Rule {
return {
id,
action: {
type: chrome.declarativeNetRequest.RuleActionType.REDIRECT,
redirect,
},
condition: typeof filter === 'string' ? { urlFilter: `|${filter}|` } : { regexFilter: filter.source },
}
}
4 changes: 2 additions & 2 deletions developer-extension/src/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
import './domain/replaceBundles'
import './domain/blockIntakeRequests'
import './domain/refreshDevServerStatus'
import './domain/syncRules'
18 changes: 0 additions & 18 deletions developer-extension/src/background/intakeUrlPatterns.ts

This file was deleted.

21 changes: 0 additions & 21 deletions developer-extension/src/background/utils.ts

This file was deleted.

39 changes: 27 additions & 12 deletions developer-extension/src/common/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Message<Actions extends { [key: string]: any }> = ValueOf<{
}
}>

export function createListenAction<Actions>() {
export function createListenAction<Actions extends { [key: string]: any }>() {
function listenAction<K extends keyof Actions>(
action: K,
callback: (payload: Actions[K], tabId: number | undefined) => void
Expand All @@ -27,18 +27,33 @@ export function createListenAction<Actions>() {
}

export function createSendAction<Actions>() {
let onDisconnect: (() => void) | undefined

function sendAction<K extends keyof Actions>(action: K, payload: Actions[K]) {
return chrome.runtime.sendMessage({ action, payload }, () => {
const error = chrome.runtime.lastError
if (
error &&
error.message !== 'Could not establish connection. Receiving end does not exist.' &&
error.message !== 'The message port closed before a response was received.'
) {
console.error(`sendAction error: ${String(error.message)}`)
}
})
try {
chrome.runtime.sendMessage({ action, payload }).catch(handleError)
} catch (error) {
handleError(error)
}
}

function handleError(error: any) {
const message = typeof error === 'object' && error !== null ? String(error.message) : '(no message)'

if (onDisconnect && message === 'Extension context invalidated.') {
onDisconnect()
} else if (
message !== 'Could not establish connection. Receiving end does not exist.' &&
message !== 'The message port closed before a response was received.'
) {
console.error(`sendAction error: ${message}`)
}
}

return sendAction
return {
sendAction,
setOnDisconnect: (newOnDisconnect: () => void) => {
onDisconnect = newOnDisconnect
},
}
}
3 changes: 2 additions & 1 deletion developer-extension/src/panel/actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createListenAction, createSendAction } from '../common/actions'
import type { BackgroundActions, PopupActions } from '../common/types'

export const sendAction = createSendAction<BackgroundActions>()
const { sendAction, setOnDisconnect } = createSendAction<BackgroundActions>()
export { sendAction, setOnDisconnect }
export const listenAction = createListenAction<PopupActions>()
Loading