Skip to content

Typescript Core/Browser implementation #1149

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

Merged
merged 63 commits into from
Dec 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
39b726b
feat: Initial commit
HazAT Oct 10, 2017
bd0281e
feat: Add tests with jest
HazAT Oct 10, 2017
1cb810a
feat: Add basic tests
HazAT Oct 10, 2017
fb4ffad
feat: Strip tests
HazAT Oct 10, 2017
6f42294
feat: Add tests for captureEvent/message
HazAT Oct 11, 2017
5a0660a
feat: Steamline options
HazAT Oct 11, 2017
58d9af8
feat: Added sdk options
HazAT Oct 11, 2017
0d87d90
feat: Write readme
HazAT Oct 11, 2017
6b366fb
feat: Move to new folder structure
HazAT Oct 11, 2017
66baabf
fix: package.json
HazAT Oct 11, 2017
74bebed
feat: Add js tests
HazAT Oct 11, 2017
01b2a44
feat: Add webpack in platform-browser to get bundle
HazAT Oct 11, 2017
554b67e
fix: rename platform folder
HazAT Oct 11, 2017
068574e
fix: Remove Set
HazAT Oct 11, 2017
9d104de
meta: Add todos
HazAT Oct 11, 2017
19d34c0
feat: Add headless chrome tests
HazAT Oct 12, 2017
9c5b1c1
ref: Rename Sdk to Integration
HazAT Oct 12, 2017
845e036
ref: Integration renaming
HazAT Oct 12, 2017
b153149
ref: Rename to adapter
HazAT Oct 12, 2017
48ce5de
fix: Implement real captureException and captureMessage
HazAT Oct 12, 2017
00f17c9
meta: Change naming
HazAT Oct 16, 2017
14ec5cd
ref: Rename main files
HazAT Oct 16, 2017
4ff9502
feat: Add sharedClient sentry
HazAT Oct 16, 2017
783d75f
feat: Add dsn parsing with tests
HazAT Oct 16, 2017
86062ef
feat: Add tests for wrong dsn
HazAT Oct 17, 2017
ac899be
Merge remote-tracking branch 'remotes/foo/merge' into feature/packages
HazAT Oct 17, 2017
41e7726
fix: Naming of SentryError
HazAT Oct 17, 2017
51997df
feat: Add setOptions function to adapters
HazAT Oct 17, 2017
cb6e611
feat: Add global create function
HazAT Oct 19, 2017
5ae9476
feat: Remove multiple adapter architecture
HazAT Oct 19, 2017
4926ea3
feat: Add context handling
HazAT Oct 20, 2017
4d7880d
feat: Add breadcrumbs api
HazAT Oct 20, 2017
ced9c63
feat: Tunnel context to adapter
HazAT Oct 20, 2017
37f5ca5
feat: Add breadcrumbCallback
HazAT Oct 20, 2017
482595b
Merge branch 'master' into feature/packages
HazAT Oct 27, 2017
927b551
feat: Add more test, Coverage, Add Sentry Log
HazAT Oct 30, 2017
a478e69
ref: Add tslint and prettier support
HazAT Nov 14, 2017
2683022
fix: Browser tests
HazAT Nov 14, 2017
5013b42
feat: Change browser adapter to reflect tslint
HazAT Nov 25, 2017
e8c27a7
ci: Fix travis config
HazAT Nov 25, 2017
cbcaf18
ci: Update yarn
HazAT Nov 25, 2017
0bf8f37
ci: Build core before browser
HazAT Nov 25, 2017
03f12a2
ci: Fix path
HazAT Nov 25, 2017
5ad2291
ci: Use yarn link
HazAT Nov 25, 2017
b1ad44e
ci: Use yarn link
HazAT Nov 25, 2017
76c17e7
fix: Different code review changes
HazAT Nov 30, 2017
cfa14b3
ref: Code review changes
HazAT Dec 4, 2017
6044d17
ref: make install return a promise
HazAT Dec 4, 2017
663140b
fix: Browser tests
HazAT Dec 4, 2017
3bfdb0b
fix: Remove node ts reference
HazAT Dec 4, 2017
219bf92
meta: Add documentation
HazAT Dec 5, 2017
43e8ccf
feat: Add npmignore
HazAT Dec 5, 2017
b001ffb
feat: package.json version changes
HazAT Dec 5, 2017
428e022
fix(ci): travis tests
HazAT Dec 5, 2017
93dc09f
ci: Fix travis build
HazAT Dec 6, 2017
14cb9d5
ci: Fix travis and skip install
HazAT Dec 6, 2017
3fb0d15
ci: Increase timeout to 60sec
HazAT Dec 6, 2017
fcab234
ci: Remove increased timeout
HazAT Dec 6, 2017
3895cfe
feat: Use rollup instead of webpack
HazAT Dec 6, 2017
7aa57db
feat: Rename Browser to SentryBrowser
HazAT Dec 6, 2017
a654394
feat: Add size:check npm script
HazAT Dec 7, 2017
8773125
fix: package.json main
HazAT Dec 7, 2017
dc5f3e5
feat: Export ISentryBrowserOptions
HazAT Dec 7, 2017
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
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ example/
vendor/
test/
scripts/

packages/core/
packages/browser/
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* @kamilogorek
packages/* @hazat
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ scratch/

.idea
*.sublime-*

yarn-error.log
13 changes: 13 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
build/
docs/
example/
node_modules/
packages/
scripts/
template/
test/

.*
karma.*
Makefile
npm-debug.log
34 changes: 28 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
branches:
only:
- master

sudo: false
language: node_js
node_js:
Expand All @@ -9,9 +10,30 @@ dist: trusty
cache:
directories:
- node_modules
addons:
chrome: stable
firefox: latest
sauce_connect: true
script:
- npm run test && if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then npm run test:ci; else exit 0; fi
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH="$HOME/.yarn/bin:$PATH"

matrix:
include:
- env: NAME="raven-js"
addons:
chrome: stable
firefox: latest
sauce_connect: true
script:
- npm run test && if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then npm run test:ci; else exit 0; fi
- env: NAME="@sentry/browser"
install: true
script:
- yarn link
- cd packages/core && yarn link && yarn install && yarn dist
- cd ../browser
- yarn remove @sentry/core # this has to be removed once we released the package
- yarn link "@sentry/core"
- yarn link "raven-js"
- yarn install && yarn test
- env: NAME="@sentry/core"
install: true
script:
- cd packages/core && yarn install && yarn test
7 changes: 7 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"esbenp.prettier-vscode"
]
}
20 changes: 20 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"editor.tabSize": 2,
"editor.rulers": [90],
"[typescript]": {
"editor.formatOnSave": true
},
"[javascript]": {
"editor.formatOnSave": true
},
"prettier.typescriptEnable": [
"typescript",
"typescriptreact"
],
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/dist/**": true
},
"tslint.autoFixOnSave": true,
}
2 changes: 2 additions & 0 deletions packages/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
coverage/
5 changes: 5 additions & 0 deletions packages/browser/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 90
}
5 changes: 5 additions & 0 deletions packages/browser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## v0.1.0

- Initial release
58 changes: 58 additions & 0 deletions packages/browser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<p align="center">
<a href="https://sentry.io" target="_blank" align="center">
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
</a>
<br/>
<h1>Sentry Browser SDK Package</h1>
</p>

[![npm version](https://img.shields.io/npm/v/@sentry/browser.svg)](https://www.npmjs.com/package/@sentry/browser)
[![npm dm](https://img.shields.io/npm/dm/@sentry/browser.svg)](https://www.npmjs.com/package/@sentry/browser)
[![npm dt](https://img.shields.io/npm/dt/@sentry/browser.svg)](https://www.npmjs.com/package/@sentry/browser)

## General

This package is meant to be used with the Core SDK package.

## Usage

First you have to create the core and `use` a corresponding SDK.
```javascript
import * as Sentry from '@sentry/core';
import { Browser } from '@sentry/browser';

Sentry.create('__DSN__')
.use(Browser)
.install();
```

After that you can call function on the global `sharedClient`:
```javascript
Sentry.getSharedClient().setTagsContext({ cordova: true });
Sentry.getSharedClient().captureMessage('test message');
Sentry.getSharedClient().captureBreadcrumb({ message: 'HOHOHOHO' });
Sentry.getSharedClient().captureException(new Error('error'));
```

If you don't want to use a global static instance of Sentry, you can create one on your own:

```javascript
const client = await new Sentry.Client(dsn).use(MockAdapter).install()
client.setTagsContext({ cordova: true });
client.captureMessage('test message');
client.captureBreadcrumb({ message: 'HOHOHOHO' });

// OR

new Sentry.Client('__DSN__')
.use(MockAdapter)
.install()
.then(client => {
client.setTagsContext({ cordova: true });
client.captureMessage('test message');
client.captureBreadcrumb({ message: 'HOHOHOHO' });
});
```

Notice, `install()` is a `Promise` but we internally wait until it is resolved,
so it is save to call other function without waiting for it.
17 changes: 17 additions & 0 deletions packages/browser/__tests__/browser.no-jest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as Sentry from '@sentry/core';
import { SentryBrowser } from '../lib/SentryBrowser';

// install() returns a promise after init
Sentry.create('https://53039209a22b4ec1bcc296a3c9fdecd6@sentry.io/4291')
.use(SentryBrowser)
.install()
.then(client => {
client.setTagsContext({ cordova: true });
client.captureBreadcrumb({ message: 'HOHOHOHO' });
});

// This should also work because we internally await for adapter install
Sentry.getSharedClient().captureMessage('PICKLE RIIIICK!');
Sentry.getSharedClient().captureException(new Error('YOYOYOY'));

// throw new Error('YP Test');
11 changes: 11 additions & 0 deletions packages/browser/__tests__/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<script src="../dist/bundle.js"></script>
</body>
</html>
54 changes: 54 additions & 0 deletions packages/browser/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/// <reference types="node" />
/// <reference types="jest" />
import * as Sentry from '@sentry/core';
import * as fs from 'fs';
import * as http from 'http';
import * as path from 'path';
import * as Puppeteer from 'puppeteer';
import { SentryBrowser } from '../index';

describe('Browser Interface', () => {
test('sending a message', async done => {
let countExpects = 0;
const expectedAssertions = 2;
expect.assertions(expectedAssertions);

const server = http
.createServer((request, response) => {
if (request.url === '/index.html') {
response.writeHead(200, { 'Content-Type': 'text/html' });
const contents = fs.readFileSync(path.join(__dirname, './index.html'));
response.write(contents);
}
if (request.url === '/dist/bundle.js') {
response.writeHead(200, { 'Content-Type': 'text/javscript' });
const contents = fs.readFileSync(path.join(__dirname, '../dist/bundle.js'));
response.write(contents);
}
response.end();
})
.listen(8999);

const browser = await Puppeteer.launch({ headless: true });
const page = await browser.newPage();

page.on('request', async request => {
// @ts-ignore
if (request.resourceType === 'xhr') {
const data = JSON.parse(request.postData as any);
if (data.exception) {
expect(data.exception).not.toBeUndefined();
} else {
expect(data.message).toBe('PICKLE RIIIICK!');
}
countExpects++;
}
if (countExpects === expectedAssertions) {
await browser.close();
done();
}
});
await page.goto('http://localhost:8999/index.html');
server.close();
});
});
1 change: 1 addition & 0 deletions packages/browser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SentryBrowser, ISentryBrowserOptions } from './lib/SentryBrowser';
96 changes: 96 additions & 0 deletions packages/browser/lib/SentryBrowser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Client, Event, IAdapter, IBreadcrumb, IUser } from '@sentry/core';
declare function require(path: string): any;
const Raven = require('raven-js');

export interface ISentryBrowserOptions {
allowSecretKey?: boolean;
allowDuplicates?: boolean;
}

export class SentryBrowser implements IAdapter {
private client: Client;

constructor(client: Client, public options: ISentryBrowserOptions = {}) {
this.client = client;
}

public install(): Promise<boolean> {
Raven.config(this.client.dsn.getDsn(false), this.options).install();
return Promise.resolve(true);
}

public getRaven() {
return Raven;
}

public setOptions(options: ISentryBrowserOptions) {
Object.assign(this.options, options);
Object.assign(Raven._globalOptions, this.options);
return this;
}

public captureException(exception: Error) {
return new Promise<Event>((resolve, reject) => {
const ravenSendRequest = Raven._sendProcessedPayload;
Raven._sendProcessedPayload = (data: any) => {
Raven._sendProcessedPayload = ravenSendRequest;
resolve(data);
};
Raven.captureException(exception);
});
}

public captureMessage(message: string) {
return new Promise<Event>((resolve, reject) => {
const ravenSendRequest = Raven._sendProcessedPayload;
Raven._sendProcessedPayload = (data: any) => {
Raven._sendProcessedPayload = ravenSendRequest;
resolve(data);
};
Raven.captureMessage(message);
});
}

public setBreadcrumbCallback(callback: (crumb: IBreadcrumb) => void) {
Raven.setBreadcrumbCallback(callback);
}

public captureBreadcrumb(crumb: IBreadcrumb) {
return new Promise<IBreadcrumb>((resolve, reject) => {
Raven.captureBreadcrumb(crumb);
resolve(crumb);
});
}

public send(event: any) {
return new Promise<Event>((resolve, reject) => {
Raven._sendProcessedPayload(event, (error: any) => {
if (error) {
reject(error);
return;
}
resolve(event);
});
});
}

public setUserContext(user?: IUser) {
Raven.setUserContext(user);
return this;
}

public setTagsContext(tags?: { [key: string]: any }) {
Raven.setTagsContext(tags);
return this;
}

public setExtraContext(extra?: { [key: string]: any }) {
Raven.setExtraContext(extra);
return this;
}

public clearContext() {
Raven.clearContext();
return this;
}
}
Loading