Skip to content
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
58 changes: 45 additions & 13 deletions packages/effect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,66 @@
"files": [
"/build"
],
"main": "build/cjs/index.js",
"module": "build/esm/index.js",
"types": "build/types/index.d.ts",
"main": "build/cjs/index.server.js",
"module": "build/esm/index.server.js",
"browser": "build/esm/index.client.js",
"types": "build/types/index.types.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./build/types/index.d.ts",
"default": "./build/esm/index.js"
"types": "./build/types/index.types.d.ts",
"browser": {
"import": "./build/esm/index.client.js",
"require": "./build/cjs/index.client.js"
},
"require": {
"types": "./build/types/index.d.ts",
"default": "./build/cjs/index.js"
"node": {
"import": "./build/esm/index.server.js",
"require": "./build/cjs/index.server.js"
}
},
Copy link

Choose a reason for hiding this comment

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

Missing default fallback conditions in exports map

Medium Severity

The "." export in package.json only defines browser and node conditions with no import/require/default fallback. The comparable @sentry/nuxt package includes top-level "import" and "require" fallbacks after "browser" and "node". Without these, environments that don't set browser or node conditions (edge runtimes, some test runners, certain bundler configurations) will fail to resolve @sentry/effect.

Fix in Cursor Fix in Web

"./server": {
"types": "./build/types/index.server.d.ts",
"import": "./build/esm/index.server.js",
"require": "./build/cjs/index.server.js"
},
"./client": {
"types": "./build/types/index.client.d.ts",
"import": "./build/esm/index.client.js",
"require": "./build/cjs/index.client.js"
}
},
"typesVersions": {
"<5.0": {
"build/types/index.d.ts": [
"build/types-ts3.8/index.d.ts"
"build/types/index.types.d.ts": [
"build/types-ts3.8/index.types.d.ts"
],
"build/types/index.server.d.ts": [
"build/types-ts3.8/index.server.d.ts"
],
"build/types/index.client.d.ts": [
"build/types-ts3.8/index.client.d.ts"
]
}
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@sentry/core": "10.42.0"
"@sentry/browser": "10.42.0",
"@sentry/core": "10.42.0",
"@sentry/node-core": "10.42.0"
},
"peerDependencies": {
"effect": "^3.0.0"
},
"peerDependenciesMeta": {
"effect": {
"optional": false
}
},
"devDependencies": {
"@effect/vitest": "^0.23.9",
"effect": "^3.19.19"
},
"scripts": {
"build": "run-p build:transpile build:types",
Expand All @@ -52,7 +84,7 @@
"build:dev:watch": "yarn build:watch",
"build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch",
"build:tarball": "npm pack",
"circularDepCheck": "madge --circular src/index.ts",
"circularDepCheck": "madge --circular src/index.client.ts && madge --circular src/index.server.ts && madge --circular src/index.types.ts",
"clean": "rimraf build coverage sentry-effect-*.tgz",
"fix": "eslint . --format stylish --fix",
"lint": "eslint . --format stylish",
Expand Down
30 changes: 22 additions & 8 deletions packages/effect/rollup.npm.config.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils';

export default makeNPMConfigVariants(
makeBaseNPMConfig({
packageSpecificConfig: {
output: {
preserveModulesRoot: 'src',
},
const baseConfig = makeBaseNPMConfig({
entrypoints: ['src/index.server.ts', 'src/index.client.ts'],
packageSpecificConfig: {
output: {
preserveModulesRoot: 'src',
},
}),
);
},
});

const defaultExternal = baseConfig.external || [];
baseConfig.external = id => {
if (defaultExternal.includes(id)) {
return true;
}

if (id === 'effect' || id.startsWith('effect/') || id.startsWith('@sentry/')) {
return true;
}

return false;
};

export default makeNPMConfigVariants(baseConfig);
30 changes: 30 additions & 0 deletions packages/effect/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { BrowserOptions } from '@sentry/browser';
import * as EffectLayer from 'effect/Layer';

/**
* Options for the Sentry Effect client layer.
*/
export type EffectClientLayerOptions = BrowserOptions;

/**
* Creates an empty Effect Layer
*
* @example
* ```typescript
* import * as Sentry from '@sentry/effect/client';
* import { Layer, Effect } from 'effect';
*
* const ApiClientWithSentry = ApiClientLive.pipe(
* Layer.provide(Sentry.effectLayer({
* dsn: '__DSN__',
* integrations: [Sentry.browserTracingIntegration()],
* tracesSampleRate: 1.0,
* })),
* );
*
* Effect.runPromise(Effect.provide(myEffect, ApiClientWithSentry));
* ```
*/
export function effectLayer(_: EffectClientLayerOptions): EffectLayer.Layer<never, never, never> {
return EffectLayer.empty;
}
4 changes: 4 additions & 0 deletions packages/effect/src/index.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from '@sentry/browser';

export { effectLayer } from './client/index';
export type { EffectClientLayerOptions } from './client/index';
4 changes: 4 additions & 0 deletions packages/effect/src/index.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from '@sentry/node-core/light';

export { effectLayer } from './server/index';
export type { EffectServerLayerOptions } from './server/index';
87 changes: 0 additions & 87 deletions packages/effect/src/index.ts

This file was deleted.

26 changes: 26 additions & 0 deletions packages/effect/src/index.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable import/export */

// We export everything from both the client part of the SDK and from the server part.
// Some of the exports collide, which is not allowed, unless we redefine the colliding
// exports in this file - which we do below.
import type { Client, Integration, Options, StackParser } from '@sentry/core';
import type * as EffectLayer from 'effect/Layer';
import type * as clientSdk from './index.client';
import type * as serverSdk from './index.server';

export * from './index.client';
export * from './index.server';

export type { EffectClientLayerOptions } from './index.client';
export type { EffectServerLayerOptions } from './index.server';

export declare function effectLayer(
options: clientSdk.EffectClientLayerOptions | serverSdk.EffectServerLayerOptions,
): EffectLayer.Layer<never, never, never>;

export declare function init(options: Options | clientSdk.BrowserOptions | serverSdk.NodeOptions): Client | undefined;
export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
export declare const getDefaultIntegrations: (options: Options) => Integration[];
export declare const defaultStackParser: StackParser;
export declare const logger: typeof clientSdk.logger | typeof serverSdk.logger;
32 changes: 32 additions & 0 deletions packages/effect/src/server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { NodeOptions } from '@sentry/node-core';
import * as EffectLayer from 'effect/Layer';

/**
* Options for the Sentry Effect server layer.
*/
export type EffectServerLayerOptions = NodeOptions;

/**
* Creates an empty Effect Layer
*
* @example
* ```typescript
* import * as Sentry from '@sentry/effect/server';
* import { NodeRuntime } from '@effect/platform-node';
* import { Layer } from 'effect';
* import { HttpLive } from './Http.js';
*
* const MainLive = HttpLive.pipe(
* Layer.provide(Sentry.effectLayer({
* dsn: '__DSN__',
* enableLogs: true,
* enableMetrics: true,
* })),
* );
*
* MainLive.pipe(Layer.launch, NodeRuntime.runMain);
* ```
*/
export function effectLayer(_: EffectServerLayerOptions): EffectLayer.Layer<never, never, never> {
return EffectLayer.empty;
}
2 changes: 1 addition & 1 deletion packages/effect/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import * as index from '../src';
import * as index from '../src/index.client';
Copy link

Choose a reason for hiding this comment

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

Missing integration or E2E tests for feature

Low Severity

This is a feat PR introducing new client/server entrypoints, but it only includes a single basic unit test checking that captureException is defined. Per review rules, feat PRs are expected to include at least one integration or E2E test. Even though the effectLayer currently returns an empty layer, a test verifying it can be constructed without error on both client and server paths would help prevent regressions as functionality is added.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot


describe('effect index export', () => {
it('has correct exports', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/effect/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"outDir": "build"
},
"include": ["src/**/*"]
Expand Down
14 changes: 13 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3269,6 +3269,11 @@
dependencies:
"@edge-runtime/primitives" "6.0.0"

"@effect/vitest@^0.23.9":
version "0.23.13"
resolved "https://registry.yarnpkg.com/@effect/vitest/-/vitest-0.23.13.tgz#17edf9d8e3443f080ff8fe93bd37b023612a07a4"
integrity sha512-F3x2phMXuVzqWexdcYp8v0z1qQHkKxp2UaHNbqZaEjPEp8FBz/iMwbi6iS/oIWzLfGF8XqdP8BGJptvGIJONNw==

"@ember-data/rfc395-data@^0.0.4":
version "0.0.4"
resolved "https://registry.yarnpkg.com/@ember-data/rfc395-data/-/rfc395-data-0.0.4.tgz#ecb86efdf5d7733a76ff14ea651a1b0ed1f8a843"
Expand Down Expand Up @@ -14877,6 +14882,14 @@ effect@3.16.12:
"@standard-schema/spec" "^1.0.0"
fast-check "^3.23.1"

effect@^3.19.19:
version "3.19.19"
resolved "https://registry.yarnpkg.com/effect/-/effect-3.19.19.tgz#643a5a4b7445cc924a28270bc6cd1a5c8facd27e"
integrity sha512-Yc8U/SVXo2dHnaP7zNBlAo83h/nzSJpi7vph6Hzyl4ulgMBIgPmz3UzOjb9sBgpFE00gC0iETR244sfXDNLHRg==
dependencies:
"@standard-schema/spec" "^1.0.0"
fast-check "^3.23.1"

ejs@^3.1.7:
version "3.1.8"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b"
Expand Down Expand Up @@ -28096,7 +28109,6 @@ stylus@0.59.0, stylus@^0.59.0:

sucrase@^3.27.0, sucrase@^3.35.0, sucrase@getsentry/sucrase#es2020-polyfills:
version "3.36.0"
uid fd682f6129e507c00bb4e6319cc5d6b767e36061
resolved "https://codeload.github.com/getsentry/sucrase/tar.gz/fd682f6129e507c00bb4e6319cc5d6b767e36061"
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
Expand Down
Loading