Skip to content
This repository was archived by the owner on Mar 10, 2025. It is now read-only.
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
1 change: 1 addition & 0 deletions e2e/stack-e2e/tests/structure/web-structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function webProjects(project: string) {
`${project}-ui-page`,
`${project}-ui-sidebar-page`,
`${project}-ui-table`,
`${project}-ui-toast`,
`shared-util-sdk`,
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'
import { UseGuards } from '@nestjs/common'
import { Resolver } from '@nestjs/graphql'
import { <%= classify(apiAppName) %><%= classify(modelName) %>DataAccessService, <%= classify(modelName) %> } from '@<%= npmScope %>/<%= apiAppName %>/<%= dasherize(modelName) %>/data-access'
import { GqlAuthGuard } from '@<%= npmScope %>/<%= apiAppName %>/auth/util'

@Resolver(() => <%= classify(modelName) %>)
export class <%= classify(projectName) %>PublicResolver {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'
import { UseGuards } from '@nestjs/common'
import { Resolver } from '@nestjs/graphql'
import { <%= classify(apiAppName) %><%= classify(modelName) %>DataAccessService } from '@<%= npmScope %>/<%= apiAppName %>/<%= dasherize(modelName) %>/data-access'
import { GqlAuthGuard } from '@<%= npmScope %>/<%= apiAppName %>/auth/util'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import {formatFiles, generateFiles, names, Tree} from '@nrwl/devkit';
import {readJsonSync} from "fs-extra";
import {join} from 'path';
import * as process from "process";
import { Tree } from '@nrwl/devkit'
import { execSync } from 'child_process'

const sleep = (seconds = 1) => new Promise((resolve) => setTimeout(resolve, seconds * 1000))
function run(command) {
console.log(`Running command: ${command}`)
execSync(command, { stdio: 'inherit' })
}

export default async function (
host: Tree,
{ name, model, nameField, plural, dryRun }: { name: string, model: string, nameField: string, plural: string, dryRun: boolean }
{ model, nameField, plural }: { model: string; nameField: string; plural: string },
) {
console.log(`nx g @nxpm/stack:api-crud ${name} --plural ${plural}`)
console.log(`yarn prisma:apply`)
console.log(`nx g @nxpm/stack:web-crud ${name} --plural ${plural}`)
console.log(`yarn build:sdk `)
console.log({ name, model, nameField, plural, dryRun })
run(`nx g @nxpm/stack:api-crud ${model} --plural ${plural} --nameField ${nameField}`)
run(`yarn prisma:apply`)

console.log('Please restart the API, will continue in 10 seconds...')
await sleep(10)

run(`nx g @nxpm/stack:web-crud ${model} --plural ${plural} --nameField ${nameField}`)
run(`yarn build:sdk`)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
{
"cli": "nx",
"id": "web-module",
"id": "crud",
"type": "object",
"properties": {
"target": {
"model": {
"type": "string",
"description": "Target folder to create the module",
"description": "Name of the model (in kebab-case), for example: company-address",
"$default": {
"$source": "argv",
"index": 0
}
},
"name": {
"plural": {
"type": "string",
"description": "Name of the module (in kebab-case)",
"description": "Name of the model (in kebab-case), for example: company-addresses",
"$default": {
"$source": "argv",
"index": 1
}
}
},
"required": ["target", "name"]
"required": ["model", "plural"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ exports[`init schematic should run successfully 1`] = `
\\"test-ui-table\\": {
\\"tags\\": [\\"scope:test\\", \\"type:ui\\"]
},
\\"test-ui-toast\\": {
\\"tags\\": [\\"scope:test\\", \\"type:ui\\"]
},
\\"shared-util-sdk\\": {
\\"tags\\": [\\"scope:shared\\", \\"type:util\\"]
}
Expand Down Expand Up @@ -1756,6 +1759,28 @@ exports[`init schematic should run successfully 2`] = `
},
\\"schematics\\": {}
},
\\"test-ui-toast\\": {
\\"projectType\\": \\"library\\",
\\"root\\": \\"libs/test/ui/toast\\",
\\"sourceRoot\\": \\"libs/test/ui/toast/src\\",
\\"prefix\\": \\"ui\\",
\\"architect\\": {
\\"lint\\": {
\\"builder\\": \\"@nrwl/linter:eslint\\",
\\"options\\": {
\\"lintFilePatterns\\": [\\"libs/test/ui/toast/src/**/*.ts\\"]
}
},
\\"test\\": {
\\"builder\\": \\"@nrwl/jest:jest\\",
\\"options\\": {
\\"jestConfig\\": \\"libs/test/ui/toast/jest.config.js\\",
\\"passWithNoTests\\": true
}
}
},
\\"schematics\\": {}
},
\\"shared-util-sdk\\": {
\\"projectType\\": \\"library\\",
\\"root\\": \\"libs/shared/util/sdk\\",
Expand Down Expand Up @@ -1856,6 +1881,7 @@ exports[`init schematic should run successfully 3`] = `
\\"@proj/test/ui/page-header\\": [\\"libs/test/ui/page-header/src/index.ts\\"],
\\"@proj/test/ui/sidebar-page\\": [\\"libs/test/ui/sidebar-page/src/index.ts\\"],
\\"@proj/test/ui/table\\": [\\"libs/test/ui/table/src/index.ts\\"],
\\"@proj/test/ui/toast\\": [\\"libs/test/ui/toast/src/index.ts\\"],
\\"@proj/shared/util/sdk\\": [\\"libs/shared/util/sdk/src/index.ts\\"]
}
}
Expand Down Expand Up @@ -1891,6 +1917,8 @@ exports[`init schematic should run successfully 4`] = `
\\"@nestjs/passport\\": \\"^7.1.5\\",
\\"@nestjs/platform-express\\": \\"^7.0.0\\",
\\"@nestjs/serve-static\\": \\"2.1.4\\",
\\"@ngneat/hot-toast\\": \\"2.0.1\\",
\\"@ngneat/overview\\": \\"1.0.0\\",
\\"@ngneat/svg-icon\\": \\"2.2.2\\",
\\"@ngrx/component-store\\": \\"11.0.0\\",
\\"@ngx-formly/core\\": \\"5.10.13\\",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
exports[`mobile-feature-core schematic should run successfully 1`] = `
"import { HttpClientModule } from '@angular/common/http'
import { NgModule } from '@angular/core'
import { HotToastModule } from '@ngneat/hot-toast';
import { SvgIconsModule } from '@ngneat/svg-icon'

import { TestCoreFeatureGraphQLModule } from './test-core-feature-graphql.module'

@NgModule({
imports: [HttpClientModule, TestCoreFeatureGraphQLModule, SvgIconsModule.forRoot()],
imports: [HttpClientModule, TestCoreFeatureGraphQLModule, HotToastModule.forRoot(), SvgIconsModule.forRoot()],
})
export class TestCoreFeatureModule {}
"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { HttpClientModule } from '@angular/common/http'
import { NgModule } from '@angular/core'
import { HotToastModule } from '@ngneat/hot-toast';
import { SvgIconsModule } from '@ngneat/svg-icon'

import { <%= classify(projectName) %>GraphQLModule } from './<%= projectName %>-graphql.module'

@NgModule({
imports: [HttpClientModule, <%= classify(projectName) %>GraphQLModule, SvgIconsModule.forRoot()],
imports: [HttpClientModule, <%= classify(projectName) %>GraphQLModule, HotToastModule.forRoot(), SvgIconsModule.forRoot()],
})
export class <%= classify(projectName) %>Module {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './lib/guards/is-admin.guard'
export * from './lib/guards/is-logged-in.guard'
export * from './lib/<%= projectName %>.module'
export * from './lib/<%= projectName %>.service'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule } from '@angular/router'
import { <%= classify(projectName) %>Service } from './<%= projectName %>.service'
import { IsAdminGuard } from './guards/is-admin.guard'
import { IsLoggedInGuard } from './guards/is-logged-in.guard'

@NgModule({
imports: [
CommonModule,
RouterModule,
],
providers: [<%= classify(projectName) %>Service, IsLoggedInGuard],
providers: [<%= classify(projectName) %>Service, IsAdminGuard, IsLoggedInGuard],
})
export class <%= classify(projectName) %>Module {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Injectable } from '@angular/core'
import { CanActivate, CanActivateChild, CanLoad, Router, UrlTree } from '@angular/router'
import { Role } from '@<%= npmScope %>/<%= appName %>/core/data-access'
import { <%= classify(appName) %>UiToastService } from '@<%= npmScope %>/<%= appName %>/ui/toast'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { <%= classify(appName) %>AuthStore } from '../<%= projectName %>.store'

@Injectable()
export class IsAdminGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(
private readonly router: Router,
private readonly store: <%= classify(appName) %>AuthStore,
private readonly toast: <%= classify(appName) %>UiToastService,
) {}

canActivate(): Observable<boolean | UrlTree> {
return this.isAdmin()
}

canActivateChild(): Observable<boolean | UrlTree> {
return this.isAdmin()
}

canLoad(): Observable<boolean | UrlTree> {
return this.isAdmin()
}

private isAdmin(): Observable<boolean | UrlTree> {
return this.store.user$.pipe(
map((user) => user?.role === Role.Admin),
map((isAdmin) => {
if (!isAdmin) {
this.toast.error(`You need to have Admin permissions.`)
return this.router.createUrlTree(['/dashboard'])
}
return true
}),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports[`web-feature-shell schematic should run successfully 1`] = `
"import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { TestAuthDataAccessModule, IsLoggedInGuard } from '@nxpm/test/auth/data-access'
import { IsAdminGuard, IsLoggedInGuard, TestAuthDataAccessModule } from '@nxpm/test/auth/data-access'
import { TestLayoutComponent } from '@nxpm/test/layout'

const routes: Routes = [
Expand All @@ -25,6 +25,7 @@ const routes: Routes = [
},
{
path: 'admin',
canActivate: [IsAdminGuard],
loadChildren: () => import('@nxpm/test/admin/feature').then((m) => m.TestAdminFeatureModule),
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { <%= classify(appName) %>AuthDataAccessModule, IsLoggedInGuard } from '@<%= npmScope %>/<%= appName %>/auth/data-access'
import { IsAdminGuard, IsLoggedInGuard, <%= classify(appName) %>AuthDataAccessModule } from '@<%= npmScope %>/<%= appName %>/auth/data-access'
import { <%= classify(appName) %>LayoutComponent } from '@<%= npmScope %>/<%= appName %>/layout'

const routes: Routes = [
Expand All @@ -22,6 +22,7 @@ const routes: Routes = [
},
{
path: 'admin',
canActivate: [IsAdminGuard],
loadChildren: () => import('@<%= npmScope %>/<%= appName %>/admin/feature').then((m) => m.<%= classify(appName) %>AdminFeatureModule),
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/<%= projectName %>.service'
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Injectable } from '@angular/core'
import { HotToastService } from '@ngneat/hot-toast'
import { ToastOptions } from '@ngneat/hot-toast/lib/hot-toast.model'
import { Content } from '@ngneat/overview'

@Injectable({ providedIn: 'root' })
export class <%= classify(projectName) %>Service {
constructor(private readonly toast: HotToastService) {}

error<DataType>(message?: Content, options?: ToastOptions<DataType>) {
return this.toast.error(message, options)
}

success<DataType>(message?: Content, options?: ToastOptions<DataType>) {
return this.toast.success(message, options)
}

warning<DataType>(message?: Content, options?: ToastOptions<DataType>) {
return this.toast.warning(message, options)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Rule } from '@angular-devkit/schematics'
import { ProjectType } from '@nrwl/workspace'
import { normalizeOptions } from '../../../utils'
import { WebUiLibsSchematicSchema } from '../schema'
import { createUiLib } from './create-ui-lib'

export function createUiLibToast(options: WebUiLibsSchematicSchema): Rule {
const name = 'toast'
const normalizedOptions = normalizeOptions({ ...options, name: `ui/${name}` }, ProjectType.Library)

return createUiLib(
options.directory,
name,
`./files/${name}`,
{
'@ngneat/hot-toast': '2.0.1',
'@ngneat/overview': '1.0.0',
},
normalizedOptions,
)
}
1 change: 1 addition & 0 deletions packages/stack/src/schematics/web-ui-libs/libs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './create-ui-lib-page'
export * from './create-ui-lib-page-header'
export * from './create-ui-lib-sidebar-page'
export * from './create-ui-lib-table'
export * from './create-ui-lib-toast'
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
createUiLibPageHeader,
createUiLibSidebarPage,
createUiLibTable,
createUiLibToast,
} from './libs'
import { WebUiLibsSchematicSchema } from './schema'

Expand All @@ -26,5 +27,6 @@ export default function (options: WebUiLibsSchematicSchema): Rule {
createUiLibPageHeader(options),
createUiLibSidebarPage(options),
createUiLibTable(options),
createUiLibToast(options),
])
}