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

#86c0b8vp3: Impement Sentry generator using ast #50

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
110600c
feat: implemented sentry generator
rbd2q Aug 5, 2024
99b7a5f
feat: updated expo-app and next-app generators
rbd2q Aug 8, 2024
d7b7633
refactor: refactored sentry generator
rbd2q Aug 26, 2024
743e548
feat: updated next and expo generators
rbd2q Aug 27, 2024
81221c4
Merge branch 'main' into 86byre0hx-implement-sentry-generator
rbd2q Aug 27, 2024
5f0234c
feat: Integrated tsquery
RuslanAktaev Oct 2, 2024
17e75c7
feat: Resolved conflicts
RuslanAktaev Oct 2, 2024
5647f01
feat: Integrated AST
RuslanAktaev Oct 4, 2024
e555fb9
feat: Added TODO
RuslanAktaev Oct 4, 2024
434cb11
feat: Generator
RuslanAktaev Oct 29, 2024
f6fe466
feat: Resolved conflicts
RuslanAktaev Oct 29, 2024
5ecf230
feat: Refactored functions
RuslanAktaev Oct 30, 2024
def2b0c
feat: Implemented sentry config for expo app
RuslanAktaev Oct 30, 2024
2bc58a5
feat: Added dsn
RuslanAktaev Oct 30, 2024
fea129e
feat: Refactored generators
RuslanAktaev Oct 30, 2024
14ac7ec
feat: Fixed for expo sentry generator
RuslanAktaev Oct 31, 2024
c7b5671
feat: Removed apps
RuslanAktaev Oct 31, 2024
1c53262
feat: Clean trash
RuslanAktaev Oct 31, 2024
789f624
feat: Removed test lib
RuslanAktaev Oct 31, 2024
aa84ee1
feat: Removed libs
RuslanAktaev Oct 31, 2024
02fa500
deps: Fixed deps
RuslanAktaev Oct 31, 2024
9cd39bc
feat: Removed extra scripts
RuslanAktaev Oct 31, 2024
655cfb0
Merge branch 'main' into 86c0b8vp3-sentry-generator-with-ast
RuslanAktaev Dec 8, 2024
a5c7c6b
refactor: Created updateFile util function
RuslanAktaev Dec 8, 2024
14b8ff3
fix: Fixed dsn name
RuslanAktaev Dec 8, 2024
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
5 changes: 5 additions & 0 deletions plugin/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"schema": "./src/generators/react-component/schema.json",
"description": "react-component generator"
},
"sentry": {
"factory": "./src/generators/sentry/generator",
"schema": "./src/generators/sentry/schema.json",
"description": "sentry generator"
},
"ui-kitten": {
"factory": "./src/shared/generators/ui-kitten/generator",
"schema": "./src/shared/generators/ui-kitten/schema.json",
Expand Down
68 changes: 50 additions & 18 deletions plugin/src/generators/expo-app/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
installPackagesTask,
readJson,
Tree,
writeJson
writeJson,
} from '@nx/devkit';
import { ExpoAppGeneratorSchema } from './schema';
import scripts from './scripts';
Expand All @@ -21,13 +21,19 @@ import {
runRNStylesGenerator,
runFormUtilsGenerator,
runStoreGenerator,
runUIKittenGenerator
runUIKittenGenerator,
} from '../../shared/generators';
import { formatName, formatAppIdentifier, addNxAppTag, askQuestion, getImportPathPrefix } from '../../shared/utils';
import {
formatName,
formatAppIdentifier,
addNxAppTag,
askQuestion,
getImportPathPrefix,
} from '../../shared/utils';

export async function expoAppGenerator(
tree: Tree,
options: ExpoAppGeneratorSchema
options: ExpoAppGeneratorSchema,
) {
const appRoot = `apps/${options.directory}`;
const i18nRoot = `i18n/${options.directory}`;
Expand All @@ -36,12 +42,12 @@ export async function expoAppGenerator(
const tags = [`app:${options.directory}`, 'type:app'];

// Install @nx/expo plugin
execSync('npx nx add @nx/expo', { stdio: 'inherit' })
execSync('npx nx add @nx/expo', { stdio: 'inherit' });

if (!existsSync(appRoot)) {
execSync(
`npx nx g @nx/expo:app ${options.name} --directory=apps/${options.directory} --tags="${tags.join(', ')}" --projectNameAndRootFormat=as-provided --unitTestRunner=none --e2eTestRunner=none`,
{ stdio: 'inherit' }
{ stdio: 'inherit' },
);
}

Expand All @@ -50,27 +56,40 @@ export async function expoAppGenerator(
await runStorageGenerator(tree, options);
await runRNStylesGenerator(tree, options);

const shouldGenerateStoreLib = await askQuestion('Do you want to create store lib? (y/n): ') === 'y';
const shouldGenerateStoreLib =
(await askQuestion('Do you want to create store lib? (y/n): ')) === 'y';

if (shouldGenerateStoreLib) {
await runStoreGenerator(tree, { ...options, baseGeneratorType: BaseGeneratorType.EXPO_APP });
await runStoreGenerator(tree, {
...options,
baseGeneratorType: BaseGeneratorType.EXPO_APP,
});
}

const shouldGenerateApiClientLib = shouldGenerateStoreLib && await askQuestion('Do you want to create api client lib? (y/n): ') === 'y';
const shouldGenerateApiClientLib =
shouldGenerateStoreLib &&
(await askQuestion('Do you want to create api client lib? (y/n): ')) ===
'y';

if (shouldGenerateApiClientLib) {
await runApiClientGenerator(tree, options);
}

const shouldGenerateAuthLibs = shouldGenerateApiClientLib && await askQuestion('Do you want to create auth lib? (y/n): ') === 'y';
const shouldGenerateAuthLibs =
shouldGenerateApiClientLib &&
(await askQuestion('Do you want to create auth lib? (y/n): ')) === 'y';

const shouldGenerateFormUtilsLib = await askQuestion('Do you want to create a lib with the form utils? (y/n): ') === 'y';
const shouldGenerateFormUtilsLib =
(await askQuestion(
'Do you want to create a lib with the form utils? (y/n): ',
)) === 'y';

if (shouldGenerateFormUtilsLib) {
await runFormUtilsGenerator(tree, options);
}

const shouldGenerateUIKittenLib = await askQuestion('Do you want to install @ui-kitten? (y/n): ') === 'y';
const shouldGenerateUIKittenLib =
(await askQuestion('Do you want to install @ui-kitten? (y/n): ')) === 'y';

if (shouldGenerateUIKittenLib) {
await runUIKittenGenerator(tree, options);
Expand Down Expand Up @@ -111,7 +130,7 @@ export async function expoAppGenerator(
formatDirectory: () => libPath,
isUIKittenEnabled: shouldGenerateUIKittenLib,
isStoreEnabled: shouldGenerateStoreLib,
appDirectory: options.directory
appDirectory: options.directory,
});

addNxAppTag(tree, options.directory);
Expand All @@ -122,15 +141,20 @@ export async function expoAppGenerator(
tree,
{
...dependencies['expo-app'],
...dependencies['expo-app-root']
...dependencies['expo-app-root'],
},
{
...devDependencies['expo-app'],
...devDependencies['expo-app-root']
}
...devDependencies['expo-app-root'],
},
);

addDependenciesToPackageJson(tree, dependencies['expo-app'], devDependencies['expo-app'], appPackagePath);
addDependenciesToPackageJson(
tree,
dependencies['expo-app'],
devDependencies['expo-app'],
appPackagePath,
);

await formatFiles(tree);

Expand All @@ -139,7 +163,15 @@ export async function expoAppGenerator(
execSync('npx expo install --fix', { stdio: 'inherit' });

if (shouldGenerateAuthLibs) {
execSync(`npx nx g auth ${options.name} ${options.directory}`, { stdio: 'inherit' });
execSync(`npx nx g auth ${options.name} ${options.directory}`, {
stdio: 'inherit',
});
}

if (options.withSentry) {
execSync(`npx nx g sentry --directory=${options.directory}`, {
stdio: 'inherit',
});
}
};
}
Expand Down
1 change: 1 addition & 0 deletions plugin/src/generators/expo-app/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface ExpoAppGeneratorSchema {
name: string;
directory: string;
withSentry: boolean;
}
7 changes: 6 additions & 1 deletion plugin/src/generators/expo-app/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
"index": 1
},
"x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: mobile)"
},
"withSentry": {
"type": "boolean",
"default": false,
"x-prompt": "Do you want to use Sentry in your app?"
}
},
"required": ["name", "directory"]
"required": ["name", "directory", "withSentry"]
}
31 changes: 26 additions & 5 deletions plugin/src/generators/next-app/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import { NextAppGeneratorSchema } from './schema';
import { existsSync } from 'fs';
import { dependencies } from '../../shared/dependencies';
import { BaseGeneratorType } from '../../shared/enums';
import { runApiClientGenerator, runAppEnvGenerator, runFormUtilsGenerator, runStoreGenerator } from '../../shared/generators';
import {
runApiClientGenerator,
runAppEnvGenerator,
runFormUtilsGenerator,
runStoreGenerator,
} from '../../shared/generators';
import { addNxAppTag, askQuestion, formatName } from '../../shared/utils';
import * as path from 'path';

Expand All @@ -35,19 +40,29 @@ export async function nextAppGenerator(

await runAppEnvGenerator(tree, options);

const shouldGenerateStoreLib = await askQuestion('Do you want to create store lib? (y/n): ') === 'y';
const shouldGenerateStoreLib =
(await askQuestion('Do you want to create store lib? (y/n): ')) === 'y';

if (shouldGenerateStoreLib) {
await runStoreGenerator(tree, { ...options, baseGeneratorType: BaseGeneratorType.NEXT_APP });
await runStoreGenerator(tree, {
...options,
baseGeneratorType: BaseGeneratorType.NEXT_APP,
});
}

const shouldGenerateApiClientLib = shouldGenerateStoreLib && await askQuestion('Do you want to create api client lib? (y/n): ') === 'y';
const shouldGenerateApiClientLib =
shouldGenerateStoreLib &&
(await askQuestion('Do you want to create api client lib? (y/n): ')) ===
'y';

if (shouldGenerateApiClientLib) {
await runApiClientGenerator(tree, options);
}

const shouldGenerateFormUtilsLib = await askQuestion('Do you want to create a lib with the form utils? (y/n): ') === 'y';
const shouldGenerateFormUtilsLib =
(await askQuestion(
'Do you want to create a lib with the form utils? (y/n): ',
)) === 'y';

if (shouldGenerateFormUtilsLib) {
await runFormUtilsGenerator(tree, options);
Expand Down Expand Up @@ -88,6 +103,12 @@ export async function nextAppGenerator(

return () => {
installPackagesTask(tree);

if (options.withSentry) {
execSync(`npx nx g sentry --directory=${options.directory}`, {
stdio: 'inherit',
});
}
};
}

Expand Down
1 change: 1 addition & 0 deletions plugin/src/generators/next-app/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface NextAppGeneratorSchema {
name: string;
directory: string;
withSentry: boolean;
}
7 changes: 6 additions & 1 deletion plugin/src/generators/next-app/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
"index": 1
},
"x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)"
},
"withSentry": {
"type": "boolean",
"default": false,
"x-prompt": "Do you want to use Sentry in your app?"
}
},
"required": ["name", "directory"]
"required": ["name", "directory", "withSentry"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import * as Sentry from '@sentry/nextjs';
import NextError from 'next/error';
import { ReactElement, useEffect } from 'react';

interface GlobalErrorProps {
error: Error & { digest?: string };
}

export default function GlobalError({ error }: GlobalErrorProps): ReactElement {
useEffect(() => {
Sentry.captureException(error);
}, [error]);

return (
<html>
<body>
<NextError statusCode={undefined as any} />
</body>
</html>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as Sentry from '@sentry/nextjs';

Sentry.init({
dsn: '<%= dsn %>',

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,

debug: false,
replaysOnErrorSampleRate: 1.0,

// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1,

// You can remove this option if you're not planning to use the Sentry Session Replay feature:
integrations: [
Sentry.replayIntegration(),
Sentry.inboundFiltersIntegration(),
],
denyUrls: ['localhost'],
});
12 changes: 12 additions & 0 deletions plugin/src/generators/sentry/files/sentry.edge.config.ts.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/nextjs';

Sentry.init({
dsn: '<%= dsn %>',

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,

debug: false,
integrations: [Sentry.inboundFiltersIntegration()],
denyUrls: ['localhost']
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/nextjs';

Sentry.init({
dsn: '<%= dsn %>',

// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1,

debug: false,
integrations: [Sentry.inboundFiltersIntegration()],
denyUrls: ['localhost'],
});
21 changes: 21 additions & 0 deletions plugin/src/generators/sentry/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { formatFiles, Tree } from '@nx/devkit';
import { SentryGeneratorSchema } from './schema';
import { isExpoApp, isNextApp } from '../../shared/utils';
import { generateSentryNext, generateSentryExpo } from './utils';

export async function sentryGenerator(
tree: Tree,
options: SentryGeneratorSchema,
) {
const projectRoot = `apps/${options.directory}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

can't we use selectProject from utils? So we can remove x-prompt for directory.

Example: https://github.com/RonasIT/nx-generators/blob/main/plugin/src/generators/react-lib/generator.ts#L22


if (isNextApp(tree, projectRoot)) {
generateSentryNext(tree, options, projectRoot);
} else if (isExpoApp(tree, projectRoot)) {
generateSentryExpo(tree, options, projectRoot);
}

await formatFiles(tree);
}

export default sentryGenerator;
5 changes: 5 additions & 0 deletions plugin/src/generators/sentry/schema.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface SentryGeneratorSchema {
name: string;
directory: string;
dsn: string;
}
23 changes: 23 additions & 0 deletions plugin/src/generators/sentry/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json-schema.org/schema",
"$id": "Sentry",
"title": "",
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)"
},
"dsn": {
"type": "string",
"description": "",
"x-prompt": "What is your Sentry DSN?"
}
},
"required": ["directory", "dsn"]
}
1 change: 1 addition & 0 deletions plugin/src/generators/sentry/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './property-assignment-data';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Expression } from 'typescript';

export type PropertyAssignmentData = {
key: string;
initializer: Expression;
comment?: string;
};
Loading