Skip to content

Commit 9c78cea

Browse files
authored
feat: 🎸 add generators to create community/event/podcast (#314)
* feat: 🎸 add generators to create community/event/podcast ✅ Closes: #164
1 parent 0a240a3 commit 9c78cea

35 files changed

+2073
-37
lines changed

‎.eslintrc.json

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
"ignorePatterns": ["**/*"],
44
"plugins": ["@nx", "html"],
55
"overrides": [
6+
{
7+
"files": "*.json",
8+
"parser": "jsonc-eslint-parser",
9+
"rules": {}
10+
},
611
{
712
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
813
"rules": {

‎.vscode/extensions.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"recommendations": [
33
"nrwl.angular-console",
44
"esbenp.prettier-vscode",
5-
"dbaeumer.vscode-eslint"
5+
"dbaeumer.vscode-eslint",
6+
"firsttris.vscode-jest-runner"
67
]
78
}

‎.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"eslint.validate": ["json"]
3+
}

‎jest.config.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { getJestProjectsAsync } from '@nx/jest';
2+
3+
export default async () => ({
4+
projects: await getJestProjectsAsync(),
5+
});

‎jest.preset.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const nxPreset = require('@nx/jest/preset').default;
2+
3+
module.exports = { ...nxPreset };

‎libs/plugin/.eslintrc.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"extends": ["../../.eslintrc.json"],
3+
"ignorePatterns": ["!**/*"],
4+
"overrides": [
5+
{
6+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7+
"rules": {}
8+
},
9+
{
10+
"files": ["*.ts", "*.tsx"],
11+
"rules": {}
12+
},
13+
{
14+
"files": ["*.js", "*.jsx"],
15+
"rules": {}
16+
},
17+
{
18+
"files": ["./package.json", "./generators.json"],
19+
"parser": "jsonc-eslint-parser",
20+
"rules": {
21+
"@nx/nx-plugin-checks": "error"
22+
}
23+
}
24+
]
25+
}

‎libs/plugin/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# plugin
2+
3+
This library was generated with [Nx](https://nx.dev).
4+
5+
## Building
6+
7+
Run `nx build plugin` to build the library.
8+
9+
## Running unit tests
10+
11+
Run `nx test plugin` to execute the unit tests via [Jest](https://jestjs.io).

‎libs/plugin/generators.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"generators": {
3+
"create-community": {
4+
"factory": "./src/generators/create-community/generator",
5+
"schema": "./src/generators/create-community/schema.json",
6+
"description": "Create a new community"
7+
},
8+
"create-podcast": {
9+
"factory": "./src/generators/create-podcast/generator",
10+
"schema": "./src/generators/create-podcast/schema.json",
11+
"description": "Create a new podcast"
12+
},
13+
"create-event": {
14+
"factory": "./src/generators/create-event/generator",
15+
"schema": "./src/generators/create-event/schema.json",
16+
"description": "Create a new event"
17+
}
18+
}
19+
}

‎libs/plugin/jest.config.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* eslint-disable */
2+
export default {
3+
displayName: 'plugin',
4+
preset: '../jest.preset.js',
5+
transform: {
6+
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7+
},
8+
moduleFileExtensions: ['ts', 'js', 'html'],
9+
coverageDirectory: '../coverage/libs/plugin',
10+
};

‎libs/plugin/package.json

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "@angular-hub/plugin",
3+
"version": "0.0.1",
4+
"dependencies": {
5+
"@nx/devkit": "19.3.1",
6+
"tslib": "^2.3.0"
7+
},
8+
"type": "commonjs",
9+
"main": "./src/index.js",
10+
"typings": "./src/index.d.ts",
11+
"private": true,
12+
"generators": "./generators.json"
13+
}

‎libs/plugin/project.json

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "plugin",
3+
"$schema": "../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "libs/plugin/src",
5+
"projectType": "library",
6+
"tags": [],
7+
"targets": {
8+
"build": {
9+
"executor": "@nx/js:tsc",
10+
"outputs": ["{options.outputPath}"],
11+
"options": {
12+
"outputPath": "dist/libs/plugin",
13+
"main": "libs/plugin/src/index.ts",
14+
"tsConfig": "libs/plugin/tsconfig.lib.json",
15+
"assets": [
16+
"libs/plugin/*.md",
17+
{
18+
"input": "./libs/plugin/src",
19+
"glob": "**/!(*.ts)",
20+
"output": "./src"
21+
},
22+
{
23+
"input": "./libs/plugin/src",
24+
"glob": "**/*.d.ts",
25+
"output": "./src"
26+
},
27+
{
28+
"input": "./libs/plugin",
29+
"glob": "generators.json",
30+
"output": "."
31+
},
32+
{
33+
"input": "./libs/plugin",
34+
"glob": "executors.json",
35+
"output": "."
36+
}
37+
]
38+
}
39+
},
40+
"lint": {
41+
"executor": "@nx/eslint:lint"
42+
},
43+
"test": {
44+
"executor": "@nx/jest:jest",
45+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
46+
"options": {
47+
"jestConfig": "libs/plugin/jest.config.ts"
48+
}
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
2+
import { Tree, readProjectConfiguration } from '@nx/devkit';
3+
4+
import { createCommunityGenerator } from './generator';
5+
import { CreateCommunityGeneratorSchema } from './schema';
6+
7+
describe('create-community generator', () => {
8+
let tree: Tree;
9+
const options: CreateCommunityGeneratorSchema = { name: 'test' };
10+
11+
beforeEach(() => {
12+
tree = createTreeWithEmptyWorkspace();
13+
});
14+
15+
it('should run successfully', async () => {
16+
await createCommunityGenerator(tree, options);
17+
const config = readProjectConfiguration(tree, 'test');
18+
expect(config).toBeDefined();
19+
});
20+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { logger, readJson, Tree, updateJson } from '@nx/devkit';
2+
import { CreateCommunityGeneratorSchema } from './schema';
3+
import { exit } from 'node:process';
4+
import { Community } from '../models/community';
5+
import { isPublicAsset } from '../utils/isPublicAsset';
6+
7+
const COMMUNITIES_PATH = 'angular-hub/src/public/assets/data/community.json';
8+
9+
export async function createCommunityGenerator(
10+
tree: Tree,
11+
options: CreateCommunityGeneratorSchema,
12+
) {
13+
const { name, type, url, logo } = options;
14+
15+
if (!name) {
16+
logger.error('[angular-hub] Name is missing');
17+
return exit(1);
18+
}
19+
20+
if (!type) {
21+
logger.error('[angular-hub] Type is missing');
22+
return exit(1);
23+
}
24+
25+
if (url && !isPublicAsset(url)) {
26+
logger.error(
27+
'[angular-hub] Url is not valid (should start with https or http). ',
28+
);
29+
return exit(1);
30+
}
31+
32+
if (logo && !isPublicAsset(logo)) {
33+
logger.info(
34+
'[angular-hub] Make sure you upload the logo file at logos folder in the assets directory',
35+
);
36+
}
37+
38+
const existingCommunities: Community[] = readJson(tree, COMMUNITIES_PATH);
39+
40+
if (isCommunityExisting(existingCommunities, name)) {
41+
logger.error(`[angular-hub] ${name} Community already exists`);
42+
return exit(1);
43+
}
44+
45+
updateJson(tree, COMMUNITIES_PATH, (communities: Community[]) => {
46+
communities.push({
47+
name,
48+
type,
49+
url: options.url ?? '',
50+
location: options.location ?? '',
51+
logo: options.logo ?? '',
52+
twitter: options.twitter ?? '',
53+
linkedin: options.linkedin ?? '',
54+
callForPapers: options.callForPapers ?? '',
55+
events: [],
56+
});
57+
58+
return communities;
59+
});
60+
61+
logger.info(
62+
`[angular-hub] Community is added successfully. You can manually update the data if needed afterwards`,
63+
);
64+
}
65+
66+
function isCommunityExisting(communities: Community[], name: string): boolean {
67+
return communities
68+
.map((community) => community.name.toLowerCase())
69+
.includes(name.toLowerCase());
70+
}
71+
72+
export default createCommunityGenerator;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface CreateCommunityGeneratorSchema {
2+
name: string;
3+
type: 'workshop' | 'conference' | 'meetup' | 'other';
4+
location?: string;
5+
url?: string;
6+
logo?: string;
7+
twitter?: string;
8+
linkedin?: string;
9+
callForPapers?: string;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"$schema": "https://json-schema.org/schema",
3+
"$id": "CreateCommunity",
4+
"title": "",
5+
"type": "object",
6+
"properties": {
7+
"name": {
8+
"type": "string",
9+
"description": "Provide the community name",
10+
"$default": {
11+
"$source": "argv",
12+
"index": 0
13+
},
14+
"x-prompt": "What is the name of community?"
15+
},
16+
"type": {
17+
"type": "string",
18+
"enum": ["workshop", "conference", "meetup", "other"],
19+
"description": "Provide the community type:",
20+
"x-prompt": {
21+
"message": "What is the type of community?",
22+
"type": "list",
23+
"items": [
24+
{
25+
"value": "workshop",
26+
"label": "Workshop"
27+
},
28+
{
29+
"value": "conference",
30+
"label": "Conference"
31+
},
32+
{
33+
"value": "meetup",
34+
"label": "Meetup"
35+
},
36+
{
37+
"value": "other",
38+
"label": "Other"
39+
}
40+
]
41+
}
42+
},
43+
"location": {
44+
"type": "string",
45+
"description": "Provide the location where community takes place",
46+
"x-prompt": "Provide the community location:"
47+
},
48+
"url": {
49+
"type": "string",
50+
"description": "Provide the site url",
51+
"x-prompt": "Provide the site url:"
52+
},
53+
"logo": {
54+
"type": "string",
55+
"description": "Provide the brand logo",
56+
"x-prompt": "Provide the brand logo url:"
57+
},
58+
"twitter": {
59+
"type": "string",
60+
"description": "Provide the twitter account link",
61+
"x-prompt": "Provide the twitter profile:"
62+
},
63+
"linkedin": {
64+
"type": "string",
65+
"description": "Provide the linkedin account link",
66+
"x-prompt": "Provide the linkedin profile:"
67+
},
68+
"callForPapers": {
69+
"type": "string",
70+
"description": "Provide the Call-For-Paper (CFP) form url",
71+
"x-prompt": "Provide the CFP form url:"
72+
}
73+
},
74+
"required": ["name", "type"]
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
2+
import { Tree, readProjectConfiguration } from '@nx/devkit';
3+
4+
import { createEventGenerator } from './generator';
5+
import { CreateEventGeneratorSchema } from './schema';
6+
7+
describe('create-event generator', () => {
8+
let tree: Tree;
9+
const options: CreateEventGeneratorSchema = { name: 'test' };
10+
11+
beforeEach(() => {
12+
tree = createTreeWithEmptyWorkspace();
13+
});
14+
15+
it('should run successfully', async () => {
16+
await createEventGenerator(tree, options);
17+
const config = readProjectConfiguration(tree, 'test');
18+
expect(config).toBeDefined();
19+
});
20+
});

0 commit comments

Comments
 (0)